UNPKG

@transactional/core

Version:

"@transactional/core" is an npm package that offers the core implementation of "@Transactional" method decorator for running your queries inside a transaction seamlessly. It achieves this by leveraging AsyncLocalStorage.

86 lines (85 loc) 4.45 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.transactional = exports.Transactional = exports.Propagation = exports.TRANSACTIONAL_CONTEXT = void 0; const async_hooks_1 = require("async_hooks"); exports.TRANSACTIONAL_CONTEXT = new async_hooks_1.AsyncLocalStorage(); var Propagation; (function (Propagation) { Propagation[Propagation["MANDATORY"] = 0] = "MANDATORY"; Propagation[Propagation["NEVER"] = 1] = "NEVER"; Propagation[Propagation["NOT_SUPPORTED"] = 2] = "NOT_SUPPORTED"; Propagation[Propagation["REQUIRED"] = 3] = "REQUIRED"; Propagation[Propagation["REQUIRES_NEW"] = 4] = "REQUIRES_NEW"; Propagation[Propagation["SUPPORTS"] = 5] = "SUPPORTS"; })(Propagation || (exports.Propagation = Propagation = {})); const Transactional = (propagation = Propagation.REQUIRED, options) => (target, propertyKey, descriptor) => { const originalMethod = descriptor.value; if (descriptor.value) { descriptor.value = (0, exports.transactional)(originalMethod, propagation, options); } }; exports.Transactional = Transactional; const transactional = (method, propagation = Propagation.REQUIRED, options) => { return function (...args) { return __awaiter(this, void 0, void 0, function* () { const store = exports.TRANSACTIONAL_CONTEXT.getStore(); if (Propagation.SUPPORTS === propagation) { return method.call(this, ...args); } if ([Propagation.REQUIRED, Propagation.MANDATORY].includes(propagation) && store) { return method.call(this, ...args); } if (Propagation.REQUIRED === propagation && !store) { return exports.TRANSACTIONAL_CONTEXT.run({ options }, () => __awaiter(this, void 0, void 0, function* () { return run.call(this); })); } if (Propagation.MANDATORY === propagation && !store) { throw new Error("Transaction is mandatory but no active transaction was found"); } if (Propagation.NOT_SUPPORTED === propagation && !store) { return method.call(this, ...args); } if (Propagation.NOT_SUPPORTED === propagation && store) { return exports.TRANSACTIONAL_CONTEXT.run(null, () => run.call(this)); } if (Propagation.REQUIRES_NEW === propagation) { return exports.TRANSACTIONAL_CONTEXT.run({ options }, () => run.call(this)); } if (Propagation.NEVER === propagation && store) { throw new Error("Transaction is forbidden yet a transaction was found"); } if (Propagation.NEVER === propagation && !store) { return method.call(this, ...args); } function run() { return __awaiter(this, void 0, void 0, function* () { try { const result = yield method.call(this, ...args); const store = exports.TRANSACTIONAL_CONTEXT.getStore(); if (store === null || store === void 0 ? void 0 : store.$commit) { yield store.$commit(); } return result; } catch (error) { const store = exports.TRANSACTIONAL_CONTEXT.getStore(); if (store === null || store === void 0 ? void 0 : store.$rollback) { yield store.$rollback(); } throw error; } }); } }); }; }; exports.transactional = transactional;