@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/common.d.ts
CHANGED
|
@@ -20,9 +20,12 @@ export * from "./task-graph/TransformRegistry";
|
|
|
20
20
|
export * from "./task-graph/TransformTypes";
|
|
21
21
|
export * from "./task-graph/transforms";
|
|
22
22
|
export * from "./task-graph/autoConnect";
|
|
23
|
+
export { registerRefcountablePredicate, asRefcountable, _resetRefcountablePredicatesForTests, type Refcountable, } from "./refcountable";
|
|
23
24
|
export * from "./task";
|
|
24
25
|
export * from "./storage/TaskGraphRepository";
|
|
25
26
|
export * from "./storage/TaskGraphTabularRepository";
|
|
26
27
|
export * from "./storage/TaskOutputRepository";
|
|
27
28
|
export * from "./storage/TaskOutputTabularRepository";
|
|
29
|
+
export { registerPortCodec, getPortCodec, _resetPortCodecsForTests } from "./storage/PortCodecRegistry";
|
|
30
|
+
export type { PortCodec } from "./storage/PortCodecRegistry";
|
|
28
31
|
//# sourceMappingURL=common.d.ts.map
|
package/dist/common.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAE5C,cAAc,oCAAoC,CAAC;AACnD,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAE7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,QAAQ,CAAC;AAEvB,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sCAAsC,CAAC;AACrD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uCAAuC,CAAC"}
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAE5C,cAAc,oCAAoC,CAAC;AACnD,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAE7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AAEzC,OAAO,EACL,6BAA6B,EAC7B,cAAc,EACd,oCAAoC,EACpC,KAAK,YAAY,GAClB,MAAM,gBAAgB,CAAC;AAExB,cAAc,QAAQ,CAAC;AAEvB,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sCAAsC,CAAC;AACrD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uCAAuC,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACxG,YAAY,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC"}
|
package/dist/node.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,14 @@ 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";
|
|
8223
|
+
// src/node.ts
|
|
8224
|
+
registerRefcountablePredicate((v) => !!v && typeof v === "object" && ("backend" in v) && ("retain" in v) && ("release" in v) && ("materialize" in v));
|
|
8124
8225
|
export {
|
|
8125
8226
|
wrapSchemaInArray,
|
|
8126
8227
|
whileTaskConfigSchema,
|
|
@@ -8143,6 +8244,8 @@ export {
|
|
|
8143
8244
|
resolveIterationBound,
|
|
8144
8245
|
resetMethodNameCache,
|
|
8145
8246
|
removeIterationProperties,
|
|
8247
|
+
registerRefcountablePredicate,
|
|
8248
|
+
registerPortCodec,
|
|
8146
8249
|
registerJobQueueFactory,
|
|
8147
8250
|
registerBuiltInTransforms,
|
|
8148
8251
|
registerBaseTasks,
|
|
@@ -8178,6 +8281,7 @@ export {
|
|
|
8178
8281
|
getSchemaFormat,
|
|
8179
8282
|
getProfileGrants,
|
|
8180
8283
|
getPortStreamMode,
|
|
8284
|
+
getPortCodec2 as getPortCodec,
|
|
8181
8285
|
getOutputStreamMode,
|
|
8182
8286
|
getObjectSchema,
|
|
8183
8287
|
getObjectPortId,
|
|
@@ -8224,9 +8328,12 @@ export {
|
|
|
8224
8328
|
calculateNodeDepths,
|
|
8225
8329
|
buildIterationInputSchema,
|
|
8226
8330
|
autoConnect,
|
|
8331
|
+
asRefcountable,
|
|
8227
8332
|
addIterationContextToSchema,
|
|
8228
8333
|
addBoundaryNodesToGraphJson,
|
|
8229
8334
|
addBoundaryNodesToDependencyJson,
|
|
8335
|
+
_resetRefcountablePredicatesForTests,
|
|
8336
|
+
_resetPortCodecsForTests,
|
|
8230
8337
|
WorkflowError,
|
|
8231
8338
|
Workflow,
|
|
8232
8339
|
WhileTaskRunner,
|
|
@@ -8300,4 +8407,4 @@ export {
|
|
|
8300
8407
|
BROWSER_GRANTS
|
|
8301
8408
|
};
|
|
8302
8409
|
|
|
8303
|
-
//# debugId=
|
|
8410
|
+
//# debugId=3044ECF32B8CA32464756E2164756E21
|