@kylebegeman/pulse 0.3.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 (62) hide show
  1. package/README.md +1078 -0
  2. package/dist/cron.d.ts +16 -0
  3. package/dist/cron.d.ts.map +1 -0
  4. package/dist/cron.js +32 -0
  5. package/dist/cron.js.map +1 -0
  6. package/dist/executor.d.ts +43 -0
  7. package/dist/executor.d.ts.map +1 -0
  8. package/dist/executor.js +333 -0
  9. package/dist/executor.js.map +1 -0
  10. package/dist/index.d.ts +4 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +198 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/logs.d.ts +11 -0
  15. package/dist/logs.d.ts.map +1 -0
  16. package/dist/logs.js +25 -0
  17. package/dist/logs.js.map +1 -0
  18. package/dist/matcher.d.ts +23 -0
  19. package/dist/matcher.d.ts.map +1 -0
  20. package/dist/matcher.js +184 -0
  21. package/dist/matcher.js.map +1 -0
  22. package/dist/queue.d.ts +42 -0
  23. package/dist/queue.d.ts.map +1 -0
  24. package/dist/queue.js +85 -0
  25. package/dist/queue.js.map +1 -0
  26. package/dist/registry.d.ts +23 -0
  27. package/dist/registry.d.ts.map +1 -0
  28. package/dist/registry.js +33 -0
  29. package/dist/registry.js.map +1 -0
  30. package/dist/replay.d.ts +10 -0
  31. package/dist/replay.d.ts.map +1 -0
  32. package/dist/replay.js +24 -0
  33. package/dist/replay.js.map +1 -0
  34. package/dist/runs.d.ts +37 -0
  35. package/dist/runs.d.ts.map +1 -0
  36. package/dist/runs.js +296 -0
  37. package/dist/runs.js.map +1 -0
  38. package/dist/scheduler.d.ts +21 -0
  39. package/dist/scheduler.d.ts.map +1 -0
  40. package/dist/scheduler.js +67 -0
  41. package/dist/scheduler.js.map +1 -0
  42. package/dist/schema/migrate.d.ts +3 -0
  43. package/dist/schema/migrate.d.ts.map +1 -0
  44. package/dist/schema/migrate.js +56 -0
  45. package/dist/schema/migrate.js.map +1 -0
  46. package/dist/schema/tables.d.ts +10 -0
  47. package/dist/schema/tables.d.ts.map +1 -0
  48. package/dist/schema/tables.js +123 -0
  49. package/dist/schema/tables.js.map +1 -0
  50. package/dist/types.d.ts +186 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +2 -0
  53. package/dist/types.js.map +1 -0
  54. package/dist/utils/errors.d.ts +30 -0
  55. package/dist/utils/errors.d.ts.map +1 -0
  56. package/dist/utils/errors.js +61 -0
  57. package/dist/utils/errors.js.map +1 -0
  58. package/dist/utils/ids.d.ts +2 -0
  59. package/dist/utils/ids.d.ts.map +1 -0
  60. package/dist/utils/ids.js +6 -0
  61. package/dist/utils/ids.js.map +1 -0
  62. package/package.json +45 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAEnB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,aAAa,CAAA;IACtB,OAAO,EAAE,aAAa,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,gBAAgB,CAAA;CAC1B;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAyC;IACzD,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,UAAU,CAAyC;IAE3D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,mBAAmB,GAAG,IAAI;IAItE,cAAc,CACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE,aAAqC,GAC7C,IAAI;IAIP,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAIhE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAIzD,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAIrD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAI3D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIhC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAGpC"}
@@ -0,0 +1,33 @@
1
+ export class Registry {
2
+ triggers = new Map();
3
+ actions = new Map();
4
+ conditions = new Map();
5
+ registerTrigger(type, registration) {
6
+ this.triggers.set(type, registration);
7
+ }
8
+ registerAction(name, handler, options = { replaySafe: false }) {
9
+ this.actions.set(name, { handler, options });
10
+ }
11
+ registerCondition(name, handler) {
12
+ this.conditions.set(name, { handler });
13
+ }
14
+ getTrigger(type) {
15
+ return this.triggers.get(type);
16
+ }
17
+ getAction(name) {
18
+ return this.actions.get(name);
19
+ }
20
+ getCondition(name) {
21
+ return this.conditions.get(name);
22
+ }
23
+ hasTrigger(type) {
24
+ return this.triggers.has(type);
25
+ }
26
+ hasAction(name) {
27
+ return this.actions.has(name);
28
+ }
29
+ hasCondition(name) {
30
+ return this.conditions.has(name);
31
+ }
32
+ }
33
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAgBA,MAAM,OAAO,QAAQ;IACX,QAAQ,GAAG,IAAI,GAAG,EAA+B,CAAA;IACjD,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAA;IAC7C,UAAU,GAAG,IAAI,GAAG,EAA+B,CAAA;IAE3D,eAAe,CAAC,IAAY,EAAE,YAAiC;QAC7D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;IACvC,CAAC;IAED,cAAc,CACZ,IAAY,EACZ,OAAsB,EACtB,UAAyB,EAAE,UAAU,EAAE,KAAK,EAAE;QAE9C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;IAC9C,CAAC;IAED,iBAAiB,CAAC,IAAY,EAAE,OAAyB;QACvD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;IACxC,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IAED,YAAY,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAClC,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IAED,YAAY,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAClC,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import type { WorkflowRun } from './types.js';
2
+ import type { Matcher } from './matcher.js';
3
+ export type StartRunFn = (run: WorkflowRun, emitDepth: number) => Promise<void>;
4
+ export declare class ReplayManager {
5
+ private matcher;
6
+ private startRun;
7
+ constructor(matcher: Matcher, startRun: StartRunFn);
8
+ replay(triggerId: string, dryRun?: boolean): Promise<WorkflowRun[]>;
9
+ }
10
+ //# sourceMappingURL=replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG3C,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAE/E,qBAAa,aAAa;IAEtB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;gBADR,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,UAAU;IAGxB,MAAM,CACV,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,WAAW,EAAE,CAAC;CAkB1B"}
package/dist/replay.js ADDED
@@ -0,0 +1,24 @@
1
+ import { ReplayError } from './utils/errors.js';
2
+ export class ReplayManager {
3
+ matcher;
4
+ startRun;
5
+ constructor(matcher, startRun) {
6
+ this.matcher = matcher;
7
+ this.startRun = startRun;
8
+ }
9
+ async replay(triggerId, dryRun = false) {
10
+ const trigger = await this.matcher.getTrigger(triggerId);
11
+ if (!trigger) {
12
+ throw new ReplayError(triggerId, 'Trigger not found');
13
+ }
14
+ const runs = await this.matcher.matchAndCreateRuns(trigger, true);
15
+ if (dryRun) {
16
+ return runs;
17
+ }
18
+ for (const run of runs) {
19
+ await this.startRun(run, 0);
20
+ }
21
+ return runs;
22
+ }
23
+ }
24
+ //# sourceMappingURL=replay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.js","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAI/C,MAAM,OAAO,aAAa;IAEd;IACA;IAFV,YACU,OAAgB,EAChB,QAAoB;QADpB,YAAO,GAAP,OAAO,CAAS;QAChB,aAAQ,GAAR,QAAQ,CAAY;IAC3B,CAAC;IAEJ,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,SAAkB,KAAK;QAEvB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;QACxD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,WAAW,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAA;QACvD,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QAEjE,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,IAAI,CAAA;QACb,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QAC7B,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
package/dist/runs.d.ts ADDED
@@ -0,0 +1,37 @@
1
+ import type { Pool } from 'pg';
2
+ import type { WorkflowRun, WorkflowStatus, WorkflowStepRun, StepStatus, WorkflowStep, DefinitionSnapshot, RunTimelineEntry } from './types.js';
3
+ import type { TableNames } from './schema/tables.js';
4
+ export declare class RunManager {
5
+ private db;
6
+ private tables;
7
+ constructor(db: Pool, tables: TableNames);
8
+ createRun(definitionId: string, tenantId: string, triggerId: string, isReplay?: boolean, snapshot?: DefinitionSnapshot): Promise<WorkflowRun>;
9
+ getRun(runId: string): Promise<WorkflowRun | null>;
10
+ getRunsByTrigger(triggerId: string): Promise<WorkflowRun[]>;
11
+ /**
12
+ * Update run status with an optional state transition guard.
13
+ * When fromStatus is provided, the update only applies if the run
14
+ * is currently in that status (compare-and-set). Throws if the
15
+ * transition is invalid.
16
+ */
17
+ updateStatus(runId: string, status: WorkflowStatus, stepIndex?: number, fromStatus?: WorkflowStatus): Promise<void>;
18
+ updateContext(runId: string, context: Record<string, unknown>): Promise<void>;
19
+ createStepRun(runId: string, tenantId: string, step: WorkflowStep, stepIndex: number, scheduledFor?: Date): Promise<WorkflowStepRun>;
20
+ createBranchStepRun(runId: string, tenantId: string, step: WorkflowStep, stepIndex: number, branchIndex: number, parentStepRunId: string, scheduledFor?: Date): Promise<WorkflowStepRun>;
21
+ getBranchStepRuns(parentStepRunId: string): Promise<WorkflowStepRun[]>;
22
+ getStepRuns(runId: string): Promise<WorkflowStepRun[]>;
23
+ /**
24
+ * Atomically claim a step for execution (compare-and-set).
25
+ * Returns the step run if claimed, null if already claimed by another worker.
26
+ */
27
+ claimStep(stepRunId: string): Promise<WorkflowStepRun | null>;
28
+ updateStepStatus(stepRunId: string, status: StepStatus, result?: Record<string, unknown>, errorMessage?: string): Promise<void>;
29
+ getRunTimeline(runId: string): Promise<RunTimelineEntry[]>;
30
+ cancelRun(runId: string, reason?: string): Promise<WorkflowRun>;
31
+ getFailedRuns(tenantId?: string): Promise<WorkflowRun[]>;
32
+ resetFailedStep(runId: string): Promise<WorkflowStepRun | null>;
33
+ getDueSteps(limit?: number): Promise<WorkflowStepRun[]>;
34
+ private mapRun;
35
+ private mapStepRun;
36
+ }
37
+ //# sourceMappingURL=runs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../src/runs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAA;AAC9B,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,eAAe,EACf,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGpD,qBAAa,UAAU;IAEnB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,MAAM;gBADN,EAAE,EAAE,IAAI,EACR,MAAM,EAAE,UAAU;IAGtB,SAAS,CACb,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,OAAe,EACzB,QAAQ,CAAC,EAAE,kBAAkB,GAC5B,OAAO,CAAC,WAAW,CAAC;IAYjB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAQlD,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAUjE;;;;;OAKG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,cAAc,EACtB,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,cAAc,GAC1B,OAAO,CAAC,IAAI,CAAC;IAyCV,aAAa,CACjB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC;IAWV,aAAa,CACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,IAAI,GAClB,OAAO,CAAC,eAAe,CAAC;IAarB,mBAAmB,CACvB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,YAAY,CAAC,EAAE,IAAI,GAClB,OAAO,CAAC,eAAe,CAAC;IAarB,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAUtE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAU5D;;;OAGG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAW7D,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,EAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC;IAuBV,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAgF1D,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA0B/D,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IASxD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IA+B/D,WAAW,CAAC,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAYjE,OAAO,CAAC,MAAM;IAqBd,OAAO,CAAC,UAAU;CAmBnB"}
package/dist/runs.js ADDED
@@ -0,0 +1,296 @@
1
+ import { generateId } from './utils/ids.js';
2
+ export class RunManager {
3
+ db;
4
+ tables;
5
+ constructor(db, tables) {
6
+ this.db = db;
7
+ this.tables = tables;
8
+ }
9
+ async createRun(definitionId, tenantId, triggerId, isReplay = false, snapshot) {
10
+ const id = generateId('run');
11
+ const result = await this.db.query(`INSERT INTO ${this.tables.workflowRuns}
12
+ (id, definition_id, tenant_id, trigger_id, status, is_replay, definition_snapshot)
13
+ VALUES ($1, $2, $3, $4, 'pending', $5, $6)
14
+ RETURNING *`, [id, definitionId, tenantId, triggerId, isReplay, JSON.stringify(snapshot ?? {})]);
15
+ return this.mapRun(result.rows[0]);
16
+ }
17
+ async getRun(runId) {
18
+ const result = await this.db.query(`SELECT * FROM ${this.tables.workflowRuns} WHERE id = $1`, [runId]);
19
+ return result.rows[0] ? this.mapRun(result.rows[0]) : null;
20
+ }
21
+ async getRunsByTrigger(triggerId) {
22
+ const result = await this.db.query(`SELECT * FROM ${this.tables.workflowRuns}
23
+ WHERE trigger_id = $1
24
+ ORDER BY created_at DESC`, [triggerId]);
25
+ return result.rows.map(this.mapRun);
26
+ }
27
+ /**
28
+ * Update run status with an optional state transition guard.
29
+ * When fromStatus is provided, the update only applies if the run
30
+ * is currently in that status (compare-and-set). Throws if the
31
+ * transition is invalid.
32
+ */
33
+ async updateStatus(runId, status, stepIndex, fromStatus) {
34
+ const now = new Date();
35
+ let timeField = '';
36
+ if (status === 'running' || status === 'waiting') {
37
+ timeField = ', started_at = COALESCE(started_at, $3)';
38
+ }
39
+ else if (status === 'completed') {
40
+ timeField = ', completed_at = $3';
41
+ }
42
+ else if (status === 'failed') {
43
+ timeField = ', failed_at = $3';
44
+ }
45
+ const params = [status, runId];
46
+ if (timeField)
47
+ params.push(now);
48
+ let stepUpdate = '';
49
+ if (stepIndex !== undefined) {
50
+ stepUpdate = `, current_step_index = $${params.length + 1}`;
51
+ params.push(stepIndex);
52
+ }
53
+ let whereClause = 'WHERE id = $2';
54
+ if (fromStatus) {
55
+ whereClause += ` AND status = $${params.length + 1}`;
56
+ params.push(fromStatus);
57
+ }
58
+ const result = await this.db.query(`UPDATE ${this.tables.workflowRuns}
59
+ SET status = $1${timeField}${stepUpdate}, updated_at = NOW()
60
+ ${whereClause}`, params);
61
+ if (fromStatus && result.rowCount === 0) {
62
+ throw new Error(`Invalid state transition for run ${runId}: cannot transition from "${fromStatus}" to "${status}"`);
63
+ }
64
+ }
65
+ async updateContext(runId, context) {
66
+ await this.db.query(`UPDATE ${this.tables.workflowRuns}
67
+ SET context = $1, updated_at = NOW()
68
+ WHERE id = $2`, [JSON.stringify(context), runId]);
69
+ }
70
+ // --- Step runs ---
71
+ async createStepRun(runId, tenantId, step, stepIndex, scheduledFor) {
72
+ const id = generateId('step');
73
+ const status = scheduledFor ? 'scheduled' : 'pending';
74
+ const result = await this.db.query(`INSERT INTO ${this.tables.workflowStepRuns}
75
+ (id, run_id, tenant_id, step_index, step_type, step_name, status, scheduled_for)
76
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
77
+ RETURNING *`, [id, runId, tenantId, stepIndex, step.type, step.name, status, scheduledFor ?? null]);
78
+ return this.mapStepRun(result.rows[0]);
79
+ }
80
+ async createBranchStepRun(runId, tenantId, step, stepIndex, branchIndex, parentStepRunId, scheduledFor) {
81
+ const id = generateId('step');
82
+ const status = scheduledFor ? 'scheduled' : 'pending';
83
+ const result = await this.db.query(`INSERT INTO ${this.tables.workflowStepRuns}
84
+ (id, run_id, tenant_id, step_index, step_type, step_name, status, scheduled_for, branch_index, parent_step_run_id)
85
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
86
+ RETURNING *`, [id, runId, tenantId, stepIndex, step.type, step.name, status, scheduledFor ?? null, branchIndex, parentStepRunId]);
87
+ return this.mapStepRun(result.rows[0]);
88
+ }
89
+ async getBranchStepRuns(parentStepRunId) {
90
+ const result = await this.db.query(`SELECT * FROM ${this.tables.workflowStepRuns}
91
+ WHERE parent_step_run_id = $1
92
+ ORDER BY branch_index ASC, created_at ASC`, [parentStepRunId]);
93
+ return result.rows.map(this.mapStepRun);
94
+ }
95
+ async getStepRuns(runId) {
96
+ const result = await this.db.query(`SELECT * FROM ${this.tables.workflowStepRuns}
97
+ WHERE run_id = $1
98
+ ORDER BY step_index ASC`, [runId]);
99
+ return result.rows.map(this.mapStepRun);
100
+ }
101
+ /**
102
+ * Atomically claim a step for execution (compare-and-set).
103
+ * Returns the step run if claimed, null if already claimed by another worker.
104
+ */
105
+ async claimStep(stepRunId) {
106
+ const result = await this.db.query(`UPDATE ${this.tables.workflowStepRuns}
107
+ SET status = 'running', started_at = NOW()
108
+ WHERE id = $1 AND status IN ('pending', 'scheduled')
109
+ RETURNING *`, [stepRunId]);
110
+ return result.rows[0] ? this.mapStepRun(result.rows[0]) : null;
111
+ }
112
+ async updateStepStatus(stepRunId, status, result, errorMessage) {
113
+ const now = new Date();
114
+ let timeField = '';
115
+ if (status === 'running') {
116
+ timeField = ', started_at = $3';
117
+ }
118
+ else if (status === 'completed' || status === 'failed' || status === 'skipped') {
119
+ timeField = ', completed_at = $3';
120
+ }
121
+ const params = [status, stepRunId];
122
+ if (timeField)
123
+ params.push(now);
124
+ await this.db.query(`UPDATE ${this.tables.workflowStepRuns}
125
+ SET status = $1${timeField},
126
+ result = COALESCE($${params.length + 1}, result),
127
+ error_message = COALESCE($${params.length + 2}, error_message)
128
+ WHERE id = $2`, [...params, result ? JSON.stringify(result) : null, errorMessage ?? null]);
129
+ }
130
+ async getRunTimeline(runId) {
131
+ const result = await this.db.query(`SELECT * FROM (
132
+ -- Run lifecycle events
133
+ SELECT created_at AS timestamp, 'run_created' AS type,
134
+ NULL::int AS step_index, NULL AS step_name, NULL AS step_type,
135
+ NULL::jsonb AS detail
136
+ FROM ${this.tables.workflowRuns} WHERE id = $1
137
+
138
+ UNION ALL
139
+
140
+ SELECT completed_at AS timestamp, 'run_completed' AS type,
141
+ NULL, NULL, NULL, NULL
142
+ FROM ${this.tables.workflowRuns} WHERE id = $1 AND status = 'completed' AND completed_at IS NOT NULL
143
+
144
+ UNION ALL
145
+
146
+ SELECT failed_at AS timestamp, 'run_failed' AS type,
147
+ NULL, NULL, NULL, NULL
148
+ FROM ${this.tables.workflowRuns} WHERE id = $1 AND status = 'failed' AND failed_at IS NOT NULL
149
+
150
+ UNION ALL
151
+
152
+ SELECT canceled_at AS timestamp, 'run_canceled' AS type,
153
+ NULL, NULL, NULL, jsonb_build_object('reason', cancel_reason)
154
+ FROM ${this.tables.workflowRuns} WHERE id = $1 AND status = 'canceled' AND canceled_at IS NOT NULL
155
+
156
+ UNION ALL
157
+
158
+ -- Step events
159
+ SELECT created_at AS timestamp, 'step_scheduled' AS type,
160
+ step_index, step_name, step_type, NULL
161
+ FROM ${this.tables.workflowStepRuns} WHERE run_id = $1
162
+
163
+ UNION ALL
164
+
165
+ SELECT started_at AS timestamp, 'step_started' AS type,
166
+ step_index, step_name, step_type, NULL
167
+ FROM ${this.tables.workflowStepRuns} WHERE run_id = $1 AND started_at IS NOT NULL
168
+
169
+ UNION ALL
170
+
171
+ SELECT completed_at AS timestamp, 'step_completed' AS type,
172
+ step_index, step_name, step_type, result::jsonb
173
+ FROM ${this.tables.workflowStepRuns} WHERE run_id = $1 AND status = 'completed' AND completed_at IS NOT NULL
174
+
175
+ UNION ALL
176
+
177
+ SELECT completed_at AS timestamp, 'step_failed' AS type,
178
+ step_index, step_name, step_type, jsonb_build_object('error', error_message)
179
+ FROM ${this.tables.workflowStepRuns} WHERE run_id = $1 AND status = 'failed' AND completed_at IS NOT NULL
180
+
181
+ UNION ALL
182
+
183
+ SELECT completed_at AS timestamp, 'step_skipped' AS type,
184
+ step_index, step_name, step_type, result::jsonb
185
+ FROM ${this.tables.workflowStepRuns} WHERE run_id = $1 AND status = 'skipped' AND completed_at IS NOT NULL
186
+
187
+ UNION ALL
188
+
189
+ -- Execution logs
190
+ SELECT created_at AS timestamp, 'log' AS type,
191
+ NULL, NULL, NULL, jsonb_build_object('level', level, 'message', message, 'data', data)
192
+ FROM ${this.tables.executionLogs} WHERE run_id = $1
193
+ ) AS timeline
194
+ WHERE timestamp IS NOT NULL
195
+ ORDER BY timestamp ASC`, [runId]);
196
+ return result.rows.map((row) => ({
197
+ timestamp: row.timestamp,
198
+ type: row.type,
199
+ stepIndex: row.step_index,
200
+ stepName: row.step_name,
201
+ stepType: row.step_type,
202
+ detail: row.detail,
203
+ }));
204
+ }
205
+ async cancelRun(runId, reason) {
206
+ const run = await this.getRun(runId);
207
+ if (!run)
208
+ throw new Error(`Run ${runId} not found`);
209
+ if (run.status === 'completed' || run.status === 'failed' || run.status === 'canceled') {
210
+ throw new Error(`Cannot cancel run ${runId} with status "${run.status}"`);
211
+ }
212
+ const now = new Date();
213
+ await this.db.query(`UPDATE ${this.tables.workflowRuns}
214
+ SET status = 'canceled', canceled_at = $2, cancel_reason = $3, updated_at = NOW()
215
+ WHERE id = $1`, [runId, now, reason ?? null]);
216
+ // Cancel pending/scheduled step runs
217
+ await this.db.query(`UPDATE ${this.tables.workflowStepRuns}
218
+ SET status = 'skipped', completed_at = $2
219
+ WHERE run_id = $1 AND status IN ('pending', 'scheduled')`, [runId, now]);
220
+ return { ...run, status: 'canceled', canceledAt: now, cancelReason: reason };
221
+ }
222
+ async getFailedRuns(tenantId) {
223
+ const query = tenantId
224
+ ? `SELECT * FROM ${this.tables.workflowRuns} WHERE status = 'failed' AND tenant_id = $1 ORDER BY failed_at DESC`
225
+ : `SELECT * FROM ${this.tables.workflowRuns} WHERE status = 'failed' ORDER BY failed_at DESC`;
226
+ const params = tenantId ? [tenantId] : [];
227
+ const result = await this.db.query(query, params);
228
+ return result.rows.map(this.mapRun);
229
+ }
230
+ async resetFailedStep(runId) {
231
+ // Find the failed step
232
+ const result = await this.db.query(`SELECT * FROM ${this.tables.workflowStepRuns}
233
+ WHERE run_id = $1 AND status = 'failed'
234
+ ORDER BY step_index ASC LIMIT 1`, [runId]);
235
+ if (result.rows.length === 0)
236
+ return null;
237
+ const stepRun = this.mapStepRun(result.rows[0]);
238
+ // Reset the step to pending
239
+ await this.db.query(`UPDATE ${this.tables.workflowStepRuns}
240
+ SET status = 'pending', started_at = NULL, completed_at = NULL, error_message = NULL, result = NULL
241
+ WHERE id = $1`, [stepRun.id]);
242
+ // Reset the run to running
243
+ await this.db.query(`UPDATE ${this.tables.workflowRuns}
244
+ SET status = 'running', failed_at = NULL, updated_at = NOW()
245
+ WHERE id = $1`, [runId]);
246
+ return { ...stepRun, status: 'pending' };
247
+ }
248
+ async getDueSteps(limit = 50) {
249
+ const result = await this.db.query(`SELECT * FROM ${this.tables.workflowStepRuns}
250
+ WHERE status = 'scheduled'
251
+ AND (scheduled_for IS NULL OR scheduled_for <= NOW())
252
+ ORDER BY scheduled_for ASC NULLS FIRST
253
+ LIMIT $1`, [limit]);
254
+ return result.rows.map(this.mapStepRun);
255
+ }
256
+ mapRun(row) {
257
+ return {
258
+ id: row.id,
259
+ definitionId: row.definition_id,
260
+ tenantId: row.tenant_id,
261
+ triggerId: row.trigger_id,
262
+ status: row.status,
263
+ context: (row.context ?? {}),
264
+ currentStepIndex: row.current_step_index,
265
+ isReplay: row.is_replay,
266
+ definitionSnapshot: (row.definition_snapshot ?? {}),
267
+ startedAt: row.started_at,
268
+ completedAt: row.completed_at,
269
+ failedAt: row.failed_at,
270
+ canceledAt: row.canceled_at,
271
+ cancelReason: row.cancel_reason,
272
+ createdAt: row.created_at,
273
+ updatedAt: row.updated_at,
274
+ };
275
+ }
276
+ mapStepRun(row) {
277
+ return {
278
+ id: row.id,
279
+ runId: row.run_id,
280
+ tenantId: row.tenant_id,
281
+ stepIndex: row.step_index,
282
+ stepType: row.step_type,
283
+ stepName: row.step_name,
284
+ status: row.status,
285
+ scheduledFor: row.scheduled_for,
286
+ startedAt: row.started_at,
287
+ completedAt: row.completed_at,
288
+ result: row.result,
289
+ errorMessage: row.error_message,
290
+ branchIndex: row.branch_index,
291
+ parentStepRunId: row.parent_step_run_id,
292
+ createdAt: row.created_at,
293
+ };
294
+ }
295
+ }
296
+ //# sourceMappingURL=runs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../src/runs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { DefinitionSnapshot, WorkflowRun, WorkflowStep, WorkflowStepRun } from './types.js';
2
+ import type { RunManager } from './runs.js';
3
+ export declare const MAX_DELAY_MS: number;
4
+ export declare class Scheduler {
5
+ private runManager;
6
+ constructor(runManager: RunManager);
7
+ scheduleFirstStep(run: WorkflowRun, snapshot: DefinitionSnapshot): Promise<void>;
8
+ scheduleNextStep(run: WorkflowRun, snapshot: DefinitionSnapshot, currentStepIndex: number, skipCount?: number): Promise<boolean>;
9
+ /**
10
+ * Schedule the first step of each branch in a parallel step.
11
+ * Returns the created step runs for enqueuing.
12
+ */
13
+ scheduleParallelBranches(run: WorkflowRun, parentStepRunId: string, branches: WorkflowStep[][], parentStepIndex: number): Promise<WorkflowStepRun[]>;
14
+ /**
15
+ * Schedule the next step within a branch.
16
+ * Returns the step run if scheduled, null if branch is complete.
17
+ */
18
+ scheduleNextBranchStep(run: WorkflowRun, branch: WorkflowStep[], branchIndex: number, parentStepRunId: string, currentBranchStepIndex: number, parentStepIndex: number): Promise<WorkflowStepRun | null>;
19
+ private getScheduledTime;
20
+ }
21
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAChG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE3C,eAAO,MAAM,YAAY,QAA2B,CAAA;AAEpD,qBAAa,SAAS;IACR,OAAO,CAAC,UAAU;gBAAV,UAAU,EAAE,UAAU;IAEpC,iBAAiB,CACrB,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,IAAI,CAAC;IAoBV,gBAAgB,CACpB,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,kBAAkB,EAC5B,gBAAgB,EAAE,MAAM,EACxB,SAAS,GAAE,MAAU,GACpB,OAAO,CAAC,OAAO,CAAC;IAyBnB;;;OAGG;IACG,wBAAwB,CAC5B,GAAG,EAAE,WAAW,EAChB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,YAAY,EAAE,EAAE,EAC1B,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,eAAe,EAAE,CAAC;IAwB7B;;;OAGG;IACG,sBAAsB,CAC1B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,YAAY,EAAE,EACtB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,sBAAsB,EAAE,MAAM,EAC9B,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAiBlC,OAAO,CAAC,gBAAgB;CAOzB"}
@@ -0,0 +1,67 @@
1
+ export const MAX_DELAY_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
2
+ export class Scheduler {
3
+ runManager;
4
+ constructor(runManager) {
5
+ this.runManager = runManager;
6
+ }
7
+ async scheduleFirstStep(run, snapshot) {
8
+ if (snapshot.steps.length === 0) {
9
+ await this.runManager.updateStatus(run.id, 'completed', undefined, 'pending');
10
+ return;
11
+ }
12
+ const step = snapshot.steps[0];
13
+ const scheduledFor = this.getScheduledTime(step);
14
+ await this.runManager.createStepRun(run.id, run.tenantId, step, 0, scheduledFor);
15
+ await this.runManager.updateStatus(run.id, 'running', 0, 'pending');
16
+ }
17
+ async scheduleNextStep(run, snapshot, currentStepIndex, skipCount = 1) {
18
+ const nextIndex = currentStepIndex + skipCount;
19
+ if (nextIndex >= snapshot.steps.length) {
20
+ await this.runManager.updateStatus(run.id, 'completed', undefined, 'running');
21
+ return false;
22
+ }
23
+ const step = snapshot.steps[nextIndex];
24
+ const scheduledFor = this.getScheduledTime(step);
25
+ await this.runManager.createStepRun(run.id, run.tenantId, step, nextIndex, scheduledFor);
26
+ const status = scheduledFor ? 'waiting' : 'running';
27
+ await this.runManager.updateStatus(run.id, status, nextIndex, 'running');
28
+ return true;
29
+ }
30
+ /**
31
+ * Schedule the first step of each branch in a parallel step.
32
+ * Returns the created step runs for enqueuing.
33
+ */
34
+ async scheduleParallelBranches(run, parentStepRunId, branches, parentStepIndex) {
35
+ const stepRuns = [];
36
+ for (let branchIdx = 0; branchIdx < branches.length; branchIdx++) {
37
+ const branch = branches[branchIdx];
38
+ if (branch.length === 0)
39
+ continue;
40
+ const step = branch[0];
41
+ const scheduledFor = this.getScheduledTime(step);
42
+ const stepRun = await this.runManager.createBranchStepRun(run.id, run.tenantId, step, parentStepIndex, branchIdx, parentStepRunId, scheduledFor);
43
+ stepRuns.push(stepRun);
44
+ }
45
+ return stepRuns;
46
+ }
47
+ /**
48
+ * Schedule the next step within a branch.
49
+ * Returns the step run if scheduled, null if branch is complete.
50
+ */
51
+ async scheduleNextBranchStep(run, branch, branchIndex, parentStepRunId, currentBranchStepIndex, parentStepIndex) {
52
+ const nextIdx = currentBranchStepIndex + 1;
53
+ if (nextIdx >= branch.length)
54
+ return null;
55
+ const step = branch[nextIdx];
56
+ const scheduledFor = this.getScheduledTime(step);
57
+ return this.runManager.createBranchStepRun(run.id, run.tenantId, step, parentStepIndex, branchIndex, parentStepRunId, scheduledFor);
58
+ }
59
+ getScheduledTime(step) {
60
+ if (step.type === 'delay' && step.delayMs) {
61
+ const capped = Math.min(step.delayMs, MAX_DELAY_MS);
62
+ return new Date(Date.now() + capped);
63
+ }
64
+ return new Date(); // schedule immediately
65
+ }
66
+ }
67
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Pool } from 'pg';
2
+ export declare function runMigrations(db: Pool, tablePrefix: string): Promise<void>;
3
+ //# sourceMappingURL=migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/schema/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAA;AA0C9B,wBAAsB,aAAa,CACjC,EAAE,EAAE,IAAI,EACR,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
@@ -0,0 +1,56 @@
1
+ import { getMigrationSQL, getTableNames } from './tables.js';
2
+ function getMigrations() {
3
+ return [
4
+ {
5
+ version: 1,
6
+ name: 'baseline_schema',
7
+ sql: (prefix) => getMigrationSQL(prefix),
8
+ },
9
+ {
10
+ version: 2,
11
+ name: 'add_cancel_cron_parallel',
12
+ sql: (prefix) => {
13
+ const t = getTableNames(prefix);
14
+ return `
15
+ ALTER TABLE ${t.workflowRuns}
16
+ ADD COLUMN IF NOT EXISTS canceled_at TIMESTAMPTZ,
17
+ ADD COLUMN IF NOT EXISTS cancel_reason TEXT;
18
+
19
+ ALTER TABLE ${t.workflowDefinitions}
20
+ ADD COLUMN IF NOT EXISTS cron_expression TEXT;
21
+
22
+ ALTER TABLE ${t.workflowStepRuns}
23
+ ADD COLUMN IF NOT EXISTS branch_index INTEGER,
24
+ ADD COLUMN IF NOT EXISTS parent_step_run_id TEXT;
25
+ `;
26
+ },
27
+ },
28
+ ];
29
+ }
30
+ function getMigrationsTableName(prefix) {
31
+ return `${prefix}migrations`;
32
+ }
33
+ export async function runMigrations(db, tablePrefix) {
34
+ const migrationsTable = getMigrationsTableName(tablePrefix);
35
+ // Create migrations tracking table
36
+ await db.query(`
37
+ CREATE TABLE IF NOT EXISTS ${migrationsTable} (
38
+ version INTEGER PRIMARY KEY,
39
+ name TEXT NOT NULL,
40
+ applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
41
+ )
42
+ `);
43
+ // Get currently applied version
44
+ const result = await db.query(`SELECT COALESCE(MAX(version), 0) AS current_version FROM ${migrationsTable}`);
45
+ const currentVersion = result.rows[0].current_version;
46
+ // Run unapplied migrations in order
47
+ const migrations = getMigrations();
48
+ for (const migration of migrations) {
49
+ if (migration.version <= currentVersion)
50
+ continue;
51
+ const sql = migration.sql(tablePrefix);
52
+ await db.query(sql);
53
+ await db.query(`INSERT INTO ${migrationsTable} (version, name) VALUES ($1, $2)`, [migration.version, migration.name]);
54
+ }
55
+ }
56
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/schema/migrate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAQ5D,SAAS,aAAa;IACpB,OAAO;QACL;YACE,OAAO,EAAE,CAAC;YACV,IAAI,EAAE,iBAAiB;YACvB,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC;SACzC;QACD;YACE,OAAO,EAAE,CAAC;YACV,IAAI,EAAE,0BAA0B;YAChC,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE;gBACd,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;gBAC/B,OAAO;wBACS,CAAC,CAAC,YAAY;;;;wBAId,CAAC,CAAC,mBAAmB;;;wBAGrB,CAAC,CAAC,gBAAgB;;;SAGjC,CAAA;YACH,CAAC;SACF;KACF,CAAA;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAc;IAC5C,OAAO,GAAG,MAAM,YAAY,CAAA;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAQ,EACR,WAAmB;IAEnB,MAAM,eAAe,GAAG,sBAAsB,CAAC,WAAW,CAAC,CAAA;IAE3D,mCAAmC;IACnC,MAAM,EAAE,CAAC,KAAK,CAAC;iCACgB,eAAe;;;;;GAK7C,CAAC,CAAA;IAEF,gCAAgC;IAChC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,CAC3B,4DAA4D,eAAe,EAAE,CAC9E,CAAA;IACD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAyB,CAAA;IAE/D,oCAAoC;IACpC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAClC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,SAAS,CAAC,OAAO,IAAI,cAAc;YAAE,SAAQ;QAEjD,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QACtC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACnB,MAAM,EAAE,CAAC,KAAK,CACZ,eAAe,eAAe,kCAAkC,EAChE,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CACpC,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare function getTableNames(prefix: string): {
2
+ readonly triggers: `${string}triggers`;
3
+ readonly workflowDefinitions: `${string}workflow_definitions`;
4
+ readonly workflowRuns: `${string}workflow_runs`;
5
+ readonly workflowStepRuns: `${string}workflow_step_runs`;
6
+ readonly executionLogs: `${string}execution_logs`;
7
+ };
8
+ export type TableNames = ReturnType<typeof getTableNames>;
9
+ export declare function getMigrationSQL(prefix: string): string;
10
+ //# sourceMappingURL=tables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../src/schema/tables.ts"],"names":[],"mappings":"AAUA,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM;;;;;;EAS3C;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;AAEzD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA0GtD"}