@cascade-flow/runner 0.2.4 → 0.2.6
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 +25 -78
- package/dist/checkpoint-ipc.d.ts +82 -0
- package/dist/checkpoint-ipc.d.ts.map +1 -0
- package/dist/index.d.ts +16 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +456 -503
- package/dist/index.js.map +8 -7
- package/dist/step-executor.d.ts +9 -12
- package/dist/step-executor.d.ts.map +1 -1
- package/dist/subprocess-executor.d.ts +6 -1
- package/dist/subprocess-executor.d.ts.map +1 -1
- package/dist/validation.d.ts +27 -0
- package/dist/validation.d.ts.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Runner
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Workflow discovery and step execution utilities used by the worker package.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,65 +8,35 @@ Core workflow execution engine for direct (non-queue) execution.
|
|
|
8
8
|
bun install
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Exports
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// Execute workflow
|
|
17
|
-
const results = await runAll({
|
|
18
|
-
workflow: "my-workflow",
|
|
19
|
-
input: { userId: "123" },
|
|
20
|
-
only: ["step1", "step2"], // Optional: run subset
|
|
21
|
-
resume: true, // Optional: resume from previous run
|
|
22
|
-
runId: "previous-run-id", // Optional: specific run to resume
|
|
23
|
-
});
|
|
24
|
-
```
|
|
14
|
+
// Step execution
|
|
15
|
+
executeStepInProcess(stepFile, stepId, dependencies, ctx, attemptNumber, backend, onLog?, options?): Promise<{ result, logs }>;
|
|
25
16
|
|
|
26
|
-
|
|
17
|
+
// Discovery
|
|
18
|
+
discoverWorkflows(dir?: string): Promise<WorkflowMetadata[]>;
|
|
19
|
+
discoverSteps(workflowDir: string): Promise<LoadedStep[]>;
|
|
27
20
|
|
|
28
|
-
|
|
21
|
+
// Versioning
|
|
22
|
+
calculateWorkflowHash(workflow): Promise<string>;
|
|
23
|
+
getGitInfo(dir): Promise<GitInfo | undefined>;
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
import { step as dependency } from "../other-step/step.ts";
|
|
25
|
+
// Validation
|
|
26
|
+
getAllDependents(stepId, steps): string[];
|
|
27
|
+
validateWorkflowVersion(workflowSlug, runId, currentVersionId, backend, log): Promise<string>;
|
|
34
28
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
exportOutput: true,
|
|
38
|
-
fn: async ({ dependencies, ctx }) => {
|
|
39
|
-
return { result: dependencies.dependency.value * 2 };
|
|
40
|
-
}
|
|
41
|
-
});
|
|
29
|
+
// Types
|
|
30
|
+
LoadedStep // Step with resolved dependencies
|
|
42
31
|
```
|
|
43
32
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
// workflows/my-workflow/input-schema.ts
|
|
48
|
-
import { z } from "zod";
|
|
49
|
-
export const inputSchema = z.object({
|
|
50
|
-
userId: z.string(),
|
|
51
|
-
count: z.number()
|
|
52
|
-
});
|
|
53
|
-
export type WorkflowInput = z.infer<typeof inputSchema>;
|
|
54
|
-
|
|
55
|
-
// workflows/my-workflow/defineStep.ts
|
|
56
|
-
import { baseDefineStep } from "runner";
|
|
57
|
-
import type { WorkflowInput } from "./input-schema";
|
|
58
|
-
export const defineStep = baseDefineStep<WorkflowInput>();
|
|
59
|
-
|
|
60
|
-
// workflows/my-workflow/steps/my-step/step.ts
|
|
61
|
-
import { defineStep } from "../../defineStep";
|
|
33
|
+
## Key Features
|
|
62
34
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
});
|
|
69
|
-
```
|
|
35
|
+
- **Workflow discovery** - Auto-discovers workflows from `./workflows/` directory
|
|
36
|
+
- **Step discovery** - Loads and wires step dependencies with full TypeScript inference
|
|
37
|
+
- **Subprocess execution** - Executes steps in isolated child processes
|
|
38
|
+
- **Cycle detection** - DFS validation prevents circular dependencies
|
|
39
|
+
- **Version tracking** - SHA-256 hashing for workflow version comparison
|
|
70
40
|
|
|
71
41
|
## Workflow Structure
|
|
72
42
|
|
|
@@ -74,37 +44,14 @@ export const step = defineStep({
|
|
|
74
44
|
workflows/my-workflow/
|
|
75
45
|
├── workflow.json # {"name": "My Workflow"}
|
|
76
46
|
├── input-schema.ts # Optional: Zod schema
|
|
77
|
-
├── defineStep.ts # Optional: Typed helper
|
|
78
47
|
└── steps/
|
|
79
48
|
├── step-1/step.ts # Flat step
|
|
80
49
|
├── step-2/step.ts # Flat step
|
|
81
50
|
└── data-processing/ # Optional: Group directory
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
└── transform/
|
|
85
|
-
└── normalize/step.ts # Nested step
|
|
51
|
+
└── extract/
|
|
52
|
+
└── fetch-data/step.ts # Nested step
|
|
86
53
|
```
|
|
87
54
|
|
|
88
|
-
##
|
|
89
|
-
|
|
90
|
-
- **Promise caching** - Automatic parallelization via cached promises
|
|
91
|
-
- **Type-safe dependencies** - Import step objects for full TypeScript inference
|
|
92
|
-
- **Cycle detection** - DFS validation prevents circular dependencies
|
|
93
|
-
- **Resume capability** - Continue from previous runs
|
|
94
|
-
- **Pluggable backend** - Abstract persistence layer
|
|
95
|
-
- **Nested step groups** - Organize steps in arbitrary directory hierarchies (purely organizational)
|
|
55
|
+
## Note
|
|
96
56
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
// Main execution
|
|
101
|
-
runAll(options: RunAllOptions): Promise<WorkflowOutput>;
|
|
102
|
-
|
|
103
|
-
// Step helpers
|
|
104
|
-
defineStep(config: StepConfig): StepDefinition;
|
|
105
|
-
baseDefineStep<TInput>(): typeof defineStep;
|
|
106
|
-
|
|
107
|
-
// Discovery
|
|
108
|
-
discoverWorkflows(dir?: string): Promise<WorkflowMetadata[]>;
|
|
109
|
-
discoverSteps(workflowDir: string): Promise<LoadedStep[]>;
|
|
110
|
-
```
|
|
57
|
+
For workflow authoring APIs (`defineStep`, `baseDefineStep`, `Skip`, `optional`), see the `@cascade-flow/workflow` package.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoint IPC Types and Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles communication between the subprocess (step execution) and parent process
|
|
5
|
+
* (worker) for checkpoint operations. Uses file-based IPC for simplicity.
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Subprocess writes request to req-{id}.json
|
|
9
|
+
* 2. Parent reads request, checks cache
|
|
10
|
+
* 3. Parent writes response to res-{id}.json (hit/miss)
|
|
11
|
+
* 4. If miss: subprocess executes fn, writes result to result-{id}.json
|
|
12
|
+
* 5. Parent persists checkpoint to backend
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Request from subprocess to parent for checkpoint lookup/save
|
|
16
|
+
*/
|
|
17
|
+
export type CheckpointRequest = {
|
|
18
|
+
requestId: string;
|
|
19
|
+
name: string;
|
|
20
|
+
sequenceNumber: number;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Response from parent to subprocess
|
|
24
|
+
*/
|
|
25
|
+
export type CheckpointResponse = {
|
|
26
|
+
requestId: string;
|
|
27
|
+
hit: boolean;
|
|
28
|
+
data?: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Result from subprocess after executing checkpoint function (on cache miss)
|
|
32
|
+
*/
|
|
33
|
+
export type CheckpointResult = {
|
|
34
|
+
requestId: string;
|
|
35
|
+
data: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Data passed to onCheckpoint callback
|
|
39
|
+
*/
|
|
40
|
+
export type CheckpointData = {
|
|
41
|
+
name: string;
|
|
42
|
+
sequenceNumber: number;
|
|
43
|
+
data: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Failure from subprocess when checkpoint function throws (on cache miss)
|
|
47
|
+
*/
|
|
48
|
+
export type CheckpointFailure = {
|
|
49
|
+
requestId: string;
|
|
50
|
+
name: string;
|
|
51
|
+
sequenceNumber: number;
|
|
52
|
+
error: string;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Data passed to onCheckpointFailed callback
|
|
56
|
+
*/
|
|
57
|
+
export type CheckpointFailedData = {
|
|
58
|
+
name: string;
|
|
59
|
+
sequenceNumber: number;
|
|
60
|
+
error: string;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Get path for checkpoint request file
|
|
64
|
+
*/
|
|
65
|
+
export declare function getRequestPath(dir: string, requestId: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* Get path for checkpoint response file
|
|
68
|
+
*/
|
|
69
|
+
export declare function getResponsePath(dir: string, requestId: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* Get path for checkpoint result file
|
|
72
|
+
*/
|
|
73
|
+
export declare function getResultPath(dir: string, requestId: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Get path for checkpoint failure file
|
|
76
|
+
*/
|
|
77
|
+
export declare function getFailurePath(dir: string, requestId: string): string;
|
|
78
|
+
/**
|
|
79
|
+
* Generate unique request ID for checkpoint IPC
|
|
80
|
+
*/
|
|
81
|
+
export declare function generateRequestId(): string;
|
|
82
|
+
//# sourceMappingURL=checkpoint-ipc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-ipc.d.ts","sourceRoot":"","sources":["../src/checkpoint-ipc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
import type { Backend, LogEntry } from "@cascade-flow/backend-interface";
|
|
2
2
|
import type { StepOutput, RunnerContext } from "@cascade-flow/workflow";
|
|
3
3
|
import type { LoadedStep } from "./types";
|
|
4
|
+
import type { CheckpointData, CheckpointFailedData } from "./checkpoint-ipc";
|
|
4
5
|
export type { LoadedStep };
|
|
6
|
+
export type { CheckpointData, CheckpointFailedData } from "./checkpoint-ipc";
|
|
5
7
|
/**
|
|
6
8
|
* Execute a step in an isolated child process
|
|
7
9
|
*
|
|
8
10
|
* Wrapper around executeStepInSubprocess that generates the output path.
|
|
11
|
+
*
|
|
12
|
+
* @param stepFile - Absolute path to the step.ts file
|
|
13
|
+
* @param stepId - Unique identifier of the step
|
|
14
|
+
* @param dependencies - Resolved dependency outputs
|
|
15
|
+
* @param ctx - Runner context passed to step
|
|
16
|
+
* @param attemptNumber - Current attempt number (for retries)
|
|
17
|
+
* @param backend - Backend for generating output path
|
|
18
|
+
* @param onLog - Optional callback for real-time log emission
|
|
19
|
+
* @param onCheckpoint - Optional callback for persisting checkpoints
|
|
20
|
+
* @param onCheckpointFailed - Optional callback for persisting checkpoint failures
|
|
21
|
+
* @param existingCheckpoints - Existing checkpoints to replay (name -> data[] by sequence)
|
|
22
|
+
* @param options - Additional options (signal for abort)
|
|
9
23
|
*/
|
|
10
|
-
export declare function executeStepInProcess(stepFile: string, stepId: string, dependencies: Record<string, unknown>, ctx: RunnerContext, attemptNumber: number, backend: Backend, onLog?: (log: LogEntry) => void | Promise<void>, options?: {
|
|
24
|
+
export declare function executeStepInProcess(stepFile: string, stepId: string, dependencies: Record<string, unknown>, ctx: RunnerContext, attemptNumber: number, backend: Backend, onLog?: (log: LogEntry) => void | Promise<void>, onCheckpoint?: (checkpoint: CheckpointData) => Promise<void>, onCheckpointFailed?: (checkpoint: CheckpointFailedData) => Promise<void>, existingCheckpoints?: Map<string, string[]>, options?: {
|
|
11
25
|
signal?: AbortSignal;
|
|
12
26
|
}): Promise<{
|
|
13
27
|
result: StepOutput;
|
|
14
28
|
logs: LogEntry[];
|
|
15
29
|
}>;
|
|
16
|
-
export declare function runAll(options: {
|
|
17
|
-
workflow: string;
|
|
18
|
-
only?: string[];
|
|
19
|
-
ctx?: Partial<RunnerContext>;
|
|
20
|
-
resume?: boolean;
|
|
21
|
-
runId?: string;
|
|
22
|
-
backend: Backend;
|
|
23
|
-
input?: unknown;
|
|
24
|
-
}): Promise<Record<string, StepOutput>>;
|
|
25
30
|
export { discoverWorkflows, discoverSteps } from "./discovery";
|
|
26
31
|
export { calculateWorkflowHash, getGitInfo } from "./versioning";
|
|
32
|
+
export { getAllDependents, validateWorkflowVersion } from "./validation";
|
|
27
33
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG7E,YAAY,EAAE,UAAU,EAAE,CAAC;AAG3B,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,GAAG,EAAE,aAAa,EAClB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC/C,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,EAC5D,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,EACxE,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC3C,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GACjC,OAAO,CAAC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,QAAQ,EAAE,CAAA;CAAE,CAAC,CAuBnD;AAGD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG/D,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAGjE,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
|