UNPKG

@melleb/pgtx

Version:

Simple node-postgres wrapper that abstracts transactions and savepoints

118 lines (112 loc) 3.76 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { default: () => pgtx }); module.exports = __toCommonJS(index_exports); // src/TransactionContext.ts var import_crypto = require("crypto"); // src/create-proxy.ts function createProxy(client, transactionContext) { return new Proxy( { client, transactionContext }, { get(target, prop) { if (prop in target.client) { return target.client[prop].bind(target.client); } if (prop in target.transactionContext) { return target.transactionContext[prop].bind( target.transactionContext ); } return void 0; } } ); } // src/TransactionContext.ts var TransactionContext = class _TransactionContext { constructor(client, parentTransaction, activeSavePoint) { this.client = client; this.parentTransaction = parentTransaction; this.activeSavePoint = activeSavePoint; } status = 0 /* ACTIVE */; async transaction(childTransaction) { let activeSavePointName = void 0; if (this.parentTransaction) { activeSavePointName = "sp_" + (0, import_crypto.randomUUID)().replaceAll("-", "_"); await this.client.query(`SAVEPOINT ${activeSavePointName}`); } else { await this.client.query("BEGIN"); } const childCtx = new _TransactionContext( this.client, this, activeSavePointName ); const proxy = createProxy(this.client, childCtx); if (!childTransaction) { return proxy; } try { await childTransaction(proxy); } catch (e) { await childCtx.rollback(); throw e; } if (childCtx.status === 0 /* ACTIVE */) { await childCtx.commit(); } return createProxy(this.client, this); } async commit() { if (this.status !== 0 /* ACTIVE */) { throw new Error("Cannot commit a transaction that is not active"); } if (this.parentTransaction && this.activeSavePoint) { await this.client.query(`RELEASE SAVEPOINT ${this.activeSavePoint}`); return createProxy(this.client, this.parentTransaction); } await this.client.query("COMMIT"); this.status = 1 /* COMMITTED */; return createProxy(this.client, this.parentTransaction || this); } async rollback() { if (this.status !== 0 /* ACTIVE */) { throw new Error("Cannot roll back a transaction that is not active"); } if (this.activeSavePoint && this.parentTransaction) { await this.client.query(`ROLLBACK TO SAVEPOINT ${this.activeSavePoint}`); this.status = 2 /* CANCELLED */; return createProxy(this.client, this.parentTransaction); } await this.client.query("ROLLBACK"); this.status = 2 /* CANCELLED */; return createProxy(this.client, this.parentTransaction || this); } }; // src/index.ts function pgtx(client) { const transactionContext = new TransactionContext(client); return createProxy(client, transactionContext); }