@sanity/workflow-engine 0.5.0 → 0.6.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/dist/_chunks-cjs/schema.cjs.map +1 -1
- package/dist/_chunks-es/schema.js.map +1 -1
- package/dist/index.cjs +140 -156
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -58
- package/dist/index.d.ts +68 -58
- package/dist/index.js +140 -156
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -738,22 +738,6 @@ async function queryGuardsAcross(clients, query, params) {
|
|
|
738
738
|
function dedupById(guards) {
|
|
739
739
|
return [...new Map(guards.map((g) => [g._id, g])).values()].sort((a, b) => a._id.localeCompare(b._id));
|
|
740
740
|
}
|
|
741
|
-
const TAG_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
742
|
-
function validateTags(tags) {
|
|
743
|
-
if (tags.length === 0)
|
|
744
|
-
throw new Error("tags: must be a non-empty array");
|
|
745
|
-
for (const tag of tags)
|
|
746
|
-
if (!TAG_RE.test(tag))
|
|
747
|
-
throw new Error(
|
|
748
|
-
`tags: invalid tag "${tag}" \u2014 must match ${TAG_RE.source} (ASCII lowercase + digits + dashes, no leading dash, no dots)`
|
|
749
|
-
);
|
|
750
|
-
}
|
|
751
|
-
function canonicalTag(tags) {
|
|
752
|
-
return tags[0];
|
|
753
|
-
}
|
|
754
|
-
function tagScopeFilter(param = "engineTags") {
|
|
755
|
-
return `count(tags[@ in $${param}]) > 0`;
|
|
756
|
-
}
|
|
757
741
|
const GUARD_OWNER = "robot:workflow-engine", GUARD_LIFTED_PREDICATE = "true";
|
|
758
742
|
function resolveGuard(guard, instance, stageName, now) {
|
|
759
743
|
const ctx = { instance, now }, targets = resolveIdRefTargets(guard.match.idRefs, ctx);
|
|
@@ -811,13 +795,13 @@ async function retractStageGuards(args) {
|
|
|
811
795
|
await client.getDocument(doc._id) && await client.patch(doc._id).set({ predicate: GUARD_LIFTED_PREDICATE }).commit();
|
|
812
796
|
}
|
|
813
797
|
async function deleteOrphanedDefinitionGuards(args) {
|
|
814
|
-
const { client, clientForGdr, workflowResource, definition, definitions,
|
|
798
|
+
const { client, clientForGdr, workflowResource, definition, definitions, tag } = args, perClient = await guardsForDefinitionByClient({
|
|
815
799
|
client,
|
|
816
800
|
clientForGdr,
|
|
817
801
|
workflowResource,
|
|
818
802
|
definition,
|
|
819
803
|
definitions
|
|
820
|
-
}), ownPartitionPrefix = `${
|
|
804
|
+
}), ownPartitionPrefix = `${tag}.`;
|
|
821
805
|
let count = 0;
|
|
822
806
|
for (const { client: resourceClient, guards } of perClient) {
|
|
823
807
|
const own = guards.filter((guard) => guard.sourceInstanceId.startsWith(ownPartitionPrefix));
|
|
@@ -1006,7 +990,7 @@ async function resolveQueryValue(entry, source, ctx, client, defaultValue) {
|
|
|
1006
990
|
stage: ctx.stageName ?? null,
|
|
1007
991
|
task: ctx.taskName ?? null,
|
|
1008
992
|
now: ctx.now,
|
|
1009
|
-
|
|
993
|
+
tag: ctx.tag
|
|
1010
994
|
});
|
|
1011
995
|
try {
|
|
1012
996
|
const fetchOptions = ctx.perspective !== void 0 ? { perspective: ctx.perspective } : void 0, result = await client.fetch(source.query, params, fetchOptions);
|
|
@@ -1173,7 +1157,7 @@ async function resolveStageStateEntries(args) {
|
|
|
1173
1157
|
client,
|
|
1174
1158
|
now,
|
|
1175
1159
|
selfId: instance._id,
|
|
1176
|
-
|
|
1160
|
+
tag: instance.tag,
|
|
1177
1161
|
stageName: stage.name,
|
|
1178
1162
|
workflowResource: instance.workflowResource,
|
|
1179
1163
|
// Allow stage-scope entries' `source: { type: "stateRead", scope:
|
|
@@ -1193,7 +1177,7 @@ async function resolveTaskStateEntries(args) {
|
|
|
1193
1177
|
client,
|
|
1194
1178
|
now,
|
|
1195
1179
|
selfId: instance._id,
|
|
1196
|
-
|
|
1180
|
+
tag: instance.tag,
|
|
1197
1181
|
stageName: stage.name,
|
|
1198
1182
|
workflowResource: instance.workflowResource,
|
|
1199
1183
|
taskName: task.name,
|
|
@@ -1415,6 +1399,16 @@ function findCurrentStageEntry(instance) {
|
|
|
1415
1399
|
function findCurrentTasks(instance) {
|
|
1416
1400
|
return findCurrentStageEntry(instance)?.tasks ?? [];
|
|
1417
1401
|
}
|
|
1402
|
+
const TAG_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
1403
|
+
function validateTag(tag) {
|
|
1404
|
+
if (!TAG_RE.test(tag))
|
|
1405
|
+
throw new Error(
|
|
1406
|
+
`tag: invalid tag "${tag}" \u2014 must match ${TAG_RE.source} (ASCII lowercase + digits + dashes, no leading dash, no dots)`
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
function tagScopeFilter() {
|
|
1410
|
+
return "tag == $tag";
|
|
1411
|
+
}
|
|
1418
1412
|
function definitionLookupGroq(explicit) {
|
|
1419
1413
|
const scoped = `_type == "${schema.WORKFLOW_DEFINITION_TYPE}" && name == $definition && ${tagScopeFilter()}`;
|
|
1420
1414
|
return explicit ? `*[${scoped} && version == $version][0]` : `*[${scoped}] | order(version desc)[0]`;
|
|
@@ -1431,6 +1425,14 @@ function clientForDiscovery(defaultClient, clientForGdr, subjectGdrUri) {
|
|
|
1431
1425
|
return defaultClient;
|
|
1432
1426
|
}
|
|
1433
1427
|
}
|
|
1428
|
+
async function reload(client, instanceId, tag) {
|
|
1429
|
+
const doc = await client.getDocument(instanceId);
|
|
1430
|
+
if (!doc)
|
|
1431
|
+
throw new Error(`Workflow instance ${instanceId} not found`);
|
|
1432
|
+
if (doc.tag !== tag)
|
|
1433
|
+
throw new Error(`Workflow instance ${instanceId} not visible to this engine (tag mismatch)`);
|
|
1434
|
+
return doc;
|
|
1435
|
+
}
|
|
1434
1436
|
function effectsContextEntry(name, value) {
|
|
1435
1437
|
const _key = randomKey();
|
|
1436
1438
|
return typeof value == "string" ? { _key, _type: "effectsContext.string", name, value } : typeof value == "number" ? { _key, _type: "effectsContext.number", name, value } : typeof value == "boolean" ? { _key, _type: "effectsContext.boolean", name, value } : { _key, _type: "effectsContext.ref", name, value };
|
|
@@ -1446,7 +1448,7 @@ function buildInstanceBase(args) {
|
|
|
1446
1448
|
_rev: "",
|
|
1447
1449
|
_createdAt: now,
|
|
1448
1450
|
_updatedAt: now,
|
|
1449
|
-
|
|
1451
|
+
tag: args.tag,
|
|
1450
1452
|
workflowResource: args.workflowResource,
|
|
1451
1453
|
definition: args.definitionName,
|
|
1452
1454
|
pinnedVersion: args.pinnedVersion,
|
|
@@ -1497,7 +1499,7 @@ async function spawnSubworkflows(ctx, mutation, task, sub, actor) {
|
|
|
1497
1499
|
`Subworkflow depth limit (${MAX_SPAWN_DEPTH}) exceeded on task "${task.name}" of ${ctx.instance._id}. Ancestor chain: ${chain}`
|
|
1498
1500
|
);
|
|
1499
1501
|
}
|
|
1500
|
-
const now = ctx.now, definition = await resolveDefinitionRef(ctx.client, sub.definition, ctx.instance.
|
|
1502
|
+
const now = ctx.now, definition = await resolveDefinitionRef(ctx.client, sub.definition, ctx.instance.tag);
|
|
1501
1503
|
if (definition === null) {
|
|
1502
1504
|
const versionLabel = sub.definition.version === void 0 || sub.definition.version === "latest" ? "latest" : `v${sub.definition.version}`;
|
|
1503
1505
|
throw new Error(
|
|
@@ -1587,15 +1589,15 @@ function coerceSpawnGdr(raw, workflowResource) {
|
|
|
1587
1589
|
}
|
|
1588
1590
|
return typeof raw == "string" && raw.length > 0 ? { id: toUri(raw), type: "document" } : null;
|
|
1589
1591
|
}
|
|
1590
|
-
async function resolveDefinitionRef(client, ref,
|
|
1591
|
-
const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name,
|
|
1592
|
+
async function resolveDefinitionRef(client, ref, tag) {
|
|
1593
|
+
const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name, tag };
|
|
1592
1594
|
return wantsExplicit && (params.version = ref.version), await client.fetch(
|
|
1593
1595
|
definitionLookupGroq(wantsExplicit),
|
|
1594
1596
|
params
|
|
1595
1597
|
) ?? null;
|
|
1596
1598
|
}
|
|
1597
1599
|
async function prepareChildInstance(args) {
|
|
1598
|
-
const { client, parent, definition, initialState, effectsContext, actor, now } = args,
|
|
1600
|
+
const { client, parent, definition, initialState, effectsContext, actor, now } = args, childTag = parent.tag, workflowResource = parent.workflowResource, childDocId = `${childTag}.wf-instance.${randomKey()}`, childRef = { id: gdrFromResource(workflowResource, childDocId), type: WORKFLOW_INSTANCE_TYPE }, ancestors = [
|
|
1599
1601
|
...parent.ancestors,
|
|
1600
1602
|
{
|
|
1601
1603
|
id: selfGdr(parent),
|
|
@@ -1608,7 +1610,7 @@ async function prepareChildInstance(args) {
|
|
|
1608
1610
|
client,
|
|
1609
1611
|
now,
|
|
1610
1612
|
selfId: childDocId,
|
|
1611
|
-
|
|
1613
|
+
tag: childTag,
|
|
1612
1614
|
workflowResource,
|
|
1613
1615
|
...inheritedPerspective !== void 0 ? { perspective: inheritedPerspective } : {}
|
|
1614
1616
|
},
|
|
@@ -1627,7 +1629,7 @@ async function prepareChildInstance(args) {
|
|
|
1627
1629
|
), base = buildInstanceBase({
|
|
1628
1630
|
id: childDocId,
|
|
1629
1631
|
now,
|
|
1630
|
-
|
|
1632
|
+
tag: childTag,
|
|
1631
1633
|
workflowResource,
|
|
1632
1634
|
definitionName: definition.name,
|
|
1633
1635
|
pinnedVersion: definition.version,
|
|
@@ -2493,17 +2495,12 @@ async function fetchGrantsCached(requestFn, resourcePath) {
|
|
|
2493
2495
|
}
|
|
2494
2496
|
}
|
|
2495
2497
|
async function evaluateInstance(args) {
|
|
2496
|
-
const { client,
|
|
2497
|
-
|
|
2498
|
+
const { client, tag, instanceId, resourceClients } = args, now = (args.clock ?? wallClock)();
|
|
2499
|
+
validateTag(tag);
|
|
2498
2500
|
const { actor, grants } = await resolveAccess(client, {
|
|
2499
2501
|
...args.access !== void 0 ? { override: args.access } : {},
|
|
2500
2502
|
...args.grantsFromPath !== void 0 ? { grantsFromPath: args.grantsFromPath } : {}
|
|
2501
|
-
}), instance = await client
|
|
2502
|
-
if (!instance)
|
|
2503
|
-
throw new Error(`Workflow instance "${instanceId}" not found`);
|
|
2504
|
-
if (!tags.some((t) => instance.tags?.includes(t)))
|
|
2505
|
-
throw new Error(`Workflow instance "${instanceId}" not visible to this engine (tag mismatch)`);
|
|
2506
|
-
const definition = parseDefinitionSnapshot(instance), snapshot = await hydrateSnapshot({ client, clientForGdr: resourceClients !== void 0 ? (parsed) => resourceClients(parsed) ?? client : () => client, instance }), guards = await verdictGuardsForInstance(client, instance._id);
|
|
2503
|
+
}), instance = await reload(client, instanceId, tag), definition = parseDefinitionSnapshot(instance), snapshot = await hydrateSnapshot({ client, clientForGdr: resourceClients !== void 0 ? (parsed) => resourceClients(parsed) ?? client : () => client, instance }), guards = await verdictGuardsForInstance(client, instance._id);
|
|
2507
2504
|
return evaluateFromSnapshot({
|
|
2508
2505
|
instance,
|
|
2509
2506
|
definition,
|
|
@@ -2644,22 +2641,21 @@ function lifecycleReason(instance, status, stageHasExits) {
|
|
|
2644
2641
|
function disabled(action, reason) {
|
|
2645
2642
|
return { action, allowed: !1, disabledReason: reason };
|
|
2646
2643
|
}
|
|
2647
|
-
function definitionDocId(_workflowResource,
|
|
2648
|
-
return `${
|
|
2644
|
+
function definitionDocId(_workflowResource, tag, definition, version) {
|
|
2645
|
+
return `${tag}.${definition}.v${version}`;
|
|
2649
2646
|
}
|
|
2650
|
-
async function sortByDependencies(client, definitions,
|
|
2651
|
-
const
|
|
2647
|
+
async function sortByDependencies(client, definitions, tag, workflowResource) {
|
|
2648
|
+
const byName = /* @__PURE__ */ new Map();
|
|
2652
2649
|
for (const def of definitions) {
|
|
2653
2650
|
const list = byName.get(def.name) ?? [];
|
|
2654
2651
|
list.push(def), byName.set(def.name, list);
|
|
2655
2652
|
}
|
|
2656
2653
|
const findInBatch = (ref) => findRefInBatch(byName, ref);
|
|
2657
2654
|
return await assertCrossBatchRefsDeployed(client, definitions, {
|
|
2658
|
-
|
|
2655
|
+
tag,
|
|
2659
2656
|
workflowResource,
|
|
2660
|
-
prefix,
|
|
2661
2657
|
findInBatch
|
|
2662
|
-
}), topoSortDefinitions(definitions, { workflowResource,
|
|
2658
|
+
}), topoSortDefinitions(definitions, { workflowResource, tag, findInBatch });
|
|
2663
2659
|
}
|
|
2664
2660
|
function findRefInBatch(byName, ref) {
|
|
2665
2661
|
const candidates = byName.get(ref.name);
|
|
@@ -2672,10 +2668,10 @@ function findRefInBatch(byName, ref) {
|
|
|
2672
2668
|
async function assertCrossBatchRefsDeployed(client, definitions, ctx) {
|
|
2673
2669
|
const missing = [];
|
|
2674
2670
|
for (const def of definitions) {
|
|
2675
|
-
const fromId = definitionDocId(ctx.workflowResource, ctx.
|
|
2671
|
+
const fromId = definitionDocId(ctx.workflowResource, ctx.tag, def.name, def.version);
|
|
2676
2672
|
for (const ref of refsOf(def)) {
|
|
2677
2673
|
if (ctx.findInBatch(ref) !== void 0) continue;
|
|
2678
|
-
const label = await resolveDeployedRefLabel(client, ref, ctx.
|
|
2674
|
+
const label = await resolveDeployedRefLabel(client, ref, ctx.tag);
|
|
2679
2675
|
label !== void 0 && missing.push({ from: fromId, ref: label });
|
|
2680
2676
|
}
|
|
2681
2677
|
}
|
|
@@ -2687,8 +2683,8 @@ async function assertCrossBatchRefsDeployed(client, definitions, ctx) {
|
|
|
2687
2683
|
`)
|
|
2688
2684
|
);
|
|
2689
2685
|
}
|
|
2690
|
-
async function resolveDeployedRefLabel(client, ref,
|
|
2691
|
-
const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name,
|
|
2686
|
+
async function resolveDeployedRefLabel(client, ref, tag) {
|
|
2687
|
+
const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name, tag };
|
|
2692
2688
|
if (wantsExplicit && (params.version = ref.version), !await client.fetch(
|
|
2693
2689
|
definitionLookupGroq(wantsExplicit),
|
|
2694
2690
|
params
|
|
@@ -2697,7 +2693,7 @@ async function resolveDeployedRefLabel(client, ref, tags) {
|
|
|
2697
2693
|
}
|
|
2698
2694
|
function topoSortDefinitions(definitions, ctx) {
|
|
2699
2695
|
const visited = /* @__PURE__ */ new Set(), visiting = /* @__PURE__ */ new Set(), ordered = [], visit = (def) => {
|
|
2700
|
-
const id = definitionDocId(ctx.workflowResource, ctx.
|
|
2696
|
+
const id = definitionDocId(ctx.workflowResource, ctx.tag, def.name, def.version);
|
|
2701
2697
|
if (!visited.has(id)) {
|
|
2702
2698
|
if (visiting.has(id))
|
|
2703
2699
|
throw new Error(`workflow.deployDefinitions: dependency cycle involving "${id}"`);
|
|
@@ -2738,11 +2734,11 @@ function stableStringify(value) {
|
|
|
2738
2734
|
([a], [b]) => a.localeCompare(b)
|
|
2739
2735
|
).map(([k, v2]) => `${JSON.stringify(k)}:${stableStringify(v2)}`).join(",")}}`;
|
|
2740
2736
|
}
|
|
2741
|
-
async function loadDefinition(client, definition, version,
|
|
2737
|
+
async function loadDefinition(client, definition, version, tag) {
|
|
2742
2738
|
if (version !== void 0) {
|
|
2743
2739
|
const doc = await client.fetch(
|
|
2744
2740
|
definitionLookupGroq(!0),
|
|
2745
|
-
{ definition, version,
|
|
2741
|
+
{ definition, version, tag }
|
|
2746
2742
|
);
|
|
2747
2743
|
if (!doc)
|
|
2748
2744
|
throw new Error(`Workflow definition ${definition} v${version} not deployed`);
|
|
@@ -2750,16 +2746,16 @@ async function loadDefinition(client, definition, version, tags) {
|
|
|
2750
2746
|
}
|
|
2751
2747
|
const latest = await client.fetch(definitionLookupGroq(!1), {
|
|
2752
2748
|
definition,
|
|
2753
|
-
|
|
2749
|
+
tag
|
|
2754
2750
|
});
|
|
2755
2751
|
if (!latest)
|
|
2756
2752
|
throw new Error(`No deployed definition for workflow ${definition}`);
|
|
2757
2753
|
return latest;
|
|
2758
2754
|
}
|
|
2759
|
-
async function loadDefinitionVersions(client, definition,
|
|
2755
|
+
async function loadDefinitionVersions(client, definition, tag) {
|
|
2760
2756
|
return client.fetch(
|
|
2761
|
-
`*[_type == "${schema.WORKFLOW_DEFINITION_TYPE}" && name == $definition &&
|
|
2762
|
-
{ definition,
|
|
2757
|
+
`*[_type == "${schema.WORKFLOW_DEFINITION_TYPE}" && name == $definition && ${tagScopeFilter()}] | order(version desc)`,
|
|
2758
|
+
{ definition, tag }
|
|
2763
2759
|
);
|
|
2764
2760
|
}
|
|
2765
2761
|
async function abortInstance(args) {
|
|
@@ -2910,7 +2906,7 @@ function bareIdFromSpawnRef(uri) {
|
|
|
2910
2906
|
}
|
|
2911
2907
|
}
|
|
2912
2908
|
async function resolveOperationContext(args) {
|
|
2913
|
-
|
|
2909
|
+
validateTag(args.tag);
|
|
2914
2910
|
const access = await resolveAccess(args.client, {
|
|
2915
2911
|
...args.access !== void 0 ? { override: args.access } : {},
|
|
2916
2912
|
...args.grantsFromPath !== void 0 ? { grantsFromPath: args.grantsFromPath } : {}
|
|
@@ -2944,16 +2940,6 @@ async function abortAndPropagate(args) {
|
|
|
2944
2940
|
function buildClientForGdr(defaultClient, resolver) {
|
|
2945
2941
|
return resolver === void 0 ? () => defaultClient : (parsed) => resolver(parsed) ?? defaultClient;
|
|
2946
2942
|
}
|
|
2947
|
-
async function reload(client, instanceId, tags) {
|
|
2948
|
-
const doc = await client.getDocument(instanceId);
|
|
2949
|
-
if (!doc) throw new Error(`Workflow instance ${instanceId} not found`);
|
|
2950
|
-
if (!intersectsTags(doc.tags, tags))
|
|
2951
|
-
throw new Error(`Workflow instance ${instanceId} not visible to this engine (tag mismatch)`);
|
|
2952
|
-
return doc;
|
|
2953
|
-
}
|
|
2954
|
-
function intersectsTags(docTags, engineTags) {
|
|
2955
|
-
return !docTags || docTags.length === 0 ? !1 : engineTags.some((t) => docTags.includes(t));
|
|
2956
|
-
}
|
|
2957
2943
|
function toEffectsContextEntries(ctx) {
|
|
2958
2944
|
return Object.entries(ctx).map(([id, value]) => effectsContextEntry(id, value));
|
|
2959
2945
|
}
|
|
@@ -2979,15 +2965,15 @@ async function applyAction(args) {
|
|
|
2979
2965
|
})).ranOps;
|
|
2980
2966
|
}
|
|
2981
2967
|
async function deleteDefinition(args) {
|
|
2982
|
-
const { client,
|
|
2968
|
+
const { client, tag, definition, version, cascade: cascade2, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, versions = await loadDefinitionVersions(client, definition, tag);
|
|
2983
2969
|
if (versions.length === 0)
|
|
2984
2970
|
throw new Error(`No deployed definition for workflow ${definition}`);
|
|
2985
2971
|
const targets = version === void 0 ? versions : versions.filter((d) => d.version === version);
|
|
2986
2972
|
if (targets.length === 0)
|
|
2987
2973
|
throw new Error(`Workflow definition ${definition} v${version} not deployed`);
|
|
2988
2974
|
const lastVersionGoes = targets.length === versions.length;
|
|
2989
|
-
await assertNoSpawnReferrers(client,
|
|
2990
|
-
const instanceIds = await nonTerminalInstanceIds(client,
|
|
2975
|
+
await assertNoSpawnReferrers(client, tag, definition, targets, lastVersionGoes);
|
|
2976
|
+
const instanceIds = await nonTerminalInstanceIds(client, tag, definition, version);
|
|
2991
2977
|
if (instanceIds.length > 0 && cascade2 !== !0)
|
|
2992
2978
|
throw new Error(
|
|
2993
2979
|
`Cannot delete ${definition}: ${instanceIds.length} non-terminal instance(s) exist (${previewIds(instanceIds)}). Pass cascade to abort them first \u2014 instances are aborted in place, never deleted.`
|
|
@@ -3008,7 +2994,7 @@ async function deleteDefinition(args) {
|
|
|
3008
2994
|
workflowResource: args.workflowResource,
|
|
3009
2995
|
definition,
|
|
3010
2996
|
definitions: versions,
|
|
3011
|
-
|
|
2997
|
+
tag
|
|
3012
2998
|
}) : 0;
|
|
3013
2999
|
return {
|
|
3014
3000
|
name: definition,
|
|
@@ -3017,10 +3003,10 @@ async function deleteDefinition(args) {
|
|
|
3017
3003
|
deletedGuardCount
|
|
3018
3004
|
};
|
|
3019
3005
|
}
|
|
3020
|
-
async function assertNoSpawnReferrers(client,
|
|
3006
|
+
async function assertNoSpawnReferrers(client, tag, definition, targets, lastVersionGoes) {
|
|
3021
3007
|
const deployed = await client.fetch(
|
|
3022
3008
|
`*[_type == "${schema.WORKFLOW_DEFINITION_TYPE}" && ${tagScopeFilter()}]`,
|
|
3023
|
-
{
|
|
3009
|
+
{ tag }
|
|
3024
3010
|
), targetIds = new Set(targets.map((d) => d._id)), targetVersions = new Set(targets.map((d) => d.version)), referrers = deployed.filter((d) => !targetIds.has(d._id)).filter(
|
|
3025
3011
|
(d) => refsOf(d).some(
|
|
3026
3012
|
(ref) => ref.name === definition && (typeof ref.version == "number" ? targetVersions.has(ref.version) : lastVersionGoes)
|
|
@@ -3033,11 +3019,11 @@ async function assertNoSpawnReferrers(client, tags, definition, targets, lastVer
|
|
|
3033
3019
|
);
|
|
3034
3020
|
}
|
|
3035
3021
|
}
|
|
3036
|
-
async function nonTerminalInstanceIds(client,
|
|
3022
|
+
async function nonTerminalInstanceIds(client, tag, definition, version) {
|
|
3037
3023
|
const versionFilter = version === void 0 ? "" : " && pinnedVersion == $version";
|
|
3038
3024
|
return (await client.fetch(
|
|
3039
3025
|
`*[_type == "${WORKFLOW_INSTANCE_TYPE}" && definition == $definition && ${tagScopeFilter()} && !defined(completedAt)${versionFilter}] | order(_id asc){_id}`,
|
|
3040
|
-
{ definition,
|
|
3026
|
+
{ definition, tag, ...version !== void 0 ? { version } : {} }
|
|
3041
3027
|
)).map((doc) => doc._id);
|
|
3042
3028
|
}
|
|
3043
3029
|
async function abortInstances(args) {
|
|
@@ -3068,20 +3054,20 @@ const workflow = {
|
|
|
3068
3054
|
* Cycles in the dependency graph error before any write happens.
|
|
3069
3055
|
*/
|
|
3070
3056
|
deployDefinitions: async (args) => {
|
|
3071
|
-
const { client,
|
|
3072
|
-
|
|
3057
|
+
const { client, tag, workflowResource, definitions } = args;
|
|
3058
|
+
validateTag(tag);
|
|
3073
3059
|
for (const def of definitions)
|
|
3074
3060
|
validateDefinition(def);
|
|
3075
|
-
const ordered = await sortByDependencies(client, definitions,
|
|
3061
|
+
const ordered = await sortByDependencies(client, definitions, tag, workflowResource), results = [], tx = client.transaction();
|
|
3076
3062
|
let hasWrites = !1;
|
|
3077
3063
|
for (const def of ordered) {
|
|
3078
|
-
const id = definitionDocId(workflowResource,
|
|
3064
|
+
const id = definitionDocId(workflowResource, tag, def.name, def.version), expected = {
|
|
3079
3065
|
...def,
|
|
3080
3066
|
_id: id,
|
|
3081
3067
|
_type: schema.WORKFLOW_DEFINITION_TYPE,
|
|
3082
|
-
|
|
3068
|
+
tag
|
|
3083
3069
|
}, existing = await client.getDocument(id);
|
|
3084
|
-
if (existing &&
|
|
3070
|
+
if (existing && existing.tag === tag && isDefinitionUnchanged(existing, expected)) {
|
|
3085
3071
|
results.push({ definition: def.name, version: def.version, status: "unchanged" });
|
|
3086
3072
|
continue;
|
|
3087
3073
|
}
|
|
@@ -3119,7 +3105,7 @@ const workflow = {
|
|
|
3119
3105
|
startInstance: async (args) => {
|
|
3120
3106
|
const {
|
|
3121
3107
|
client,
|
|
3122
|
-
|
|
3108
|
+
tag,
|
|
3123
3109
|
workflowResource,
|
|
3124
3110
|
definition: definitionName,
|
|
3125
3111
|
version,
|
|
@@ -3128,7 +3114,7 @@ const workflow = {
|
|
|
3128
3114
|
effectsContext,
|
|
3129
3115
|
instanceId,
|
|
3130
3116
|
perspective
|
|
3131
|
-
} = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, definition = await loadDefinition(client, definitionName, version,
|
|
3117
|
+
} = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, definition = await loadDefinition(client, definitionName, version, tag), id = instanceId ?? `${tag}.wf-instance.${randomKey()}`;
|
|
3132
3118
|
if (definition.stages.find((s) => s.name === definition.initialStage) === void 0)
|
|
3133
3119
|
throw new Error(
|
|
3134
3120
|
`Initial stage "${definition.initialStage}" missing in ${definitionName} v${definition.version}`
|
|
@@ -3140,7 +3126,7 @@ const workflow = {
|
|
|
3140
3126
|
client,
|
|
3141
3127
|
now,
|
|
3142
3128
|
selfId: id,
|
|
3143
|
-
|
|
3129
|
+
tag,
|
|
3144
3130
|
workflowResource,
|
|
3145
3131
|
...perspective !== void 0 ? { perspective } : {}
|
|
3146
3132
|
},
|
|
@@ -3148,7 +3134,7 @@ const workflow = {
|
|
|
3148
3134
|
}), effectivePerspective = perspective ?? derivePerspectiveFromState(resolvedState), base = buildInstanceBase({
|
|
3149
3135
|
id,
|
|
3150
3136
|
now,
|
|
3151
|
-
|
|
3137
|
+
tag,
|
|
3152
3138
|
workflowResource,
|
|
3153
3139
|
definitionName: definition.name,
|
|
3154
3140
|
pinnedVersion: definition.version,
|
|
@@ -3160,7 +3146,7 @@ const workflow = {
|
|
|
3160
3146
|
initialStage: definition.initialStage,
|
|
3161
3147
|
actor
|
|
3162
3148
|
});
|
|
3163
|
-
return await client.create(base), await primeInitialStage(client, id, actor, clientForGdr, clock), await cascade(client, id, actor, clientForGdr, clock), reload(client, id,
|
|
3149
|
+
return await client.create(base), await primeInitialStage(client, id, actor, clientForGdr, clock), await cascade(client, id, actor, clientForGdr, clock), reload(client, id, tag);
|
|
3164
3150
|
},
|
|
3165
3151
|
/**
|
|
3166
3152
|
* Fire an action against a task. If the task is pending, it is
|
|
@@ -3175,19 +3161,19 @@ const workflow = {
|
|
|
3175
3161
|
fireAction: async (args) => {
|
|
3176
3162
|
const {
|
|
3177
3163
|
client,
|
|
3178
|
-
|
|
3164
|
+
tag,
|
|
3179
3165
|
instanceId,
|
|
3180
3166
|
task,
|
|
3181
3167
|
action,
|
|
3182
3168
|
params,
|
|
3183
3169
|
idempotent,
|
|
3184
3170
|
resourceClients
|
|
3185
|
-
} = args, { access, actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, before = await reload(client, instanceId,
|
|
3171
|
+
} = args, { access, actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, before = await reload(client, instanceId, tag);
|
|
3186
3172
|
if (findOpenStageEntry(before)?.tasks.find((t) => t.name === task) === void 0 && idempotent === !0)
|
|
3187
3173
|
return { instance: before, cascaded: 0, fired: !1 };
|
|
3188
3174
|
const evaluation = await evaluateInstance({
|
|
3189
3175
|
client,
|
|
3190
|
-
|
|
3176
|
+
tag,
|
|
3191
3177
|
instanceId,
|
|
3192
3178
|
access,
|
|
3193
3179
|
clock,
|
|
@@ -3206,7 +3192,7 @@ const workflow = {
|
|
|
3206
3192
|
...params !== void 0 ? { params } : {}
|
|
3207
3193
|
}), cascaded = await cascade(client, instanceId, actor, clientForGdr, clock);
|
|
3208
3194
|
return {
|
|
3209
|
-
instance: await reload(client, instanceId,
|
|
3195
|
+
instance: await reload(client, instanceId, tag),
|
|
3210
3196
|
cascaded,
|
|
3211
3197
|
fired: !0,
|
|
3212
3198
|
...ranOps !== void 0 ? { ranOps } : {}
|
|
@@ -3220,7 +3206,7 @@ const workflow = {
|
|
|
3220
3206
|
* reference them. Cascades after.
|
|
3221
3207
|
*/
|
|
3222
3208
|
completeEffect: async (args) => {
|
|
3223
|
-
const { client,
|
|
3209
|
+
const { client, tag, instanceId, effectKey, status, outputs, detail, error, durationMs } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
|
|
3224
3210
|
await completeEffect({
|
|
3225
3211
|
client,
|
|
3226
3212
|
instanceId,
|
|
@@ -3234,7 +3220,7 @@ const workflow = {
|
|
|
3234
3220
|
});
|
|
3235
3221
|
const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock);
|
|
3236
3222
|
return {
|
|
3237
|
-
instance: await reload(client, instanceId,
|
|
3223
|
+
instance: await reload(client, instanceId, tag),
|
|
3238
3224
|
cascaded,
|
|
3239
3225
|
fired: !0
|
|
3240
3226
|
};
|
|
@@ -3249,11 +3235,11 @@ const workflow = {
|
|
|
3249
3235
|
* affected instances and the engine re-evaluates.
|
|
3250
3236
|
*/
|
|
3251
3237
|
tick: async (args) => {
|
|
3252
|
-
const { client,
|
|
3238
|
+
const { client, tag, instanceId } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, current = await reload(client, instanceId, tag), guards = await verdictGuardsForInstance(client, current._id);
|
|
3253
3239
|
await assertInstanceWriteAllowed({ instance: current, guards, identity: actor.id });
|
|
3254
3240
|
const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock);
|
|
3255
3241
|
return {
|
|
3256
|
-
instance: await reload(client, instanceId,
|
|
3242
|
+
instance: await reload(client, instanceId, tag),
|
|
3257
3243
|
cascaded,
|
|
3258
3244
|
fired: cascaded > 0
|
|
3259
3245
|
};
|
|
@@ -3264,8 +3250,8 @@ const workflow = {
|
|
|
3264
3250
|
* upstream; this verb performs the mechanical move.
|
|
3265
3251
|
*/
|
|
3266
3252
|
setStage: async (args) => {
|
|
3267
|
-
const { client,
|
|
3268
|
-
await reload(client, instanceId,
|
|
3253
|
+
const { client, tag, instanceId, targetStage, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
|
|
3254
|
+
await reload(client, instanceId, tag);
|
|
3269
3255
|
const result = await setStage({
|
|
3270
3256
|
client,
|
|
3271
3257
|
instanceId,
|
|
@@ -3274,7 +3260,7 @@ const workflow = {
|
|
|
3274
3260
|
options: { ...actor !== void 0 ? { actor } : {}, clock, clientForGdr }
|
|
3275
3261
|
}), cascaded = result.fired ? await cascade(client, instanceId, actor, clientForGdr, clock) : 0;
|
|
3276
3262
|
return {
|
|
3277
|
-
instance: await reload(client, instanceId,
|
|
3263
|
+
instance: await reload(client, instanceId, tag),
|
|
3278
3264
|
cascaded,
|
|
3279
3265
|
fired: result.fired
|
|
3280
3266
|
};
|
|
@@ -3286,28 +3272,28 @@ const workflow = {
|
|
|
3286
3272
|
* contract (propagated, not cascaded — the instance is terminal).
|
|
3287
3273
|
*/
|
|
3288
3274
|
abortInstance: async (args) => {
|
|
3289
|
-
const { client,
|
|
3290
|
-
await reload(client, instanceId,
|
|
3275
|
+
const { client, tag, instanceId, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
|
|
3276
|
+
await reload(client, instanceId, tag);
|
|
3291
3277
|
const fired = await abortAndPropagate({ client, instanceId, reason, actor, clientForGdr, clock });
|
|
3292
3278
|
return {
|
|
3293
|
-
instance: await reload(client, instanceId,
|
|
3279
|
+
instance: await reload(client, instanceId, tag),
|
|
3294
3280
|
cascaded: 0,
|
|
3295
3281
|
fired
|
|
3296
3282
|
};
|
|
3297
3283
|
},
|
|
3298
3284
|
/**
|
|
3299
|
-
* Fetch a workflow instance by id, scoped to the engine's
|
|
3285
|
+
* Fetch a workflow instance by id, scoped to the engine's tag.
|
|
3300
3286
|
* Throws when the instance doesn't exist or isn't visible to this
|
|
3301
3287
|
* engine.
|
|
3302
3288
|
*/
|
|
3303
3289
|
getInstance: async (args) => {
|
|
3304
|
-
const { client,
|
|
3305
|
-
return
|
|
3290
|
+
const { client, tag, instanceId } = args;
|
|
3291
|
+
return validateTag(tag), reload(client, instanceId, tag);
|
|
3306
3292
|
},
|
|
3307
3293
|
guardsForInstance: async (args) => {
|
|
3308
|
-
const { client,
|
|
3309
|
-
|
|
3310
|
-
const instance = await reload(client, instanceId,
|
|
3294
|
+
const { client, tag, instanceId, resourceClients } = args;
|
|
3295
|
+
validateTag(tag);
|
|
3296
|
+
const instance = await reload(client, instanceId, tag);
|
|
3311
3297
|
return guardsForInstance({
|
|
3312
3298
|
client,
|
|
3313
3299
|
clientForGdr: buildClientForGdr(client, resourceClients),
|
|
@@ -3315,9 +3301,9 @@ const workflow = {
|
|
|
3315
3301
|
});
|
|
3316
3302
|
},
|
|
3317
3303
|
guardsForDefinition: async (args) => {
|
|
3318
|
-
const { client,
|
|
3319
|
-
|
|
3320
|
-
const definitions = await loadDefinitionVersions(client, definition,
|
|
3304
|
+
const { client, tag, workflowResource, definition, resourceClients } = args;
|
|
3305
|
+
validateTag(tag);
|
|
3306
|
+
const definitions = await loadDefinitionVersions(client, definition, tag);
|
|
3321
3307
|
if (definitions.length === 0)
|
|
3322
3308
|
throw new Error(`No deployed definition for workflow ${definition}`);
|
|
3323
3309
|
return guardsForDefinition({
|
|
@@ -3329,22 +3315,21 @@ const workflow = {
|
|
|
3329
3315
|
});
|
|
3330
3316
|
},
|
|
3331
3317
|
/**
|
|
3332
|
-
* Run a caller-supplied GROQ query with the engine's
|
|
3333
|
-
* `$
|
|
3318
|
+
* Run a caller-supplied GROQ query with the engine's tag bound as
|
|
3319
|
+
* `$tag`. This does NOT rewrite the query — arbitrary GROQ
|
|
3334
3320
|
* can't be safely tag-scoped after the fact — so the CALLER MUST
|
|
3335
|
-
* filter on `$
|
|
3336
|
-
*
|
|
3337
|
-
* cross-tenant reads, a query that never references `$engineTags` is
|
|
3321
|
+
* filter on `$tag` (e.g. `tag == $tag`). To guard against accidental
|
|
3322
|
+
* cross-partition reads, a query that never references `$tag` is
|
|
3338
3323
|
* rejected before it reaches the lake. Caller is responsible for type
|
|
3339
3324
|
* narrowing the result.
|
|
3340
3325
|
*/
|
|
3341
3326
|
query: async (args) => {
|
|
3342
|
-
const { client,
|
|
3343
|
-
if (
|
|
3327
|
+
const { client, tag, groq, params } = args;
|
|
3328
|
+
if (validateTag(tag), !/\$tag\b/.test(groq))
|
|
3344
3329
|
throw new Error(
|
|
3345
|
-
`workflow.query: query must filter on $
|
|
3330
|
+
`workflow.query: query must filter on $tag to stay tag-scoped (e.g. "tag == $tag"); got: ${groq}`
|
|
3346
3331
|
);
|
|
3347
|
-
return client.fetch(groq, { ...params,
|
|
3332
|
+
return client.fetch(groq, { ...params, tag });
|
|
3348
3333
|
},
|
|
3349
3334
|
/**
|
|
3350
3335
|
* Snapshot-aware GROQ — runs against the same in-memory view that
|
|
@@ -3363,9 +3348,9 @@ const workflow = {
|
|
|
3363
3348
|
* without re-implementing hydration. Pure read — never writes.
|
|
3364
3349
|
*/
|
|
3365
3350
|
queryInScope: async (args) => {
|
|
3366
|
-
const { client,
|
|
3367
|
-
|
|
3368
|
-
const instance = await reload(client, instanceId,
|
|
3351
|
+
const { client, tag, instanceId, groq, params, resourceClients } = args, clock = args.clock ?? wallClock;
|
|
3352
|
+
validateTag(tag);
|
|
3353
|
+
const instance = await reload(client, instanceId, tag), clientForGdr = buildClientForGdr(client, resourceClients), snapshot = await hydrateSnapshot({ client, clientForGdr, instance }), reserved = buildParams({ instance, now: clock(), snapshot }), tree = groqJs.parse(groq, { params: { ...reserved, ...params } });
|
|
3369
3354
|
return await (await groqJs.evaluate(tree, {
|
|
3370
3355
|
dataset: snapshot.docs,
|
|
3371
3356
|
params: { ...reserved, ...params }
|
|
@@ -3375,13 +3360,13 @@ const workflow = {
|
|
|
3375
3360
|
* List every pending effect on the instance. Returns the same entries
|
|
3376
3361
|
* the runtime would see — claimed and unclaimed alike.
|
|
3377
3362
|
*/
|
|
3378
|
-
listPendingEffects: async (args) => (await reload(args.client, args.instanceId, args.
|
|
3363
|
+
listPendingEffects: async (args) => (await reload(args.client, args.instanceId, args.tag)).pendingEffects,
|
|
3379
3364
|
/**
|
|
3380
3365
|
* Filter pending effects on the instance by criteria. `claimed`
|
|
3381
3366
|
* filters on claim presence; `names` restricts to specific effect
|
|
3382
3367
|
* names. Both filters compose (AND).
|
|
3383
3368
|
*/
|
|
3384
|
-
findPendingEffects: async (args) => (await reload(args.client, args.instanceId, args.
|
|
3369
|
+
findPendingEffects: async (args) => (await reload(args.client, args.instanceId, args.tag)).pendingEffects.filter((e) => !(args.claimed === !0 && e.claim === void 0 || args.claimed === !1 && e.claim !== void 0 || args.names !== void 0 && !args.names.includes(e.name))),
|
|
3385
3370
|
/**
|
|
3386
3371
|
* Project the instance from a given actor's perspective. Returns a
|
|
3387
3372
|
* `WorkflowEvaluation` with per-action verdicts (`allowed` + a
|
|
@@ -3422,18 +3407,18 @@ const workflow = {
|
|
|
3422
3407
|
* record. (The per-task `spawnedInstances` field on the active stage
|
|
3423
3408
|
* only exists while that stage is current; history survives.) Strips
|
|
3424
3409
|
* the GDR URI on each `instanceRef` to a bare `_id`, fetches the
|
|
3425
|
-
* instances, drops any that aren't visible to this engine's
|
|
3410
|
+
* instances, drops any that aren't visible to this engine's tag, and
|
|
3426
3411
|
* returns them sorted by `startedAt` ascending.
|
|
3427
3412
|
*
|
|
3428
3413
|
* Pass `task` to restrict to a single spawning task on the parent.
|
|
3429
3414
|
*/
|
|
3430
3415
|
children: async (args) => {
|
|
3431
|
-
const { client,
|
|
3432
|
-
|
|
3433
|
-
const parent = await reload(client, instanceId,
|
|
3416
|
+
const { client, tag, instanceId, task } = args;
|
|
3417
|
+
validateTag(tag);
|
|
3418
|
+
const parent = await reload(client, instanceId, tag), isSpawned = (h) => h._type === "spawned", ids = parent.history.filter(isSpawned).filter((h) => task === void 0 || h.task === task).flatMap((h) => bareIdFromSpawnRef(h.instanceRef.id));
|
|
3434
3419
|
return ids.length === 0 ? [] : client.fetch(
|
|
3435
3420
|
`*[_id in $ids && ${tagScopeFilter()}] | order(startedAt asc)`,
|
|
3436
|
-
{ ids,
|
|
3421
|
+
{ ids, tag }
|
|
3437
3422
|
);
|
|
3438
3423
|
},
|
|
3439
3424
|
/**
|
|
@@ -3448,11 +3433,11 @@ const workflow = {
|
|
|
3448
3433
|
}
|
|
3449
3434
|
};
|
|
3450
3435
|
async function verifyDeployedDefinitionsInternal(args) {
|
|
3451
|
-
const { client,
|
|
3452
|
-
|
|
3436
|
+
const { client, tag, effectHandlers, missingHandler, logger } = args;
|
|
3437
|
+
validateTag(tag);
|
|
3453
3438
|
const log = logger("verifyDeployedDefinitions"), definitions = await client.fetch(
|
|
3454
3439
|
`*[_type == "${schema.WORKFLOW_DEFINITION_TYPE}" && ${tagScopeFilter()}] | order(name asc, version asc)`,
|
|
3455
|
-
{
|
|
3440
|
+
{ tag }
|
|
3456
3441
|
), seen = [], missingByName = /* @__PURE__ */ new Map();
|
|
3457
3442
|
for (const def of definitions)
|
|
3458
3443
|
seen.push({ name: def.name, version: def.version, _id: def._id }), walkEffectNames(def, (name, location) => {
|
|
@@ -3501,7 +3486,7 @@ function walkEffectNames(def, visit) {
|
|
|
3501
3486
|
async function drainEffectsInternal(args) {
|
|
3502
3487
|
const {
|
|
3503
3488
|
client,
|
|
3504
|
-
|
|
3489
|
+
tag,
|
|
3505
3490
|
workflowResource,
|
|
3506
3491
|
resourceClients,
|
|
3507
3492
|
instanceId,
|
|
@@ -3512,10 +3497,10 @@ async function drainEffectsInternal(args) {
|
|
|
3512
3497
|
actor: drainerActor,
|
|
3513
3498
|
...args.access?.grants !== void 0 ? { grants: args.access.grants } : {}
|
|
3514
3499
|
};
|
|
3515
|
-
|
|
3500
|
+
validateTag(tag);
|
|
3516
3501
|
const log = logger("drainEffects"), drained = [], failed = [], skipped = [], skippedKeys = /* @__PURE__ */ new Set();
|
|
3517
3502
|
for (; ; ) {
|
|
3518
|
-
const before = await reload(client, instanceId,
|
|
3503
|
+
const before = await reload(client, instanceId, tag), candidate = before.pendingEffects.find(
|
|
3519
3504
|
(e) => e.claim === void 0 && !skippedKeys.has(e._key)
|
|
3520
3505
|
);
|
|
3521
3506
|
if (candidate === void 0) break;
|
|
@@ -3532,7 +3517,7 @@ async function drainEffectsInternal(args) {
|
|
|
3532
3517
|
});
|
|
3533
3518
|
await reportEffectOutcome({
|
|
3534
3519
|
client,
|
|
3535
|
-
|
|
3520
|
+
tag,
|
|
3536
3521
|
workflowResource,
|
|
3537
3522
|
...resourceClients !== void 0 ? { resourceClients } : {},
|
|
3538
3523
|
instanceId,
|
|
@@ -3602,7 +3587,7 @@ async function applyMissingHandler(policy, info, log) {
|
|
|
3602
3587
|
}
|
|
3603
3588
|
}
|
|
3604
3589
|
function createInstanceSession(args) {
|
|
3605
|
-
const { client,
|
|
3590
|
+
const { client, tag, clock } = args, clientForGdr = buildClientForGdr(client, args.resourceClients);
|
|
3606
3591
|
let instance = asHeldInstance(args.instance), overlay = /* @__PURE__ */ new Map(), heldGuards = [], committing = !1, buffered;
|
|
3607
3592
|
const selfUri = () => gdrFromResource(instance.workflowResource, instance._id), applyUpdate = (docs) => {
|
|
3608
3593
|
const next = /* @__PURE__ */ new Map();
|
|
@@ -3663,7 +3648,7 @@ function createInstanceSession(args) {
|
|
|
3663
3648
|
return commit(async (actor, held) => {
|
|
3664
3649
|
await assertInstanceWriteAllowed({ instance, guards: heldGuards, identity: actor.id });
|
|
3665
3650
|
const cascaded = await cascade(client, instance._id, actor, clientForGdr, clock, held);
|
|
3666
|
-
return instance = await reload(client, instance._id,
|
|
3651
|
+
return instance = await reload(client, instance._id, tag), { instance, cascaded, fired: cascaded > 0 };
|
|
3667
3652
|
});
|
|
3668
3653
|
},
|
|
3669
3654
|
fireAction({ task, action, params }) {
|
|
@@ -3680,7 +3665,7 @@ function createInstanceSession(args) {
|
|
|
3680
3665
|
...clock !== void 0 ? { clock } : {},
|
|
3681
3666
|
...params !== void 0 ? { params } : {}
|
|
3682
3667
|
}), cascaded = await cascade(client, instance._id, actor, clientForGdr, clock, held);
|
|
3683
|
-
return instance = await reload(client, instance._id,
|
|
3668
|
+
return instance = await reload(client, instance._id, tag), { instance, cascaded, fired: !0, ...ranOps !== void 0 ? { ranOps } : {} };
|
|
3684
3669
|
});
|
|
3685
3670
|
}
|
|
3686
3671
|
};
|
|
@@ -3708,11 +3693,11 @@ const defaultLoggerFactory = (name) => ({
|
|
|
3708
3693
|
}
|
|
3709
3694
|
};
|
|
3710
3695
|
function createEngine(args) {
|
|
3711
|
-
const { client, workflowResource,
|
|
3712
|
-
|
|
3696
|
+
const { client, workflowResource, resourceClients, clock, tag } = args;
|
|
3697
|
+
validateTag(tag);
|
|
3713
3698
|
const effectHandlers = args.effectHandlers ?? {}, missingHandler = args.missingHandler ?? "fail", logger = args.loggerFactory ?? defaultLoggerFactory, bind = (rest) => ({
|
|
3714
3699
|
client,
|
|
3715
|
-
|
|
3700
|
+
tag,
|
|
3716
3701
|
workflowResource,
|
|
3717
3702
|
...resourceClients !== void 0 ? { resourceClients } : {},
|
|
3718
3703
|
...clock !== void 0 ? { clock } : {},
|
|
@@ -3720,7 +3705,7 @@ function createEngine(args) {
|
|
|
3720
3705
|
});
|
|
3721
3706
|
return {
|
|
3722
3707
|
client,
|
|
3723
|
-
|
|
3708
|
+
tag,
|
|
3724
3709
|
workflowResource,
|
|
3725
3710
|
effectHandlers,
|
|
3726
3711
|
missingHandler,
|
|
@@ -3736,11 +3721,11 @@ function createEngine(args) {
|
|
|
3736
3721
|
setStage: (rest) => workflow.setStage(bind(rest)),
|
|
3737
3722
|
abortInstance: (rest) => workflow.abortInstance(bind(rest)),
|
|
3738
3723
|
deleteDefinition: (rest) => workflow.deleteDefinition(bind(rest)),
|
|
3739
|
-
getInstance: ({ instanceId }) => workflow.getInstance({ client,
|
|
3740
|
-
subscriptionDocumentsForInstance: ({ instanceId }) => workflow.getInstance({ client,
|
|
3724
|
+
getInstance: ({ instanceId }) => workflow.getInstance({ client, tag, workflowResource, instanceId }),
|
|
3725
|
+
subscriptionDocumentsForInstance: ({ instanceId }) => workflow.getInstance({ client, tag, workflowResource, instanceId }).then(subscriptionDocumentsForInstance),
|
|
3741
3726
|
instance: (instanceDoc, opts) => createInstanceSession({
|
|
3742
3727
|
client,
|
|
3743
|
-
|
|
3728
|
+
tag,
|
|
3744
3729
|
instance: instanceDoc,
|
|
3745
3730
|
...resourceClients !== void 0 ? { resourceClients } : {},
|
|
3746
3731
|
...clock !== void 0 ? { clock } : {},
|
|
@@ -3749,45 +3734,45 @@ function createEngine(args) {
|
|
|
3749
3734
|
}),
|
|
3750
3735
|
guardsForInstance: ({ instanceId }) => workflow.guardsForInstance({
|
|
3751
3736
|
client,
|
|
3752
|
-
|
|
3737
|
+
tag,
|
|
3753
3738
|
workflowResource,
|
|
3754
3739
|
instanceId,
|
|
3755
3740
|
...resourceClients !== void 0 ? { resourceClients } : {}
|
|
3756
3741
|
}),
|
|
3757
3742
|
guardsForDefinition: ({ definition }) => workflow.guardsForDefinition({
|
|
3758
3743
|
client,
|
|
3759
|
-
|
|
3744
|
+
tag,
|
|
3760
3745
|
workflowResource,
|
|
3761
3746
|
definition,
|
|
3762
3747
|
...resourceClients !== void 0 ? { resourceClients } : {}
|
|
3763
3748
|
}),
|
|
3764
3749
|
children: ({ instanceId, task }) => workflow.children({
|
|
3765
3750
|
client,
|
|
3766
|
-
|
|
3751
|
+
tag,
|
|
3767
3752
|
workflowResource,
|
|
3768
3753
|
instanceId,
|
|
3769
3754
|
...task !== void 0 ? { task } : {}
|
|
3770
3755
|
}),
|
|
3771
3756
|
query: ({ groq, params }) => workflow.query({
|
|
3772
3757
|
client,
|
|
3773
|
-
|
|
3758
|
+
tag,
|
|
3774
3759
|
workflowResource,
|
|
3775
3760
|
groq,
|
|
3776
3761
|
...params !== void 0 ? { params } : {}
|
|
3777
3762
|
}),
|
|
3778
3763
|
queryInScope: ({ instanceId, groq, params }) => workflow.queryInScope({
|
|
3779
3764
|
client,
|
|
3780
|
-
|
|
3765
|
+
tag,
|
|
3781
3766
|
workflowResource,
|
|
3782
3767
|
instanceId,
|
|
3783
3768
|
groq,
|
|
3784
3769
|
...params !== void 0 ? { params } : {},
|
|
3785
3770
|
...clock !== void 0 ? { clock } : {}
|
|
3786
3771
|
}),
|
|
3787
|
-
listPendingEffects: ({ instanceId }) => workflow.listPendingEffects({ client,
|
|
3772
|
+
listPendingEffects: ({ instanceId }) => workflow.listPendingEffects({ client, tag, workflowResource, instanceId }),
|
|
3788
3773
|
findPendingEffects: ({ instanceId, claimed, names }) => workflow.findPendingEffects({
|
|
3789
3774
|
client,
|
|
3790
|
-
|
|
3775
|
+
tag,
|
|
3791
3776
|
workflowResource,
|
|
3792
3777
|
instanceId,
|
|
3793
3778
|
...claimed !== void 0 ? { claimed } : {},
|
|
@@ -3795,7 +3780,7 @@ function createEngine(args) {
|
|
|
3795
3780
|
}),
|
|
3796
3781
|
drainEffects: ({ instanceId, access }) => drainEffectsInternal({
|
|
3797
3782
|
client,
|
|
3798
|
-
|
|
3783
|
+
tag,
|
|
3799
3784
|
workflowResource,
|
|
3800
3785
|
...resourceClients !== void 0 ? { resourceClients } : {},
|
|
3801
3786
|
instanceId,
|
|
@@ -3806,7 +3791,7 @@ function createEngine(args) {
|
|
|
3806
3791
|
}),
|
|
3807
3792
|
verifyDeployedDefinitions: () => verifyDeployedDefinitionsInternal({
|
|
3808
3793
|
client,
|
|
3809
|
-
|
|
3794
|
+
tag,
|
|
3810
3795
|
effectHandlers,
|
|
3811
3796
|
missingHandler,
|
|
3812
3797
|
logger
|
|
@@ -3814,7 +3799,7 @@ function createEngine(args) {
|
|
|
3814
3799
|
};
|
|
3815
3800
|
}
|
|
3816
3801
|
function docIdFor(def, target) {
|
|
3817
|
-
return definitionDocId(target.workflowResource,
|
|
3802
|
+
return definitionDocId(target.workflowResource, target.tag, def.name, def.version);
|
|
3818
3803
|
}
|
|
3819
3804
|
function diffStatus(existing, expected) {
|
|
3820
3805
|
return existing === void 0 ? "create" : isDefinitionUnchanged(existing, expected) ? "unchanged" : "update";
|
|
@@ -3824,7 +3809,7 @@ function diffEntry(def, existingRaw, target) {
|
|
|
3824
3809
|
...def,
|
|
3825
3810
|
_id: docId,
|
|
3826
3811
|
_type: schema.WORKFLOW_DEFINITION_TYPE,
|
|
3827
|
-
|
|
3812
|
+
tag: target.tag
|
|
3828
3813
|
}, status = diffStatus(existingRaw, expected), existing = existingRaw ? stripSystemFields(existingRaw) : void 0;
|
|
3829
3814
|
return {
|
|
3830
3815
|
name: def.name,
|
|
@@ -4040,7 +4025,6 @@ exports.actionVerdict = actionVerdict;
|
|
|
4040
4025
|
exports.assigneesOf = assigneesOf;
|
|
4041
4026
|
exports.availableActions = availableActions;
|
|
4042
4027
|
exports.buildSnapshot = buildSnapshot;
|
|
4043
|
-
exports.canonicalTag = canonicalTag;
|
|
4044
4028
|
exports.compileGuard = compileGuard;
|
|
4045
4029
|
exports.computeDiffEntries = computeDiffEntries;
|
|
4046
4030
|
exports.contentReleaseName = contentReleaseName;
|
|
@@ -4086,7 +4070,7 @@ exports.subscriptionDocument = subscriptionDocument;
|
|
|
4086
4070
|
exports.subscriptionDocumentsForInstance = subscriptionDocumentsForInstance;
|
|
4087
4071
|
exports.tagScopeFilter = tagScopeFilter;
|
|
4088
4072
|
exports.validateDefinition = validateDefinition;
|
|
4089
|
-
exports.
|
|
4073
|
+
exports.validateTag = validateTag;
|
|
4090
4074
|
exports.verdictGuardsForInstance = verdictGuardsForInstance;
|
|
4091
4075
|
exports.wallClock = wallClock;
|
|
4092
4076
|
exports.workflow = workflow;
|