@cascade-flow/client 0.1.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 +114 -0
- package/dist/index.d.ts +613 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +247 -0
- package/dist/index.js.map +10 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# @cascadeflow/client
|
|
2
|
+
|
|
3
|
+
Type-safe programmatic client for submitting and managing workflow runs.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
The client requires a backend implementation to persist workflow state. Install the client along with your chosen backend:
|
|
8
|
+
|
|
9
|
+
### With Filesystem Backend (Recommended for Development)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @cascadeflow/client @cascadeflow/backend-filesystem
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### With PostgreSQL Backend (Production)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @cascadeflow/client @cascadeflow/backend-postgres
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { WorkflowClient } from "@cascadeflow/client";
|
|
25
|
+
import { FileSystemBackend } from "@cascadeflow/backend-filesystem";
|
|
26
|
+
|
|
27
|
+
const client = new WorkflowClient(new FileSystemBackend("./.runs"));
|
|
28
|
+
|
|
29
|
+
// Submit run
|
|
30
|
+
const { runId } = await client.submit({
|
|
31
|
+
workflow: "my-workflow",
|
|
32
|
+
input: { userId: "123", count: 42 },
|
|
33
|
+
priority: 10,
|
|
34
|
+
timeout: 300000
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Wait for completion
|
|
38
|
+
const output = await client.waitForCompletion(runId, {
|
|
39
|
+
timeout: 60000,
|
|
40
|
+
exponentialBackoff: true
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Check status
|
|
44
|
+
const info = await client.getRun(runId);
|
|
45
|
+
|
|
46
|
+
// Cancel
|
|
47
|
+
await client.cancel(runId, "reason");
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Type Safety
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
interface MyInput { userId: string; count: number; }
|
|
54
|
+
interface MyOutput { results: string[]; }
|
|
55
|
+
|
|
56
|
+
const { runId } = await client.submit<MyInput>({
|
|
57
|
+
workflow: "my-workflow",
|
|
58
|
+
input: { userId: "123", count: 42 } // Type-checked
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const output = await client.waitForCompletion<MyOutput>(runId);
|
|
62
|
+
console.log(output.results); // Type-safe access
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Methods
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
// Submit run
|
|
69
|
+
submit<TInput>(params: {
|
|
70
|
+
workflow: string;
|
|
71
|
+
input?: TInput;
|
|
72
|
+
priority?: number;
|
|
73
|
+
timeout?: number;
|
|
74
|
+
idempotencyKey?: string;
|
|
75
|
+
metadata?: Record<string, unknown>;
|
|
76
|
+
tags?: string[];
|
|
77
|
+
}): Promise<{ runId: string; isNew: boolean }>;
|
|
78
|
+
|
|
79
|
+
// Get status
|
|
80
|
+
getStatus(runId: string): Promise<RunStatus>;
|
|
81
|
+
|
|
82
|
+
// Get detailed info
|
|
83
|
+
getRun(runId: string): Promise<RunState | null>;
|
|
84
|
+
|
|
85
|
+
// Wait for completion
|
|
86
|
+
waitForCompletion<TOutput>(runId: string, options?: {
|
|
87
|
+
interval?: number;
|
|
88
|
+
exponentialBackoff?: boolean;
|
|
89
|
+
maxBackoff?: number;
|
|
90
|
+
timeout?: number;
|
|
91
|
+
}): Promise<TOutput>;
|
|
92
|
+
|
|
93
|
+
// List runs
|
|
94
|
+
listRuns(options?: { status?: RunStatus; limit?: number }): Promise<RunState[]>;
|
|
95
|
+
|
|
96
|
+
// Cancel run
|
|
97
|
+
cancel(runId: string, reason?: string): Promise<void>;
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Timeouts
|
|
101
|
+
|
|
102
|
+
**3-tier fallback for step execution:**
|
|
103
|
+
1. Step-level: `defineStep({ timeoutMs })`
|
|
104
|
+
2. **Submission-level: `submit({ timeout })`** ← This package
|
|
105
|
+
3. System default: 300000ms (5 min)
|
|
106
|
+
|
|
107
|
+
Submission timeout sets workflow-wide execution limit for steps without their own `timeoutMs`.
|
|
108
|
+
|
|
109
|
+
## CLI Integration
|
|
110
|
+
|
|
111
|
+
Used internally by:
|
|
112
|
+
- `cf submit` → `client.submit()`
|
|
113
|
+
- `cf status` → `client.getRun()`
|
|
114
|
+
- `cf cancel` → `client.cancel()`
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
import type { Backend, RunState, WorkflowMetadata, AnalyticsOptions, ErrorAnalysis, RetryAnalysis, SchedulingLatency, StepDuration, WorkflowDuration, WorkerStability, Throughput, QueueDepth, QueueDepthByWorkflow, SuccessRate, AnalyticsSummary, StepEvent, StepState, LogEntry } from "@cascade-flow/backend-interface";
|
|
2
|
+
import { type AttemptMetadata } from "@cascade-flow/backend-interface";
|
|
3
|
+
import type { PollOptions, ListRunsOptions, RunInfo } from "./types.ts";
|
|
4
|
+
/**
|
|
5
|
+
* WorkflowClient - submit and manage workflow runs via queue
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Type-safe submission with generic input types
|
|
9
|
+
* - Status checking and polling
|
|
10
|
+
* - Wait for completion with timeout
|
|
11
|
+
* - List and filter runs
|
|
12
|
+
* - Cancellation support
|
|
13
|
+
*/
|
|
14
|
+
export declare class WorkflowClient {
|
|
15
|
+
private backend;
|
|
16
|
+
constructor(backend: Backend);
|
|
17
|
+
/**
|
|
18
|
+
* Submit a workflow run to the queue
|
|
19
|
+
*
|
|
20
|
+
* Generic type TInput provides type safety for workflow input
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import type { WorkflowInput } from './workflows/my-workflow/input-schema';
|
|
25
|
+
*
|
|
26
|
+
* const { runId } = await client.submit<WorkflowInput>({
|
|
27
|
+
* workflow: 'my-workflow',
|
|
28
|
+
* input: { userId: "123", count: 42 } // Fully typed!
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
submit<TInput = unknown>(params: {
|
|
33
|
+
workflow: string;
|
|
34
|
+
input?: TInput;
|
|
35
|
+
runId?: string;
|
|
36
|
+
availableAt?: number;
|
|
37
|
+
priority?: number;
|
|
38
|
+
timeout?: number;
|
|
39
|
+
idempotencyKey?: string;
|
|
40
|
+
metadata?: Record<string, unknown>;
|
|
41
|
+
tags?: string[];
|
|
42
|
+
}): Promise<{
|
|
43
|
+
runId: string;
|
|
44
|
+
isNew: boolean;
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Get the current status of a run
|
|
48
|
+
*
|
|
49
|
+
* @param runId - The run ID to query
|
|
50
|
+
* @returns Run state or null if not found
|
|
51
|
+
*/
|
|
52
|
+
getStatus(runId: string): Promise<RunState | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Get detailed run information including output/error
|
|
55
|
+
*
|
|
56
|
+
* @param runId - The run ID to query
|
|
57
|
+
* @returns Extended run info or null if not found
|
|
58
|
+
*/
|
|
59
|
+
getRun(runId: string): Promise<RunInfo | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Wait for a run to complete
|
|
62
|
+
*
|
|
63
|
+
* Polls the backend until the run reaches a terminal state (completed/failed/cancelled)
|
|
64
|
+
*
|
|
65
|
+
* @param runId - The run ID to wait for
|
|
66
|
+
* @param options - Polling options
|
|
67
|
+
* @returns Run info when complete
|
|
68
|
+
* @throws Error if timeout or run fails
|
|
69
|
+
*/
|
|
70
|
+
waitForCompletion<TOutput = unknown>(runId: string, options?: PollOptions): Promise<TOutput>;
|
|
71
|
+
/**
|
|
72
|
+
* List runs matching filters
|
|
73
|
+
*
|
|
74
|
+
* @param options - Filter options
|
|
75
|
+
* @returns Array of run states
|
|
76
|
+
*/
|
|
77
|
+
listRuns(options?: ListRunsOptions): Promise<RunState[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Cancel a run
|
|
80
|
+
*
|
|
81
|
+
* Can cancel runs in pending, claimed, or running status
|
|
82
|
+
*
|
|
83
|
+
* @param runId - The run to cancel
|
|
84
|
+
* @param reason - Optional cancellation reason
|
|
85
|
+
*/
|
|
86
|
+
cancel(runId: string, reason?: string): Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Retry a failed workflow
|
|
89
|
+
*
|
|
90
|
+
* Retries all failed steps in the workflow, keeping successful steps from the original run.
|
|
91
|
+
* Step attempt numbers are reset to 1 for each retried step.
|
|
92
|
+
*
|
|
93
|
+
* @param runId - The run ID to retry
|
|
94
|
+
* @param reason - Optional reason for retry
|
|
95
|
+
* @returns Retry information including new workflow attempt number
|
|
96
|
+
* @throws Error if run is not in failed status
|
|
97
|
+
*/
|
|
98
|
+
retry(runId: string, reason?: string): Promise<{
|
|
99
|
+
runId: string;
|
|
100
|
+
workflowAttemptNumber: number;
|
|
101
|
+
retriedSteps: string[];
|
|
102
|
+
}>;
|
|
103
|
+
/**
|
|
104
|
+
* List all available workflows
|
|
105
|
+
*
|
|
106
|
+
* @returns Array of workflow metadata
|
|
107
|
+
*/
|
|
108
|
+
listWorkflows(): Promise<WorkflowMetadata[]>;
|
|
109
|
+
/**
|
|
110
|
+
* Get metadata for a specific workflow
|
|
111
|
+
*
|
|
112
|
+
* @param workflowSlug - Workflow identifier (directory name)
|
|
113
|
+
* @returns Workflow metadata or null if not found
|
|
114
|
+
*/
|
|
115
|
+
getWorkflowMetadata(workflowSlug: string): Promise<WorkflowMetadata | null>;
|
|
116
|
+
/**
|
|
117
|
+
* Get step definitions for a specific workflow
|
|
118
|
+
*
|
|
119
|
+
* @param workflowSlug - Workflow identifier (directory name)
|
|
120
|
+
* @returns Array of step definitions or empty array if workflow not found
|
|
121
|
+
*/
|
|
122
|
+
getWorkflowSteps(workflowSlug: string): Promise<any[]>;
|
|
123
|
+
/**
|
|
124
|
+
* Get the JSON Schema for a workflow's input
|
|
125
|
+
*
|
|
126
|
+
* @param workflowSlug - Workflow identifier (directory name)
|
|
127
|
+
* @returns JSON Schema object or null if workflow has no input schema
|
|
128
|
+
*/
|
|
129
|
+
getWorkflowSchema(workflowSlug: string): Promise<any | null>;
|
|
130
|
+
/**
|
|
131
|
+
* Helper to sleep
|
|
132
|
+
*/
|
|
133
|
+
private sleep;
|
|
134
|
+
/**
|
|
135
|
+
* Get error analysis for workflows and steps
|
|
136
|
+
*
|
|
137
|
+
* Analyzes failure patterns, error types, and common error messages.
|
|
138
|
+
*
|
|
139
|
+
* @param options - Optional filters for time range, workflow, or step
|
|
140
|
+
* @returns Error analysis data
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* // Get errors for last 24 hours (default)
|
|
145
|
+
* const errors = await client.getErrorAnalysis();
|
|
146
|
+
*
|
|
147
|
+
* // Get errors for specific workflow
|
|
148
|
+
* const errors = await client.getErrorAnalysis({
|
|
149
|
+
* workflowSlug: 'my-workflow',
|
|
150
|
+
* startUs: Date.now() * 1000 - 7 * 24 * 60 * 60 * 1000 * 1000 // Last 7 days
|
|
151
|
+
* });
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
getErrorAnalysis(options?: AnalyticsOptions): Promise<ErrorAnalysis>;
|
|
155
|
+
/**
|
|
156
|
+
* Get retry analysis metrics
|
|
157
|
+
*
|
|
158
|
+
* Analyzes retry patterns, success rates after retries, and retry effectiveness.
|
|
159
|
+
*
|
|
160
|
+
* @param options - Optional filters for time range, workflow, or step
|
|
161
|
+
* @returns Retry analysis data
|
|
162
|
+
*/
|
|
163
|
+
getRetryAnalysis(options?: AnalyticsOptions): Promise<RetryAnalysis>;
|
|
164
|
+
/**
|
|
165
|
+
* Get scheduling latency metrics
|
|
166
|
+
*
|
|
167
|
+
* Measures time between step being scheduled and actually starting execution.
|
|
168
|
+
* High latency indicates worker starvation or queue congestion.
|
|
169
|
+
*
|
|
170
|
+
* @param options - Optional filters for time range, workflow, or step
|
|
171
|
+
* @returns Scheduling latency statistics
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* const latency = await client.getSchedulingLatency({ workflowSlug: 'my-workflow' });
|
|
176
|
+
* console.log(`Average wait time: ${latency.averageUs / 1000}ms`);
|
|
177
|
+
* console.log(`P95 wait time: ${latency.p95Us / 1000}ms`);
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
getSchedulingLatency(options?: AnalyticsOptions): Promise<SchedulingLatency>;
|
|
181
|
+
/**
|
|
182
|
+
* Get step duration metrics
|
|
183
|
+
*
|
|
184
|
+
* Analyzes how long steps take to execute.
|
|
185
|
+
*
|
|
186
|
+
* @param options - Optional filters for time range, workflow, or step
|
|
187
|
+
* @returns Step duration statistics
|
|
188
|
+
*/
|
|
189
|
+
getStepDuration(options?: AnalyticsOptions): Promise<StepDuration>;
|
|
190
|
+
/**
|
|
191
|
+
* Get workflow duration metrics
|
|
192
|
+
*
|
|
193
|
+
* Analyzes end-to-end workflow execution time (from submission to completion).
|
|
194
|
+
*
|
|
195
|
+
* @param options - Optional filters for time range or workflow
|
|
196
|
+
* @returns Workflow duration statistics
|
|
197
|
+
*/
|
|
198
|
+
getWorkflowDuration(options?: AnalyticsOptions): Promise<WorkflowDuration>;
|
|
199
|
+
/**
|
|
200
|
+
* Get worker stability metrics
|
|
201
|
+
*
|
|
202
|
+
* Analyzes worker crashes, reclamations, and stale heartbeats.
|
|
203
|
+
*
|
|
204
|
+
* @param options - Optional filters for time range
|
|
205
|
+
* @returns Worker stability data
|
|
206
|
+
*/
|
|
207
|
+
getWorkerStability(options?: AnalyticsOptions): Promise<WorkerStability>;
|
|
208
|
+
/**
|
|
209
|
+
* Get throughput metrics
|
|
210
|
+
*
|
|
211
|
+
* Analyzes how many runs/steps are being completed per unit time.
|
|
212
|
+
*
|
|
213
|
+
* @param options - Optional filters for time range or workflow
|
|
214
|
+
* @returns Throughput data
|
|
215
|
+
*/
|
|
216
|
+
getThroughput(options?: AnalyticsOptions): Promise<Throughput>;
|
|
217
|
+
/**
|
|
218
|
+
* Get current queue depth
|
|
219
|
+
*
|
|
220
|
+
* Real-time snapshot of pending/running runs and steps.
|
|
221
|
+
*
|
|
222
|
+
* @param options - Optional filter for workflow
|
|
223
|
+
* @returns Queue depth data
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```typescript
|
|
227
|
+
* const depth = await client.getQueueDepth();
|
|
228
|
+
* console.log(`Pending runs: ${depth.pendingRuns}`);
|
|
229
|
+
* console.log(`Scheduled steps: ${depth.scheduledSteps}`);
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
getQueueDepth(options?: Pick<AnalyticsOptions, "workflowSlug">): Promise<QueueDepth>;
|
|
233
|
+
/**
|
|
234
|
+
* Get queue depth broken down by workflow
|
|
235
|
+
*
|
|
236
|
+
* Real-time snapshot showing per-workflow queue statistics.
|
|
237
|
+
* Useful for identifying which workflows have pending work.
|
|
238
|
+
*
|
|
239
|
+
* @returns Array of per-workflow queue depth data
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```typescript
|
|
243
|
+
* const breakdown = await client.getQueueDepthByWorkflow();
|
|
244
|
+
* for (const workflow of breakdown) {
|
|
245
|
+
* console.log(`${workflow.workflowName}: ${workflow.pendingRuns} pending, ${workflow.scheduledSteps} scheduled`);
|
|
246
|
+
* }
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
getQueueDepthByWorkflow(): Promise<QueueDepthByWorkflow>;
|
|
250
|
+
/**
|
|
251
|
+
* Get success/failure rate metrics
|
|
252
|
+
*
|
|
253
|
+
* Analyzes overall health of workflows and steps.
|
|
254
|
+
*
|
|
255
|
+
* @param options - Optional filters for time range, workflow, or step
|
|
256
|
+
* @returns Success rate data
|
|
257
|
+
*/
|
|
258
|
+
getSuccessRate(options?: AnalyticsOptions): Promise<SuccessRate>;
|
|
259
|
+
/**
|
|
260
|
+
* Get comprehensive analytics summary
|
|
261
|
+
*
|
|
262
|
+
* Combines all analytics metrics into a single response.
|
|
263
|
+
* Useful for dashboard views.
|
|
264
|
+
*
|
|
265
|
+
* @param options - Optional filters for time range or workflow
|
|
266
|
+
* @returns Complete analytics summary
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```typescript
|
|
270
|
+
* // Get full analytics for last 24 hours
|
|
271
|
+
* const summary = await client.getAnalyticsSummary();
|
|
272
|
+
*
|
|
273
|
+
* // Get analytics for specific workflow over last week
|
|
274
|
+
* const summary = await client.getAnalyticsSummary({
|
|
275
|
+
* workflowSlug: 'my-workflow',
|
|
276
|
+
* startUs: Date.now() * 1000 - 7 * 24 * 60 * 60 * 1000 * 1000
|
|
277
|
+
* });
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
280
|
+
getAnalyticsSummary(options?: AnalyticsOptions): Promise<AnalyticsSummary>;
|
|
281
|
+
/**
|
|
282
|
+
* Get paginated list of errors grouped by fingerprint
|
|
283
|
+
*
|
|
284
|
+
* @param options - Filtering and pagination options
|
|
285
|
+
* @returns Paginated list of error groups
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```typescript
|
|
289
|
+
* // Get errors for last 24h
|
|
290
|
+
* const { errors, total } = await client.getErrorsList({
|
|
291
|
+
* timeRange: { start: Date.now() * 1000 - 86400000000, end: Date.now() * 1000 },
|
|
292
|
+
* groupingStrategy: 'exact',
|
|
293
|
+
* limit: 50,
|
|
294
|
+
* offset: 0
|
|
295
|
+
* });
|
|
296
|
+
* ```
|
|
297
|
+
*/
|
|
298
|
+
getErrorsList(options?: {
|
|
299
|
+
timeRange?: {
|
|
300
|
+
start: number;
|
|
301
|
+
end: number;
|
|
302
|
+
};
|
|
303
|
+
workflowSlug?: string;
|
|
304
|
+
groupingStrategy?: 'exact' | 'normalized' | 'portable';
|
|
305
|
+
limit?: number;
|
|
306
|
+
offset?: number;
|
|
307
|
+
}): Promise<{
|
|
308
|
+
errors: Array<{
|
|
309
|
+
fingerprint: string;
|
|
310
|
+
errorMessage: string;
|
|
311
|
+
errorName: string;
|
|
312
|
+
sampleStack: string;
|
|
313
|
+
count: number;
|
|
314
|
+
affectedRuns: number;
|
|
315
|
+
firstSeen: number;
|
|
316
|
+
lastSeen: number;
|
|
317
|
+
}>;
|
|
318
|
+
total: number;
|
|
319
|
+
}>;
|
|
320
|
+
/**
|
|
321
|
+
* Get detailed information about a specific error by fingerprint
|
|
322
|
+
*
|
|
323
|
+
* @param fingerprint - Composite fingerprint (nameHash:messageHash:stackHash)
|
|
324
|
+
* @param groupingStrategy - Which stack hash variant to use
|
|
325
|
+
* @param options - Filtering and pagination options
|
|
326
|
+
* @returns Error details with all occurrences
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```typescript
|
|
330
|
+
* const detail = await client.getErrorDetail(
|
|
331
|
+
* 'abc123:def456:ghi789',
|
|
332
|
+
* 'exact',
|
|
333
|
+
* { limit: 100, offset: 0 }
|
|
334
|
+
* );
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
337
|
+
getErrorDetail(fingerprint: string, groupingStrategy: 'exact' | 'normalized' | 'portable', options?: {
|
|
338
|
+
timeRange?: {
|
|
339
|
+
start: number;
|
|
340
|
+
end: number;
|
|
341
|
+
};
|
|
342
|
+
limit?: number;
|
|
343
|
+
offset?: number;
|
|
344
|
+
}): Promise<{
|
|
345
|
+
fingerprint: string;
|
|
346
|
+
errorMessage: string;
|
|
347
|
+
errorName: string;
|
|
348
|
+
sampleStack: string;
|
|
349
|
+
totalCount: number;
|
|
350
|
+
affectedRuns: number;
|
|
351
|
+
firstSeen: number;
|
|
352
|
+
lastSeen: number;
|
|
353
|
+
occurrences: Array<{
|
|
354
|
+
workflowSlug: string;
|
|
355
|
+
runId: string;
|
|
356
|
+
stepId: string;
|
|
357
|
+
attemptNumber: number;
|
|
358
|
+
timestampUs: number;
|
|
359
|
+
}>;
|
|
360
|
+
total: number;
|
|
361
|
+
}>;
|
|
362
|
+
/**
|
|
363
|
+
* Get the state of all steps for a run
|
|
364
|
+
* Projects step events to compute current state
|
|
365
|
+
*/
|
|
366
|
+
getStepStates(workflowSlug: string, runId: string): Promise<StepState[]>;
|
|
367
|
+
/**
|
|
368
|
+
* Get all events for a specific run (both workflow and step events)
|
|
369
|
+
*/
|
|
370
|
+
getRunEvents(workflowSlug: string, runId: string): Promise<({
|
|
371
|
+
eventId: string;
|
|
372
|
+
timestampUs: number;
|
|
373
|
+
workflowSlug: string;
|
|
374
|
+
runId: string;
|
|
375
|
+
category: "step";
|
|
376
|
+
stepId: string;
|
|
377
|
+
type: "StepStarted";
|
|
378
|
+
workerId: string;
|
|
379
|
+
dependencies: string[];
|
|
380
|
+
attemptNumber: number;
|
|
381
|
+
} | {
|
|
382
|
+
eventId: string;
|
|
383
|
+
timestampUs: number;
|
|
384
|
+
workflowSlug: string;
|
|
385
|
+
runId: string;
|
|
386
|
+
category: "step";
|
|
387
|
+
stepId: string;
|
|
388
|
+
type: "StepCompleted";
|
|
389
|
+
output: string;
|
|
390
|
+
durationUs: number;
|
|
391
|
+
attemptNumber: number;
|
|
392
|
+
exportOutput: boolean;
|
|
393
|
+
} | {
|
|
394
|
+
eventId: string;
|
|
395
|
+
timestampUs: number;
|
|
396
|
+
workflowSlug: string;
|
|
397
|
+
runId: string;
|
|
398
|
+
category: "step";
|
|
399
|
+
stepId: string;
|
|
400
|
+
type: "StepFailed";
|
|
401
|
+
error: {
|
|
402
|
+
message: string;
|
|
403
|
+
stack?: string | undefined;
|
|
404
|
+
name?: string | undefined;
|
|
405
|
+
};
|
|
406
|
+
errorFingerprints: {
|
|
407
|
+
nameHash: string;
|
|
408
|
+
messageHash: string;
|
|
409
|
+
stackExactHash: string;
|
|
410
|
+
stackNormalizedHash: string;
|
|
411
|
+
stackPortableHash: string;
|
|
412
|
+
};
|
|
413
|
+
durationUs: number;
|
|
414
|
+
attemptNumber: number;
|
|
415
|
+
terminal: boolean;
|
|
416
|
+
failureReason: "timeout" | "cancelled" | "worker-crash" | "exhausted-retries" | "execution-error";
|
|
417
|
+
nextRetryAtUs?: number | undefined;
|
|
418
|
+
} | {
|
|
419
|
+
eventId: string;
|
|
420
|
+
timestampUs: number;
|
|
421
|
+
workflowSlug: string;
|
|
422
|
+
runId: string;
|
|
423
|
+
category: "step";
|
|
424
|
+
stepId: string;
|
|
425
|
+
type: "LogEntry";
|
|
426
|
+
stream: "stdout" | "stderr";
|
|
427
|
+
message: string;
|
|
428
|
+
attemptNumber: number;
|
|
429
|
+
} | {
|
|
430
|
+
eventId: string;
|
|
431
|
+
timestampUs: number;
|
|
432
|
+
workflowSlug: string;
|
|
433
|
+
runId: string;
|
|
434
|
+
category: "step";
|
|
435
|
+
stepId: string;
|
|
436
|
+
type: "StepRetrying";
|
|
437
|
+
attemptNumber: number;
|
|
438
|
+
nextAttempt: number;
|
|
439
|
+
error: {
|
|
440
|
+
message: string;
|
|
441
|
+
stack?: string | undefined;
|
|
442
|
+
name?: string | undefined;
|
|
443
|
+
};
|
|
444
|
+
maxRetries: number;
|
|
445
|
+
} | {
|
|
446
|
+
eventId: string;
|
|
447
|
+
timestampUs: number;
|
|
448
|
+
workflowSlug: string;
|
|
449
|
+
runId: string;
|
|
450
|
+
category: "step";
|
|
451
|
+
stepId: string;
|
|
452
|
+
type: "StepScheduled";
|
|
453
|
+
availableAtUs: number;
|
|
454
|
+
reason: "retry" | "initial" | "dependency-satisfied";
|
|
455
|
+
attemptNumber: number;
|
|
456
|
+
retryDelayMs?: number | undefined;
|
|
457
|
+
} | {
|
|
458
|
+
eventId: string;
|
|
459
|
+
workflowSlug: string;
|
|
460
|
+
runId: string;
|
|
461
|
+
category: "step";
|
|
462
|
+
stepId: string;
|
|
463
|
+
type: "StepHeartbeat";
|
|
464
|
+
workerId: string;
|
|
465
|
+
timestampUs: number;
|
|
466
|
+
attemptNumber: number;
|
|
467
|
+
} | {
|
|
468
|
+
eventId: string;
|
|
469
|
+
timestampUs: number;
|
|
470
|
+
workflowSlug: string;
|
|
471
|
+
runId: string;
|
|
472
|
+
category: "step";
|
|
473
|
+
stepId: string;
|
|
474
|
+
type: "StepReclaimed";
|
|
475
|
+
originalWorkerId: string;
|
|
476
|
+
reclaimedBy: string;
|
|
477
|
+
lastHeartbeatUs: number;
|
|
478
|
+
staleThresholdUs: number;
|
|
479
|
+
staleDurationUs: number;
|
|
480
|
+
attemptNumber: number;
|
|
481
|
+
} | {
|
|
482
|
+
eventId: string;
|
|
483
|
+
timestampUs: number;
|
|
484
|
+
workflowSlug: string;
|
|
485
|
+
runId: string;
|
|
486
|
+
category: "step";
|
|
487
|
+
stepId: string;
|
|
488
|
+
type: "StepSkipped";
|
|
489
|
+
skipType: "primary" | "cascade";
|
|
490
|
+
reason: string;
|
|
491
|
+
durationUs: number;
|
|
492
|
+
attemptNumber: number;
|
|
493
|
+
metadata?: Record<string, any> | undefined;
|
|
494
|
+
cascadedFrom?: string | undefined;
|
|
495
|
+
} | {
|
|
496
|
+
eventId: string;
|
|
497
|
+
timestampUs: number;
|
|
498
|
+
workflowSlug: string;
|
|
499
|
+
runId: string;
|
|
500
|
+
category: "workflow";
|
|
501
|
+
type: "RunSubmitted";
|
|
502
|
+
availableAtUs: number;
|
|
503
|
+
priority: number;
|
|
504
|
+
hasInputSchema: boolean;
|
|
505
|
+
input?: string | undefined;
|
|
506
|
+
timeoutUs?: number | undefined;
|
|
507
|
+
idempotencyKey?: string | undefined;
|
|
508
|
+
metadata?: Record<string, any> | undefined;
|
|
509
|
+
tags?: string[] | undefined;
|
|
510
|
+
} | {
|
|
511
|
+
eventId: string;
|
|
512
|
+
timestampUs: number;
|
|
513
|
+
workflowSlug: string;
|
|
514
|
+
runId: string;
|
|
515
|
+
category: "workflow";
|
|
516
|
+
type: "WorkflowStarted";
|
|
517
|
+
workflowAttemptNumber: number;
|
|
518
|
+
hasInputSchema: boolean;
|
|
519
|
+
hasInput: boolean;
|
|
520
|
+
} | {
|
|
521
|
+
eventId: string;
|
|
522
|
+
timestampUs: number;
|
|
523
|
+
workflowSlug: string;
|
|
524
|
+
runId: string;
|
|
525
|
+
category: "workflow";
|
|
526
|
+
type: "WorkflowInputValidation";
|
|
527
|
+
workflowAttemptNumber: number;
|
|
528
|
+
hasSchema: boolean;
|
|
529
|
+
success: boolean;
|
|
530
|
+
error?: {
|
|
531
|
+
message: string;
|
|
532
|
+
stack?: string | undefined;
|
|
533
|
+
name?: string | undefined;
|
|
534
|
+
} | undefined;
|
|
535
|
+
validationErrors?: {
|
|
536
|
+
path: string;
|
|
537
|
+
message: string;
|
|
538
|
+
}[] | undefined;
|
|
539
|
+
} | {
|
|
540
|
+
eventId: string;
|
|
541
|
+
timestampUs: number;
|
|
542
|
+
workflowSlug: string;
|
|
543
|
+
runId: string;
|
|
544
|
+
category: "workflow";
|
|
545
|
+
type: "WorkflowCompleted";
|
|
546
|
+
workflowAttemptNumber: number;
|
|
547
|
+
output: string;
|
|
548
|
+
durationUs: number;
|
|
549
|
+
totalSteps: number;
|
|
550
|
+
} | {
|
|
551
|
+
eventId: string;
|
|
552
|
+
timestampUs: number;
|
|
553
|
+
workflowSlug: string;
|
|
554
|
+
runId: string;
|
|
555
|
+
category: "workflow";
|
|
556
|
+
type: "WorkflowFailed";
|
|
557
|
+
workflowAttemptNumber: number;
|
|
558
|
+
error: {
|
|
559
|
+
message: string;
|
|
560
|
+
stack?: string | undefined;
|
|
561
|
+
name?: string | undefined;
|
|
562
|
+
};
|
|
563
|
+
durationUs: number;
|
|
564
|
+
completedSteps: number;
|
|
565
|
+
failureReason: "timeout" | "cancelled" | "worker-crash" | "step-failed";
|
|
566
|
+
failedStep?: string | undefined;
|
|
567
|
+
} | {
|
|
568
|
+
eventId: string;
|
|
569
|
+
timestampUs: number;
|
|
570
|
+
workflowSlug: string;
|
|
571
|
+
runId: string;
|
|
572
|
+
category: "workflow";
|
|
573
|
+
type: "WorkflowResumed";
|
|
574
|
+
originalRunId: string;
|
|
575
|
+
resumedSteps: number;
|
|
576
|
+
pendingSteps: number;
|
|
577
|
+
} | {
|
|
578
|
+
eventId: string;
|
|
579
|
+
timestampUs: number;
|
|
580
|
+
workflowSlug: string;
|
|
581
|
+
runId: string;
|
|
582
|
+
category: "workflow";
|
|
583
|
+
type: "WorkflowCancelled";
|
|
584
|
+
workflowAttemptNumber: number;
|
|
585
|
+
durationUs: number;
|
|
586
|
+
completedSteps: number;
|
|
587
|
+
reason?: string | undefined;
|
|
588
|
+
} | {
|
|
589
|
+
eventId: string;
|
|
590
|
+
timestampUs: number;
|
|
591
|
+
workflowSlug: string;
|
|
592
|
+
runId: string;
|
|
593
|
+
category: "workflow";
|
|
594
|
+
type: "WorkflowRetryStarted";
|
|
595
|
+
workflowAttemptNumber: number;
|
|
596
|
+
previousAttemptNumber: number;
|
|
597
|
+
retriedSteps: string[];
|
|
598
|
+
reason?: string | undefined;
|
|
599
|
+
})[]>;
|
|
600
|
+
/**
|
|
601
|
+
* Get detailed information for a specific step
|
|
602
|
+
* Includes state, events, and logs
|
|
603
|
+
*/
|
|
604
|
+
getStepDetail(workflowSlug: string, runId: string, stepName: string): Promise<{
|
|
605
|
+
state: StepState;
|
|
606
|
+
events: StepEvent[];
|
|
607
|
+
logs: LogEntry[];
|
|
608
|
+
attempts: AttemptMetadata[];
|
|
609
|
+
} | null>;
|
|
610
|
+
}
|
|
611
|
+
export type { PollOptions, ListRunsOptions, RunInfo } from "./types.ts";
|
|
612
|
+
export type { AnalyticsOptions, ErrorAnalysis, RetryAnalysis, SchedulingLatency, StepDuration, WorkflowDuration, WorkerStability, Throughput, QueueDepth, QueueDepthByWorkflow, SuccessRate, AnalyticsSummary, } from "@cascade-flow/backend-interface";
|
|
613
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
projectStepState,
|
|
4
|
+
extractLogsFromEvents,
|
|
5
|
+
extractAttemptMetadata
|
|
6
|
+
} from "@cascade-flow/backend-interface";
|
|
7
|
+
|
|
8
|
+
class WorkflowClient {
|
|
9
|
+
backend;
|
|
10
|
+
constructor(backend) {
|
|
11
|
+
this.backend = backend;
|
|
12
|
+
}
|
|
13
|
+
async submit(params) {
|
|
14
|
+
const submission = {
|
|
15
|
+
workflowSlug: params.workflow,
|
|
16
|
+
input: params.input,
|
|
17
|
+
runId: params.runId,
|
|
18
|
+
availableAt: params.availableAt,
|
|
19
|
+
priority: params.priority,
|
|
20
|
+
timeout: params.timeout,
|
|
21
|
+
idempotencyKey: params.idempotencyKey,
|
|
22
|
+
metadata: params.metadata,
|
|
23
|
+
tags: params.tags
|
|
24
|
+
};
|
|
25
|
+
return this.backend.submitRun(submission);
|
|
26
|
+
}
|
|
27
|
+
async getStatus(runId) {
|
|
28
|
+
return this.backend.getRun(runId);
|
|
29
|
+
}
|
|
30
|
+
async getRun(runId) {
|
|
31
|
+
const runState = await this.backend.getRun(runId);
|
|
32
|
+
if (!runState)
|
|
33
|
+
return null;
|
|
34
|
+
const info = { ...runState };
|
|
35
|
+
if (runState.status === "completed" || runState.status === "failed") {
|
|
36
|
+
try {
|
|
37
|
+
const events = await this.backend.loadEvents(runState.workflowSlug, runId, {
|
|
38
|
+
category: "workflow"
|
|
39
|
+
});
|
|
40
|
+
for (const event of events) {
|
|
41
|
+
if (event.category === "workflow") {
|
|
42
|
+
if (event.type === "WorkflowCompleted") {
|
|
43
|
+
info.output = JSON.parse(event.output);
|
|
44
|
+
} else if (event.type === "WorkflowFailed") {
|
|
45
|
+
info.error = event.error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
} catch (err) {}
|
|
50
|
+
}
|
|
51
|
+
return info;
|
|
52
|
+
}
|
|
53
|
+
async waitForCompletion(runId, options = {}) {
|
|
54
|
+
const {
|
|
55
|
+
interval = 1000,
|
|
56
|
+
maxAttempts = 60,
|
|
57
|
+
timeout,
|
|
58
|
+
exponentialBackoff = false,
|
|
59
|
+
maxBackoff = 1e4
|
|
60
|
+
} = options;
|
|
61
|
+
const startTime = Date.now();
|
|
62
|
+
const effectiveTimeout = timeout || maxAttempts * interval;
|
|
63
|
+
let currentInterval = interval;
|
|
64
|
+
let attempts = 0;
|
|
65
|
+
while (true) {
|
|
66
|
+
attempts++;
|
|
67
|
+
if (Date.now() - startTime > effectiveTimeout) {
|
|
68
|
+
throw new Error(`Timeout waiting for run ${runId} after ${effectiveTimeout}ms`);
|
|
69
|
+
}
|
|
70
|
+
const run = await this.getRun(runId);
|
|
71
|
+
if (!run) {
|
|
72
|
+
throw new Error(`Run ${runId} not found`);
|
|
73
|
+
}
|
|
74
|
+
if (run.status === "completed") {
|
|
75
|
+
return run.output;
|
|
76
|
+
} else if (run.status === "failed") {
|
|
77
|
+
const errorMsg = run.error?.message || "Run failed";
|
|
78
|
+
throw new Error(`Run ${runId} failed: ${errorMsg}`);
|
|
79
|
+
} else if (run.status === "cancelled") {
|
|
80
|
+
throw new Error(`Run ${runId} was cancelled`);
|
|
81
|
+
}
|
|
82
|
+
await this.sleep(currentInterval);
|
|
83
|
+
if (exponentialBackoff) {
|
|
84
|
+
currentInterval = Math.min(currentInterval * 2, maxBackoff);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async listRuns(options = {}) {
|
|
89
|
+
const { workflowSlug, status, tags, limit } = options;
|
|
90
|
+
let statuses;
|
|
91
|
+
if (status) {
|
|
92
|
+
statuses = Array.isArray(status) ? status : [status];
|
|
93
|
+
}
|
|
94
|
+
return this.backend.listRuns({
|
|
95
|
+
workflowSlug,
|
|
96
|
+
status: statuses,
|
|
97
|
+
tags,
|
|
98
|
+
limit
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
async cancel(runId, reason) {
|
|
102
|
+
await this.backend.cancelRun(runId, reason);
|
|
103
|
+
}
|
|
104
|
+
async retry(runId, reason) {
|
|
105
|
+
const runState = await this.backend.getRun(runId);
|
|
106
|
+
if (!runState) {
|
|
107
|
+
throw new Error(`Run ${runId} not found`);
|
|
108
|
+
}
|
|
109
|
+
if (runState.status !== "failed") {
|
|
110
|
+
throw new Error(`Cannot retry run ${runId} - status is ${runState.status}, expected 'failed'`);
|
|
111
|
+
}
|
|
112
|
+
const workflowSlug = runState.workflowSlug;
|
|
113
|
+
const failedSteps = await this.backend.getFailedSteps(workflowSlug, runId);
|
|
114
|
+
if (failedSteps.length === 0) {
|
|
115
|
+
throw new Error(`No failed steps found in run ${runId}`);
|
|
116
|
+
}
|
|
117
|
+
const previousAttemptNumber = runState.workflowAttemptNumber || 1;
|
|
118
|
+
const workflowAttemptNumber = previousAttemptNumber + 1;
|
|
119
|
+
const retriedStepIds = failedSteps.map((s) => s.stepId);
|
|
120
|
+
await this.backend.saveWorkflowRetryStarted(workflowSlug, runId, {
|
|
121
|
+
workflowAttemptNumber,
|
|
122
|
+
previousAttemptNumber,
|
|
123
|
+
retriedSteps: retriedStepIds,
|
|
124
|
+
reason
|
|
125
|
+
});
|
|
126
|
+
const now = Date.now() * 1000;
|
|
127
|
+
for (const step of failedSteps) {
|
|
128
|
+
await this.backend.saveStepScheduled(workflowSlug, runId, step.stepId, {
|
|
129
|
+
availableAt: now,
|
|
130
|
+
reason: "retry",
|
|
131
|
+
attemptNumber: 1,
|
|
132
|
+
retryDelayMs: 0
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
runId,
|
|
137
|
+
workflowAttemptNumber,
|
|
138
|
+
retriedSteps: retriedStepIds
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
async listWorkflows() {
|
|
142
|
+
return this.backend.listWorkflowMetadata();
|
|
143
|
+
}
|
|
144
|
+
async getWorkflowMetadata(workflowSlug) {
|
|
145
|
+
return this.backend.getWorkflowMetadata(workflowSlug);
|
|
146
|
+
}
|
|
147
|
+
async getWorkflowSteps(workflowSlug) {
|
|
148
|
+
return this.backend.getWorkflowSteps(workflowSlug);
|
|
149
|
+
}
|
|
150
|
+
async getWorkflowSchema(workflowSlug) {
|
|
151
|
+
const metadata = await this.backend.getWorkflowMetadata(workflowSlug);
|
|
152
|
+
return metadata?.inputSchemaJSON ?? null;
|
|
153
|
+
}
|
|
154
|
+
sleep(ms) {
|
|
155
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
156
|
+
}
|
|
157
|
+
async getErrorAnalysis(options) {
|
|
158
|
+
return this.backend.getErrorAnalysis(options);
|
|
159
|
+
}
|
|
160
|
+
async getRetryAnalysis(options) {
|
|
161
|
+
return this.backend.getRetryAnalysis(options);
|
|
162
|
+
}
|
|
163
|
+
async getSchedulingLatency(options) {
|
|
164
|
+
return this.backend.getSchedulingLatency(options);
|
|
165
|
+
}
|
|
166
|
+
async getStepDuration(options) {
|
|
167
|
+
return this.backend.getStepDuration(options);
|
|
168
|
+
}
|
|
169
|
+
async getWorkflowDuration(options) {
|
|
170
|
+
return this.backend.getWorkflowDuration(options);
|
|
171
|
+
}
|
|
172
|
+
async getWorkerStability(options) {
|
|
173
|
+
return this.backend.getWorkerStability(options);
|
|
174
|
+
}
|
|
175
|
+
async getThroughput(options) {
|
|
176
|
+
return this.backend.getThroughput(options);
|
|
177
|
+
}
|
|
178
|
+
async getQueueDepth(options) {
|
|
179
|
+
return this.backend.getQueueDepth(options);
|
|
180
|
+
}
|
|
181
|
+
async getQueueDepthByWorkflow() {
|
|
182
|
+
return this.backend.getQueueDepthByWorkflow();
|
|
183
|
+
}
|
|
184
|
+
async getSuccessRate(options) {
|
|
185
|
+
return this.backend.getSuccessRate(options);
|
|
186
|
+
}
|
|
187
|
+
async getAnalyticsSummary(options) {
|
|
188
|
+
return this.backend.getAnalyticsSummary(options);
|
|
189
|
+
}
|
|
190
|
+
async getErrorsList(options) {
|
|
191
|
+
return this.backend.getErrorsList(options);
|
|
192
|
+
}
|
|
193
|
+
async getErrorDetail(fingerprint, groupingStrategy, options) {
|
|
194
|
+
return this.backend.getErrorDetail(fingerprint, groupingStrategy, options);
|
|
195
|
+
}
|
|
196
|
+
async getStepStates(workflowSlug, runId) {
|
|
197
|
+
const events = await this.backend.loadEvents(workflowSlug, runId, {
|
|
198
|
+
category: "step"
|
|
199
|
+
});
|
|
200
|
+
const stepGroups = new Map;
|
|
201
|
+
for (const event of events) {
|
|
202
|
+
if (event.category === "step") {
|
|
203
|
+
if (!stepGroups.has(event.stepId)) {
|
|
204
|
+
stepGroups.set(event.stepId, []);
|
|
205
|
+
}
|
|
206
|
+
stepGroups.get(event.stepId).push(event);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const states = [];
|
|
210
|
+
for (const [stepId, stepEvents] of stepGroups) {
|
|
211
|
+
try {
|
|
212
|
+
const state = projectStepState(stepEvents, workflowSlug);
|
|
213
|
+
states.push(state);
|
|
214
|
+
} catch (err) {
|
|
215
|
+
console.error(`Failed to project state for step ${stepId}:`, err);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return states;
|
|
219
|
+
}
|
|
220
|
+
async getRunEvents(workflowSlug, runId) {
|
|
221
|
+
return this.backend.loadEvents(workflowSlug, runId);
|
|
222
|
+
}
|
|
223
|
+
async getStepDetail(workflowSlug, runId, stepName) {
|
|
224
|
+
const events = await this.backend.loadEvents(workflowSlug, runId, {
|
|
225
|
+
category: "step",
|
|
226
|
+
stepId: stepName
|
|
227
|
+
});
|
|
228
|
+
const stepEvents = events.filter((e) => e.category === "step");
|
|
229
|
+
if (stepEvents.length === 0) {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
const state = projectStepState(stepEvents, workflowSlug);
|
|
233
|
+
const logs = extractLogsFromEvents(stepEvents);
|
|
234
|
+
const attempts = extractAttemptMetadata(stepEvents);
|
|
235
|
+
return {
|
|
236
|
+
state,
|
|
237
|
+
events: stepEvents,
|
|
238
|
+
logs,
|
|
239
|
+
attempts
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
export {
|
|
244
|
+
WorkflowClient
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
//# debugId=092C4E0F5E8FB25364756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type {\n Backend,\n RunSubmission,\n RunState,\n WorkflowMetadata,\n AnalyticsOptions,\n ErrorAnalysis,\n RetryAnalysis,\n SchedulingLatency,\n StepDuration,\n WorkflowDuration,\n WorkerStability,\n Throughput,\n QueueDepth,\n QueueDepthByWorkflow,\n SuccessRate,\n AnalyticsSummary,\n StepEvent,\n StepState,\n LogEntry,\n} from \"@cascade-flow/backend-interface\";\nimport {\n projectStepState,\n extractLogsFromEvents,\n extractAttemptMetadata,\n type AttemptMetadata,\n} from \"@cascade-flow/backend-interface\";\nimport type { PollOptions, ListRunsOptions, RunInfo } from \"./types.ts\";\n\n/**\n * WorkflowClient - submit and manage workflow runs via queue\n *\n * Features:\n * - Type-safe submission with generic input types\n * - Status checking and polling\n * - Wait for completion with timeout\n * - List and filter runs\n * - Cancellation support\n */\nexport class WorkflowClient {\n constructor(private backend: Backend) {}\n\n /**\n * Submit a workflow run to the queue\n *\n * Generic type TInput provides type safety for workflow input\n *\n * @example\n * ```typescript\n * import type { WorkflowInput } from './workflows/my-workflow/input-schema';\n *\n * const { runId } = await client.submit<WorkflowInput>({\n * workflow: 'my-workflow',\n * input: { userId: \"123\", count: 42 } // Fully typed!\n * });\n * ```\n */\n async submit<TInput = unknown>(params: {\n workflow: string;\n input?: TInput;\n runId?: string;\n availableAt?: number;\n priority?: number;\n timeout?: number;\n idempotencyKey?: string;\n metadata?: Record<string, unknown>;\n tags?: string[];\n }): Promise<{ runId: string; isNew: boolean }> {\n const submission: RunSubmission = {\n workflowSlug: params.workflow,\n input: params.input,\n runId: params.runId,\n availableAt: params.availableAt,\n priority: params.priority,\n timeout: params.timeout,\n idempotencyKey: params.idempotencyKey,\n metadata: params.metadata,\n tags: params.tags,\n };\n\n return this.backend.submitRun(submission);\n }\n\n /**\n * Get the current status of a run\n *\n * @param runId - The run ID to query\n * @returns Run state or null if not found\n */\n async getStatus(runId: string): Promise<RunState | null> {\n return this.backend.getRun(runId);\n }\n\n /**\n * Get detailed run information including output/error\n *\n * @param runId - The run ID to query\n * @returns Extended run info or null if not found\n */\n async getRun(runId: string): Promise<RunInfo | null> {\n const runState = await this.backend.getRun(runId);\n if (!runState) return null;\n\n const info: RunInfo = { ...runState };\n\n // Load output or error if run is completed/failed\n if (runState.status === \"completed\" || runState.status === \"failed\") {\n try {\n // Load workflow events to get output/error\n const events = await this.backend.loadEvents(runState.workflowSlug, runId, {\n category: \"workflow\",\n });\n\n // Find WorkflowCompleted or WorkflowFailed event\n for (const event of events) {\n if (event.category === \"workflow\") {\n if (event.type === \"WorkflowCompleted\") {\n info.output = JSON.parse(event.output);\n } else if (event.type === \"WorkflowFailed\") {\n info.error = event.error;\n }\n }\n }\n } catch (err) {\n // Failed to load output/error, return state only\n }\n }\n\n return info;\n }\n\n /**\n * Wait for a run to complete\n *\n * Polls the backend until the run reaches a terminal state (completed/failed/cancelled)\n *\n * @param runId - The run ID to wait for\n * @param options - Polling options\n * @returns Run info when complete\n * @throws Error if timeout or run fails\n */\n async waitForCompletion<TOutput = unknown>(\n runId: string,\n options: PollOptions = {}\n ): Promise<TOutput> {\n const {\n interval = 1000,\n maxAttempts = 60,\n timeout,\n exponentialBackoff = false,\n maxBackoff = 10000,\n } = options;\n\n const startTime = Date.now();\n const effectiveTimeout = timeout || maxAttempts * interval;\n\n let currentInterval = interval;\n let attempts = 0;\n\n while (true) {\n attempts++;\n\n // Check timeout\n if (Date.now() - startTime > effectiveTimeout) {\n throw new Error(`Timeout waiting for run ${runId} after ${effectiveTimeout}ms`);\n }\n\n // Get run status\n const run = await this.getRun(runId);\n\n if (!run) {\n throw new Error(`Run ${runId} not found`);\n }\n\n // Check if run reached terminal state\n if (run.status === \"completed\") {\n return run.output as TOutput;\n } else if (run.status === \"failed\") {\n const errorMsg = run.error?.message || \"Run failed\";\n throw new Error(`Run ${runId} failed: ${errorMsg}`);\n } else if (run.status === \"cancelled\") {\n throw new Error(`Run ${runId} was cancelled`);\n }\n\n // Sleep before next poll\n await this.sleep(currentInterval);\n\n // Apply exponential backoff if enabled\n if (exponentialBackoff) {\n currentInterval = Math.min(currentInterval * 2, maxBackoff);\n }\n }\n }\n\n /**\n * List runs matching filters\n *\n * @param options - Filter options\n * @returns Array of run states\n */\n async listRuns(options: ListRunsOptions = {}): Promise<RunState[]> {\n const { workflowSlug, status, tags, limit } = options;\n\n // Convert status to array for backend (if provided)\n let statuses: RunState[\"status\"][] | undefined;\n if (status) {\n statuses = Array.isArray(status) ? status : [status];\n }\n\n return this.backend.listRuns({\n workflowSlug,\n status: statuses,\n tags,\n limit,\n });\n }\n\n /**\n * Cancel a run\n *\n * Can cancel runs in pending, claimed, or running status\n *\n * @param runId - The run to cancel\n * @param reason - Optional cancellation reason\n */\n async cancel(runId: string, reason?: string): Promise<void> {\n await this.backend.cancelRun(runId, reason);\n }\n\n /**\n * Retry a failed workflow\n *\n * Retries all failed steps in the workflow, keeping successful steps from the original run.\n * Step attempt numbers are reset to 1 for each retried step.\n *\n * @param runId - The run ID to retry\n * @param reason - Optional reason for retry\n * @returns Retry information including new workflow attempt number\n * @throws Error if run is not in failed status\n */\n async retry(\n runId: string,\n reason?: string\n ): Promise<{\n runId: string;\n workflowAttemptNumber: number;\n retriedSteps: string[];\n }> {\n // Get run state\n const runState = await this.backend.getRun(runId);\n if (!runState) {\n throw new Error(`Run ${runId} not found`);\n }\n\n // Verify run is failed\n if (runState.status !== \"failed\") {\n throw new Error(`Cannot retry run ${runId} - status is ${runState.status}, expected 'failed'`);\n }\n\n const workflowSlug = runState.workflowSlug;\n\n // Get failed steps\n const failedSteps = await this.backend.getFailedSteps(workflowSlug, runId);\n if (failedSteps.length === 0) {\n throw new Error(`No failed steps found in run ${runId}`);\n }\n\n // Calculate new workflow attempt number\n const previousAttemptNumber = runState.workflowAttemptNumber || 1;\n const workflowAttemptNumber = previousAttemptNumber + 1;\n\n const retriedStepIds = failedSteps.map((s) => s.stepId);\n\n // Emit WorkflowRetryStarted event\n await this.backend.saveWorkflowRetryStarted(workflowSlug, runId, {\n workflowAttemptNumber,\n previousAttemptNumber,\n retriedSteps: retriedStepIds,\n reason,\n });\n\n // Schedule each failed step for retry with fresh attempt number\n const now = Date.now() * 1000; // Convert to microseconds\n for (const step of failedSteps) {\n await this.backend.saveStepScheduled(workflowSlug, runId, step.stepId, {\n availableAt: now,\n reason: \"retry\",\n attemptNumber: 1, // Reset to 1 for workflow retry\n retryDelayMs: 0,\n });\n }\n\n return {\n runId,\n workflowAttemptNumber,\n retriedSteps: retriedStepIds,\n };\n }\n\n /**\n * List all available workflows\n *\n * @returns Array of workflow metadata\n */\n async listWorkflows(): Promise<WorkflowMetadata[]> {\n return this.backend.listWorkflowMetadata();\n }\n\n /**\n * Get metadata for a specific workflow\n *\n * @param workflowSlug - Workflow identifier (directory name)\n * @returns Workflow metadata or null if not found\n */\n async getWorkflowMetadata(workflowSlug: string): Promise<WorkflowMetadata | null> {\n return this.backend.getWorkflowMetadata(workflowSlug);\n }\n\n /**\n * Get step definitions for a specific workflow\n *\n * @param workflowSlug - Workflow identifier (directory name)\n * @returns Array of step definitions or empty array if workflow not found\n */\n async getWorkflowSteps(workflowSlug: string): Promise<any[]> {\n return this.backend.getWorkflowSteps(workflowSlug);\n }\n\n /**\n * Get the JSON Schema for a workflow's input\n *\n * @param workflowSlug - Workflow identifier (directory name)\n * @returns JSON Schema object or null if workflow has no input schema\n */\n async getWorkflowSchema(workflowSlug: string): Promise<any | null> {\n const metadata = await this.backend.getWorkflowMetadata(workflowSlug);\n return metadata?.inputSchemaJSON ?? null;\n }\n\n /**\n * Helper to sleep\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n // ============================================================================\n // Analytics Methods\n // ============================================================================\n\n /**\n * Get error analysis for workflows and steps\n *\n * Analyzes failure patterns, error types, and common error messages.\n *\n * @param options - Optional filters for time range, workflow, or step\n * @returns Error analysis data\n *\n * @example\n * ```typescript\n * // Get errors for last 24 hours (default)\n * const errors = await client.getErrorAnalysis();\n *\n * // Get errors for specific workflow\n * const errors = await client.getErrorAnalysis({\n * workflowSlug: 'my-workflow',\n * startUs: Date.now() * 1000 - 7 * 24 * 60 * 60 * 1000 * 1000 // Last 7 days\n * });\n * ```\n */\n async getErrorAnalysis(options?: AnalyticsOptions): Promise<ErrorAnalysis> {\n return this.backend.getErrorAnalysis(options);\n }\n\n /**\n * Get retry analysis metrics\n *\n * Analyzes retry patterns, success rates after retries, and retry effectiveness.\n *\n * @param options - Optional filters for time range, workflow, or step\n * @returns Retry analysis data\n */\n async getRetryAnalysis(options?: AnalyticsOptions): Promise<RetryAnalysis> {\n return this.backend.getRetryAnalysis(options);\n }\n\n /**\n * Get scheduling latency metrics\n *\n * Measures time between step being scheduled and actually starting execution.\n * High latency indicates worker starvation or queue congestion.\n *\n * @param options - Optional filters for time range, workflow, or step\n * @returns Scheduling latency statistics\n *\n * @example\n * ```typescript\n * const latency = await client.getSchedulingLatency({ workflowSlug: 'my-workflow' });\n * console.log(`Average wait time: ${latency.averageUs / 1000}ms`);\n * console.log(`P95 wait time: ${latency.p95Us / 1000}ms`);\n * ```\n */\n async getSchedulingLatency(options?: AnalyticsOptions): Promise<SchedulingLatency> {\n return this.backend.getSchedulingLatency(options);\n }\n\n /**\n * Get step duration metrics\n *\n * Analyzes how long steps take to execute.\n *\n * @param options - Optional filters for time range, workflow, or step\n * @returns Step duration statistics\n */\n async getStepDuration(options?: AnalyticsOptions): Promise<StepDuration> {\n return this.backend.getStepDuration(options);\n }\n\n /**\n * Get workflow duration metrics\n *\n * Analyzes end-to-end workflow execution time (from submission to completion).\n *\n * @param options - Optional filters for time range or workflow\n * @returns Workflow duration statistics\n */\n async getWorkflowDuration(options?: AnalyticsOptions): Promise<WorkflowDuration> {\n return this.backend.getWorkflowDuration(options);\n }\n\n /**\n * Get worker stability metrics\n *\n * Analyzes worker crashes, reclamations, and stale heartbeats.\n *\n * @param options - Optional filters for time range\n * @returns Worker stability data\n */\n async getWorkerStability(options?: AnalyticsOptions): Promise<WorkerStability> {\n return this.backend.getWorkerStability(options);\n }\n\n /**\n * Get throughput metrics\n *\n * Analyzes how many runs/steps are being completed per unit time.\n *\n * @param options - Optional filters for time range or workflow\n * @returns Throughput data\n */\n async getThroughput(options?: AnalyticsOptions): Promise<Throughput> {\n return this.backend.getThroughput(options);\n }\n\n /**\n * Get current queue depth\n *\n * Real-time snapshot of pending/running runs and steps.\n *\n * @param options - Optional filter for workflow\n * @returns Queue depth data\n *\n * @example\n * ```typescript\n * const depth = await client.getQueueDepth();\n * console.log(`Pending runs: ${depth.pendingRuns}`);\n * console.log(`Scheduled steps: ${depth.scheduledSteps}`);\n * ```\n */\n async getQueueDepth(options?: Pick<AnalyticsOptions, \"workflowSlug\">): Promise<QueueDepth> {\n return this.backend.getQueueDepth(options);\n }\n\n /**\n * Get queue depth broken down by workflow\n *\n * Real-time snapshot showing per-workflow queue statistics.\n * Useful for identifying which workflows have pending work.\n *\n * @returns Array of per-workflow queue depth data\n *\n * @example\n * ```typescript\n * const breakdown = await client.getQueueDepthByWorkflow();\n * for (const workflow of breakdown) {\n * console.log(`${workflow.workflowName}: ${workflow.pendingRuns} pending, ${workflow.scheduledSteps} scheduled`);\n * }\n * ```\n */\n async getQueueDepthByWorkflow(): Promise<QueueDepthByWorkflow> {\n return this.backend.getQueueDepthByWorkflow();\n }\n\n /**\n * Get success/failure rate metrics\n *\n * Analyzes overall health of workflows and steps.\n *\n * @param options - Optional filters for time range, workflow, or step\n * @returns Success rate data\n */\n async getSuccessRate(options?: AnalyticsOptions): Promise<SuccessRate> {\n return this.backend.getSuccessRate(options);\n }\n\n /**\n * Get comprehensive analytics summary\n *\n * Combines all analytics metrics into a single response.\n * Useful for dashboard views.\n *\n * @param options - Optional filters for time range or workflow\n * @returns Complete analytics summary\n *\n * @example\n * ```typescript\n * // Get full analytics for last 24 hours\n * const summary = await client.getAnalyticsSummary();\n *\n * // Get analytics for specific workflow over last week\n * const summary = await client.getAnalyticsSummary({\n * workflowSlug: 'my-workflow',\n * startUs: Date.now() * 1000 - 7 * 24 * 60 * 60 * 1000 * 1000\n * });\n * ```\n */\n async getAnalyticsSummary(options?: AnalyticsOptions): Promise<AnalyticsSummary> {\n return this.backend.getAnalyticsSummary(options);\n }\n\n /**\n * Get paginated list of errors grouped by fingerprint\n *\n * @param options - Filtering and pagination options\n * @returns Paginated list of error groups\n *\n * @example\n * ```typescript\n * // Get errors for last 24h\n * const { errors, total } = await client.getErrorsList({\n * timeRange: { start: Date.now() * 1000 - 86400000000, end: Date.now() * 1000 },\n * groupingStrategy: 'exact',\n * limit: 50,\n * offset: 0\n * });\n * ```\n */\n async getErrorsList(options?: {\n timeRange?: { start: number; end: number };\n workflowSlug?: string;\n groupingStrategy?: 'exact' | 'normalized' | 'portable';\n limit?: number;\n offset?: number;\n }): Promise<{\n errors: Array<{\n fingerprint: string;\n errorMessage: string;\n errorName: string;\n sampleStack: string;\n count: number;\n affectedRuns: number;\n firstSeen: number;\n lastSeen: number;\n }>;\n total: number;\n }> {\n return this.backend.getErrorsList(options);\n }\n\n /**\n * Get detailed information about a specific error by fingerprint\n *\n * @param fingerprint - Composite fingerprint (nameHash:messageHash:stackHash)\n * @param groupingStrategy - Which stack hash variant to use\n * @param options - Filtering and pagination options\n * @returns Error details with all occurrences\n *\n * @example\n * ```typescript\n * const detail = await client.getErrorDetail(\n * 'abc123:def456:ghi789',\n * 'exact',\n * { limit: 100, offset: 0 }\n * );\n * ```\n */\n async getErrorDetail(\n fingerprint: string,\n groupingStrategy: 'exact' | 'normalized' | 'portable',\n options?: {\n timeRange?: { start: number; end: number };\n limit?: number;\n offset?: number;\n }\n ): Promise<{\n fingerprint: string;\n errorMessage: string;\n errorName: string;\n sampleStack: string;\n totalCount: number;\n affectedRuns: number;\n firstSeen: number;\n lastSeen: number;\n occurrences: Array<{\n workflowSlug: string;\n runId: string;\n stepId: string;\n attemptNumber: number;\n timestampUs: number;\n }>;\n total: number;\n }> {\n return this.backend.getErrorDetail(fingerprint, groupingStrategy, options);\n }\n\n /**\n * Get the state of all steps for a run\n * Projects step events to compute current state\n */\n async getStepStates(workflowSlug: string, runId: string): Promise<StepState[]> {\n const events = await this.backend.loadEvents(workflowSlug, runId, {\n category: 'step',\n });\n\n // Group events by step ID\n const stepGroups = new Map<string, StepEvent[]>();\n for (const event of events) {\n if (event.category === 'step') {\n if (!stepGroups.has(event.stepId)) {\n stepGroups.set(event.stepId, []);\n }\n stepGroups.get(event.stepId)!.push(event as StepEvent);\n }\n }\n\n // Project each step's state\n const states: StepState[] = [];\n for (const [stepId, stepEvents] of stepGroups) {\n try {\n const state = projectStepState(stepEvents, workflowSlug);\n states.push(state);\n } catch (err) {\n console.error(`Failed to project state for step ${stepId}:`, err);\n }\n }\n\n return states;\n }\n\n /**\n * Get all events for a specific run (both workflow and step events)\n */\n async getRunEvents(workflowSlug: string, runId: string) {\n return this.backend.loadEvents(workflowSlug, runId);\n }\n\n /**\n * Get detailed information for a specific step\n * Includes state, events, and logs\n */\n async getStepDetail(\n workflowSlug: string,\n runId: string,\n stepName: string\n ): Promise<{\n state: StepState;\n events: StepEvent[];\n logs: LogEntry[];\n attempts: AttemptMetadata[];\n } | null> {\n // Load all events for this specific step\n const events = await this.backend.loadEvents(workflowSlug, runId, {\n category: 'step',\n stepId: stepName,\n });\n\n // Filter to only step events\n const stepEvents = events.filter((e): e is StepEvent => e.category === 'step');\n\n if (stepEvents.length === 0) {\n return null;\n }\n\n // Project events to current state\n const state = projectStepState(stepEvents, workflowSlug);\n\n // Extract logs from events\n const logs = extractLogsFromEvents(stepEvents);\n\n // Extract attempt metadata\n const attempts = extractAttemptMetadata(stepEvents);\n\n return {\n state,\n events: stepEvents,\n logs,\n attempts,\n };\n }\n}\n\n// Export types\nexport type { PollOptions, ListRunsOptions, RunInfo } from \"./types.ts\";\nexport type {\n AnalyticsOptions,\n ErrorAnalysis,\n RetryAnalysis,\n SchedulingLatency,\n StepDuration,\n WorkflowDuration,\n WorkerStability,\n Throughput,\n QueueDepth,\n QueueDepthByWorkflow,\n SuccessRate,\n AnalyticsSummary,\n} from \"@cascade-flow/backend-interface\";\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "092C4E0F5E8FB25364756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { RunState } from "@cascade-flow/backend-interface";
|
|
2
|
+
/**
|
|
3
|
+
* Options for polling and waiting
|
|
4
|
+
*/
|
|
5
|
+
export type PollOptions = {
|
|
6
|
+
/** Interval between polls (ms, default: 1000) */
|
|
7
|
+
interval?: number;
|
|
8
|
+
/** Maximum number of poll attempts (default: 60) */
|
|
9
|
+
maxAttempts?: number;
|
|
10
|
+
/** Timeout in milliseconds (overrides maxAttempts if provided) */
|
|
11
|
+
timeout?: number;
|
|
12
|
+
/** Use exponential backoff (default: false) */
|
|
13
|
+
exponentialBackoff?: boolean;
|
|
14
|
+
/** Maximum backoff interval (ms, default: 10000) */
|
|
15
|
+
maxBackoff?: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Options for listing runs
|
|
19
|
+
*/
|
|
20
|
+
export type ListRunsOptions = {
|
|
21
|
+
/** Filter by workflow slug */
|
|
22
|
+
workflowSlug?: string;
|
|
23
|
+
/** Filter by status (single status or array of statuses) */
|
|
24
|
+
status?: RunState["status"] | RunState["status"][];
|
|
25
|
+
/** Filter by tags (runs must have all tags) */
|
|
26
|
+
tags?: string[];
|
|
27
|
+
/** Limit results */
|
|
28
|
+
limit?: number;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Extended run information with output
|
|
32
|
+
*/
|
|
33
|
+
export type RunInfo = RunState & {
|
|
34
|
+
output?: any;
|
|
35
|
+
error?: {
|
|
36
|
+
message: string;
|
|
37
|
+
stack?: string;
|
|
38
|
+
name?: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,iCAAiC,CAAC;AAE/E;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,+CAA+C;IAC/C,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,8BAA8B;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IAEnD,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG;IAC/B,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cascade-flow/client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"module": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "rm -rf dist && bun build src/index.ts --outdir dist --target node --sourcemap=external --external=@cascade-flow/* && tsc -p tsconfig.build.json",
|
|
17
|
+
"prepublishOnly": "bun run build",
|
|
18
|
+
"test": "bun test"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@cascade-flow/backend-interface": "0.1.0",
|
|
22
|
+
"zod": "^4.1.12"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/bun": "latest",
|
|
26
|
+
"typescript": "^5"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"typescript": "^5"
|
|
30
|
+
},
|
|
31
|
+
"peerDependenciesMeta": {
|
|
32
|
+
"@cascadeflow/backend-filesystem": {
|
|
33
|
+
"optional": true
|
|
34
|
+
},
|
|
35
|
+
"@cascadeflow/backend-postgres": {
|
|
36
|
+
"optional": true
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist"
|
|
41
|
+
],
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/cascadeflow/cascadeflow.git",
|
|
48
|
+
"directory": "packages/client"
|
|
49
|
+
},
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"description": "Type-safe programmatic client for CascadeFlow workflow orchestrator",
|
|
52
|
+
"keywords": [
|
|
53
|
+
"workflow",
|
|
54
|
+
"orchestrator",
|
|
55
|
+
"client",
|
|
56
|
+
"api",
|
|
57
|
+
"typescript"
|
|
58
|
+
]
|
|
59
|
+
}
|