@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
JavaScript
;
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;