@workglow/task-graph 0.2.16 → 0.2.18
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 +8 -3
- package/dist/browser.js +212 -102
- package/dist/browser.js.map +16 -13
- package/dist/bun.js +212 -102
- package/dist/bun.js.map +16 -13
- package/dist/common.d.ts +3 -0
- package/dist/common.d.ts.map +1 -1
- package/dist/node.js +212 -102
- package/dist/node.js.map +16 -13
- package/dist/refcountable.d.ts +29 -0
- package/dist/refcountable.d.ts.map +1 -0
- package/dist/storage/PortCodecRegistry.d.ts +8 -0
- package/dist/storage/PortCodecRegistry.d.ts.map +1 -0
- package/dist/task/FallbackTaskRunner.d.ts +2 -2
- package/dist/task/FallbackTaskRunner.d.ts.map +1 -1
- package/dist/task/GraphAsTaskRunner.d.ts +5 -5
- package/dist/task/GraphAsTaskRunner.d.ts.map +1 -1
- package/dist/task/ITask.d.ts +3 -3
- package/dist/task/ITask.d.ts.map +1 -1
- package/dist/task/ITaskRunner.d.ts +2 -2
- package/dist/task/ITaskRunner.d.ts.map +1 -1
- package/dist/task/InputResolver.d.ts.map +1 -1
- package/dist/task/IteratorTaskRunner.d.ts +4 -3
- package/dist/task/IteratorTaskRunner.d.ts.map +1 -1
- package/dist/task/Task.d.ts +8 -9
- package/dist/task/Task.d.ts.map +1 -1
- package/dist/task/TaskRunner.d.ts +9 -9
- package/dist/task/TaskRunner.d.ts.map +1 -1
- package/dist/task/WhileTaskRunner.d.ts +2 -2
- package/dist/task/WhileTaskRunner.d.ts.map +1 -1
- package/dist/task-graph/ITaskGraph.d.ts +1 -1
- package/dist/task-graph/ITaskGraph.d.ts.map +1 -1
- package/dist/task-graph/TaskGraph.d.ts +3 -3
- package/dist/task-graph/TaskGraph.d.ts.map +1 -1
- package/dist/task-graph/TaskGraphRunner.d.ts +13 -13
- package/dist/task-graph/TaskGraphRunner.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/EXECUTION_MODEL.md +132 -74
- package/src/task/README.md +5 -4
- package/src/task-graph/README.md +1 -1
- package/dist/__tests__/public-exports.test.d.ts +0 -7
- package/dist/__tests__/public-exports.test.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskGraphRunner.d.ts","sourceRoot":"","sources":["../../src/task-graph/TaskGraphRunner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAEL,yBAAyB,EAIzB,aAAa,EACb,eAAe,EAGhB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"TaskGraphRunner.d.ts","sourceRoot":"","sources":["../../src/task-graph/TaskGraphRunner.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workglow/task-graph",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.18",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/workglow-dev/workglow.git",
|
|
@@ -51,9 +51,9 @@
|
|
|
51
51
|
"access": "public"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@workglow/job-queue": "0.2.
|
|
55
|
-
"@workglow/storage": "0.2.
|
|
56
|
-
"@workglow/util": "0.2.
|
|
54
|
+
"@workglow/job-queue": "0.2.18",
|
|
55
|
+
"@workglow/storage": "0.2.18",
|
|
56
|
+
"@workglow/util": "0.2.18"
|
|
57
57
|
},
|
|
58
58
|
"peerDependenciesMeta": {
|
|
59
59
|
"@workglow/job-queue": {
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
}
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@workglow/job-queue": "0.2.
|
|
71
|
-
"@workglow/storage": "0.2.
|
|
72
|
-
"@workglow/util": "0.2.
|
|
70
|
+
"@workglow/job-queue": "0.2.18",
|
|
71
|
+
"@workglow/storage": "0.2.18",
|
|
72
|
+
"@workglow/util": "0.2.18"
|
|
73
73
|
}
|
|
74
74
|
}
|
package/src/EXECUTION_MODEL.md
CHANGED
|
@@ -7,7 +7,7 @@ This document explains the internal execution model of the task graph system. It
|
|
|
7
7
|
- [Overview](#overview)
|
|
8
8
|
- [Task Lifecycle](#task-lifecycle)
|
|
9
9
|
- [Normal Execution (run)](#normal-execution-run)
|
|
10
|
-
- [
|
|
10
|
+
- [Preview Execution (runPreview)](#preview-execution-runpreview)
|
|
11
11
|
- [Dataflow and Input Propagation](#dataflow-and-input-propagation)
|
|
12
12
|
- [GraphAsTask (Subgraphs)](#graphastask-subgraphs)
|
|
13
13
|
- [Key Invariants](#key-invariants)
|
|
@@ -17,12 +17,12 @@ This document explains the internal execution model of the task graph system. It
|
|
|
17
17
|
|
|
18
18
|
## Overview
|
|
19
19
|
|
|
20
|
-
The task graph system has two execution
|
|
20
|
+
The task graph system has two **strictly orthogonal** execution paths:
|
|
21
21
|
|
|
22
|
-
1. **`run()`**
|
|
23
|
-
2. **`
|
|
22
|
+
1. **`run()`** — Full execution that produces cached, immutable results by calling `execute()` (or `executeStream()`).
|
|
23
|
+
2. **`runPreview()`** — Lightweight execution for UI updates and previews by calling `executePreview()`.
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
`run()` never invokes `executePreview()`, and `runPreview()` never invokes `execute()` or `executeStream()`. Cache hits return the cached value verbatim.
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
@@ -61,7 +61,7 @@ Each task maintains:
|
|
|
61
61
|
|
|
62
62
|
Full execution that:
|
|
63
63
|
|
|
64
|
-
- Runs the task's `execute()` method
|
|
64
|
+
- Runs the task's `execute()` (or `executeStream()`) method
|
|
65
65
|
- Produces cached, deterministic results
|
|
66
66
|
- Transitions task to `COMPLETED` status
|
|
67
67
|
- Makes output immutable
|
|
@@ -73,17 +73,21 @@ Task.run(overrides)
|
|
|
73
73
|
↓
|
|
74
74
|
TaskRunner.run(overrides)
|
|
75
75
|
↓
|
|
76
|
-
1.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
1. Guard: if task overrides executePreview() but not execute(),
|
|
77
|
+
throw TaskConfigurationError
|
|
78
|
+
2. setInput(overrides) # Merge overrides into runInputData
|
|
79
|
+
3. resolveSchemaInputs() # Resolve model/repository strings to instances
|
|
80
|
+
4. validateInput() # Validate against input schema
|
|
81
|
+
5. Check cache # If cacheable: cache hit returns verbatim, no preview overlay
|
|
82
|
+
6. executeTask() # Call task.execute(input, context) only
|
|
83
|
+
7. Store in cache # If cacheable, cache the result
|
|
84
|
+
8. handleComplete() # Set status = COMPLETED
|
|
83
85
|
↓
|
|
84
86
|
Return runOutputData (locked)
|
|
85
87
|
```
|
|
86
88
|
|
|
89
|
+
`executePreview()` is never called as part of `run()`. There is no post-execute overlay, even on cache hits or after `executeStream()` finishes.
|
|
90
|
+
|
|
87
91
|
### Graph-Level Execution
|
|
88
92
|
|
|
89
93
|
```
|
|
@@ -99,9 +103,13 @@ For each task (in topological order):
|
|
|
99
103
|
Return results from ending nodes (no outgoing dataflows)
|
|
100
104
|
```
|
|
101
105
|
|
|
106
|
+
### Runtime guard
|
|
107
|
+
|
|
108
|
+
`TaskRunner.run()` checks at the start of execution whether the task overrides `executePreview()` but not `execute()`. If so, it throws `TaskConfigurationError`. The check fires on `run()`, not on construction. `runPreview()` does not trigger the guard.
|
|
109
|
+
|
|
102
110
|
---
|
|
103
111
|
|
|
104
|
-
##
|
|
112
|
+
## Preview Execution (runPreview)
|
|
105
113
|
|
|
106
114
|
### Purpose
|
|
107
115
|
|
|
@@ -111,20 +119,20 @@ Lightweight execution for:
|
|
|
111
119
|
- Fast transformations (e.g., image filters)
|
|
112
120
|
- Propagating intermediate results through PENDING tasks
|
|
113
121
|
|
|
114
|
-
**Important:**
|
|
122
|
+
**Important:** Preview execution only affects `PENDING` tasks. `COMPLETED` tasks return their cached output unchanged.
|
|
115
123
|
|
|
116
124
|
### Use Case Example
|
|
117
125
|
|
|
118
126
|
```
|
|
119
127
|
User edits an InputNode default → Task is PENDING
|
|
120
128
|
↓
|
|
121
|
-
|
|
129
|
+
runPreview() is called
|
|
122
130
|
↓
|
|
123
131
|
InputTask (PENDING) receives new value
|
|
124
132
|
↓
|
|
125
|
-
Downstream tasks (PENDING) get
|
|
133
|
+
Downstream tasks (PENDING) get preview updates
|
|
126
134
|
↓
|
|
127
|
-
Tasks run their
|
|
135
|
+
Tasks run their executePreview() for quick previews
|
|
128
136
|
↓
|
|
129
137
|
Eventually run() is called → All tasks become COMPLETED (locked)
|
|
130
138
|
```
|
|
@@ -132,18 +140,19 @@ Eventually run() is called → All tasks become COMPLETED (locked)
|
|
|
132
140
|
### Task-Level Flow
|
|
133
141
|
|
|
134
142
|
```
|
|
135
|
-
Task.
|
|
143
|
+
Task.runPreview(overrides)
|
|
136
144
|
↓
|
|
137
|
-
TaskRunner.
|
|
145
|
+
TaskRunner.runPreview(overrides)
|
|
138
146
|
↓
|
|
139
147
|
1. If status == PROCESSING: return existing output (no re-entry)
|
|
140
148
|
2. setInput(overrides) # Update runInputData
|
|
141
149
|
3. resolveSchemaInputs() # Resolve strings to instances
|
|
142
|
-
4.
|
|
150
|
+
4. handleStartPreview() # previewRunning = true
|
|
143
151
|
5. validateInput()
|
|
144
|
-
6.
|
|
145
|
-
7. runOutputData =
|
|
146
|
-
|
|
152
|
+
6. executeTaskPreview(input) # Call task.executePreview()
|
|
153
|
+
7. If result !== undefined: runOutputData = result # No merge
|
|
154
|
+
Else: leave runOutputData unchanged
|
|
155
|
+
8. handleCompletePreview() # previewRunning = false
|
|
147
156
|
↓
|
|
148
157
|
Return runOutputData
|
|
149
158
|
```
|
|
@@ -151,9 +160,9 @@ Return runOutputData
|
|
|
151
160
|
### Graph-Level Flow
|
|
152
161
|
|
|
153
162
|
```
|
|
154
|
-
TaskGraph.
|
|
163
|
+
TaskGraph.runPreview(input)
|
|
155
164
|
↓
|
|
156
|
-
TaskGraphRunner.
|
|
165
|
+
TaskGraphRunner.runGraphPreview(input)
|
|
157
166
|
↓
|
|
158
167
|
For each task (in topological order):
|
|
159
168
|
↓
|
|
@@ -168,28 +177,35 @@ For each task (in topological order):
|
|
|
168
177
|
Else:
|
|
169
178
|
taskInput = {}
|
|
170
179
|
↓
|
|
171
|
-
task.
|
|
180
|
+
task.runPreview(taskInput)
|
|
172
181
|
↓
|
|
173
182
|
pushOutputFromNodeToEdges() # Push output to dataflows
|
|
174
183
|
↓
|
|
175
184
|
Return results from ending nodes
|
|
176
185
|
```
|
|
177
186
|
|
|
178
|
-
### The
|
|
187
|
+
### The executePreview Method
|
|
179
188
|
|
|
180
189
|
```typescript
|
|
181
|
-
// Default implementation -
|
|
182
|
-
async
|
|
183
|
-
return
|
|
190
|
+
// Default implementation - returns undefined, leaves runOutputData unchanged
|
|
191
|
+
async executePreview(input, context): Promise<Output | undefined> {
|
|
192
|
+
return undefined;
|
|
184
193
|
}
|
|
185
194
|
|
|
186
195
|
// Custom implementation for quick transformations
|
|
187
|
-
async
|
|
188
|
-
// Lightweight operation (
|
|
189
|
-
return {
|
|
196
|
+
async executePreview(input, context): Promise<Output | undefined> {
|
|
197
|
+
// Lightweight operation (< 1ms)
|
|
198
|
+
return { preview: this.quickTransform(input) };
|
|
190
199
|
}
|
|
191
200
|
```
|
|
192
201
|
|
|
202
|
+
Return-value semantics:
|
|
203
|
+
|
|
204
|
+
- Non-`undefined` `Output` — replaces `runOutputData` entirely. **No merge** with prior output.
|
|
205
|
+
- `undefined` — leaves `runOutputData` unchanged.
|
|
206
|
+
|
|
207
|
+
If a preview needs the prior output, it can read `this.runOutputData` directly.
|
|
208
|
+
|
|
193
209
|
---
|
|
194
210
|
|
|
195
211
|
## Dataflow and Input Propagation
|
|
@@ -218,11 +234,11 @@ TaskA.runOutputData.result → TaskB.runInputData.value
|
|
|
218
234
|
|
|
219
235
|
### When Input is Copied
|
|
220
236
|
|
|
221
|
-
| Execution
|
|
222
|
-
|
|
|
223
|
-
| `run()`
|
|
224
|
-
| `
|
|
225
|
-
| `
|
|
237
|
+
| Execution Path | Task Status | Input Copied? |
|
|
238
|
+
| -------------- | ----------- | ------------------------- |
|
|
239
|
+
| `run()` | Any | Yes (always) |
|
|
240
|
+
| `runPreview()` | PENDING | Yes |
|
|
241
|
+
| `runPreview()` | COMPLETED | **No** (output is locked) |
|
|
226
242
|
|
|
227
243
|
---
|
|
228
244
|
|
|
@@ -250,25 +266,25 @@ subGraph.run(input) # Execute the entire subgraph
|
|
|
250
266
|
mergeExecuteOutputsToRunOutput() # Combine results from ending nodes
|
|
251
267
|
```
|
|
252
268
|
|
|
253
|
-
###
|
|
269
|
+
### Preview Execution with Subgraphs
|
|
254
270
|
|
|
255
271
|
```
|
|
256
|
-
GraphAsTask.
|
|
272
|
+
GraphAsTask.runPreview(input)
|
|
257
273
|
↓
|
|
258
|
-
GraphAsTaskRunner.
|
|
274
|
+
GraphAsTaskRunner.executeTaskPreview(input)
|
|
259
275
|
↓
|
|
260
|
-
|
|
276
|
+
executeTaskChildrenPreview()
|
|
261
277
|
↓
|
|
262
|
-
subGraph.
|
|
278
|
+
subGraph.runPreview(this.task.runInputData) # ← IMPORTANT: Pass parent's input
|
|
263
279
|
↓
|
|
264
280
|
mergeExecuteOutputsToRunOutput()
|
|
265
281
|
```
|
|
266
282
|
|
|
267
|
-
**Critical:** The parent's `runInputData` is passed to `subGraph.
|
|
283
|
+
**Critical:** The parent's `runInputData` is passed to `subGraph.runPreview()` so that root tasks in the subgraph (like InputTask) receive the input values.
|
|
268
284
|
|
|
269
285
|
### Root Task Input Propagation
|
|
270
286
|
|
|
271
|
-
In `
|
|
287
|
+
In `runGraphPreview()`:
|
|
272
288
|
|
|
273
289
|
```typescript
|
|
274
290
|
const isRootTask = this.graph.getSourceDataflows(task.id).length === 0;
|
|
@@ -276,7 +292,7 @@ const isRootTask = this.graph.getSourceDataflows(task.id).length === 0;
|
|
|
276
292
|
// For root tasks, pass the input parameter (from parent GraphAsTask)
|
|
277
293
|
const taskInput = isRootTask ? input : {};
|
|
278
294
|
|
|
279
|
-
const taskResult = await task.
|
|
295
|
+
const taskResult = await task.runPreview(taskInput);
|
|
280
296
|
```
|
|
281
297
|
|
|
282
298
|
This ensures:
|
|
@@ -300,9 +316,9 @@ Once a task's `run()` completes and status becomes `COMPLETED`:
|
|
|
300
316
|
|
|
301
317
|
- `runOutputData` is **locked** and **cacheable**
|
|
302
318
|
- `runInputData` should not be modified
|
|
303
|
-
- `
|
|
319
|
+
- `runPreview()` returns the cached output unchanged (does not invoke `executePreview()`)
|
|
304
320
|
|
|
305
|
-
### 2. Only PENDING Tasks Receive Dataflow Updates in
|
|
321
|
+
### 2. Only PENDING Tasks Receive Dataflow Updates in Preview Mode
|
|
306
322
|
|
|
307
323
|
```typescript
|
|
308
324
|
if (task.status === TaskStatus.PENDING) {
|
|
@@ -317,26 +333,32 @@ In subgraphs, root tasks (no incoming dataflows) receive the parent's input:
|
|
|
317
333
|
|
|
318
334
|
```typescript
|
|
319
335
|
const taskInput = isRootTask ? input : {};
|
|
320
|
-
task.
|
|
336
|
+
task.runPreview(taskInput);
|
|
321
337
|
```
|
|
322
338
|
|
|
323
|
-
### 4.
|
|
339
|
+
### 4. executePreview is Lightweight
|
|
324
340
|
|
|
325
|
-
The `
|
|
341
|
+
The `executePreview()` method should:
|
|
326
342
|
|
|
327
343
|
- Complete quickly (< 1ms ideally)
|
|
328
344
|
- Not perform heavy computation
|
|
329
|
-
- Return UI preview data
|
|
345
|
+
- Return UI preview data (or `undefined` to leave the prior output unchanged)
|
|
330
346
|
|
|
331
347
|
Heavy computation belongs in `execute()`.
|
|
332
348
|
|
|
333
|
-
### 5.
|
|
349
|
+
### 5. Preview Execution Respects Task Order
|
|
334
350
|
|
|
335
|
-
Tasks are executed in topological order (via
|
|
351
|
+
Tasks are executed in topological order (via the preview scheduler), ensuring:
|
|
336
352
|
|
|
337
353
|
- Upstream tasks run before downstream tasks
|
|
338
354
|
- Data is available when needed
|
|
339
355
|
|
|
356
|
+
### 6. run() and runPreview() Are Strictly Separate
|
|
357
|
+
|
|
358
|
+
`run()` never invokes `executePreview()`. `runPreview()` never invokes `execute()` or `executeStream()`. There is no overlay, no merge, and no second hidden stage. Cache hits during `run()` return the cached value verbatim.
|
|
359
|
+
|
|
360
|
+
A task that overrides `executePreview()` but not `execute()` throws `TaskConfigurationError` on its first `run()` call. Implement `execute()` to fix this — typically by extracting a shared helper called by both methods.
|
|
361
|
+
|
|
340
362
|
---
|
|
341
363
|
|
|
342
364
|
## Common Pitfalls
|
|
@@ -358,16 +380,16 @@ Only modify input for PENDING tasks, or reset the entire graph first.
|
|
|
358
380
|
**Wrong:**
|
|
359
381
|
|
|
360
382
|
```typescript
|
|
361
|
-
protected async
|
|
362
|
-
return this.task.subGraph!.
|
|
383
|
+
protected async executeTaskChildrenPreview() {
|
|
384
|
+
return this.task.subGraph!.runPreview(); // ❌ No input passed
|
|
363
385
|
}
|
|
364
386
|
```
|
|
365
387
|
|
|
366
388
|
**Correct:**
|
|
367
389
|
|
|
368
390
|
```typescript
|
|
369
|
-
protected async
|
|
370
|
-
return this.task.subGraph!.
|
|
391
|
+
protected async executeTaskChildrenPreview() {
|
|
392
|
+
return this.task.subGraph!.runPreview(this.task.runInputData); // ✓
|
|
371
393
|
}
|
|
372
394
|
```
|
|
373
395
|
|
|
@@ -376,7 +398,7 @@ protected async executeTaskChildrenReactive() {
|
|
|
376
398
|
**Wrong:**
|
|
377
399
|
|
|
378
400
|
```typescript
|
|
379
|
-
// In
|
|
401
|
+
// In runGraphPreview
|
|
380
402
|
this.copyInputFromEdgesToNode(task); // ❌ Always copies, even for COMPLETED
|
|
381
403
|
```
|
|
382
404
|
|
|
@@ -389,12 +411,12 @@ if (task.status === TaskStatus.PENDING) {
|
|
|
389
411
|
}
|
|
390
412
|
```
|
|
391
413
|
|
|
392
|
-
### 4. Heavy Computation in
|
|
414
|
+
### 4. Heavy Computation in executePreview
|
|
393
415
|
|
|
394
416
|
**Wrong:**
|
|
395
417
|
|
|
396
418
|
```typescript
|
|
397
|
-
async
|
|
419
|
+
async executePreview(input) {
|
|
398
420
|
// ❌ Takes 30 seconds
|
|
399
421
|
const result = await this.trainNeuralNetwork(input);
|
|
400
422
|
return { result };
|
|
@@ -404,7 +426,7 @@ async executeReactive(input, output) {
|
|
|
404
426
|
**Correct:**
|
|
405
427
|
|
|
406
428
|
```typescript
|
|
407
|
-
async
|
|
429
|
+
async executePreview(input) {
|
|
408
430
|
// ✓ Quick preview (< 1ms)
|
|
409
431
|
return { preview: this.quickPreview(input) };
|
|
410
432
|
}
|
|
@@ -416,24 +438,60 @@ async execute(input) {
|
|
|
416
438
|
}
|
|
417
439
|
```
|
|
418
440
|
|
|
441
|
+
### 5. Implementing only executePreview()
|
|
442
|
+
|
|
443
|
+
**Wrong:**
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
class MyTask extends Task {
|
|
447
|
+
// ❌ Only override executePreview
|
|
448
|
+
async executePreview(input) {
|
|
449
|
+
return { result: input.value * 2 };
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
`run()` will throw `TaskConfigurationError` because there is no `execute()` to call.
|
|
455
|
+
|
|
456
|
+
**Correct:** Extract a shared helper and call it from both methods:
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
function double(value: number): number {
|
|
460
|
+
return value * 2;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
class MyTask extends Task {
|
|
464
|
+
async execute(input) {
|
|
465
|
+
return { result: double(input.value) };
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
async executePreview(input) {
|
|
469
|
+
return { result: double(input.value) };
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
419
474
|
---
|
|
420
475
|
|
|
421
476
|
## Summary
|
|
422
477
|
|
|
423
|
-
| Aspect | `run()`
|
|
424
|
-
| -------------------- |
|
|
425
|
-
| **Purpose** | Full execution
|
|
426
|
-
| **Method called** | `execute()`
|
|
427
|
-
| **
|
|
428
|
-
| **
|
|
429
|
-
| **
|
|
430
|
-
| **
|
|
431
|
-
| **
|
|
478
|
+
| Aspect | `run()` | `runPreview()` |
|
|
479
|
+
| -------------------- | ---------------------------------- | ------------------ |
|
|
480
|
+
| **Purpose** | Full execution | UI previews |
|
|
481
|
+
| **Method called** | `execute()` (or `executeStream()`) | `executePreview()` |
|
|
482
|
+
| **Calls preview?** | Never | n/a |
|
|
483
|
+
| **Calls execute?** | n/a | Never |
|
|
484
|
+
| **Final status** | COMPLETED | Unchanged |
|
|
485
|
+
| **Output** | Locked/cached | Temporary |
|
|
486
|
+
| **Dataflow updates** | Always | Only PENDING tasks |
|
|
487
|
+
| **Performance** | Can be slow | Should be < 1ms |
|
|
488
|
+
| **User edits** | Before run starts | Before run starts |
|
|
432
489
|
|
|
433
490
|
### Key Takeaways
|
|
434
491
|
|
|
435
492
|
1. Users only edit inputs on PENDING tasks
|
|
436
493
|
2. Once `run()` completes, the task is COMPLETED and immutable
|
|
437
|
-
3. `
|
|
438
|
-
4. COMPLETED tasks return cached results in
|
|
494
|
+
3. `runPreview()` propagates lightweight updates through PENDING tasks
|
|
495
|
+
4. COMPLETED tasks return cached results in preview mode
|
|
439
496
|
5. Root tasks in subgraphs receive input from the parent GraphAsTask
|
|
497
|
+
6. `run()` and `runPreview()` are strictly separate — no overlay, no merge, no second stage
|
package/src/task/README.md
CHANGED
|
@@ -50,7 +50,8 @@ class MyTask extends Task {
|
|
|
50
50
|
result: Type.Number(),
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
//
|
|
53
|
+
// execute() is called by run(); executePreview() is called by runPreview().
|
|
54
|
+
// The two paths are strictly separate — run() never invokes executePreview().
|
|
54
55
|
async execute(input: MyTaskInput, { signal, updateProgress }: IExecuteContext) {
|
|
55
56
|
await sleep(1000);
|
|
56
57
|
if (signal.aborted) {
|
|
@@ -61,7 +62,7 @@ class MyTask extends Task {
|
|
|
61
62
|
await sleep(1000);
|
|
62
63
|
return { result: input.input * 2 };
|
|
63
64
|
}
|
|
64
|
-
async
|
|
65
|
+
async executePreview(input: MyTaskInput) {
|
|
65
66
|
return { result: input.input * 2 };
|
|
66
67
|
}
|
|
67
68
|
}
|
|
@@ -75,8 +76,8 @@ class MyTask extends Task {
|
|
|
75
76
|
|
|
76
77
|
- **Statuses**: `Pending` → `Processing` → (`Completed`|`Failed`|`Aborted`)
|
|
77
78
|
- **Methods**:
|
|
78
|
-
- `run()`: Full execution with caching, calls the subclass `execute` method
|
|
79
|
-
- `
|
|
79
|
+
- `run()`: Full execution with caching, calls the subclass `execute` method only
|
|
80
|
+
- `runPreview()`: Lightweight execution for UI updates, calls the subclass `executePreview` method only
|
|
80
81
|
- `abort()`: Cancel running task
|
|
81
82
|
|
|
82
83
|
## Event Handling
|
package/src/task-graph/README.md
CHANGED
|
@@ -28,7 +28,7 @@ A robust TypeScript library for creating and managing task graphs with dependenc
|
|
|
28
28
|
- Caching of task results (same run on same input returns cached result)
|
|
29
29
|
- Error handling and abortion support
|
|
30
30
|
- Serial and parallel execution patterns
|
|
31
|
-
-
|
|
31
|
+
- Live preview execution to drive UI updates
|
|
32
32
|
|
|
33
33
|
## Installation
|
|
34
34
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"public-exports.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/public-exports.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|