@workglow/task-graph 0.2.17 → 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/dist/browser.js +112 -5
- package/dist/browser.js.map +10 -7
- package/dist/bun.js +112 -5
- package/dist/bun.js.map +10 -7
- package/dist/common.d.ts +3 -0
- package/dist/common.d.ts.map +1 -1
- package/dist/node.js +112 -5
- package/dist/node.js.map +10 -7
- 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/InputResolver.d.ts.map +1 -1
- package/dist/task/TaskRunner.d.ts.map +1 -1
- package/dist/task-graph/TaskGraphRunner.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
|
}
|
|
@@ -1403,9 +1474,13 @@ class TaskRunner {
|
|
|
1403
1474
|
getLogger().warn(`Task "${this.task.type}" declares streaming output (x-stream: "${streamMode}") ` + `but does not implement executeStream(). Falling back to non-streaming execute().`);
|
|
1404
1475
|
}
|
|
1405
1476
|
}
|
|
1477
|
+
const inputSchema = this.task.constructor.inputSchema();
|
|
1478
|
+
const outputSchema = this.task.constructor.outputSchema();
|
|
1479
|
+
const inputsForKey = this.outputCache ? await normalizeInputsForCacheKey(inputs, inputSchema) : inputs;
|
|
1406
1480
|
if (this.task.cacheable) {
|
|
1407
|
-
|
|
1408
|
-
if (
|
|
1481
|
+
const cached = await this.outputCache?.getOutput(this.task.type, inputsForKey);
|
|
1482
|
+
if (cached !== undefined) {
|
|
1483
|
+
outputs = await deserializeOutputPorts(cached, outputSchema);
|
|
1409
1484
|
this.telemetrySpan?.addEvent("workglow.task.cache_hit");
|
|
1410
1485
|
if (isStreamable) {
|
|
1411
1486
|
this.task.runOutputData = outputs;
|
|
@@ -1424,7 +1499,8 @@ class TaskRunner {
|
|
|
1424
1499
|
outputs = await this.executeTask(inputs);
|
|
1425
1500
|
}
|
|
1426
1501
|
if (this.task.cacheable && outputs !== undefined) {
|
|
1427
|
-
await
|
|
1502
|
+
const wireOutputs = await serializeOutputPorts(outputs, outputSchema);
|
|
1503
|
+
await this.outputCache?.saveOutput(this.task.type, inputsForKey, wireOutputs);
|
|
1428
1504
|
}
|
|
1429
1505
|
this.task.runOutputData = outputs ?? {};
|
|
1430
1506
|
}
|
|
@@ -3046,6 +3122,23 @@ class TaskGraphRunner {
|
|
|
3046
3122
|
}
|
|
3047
3123
|
async pushOutputFromNodeToEdges(node, results) {
|
|
3048
3124
|
const dataflows = this.graph.getTargetDataflows(node.id);
|
|
3125
|
+
if (Object.keys(results).length > 0) {
|
|
3126
|
+
const consumerCounts = new Map;
|
|
3127
|
+
for (const dataflow of dataflows) {
|
|
3128
|
+
if (dataflow.stream !== undefined)
|
|
3129
|
+
continue;
|
|
3130
|
+
const port = dataflow.sourceTaskPortId;
|
|
3131
|
+
consumerCounts.set(port, (consumerCounts.get(port) ?? 0) + 1);
|
|
3132
|
+
}
|
|
3133
|
+
for (const [port, count] of consumerCounts) {
|
|
3134
|
+
if (count <= 1)
|
|
3135
|
+
continue;
|
|
3136
|
+
const value = results[port];
|
|
3137
|
+
const ref = asRefcountable(value);
|
|
3138
|
+
if (ref)
|
|
3139
|
+
ref.retain(count - 1);
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3049
3142
|
for (const dataflow of dataflows) {
|
|
3050
3143
|
if (dataflow.stream !== undefined)
|
|
3051
3144
|
continue;
|
|
@@ -8121,6 +8214,12 @@ class TaskOutputTabularRepository extends TaskOutputRepository {
|
|
|
8121
8214
|
this.emit("output_pruned");
|
|
8122
8215
|
}
|
|
8123
8216
|
}
|
|
8217
|
+
// src/storage/PortCodecRegistry.ts
|
|
8218
|
+
import {
|
|
8219
|
+
registerPortCodec,
|
|
8220
|
+
getPortCodec as getPortCodec2,
|
|
8221
|
+
_resetPortCodecsForTests
|
|
8222
|
+
} from "@workglow/util";
|
|
8124
8223
|
// src/debug/console/ConsoleFormatters.ts
|
|
8125
8224
|
import { DirectedAcyclicGraph as DirectedAcyclicGraph2 } from "@workglow/util/graph";
|
|
8126
8225
|
function formatDuration(ms) {
|
|
@@ -8756,6 +8855,8 @@ function installDevToolsFormatters() {
|
|
|
8756
8855
|
window.devtoolsFormatters = window.devtoolsFormatters || [];
|
|
8757
8856
|
window.devtoolsFormatters.push(new WorkflowAPIConsoleFormatter, new CreateWorkflowConsoleFormatter, new WorkflowConsoleFormatter, new TaskConsoleFormatter, new ReactElementConsoleFormatter, new DataflowConsoleFormatter, new DAGConsoleFormatter);
|
|
8758
8857
|
}
|
|
8858
|
+
// src/browser.ts
|
|
8859
|
+
registerRefcountablePredicate((v) => !!v && typeof v === "object" && ("backend" in v) && ("retain" in v) && ("release" in v) && ("materialize" in v));
|
|
8759
8860
|
export {
|
|
8760
8861
|
wrapSchemaInArray,
|
|
8761
8862
|
whileTaskConfigSchema,
|
|
@@ -8778,6 +8879,8 @@ export {
|
|
|
8778
8879
|
resolveIterationBound,
|
|
8779
8880
|
resetMethodNameCache,
|
|
8780
8881
|
removeIterationProperties,
|
|
8882
|
+
registerRefcountablePredicate,
|
|
8883
|
+
registerPortCodec,
|
|
8781
8884
|
registerJobQueueFactory,
|
|
8782
8885
|
registerBuiltInTransforms,
|
|
8783
8886
|
registerBaseTasks,
|
|
@@ -8815,6 +8918,7 @@ export {
|
|
|
8815
8918
|
getSchemaFormat,
|
|
8816
8919
|
getProfileGrants,
|
|
8817
8920
|
getPortStreamMode,
|
|
8921
|
+
getPortCodec2 as getPortCodec,
|
|
8818
8922
|
getOutputStreamMode,
|
|
8819
8923
|
getObjectSchema,
|
|
8820
8924
|
getObjectPortId,
|
|
@@ -8861,9 +8965,12 @@ export {
|
|
|
8861
8965
|
calculateNodeDepths,
|
|
8862
8966
|
buildIterationInputSchema,
|
|
8863
8967
|
autoConnect,
|
|
8968
|
+
asRefcountable,
|
|
8864
8969
|
addIterationContextToSchema,
|
|
8865
8970
|
addBoundaryNodesToGraphJson,
|
|
8866
8971
|
addBoundaryNodesToDependencyJson,
|
|
8972
|
+
_resetRefcountablePredicatesForTests,
|
|
8973
|
+
_resetPortCodecsForTests,
|
|
8867
8974
|
WorkflowError,
|
|
8868
8975
|
Workflow,
|
|
8869
8976
|
WhileTaskRunner,
|
|
@@ -8937,4 +9044,4 @@ export {
|
|
|
8937
9044
|
BROWSER_GRANTS
|
|
8938
9045
|
};
|
|
8939
9046
|
|
|
8940
|
-
//# debugId=
|
|
9047
|
+
//# debugId=09531002308E754B64756E2164756E21
|