@workglow/task-graph 0.2.17 → 0.2.19
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/dist/browser.js +139 -10
- package/dist/browser.js.map +13 -10
- package/dist/bun.js +139 -10
- package/dist/bun.js.map +13 -10
- package/dist/common.d.ts +3 -0
- package/dist/common.d.ts.map +1 -1
- package/dist/node.js +139 -10
- package/dist/node.js.map +13 -10
- 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/GraphAsTaskRunner.d.ts.map +1 -1
- package/dist/task/ITask.d.ts +6 -0
- package/dist/task/ITask.d.ts.map +1 -1
- package/dist/task/InputResolver.d.ts.map +1 -1
- package/dist/task/TaskRunner.d.ts +6 -0
- package/dist/task/TaskRunner.d.ts.map +1 -1
- package/dist/task-graph/IWorkflow.d.ts +2 -0
- package/dist/task-graph/IWorkflow.d.ts.map +1 -1
- package/dist/task-graph/TaskGraph.d.ts +12 -0
- package/dist/task-graph/TaskGraph.d.ts.map +1 -1
- package/dist/task-graph/TaskGraphRunner.d.ts +6 -0
- package/dist/task-graph/TaskGraphRunner.d.ts.map +1 -1
- package/dist/task-graph/Workflow.d.ts.map +1 -1
- package/package.json +7 -7
- package/dist/__tests__/public-exports.test.d.ts +0 -7
- package/dist/__tests__/public-exports.test.d.ts.map +0 -1
package/dist/browser.js
CHANGED
|
@@ -584,6 +584,10 @@ function computeGraphEntitlements(graph, options) {
|
|
|
584
584
|
}
|
|
585
585
|
// src/task/InputResolver.ts
|
|
586
586
|
import { getInputResolvers } from "@workglow/util";
|
|
587
|
+
function isPlainObject(value) {
|
|
588
|
+
const proto = Object.getPrototypeOf(value);
|
|
589
|
+
return proto === Object.prototype || proto === null;
|
|
590
|
+
}
|
|
587
591
|
function getSchemaFormat(schema, visited = new WeakSet) {
|
|
588
592
|
if (typeof schema !== "object" || schema === null)
|
|
589
593
|
return;
|
|
@@ -671,6 +675,7 @@ async function resolveSchemaInputs(input, schema, config, visited = new Set) {
|
|
|
671
675
|
for (const [key, propSchema] of Object.entries(properties)) {
|
|
672
676
|
let value = resolved[key];
|
|
673
677
|
const format = getSchemaFormat(propSchema);
|
|
678
|
+
let phase1Transformed = false;
|
|
674
679
|
if (format) {
|
|
675
680
|
let resolver = resolvers.get(format);
|
|
676
681
|
if (!resolver) {
|
|
@@ -681,14 +686,18 @@ async function resolveSchemaInputs(input, schema, config, visited = new Set) {
|
|
|
681
686
|
if (typeof value === "string") {
|
|
682
687
|
value = await resolver(value, format, config.registry);
|
|
683
688
|
resolved[key] = value;
|
|
689
|
+
phase1Transformed = true;
|
|
684
690
|
} else if (Array.isArray(value) && value.some((item) => typeof item === "string")) {
|
|
685
691
|
const results = await Promise.all(value.map((item) => typeof item === "string" ? resolver(item, format, config.registry) : item));
|
|
686
692
|
value = results.filter((result) => result !== undefined);
|
|
687
693
|
resolved[key] = value;
|
|
694
|
+
phase1Transformed = true;
|
|
688
695
|
}
|
|
689
696
|
}
|
|
690
697
|
}
|
|
691
|
-
|
|
698
|
+
const hasFormatResolver = format ? !!(resolvers.get(format) ?? resolvers.get(getFormatPrefix(format))) : false;
|
|
699
|
+
const skipPhase2 = hasFormatResolver && !phase1Transformed;
|
|
700
|
+
if (!skipPhase2 && value !== null && value !== undefined && typeof value === "object" && !Array.isArray(value) && isPlainObject(value)) {
|
|
692
701
|
const objectSchema = getObjectSchema(propSchema);
|
|
693
702
|
if (objectSchema && !visited.has(objectSchema)) {
|
|
694
703
|
visited.add(objectSchema);
|
|
@@ -1134,6 +1143,31 @@ import {
|
|
|
1134
1143
|
uuid4 as uuid43
|
|
1135
1144
|
} from "@workglow/util";
|
|
1136
1145
|
|
|
1146
|
+
// src/refcountable.ts
|
|
1147
|
+
var GLOBAL_KEY = Symbol.for("@workglow/task-graph/refcountable.predicates");
|
|
1148
|
+
var _g = globalThis;
|
|
1149
|
+
if (!Array.isArray(_g[GLOBAL_KEY])) {
|
|
1150
|
+
_g[GLOBAL_KEY] = [];
|
|
1151
|
+
}
|
|
1152
|
+
var predicates = _g[GLOBAL_KEY];
|
|
1153
|
+
function registerRefcountablePredicate(p) {
|
|
1154
|
+
predicates.push(p);
|
|
1155
|
+
}
|
|
1156
|
+
function asRefcountable(v) {
|
|
1157
|
+
if (v === null || v === undefined)
|
|
1158
|
+
return null;
|
|
1159
|
+
if (typeof v !== "object")
|
|
1160
|
+
return null;
|
|
1161
|
+
for (const p of predicates) {
|
|
1162
|
+
if (p(v))
|
|
1163
|
+
return v;
|
|
1164
|
+
}
|
|
1165
|
+
return null;
|
|
1166
|
+
}
|
|
1167
|
+
function _resetRefcountablePredicatesForTests() {
|
|
1168
|
+
predicates.length = 0;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1137
1171
|
// src/storage/TaskOutputRepository.ts
|
|
1138
1172
|
import { createServiceToken as createServiceToken2, EventEmitter as EventEmitter2 } from "@workglow/util";
|
|
1139
1173
|
var TASK_OUTPUT_REPOSITORY = createServiceToken2("taskgraph.taskOutputRepository");
|
|
@@ -1245,6 +1279,7 @@ import {
|
|
|
1245
1279
|
globalServiceRegistry as globalServiceRegistry2,
|
|
1246
1280
|
SpanStatusCode
|
|
1247
1281
|
} from "@workglow/util";
|
|
1282
|
+
import { getPortCodec } from "@workglow/util";
|
|
1248
1283
|
|
|
1249
1284
|
// src/task/StreamTypes.ts
|
|
1250
1285
|
function getPortStreamMode(schema, portId) {
|
|
@@ -1348,6 +1383,42 @@ function hasStructuredOutput(schema) {
|
|
|
1348
1383
|
}
|
|
1349
1384
|
|
|
1350
1385
|
// src/task/TaskRunner.ts
|
|
1386
|
+
async function serializeOutputPorts(output, schema) {
|
|
1387
|
+
if (!schema?.properties)
|
|
1388
|
+
return output;
|
|
1389
|
+
const out = { ...output };
|
|
1390
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
1391
|
+
const codec = prop.format ? getPortCodec(prop.format) : undefined;
|
|
1392
|
+
if (codec && out[key] !== undefined) {
|
|
1393
|
+
out[key] = await codec.serialize(out[key]);
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
return out;
|
|
1397
|
+
}
|
|
1398
|
+
async function deserializeOutputPorts(output, schema) {
|
|
1399
|
+
if (!schema?.properties)
|
|
1400
|
+
return output;
|
|
1401
|
+
const out = { ...output };
|
|
1402
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
1403
|
+
const codec = prop.format ? getPortCodec(prop.format) : undefined;
|
|
1404
|
+
if (codec && out[key] !== undefined) {
|
|
1405
|
+
out[key] = await codec.deserialize(out[key]);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
return out;
|
|
1409
|
+
}
|
|
1410
|
+
async function normalizeInputsForCacheKey(inputs, schema) {
|
|
1411
|
+
if (!schema?.properties)
|
|
1412
|
+
return inputs;
|
|
1413
|
+
const out = { ...inputs };
|
|
1414
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
1415
|
+
const codec = prop.format ? getPortCodec(prop.format) : undefined;
|
|
1416
|
+
if (codec && out[key] !== undefined) {
|
|
1417
|
+
out[key] = await codec.serialize(out[key]);
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
return out;
|
|
1421
|
+
}
|
|
1351
1422
|
function hasRunConfig(i) {
|
|
1352
1423
|
return i !== null && typeof i === "object" && "runConfig" in i;
|
|
1353
1424
|
}
|
|
@@ -1364,6 +1435,7 @@ class TaskRunner {
|
|
|
1364
1435
|
timeoutTimer;
|
|
1365
1436
|
pendingTimeoutError;
|
|
1366
1437
|
shouldAccumulate = true;
|
|
1438
|
+
runWithPreviews = false;
|
|
1367
1439
|
telemetrySpan;
|
|
1368
1440
|
constructor(task) {
|
|
1369
1441
|
this.task = task;
|
|
@@ -1403,9 +1475,13 @@ class TaskRunner {
|
|
|
1403
1475
|
getLogger().warn(`Task "${this.task.type}" declares streaming output (x-stream: "${streamMode}") ` + `but does not implement executeStream(). Falling back to non-streaming execute().`);
|
|
1404
1476
|
}
|
|
1405
1477
|
}
|
|
1478
|
+
const inputSchema = this.task.constructor.inputSchema();
|
|
1479
|
+
const outputSchema = this.task.constructor.outputSchema();
|
|
1480
|
+
const inputsForKey = this.outputCache ? await normalizeInputsForCacheKey(inputs, inputSchema) : inputs;
|
|
1406
1481
|
if (this.task.cacheable) {
|
|
1407
|
-
|
|
1408
|
-
if (
|
|
1482
|
+
const cached = await this.outputCache?.getOutput(this.task.type, inputsForKey);
|
|
1483
|
+
if (cached !== undefined) {
|
|
1484
|
+
outputs = await deserializeOutputPorts(cached, outputSchema);
|
|
1409
1485
|
this.telemetrySpan?.addEvent("workglow.task.cache_hit");
|
|
1410
1486
|
if (isStreamable) {
|
|
1411
1487
|
this.task.runOutputData = outputs;
|
|
@@ -1424,7 +1500,8 @@ class TaskRunner {
|
|
|
1424
1500
|
outputs = await this.executeTask(inputs);
|
|
1425
1501
|
}
|
|
1426
1502
|
if (this.task.cacheable && outputs !== undefined) {
|
|
1427
|
-
await
|
|
1503
|
+
const wireOutputs = await serializeOutputPorts(outputs, outputSchema);
|
|
1504
|
+
await this.outputCache?.saveOutput(this.task.type, inputsForKey, wireOutputs);
|
|
1428
1505
|
}
|
|
1429
1506
|
this.task.runOutputData = outputs ?? {};
|
|
1430
1507
|
}
|
|
@@ -1641,6 +1718,7 @@ class TaskRunner {
|
|
|
1641
1718
|
this.outputCache = cache;
|
|
1642
1719
|
}
|
|
1643
1720
|
this.shouldAccumulate = config.shouldAccumulate !== false;
|
|
1721
|
+
this.runWithPreviews = config.runWithPreviews === true;
|
|
1644
1722
|
if (config.updateProgress) {
|
|
1645
1723
|
this.updateProgress = config.updateProgress;
|
|
1646
1724
|
}
|
|
@@ -2812,6 +2890,7 @@ class TaskGraphRunner {
|
|
|
2812
2890
|
graph;
|
|
2813
2891
|
outputCache;
|
|
2814
2892
|
accumulateLeafOutputs = true;
|
|
2893
|
+
runWithPreviews = false;
|
|
2815
2894
|
registry = globalServiceRegistry3;
|
|
2816
2895
|
resourceScope;
|
|
2817
2896
|
abortController;
|
|
@@ -3046,6 +3125,24 @@ class TaskGraphRunner {
|
|
|
3046
3125
|
}
|
|
3047
3126
|
async pushOutputFromNodeToEdges(node, results) {
|
|
3048
3127
|
const dataflows = this.graph.getTargetDataflows(node.id);
|
|
3128
|
+
if (Object.keys(results).length > 0) {
|
|
3129
|
+
const consumerCounts = new Map;
|
|
3130
|
+
for (const dataflow of dataflows) {
|
|
3131
|
+
if (dataflow.stream !== undefined)
|
|
3132
|
+
continue;
|
|
3133
|
+
const port = dataflow.sourceTaskPortId;
|
|
3134
|
+
consumerCounts.set(port, (consumerCounts.get(port) ?? 0) + 1);
|
|
3135
|
+
}
|
|
3136
|
+
for (const [port, count] of consumerCounts) {
|
|
3137
|
+
const extra = this.runWithPreviews ? count : count - 1;
|
|
3138
|
+
if (extra <= 0)
|
|
3139
|
+
continue;
|
|
3140
|
+
const value = results[port];
|
|
3141
|
+
const ref = asRefcountable(value);
|
|
3142
|
+
if (ref)
|
|
3143
|
+
ref.retain(extra);
|
|
3144
|
+
}
|
|
3145
|
+
}
|
|
3049
3146
|
for (const dataflow of dataflows) {
|
|
3050
3147
|
if (dataflow.stream !== undefined)
|
|
3051
3148
|
continue;
|
|
@@ -3215,7 +3312,8 @@ class TaskGraphRunner {
|
|
|
3215
3312
|
outputCache: this.outputCache ?? false,
|
|
3216
3313
|
updateProgress: async (task2, progress, message, ...args) => await this.handleProgress(task2, progress, message, ...args),
|
|
3217
3314
|
registry: this.registry,
|
|
3218
|
-
resourceScope: this.resourceScope
|
|
3315
|
+
resourceScope: this.resourceScope,
|
|
3316
|
+
runWithPreviews: this.runWithPreviews
|
|
3219
3317
|
});
|
|
3220
3318
|
await this.pushOutputFromNodeToEdges(task, results);
|
|
3221
3319
|
return {
|
|
@@ -3265,7 +3363,8 @@ class TaskGraphRunner {
|
|
|
3265
3363
|
shouldAccumulate,
|
|
3266
3364
|
updateProgress: async (task2, progress, message, ...args) => await this.handleProgress(task2, progress, message, ...args),
|
|
3267
3365
|
registry: this.registry,
|
|
3268
|
-
resourceScope: this.resourceScope
|
|
3366
|
+
resourceScope: this.resourceScope,
|
|
3367
|
+
runWithPreviews: this.runWithPreviews
|
|
3269
3368
|
});
|
|
3270
3369
|
await this.pushOutputFromNodeToEdges(task, results);
|
|
3271
3370
|
return {
|
|
@@ -3340,6 +3439,17 @@ class TaskGraphRunner {
|
|
|
3340
3439
|
}
|
|
3341
3440
|
}
|
|
3342
3441
|
resetTask(graph, task, runId) {
|
|
3442
|
+
const previous = task.runOutputData;
|
|
3443
|
+
if (previous) {
|
|
3444
|
+
for (const port of Object.keys(previous)) {
|
|
3445
|
+
const ref = asRefcountable(previous[port]);
|
|
3446
|
+
if (!ref)
|
|
3447
|
+
continue;
|
|
3448
|
+
try {
|
|
3449
|
+
ref.release();
|
|
3450
|
+
} catch {}
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3343
3453
|
task.status = TaskStatus.PENDING;
|
|
3344
3454
|
task.resetInputData();
|
|
3345
3455
|
task.runOutputData = {};
|
|
@@ -3373,6 +3483,7 @@ class TaskGraphRunner {
|
|
|
3373
3483
|
this.resourceScope = config.resourceScope;
|
|
3374
3484
|
}
|
|
3375
3485
|
this.accumulateLeafOutputs = config?.accumulateLeafOutputs !== false;
|
|
3486
|
+
this.runWithPreviews = config?.runWithPreviews === true;
|
|
3376
3487
|
if (config?.outputCache !== undefined) {
|
|
3377
3488
|
if (typeof config.outputCache === "boolean") {
|
|
3378
3489
|
if (config.outputCache === true) {
|
|
@@ -3472,6 +3583,7 @@ class TaskGraphRunner {
|
|
|
3472
3583
|
throw new TaskConfigurationError(`Graph has ${taskCount} tasks, exceeding the limit of ${config.maxTasks}`);
|
|
3473
3584
|
}
|
|
3474
3585
|
}
|
|
3586
|
+
this.runWithPreviews = false;
|
|
3475
3587
|
this.previewScheduler.reset();
|
|
3476
3588
|
this.previewRunning = true;
|
|
3477
3589
|
}
|
|
@@ -3571,7 +3683,8 @@ class GraphAsTaskRunner extends TaskRunner {
|
|
|
3571
3683
|
parentSignal: this.abortController?.signal,
|
|
3572
3684
|
outputCache: this.outputCache,
|
|
3573
3685
|
registry: this.registry,
|
|
3574
|
-
resourceScope: this.resourceScope
|
|
3686
|
+
resourceScope: this.resourceScope,
|
|
3687
|
+
runWithPreviews: this.runWithPreviews
|
|
3575
3688
|
});
|
|
3576
3689
|
unsubscribe();
|
|
3577
3690
|
return results;
|
|
@@ -4034,7 +4147,8 @@ class TaskGraph {
|
|
|
4034
4147
|
registry: config?.registry,
|
|
4035
4148
|
timeout: config?.timeout,
|
|
4036
4149
|
maxTasks: config?.maxTasks,
|
|
4037
|
-
resourceScope: config?.resourceScope
|
|
4150
|
+
resourceScope: config?.resourceScope,
|
|
4151
|
+
runWithPreviews: config?.runWithPreviews
|
|
4038
4152
|
});
|
|
4039
4153
|
}
|
|
4040
4154
|
runPreview(input = {}, config = {}) {
|
|
@@ -4887,7 +5001,8 @@ class Workflow {
|
|
|
4887
5001
|
parentSignal: this._abortController.signal,
|
|
4888
5002
|
outputCache: this._outputCache,
|
|
4889
5003
|
registry: config?.registry ?? this._registry,
|
|
4890
|
-
resourceScope: config?.resourceScope
|
|
5004
|
+
resourceScope: config?.resourceScope,
|
|
5005
|
+
runWithPreviews: config?.runWithPreviews
|
|
4891
5006
|
});
|
|
4892
5007
|
const results = this.graph.mergeExecuteOutputsToRunOutput(output, PROPERTY_ARRAY);
|
|
4893
5008
|
this.events.emit("complete");
|
|
@@ -8121,6 +8236,12 @@ class TaskOutputTabularRepository extends TaskOutputRepository {
|
|
|
8121
8236
|
this.emit("output_pruned");
|
|
8122
8237
|
}
|
|
8123
8238
|
}
|
|
8239
|
+
// src/storage/PortCodecRegistry.ts
|
|
8240
|
+
import {
|
|
8241
|
+
registerPortCodec,
|
|
8242
|
+
getPortCodec as getPortCodec2,
|
|
8243
|
+
_resetPortCodecsForTests
|
|
8244
|
+
} from "@workglow/util";
|
|
8124
8245
|
// src/debug/console/ConsoleFormatters.ts
|
|
8125
8246
|
import { DirectedAcyclicGraph as DirectedAcyclicGraph2 } from "@workglow/util/graph";
|
|
8126
8247
|
function formatDuration(ms) {
|
|
@@ -8756,6 +8877,8 @@ function installDevToolsFormatters() {
|
|
|
8756
8877
|
window.devtoolsFormatters = window.devtoolsFormatters || [];
|
|
8757
8878
|
window.devtoolsFormatters.push(new WorkflowAPIConsoleFormatter, new CreateWorkflowConsoleFormatter, new WorkflowConsoleFormatter, new TaskConsoleFormatter, new ReactElementConsoleFormatter, new DataflowConsoleFormatter, new DAGConsoleFormatter);
|
|
8758
8879
|
}
|
|
8880
|
+
// src/browser.ts
|
|
8881
|
+
registerRefcountablePredicate((v) => !!v && typeof v === "object" && ("backend" in v) && ("retain" in v) && ("release" in v) && ("materialize" in v));
|
|
8759
8882
|
export {
|
|
8760
8883
|
wrapSchemaInArray,
|
|
8761
8884
|
whileTaskConfigSchema,
|
|
@@ -8778,6 +8901,8 @@ export {
|
|
|
8778
8901
|
resolveIterationBound,
|
|
8779
8902
|
resetMethodNameCache,
|
|
8780
8903
|
removeIterationProperties,
|
|
8904
|
+
registerRefcountablePredicate,
|
|
8905
|
+
registerPortCodec,
|
|
8781
8906
|
registerJobQueueFactory,
|
|
8782
8907
|
registerBuiltInTransforms,
|
|
8783
8908
|
registerBaseTasks,
|
|
@@ -8815,6 +8940,7 @@ export {
|
|
|
8815
8940
|
getSchemaFormat,
|
|
8816
8941
|
getProfileGrants,
|
|
8817
8942
|
getPortStreamMode,
|
|
8943
|
+
getPortCodec2 as getPortCodec,
|
|
8818
8944
|
getOutputStreamMode,
|
|
8819
8945
|
getObjectSchema,
|
|
8820
8946
|
getObjectPortId,
|
|
@@ -8861,9 +8987,12 @@ export {
|
|
|
8861
8987
|
calculateNodeDepths,
|
|
8862
8988
|
buildIterationInputSchema,
|
|
8863
8989
|
autoConnect,
|
|
8990
|
+
asRefcountable,
|
|
8864
8991
|
addIterationContextToSchema,
|
|
8865
8992
|
addBoundaryNodesToGraphJson,
|
|
8866
8993
|
addBoundaryNodesToDependencyJson,
|
|
8994
|
+
_resetRefcountablePredicatesForTests,
|
|
8995
|
+
_resetPortCodecsForTests,
|
|
8867
8996
|
WorkflowError,
|
|
8868
8997
|
Workflow,
|
|
8869
8998
|
WhileTaskRunner,
|
|
@@ -8937,4 +9066,4 @@ export {
|
|
|
8937
9066
|
BROWSER_GRANTS
|
|
8938
9067
|
};
|
|
8939
9068
|
|
|
8940
|
-
//# debugId=
|
|
9069
|
+
//# debugId=DACDDF54D5A4197B64756E2164756E21
|