@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.
- package/README.md +127 -0
- package/dist/cjs/index.d.ts +24 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +53 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/kysely-database.d.ts +44 -0
- package/dist/cjs/kysely-database.d.ts.map +1 -0
- package/dist/cjs/kysely-database.js +3 -0
- package/dist/cjs/kysely-database.js.map +1 -0
- package/dist/cjs/kysely-history-store.d.ts +14 -0
- package/dist/cjs/kysely-history-store.d.ts.map +1 -0
- package/dist/cjs/kysely-history-store.js +56 -0
- package/dist/cjs/kysely-history-store.js.map +1 -0
- package/dist/cjs/kysely-instance-store.d.ts +15 -0
- package/dist/cjs/kysely-instance-store.d.ts.map +1 -0
- package/dist/cjs/kysely-instance-store.js +109 -0
- package/dist/cjs/kysely-instance-store.js.map +1 -0
- package/dist/cjs/kysely-transaction-context.d.ts +16 -0
- package/dist/cjs/kysely-transaction-context.d.ts.map +1 -0
- package/dist/cjs/kysely-transaction-context.js +23 -0
- package/dist/cjs/kysely-transaction-context.js.map +1 -0
- package/dist/cjs/kysely-transaction-runner.d.ts +9 -0
- package/dist/cjs/kysely-transaction-runner.d.ts.map +1 -0
- package/dist/cjs/kysely-transaction-runner.js +21 -0
- package/dist/cjs/kysely-transaction-runner.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/kysely-database.d.ts +44 -0
- package/dist/kysely-database.d.ts.map +1 -0
- package/dist/kysely-database.js +2 -0
- package/dist/kysely-database.js.map +1 -0
- package/dist/kysely-history-store.d.ts +14 -0
- package/dist/kysely-history-store.d.ts.map +1 -0
- package/dist/kysely-history-store.js +52 -0
- package/dist/kysely-history-store.js.map +1 -0
- package/dist/kysely-instance-store.d.ts +15 -0
- package/dist/kysely-instance-store.d.ts.map +1 -0
- package/dist/kysely-instance-store.js +105 -0
- package/dist/kysely-instance-store.js.map +1 -0
- package/dist/kysely-transaction-context.d.ts +16 -0
- package/dist/kysely-transaction-context.d.ts.map +1 -0
- package/dist/kysely-transaction-context.js +20 -0
- package/dist/kysely-transaction-context.js.map +1 -0
- package/dist/kysely-transaction-runner.d.ts +9 -0
- package/dist/kysely-transaction-runner.d.ts.map +1 -0
- package/dist/kysely-transaction-runner.js +17 -0
- package/dist/kysely-transaction-runner.js.map +1 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# @duraflows/kysely
|
|
2
|
+
|
|
3
|
+
[Kysely](https://kysely.dev/) persistence adapter for [duraflows](https://github.com/camcima/duraflows).
|
|
4
|
+
|
|
5
|
+
Part of the [duraflows](https://github.com/camcima/duraflows) monorepo.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Full implementation of `@duraflows/core` persistence interfaces using Kysely query builder
|
|
10
|
+
- Row-level locking with `SKIP LOCKED` for concurrent access safety
|
|
11
|
+
- JSONB storage for workflow context, metadata, and command results
|
|
12
|
+
- Transaction sharing via `AsyncLocalStorage` -- run Duraflows and your own queries in a single Kysely transaction
|
|
13
|
+
- Type-safe `WorkflowDatabase` interface for composing with your own Kysely database types
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @duraflows/core @duraflows/kysely kysely pg
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { WorkflowRuntime, InMemoryDefinitionRegistry, InMemoryCommandRegistry } from "@duraflows/core";
|
|
25
|
+
import { kyselyWorkflowProviders } from "@duraflows/kysely";
|
|
26
|
+
import { Kysely, PostgresDialect } from "kysely";
|
|
27
|
+
import { Pool } from "pg";
|
|
28
|
+
|
|
29
|
+
const db = new Kysely({
|
|
30
|
+
dialect: new PostgresDialect({ pool: new Pool({ connectionString: process.env.DATABASE_URL }) }),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const persistence = kyselyWorkflowProviders(db);
|
|
34
|
+
|
|
35
|
+
const runtime = new WorkflowRuntime({
|
|
36
|
+
definitionRegistry,
|
|
37
|
+
commandRegistry,
|
|
38
|
+
...persistence,
|
|
39
|
+
clock: { now: () => new Date() },
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Sharing a Transaction
|
|
44
|
+
|
|
45
|
+
The primary use case for this package is running Duraflows workflow transitions and your own database writes in a single atomic transaction.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { KyselyTransactionContext } from "@duraflows/kysely";
|
|
49
|
+
|
|
50
|
+
// Seed the transaction context so Duraflows participates in your transaction
|
|
51
|
+
await db.transaction().execute(async (trx) => {
|
|
52
|
+
await KyselyTransactionContext.run(trx, async () => {
|
|
53
|
+
// Your own writes -- uses trx
|
|
54
|
+
await trx.insertInto("orders").values({ id: "ORD-1", status: "paid" }).execute();
|
|
55
|
+
|
|
56
|
+
// Duraflows writes -- also uses trx (same transaction)
|
|
57
|
+
await runtime.triggerEvent({
|
|
58
|
+
workflowInstanceUuid: instanceUuid,
|
|
59
|
+
eventName: "PaymentReceived",
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
// Both commit or both rollback -- no split-brain
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### How It Works
|
|
67
|
+
|
|
68
|
+
`KyselyTransactionContext` uses Node.js `AsyncLocalStorage` to propagate the active Kysely transaction through the async call chain. When Duraflows' internal `WorkflowTransactionRunner.runInTransaction()` is called, it checks for an existing transaction in the context:
|
|
69
|
+
|
|
70
|
+
- **Found:** Reuses it (no nested transaction)
|
|
71
|
+
- **Not found:** Starts a new Kysely transaction and seeds the context
|
|
72
|
+
|
|
73
|
+
This re-entrancy contract means your application code controls the transaction boundary.
|
|
74
|
+
|
|
75
|
+
## Composing Database Types
|
|
76
|
+
|
|
77
|
+
Merge `WorkflowDatabase` with your own Kysely database type:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import type { WorkflowDatabase } from "@duraflows/kysely";
|
|
81
|
+
|
|
82
|
+
interface MyDatabase extends WorkflowDatabase {
|
|
83
|
+
orders: OrdersTable;
|
|
84
|
+
products: ProductsTable;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const db = new Kysely<MyDatabase>({ ... });
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Database Setup
|
|
91
|
+
|
|
92
|
+
This package uses the same database schema as `@duraflows/pg`. Use the migration generator from `@duraflows/pg` or copy the reference migration:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { generateMigrationSql } from "@duraflows/pg";
|
|
96
|
+
|
|
97
|
+
const { up, down } = generateMigrationSql();
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
See the [`@duraflows/pg` README](https://github.com/camcima/duraflows/tree/main/packages/duraflows-pg#database-setup) for full details.
|
|
101
|
+
|
|
102
|
+
## API
|
|
103
|
+
|
|
104
|
+
### `kyselyWorkflowProviders(db): WorkflowPersistenceProvider`
|
|
105
|
+
|
|
106
|
+
Factory function that creates all required persistence providers from a `Kysely<WorkflowDatabase>` instance. Returns:
|
|
107
|
+
|
|
108
|
+
- `instanceStore` -- `KyselyWorkflowInstanceStore`
|
|
109
|
+
- `historyStore` -- `KyselyWorkflowHistoryStore`
|
|
110
|
+
- `transactionRunner` -- `KyselyTransactionRunner`
|
|
111
|
+
|
|
112
|
+
### `kyselyWorkflowProvidersFromTransaction(trx): WorkflowPersistenceProvider`
|
|
113
|
+
|
|
114
|
+
Convenience factory for short-lived runtimes pre-bound to an existing transaction. The returned transaction runner seeds the context with the bound `trx` if no context already exists.
|
|
115
|
+
|
|
116
|
+
### `KyselyTransactionContext`
|
|
117
|
+
|
|
118
|
+
- `getTransaction()` -- Returns the active `Transaction<WorkflowDatabase>` or `undefined`
|
|
119
|
+
- `run(trx, callback)` -- Executes `callback` with `trx` as the active transaction context
|
|
120
|
+
|
|
121
|
+
## Documentation
|
|
122
|
+
|
|
123
|
+
See the full documentation in the [duraflows repository](https://github.com/camcima/duraflows).
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
|
|
127
|
+
MIT
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Kysely, Transaction } from "kysely";
|
|
2
|
+
import type { WorkflowPersistenceProvider } from "@duraflows/core";
|
|
3
|
+
import type { WorkflowDatabase } from "./kysely-database.js";
|
|
4
|
+
export { KyselyTransactionContext } from "./kysely-transaction-context.js";
|
|
5
|
+
export { KyselyTransactionRunner } from "./kysely-transaction-runner.js";
|
|
6
|
+
export { KyselyWorkflowInstanceStore } from "./kysely-instance-store.js";
|
|
7
|
+
export { KyselyWorkflowHistoryStore } from "./kysely-history-store.js";
|
|
8
|
+
export type { WorkflowDatabase, WorkflowInstancesTable, WorkflowHistoryTable } from "./kysely-database.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 declare function kyselyWorkflowProviders<DB extends WorkflowDatabase>(db: Kysely<DB>): WorkflowPersistenceProvider;
|
|
18
|
+
/**
|
|
19
|
+
* Creates providers pre-bound to an existing Kysely transaction.
|
|
20
|
+
*
|
|
21
|
+
* Generic so callers can pass `Transaction<MyDb & WorkflowDatabase>`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function kyselyWorkflowProvidersFromTransaction<DB extends WorkflowDatabase>(trx: Transaction<DB>): WorkflowPersistenceProvider;
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAM7D,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;AACvE,YAAY,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE3G;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,SAAS,gBAAgB,EACjE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,GACb,2BAA2B,CAM7B;AAED;;;;GAIG;AACH,wBAAgB,sCAAsC,CAAC,EAAE,SAAS,gBAAgB,EAChF,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC,GACnB,2BAA2B,CAc7B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KyselyWorkflowHistoryStore = exports.KyselyWorkflowInstanceStore = exports.KyselyTransactionRunner = exports.KyselyTransactionContext = void 0;
|
|
4
|
+
exports.kyselyWorkflowProviders = kyselyWorkflowProviders;
|
|
5
|
+
exports.kyselyWorkflowProvidersFromTransaction = kyselyWorkflowProvidersFromTransaction;
|
|
6
|
+
const kysely_instance_store_js_1 = require("./kysely-instance-store.js");
|
|
7
|
+
const kysely_history_store_js_1 = require("./kysely-history-store.js");
|
|
8
|
+
const kysely_transaction_runner_js_1 = require("./kysely-transaction-runner.js");
|
|
9
|
+
const kysely_transaction_context_js_1 = require("./kysely-transaction-context.js");
|
|
10
|
+
var kysely_transaction_context_js_2 = require("./kysely-transaction-context.js");
|
|
11
|
+
Object.defineProperty(exports, "KyselyTransactionContext", { enumerable: true, get: function () { return kysely_transaction_context_js_2.KyselyTransactionContext; } });
|
|
12
|
+
var kysely_transaction_runner_js_2 = require("./kysely-transaction-runner.js");
|
|
13
|
+
Object.defineProperty(exports, "KyselyTransactionRunner", { enumerable: true, get: function () { return kysely_transaction_runner_js_2.KyselyTransactionRunner; } });
|
|
14
|
+
var kysely_instance_store_js_2 = require("./kysely-instance-store.js");
|
|
15
|
+
Object.defineProperty(exports, "KyselyWorkflowInstanceStore", { enumerable: true, get: function () { return kysely_instance_store_js_2.KyselyWorkflowInstanceStore; } });
|
|
16
|
+
var kysely_history_store_js_2 = require("./kysely-history-store.js");
|
|
17
|
+
Object.defineProperty(exports, "KyselyWorkflowHistoryStore", { enumerable: true, get: function () { return kysely_history_store_js_2.KyselyWorkflowHistoryStore; } });
|
|
18
|
+
/**
|
|
19
|
+
* Creates long-lived persistence providers from a Kysely instance.
|
|
20
|
+
*
|
|
21
|
+
* Generic so callers can pass `Kysely<MyDb & WorkflowDatabase>`.
|
|
22
|
+
* Internally narrows to `Kysely<WorkflowDatabase>` (safe — stores
|
|
23
|
+
* only access workflow tables; the `unknown` cast is needed because
|
|
24
|
+
* Kysely is invariant in its DB type parameter).
|
|
25
|
+
*/
|
|
26
|
+
function kyselyWorkflowProviders(db) {
|
|
27
|
+
const narrowed = db;
|
|
28
|
+
const transactionRunner = new kysely_transaction_runner_js_1.KyselyTransactionRunner(narrowed);
|
|
29
|
+
const instanceStore = new kysely_instance_store_js_1.KyselyWorkflowInstanceStore(narrowed);
|
|
30
|
+
const historyStore = new kysely_history_store_js_1.KyselyWorkflowHistoryStore(narrowed);
|
|
31
|
+
return { instanceStore, historyStore, transactionRunner };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Creates providers pre-bound to an existing Kysely transaction.
|
|
35
|
+
*
|
|
36
|
+
* Generic so callers can pass `Transaction<MyDb & WorkflowDatabase>`.
|
|
37
|
+
*/
|
|
38
|
+
function kyselyWorkflowProvidersFromTransaction(trx) {
|
|
39
|
+
const narrowed = trx;
|
|
40
|
+
const transactionRunner = {
|
|
41
|
+
async runInTransaction(callback) {
|
|
42
|
+
const existing = kysely_transaction_context_js_1.KyselyTransactionContext.getTransaction();
|
|
43
|
+
if (existing) {
|
|
44
|
+
return callback();
|
|
45
|
+
}
|
|
46
|
+
return kysely_transaction_context_js_1.KyselyTransactionContext.run(trx, callback);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
const instanceStore = new kysely_instance_store_js_1.KyselyWorkflowInstanceStore(narrowed);
|
|
50
|
+
const historyStore = new kysely_history_store_js_1.KyselyWorkflowHistoryStore(narrowed);
|
|
51
|
+
return { instanceStore, historyStore, transactionRunner };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAsBA,0DAQC;AAOD,wFAgBC;AAlDD,yEAAyE;AACzE,uEAAuE;AACvE,iFAAyE;AACzE,mFAA2E;AAE3E,iFAA2E;AAAlE,yIAAA,wBAAwB,OAAA;AACjC,+EAAyE;AAAhE,uIAAA,uBAAuB,OAAA;AAChC,uEAAyE;AAAhE,uIAAA,2BAA2B,OAAA;AACpC,qEAAuE;AAA9D,qIAAA,0BAA0B,OAAA;AAGnC;;;;;;;GAOG;AACH,SAAgB,uBAAuB,CACrC,EAAc;IAEd,MAAM,QAAQ,GAAG,EAAyC,CAAC;IAC3D,MAAM,iBAAiB,GAAG,IAAI,sDAAuB,CAAC,QAAQ,CAAC,CAAC;IAChE,MAAM,aAAa,GAAG,IAAI,sDAA2B,CAAC,QAAQ,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,IAAI,oDAA0B,CAAC,QAAQ,CAAC,CAAC;IAC9D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAC5D,CAAC;AAED;;;;GAIG;AACH,SAAgB,sCAAsC,CACpD,GAAoB;IAEpB,MAAM,QAAQ,GAAG,GAA0C,CAAC;IAC5D,MAAM,iBAAiB,GAAqD;QAC1E,KAAK,CAAC,gBAAgB,CAAI,QAA0B;YAClD,MAAM,QAAQ,GAAG,wDAAwB,CAAC,cAAc,EAAE,CAAC;YAC3D,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,QAAQ,EAAE,CAAC;YACpB,CAAC;YACD,OAAO,wDAAwB,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACrD,CAAC;KACF,CAAC;IACF,MAAM,aAAa,GAAG,IAAI,sDAA2B,CAAC,QAAQ,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,IAAI,oDAA0B,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 @@
|
|
|
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,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KyselyWorkflowHistoryStore = void 0;
|
|
4
|
+
const kysely_transaction_context_js_1 = require("./kysely-transaction-context.js");
|
|
5
|
+
class KyselyWorkflowHistoryStore {
|
|
6
|
+
db;
|
|
7
|
+
constructor(db) {
|
|
8
|
+
this.db = db;
|
|
9
|
+
}
|
|
10
|
+
getExecutor() {
|
|
11
|
+
return kysely_transaction_context_js_1.KyselyTransactionContext.getTransaction() ?? this.db;
|
|
12
|
+
}
|
|
13
|
+
async append(entry) {
|
|
14
|
+
const executor = this.getExecutor();
|
|
15
|
+
const row = await executor
|
|
16
|
+
.insertInto("workflow_history")
|
|
17
|
+
.values({
|
|
18
|
+
workflow_instance_uuid: entry.workflowInstanceUuid,
|
|
19
|
+
from_state: entry.fromState,
|
|
20
|
+
event_name: entry.eventName,
|
|
21
|
+
to_state: entry.toState,
|
|
22
|
+
outcome: entry.outcome,
|
|
23
|
+
error_message: entry.errorMessage ?? null,
|
|
24
|
+
command_results_json: JSON.stringify(entry.commandResultsJson),
|
|
25
|
+
trigger_metadata_json: JSON.stringify(entry.triggerMetadata ?? {}),
|
|
26
|
+
})
|
|
27
|
+
.returning("uuid")
|
|
28
|
+
.executeTakeFirstOrThrow();
|
|
29
|
+
return row.uuid;
|
|
30
|
+
}
|
|
31
|
+
async findByInstanceUuid(workflowInstanceUuid, options) {
|
|
32
|
+
const executor = this.getExecutor();
|
|
33
|
+
const limit = options?.limit ?? 50;
|
|
34
|
+
const offset = options?.offset ?? 0;
|
|
35
|
+
const rows = await executor
|
|
36
|
+
.selectFrom("workflow_history")
|
|
37
|
+
.selectAll()
|
|
38
|
+
.where("workflow_instance_uuid", "=", workflowInstanceUuid)
|
|
39
|
+
.orderBy("created_at", "desc")
|
|
40
|
+
.limit(limit)
|
|
41
|
+
.offset(offset)
|
|
42
|
+
.execute();
|
|
43
|
+
return rows.map((row) => ({
|
|
44
|
+
workflowInstanceUuid: row.workflow_instance_uuid,
|
|
45
|
+
fromState: row.from_state,
|
|
46
|
+
eventName: row.event_name,
|
|
47
|
+
toState: row.to_state,
|
|
48
|
+
outcome: row.outcome,
|
|
49
|
+
errorMessage: row.error_message ?? undefined,
|
|
50
|
+
commandResultsJson: row.command_results_json,
|
|
51
|
+
triggerMetadata: row.trigger_metadata_json,
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.KyselyWorkflowHistoryStore = KyselyWorkflowHistoryStore;
|
|
56
|
+
//# 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,mFAA2E;AAE3E,MAAa,0BAA0B;IACR;IAA7B,YAA6B,EAA4B;QAA5B,OAAE,GAAF,EAAE,CAA0B;IAAG,CAAC;IAErD,WAAW;QACjB,OAAO,wDAAwB,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;AAvDD,gEAuDC"}
|
|
@@ -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,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KyselyWorkflowInstanceStore = void 0;
|
|
4
|
+
const core_1 = require("@duraflows/core");
|
|
5
|
+
const kysely_transaction_context_js_1 = require("./kysely-transaction-context.js");
|
|
6
|
+
class KyselyWorkflowInstanceStore {
|
|
7
|
+
db;
|
|
8
|
+
constructor(db) {
|
|
9
|
+
this.db = db;
|
|
10
|
+
}
|
|
11
|
+
getExecutor() {
|
|
12
|
+
return kysely_transaction_context_js_1.KyselyTransactionContext.getTransaction() ?? this.db;
|
|
13
|
+
}
|
|
14
|
+
async create(instance) {
|
|
15
|
+
const executor = this.getExecutor();
|
|
16
|
+
await executor
|
|
17
|
+
.insertInto("workflow_instances")
|
|
18
|
+
.values({
|
|
19
|
+
uuid: instance.uuid,
|
|
20
|
+
workflow_name: instance.workflowName,
|
|
21
|
+
current_state: instance.currentState,
|
|
22
|
+
version: instance.version,
|
|
23
|
+
expires_at: instance.expiresAt,
|
|
24
|
+
last_transition_at: instance.lastTransitionAt,
|
|
25
|
+
context_json: JSON.stringify(instance.context),
|
|
26
|
+
metadata_json: JSON.stringify(instance.metadata),
|
|
27
|
+
created_at: instance.createdAt,
|
|
28
|
+
updated_at: instance.updatedAt,
|
|
29
|
+
})
|
|
30
|
+
.execute();
|
|
31
|
+
}
|
|
32
|
+
async findByUuid(uuid) {
|
|
33
|
+
const executor = this.getExecutor();
|
|
34
|
+
const row = await executor.selectFrom("workflow_instances").selectAll().where("uuid", "=", uuid).executeTakeFirst();
|
|
35
|
+
if (!row)
|
|
36
|
+
return null;
|
|
37
|
+
return this.mapRow(row);
|
|
38
|
+
}
|
|
39
|
+
async lockByUuid(uuid) {
|
|
40
|
+
const trx = kysely_transaction_context_js_1.KyselyTransactionContext.getTransaction();
|
|
41
|
+
if (!trx) {
|
|
42
|
+
throw new Error("lockByUuid requires an active transaction");
|
|
43
|
+
}
|
|
44
|
+
const row = await trx
|
|
45
|
+
.selectFrom("workflow_instances")
|
|
46
|
+
.selectAll()
|
|
47
|
+
.where("uuid", "=", uuid)
|
|
48
|
+
.forUpdate()
|
|
49
|
+
.executeTakeFirst();
|
|
50
|
+
if (!row)
|
|
51
|
+
return null;
|
|
52
|
+
return this.mapRow(row);
|
|
53
|
+
}
|
|
54
|
+
async update(instance) {
|
|
55
|
+
const executor = this.getExecutor();
|
|
56
|
+
const expectedVersion = instance.version - 1;
|
|
57
|
+
const result = await executor
|
|
58
|
+
.updateTable("workflow_instances")
|
|
59
|
+
.set({
|
|
60
|
+
current_state: instance.currentState,
|
|
61
|
+
version: instance.version,
|
|
62
|
+
expires_at: instance.expiresAt,
|
|
63
|
+
last_transition_at: instance.lastTransitionAt,
|
|
64
|
+
context_json: JSON.stringify(instance.context),
|
|
65
|
+
metadata_json: JSON.stringify(instance.metadata),
|
|
66
|
+
updated_at: instance.updatedAt,
|
|
67
|
+
})
|
|
68
|
+
.where("uuid", "=", instance.uuid)
|
|
69
|
+
.where("version", "=", expectedVersion)
|
|
70
|
+
.execute();
|
|
71
|
+
const numUpdatedRows = result[0]?.numUpdatedRows ?? BigInt(0);
|
|
72
|
+
if (numUpdatedRows === BigInt(0)) {
|
|
73
|
+
throw new core_1.WorkflowError(`Optimistic locking failure: workflow instance "${instance.uuid}" was modified concurrently (expected version ${expectedVersion})`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async findExpired(limit, now) {
|
|
77
|
+
const trx = kysely_transaction_context_js_1.KyselyTransactionContext.getTransaction();
|
|
78
|
+
if (!trx) {
|
|
79
|
+
throw new Error("findExpired requires an active transaction");
|
|
80
|
+
}
|
|
81
|
+
const rows = await trx
|
|
82
|
+
.selectFrom("workflow_instances")
|
|
83
|
+
.selectAll()
|
|
84
|
+
.where("expires_at", "is not", null)
|
|
85
|
+
.where("expires_at", "<", now)
|
|
86
|
+
.orderBy("expires_at")
|
|
87
|
+
.forUpdate()
|
|
88
|
+
.skipLocked()
|
|
89
|
+
.limit(limit)
|
|
90
|
+
.execute();
|
|
91
|
+
return rows.map((row) => this.mapRow(row));
|
|
92
|
+
}
|
|
93
|
+
mapRow(row) {
|
|
94
|
+
return {
|
|
95
|
+
uuid: row.uuid,
|
|
96
|
+
workflowName: row.workflow_name,
|
|
97
|
+
currentState: row.current_state,
|
|
98
|
+
version: row.version,
|
|
99
|
+
expiresAt: row.expires_at,
|
|
100
|
+
lastTransitionAt: row.last_transition_at,
|
|
101
|
+
context: row.context_json,
|
|
102
|
+
metadata: row.metadata_json,
|
|
103
|
+
createdAt: row.created_at,
|
|
104
|
+
updatedAt: row.updated_at,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.KyselyWorkflowInstanceStore = KyselyWorkflowInstanceStore;
|
|
109
|
+
//# 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,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KyselyTransactionContext = void 0;
|
|
4
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
5
|
+
const storage = new node_async_hooks_1.AsyncLocalStorage();
|
|
6
|
+
exports.KyselyTransactionContext = {
|
|
7
|
+
getTransaction() {
|
|
8
|
+
return storage.getStore();
|
|
9
|
+
},
|
|
10
|
+
/**
|
|
11
|
+
* Executes callback with `trx` as the active transaction context.
|
|
12
|
+
*
|
|
13
|
+
* Generic so callers can pass `Transaction<MyDb & WorkflowDatabase>`
|
|
14
|
+
* (Kysely is invariant in DB, so a non-generic signature would reject
|
|
15
|
+
* intersection-typed transactions). The stored value is narrowed to
|
|
16
|
+
* `Transaction<WorkflowDatabase>` which is safe — stores only access
|
|
17
|
+
* workflow tables.
|
|
18
|
+
*/
|
|
19
|
+
run(trx, callback) {
|
|
20
|
+
return storage.run(trx, callback);
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
//# 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,uDAAqD;AAIrD,MAAM,OAAO,GAAG,IAAI,oCAAiB,EAAiC,CAAC;AAE1D,QAAA,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,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KyselyTransactionRunner = void 0;
|
|
4
|
+
const kysely_transaction_context_js_1 = require("./kysely-transaction-context.js");
|
|
5
|
+
class KyselyTransactionRunner {
|
|
6
|
+
db;
|
|
7
|
+
constructor(db) {
|
|
8
|
+
this.db = db;
|
|
9
|
+
}
|
|
10
|
+
async runInTransaction(callback) {
|
|
11
|
+
const existing = kysely_transaction_context_js_1.KyselyTransactionContext.getTransaction();
|
|
12
|
+
if (existing) {
|
|
13
|
+
return callback();
|
|
14
|
+
}
|
|
15
|
+
return this.db.transaction().execute(async (trx) => {
|
|
16
|
+
return kysely_transaction_context_js_1.KyselyTransactionContext.run(trx, callback);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.KyselyTransactionRunner = KyselyTransactionRunner;
|
|
21
|
+
//# 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,mFAA2E;AAE3E,MAAa,uBAAuB;IACL;IAA7B,YAA6B,EAA4B;QAA5B,OAAE,GAAF,EAAE,CAA0B;IAAG,CAAC;IAE7D,KAAK,CAAC,gBAAgB,CAAI,QAA0B;QAClD,MAAM,QAAQ,GAAG,wDAAwB,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,wDAAwB,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAbD,0DAaC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Kysely, Transaction } from "kysely";
|
|
2
|
+
import type { WorkflowPersistenceProvider } from "@duraflows/core";
|
|
3
|
+
import type { WorkflowDatabase } from "./kysely-database.js";
|
|
4
|
+
export { KyselyTransactionContext } from "./kysely-transaction-context.js";
|
|
5
|
+
export { KyselyTransactionRunner } from "./kysely-transaction-runner.js";
|
|
6
|
+
export { KyselyWorkflowInstanceStore } from "./kysely-instance-store.js";
|
|
7
|
+
export { KyselyWorkflowHistoryStore } from "./kysely-history-store.js";
|
|
8
|
+
export type { WorkflowDatabase, WorkflowInstancesTable, WorkflowHistoryTable } from "./kysely-database.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 declare function kyselyWorkflowProviders<DB extends WorkflowDatabase>(db: Kysely<DB>): WorkflowPersistenceProvider;
|
|
18
|
+
/**
|
|
19
|
+
* Creates providers pre-bound to an existing Kysely transaction.
|
|
20
|
+
*
|
|
21
|
+
* Generic so callers can pass `Transaction<MyDb & WorkflowDatabase>`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function kyselyWorkflowProvidersFromTransaction<DB extends WorkflowDatabase>(trx: Transaction<DB>): WorkflowPersistenceProvider;
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAM7D,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;AACvE,YAAY,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE3G;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,SAAS,gBAAgB,EACjE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,GACb,2BAA2B,CAM7B;AAED;;;;GAIG;AACH,wBAAgB,sCAAsC,CAAC,EAAE,SAAS,gBAAgB,EAChF,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC,GACnB,2BAA2B,CAc7B"}
|