@duraflows/kysely 5.2.0 → 5.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -144,6 +144,8 @@ Both are applied transaction-locally via `set_config(name, value, true)` — the
144
144
 
145
145
  Convenience factory for short-lived runtimes pre-bound to an existing transaction. Each workflow call runs in a savepoint on `trx`, so a failed call leaves no partial writes behind even if you catch its error. Observers fire when the call resolves, before your transaction commits, and duraflows calls they make join `trx`. For strictly post-commit observers, use `KyselyTransactionContext.transaction(db, …)` with the long-lived providers instead.
146
146
 
147
+ Don't mix these providers with the long-lived `kyselyWorkflowProviders(db)` (or `KyselyTransactionContext.transaction(db, …)`) inside one transaction. The two track their active transaction separately, one per `trx` and the other per `db`, so a call through one doesn't see a transaction opened through the other. It starts a second transaction on another connection instead, which can wait on row locks the first one holds. Use one style per transaction.
148
+
147
149
  ### `KyselyTransactionContext`
148
150
 
149
151
  The context is scoped per Kysely instance:
package/dist/cjs/index.js CHANGED
@@ -49,7 +49,7 @@ function kyselyWorkflowProvidersFromTransaction(trx) {
49
49
  // provider must never supersede it.
50
50
  const scope = kysely_transaction_context_js_1.kyselyTransactionScopes.current(narrowed);
51
51
  if (scope) {
52
- return kysely_transaction_context_js_1.kyselyTransactionScopes.runInSavepoint(narrowed, scope, callback, (sql) => (0, kysely_transaction_context_js_1.executeRawStatement)(scope.connection, sql));
52
+ return (0, kysely_transaction_context_js_1.runInKyselySavepoint)(narrowed, scope, callback);
53
53
  }
54
54
  // The caller owns `trx`, so even this outermost call is nested in their
55
55
  // transaction: run it in a savepoint so a failure leaves no partial
@@ -58,7 +58,7 @@ function kyselyWorkflowProvidersFromTransaction(trx) {
58
58
  // duraflows call they make joins `trx` as a savepoint, and the
59
59
  // callbacks it queues drain in the same pass.
60
60
  const root = kysely_transaction_context_js_1.kyselyTransactionScopes.createRoot(boundTrx);
61
- const result = await kysely_transaction_context_js_1.kyselyTransactionScopes.run(narrowed, root, () => kysely_transaction_context_js_1.kyselyTransactionScopes.runInSavepoint(narrowed, root, callback, (sql) => (0, kysely_transaction_context_js_1.executeRawStatement)(boundTrx, sql)));
61
+ const result = await kysely_transaction_context_js_1.kyselyTransactionScopes.run(narrowed, root, () => (0, kysely_transaction_context_js_1.runInKyselySavepoint)(narrowed, root, callback));
62
62
  await kysely_transaction_context_js_1.kyselyTransactionScopes.run(narrowed, root, () => (0, core_1.runAfterCommitCallbacks)(root.callbacks));
63
63
  return result;
64
64
  },
@@ -1,20 +1,15 @@
1
1
  import type { Kysely, Transaction } from "kysely";
2
- import { ScopedTransactionContext } from "@duraflows/core";
2
+ import { ScopedTransactionContext, type TransactionScope } from "@duraflows/core";
3
3
  import type { WorkflowDatabase } from "./kysely-database.js";
4
4
  type WorkflowTransaction = Transaction<WorkflowDatabase>;
5
5
  /** @internal Shared with the runners; not part of the public API. */
6
6
  export declare const kyselyTransactionScopes: ScopedTransactionContext<Kysely<WorkflowDatabase>, WorkflowTransaction>;
7
7
  /**
8
- * @internal Runs one fixed SQL statement (a savepoint command) on `trx`.
9
- *
10
- * `Transaction` has no savepoint API in kysely 0.29 (only `ControlledTransaction`
11
- * does), and this package imports kysely for types only, since kysely is
12
- * ESM-only and a runtime import would break the CommonJS build. So the
13
- * statement is handed to `executeQuery` as a compiled query built by hand,
14
- * shaped exactly like `CompiledQuery.raw(sql)`. `sql` is always an internally
15
- * generated `SAVEPOINT` / `RELEASE` / `ROLLBACK TO` statement, never user input.
8
+ * @internal Runs `callback` in a savepoint nested in `scope`, issuing the
9
+ * savepoint statements on that scope's own transaction. Every kysely entry
10
+ * point that nests (the runners and `transaction()`) goes through here.
16
11
  */
17
- export declare function executeRawStatement(trx: WorkflowTransaction, sql: string): Promise<unknown>;
12
+ export declare function runInKyselySavepoint<T>(owner: Kysely<WorkflowDatabase>, scope: TransactionScope<WorkflowTransaction>, callback: () => Promise<T>): Promise<T>;
18
13
  /**
19
14
  * @internal Runs `callback` as the root of a new kysely transaction on `db`
20
15
  * (after `setup`, e.g. transaction-local timeouts), and only once kysely has
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.KyselyTransactionContext = exports.kyselyTransactionScopes = void 0;
4
- exports.executeRawStatement = executeRawStatement;
4
+ exports.runInKyselySavepoint = runInKyselySavepoint;
5
5
  exports.runOwnedKyselyTransaction = runOwnedKyselyTransaction;
6
6
  const node_crypto_1 = require("node:crypto");
7
7
  const core_1 = require("@duraflows/core");
@@ -10,7 +10,7 @@ const core_1 = require("@duraflows/core");
10
10
  /** @internal Shared with the runners; not part of the public API. */
11
11
  exports.kyselyTransactionScopes = new core_1.ScopedTransactionContext();
12
12
  /**
13
- * @internal Runs one fixed SQL statement (a savepoint command) on `trx`.
13
+ * Runs one fixed SQL statement (a savepoint command) on `trx`.
14
14
  *
15
15
  * `Transaction` has no savepoint API in kysely 0.29 (only `ControlledTransaction`
16
16
  * does), and this package imports kysely for types only, since kysely is
@@ -28,6 +28,14 @@ function executeRawStatement(trx, sql) {
28
28
  };
29
29
  return trx.executeQuery(query);
30
30
  }
31
+ /**
32
+ * @internal Runs `callback` in a savepoint nested in `scope`, issuing the
33
+ * savepoint statements on that scope's own transaction. Every kysely entry
34
+ * point that nests (the runners and `transaction()`) goes through here.
35
+ */
36
+ function runInKyselySavepoint(owner, scope, callback) {
37
+ return exports.kyselyTransactionScopes.runInSavepoint(owner, scope, callback, (sql) => executeRawStatement(scope.connection, sql));
38
+ }
31
39
  /**
32
40
  * @internal Runs `callback` as the root of a new kysely transaction on `db`
33
41
  * (after `setup`, e.g. transaction-local timeouts), and only once kysely has
@@ -84,7 +92,7 @@ exports.KyselyTransactionContext = {
84
92
  const owner = db;
85
93
  const scope = exports.kyselyTransactionScopes.current(owner);
86
94
  if (scope) {
87
- return exports.kyselyTransactionScopes.runInSavepoint(owner, scope, () => callback(scope.connection), (sql) => executeRawStatement(scope.connection, sql));
95
+ return runInKyselySavepoint(owner, scope, () => callback(scope.connection));
88
96
  }
89
97
  return runOwnedKyselyTransaction(owner, async () => { }, (trx) => callback(trx));
90
98
  },
@@ -40,7 +40,7 @@ class KyselyTransactionRunner {
40
40
  if (scope) {
41
41
  // Nested: a savepoint on the outer transaction, so a failure rolls back
42
42
  // only this call. The outer transaction's timeouts stay in force.
43
- return kysely_transaction_context_js_1.kyselyTransactionScopes.runInSavepoint(this.db, scope, callback, (sql) => (0, kysely_transaction_context_js_1.executeRawStatement)(scope.connection, sql));
43
+ return (0, kysely_transaction_context_js_1.runInKyselySavepoint)(this.db, scope, callback);
44
44
  }
45
45
  return (0, kysely_transaction_context_js_1.runOwnedKyselyTransaction)(this.db, (trx) => this.applyTimeouts(trx), () => callback());
46
46
  }
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { KyselyWorkflowInstanceStore } from "./kysely-instance-store.js";
3
3
  import { KyselyWorkflowHistoryStore } from "./kysely-history-store.js";
4
4
  import { KyselyWorkflowDefinitionStore } from "./kysely-definition-store.js";
5
5
  import { KyselyTransactionRunner } from "./kysely-transaction-runner.js";
6
- import { executeRawStatement, kyselyTransactionScopes } from "./kysely-transaction-context.js";
6
+ import { kyselyTransactionScopes, runInKyselySavepoint } from "./kysely-transaction-context.js";
7
7
  export { KyselyTransactionContext } from "./kysely-transaction-context.js";
8
8
  export { KyselyTransactionRunner } from "./kysely-transaction-runner.js";
9
9
  export { KyselyWorkflowInstanceStore } from "./kysely-instance-store.js";
@@ -39,7 +39,7 @@ export function kyselyWorkflowProvidersFromTransaction(trx) {
39
39
  // provider must never supersede it.
40
40
  const scope = kyselyTransactionScopes.current(narrowed);
41
41
  if (scope) {
42
- return kyselyTransactionScopes.runInSavepoint(narrowed, scope, callback, (sql) => executeRawStatement(scope.connection, sql));
42
+ return runInKyselySavepoint(narrowed, scope, callback);
43
43
  }
44
44
  // The caller owns `trx`, so even this outermost call is nested in their
45
45
  // transaction: run it in a savepoint so a failure leaves no partial
@@ -48,7 +48,7 @@ export function kyselyWorkflowProvidersFromTransaction(trx) {
48
48
  // duraflows call they make joins `trx` as a savepoint, and the
49
49
  // callbacks it queues drain in the same pass.
50
50
  const root = kyselyTransactionScopes.createRoot(boundTrx);
51
- const result = await kyselyTransactionScopes.run(narrowed, root, () => kyselyTransactionScopes.runInSavepoint(narrowed, root, callback, (sql) => executeRawStatement(boundTrx, sql)));
51
+ const result = await kyselyTransactionScopes.run(narrowed, root, () => runInKyselySavepoint(narrowed, root, callback));
52
52
  await kyselyTransactionScopes.run(narrowed, root, () => runAfterCommitCallbacks(root.callbacks));
53
53
  return result;
54
54
  },
@@ -1,20 +1,15 @@
1
1
  import type { Kysely, Transaction } from "kysely";
2
- import { ScopedTransactionContext } from "@duraflows/core";
2
+ import { ScopedTransactionContext, type TransactionScope } from "@duraflows/core";
3
3
  import type { WorkflowDatabase } from "./kysely-database.js";
4
4
  type WorkflowTransaction = Transaction<WorkflowDatabase>;
5
5
  /** @internal Shared with the runners; not part of the public API. */
6
6
  export declare const kyselyTransactionScopes: ScopedTransactionContext<Kysely<WorkflowDatabase>, WorkflowTransaction>;
7
7
  /**
8
- * @internal Runs one fixed SQL statement (a savepoint command) on `trx`.
9
- *
10
- * `Transaction` has no savepoint API in kysely 0.29 (only `ControlledTransaction`
11
- * does), and this package imports kysely for types only, since kysely is
12
- * ESM-only and a runtime import would break the CommonJS build. So the
13
- * statement is handed to `executeQuery` as a compiled query built by hand,
14
- * shaped exactly like `CompiledQuery.raw(sql)`. `sql` is always an internally
15
- * generated `SAVEPOINT` / `RELEASE` / `ROLLBACK TO` statement, never user input.
8
+ * @internal Runs `callback` in a savepoint nested in `scope`, issuing the
9
+ * savepoint statements on that scope's own transaction. Every kysely entry
10
+ * point that nests (the runners and `transaction()`) goes through here.
16
11
  */
17
- export declare function executeRawStatement(trx: WorkflowTransaction, sql: string): Promise<unknown>;
12
+ export declare function runInKyselySavepoint<T>(owner: Kysely<WorkflowDatabase>, scope: TransactionScope<WorkflowTransaction>, callback: () => Promise<T>): Promise<T>;
18
13
  /**
19
14
  * @internal Runs `callback` as the root of a new kysely transaction on `db`
20
15
  * (after `setup`, e.g. transaction-local timeouts), and only once kysely has
@@ -5,7 +5,7 @@ import { ScopedTransactionContext, runAfterCommitCallbacks } from "@duraflows/co
5
5
  /** @internal Shared with the runners; not part of the public API. */
6
6
  export const kyselyTransactionScopes = new ScopedTransactionContext();
7
7
  /**
8
- * @internal Runs one fixed SQL statement (a savepoint command) on `trx`.
8
+ * Runs one fixed SQL statement (a savepoint command) on `trx`.
9
9
  *
10
10
  * `Transaction` has no savepoint API in kysely 0.29 (only `ControlledTransaction`
11
11
  * does), and this package imports kysely for types only, since kysely is
@@ -14,7 +14,7 @@ export const kyselyTransactionScopes = new ScopedTransactionContext();
14
14
  * shaped exactly like `CompiledQuery.raw(sql)`. `sql` is always an internally
15
15
  * generated `SAVEPOINT` / `RELEASE` / `ROLLBACK TO` statement, never user input.
16
16
  */
17
- export function executeRawStatement(trx, sql) {
17
+ function executeRawStatement(trx, sql) {
18
18
  const query = {
19
19
  sql,
20
20
  parameters: [],
@@ -23,6 +23,14 @@ export function executeRawStatement(trx, sql) {
23
23
  };
24
24
  return trx.executeQuery(query);
25
25
  }
26
+ /**
27
+ * @internal Runs `callback` in a savepoint nested in `scope`, issuing the
28
+ * savepoint statements on that scope's own transaction. Every kysely entry
29
+ * point that nests (the runners and `transaction()`) goes through here.
30
+ */
31
+ export function runInKyselySavepoint(owner, scope, callback) {
32
+ return kyselyTransactionScopes.runInSavepoint(owner, scope, callback, (sql) => executeRawStatement(scope.connection, sql));
33
+ }
26
34
  /**
27
35
  * @internal Runs `callback` as the root of a new kysely transaction on `db`
28
36
  * (after `setup`, e.g. transaction-local timeouts), and only once kysely has
@@ -79,7 +87,7 @@ export const KyselyTransactionContext = {
79
87
  const owner = db;
80
88
  const scope = kyselyTransactionScopes.current(owner);
81
89
  if (scope) {
82
- return kyselyTransactionScopes.runInSavepoint(owner, scope, () => callback(scope.connection), (sql) => executeRawStatement(scope.connection, sql));
90
+ return runInKyselySavepoint(owner, scope, () => callback(scope.connection));
83
91
  }
84
92
  return runOwnedKyselyTransaction(owner, async () => { }, (trx) => callback(trx));
85
93
  },
@@ -1,5 +1,5 @@
1
1
  import { WorkflowError } from "@duraflows/core";
2
- import { executeRawStatement, kyselyTransactionScopes, runOwnedKyselyTransaction, } from "./kysely-transaction-context.js";
2
+ import { kyselyTransactionScopes, runInKyselySavepoint, runOwnedKyselyTransaction, } from "./kysely-transaction-context.js";
3
3
  /**
4
4
  * Rejects anything that is not a finite, non-negative integer. Called at
5
5
  * construction time so an invalid value can never reach the database.
@@ -37,7 +37,7 @@ export class KyselyTransactionRunner {
37
37
  if (scope) {
38
38
  // Nested: a savepoint on the outer transaction, so a failure rolls back
39
39
  // only this call. The outer transaction's timeouts stay in force.
40
- return kyselyTransactionScopes.runInSavepoint(this.db, scope, callback, (sql) => executeRawStatement(scope.connection, sql));
40
+ return runInKyselySavepoint(this.db, scope, callback);
41
41
  }
42
42
  return runOwnedKyselyTransaction(this.db, (trx) => this.applyTimeouts(trx), () => callback());
43
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duraflows/kysely",
3
- "version": "5.2.0",
3
+ "version": "5.2.1",
4
4
  "description": "PostgreSQL persistence adapter for duraflows using `kysely`. Integrates with kysely's type-safe query builder and AsyncLocalStorage-based transaction context.",
5
5
  "keywords": [
6
6
  "duraflows",
@@ -51,15 +51,15 @@
51
51
  "access": "public"
52
52
  },
53
53
  "peerDependencies": {
54
- "@duraflows/core": "^5.2.0",
54
+ "@duraflows/core": "^5.2.1",
55
55
  "kysely": "^0.29.6"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/pg": "^8.23.1",
59
59
  "kysely": "^0.29.6",
60
60
  "pg": "^8.23.0",
61
- "@duraflows/core": "5.2.0",
62
- "@duraflows/pg": "5.2.0"
61
+ "@duraflows/core": "5.2.1",
62
+ "@duraflows/pg": "5.2.1"
63
63
  },
64
64
  "scripts": {
65
65
  "build": "tsc --build"