@duraflows/kysely 0.4.0

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.
Files changed (52) hide show
  1. package/README.md +127 -0
  2. package/dist/cjs/index.d.ts +24 -0
  3. package/dist/cjs/index.d.ts.map +1 -0
  4. package/dist/cjs/index.js +53 -0
  5. package/dist/cjs/index.js.map +1 -0
  6. package/dist/cjs/kysely-database.d.ts +44 -0
  7. package/dist/cjs/kysely-database.d.ts.map +1 -0
  8. package/dist/cjs/kysely-database.js +3 -0
  9. package/dist/cjs/kysely-database.js.map +1 -0
  10. package/dist/cjs/kysely-history-store.d.ts +14 -0
  11. package/dist/cjs/kysely-history-store.d.ts.map +1 -0
  12. package/dist/cjs/kysely-history-store.js +56 -0
  13. package/dist/cjs/kysely-history-store.js.map +1 -0
  14. package/dist/cjs/kysely-instance-store.d.ts +15 -0
  15. package/dist/cjs/kysely-instance-store.d.ts.map +1 -0
  16. package/dist/cjs/kysely-instance-store.js +109 -0
  17. package/dist/cjs/kysely-instance-store.js.map +1 -0
  18. package/dist/cjs/kysely-transaction-context.d.ts +16 -0
  19. package/dist/cjs/kysely-transaction-context.d.ts.map +1 -0
  20. package/dist/cjs/kysely-transaction-context.js +23 -0
  21. package/dist/cjs/kysely-transaction-context.js.map +1 -0
  22. package/dist/cjs/kysely-transaction-runner.d.ts +9 -0
  23. package/dist/cjs/kysely-transaction-runner.d.ts.map +1 -0
  24. package/dist/cjs/kysely-transaction-runner.js +21 -0
  25. package/dist/cjs/kysely-transaction-runner.js.map +1 -0
  26. package/dist/cjs/package.json +1 -0
  27. package/dist/index.d.ts +24 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +44 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/kysely-database.d.ts +44 -0
  32. package/dist/kysely-database.d.ts.map +1 -0
  33. package/dist/kysely-database.js +2 -0
  34. package/dist/kysely-database.js.map +1 -0
  35. package/dist/kysely-history-store.d.ts +14 -0
  36. package/dist/kysely-history-store.d.ts.map +1 -0
  37. package/dist/kysely-history-store.js +52 -0
  38. package/dist/kysely-history-store.js.map +1 -0
  39. package/dist/kysely-instance-store.d.ts +15 -0
  40. package/dist/kysely-instance-store.d.ts.map +1 -0
  41. package/dist/kysely-instance-store.js +105 -0
  42. package/dist/kysely-instance-store.js.map +1 -0
  43. package/dist/kysely-transaction-context.d.ts +16 -0
  44. package/dist/kysely-transaction-context.d.ts.map +1 -0
  45. package/dist/kysely-transaction-context.js +20 -0
  46. package/dist/kysely-transaction-context.js.map +1 -0
  47. package/dist/kysely-transaction-runner.d.ts +9 -0
  48. package/dist/kysely-transaction-runner.d.ts.map +1 -0
  49. package/dist/kysely-transaction-runner.js +17 -0
  50. package/dist/kysely-transaction-runner.js.map +1 -0
  51. package/dist/tsconfig.cjs.tsbuildinfo +1 -0
  52. package/package.json +35 -0
package/dist/index.js ADDED
@@ -0,0 +1,44 @@
1
+ import { KyselyWorkflowInstanceStore } from "./kysely-instance-store.js";
2
+ import { KyselyWorkflowHistoryStore } from "./kysely-history-store.js";
3
+ import { KyselyTransactionRunner } from "./kysely-transaction-runner.js";
4
+ import { KyselyTransactionContext } from "./kysely-transaction-context.js";
5
+ export { KyselyTransactionContext } from "./kysely-transaction-context.js";
6
+ export { KyselyTransactionRunner } from "./kysely-transaction-runner.js";
7
+ export { KyselyWorkflowInstanceStore } from "./kysely-instance-store.js";
8
+ export { KyselyWorkflowHistoryStore } from "./kysely-history-store.js";
9
+ /**
10
+ * Creates long-lived persistence providers from a Kysely instance.
11
+ *
12
+ * Generic so callers can pass `Kysely<MyDb & WorkflowDatabase>`.
13
+ * Internally narrows to `Kysely<WorkflowDatabase>` (safe — stores
14
+ * only access workflow tables; the `unknown` cast is needed because
15
+ * Kysely is invariant in its DB type parameter).
16
+ */
17
+ export function kyselyWorkflowProviders(db) {
18
+ const narrowed = db;
19
+ const transactionRunner = new KyselyTransactionRunner(narrowed);
20
+ const instanceStore = new KyselyWorkflowInstanceStore(narrowed);
21
+ const historyStore = new KyselyWorkflowHistoryStore(narrowed);
22
+ return { instanceStore, historyStore, transactionRunner };
23
+ }
24
+ /**
25
+ * Creates providers pre-bound to an existing Kysely transaction.
26
+ *
27
+ * Generic so callers can pass `Transaction<MyDb & WorkflowDatabase>`.
28
+ */
29
+ export function kyselyWorkflowProvidersFromTransaction(trx) {
30
+ const narrowed = trx;
31
+ const transactionRunner = {
32
+ async runInTransaction(callback) {
33
+ const existing = KyselyTransactionContext.getTransaction();
34
+ if (existing) {
35
+ return callback();
36
+ }
37
+ return KyselyTransactionContext.run(trx, callback);
38
+ },
39
+ };
40
+ const instanceStore = new KyselyWorkflowInstanceStore(narrowed);
41
+ const historyStore = new KyselyWorkflowHistoryStore(narrowed);
42
+ return { instanceStore, historyStore, transactionRunner };
43
+ }
44
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAGvE;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CACrC,EAAc;IAEd,MAAM,QAAQ,GAAG,EAAyC,CAAC;IAC3D,MAAM,iBAAiB,GAAG,IAAI,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAChE,MAAM,aAAa,GAAG,IAAI,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,IAAI,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IAC9D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAC5D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sCAAsC,CACpD,GAAoB;IAEpB,MAAM,QAAQ,GAAG,GAA0C,CAAC;IAC5D,MAAM,iBAAiB,GAAqD;QAC1E,KAAK,CAAC,gBAAgB,CAAI,QAA0B;YAClD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,cAAc,EAAE,CAAC;YAC3D,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,QAAQ,EAAE,CAAC;YACpB,CAAC;YACD,OAAO,wBAAwB,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACrD,CAAC;KACF,CAAC;IACF,MAAM,aAAa,GAAG,IAAI,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,IAAI,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IAC9D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { ColumnType, Generated } from "kysely";
2
+ /**
3
+ * JSON column type that accepts Record<string, unknown> in TS
4
+ * but is stored as JSONB in PostgreSQL.
5
+ *
6
+ * - Select: returns parsed object
7
+ * - Insert: accepts string (caller uses JSON.stringify)
8
+ * - Update: accepts string (caller uses JSON.stringify)
9
+ */
10
+ type JsonObjectColumn = ColumnType<Record<string, unknown>, string, string>;
11
+ /**
12
+ * JSON array column type for command_results_json.
13
+ */
14
+ type JsonArrayColumn = ColumnType<Record<string, unknown>[], string, string>;
15
+ export interface WorkflowInstancesTable {
16
+ uuid: string;
17
+ workflow_name: string;
18
+ current_state: string;
19
+ version: number;
20
+ expires_at: Date | null;
21
+ last_transition_at: Date;
22
+ context_json: JsonObjectColumn;
23
+ metadata_json: JsonObjectColumn;
24
+ created_at: Generated<Date>;
25
+ updated_at: Generated<Date>;
26
+ }
27
+ export interface WorkflowHistoryTable {
28
+ uuid: Generated<string>;
29
+ workflow_instance_uuid: string;
30
+ from_state: string | null;
31
+ event_name: string;
32
+ to_state: string;
33
+ outcome: string;
34
+ error_message: string | null;
35
+ command_results_json: JsonArrayColumn;
36
+ trigger_metadata_json: JsonObjectColumn;
37
+ created_at: Generated<Date>;
38
+ }
39
+ export interface WorkflowDatabase {
40
+ workflow_instances: WorkflowInstancesTable;
41
+ workflow_history: WorkflowHistoryTable;
42
+ }
43
+ export {};
44
+ //# sourceMappingURL=kysely-database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely-database.d.ts","sourceRoot":"","sources":["../src/kysely-database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEpD;;;;;;;GAOG;AACH,KAAK,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE5E;;GAEG;AACH,KAAK,eAAe,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE7E,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,kBAAkB,EAAE,IAAI,CAAC;IACzB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,aAAa,EAAE,gBAAgB,CAAC;IAChC,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IAC5B,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,oBAAoB,EAAE,eAAe,CAAC;IACtC,qBAAqB,EAAE,gBAAgB,CAAC;IACxC,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB,EAAE,sBAAsB,CAAC;IAC3C,gBAAgB,EAAE,oBAAoB,CAAC;CACxC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=kysely-database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely-database.js","sourceRoot":"","sources":["../src/kysely-database.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import type { Kysely } from "kysely";
2
+ import type { WorkflowHistoryStore, WorkflowHistoryRecord } from "@duraflows/core";
3
+ import type { WorkflowDatabase } from "./kysely-database.js";
4
+ export declare class KyselyWorkflowHistoryStore implements WorkflowHistoryStore {
5
+ private readonly db;
6
+ constructor(db: Kysely<WorkflowDatabase>);
7
+ private getExecutor;
8
+ append(entry: WorkflowHistoryRecord): Promise<string>;
9
+ findByInstanceUuid(workflowInstanceUuid: string, options?: {
10
+ limit?: number;
11
+ offset?: number;
12
+ }): Promise<WorkflowHistoryRecord[]>;
13
+ }
14
+ //# sourceMappingURL=kysely-history-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely-history-store.d.ts","sourceRoot":"","sources":["../src/kysely-history-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,qBAAa,0BAA2B,YAAW,oBAAoB;IACzD,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,MAAM,CAAC,gBAAgB,CAAC;IAEzD,OAAO,CAAC,WAAW;IAIb,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBrD,kBAAkB,CACtB,oBAAoB,EAAE,MAAM,EAC5B,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5C,OAAO,CAAC,qBAAqB,EAAE,CAAC;CAyBpC"}
@@ -0,0 +1,52 @@
1
+ import { KyselyTransactionContext } from "./kysely-transaction-context.js";
2
+ export class KyselyWorkflowHistoryStore {
3
+ db;
4
+ constructor(db) {
5
+ this.db = db;
6
+ }
7
+ getExecutor() {
8
+ return KyselyTransactionContext.getTransaction() ?? this.db;
9
+ }
10
+ async append(entry) {
11
+ const executor = this.getExecutor();
12
+ const row = await executor
13
+ .insertInto("workflow_history")
14
+ .values({
15
+ workflow_instance_uuid: entry.workflowInstanceUuid,
16
+ from_state: entry.fromState,
17
+ event_name: entry.eventName,
18
+ to_state: entry.toState,
19
+ outcome: entry.outcome,
20
+ error_message: entry.errorMessage ?? null,
21
+ command_results_json: JSON.stringify(entry.commandResultsJson),
22
+ trigger_metadata_json: JSON.stringify(entry.triggerMetadata ?? {}),
23
+ })
24
+ .returning("uuid")
25
+ .executeTakeFirstOrThrow();
26
+ return row.uuid;
27
+ }
28
+ async findByInstanceUuid(workflowInstanceUuid, options) {
29
+ const executor = this.getExecutor();
30
+ const limit = options?.limit ?? 50;
31
+ const offset = options?.offset ?? 0;
32
+ const rows = await executor
33
+ .selectFrom("workflow_history")
34
+ .selectAll()
35
+ .where("workflow_instance_uuid", "=", workflowInstanceUuid)
36
+ .orderBy("created_at", "desc")
37
+ .limit(limit)
38
+ .offset(offset)
39
+ .execute();
40
+ return rows.map((row) => ({
41
+ workflowInstanceUuid: row.workflow_instance_uuid,
42
+ fromState: row.from_state,
43
+ eventName: row.event_name,
44
+ toState: row.to_state,
45
+ outcome: row.outcome,
46
+ errorMessage: row.error_message ?? undefined,
47
+ commandResultsJson: row.command_results_json,
48
+ triggerMetadata: row.trigger_metadata_json,
49
+ }));
50
+ }
51
+ }
52
+ //# sourceMappingURL=kysely-history-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely-history-store.js","sourceRoot":"","sources":["../src/kysely-history-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,MAAM,OAAO,0BAA0B;IACR;IAA7B,YAA6B,EAA4B;QAA5B,OAAE,GAAF,EAAE,CAA0B;IAAG,CAAC;IAErD,WAAW;QACjB,OAAO,wBAAwB,CAAC,cAAc,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAA4B;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,MAAM,QAAQ;aACvB,UAAU,CAAC,kBAAkB,CAAC;aAC9B,MAAM,CAAC;YACN,sBAAsB,EAAE,KAAK,CAAC,oBAAoB;YAClD,UAAU,EAAE,KAAK,CAAC,SAAS;YAC3B,UAAU,EAAE,KAAK,CAAC,SAAS;YAC3B,QAAQ,EAAE,KAAK,CAAC,OAAO;YACvB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,aAAa,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI;YACzC,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,kBAAkB,CAAC;YAC9D,qBAAqB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,eAAe,IAAI,EAAE,CAAC;SACnE,CAAC;aACD,SAAS,CAAC,MAAM,CAAC;aACjB,uBAAuB,EAAE,CAAC;QAE7B,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,kBAAkB,CACtB,oBAA4B,EAC5B,OAA6C;QAE7C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,CAAC,CAAC;QAEpC,MAAM,IAAI,GAAG,MAAM,QAAQ;aACxB,UAAU,CAAC,kBAAkB,CAAC;aAC9B,SAAS,EAAE;aACX,KAAK,CAAC,wBAAwB,EAAE,GAAG,EAAE,oBAAoB,CAAC;aAC1D,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC;aAC7B,KAAK,CAAC,KAAK,CAAC;aACZ,MAAM,CAAC,MAAM,CAAC;aACd,OAAO,EAAE,CAAC;QAEb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACxB,oBAAoB,EAAE,GAAG,CAAC,sBAAsB;YAChD,SAAS,EAAE,GAAG,CAAC,UAAU;YACzB,SAAS,EAAE,GAAG,CAAC,UAAU;YACzB,OAAO,EAAE,GAAG,CAAC,QAAQ;YACrB,OAAO,EAAE,GAAG,CAAC,OAAgC;YAC7C,YAAY,EAAE,GAAG,CAAC,aAAa,IAAI,SAAS;YAC5C,kBAAkB,EAAE,GAAG,CAAC,oBAA8E;YACtG,eAAe,EAAE,GAAG,CAAC,qBAA4D;SAClF,CAAC,CAAC,CAAC;IACN,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import type { Kysely } from "kysely";
2
+ import type { WorkflowInstanceStore, WorkflowInstance } from "@duraflows/core";
3
+ import type { WorkflowDatabase } from "./kysely-database.js";
4
+ export declare class KyselyWorkflowInstanceStore implements WorkflowInstanceStore {
5
+ private readonly db;
6
+ constructor(db: Kysely<WorkflowDatabase>);
7
+ private getExecutor;
8
+ create(instance: WorkflowInstance): Promise<void>;
9
+ findByUuid(uuid: string): Promise<WorkflowInstance | null>;
10
+ lockByUuid(uuid: string): Promise<WorkflowInstance | null>;
11
+ update(instance: WorkflowInstance): Promise<void>;
12
+ findExpired(limit: number, now: Date): Promise<WorkflowInstance[]>;
13
+ private mapRow;
14
+ }
15
+ //# sourceMappingURL=kysely-instance-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely-instance-store.d.ts","sourceRoot":"","sources":["../src/kysely-instance-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE/E,OAAO,KAAK,EAAE,gBAAgB,EAA0B,MAAM,sBAAsB,CAAC;AAGrF,qBAAa,2BAA4B,YAAW,qBAAqB;IAC3D,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,MAAM,CAAC,gBAAgB,CAAC;IAEzD,OAAO,CAAC,WAAW;IAIb,MAAM,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBjD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAQ1D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAgB1D,MAAM,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BjD,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAmBxE,OAAO,CAAC,MAAM;CAcf"}
@@ -0,0 +1,105 @@
1
+ import { WorkflowError } from "@duraflows/core";
2
+ import { KyselyTransactionContext } from "./kysely-transaction-context.js";
3
+ export class KyselyWorkflowInstanceStore {
4
+ db;
5
+ constructor(db) {
6
+ this.db = db;
7
+ }
8
+ getExecutor() {
9
+ return KyselyTransactionContext.getTransaction() ?? this.db;
10
+ }
11
+ async create(instance) {
12
+ const executor = this.getExecutor();
13
+ await executor
14
+ .insertInto("workflow_instances")
15
+ .values({
16
+ uuid: instance.uuid,
17
+ workflow_name: instance.workflowName,
18
+ current_state: instance.currentState,
19
+ version: instance.version,
20
+ expires_at: instance.expiresAt,
21
+ last_transition_at: instance.lastTransitionAt,
22
+ context_json: JSON.stringify(instance.context),
23
+ metadata_json: JSON.stringify(instance.metadata),
24
+ created_at: instance.createdAt,
25
+ updated_at: instance.updatedAt,
26
+ })
27
+ .execute();
28
+ }
29
+ async findByUuid(uuid) {
30
+ const executor = this.getExecutor();
31
+ const row = await executor.selectFrom("workflow_instances").selectAll().where("uuid", "=", uuid).executeTakeFirst();
32
+ if (!row)
33
+ return null;
34
+ return this.mapRow(row);
35
+ }
36
+ async lockByUuid(uuid) {
37
+ const trx = KyselyTransactionContext.getTransaction();
38
+ if (!trx) {
39
+ throw new Error("lockByUuid requires an active transaction");
40
+ }
41
+ const row = await trx
42
+ .selectFrom("workflow_instances")
43
+ .selectAll()
44
+ .where("uuid", "=", uuid)
45
+ .forUpdate()
46
+ .executeTakeFirst();
47
+ if (!row)
48
+ return null;
49
+ return this.mapRow(row);
50
+ }
51
+ async update(instance) {
52
+ const executor = this.getExecutor();
53
+ const expectedVersion = instance.version - 1;
54
+ const result = await executor
55
+ .updateTable("workflow_instances")
56
+ .set({
57
+ current_state: instance.currentState,
58
+ version: instance.version,
59
+ expires_at: instance.expiresAt,
60
+ last_transition_at: instance.lastTransitionAt,
61
+ context_json: JSON.stringify(instance.context),
62
+ metadata_json: JSON.stringify(instance.metadata),
63
+ updated_at: instance.updatedAt,
64
+ })
65
+ .where("uuid", "=", instance.uuid)
66
+ .where("version", "=", expectedVersion)
67
+ .execute();
68
+ const numUpdatedRows = result[0]?.numUpdatedRows ?? BigInt(0);
69
+ if (numUpdatedRows === BigInt(0)) {
70
+ throw new WorkflowError(`Optimistic locking failure: workflow instance "${instance.uuid}" was modified concurrently (expected version ${expectedVersion})`);
71
+ }
72
+ }
73
+ async findExpired(limit, now) {
74
+ const trx = KyselyTransactionContext.getTransaction();
75
+ if (!trx) {
76
+ throw new Error("findExpired requires an active transaction");
77
+ }
78
+ const rows = await trx
79
+ .selectFrom("workflow_instances")
80
+ .selectAll()
81
+ .where("expires_at", "is not", null)
82
+ .where("expires_at", "<", now)
83
+ .orderBy("expires_at")
84
+ .forUpdate()
85
+ .skipLocked()
86
+ .limit(limit)
87
+ .execute();
88
+ return rows.map((row) => this.mapRow(row));
89
+ }
90
+ mapRow(row) {
91
+ return {
92
+ uuid: row.uuid,
93
+ workflowName: row.workflow_name,
94
+ currentState: row.current_state,
95
+ version: row.version,
96
+ expiresAt: row.expires_at,
97
+ lastTransitionAt: row.last_transition_at,
98
+ context: row.context_json,
99
+ metadata: row.metadata_json,
100
+ createdAt: row.created_at,
101
+ updatedAt: row.updated_at,
102
+ };
103
+ }
104
+ }
105
+ //# sourceMappingURL=kysely-instance-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely-instance-store.js","sourceRoot":"","sources":["../src/kysely-instance-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Transaction } from "kysely";
2
+ import type { WorkflowDatabase } from "./kysely-database.js";
3
+ export declare const KyselyTransactionContext: {
4
+ getTransaction(): Transaction<WorkflowDatabase> | undefined;
5
+ /**
6
+ * Executes callback with `trx` as the active transaction context.
7
+ *
8
+ * Generic so callers can pass `Transaction<MyDb & WorkflowDatabase>`
9
+ * (Kysely is invariant in DB, so a non-generic signature would reject
10
+ * intersection-typed transactions). The stored value is narrowed to
11
+ * `Transaction<WorkflowDatabase>` which is safe — stores only access
12
+ * workflow tables.
13
+ */
14
+ run<T, DB extends WorkflowDatabase = WorkflowDatabase>(trx: Transaction<DB>, callback: () => T): T;
15
+ };
16
+ //# sourceMappingURL=kysely-transaction-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely-transaction-context.d.ts","sourceRoot":"","sources":["../src/kysely-transaction-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAI7D,eAAO,MAAM,wBAAwB;sBACjB,WAAW,CAAC,gBAAgB,CAAC,GAAG,SAAS;IAI3D;;;;;;;;OAQG;QACC,CAAC,EAAE,EAAE,SAAS,gBAAgB,0BAC3B,WAAW,CAAC,EAAE,CAAC,YACV,MAAM,CAAC,GAChB,CAAC;CAGL,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ const storage = new AsyncLocalStorage();
3
+ export const KyselyTransactionContext = {
4
+ getTransaction() {
5
+ return storage.getStore();
6
+ },
7
+ /**
8
+ * Executes callback with `trx` as the active transaction context.
9
+ *
10
+ * Generic so callers can pass `Transaction<MyDb & WorkflowDatabase>`
11
+ * (Kysely is invariant in DB, so a non-generic signature would reject
12
+ * intersection-typed transactions). The stored value is narrowed to
13
+ * `Transaction<WorkflowDatabase>` which is safe — stores only access
14
+ * workflow tables.
15
+ */
16
+ run(trx, callback) {
17
+ return storage.run(trx, callback);
18
+ },
19
+ };
20
+ //# sourceMappingURL=kysely-transaction-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely-transaction-context.js","sourceRoot":"","sources":["../src/kysely-transaction-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAIrD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAiC,CAAC;AAEvE,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,cAAc;QACZ,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC;IAED;;;;;;;;OAQG;IACH,GAAG,CACD,GAAoB,EACpB,QAAiB;QAEjB,OAAO,OAAO,CAAC,GAAG,CAAC,GAA+C,EAAE,QAAQ,CAAC,CAAC;IAChF,CAAC;CACF,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Kysely } from "kysely";
2
+ import type { WorkflowTransactionRunner } from "@duraflows/core";
3
+ import type { WorkflowDatabase } from "./kysely-database.js";
4
+ export declare class KyselyTransactionRunner implements WorkflowTransactionRunner {
5
+ private readonly db;
6
+ constructor(db: Kysely<WorkflowDatabase>);
7
+ runInTransaction<T>(callback: () => Promise<T>): Promise<T>;
8
+ }
9
+ //# sourceMappingURL=kysely-transaction-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely-transaction-runner.d.ts","sourceRoot":"","sources":["../src/kysely-transaction-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,qBAAa,uBAAwB,YAAW,yBAAyB;IAC3D,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,MAAM,CAAC,gBAAgB,CAAC;IAEnD,gBAAgB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAUlE"}
@@ -0,0 +1,17 @@
1
+ import { KyselyTransactionContext } from "./kysely-transaction-context.js";
2
+ export class KyselyTransactionRunner {
3
+ db;
4
+ constructor(db) {
5
+ this.db = db;
6
+ }
7
+ async runInTransaction(callback) {
8
+ const existing = KyselyTransactionContext.getTransaction();
9
+ if (existing) {
10
+ return callback();
11
+ }
12
+ return this.db.transaction().execute(async (trx) => {
13
+ return KyselyTransactionContext.run(trx, callback);
14
+ });
15
+ }
16
+ }
17
+ //# sourceMappingURL=kysely-transaction-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely-transaction-runner.js","sourceRoot":"","sources":["../src/kysely-transaction-runner.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,MAAM,OAAO,uBAAuB;IACL;IAA7B,YAA6B,EAA4B;QAA5B,OAAE,GAAF,EAAE,CAA0B;IAAG,CAAC;IAE7D,KAAK,CAAC,gBAAgB,CAAI,QAA0B;QAClD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,cAAc,EAAE,CAAC;QAC3D,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,EAAE,CAAC;QACpB,CAAC;QAED,OAAO,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACjD,OAAO,wBAAwB,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}