@multiplier-labs/stepflow 0.3.1 → 0.3.3
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/.codekin/reports/comments/2026-04-04_comment-assessment.md +179 -0
- package/.codekin/reports/complexity/2026-04-03_complexity-report.md +152 -0
- package/.codekin/reports/dependencies/2026-04-04_dependency-health.md +94 -0
- package/.codekin/reports/docs-audit/2026-04-04_docs-audit.md +10 -0
- package/.codekin/reports/security/2026-04-03_security-audit.md +208 -0
- package/.github/CODEOWNERS +15 -0
- package/.github/dependabot.yml +23 -0
- package/.github/workflows/ci.yml +38 -0
- package/.github/workflows/publish.yml +11 -5
- package/.github/workflows/security.yml +29 -0
- package/CHANGELOG.md +34 -0
- package/README.md +24 -0
- package/SECURITY.md +40 -0
- package/dist/{chunk-FQCT3I2A.js → chunk-4VOKMGP6.js} +23 -42
- package/dist/chunk-4VOKMGP6.js.map +1 -0
- package/dist/{chunk-XCF4PLN7.js → chunk-GYPNJBDP.js} +12 -16
- package/dist/chunk-GYPNJBDP.js.map +1 -0
- package/dist/{chunk-U5QGN3RT.js → chunk-KHTUWLVZ.js} +14 -47
- package/dist/chunk-KHTUWLVZ.js.map +1 -0
- package/dist/{chunk-GXY66V7Q.js → chunk-ML35PIHX.js} +1 -1
- package/dist/chunk-ML35PIHX.js.map +1 -0
- package/dist/events/index.d.ts +4 -4
- package/dist/events/index.js +1 -1
- package/dist/{index-CPfGsmrp.d.ts → index-Dzr437iW.d.ts} +6 -6
- package/dist/index.d.ts +14 -12
- package/dist/index.js +40 -82
- package/dist/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +4 -4
- package/dist/scheduler/index.js +2 -2
- package/dist/storage/index.d.ts +13 -13
- package/dist/storage/index.js +2 -2
- package/dist/{types-BlwFEGzj.d.ts → types-DSEjiLMj.d.ts} +16 -15
- package/dist/{types-DzkEqnQJ.d.ts → types-DZUdWmCc.d.ts} +2 -2
- package/dist/{types-BVShq7zT.d.ts → types-K5Gjk3H_.d.ts} +4 -4
- package/docs/stepflow-api-reference.md +2 -3
- package/package.json +7 -6
- package/src/core/engine.test.ts +466 -522
- package/src/core/engine.ts +42 -67
- package/src/core/index.ts +3 -3
- package/src/core/orchestrator.ts +64 -83
- package/src/core/types.ts +7 -29
- package/src/events/index.ts +4 -4
- package/src/events/memory.test.ts +39 -41
- package/src/events/memory.ts +7 -10
- package/src/events/socketio.test.ts +112 -162
- package/src/events/socketio.ts +20 -27
- package/src/events/types.ts +16 -19
- package/src/events/webhook.test.ts +197 -235
- package/src/events/webhook.ts +44 -71
- package/src/index.ts +19 -19
- package/src/planning/index.ts +6 -3
- package/src/planning/planner.ts +66 -91
- package/src/planning/planning.test.ts +303 -366
- package/src/planning/registry.test.ts +204 -251
- package/src/planning/registry.ts +39 -43
- package/src/planning/types.ts +23 -27
- package/src/scheduler/cron.test.ts +141 -150
- package/src/scheduler/cron.ts +32 -67
- package/src/scheduler/index.ts +4 -14
- package/src/scheduler/postgres-persistence.ts +71 -99
- package/src/scheduler/sqlite-persistence.test.ts +96 -96
- package/src/scheduler/sqlite-persistence.ts +12 -19
- package/src/scheduler/types.ts +4 -9
- package/src/storage/index.ts +5 -5
- package/src/storage/memory.test.ts +133 -183
- package/src/storage/memory.ts +21 -42
- package/src/storage/postgres.ts +197 -393
- package/src/storage/sqlite.test.ts +154 -281
- package/src/storage/sqlite.ts +50 -85
- package/src/storage/types.ts +33 -58
- package/src/utils/errors.test.ts +78 -80
- package/src/utils/errors.ts +27 -57
- package/src/utils/id.ts +3 -3
- package/src/utils/index.ts +4 -4
- package/src/utils/logger.test.ts +52 -58
- package/src/utils/logger.ts +4 -4
- package/src/utils/postgres-deps.ts +4 -4
- package/src/utils/retry.test.ts +47 -67
- package/src/utils/retry.ts +9 -9
- package/dist/chunk-FQCT3I2A.js.map +0 -1
- package/dist/chunk-GXY66V7Q.js.map +0 -1
- package/dist/chunk-U5QGN3RT.js.map +0 -1
- package/dist/chunk-XCF4PLN7.js.map +0 -1
- package/src/scheduler/postgres-persistence.test.ts +0 -906
package/src/storage/sqlite.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Provides durable persistence for workflow runs, steps, and events.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type Database from
|
|
8
|
-
import { generateId } from
|
|
7
|
+
import type Database from 'better-sqlite3';
|
|
8
|
+
import { generateId } from '../utils/id';
|
|
9
9
|
import type {
|
|
10
10
|
StorageAdapter,
|
|
11
11
|
WorkflowRunRecord,
|
|
@@ -14,9 +14,9 @@ import type {
|
|
|
14
14
|
ListRunsOptions,
|
|
15
15
|
ListEventsOptions,
|
|
16
16
|
PaginatedResult,
|
|
17
|
-
} from
|
|
18
|
-
import type { RunStatus, StepStatus, WorkflowError } from
|
|
19
|
-
import { sanitizeErrorForStorage } from
|
|
17
|
+
} from './types';
|
|
18
|
+
import type { RunStatus, StepStatus, WorkflowError } from '../core/types';
|
|
19
|
+
import { sanitizeErrorForStorage } from '../utils/logger';
|
|
20
20
|
|
|
21
21
|
// ============================================================================
|
|
22
22
|
// Schema SQL
|
|
@@ -36,6 +36,7 @@ CREATE TABLE IF NOT EXISTS workflow_runs (
|
|
|
36
36
|
input_json TEXT NOT NULL,
|
|
37
37
|
metadata_json TEXT NOT NULL,
|
|
38
38
|
context_json TEXT NOT NULL,
|
|
39
|
+
completed_steps_json TEXT,
|
|
39
40
|
error_json TEXT,
|
|
40
41
|
created_at TEXT NOT NULL,
|
|
41
42
|
started_at TEXT,
|
|
@@ -158,10 +159,10 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
158
159
|
|
|
159
160
|
constructor(config: SQLiteStorageConfig) {
|
|
160
161
|
this.db = config.db;
|
|
161
|
-
this.prefix = config.tablePrefix ??
|
|
162
|
+
this.prefix = config.tablePrefix ?? 'workflow';
|
|
162
163
|
|
|
163
164
|
// Enable foreign keys
|
|
164
|
-
this.db.pragma(
|
|
165
|
+
this.db.pragma('foreign_keys = ON');
|
|
165
166
|
|
|
166
167
|
// Create tables if needed
|
|
167
168
|
if (config.autoCreateTables !== false) {
|
|
@@ -185,8 +186,8 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
185
186
|
private prepareStatements(): void {
|
|
186
187
|
this.stmts = {
|
|
187
188
|
insertRun: this.db.prepare(`
|
|
188
|
-
INSERT INTO workflow_runs (id, kind, status, parent_run_id, input_json, metadata_json, context_json, error_json, created_at, started_at, finished_at)
|
|
189
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
189
|
+
INSERT INTO workflow_runs (id, kind, status, parent_run_id, input_json, metadata_json, context_json, completed_steps_json, error_json, created_at, started_at, finished_at)
|
|
190
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
190
191
|
`),
|
|
191
192
|
getRun: this.db.prepare(`
|
|
192
193
|
SELECT * FROM workflow_runs WHERE id = ?
|
|
@@ -195,6 +196,7 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
195
196
|
UPDATE workflow_runs
|
|
196
197
|
SET status = COALESCE(?, status),
|
|
197
198
|
context_json = COALESCE(?, context_json),
|
|
199
|
+
completed_steps_json = COALESCE(?, completed_steps_json),
|
|
198
200
|
error_json = COALESCE(?, error_json),
|
|
199
201
|
started_at = COALESCE(?, started_at),
|
|
200
202
|
finished_at = COALESCE(?, finished_at)
|
|
@@ -277,9 +279,7 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
277
279
|
// Run Operations
|
|
278
280
|
// ============================================================================
|
|
279
281
|
|
|
280
|
-
async createRun(
|
|
281
|
-
run: Omit<WorkflowRunRecord, "id" | "createdAt">,
|
|
282
|
-
): Promise<WorkflowRunRecord> {
|
|
282
|
+
async createRun(run: Omit<WorkflowRunRecord, 'id' | 'createdAt'>): Promise<WorkflowRunRecord> {
|
|
283
283
|
const id = generateId();
|
|
284
284
|
const createdAt = new Date();
|
|
285
285
|
|
|
@@ -291,10 +291,11 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
291
291
|
JSON.stringify(run.input),
|
|
292
292
|
JSON.stringify(run.metadata),
|
|
293
293
|
JSON.stringify(run.context),
|
|
294
|
+
run.completedSteps ? JSON.stringify(run.completedSteps) : null,
|
|
294
295
|
run.error ? JSON.stringify(sanitizeErrorForStorage(run.error)) : null,
|
|
295
296
|
createdAt.toISOString(),
|
|
296
297
|
run.startedAt?.toISOString() ?? null,
|
|
297
|
-
run.finishedAt?.toISOString() ?? null
|
|
298
|
+
run.finishedAt?.toISOString() ?? null
|
|
298
299
|
);
|
|
299
300
|
|
|
300
301
|
return {
|
|
@@ -309,56 +310,41 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
309
310
|
return row ? this.mapRunRow(row) : null;
|
|
310
311
|
}
|
|
311
312
|
|
|
312
|
-
async updateRun(
|
|
313
|
-
runId: string,
|
|
314
|
-
updates: Partial<WorkflowRunRecord>,
|
|
315
|
-
): Promise<void> {
|
|
313
|
+
async updateRun(runId: string, updates: Partial<WorkflowRunRecord>): Promise<void> {
|
|
316
314
|
this.stmts!.updateRun.run(
|
|
317
315
|
updates.status ?? null,
|
|
318
316
|
updates.context ? JSON.stringify(updates.context) : null,
|
|
319
|
-
updates.
|
|
320
|
-
|
|
321
|
-
: null,
|
|
317
|
+
updates.completedSteps ? JSON.stringify(updates.completedSteps) : null,
|
|
318
|
+
updates.error ? JSON.stringify(sanitizeErrorForStorage(updates.error)) : null,
|
|
322
319
|
updates.startedAt?.toISOString() ?? null,
|
|
323
320
|
updates.finishedAt?.toISOString() ?? null,
|
|
324
|
-
runId
|
|
321
|
+
runId
|
|
325
322
|
);
|
|
326
323
|
}
|
|
327
324
|
|
|
328
|
-
async listRuns(
|
|
329
|
-
options: ListRunsOptions = {},
|
|
330
|
-
): Promise<PaginatedResult<WorkflowRunRecord>> {
|
|
325
|
+
async listRuns(options: ListRunsOptions = {}): Promise<PaginatedResult<WorkflowRunRecord>> {
|
|
331
326
|
const limit = options.limit ?? 50;
|
|
332
327
|
const offset = options.offset ?? 0;
|
|
333
328
|
const kind = options.kind ?? null;
|
|
334
329
|
const status = options.status ?? null;
|
|
335
|
-
const statusJson = status
|
|
336
|
-
? JSON.stringify(Array.isArray(status) ? status : [status])
|
|
337
|
-
: null;
|
|
330
|
+
const statusJson = status ? JSON.stringify(Array.isArray(status) ? status : [status]) : null;
|
|
338
331
|
const parentRunId = options.parentRunId ?? null;
|
|
339
332
|
|
|
340
333
|
const rows = this.stmts!.listRuns.all(
|
|
341
|
-
kind,
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
parentRunId,
|
|
346
|
-
parentRunId,
|
|
347
|
-
limit,
|
|
348
|
-
offset,
|
|
334
|
+
kind, kind,
|
|
335
|
+
statusJson, statusJson,
|
|
336
|
+
parentRunId, parentRunId,
|
|
337
|
+
limit, offset
|
|
349
338
|
) as SQLiteRunRow[];
|
|
350
339
|
|
|
351
340
|
const countResult = this.stmts!.countRuns.get(
|
|
352
|
-
kind,
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
statusJson,
|
|
356
|
-
parentRunId,
|
|
357
|
-
parentRunId,
|
|
341
|
+
kind, kind,
|
|
342
|
+
statusJson, statusJson,
|
|
343
|
+
parentRunId, parentRunId
|
|
358
344
|
) as { count: number };
|
|
359
345
|
|
|
360
346
|
return {
|
|
361
|
-
items: rows.map(
|
|
347
|
+
items: rows.map(row => this.mapRunRow(row)),
|
|
362
348
|
total: countResult.count,
|
|
363
349
|
limit,
|
|
364
350
|
offset,
|
|
@@ -369,9 +355,7 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
369
355
|
// Step Operations
|
|
370
356
|
// ============================================================================
|
|
371
357
|
|
|
372
|
-
async createStep(
|
|
373
|
-
step: Omit<WorkflowRunStepRecord, "id">,
|
|
374
|
-
): Promise<WorkflowRunStepRecord> {
|
|
358
|
+
async createStep(step: Omit<WorkflowRunStepRecord, 'id'>): Promise<WorkflowRunStepRecord> {
|
|
375
359
|
const id = generateId();
|
|
376
360
|
|
|
377
361
|
this.stmts!.insertStep.run(
|
|
@@ -384,7 +368,7 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
384
368
|
step.result !== undefined ? JSON.stringify(step.result) : null,
|
|
385
369
|
step.error ? JSON.stringify(sanitizeErrorForStorage(step.error)) : null,
|
|
386
370
|
step.startedAt?.toISOString() ?? null,
|
|
387
|
-
step.finishedAt?.toISOString() ?? null
|
|
371
|
+
step.finishedAt?.toISOString() ?? null
|
|
388
372
|
);
|
|
389
373
|
|
|
390
374
|
return { ...step, id };
|
|
@@ -395,32 +379,27 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
395
379
|
return row ? this.mapStepRow(row) : null;
|
|
396
380
|
}
|
|
397
381
|
|
|
398
|
-
async updateStep(
|
|
399
|
-
stepId: string,
|
|
400
|
-
updates: Partial<WorkflowRunStepRecord>,
|
|
401
|
-
): Promise<void> {
|
|
382
|
+
async updateStep(stepId: string, updates: Partial<WorkflowRunStepRecord>): Promise<void> {
|
|
402
383
|
this.stmts!.updateStep.run(
|
|
403
384
|
updates.status ?? null,
|
|
404
385
|
updates.attempt ?? null,
|
|
405
386
|
updates.result !== undefined ? JSON.stringify(updates.result) : null,
|
|
406
|
-
updates.error
|
|
407
|
-
? JSON.stringify(sanitizeErrorForStorage(updates.error))
|
|
408
|
-
: null,
|
|
387
|
+
updates.error ? JSON.stringify(sanitizeErrorForStorage(updates.error)) : null,
|
|
409
388
|
updates.finishedAt?.toISOString() ?? null,
|
|
410
|
-
stepId
|
|
389
|
+
stepId
|
|
411
390
|
);
|
|
412
391
|
}
|
|
413
392
|
|
|
414
393
|
async getStepsForRun(runId: string): Promise<WorkflowRunStepRecord[]> {
|
|
415
394
|
const rows = this.stmts!.getStepsForRun.all(runId) as SQLiteStepRow[];
|
|
416
|
-
return rows.map(
|
|
395
|
+
return rows.map(row => this.mapStepRow(row));
|
|
417
396
|
}
|
|
418
397
|
|
|
419
398
|
// ============================================================================
|
|
420
399
|
// Event Operations
|
|
421
400
|
// ============================================================================
|
|
422
401
|
|
|
423
|
-
async saveEvent(event: Omit<WorkflowEventRecord,
|
|
402
|
+
async saveEvent(event: Omit<WorkflowEventRecord, 'id'>): Promise<void> {
|
|
424
403
|
const id = generateId();
|
|
425
404
|
|
|
426
405
|
this.stmts!.insertEvent.run(
|
|
@@ -430,14 +409,11 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
430
409
|
event.eventType,
|
|
431
410
|
event.level,
|
|
432
411
|
event.payload !== undefined ? JSON.stringify(event.payload) : null,
|
|
433
|
-
event.timestamp.toISOString()
|
|
412
|
+
event.timestamp.toISOString()
|
|
434
413
|
);
|
|
435
414
|
}
|
|
436
415
|
|
|
437
|
-
async getEventsForRun(
|
|
438
|
-
runId: string,
|
|
439
|
-
options: ListEventsOptions = {},
|
|
440
|
-
): Promise<WorkflowEventRecord[]> {
|
|
416
|
+
async getEventsForRun(runId: string, options: ListEventsOptions = {}): Promise<WorkflowEventRecord[]> {
|
|
441
417
|
const limit = options.limit ?? 1000;
|
|
442
418
|
const offset = options.offset ?? 0;
|
|
443
419
|
const stepKey = options.stepKey ?? null;
|
|
@@ -445,15 +421,12 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
445
421
|
|
|
446
422
|
const rows = this.stmts!.getEventsForRun.all(
|
|
447
423
|
runId,
|
|
448
|
-
stepKey,
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
level,
|
|
452
|
-
limit,
|
|
453
|
-
offset,
|
|
424
|
+
stepKey, stepKey,
|
|
425
|
+
level, level,
|
|
426
|
+
limit, offset
|
|
454
427
|
) as SQLiteEventRow[];
|
|
455
428
|
|
|
456
|
-
return rows.map(
|
|
429
|
+
return rows.map(row => this.mapEventRow(row));
|
|
457
430
|
}
|
|
458
431
|
|
|
459
432
|
// ============================================================================
|
|
@@ -524,19 +497,15 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
524
497
|
*/
|
|
525
498
|
async getInterruptedRuns(): Promise<WorkflowRunRecord[]> {
|
|
526
499
|
const rows = this.stmts!.getInterruptedRuns.all() as SQLiteRunRow[];
|
|
527
|
-
return rows.map(
|
|
500
|
+
return rows.map(row => this.mapRunRow(row));
|
|
528
501
|
}
|
|
529
502
|
|
|
530
503
|
/**
|
|
531
504
|
* Get the last completed step for a run.
|
|
532
505
|
* Useful for resuming from a checkpoint.
|
|
533
506
|
*/
|
|
534
|
-
async getLastCompletedStep(
|
|
535
|
-
runId
|
|
536
|
-
): Promise<WorkflowRunStepRecord | null> {
|
|
537
|
-
const row = this.stmts!.getLastCompletedStep.get(runId) as
|
|
538
|
-
| SQLiteStepRow
|
|
539
|
-
| undefined;
|
|
507
|
+
async getLastCompletedStep(runId: string): Promise<WorkflowRunStepRecord | null> {
|
|
508
|
+
const row = this.stmts!.getLastCompletedStep.get(runId) as SQLiteStepRow | undefined;
|
|
540
509
|
return row ? this.mapStepRow(row) : null;
|
|
541
510
|
}
|
|
542
511
|
|
|
@@ -553,6 +522,7 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
553
522
|
input: JSON.parse(row.input_json),
|
|
554
523
|
metadata: JSON.parse(row.metadata_json),
|
|
555
524
|
context: JSON.parse(row.context_json),
|
|
525
|
+
completedSteps: row.completed_steps_json ? JSON.parse(row.completed_steps_json) : undefined,
|
|
556
526
|
error: row.error_json ? JSON.parse(row.error_json) : undefined,
|
|
557
527
|
createdAt: new Date(row.created_at),
|
|
558
528
|
startedAt: row.started_at ? new Date(row.started_at) : undefined,
|
|
@@ -581,7 +551,7 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
581
551
|
runId: row.run_id,
|
|
582
552
|
stepKey: row.step_key ?? undefined,
|
|
583
553
|
eventType: row.event_type,
|
|
584
|
-
level: row.level as
|
|
554
|
+
level: row.level as 'info' | 'warn' | 'error',
|
|
585
555
|
payload: row.payload_json ? JSON.parse(row.payload_json) : undefined,
|
|
586
556
|
timestamp: new Date(row.timestamp),
|
|
587
557
|
};
|
|
@@ -602,15 +572,9 @@ export class SQLiteStorageAdapter implements StorageAdapter {
|
|
|
602
572
|
* Get database statistics.
|
|
603
573
|
*/
|
|
604
574
|
getStats(): { runs: number; steps: number; events: number } {
|
|
605
|
-
const runsCount = this.db
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
const stepsCount = this.db
|
|
609
|
-
.prepare("SELECT COUNT(*) as count FROM workflow_run_steps")
|
|
610
|
-
.get() as { count: number };
|
|
611
|
-
const eventsCount = this.db
|
|
612
|
-
.prepare("SELECT COUNT(*) as count FROM workflow_events")
|
|
613
|
-
.get() as { count: number };
|
|
575
|
+
const runsCount = this.db.prepare('SELECT COUNT(*) as count FROM workflow_runs').get() as { count: number };
|
|
576
|
+
const stepsCount = this.db.prepare('SELECT COUNT(*) as count FROM workflow_run_steps').get() as { count: number };
|
|
577
|
+
const eventsCount = this.db.prepare('SELECT COUNT(*) as count FROM workflow_events').get() as { count: number };
|
|
614
578
|
|
|
615
579
|
return {
|
|
616
580
|
runs: runsCount.count,
|
|
@@ -632,6 +596,7 @@ interface SQLiteRunRow {
|
|
|
632
596
|
input_json: string;
|
|
633
597
|
metadata_json: string;
|
|
634
598
|
context_json: string;
|
|
599
|
+
completed_steps_json: string | null;
|
|
635
600
|
error_json: string | null;
|
|
636
601
|
created_at: string;
|
|
637
602
|
started_at: string | null;
|
package/src/storage/types.ts
CHANGED
|
@@ -3,12 +3,7 @@
|
|
|
3
3
|
* Implement StorageAdapter to use your preferred database.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
7
|
-
WorkflowKind,
|
|
8
|
-
RunStatus,
|
|
9
|
-
StepStatus,
|
|
10
|
-
WorkflowError,
|
|
11
|
-
} from "../core/types";
|
|
6
|
+
import type { WorkflowKind, RunStatus, StepStatus, WorkflowError } from '../core/types';
|
|
12
7
|
|
|
13
8
|
// ============================================================================
|
|
14
9
|
// Extended Status Types (New)
|
|
@@ -19,25 +14,25 @@ import type {
|
|
|
19
14
|
* Adds 'pending' and 'timeout' to the core statuses.
|
|
20
15
|
*/
|
|
21
16
|
export type ExtendedRunStatus =
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
17
|
+
| 'pending'
|
|
18
|
+
| 'queued'
|
|
19
|
+
| 'running'
|
|
20
|
+
| 'succeeded'
|
|
21
|
+
| 'failed'
|
|
22
|
+
| 'canceled'
|
|
23
|
+
| 'timeout';
|
|
29
24
|
|
|
30
25
|
/**
|
|
31
26
|
* Extended status of a workflow step.
|
|
32
27
|
* Uses 'completed' instead of 'succeeded' for consistency.
|
|
33
28
|
*/
|
|
34
29
|
export type ExtendedStepStatus =
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
30
|
+
| 'pending'
|
|
31
|
+
| 'running'
|
|
32
|
+
| 'completed'
|
|
33
|
+
| 'failed'
|
|
34
|
+
| 'skipped'
|
|
35
|
+
| 'canceled';
|
|
41
36
|
|
|
42
37
|
// ============================================================================
|
|
43
38
|
// Legacy Record Types (Backward Compatible)
|
|
@@ -53,6 +48,7 @@ export interface WorkflowRunRecord {
|
|
|
53
48
|
parentRunId?: string;
|
|
54
49
|
input: Record<string, unknown>;
|
|
55
50
|
context: Record<string, unknown>;
|
|
51
|
+
completedSteps?: string[];
|
|
56
52
|
output?: Record<string, unknown>;
|
|
57
53
|
error?: { code: string; message: string };
|
|
58
54
|
metadata?: Record<string, unknown>;
|
|
@@ -87,7 +83,7 @@ export interface WorkflowEventRecord {
|
|
|
87
83
|
runId: string;
|
|
88
84
|
stepKey?: string;
|
|
89
85
|
eventType: string;
|
|
90
|
-
level:
|
|
86
|
+
level: 'info' | 'warn' | 'error';
|
|
91
87
|
payload?: unknown;
|
|
92
88
|
timestamp: Date;
|
|
93
89
|
}
|
|
@@ -189,8 +185,8 @@ export interface ListRunsOptions {
|
|
|
189
185
|
parentRunId?: string;
|
|
190
186
|
limit?: number;
|
|
191
187
|
offset?: number;
|
|
192
|
-
orderBy?:
|
|
193
|
-
orderDirection?:
|
|
188
|
+
orderBy?: 'createdAt' | 'startedAt' | 'finishedAt';
|
|
189
|
+
orderDirection?: 'asc' | 'desc';
|
|
194
190
|
}
|
|
195
191
|
|
|
196
192
|
/**
|
|
@@ -201,8 +197,8 @@ export interface ExtendedListRunsOptions {
|
|
|
201
197
|
status?: ExtendedRunStatus | ExtendedRunStatus[];
|
|
202
198
|
limit?: number;
|
|
203
199
|
offset?: number;
|
|
204
|
-
orderBy?:
|
|
205
|
-
orderDir?:
|
|
200
|
+
orderBy?: 'createdAt' | 'startedAt' | 'finishedAt';
|
|
201
|
+
orderDir?: 'asc' | 'desc';
|
|
206
202
|
}
|
|
207
203
|
|
|
208
204
|
/**
|
|
@@ -210,7 +206,7 @@ export interface ExtendedListRunsOptions {
|
|
|
210
206
|
*/
|
|
211
207
|
export interface ListEventsOptions {
|
|
212
208
|
stepKey?: string;
|
|
213
|
-
level?:
|
|
209
|
+
level?: 'info' | 'warn' | 'error';
|
|
214
210
|
limit?: number;
|
|
215
211
|
offset?: number;
|
|
216
212
|
}
|
|
@@ -238,30 +234,21 @@ export interface WorkflowStorage {
|
|
|
238
234
|
createRun(run: CreateRunInput): Promise<ExtendedWorkflowRunRecord>;
|
|
239
235
|
getRun(id: string): Promise<ExtendedWorkflowRunRecord | null>;
|
|
240
236
|
updateRun(id: string, updates: UpdateRunInput): Promise<void>;
|
|
241
|
-
listRuns(
|
|
242
|
-
options?: ExtendedListRunsOptions,
|
|
243
|
-
): Promise<PaginatedResult<ExtendedWorkflowRunRecord>>;
|
|
237
|
+
listRuns(options?: ExtendedListRunsOptions): Promise<PaginatedResult<ExtendedWorkflowRunRecord>>;
|
|
244
238
|
deleteRun(id: string): Promise<void>;
|
|
245
239
|
|
|
246
240
|
// Atomic dequeue for concurrency control
|
|
247
|
-
dequeueRun(
|
|
248
|
-
workflowKinds: string[],
|
|
249
|
-
): Promise<ExtendedWorkflowRunRecord | null>;
|
|
241
|
+
dequeueRun(workflowKinds: string[]): Promise<ExtendedWorkflowRunRecord | null>;
|
|
250
242
|
|
|
251
243
|
// Stale workflow cleanup
|
|
252
244
|
cleanupStaleRuns(defaultTimeoutMs?: number): Promise<number>;
|
|
253
245
|
markRunsAsFailed(runIds: string[], reason: string): Promise<void>;
|
|
254
246
|
|
|
255
247
|
// Step operations
|
|
256
|
-
getStepResult(
|
|
257
|
-
runId: string,
|
|
258
|
-
stepName: string,
|
|
259
|
-
): Promise<StepResult | undefined>;
|
|
248
|
+
getStepResult(runId: string, stepName: string): Promise<StepResult | undefined>;
|
|
260
249
|
getStepResults(runId: string): Promise<StepResult[]>;
|
|
261
250
|
getStepsForRun(runId: string): Promise<StepRecord[]>;
|
|
262
|
-
saveStepResult(
|
|
263
|
-
result: Omit<StepResult, "id"> & { id?: string },
|
|
264
|
-
): Promise<void>;
|
|
251
|
+
saveStepResult(result: Omit<StepResult, 'id'> & { id?: string }): Promise<void>;
|
|
265
252
|
|
|
266
253
|
// Lifecycle
|
|
267
254
|
initialize(): Promise<void>;
|
|
@@ -278,32 +265,20 @@ export interface WorkflowStorage {
|
|
|
278
265
|
*/
|
|
279
266
|
export interface StorageAdapter {
|
|
280
267
|
// Run operations
|
|
281
|
-
createRun(
|
|
282
|
-
run: Omit<WorkflowRunRecord, "id" | "createdAt">,
|
|
283
|
-
): Promise<WorkflowRunRecord>;
|
|
268
|
+
createRun(run: Omit<WorkflowRunRecord, 'id' | 'createdAt'>): Promise<WorkflowRunRecord>;
|
|
284
269
|
getRun(runId: string): Promise<WorkflowRunRecord | null>;
|
|
285
270
|
updateRun(runId: string, updates: Partial<WorkflowRunRecord>): Promise<void>;
|
|
286
|
-
listRuns(
|
|
287
|
-
options?: ListRunsOptions,
|
|
288
|
-
): Promise<PaginatedResult<WorkflowRunRecord>>;
|
|
271
|
+
listRuns(options?: ListRunsOptions): Promise<PaginatedResult<WorkflowRunRecord>>;
|
|
289
272
|
|
|
290
273
|
// Step operations
|
|
291
|
-
createStep(
|
|
292
|
-
step: Omit<WorkflowRunStepRecord, "id">,
|
|
293
|
-
): Promise<WorkflowRunStepRecord>;
|
|
274
|
+
createStep(step: Omit<WorkflowRunStepRecord, 'id'>): Promise<WorkflowRunStepRecord>;
|
|
294
275
|
getStep(stepId: string): Promise<WorkflowRunStepRecord | null>;
|
|
295
|
-
updateStep(
|
|
296
|
-
stepId: string,
|
|
297
|
-
updates: Partial<WorkflowRunStepRecord>,
|
|
298
|
-
): Promise<void>;
|
|
276
|
+
updateStep(stepId: string, updates: Partial<WorkflowRunStepRecord>): Promise<void>;
|
|
299
277
|
getStepsForRun(runId: string): Promise<WorkflowRunStepRecord[]>;
|
|
300
278
|
|
|
301
279
|
// Event operations
|
|
302
|
-
saveEvent(event: Omit<WorkflowEventRecord,
|
|
303
|
-
getEventsForRun(
|
|
304
|
-
runId: string,
|
|
305
|
-
options?: ListEventsOptions,
|
|
306
|
-
): Promise<WorkflowEventRecord[]>;
|
|
280
|
+
saveEvent(event: Omit<WorkflowEventRecord, 'id'>): Promise<void>;
|
|
281
|
+
getEventsForRun(runId: string, options?: ListEventsOptions): Promise<WorkflowEventRecord[]>;
|
|
307
282
|
|
|
308
283
|
/**
|
|
309
284
|
* Optional transaction support.
|
|
@@ -363,6 +338,6 @@ export interface StepflowStepResultsTable {
|
|
|
363
338
|
* Combined database schema for Stepflow.
|
|
364
339
|
*/
|
|
365
340
|
export interface StepflowDatabase {
|
|
366
|
-
|
|
367
|
-
|
|
341
|
+
'stepflow.runs': StepflowRunsTable;
|
|
342
|
+
'stepflow.step_results': StepflowStepResultsTable;
|
|
368
343
|
}
|