@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.js
CHANGED
|
@@ -722,22 +722,6 @@ async function queryGuardsAcross(clients, query, params) {
|
|
|
722
722
|
function dedupById(guards) {
|
|
723
723
|
return [...new Map(guards.map((g) => [g._id, g])).values()].sort((a, b) => a._id.localeCompare(b._id));
|
|
724
724
|
}
|
|
725
|
-
const TAG_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
726
|
-
function validateTags(tags) {
|
|
727
|
-
if (tags.length === 0)
|
|
728
|
-
throw new Error("tags: must be a non-empty array");
|
|
729
|
-
for (const tag of tags)
|
|
730
|
-
if (!TAG_RE.test(tag))
|
|
731
|
-
throw new Error(
|
|
732
|
-
`tags: invalid tag "${tag}" \u2014 must match ${TAG_RE.source} (ASCII lowercase + digits + dashes, no leading dash, no dots)`
|
|
733
|
-
);
|
|
734
|
-
}
|
|
735
|
-
function canonicalTag(tags) {
|
|
736
|
-
return tags[0];
|
|
737
|
-
}
|
|
738
|
-
function tagScopeFilter(param = "engineTags") {
|
|
739
|
-
return `count(tags[@ in $${param}]) > 0`;
|
|
740
|
-
}
|
|
741
725
|
const GUARD_OWNER = "robot:workflow-engine", GUARD_LIFTED_PREDICATE = "true";
|
|
742
726
|
function resolveGuard(guard, instance, stageName, now) {
|
|
743
727
|
const ctx = { instance, now }, targets = resolveIdRefTargets(guard.match.idRefs, ctx);
|
|
@@ -795,13 +779,13 @@ async function retractStageGuards(args) {
|
|
|
795
779
|
await client.getDocument(doc._id) && await client.patch(doc._id).set({ predicate: GUARD_LIFTED_PREDICATE }).commit();
|
|
796
780
|
}
|
|
797
781
|
async function deleteOrphanedDefinitionGuards(args) {
|
|
798
|
-
const { client, clientForGdr, workflowResource, definition, definitions,
|
|
782
|
+
const { client, clientForGdr, workflowResource, definition, definitions, tag } = args, perClient = await guardsForDefinitionByClient({
|
|
799
783
|
client,
|
|
800
784
|
clientForGdr,
|
|
801
785
|
workflowResource,
|
|
802
786
|
definition,
|
|
803
787
|
definitions
|
|
804
|
-
}), ownPartitionPrefix = `${
|
|
788
|
+
}), ownPartitionPrefix = `${tag}.`;
|
|
805
789
|
let count = 0;
|
|
806
790
|
for (const { client: resourceClient, guards } of perClient) {
|
|
807
791
|
const own = guards.filter((guard) => guard.sourceInstanceId.startsWith(ownPartitionPrefix));
|
|
@@ -990,7 +974,7 @@ async function resolveQueryValue(entry, source, ctx, client, defaultValue) {
|
|
|
990
974
|
stage: ctx.stageName ?? null,
|
|
991
975
|
task: ctx.taskName ?? null,
|
|
992
976
|
now: ctx.now,
|
|
993
|
-
|
|
977
|
+
tag: ctx.tag
|
|
994
978
|
});
|
|
995
979
|
try {
|
|
996
980
|
const fetchOptions = ctx.perspective !== void 0 ? { perspective: ctx.perspective } : void 0, result = await client.fetch(source.query, params, fetchOptions);
|
|
@@ -1157,7 +1141,7 @@ async function resolveStageStateEntries(args) {
|
|
|
1157
1141
|
client,
|
|
1158
1142
|
now,
|
|
1159
1143
|
selfId: instance._id,
|
|
1160
|
-
|
|
1144
|
+
tag: instance.tag,
|
|
1161
1145
|
stageName: stage.name,
|
|
1162
1146
|
workflowResource: instance.workflowResource,
|
|
1163
1147
|
// Allow stage-scope entries' `source: { type: "stateRead", scope:
|
|
@@ -1177,7 +1161,7 @@ async function resolveTaskStateEntries(args) {
|
|
|
1177
1161
|
client,
|
|
1178
1162
|
now,
|
|
1179
1163
|
selfId: instance._id,
|
|
1180
|
-
|
|
1164
|
+
tag: instance.tag,
|
|
1181
1165
|
stageName: stage.name,
|
|
1182
1166
|
workflowResource: instance.workflowResource,
|
|
1183
1167
|
taskName: task.name,
|
|
@@ -1399,6 +1383,16 @@ function findCurrentStageEntry(instance) {
|
|
|
1399
1383
|
function findCurrentTasks(instance) {
|
|
1400
1384
|
return findCurrentStageEntry(instance)?.tasks ?? [];
|
|
1401
1385
|
}
|
|
1386
|
+
const TAG_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
1387
|
+
function validateTag(tag) {
|
|
1388
|
+
if (!TAG_RE.test(tag))
|
|
1389
|
+
throw new Error(
|
|
1390
|
+
`tag: invalid tag "${tag}" \u2014 must match ${TAG_RE.source} (ASCII lowercase + digits + dashes, no leading dash, no dots)`
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
function tagScopeFilter() {
|
|
1394
|
+
return "tag == $tag";
|
|
1395
|
+
}
|
|
1402
1396
|
function definitionLookupGroq(explicit) {
|
|
1403
1397
|
const scoped = `_type == "${WORKFLOW_DEFINITION_TYPE}" && name == $definition && ${tagScopeFilter()}`;
|
|
1404
1398
|
return explicit ? `*[${scoped} && version == $version][0]` : `*[${scoped}] | order(version desc)[0]`;
|
|
@@ -1415,6 +1409,14 @@ function clientForDiscovery(defaultClient, clientForGdr, subjectGdrUri) {
|
|
|
1415
1409
|
return defaultClient;
|
|
1416
1410
|
}
|
|
1417
1411
|
}
|
|
1412
|
+
async function reload(client, instanceId, tag) {
|
|
1413
|
+
const doc = await client.getDocument(instanceId);
|
|
1414
|
+
if (!doc)
|
|
1415
|
+
throw new Error(`Workflow instance ${instanceId} not found`);
|
|
1416
|
+
if (doc.tag !== tag)
|
|
1417
|
+
throw new Error(`Workflow instance ${instanceId} not visible to this engine (tag mismatch)`);
|
|
1418
|
+
return doc;
|
|
1419
|
+
}
|
|
1418
1420
|
function effectsContextEntry(name, value) {
|
|
1419
1421
|
const _key = randomKey();
|
|
1420
1422
|
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 };
|
|
@@ -1430,7 +1432,7 @@ function buildInstanceBase(args) {
|
|
|
1430
1432
|
_rev: "",
|
|
1431
1433
|
_createdAt: now,
|
|
1432
1434
|
_updatedAt: now,
|
|
1433
|
-
|
|
1435
|
+
tag: args.tag,
|
|
1434
1436
|
workflowResource: args.workflowResource,
|
|
1435
1437
|
definition: args.definitionName,
|
|
1436
1438
|
pinnedVersion: args.pinnedVersion,
|
|
@@ -1481,7 +1483,7 @@ async function spawnSubworkflows(ctx, mutation, task, sub, actor) {
|
|
|
1481
1483
|
`Subworkflow depth limit (${MAX_SPAWN_DEPTH}) exceeded on task "${task.name}" of ${ctx.instance._id}. Ancestor chain: ${chain}`
|
|
1482
1484
|
);
|
|
1483
1485
|
}
|
|
1484
|
-
const now = ctx.now, definition = await resolveDefinitionRef(ctx.client, sub.definition, ctx.instance.
|
|
1486
|
+
const now = ctx.now, definition = await resolveDefinitionRef(ctx.client, sub.definition, ctx.instance.tag);
|
|
1485
1487
|
if (definition === null) {
|
|
1486
1488
|
const versionLabel = sub.definition.version === void 0 || sub.definition.version === "latest" ? "latest" : `v${sub.definition.version}`;
|
|
1487
1489
|
throw new Error(
|
|
@@ -1571,15 +1573,15 @@ function coerceSpawnGdr(raw, workflowResource) {
|
|
|
1571
1573
|
}
|
|
1572
1574
|
return typeof raw == "string" && raw.length > 0 ? { id: toUri(raw), type: "document" } : null;
|
|
1573
1575
|
}
|
|
1574
|
-
async function resolveDefinitionRef(client, ref,
|
|
1575
|
-
const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name,
|
|
1576
|
+
async function resolveDefinitionRef(client, ref, tag) {
|
|
1577
|
+
const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name, tag };
|
|
1576
1578
|
return wantsExplicit && (params.version = ref.version), await client.fetch(
|
|
1577
1579
|
definitionLookupGroq(wantsExplicit),
|
|
1578
1580
|
params
|
|
1579
1581
|
) ?? null;
|
|
1580
1582
|
}
|
|
1581
1583
|
async function prepareChildInstance(args) {
|
|
1582
|
-
const { client, parent, definition, initialState, effectsContext, actor, now } = args,
|
|
1584
|
+
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 = [
|
|
1583
1585
|
...parent.ancestors,
|
|
1584
1586
|
{
|
|
1585
1587
|
id: selfGdr(parent),
|
|
@@ -1592,7 +1594,7 @@ async function prepareChildInstance(args) {
|
|
|
1592
1594
|
client,
|
|
1593
1595
|
now,
|
|
1594
1596
|
selfId: childDocId,
|
|
1595
|
-
|
|
1597
|
+
tag: childTag,
|
|
1596
1598
|
workflowResource,
|
|
1597
1599
|
...inheritedPerspective !== void 0 ? { perspective: inheritedPerspective } : {}
|
|
1598
1600
|
},
|
|
@@ -1611,7 +1613,7 @@ async function prepareChildInstance(args) {
|
|
|
1611
1613
|
), base = buildInstanceBase({
|
|
1612
1614
|
id: childDocId,
|
|
1613
1615
|
now,
|
|
1614
|
-
|
|
1616
|
+
tag: childTag,
|
|
1615
1617
|
workflowResource,
|
|
1616
1618
|
definitionName: definition.name,
|
|
1617
1619
|
pinnedVersion: definition.version,
|
|
@@ -2477,17 +2479,12 @@ async function fetchGrantsCached(requestFn, resourcePath) {
|
|
|
2477
2479
|
}
|
|
2478
2480
|
}
|
|
2479
2481
|
async function evaluateInstance(args) {
|
|
2480
|
-
const { client,
|
|
2481
|
-
|
|
2482
|
+
const { client, tag, instanceId, resourceClients } = args, now = (args.clock ?? wallClock)();
|
|
2483
|
+
validateTag(tag);
|
|
2482
2484
|
const { actor, grants } = await resolveAccess(client, {
|
|
2483
2485
|
...args.access !== void 0 ? { override: args.access } : {},
|
|
2484
2486
|
...args.grantsFromPath !== void 0 ? { grantsFromPath: args.grantsFromPath } : {}
|
|
2485
|
-
}), instance = await client
|
|
2486
|
-
if (!instance)
|
|
2487
|
-
throw new Error(`Workflow instance "${instanceId}" not found`);
|
|
2488
|
-
if (!tags.some((t) => instance.tags?.includes(t)))
|
|
2489
|
-
throw new Error(`Workflow instance "${instanceId}" not visible to this engine (tag mismatch)`);
|
|
2490
|
-
const definition = parseDefinitionSnapshot(instance), snapshot = await hydrateSnapshot({ client, clientForGdr: resourceClients !== void 0 ? (parsed) => resourceClients(parsed) ?? client : () => client, instance }), guards = await verdictGuardsForInstance(client, instance._id);
|
|
2487
|
+
}), 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);
|
|
2491
2488
|
return evaluateFromSnapshot({
|
|
2492
2489
|
instance,
|
|
2493
2490
|
definition,
|
|
@@ -2628,22 +2625,21 @@ function lifecycleReason(instance, status, stageHasExits) {
|
|
|
2628
2625
|
function disabled(action, reason) {
|
|
2629
2626
|
return { action, allowed: !1, disabledReason: reason };
|
|
2630
2627
|
}
|
|
2631
|
-
function definitionDocId(_workflowResource,
|
|
2632
|
-
return `${
|
|
2628
|
+
function definitionDocId(_workflowResource, tag, definition, version) {
|
|
2629
|
+
return `${tag}.${definition}.v${version}`;
|
|
2633
2630
|
}
|
|
2634
|
-
async function sortByDependencies(client, definitions,
|
|
2635
|
-
const
|
|
2631
|
+
async function sortByDependencies(client, definitions, tag, workflowResource) {
|
|
2632
|
+
const byName = /* @__PURE__ */ new Map();
|
|
2636
2633
|
for (const def of definitions) {
|
|
2637
2634
|
const list = byName.get(def.name) ?? [];
|
|
2638
2635
|
list.push(def), byName.set(def.name, list);
|
|
2639
2636
|
}
|
|
2640
2637
|
const findInBatch = (ref) => findRefInBatch(byName, ref);
|
|
2641
2638
|
return await assertCrossBatchRefsDeployed(client, definitions, {
|
|
2642
|
-
|
|
2639
|
+
tag,
|
|
2643
2640
|
workflowResource,
|
|
2644
|
-
prefix,
|
|
2645
2641
|
findInBatch
|
|
2646
|
-
}), topoSortDefinitions(definitions, { workflowResource,
|
|
2642
|
+
}), topoSortDefinitions(definitions, { workflowResource, tag, findInBatch });
|
|
2647
2643
|
}
|
|
2648
2644
|
function findRefInBatch(byName, ref) {
|
|
2649
2645
|
const candidates = byName.get(ref.name);
|
|
@@ -2656,10 +2652,10 @@ function findRefInBatch(byName, ref) {
|
|
|
2656
2652
|
async function assertCrossBatchRefsDeployed(client, definitions, ctx) {
|
|
2657
2653
|
const missing = [];
|
|
2658
2654
|
for (const def of definitions) {
|
|
2659
|
-
const fromId = definitionDocId(ctx.workflowResource, ctx.
|
|
2655
|
+
const fromId = definitionDocId(ctx.workflowResource, ctx.tag, def.name, def.version);
|
|
2660
2656
|
for (const ref of refsOf(def)) {
|
|
2661
2657
|
if (ctx.findInBatch(ref) !== void 0) continue;
|
|
2662
|
-
const label = await resolveDeployedRefLabel(client, ref, ctx.
|
|
2658
|
+
const label = await resolveDeployedRefLabel(client, ref, ctx.tag);
|
|
2663
2659
|
label !== void 0 && missing.push({ from: fromId, ref: label });
|
|
2664
2660
|
}
|
|
2665
2661
|
}
|
|
@@ -2671,8 +2667,8 @@ async function assertCrossBatchRefsDeployed(client, definitions, ctx) {
|
|
|
2671
2667
|
`)
|
|
2672
2668
|
);
|
|
2673
2669
|
}
|
|
2674
|
-
async function resolveDeployedRefLabel(client, ref,
|
|
2675
|
-
const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name,
|
|
2670
|
+
async function resolveDeployedRefLabel(client, ref, tag) {
|
|
2671
|
+
const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name, tag };
|
|
2676
2672
|
if (wantsExplicit && (params.version = ref.version), !await client.fetch(
|
|
2677
2673
|
definitionLookupGroq(wantsExplicit),
|
|
2678
2674
|
params
|
|
@@ -2681,7 +2677,7 @@ async function resolveDeployedRefLabel(client, ref, tags) {
|
|
|
2681
2677
|
}
|
|
2682
2678
|
function topoSortDefinitions(definitions, ctx) {
|
|
2683
2679
|
const visited = /* @__PURE__ */ new Set(), visiting = /* @__PURE__ */ new Set(), ordered = [], visit = (def) => {
|
|
2684
|
-
const id = definitionDocId(ctx.workflowResource, ctx.
|
|
2680
|
+
const id = definitionDocId(ctx.workflowResource, ctx.tag, def.name, def.version);
|
|
2685
2681
|
if (!visited.has(id)) {
|
|
2686
2682
|
if (visiting.has(id))
|
|
2687
2683
|
throw new Error(`workflow.deployDefinitions: dependency cycle involving "${id}"`);
|
|
@@ -2722,11 +2718,11 @@ function stableStringify(value) {
|
|
|
2722
2718
|
([a], [b]) => a.localeCompare(b)
|
|
2723
2719
|
).map(([k, v2]) => `${JSON.stringify(k)}:${stableStringify(v2)}`).join(",")}}`;
|
|
2724
2720
|
}
|
|
2725
|
-
async function loadDefinition(client, definition, version,
|
|
2721
|
+
async function loadDefinition(client, definition, version, tag) {
|
|
2726
2722
|
if (version !== void 0) {
|
|
2727
2723
|
const doc = await client.fetch(
|
|
2728
2724
|
definitionLookupGroq(!0),
|
|
2729
|
-
{ definition, version,
|
|
2725
|
+
{ definition, version, tag }
|
|
2730
2726
|
);
|
|
2731
2727
|
if (!doc)
|
|
2732
2728
|
throw new Error(`Workflow definition ${definition} v${version} not deployed`);
|
|
@@ -2734,16 +2730,16 @@ async function loadDefinition(client, definition, version, tags) {
|
|
|
2734
2730
|
}
|
|
2735
2731
|
const latest = await client.fetch(definitionLookupGroq(!1), {
|
|
2736
2732
|
definition,
|
|
2737
|
-
|
|
2733
|
+
tag
|
|
2738
2734
|
});
|
|
2739
2735
|
if (!latest)
|
|
2740
2736
|
throw new Error(`No deployed definition for workflow ${definition}`);
|
|
2741
2737
|
return latest;
|
|
2742
2738
|
}
|
|
2743
|
-
async function loadDefinitionVersions(client, definition,
|
|
2739
|
+
async function loadDefinitionVersions(client, definition, tag) {
|
|
2744
2740
|
return client.fetch(
|
|
2745
|
-
`*[_type == "${WORKFLOW_DEFINITION_TYPE}" && name == $definition &&
|
|
2746
|
-
{ definition,
|
|
2741
|
+
`*[_type == "${WORKFLOW_DEFINITION_TYPE}" && name == $definition && ${tagScopeFilter()}] | order(version desc)`,
|
|
2742
|
+
{ definition, tag }
|
|
2747
2743
|
);
|
|
2748
2744
|
}
|
|
2749
2745
|
async function abortInstance(args) {
|
|
@@ -2894,7 +2890,7 @@ function bareIdFromSpawnRef(uri) {
|
|
|
2894
2890
|
}
|
|
2895
2891
|
}
|
|
2896
2892
|
async function resolveOperationContext(args) {
|
|
2897
|
-
|
|
2893
|
+
validateTag(args.tag);
|
|
2898
2894
|
const access = await resolveAccess(args.client, {
|
|
2899
2895
|
...args.access !== void 0 ? { override: args.access } : {},
|
|
2900
2896
|
...args.grantsFromPath !== void 0 ? { grantsFromPath: args.grantsFromPath } : {}
|
|
@@ -2928,16 +2924,6 @@ async function abortAndPropagate(args) {
|
|
|
2928
2924
|
function buildClientForGdr(defaultClient, resolver) {
|
|
2929
2925
|
return resolver === void 0 ? () => defaultClient : (parsed) => resolver(parsed) ?? defaultClient;
|
|
2930
2926
|
}
|
|
2931
|
-
async function reload(client, instanceId, tags) {
|
|
2932
|
-
const doc = await client.getDocument(instanceId);
|
|
2933
|
-
if (!doc) throw new Error(`Workflow instance ${instanceId} not found`);
|
|
2934
|
-
if (!intersectsTags(doc.tags, tags))
|
|
2935
|
-
throw new Error(`Workflow instance ${instanceId} not visible to this engine (tag mismatch)`);
|
|
2936
|
-
return doc;
|
|
2937
|
-
}
|
|
2938
|
-
function intersectsTags(docTags, engineTags) {
|
|
2939
|
-
return !docTags || docTags.length === 0 ? !1 : engineTags.some((t) => docTags.includes(t));
|
|
2940
|
-
}
|
|
2941
2927
|
function toEffectsContextEntries(ctx) {
|
|
2942
2928
|
return Object.entries(ctx).map(([id, value]) => effectsContextEntry(id, value));
|
|
2943
2929
|
}
|
|
@@ -2963,15 +2949,15 @@ async function applyAction(args) {
|
|
|
2963
2949
|
})).ranOps;
|
|
2964
2950
|
}
|
|
2965
2951
|
async function deleteDefinition(args) {
|
|
2966
|
-
const { client,
|
|
2952
|
+
const { client, tag, definition, version, cascade: cascade2, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, versions = await loadDefinitionVersions(client, definition, tag);
|
|
2967
2953
|
if (versions.length === 0)
|
|
2968
2954
|
throw new Error(`No deployed definition for workflow ${definition}`);
|
|
2969
2955
|
const targets = version === void 0 ? versions : versions.filter((d) => d.version === version);
|
|
2970
2956
|
if (targets.length === 0)
|
|
2971
2957
|
throw new Error(`Workflow definition ${definition} v${version} not deployed`);
|
|
2972
2958
|
const lastVersionGoes = targets.length === versions.length;
|
|
2973
|
-
await assertNoSpawnReferrers(client,
|
|
2974
|
-
const instanceIds = await nonTerminalInstanceIds(client,
|
|
2959
|
+
await assertNoSpawnReferrers(client, tag, definition, targets, lastVersionGoes);
|
|
2960
|
+
const instanceIds = await nonTerminalInstanceIds(client, tag, definition, version);
|
|
2975
2961
|
if (instanceIds.length > 0 && cascade2 !== !0)
|
|
2976
2962
|
throw new Error(
|
|
2977
2963
|
`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.`
|
|
@@ -2992,7 +2978,7 @@ async function deleteDefinition(args) {
|
|
|
2992
2978
|
workflowResource: args.workflowResource,
|
|
2993
2979
|
definition,
|
|
2994
2980
|
definitions: versions,
|
|
2995
|
-
|
|
2981
|
+
tag
|
|
2996
2982
|
}) : 0;
|
|
2997
2983
|
return {
|
|
2998
2984
|
name: definition,
|
|
@@ -3001,10 +2987,10 @@ async function deleteDefinition(args) {
|
|
|
3001
2987
|
deletedGuardCount
|
|
3002
2988
|
};
|
|
3003
2989
|
}
|
|
3004
|
-
async function assertNoSpawnReferrers(client,
|
|
2990
|
+
async function assertNoSpawnReferrers(client, tag, definition, targets, lastVersionGoes) {
|
|
3005
2991
|
const deployed = await client.fetch(
|
|
3006
2992
|
`*[_type == "${WORKFLOW_DEFINITION_TYPE}" && ${tagScopeFilter()}]`,
|
|
3007
|
-
{
|
|
2993
|
+
{ tag }
|
|
3008
2994
|
), 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(
|
|
3009
2995
|
(d) => refsOf(d).some(
|
|
3010
2996
|
(ref) => ref.name === definition && (typeof ref.version == "number" ? targetVersions.has(ref.version) : lastVersionGoes)
|
|
@@ -3017,11 +3003,11 @@ async function assertNoSpawnReferrers(client, tags, definition, targets, lastVer
|
|
|
3017
3003
|
);
|
|
3018
3004
|
}
|
|
3019
3005
|
}
|
|
3020
|
-
async function nonTerminalInstanceIds(client,
|
|
3006
|
+
async function nonTerminalInstanceIds(client, tag, definition, version) {
|
|
3021
3007
|
const versionFilter = version === void 0 ? "" : " && pinnedVersion == $version";
|
|
3022
3008
|
return (await client.fetch(
|
|
3023
3009
|
`*[_type == "${WORKFLOW_INSTANCE_TYPE}" && definition == $definition && ${tagScopeFilter()} && !defined(completedAt)${versionFilter}] | order(_id asc){_id}`,
|
|
3024
|
-
{ definition,
|
|
3010
|
+
{ definition, tag, ...version !== void 0 ? { version } : {} }
|
|
3025
3011
|
)).map((doc) => doc._id);
|
|
3026
3012
|
}
|
|
3027
3013
|
async function abortInstances(args) {
|
|
@@ -3052,20 +3038,20 @@ const workflow = {
|
|
|
3052
3038
|
* Cycles in the dependency graph error before any write happens.
|
|
3053
3039
|
*/
|
|
3054
3040
|
deployDefinitions: async (args) => {
|
|
3055
|
-
const { client,
|
|
3056
|
-
|
|
3041
|
+
const { client, tag, workflowResource, definitions } = args;
|
|
3042
|
+
validateTag(tag);
|
|
3057
3043
|
for (const def of definitions)
|
|
3058
3044
|
validateDefinition(def);
|
|
3059
|
-
const ordered = await sortByDependencies(client, definitions,
|
|
3045
|
+
const ordered = await sortByDependencies(client, definitions, tag, workflowResource), results = [], tx = client.transaction();
|
|
3060
3046
|
let hasWrites = !1;
|
|
3061
3047
|
for (const def of ordered) {
|
|
3062
|
-
const id = definitionDocId(workflowResource,
|
|
3048
|
+
const id = definitionDocId(workflowResource, tag, def.name, def.version), expected = {
|
|
3063
3049
|
...def,
|
|
3064
3050
|
_id: id,
|
|
3065
3051
|
_type: WORKFLOW_DEFINITION_TYPE,
|
|
3066
|
-
|
|
3052
|
+
tag
|
|
3067
3053
|
}, existing = await client.getDocument(id);
|
|
3068
|
-
if (existing &&
|
|
3054
|
+
if (existing && existing.tag === tag && isDefinitionUnchanged(existing, expected)) {
|
|
3069
3055
|
results.push({ definition: def.name, version: def.version, status: "unchanged" });
|
|
3070
3056
|
continue;
|
|
3071
3057
|
}
|
|
@@ -3103,7 +3089,7 @@ const workflow = {
|
|
|
3103
3089
|
startInstance: async (args) => {
|
|
3104
3090
|
const {
|
|
3105
3091
|
client,
|
|
3106
|
-
|
|
3092
|
+
tag,
|
|
3107
3093
|
workflowResource,
|
|
3108
3094
|
definition: definitionName,
|
|
3109
3095
|
version,
|
|
@@ -3112,7 +3098,7 @@ const workflow = {
|
|
|
3112
3098
|
effectsContext,
|
|
3113
3099
|
instanceId,
|
|
3114
3100
|
perspective
|
|
3115
|
-
} = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, definition = await loadDefinition(client, definitionName, version,
|
|
3101
|
+
} = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, definition = await loadDefinition(client, definitionName, version, tag), id = instanceId ?? `${tag}.wf-instance.${randomKey()}`;
|
|
3116
3102
|
if (definition.stages.find((s) => s.name === definition.initialStage) === void 0)
|
|
3117
3103
|
throw new Error(
|
|
3118
3104
|
`Initial stage "${definition.initialStage}" missing in ${definitionName} v${definition.version}`
|
|
@@ -3124,7 +3110,7 @@ const workflow = {
|
|
|
3124
3110
|
client,
|
|
3125
3111
|
now,
|
|
3126
3112
|
selfId: id,
|
|
3127
|
-
|
|
3113
|
+
tag,
|
|
3128
3114
|
workflowResource,
|
|
3129
3115
|
...perspective !== void 0 ? { perspective } : {}
|
|
3130
3116
|
},
|
|
@@ -3132,7 +3118,7 @@ const workflow = {
|
|
|
3132
3118
|
}), effectivePerspective = perspective ?? derivePerspectiveFromState(resolvedState), base = buildInstanceBase({
|
|
3133
3119
|
id,
|
|
3134
3120
|
now,
|
|
3135
|
-
|
|
3121
|
+
tag,
|
|
3136
3122
|
workflowResource,
|
|
3137
3123
|
definitionName: definition.name,
|
|
3138
3124
|
pinnedVersion: definition.version,
|
|
@@ -3144,7 +3130,7 @@ const workflow = {
|
|
|
3144
3130
|
initialStage: definition.initialStage,
|
|
3145
3131
|
actor
|
|
3146
3132
|
});
|
|
3147
|
-
return await client.create(base), await primeInitialStage(client, id, actor, clientForGdr, clock), await cascade(client, id, actor, clientForGdr, clock), reload(client, id,
|
|
3133
|
+
return await client.create(base), await primeInitialStage(client, id, actor, clientForGdr, clock), await cascade(client, id, actor, clientForGdr, clock), reload(client, id, tag);
|
|
3148
3134
|
},
|
|
3149
3135
|
/**
|
|
3150
3136
|
* Fire an action against a task. If the task is pending, it is
|
|
@@ -3159,19 +3145,19 @@ const workflow = {
|
|
|
3159
3145
|
fireAction: async (args) => {
|
|
3160
3146
|
const {
|
|
3161
3147
|
client,
|
|
3162
|
-
|
|
3148
|
+
tag,
|
|
3163
3149
|
instanceId,
|
|
3164
3150
|
task,
|
|
3165
3151
|
action,
|
|
3166
3152
|
params,
|
|
3167
3153
|
idempotent,
|
|
3168
3154
|
resourceClients
|
|
3169
|
-
} = args, { access, actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, before = await reload(client, instanceId,
|
|
3155
|
+
} = args, { access, actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, before = await reload(client, instanceId, tag);
|
|
3170
3156
|
if (findOpenStageEntry(before)?.tasks.find((t) => t.name === task) === void 0 && idempotent === !0)
|
|
3171
3157
|
return { instance: before, cascaded: 0, fired: !1 };
|
|
3172
3158
|
const evaluation = await evaluateInstance({
|
|
3173
3159
|
client,
|
|
3174
|
-
|
|
3160
|
+
tag,
|
|
3175
3161
|
instanceId,
|
|
3176
3162
|
access,
|
|
3177
3163
|
clock,
|
|
@@ -3190,7 +3176,7 @@ const workflow = {
|
|
|
3190
3176
|
...params !== void 0 ? { params } : {}
|
|
3191
3177
|
}), cascaded = await cascade(client, instanceId, actor, clientForGdr, clock);
|
|
3192
3178
|
return {
|
|
3193
|
-
instance: await reload(client, instanceId,
|
|
3179
|
+
instance: await reload(client, instanceId, tag),
|
|
3194
3180
|
cascaded,
|
|
3195
3181
|
fired: !0,
|
|
3196
3182
|
...ranOps !== void 0 ? { ranOps } : {}
|
|
@@ -3204,7 +3190,7 @@ const workflow = {
|
|
|
3204
3190
|
* reference them. Cascades after.
|
|
3205
3191
|
*/
|
|
3206
3192
|
completeEffect: async (args) => {
|
|
3207
|
-
const { client,
|
|
3193
|
+
const { client, tag, instanceId, effectKey, status, outputs, detail, error, durationMs } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
|
|
3208
3194
|
await completeEffect({
|
|
3209
3195
|
client,
|
|
3210
3196
|
instanceId,
|
|
@@ -3218,7 +3204,7 @@ const workflow = {
|
|
|
3218
3204
|
});
|
|
3219
3205
|
const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock);
|
|
3220
3206
|
return {
|
|
3221
|
-
instance: await reload(client, instanceId,
|
|
3207
|
+
instance: await reload(client, instanceId, tag),
|
|
3222
3208
|
cascaded,
|
|
3223
3209
|
fired: !0
|
|
3224
3210
|
};
|
|
@@ -3233,11 +3219,11 @@ const workflow = {
|
|
|
3233
3219
|
* affected instances and the engine re-evaluates.
|
|
3234
3220
|
*/
|
|
3235
3221
|
tick: async (args) => {
|
|
3236
|
-
const { client,
|
|
3222
|
+
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);
|
|
3237
3223
|
await assertInstanceWriteAllowed({ instance: current, guards, identity: actor.id });
|
|
3238
3224
|
const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock);
|
|
3239
3225
|
return {
|
|
3240
|
-
instance: await reload(client, instanceId,
|
|
3226
|
+
instance: await reload(client, instanceId, tag),
|
|
3241
3227
|
cascaded,
|
|
3242
3228
|
fired: cascaded > 0
|
|
3243
3229
|
};
|
|
@@ -3248,8 +3234,8 @@ const workflow = {
|
|
|
3248
3234
|
* upstream; this verb performs the mechanical move.
|
|
3249
3235
|
*/
|
|
3250
3236
|
setStage: async (args) => {
|
|
3251
|
-
const { client,
|
|
3252
|
-
await reload(client, instanceId,
|
|
3237
|
+
const { client, tag, instanceId, targetStage, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
|
|
3238
|
+
await reload(client, instanceId, tag);
|
|
3253
3239
|
const result = await setStage({
|
|
3254
3240
|
client,
|
|
3255
3241
|
instanceId,
|
|
@@ -3258,7 +3244,7 @@ const workflow = {
|
|
|
3258
3244
|
options: { ...actor !== void 0 ? { actor } : {}, clock, clientForGdr }
|
|
3259
3245
|
}), cascaded = result.fired ? await cascade(client, instanceId, actor, clientForGdr, clock) : 0;
|
|
3260
3246
|
return {
|
|
3261
|
-
instance: await reload(client, instanceId,
|
|
3247
|
+
instance: await reload(client, instanceId, tag),
|
|
3262
3248
|
cascaded,
|
|
3263
3249
|
fired: result.fired
|
|
3264
3250
|
};
|
|
@@ -3270,28 +3256,28 @@ const workflow = {
|
|
|
3270
3256
|
* contract (propagated, not cascaded — the instance is terminal).
|
|
3271
3257
|
*/
|
|
3272
3258
|
abortInstance: async (args) => {
|
|
3273
|
-
const { client,
|
|
3274
|
-
await reload(client, instanceId,
|
|
3259
|
+
const { client, tag, instanceId, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
|
|
3260
|
+
await reload(client, instanceId, tag);
|
|
3275
3261
|
const fired = await abortAndPropagate({ client, instanceId, reason, actor, clientForGdr, clock });
|
|
3276
3262
|
return {
|
|
3277
|
-
instance: await reload(client, instanceId,
|
|
3263
|
+
instance: await reload(client, instanceId, tag),
|
|
3278
3264
|
cascaded: 0,
|
|
3279
3265
|
fired
|
|
3280
3266
|
};
|
|
3281
3267
|
},
|
|
3282
3268
|
/**
|
|
3283
|
-
* Fetch a workflow instance by id, scoped to the engine's
|
|
3269
|
+
* Fetch a workflow instance by id, scoped to the engine's tag.
|
|
3284
3270
|
* Throws when the instance doesn't exist or isn't visible to this
|
|
3285
3271
|
* engine.
|
|
3286
3272
|
*/
|
|
3287
3273
|
getInstance: async (args) => {
|
|
3288
|
-
const { client,
|
|
3289
|
-
return
|
|
3274
|
+
const { client, tag, instanceId } = args;
|
|
3275
|
+
return validateTag(tag), reload(client, instanceId, tag);
|
|
3290
3276
|
},
|
|
3291
3277
|
guardsForInstance: async (args) => {
|
|
3292
|
-
const { client,
|
|
3293
|
-
|
|
3294
|
-
const instance = await reload(client, instanceId,
|
|
3278
|
+
const { client, tag, instanceId, resourceClients } = args;
|
|
3279
|
+
validateTag(tag);
|
|
3280
|
+
const instance = await reload(client, instanceId, tag);
|
|
3295
3281
|
return guardsForInstance({
|
|
3296
3282
|
client,
|
|
3297
3283
|
clientForGdr: buildClientForGdr(client, resourceClients),
|
|
@@ -3299,9 +3285,9 @@ const workflow = {
|
|
|
3299
3285
|
});
|
|
3300
3286
|
},
|
|
3301
3287
|
guardsForDefinition: async (args) => {
|
|
3302
|
-
const { client,
|
|
3303
|
-
|
|
3304
|
-
const definitions = await loadDefinitionVersions(client, definition,
|
|
3288
|
+
const { client, tag, workflowResource, definition, resourceClients } = args;
|
|
3289
|
+
validateTag(tag);
|
|
3290
|
+
const definitions = await loadDefinitionVersions(client, definition, tag);
|
|
3305
3291
|
if (definitions.length === 0)
|
|
3306
3292
|
throw new Error(`No deployed definition for workflow ${definition}`);
|
|
3307
3293
|
return guardsForDefinition({
|
|
@@ -3313,22 +3299,21 @@ const workflow = {
|
|
|
3313
3299
|
});
|
|
3314
3300
|
},
|
|
3315
3301
|
/**
|
|
3316
|
-
* Run a caller-supplied GROQ query with the engine's
|
|
3317
|
-
* `$
|
|
3302
|
+
* Run a caller-supplied GROQ query with the engine's tag bound as
|
|
3303
|
+
* `$tag`. This does NOT rewrite the query — arbitrary GROQ
|
|
3318
3304
|
* can't be safely tag-scoped after the fact — so the CALLER MUST
|
|
3319
|
-
* filter on `$
|
|
3320
|
-
*
|
|
3321
|
-
* cross-tenant reads, a query that never references `$engineTags` is
|
|
3305
|
+
* filter on `$tag` (e.g. `tag == $tag`). To guard against accidental
|
|
3306
|
+
* cross-partition reads, a query that never references `$tag` is
|
|
3322
3307
|
* rejected before it reaches the lake. Caller is responsible for type
|
|
3323
3308
|
* narrowing the result.
|
|
3324
3309
|
*/
|
|
3325
3310
|
query: async (args) => {
|
|
3326
|
-
const { client,
|
|
3327
|
-
if (
|
|
3311
|
+
const { client, tag, groq, params } = args;
|
|
3312
|
+
if (validateTag(tag), !/\$tag\b/.test(groq))
|
|
3328
3313
|
throw new Error(
|
|
3329
|
-
`workflow.query: query must filter on $
|
|
3314
|
+
`workflow.query: query must filter on $tag to stay tag-scoped (e.g. "tag == $tag"); got: ${groq}`
|
|
3330
3315
|
);
|
|
3331
|
-
return client.fetch(groq, { ...params,
|
|
3316
|
+
return client.fetch(groq, { ...params, tag });
|
|
3332
3317
|
},
|
|
3333
3318
|
/**
|
|
3334
3319
|
* Snapshot-aware GROQ — runs against the same in-memory view that
|
|
@@ -3347,9 +3332,9 @@ const workflow = {
|
|
|
3347
3332
|
* without re-implementing hydration. Pure read — never writes.
|
|
3348
3333
|
*/
|
|
3349
3334
|
queryInScope: async (args) => {
|
|
3350
|
-
const { client,
|
|
3351
|
-
|
|
3352
|
-
const instance = await reload(client, instanceId,
|
|
3335
|
+
const { client, tag, instanceId, groq, params, resourceClients } = args, clock = args.clock ?? wallClock;
|
|
3336
|
+
validateTag(tag);
|
|
3337
|
+
const instance = await reload(client, instanceId, tag), clientForGdr = buildClientForGdr(client, resourceClients), snapshot = await hydrateSnapshot({ client, clientForGdr, instance }), reserved = buildParams({ instance, now: clock(), snapshot }), tree = parse(groq, { params: { ...reserved, ...params } });
|
|
3353
3338
|
return await (await evaluate(tree, {
|
|
3354
3339
|
dataset: snapshot.docs,
|
|
3355
3340
|
params: { ...reserved, ...params }
|
|
@@ -3359,13 +3344,13 @@ const workflow = {
|
|
|
3359
3344
|
* List every pending effect on the instance. Returns the same entries
|
|
3360
3345
|
* the runtime would see — claimed and unclaimed alike.
|
|
3361
3346
|
*/
|
|
3362
|
-
listPendingEffects: async (args) => (await reload(args.client, args.instanceId, args.
|
|
3347
|
+
listPendingEffects: async (args) => (await reload(args.client, args.instanceId, args.tag)).pendingEffects,
|
|
3363
3348
|
/**
|
|
3364
3349
|
* Filter pending effects on the instance by criteria. `claimed`
|
|
3365
3350
|
* filters on claim presence; `names` restricts to specific effect
|
|
3366
3351
|
* names. Both filters compose (AND).
|
|
3367
3352
|
*/
|
|
3368
|
-
findPendingEffects: async (args) => (await reload(args.client, args.instanceId, args.
|
|
3353
|
+
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))),
|
|
3369
3354
|
/**
|
|
3370
3355
|
* Project the instance from a given actor's perspective. Returns a
|
|
3371
3356
|
* `WorkflowEvaluation` with per-action verdicts (`allowed` + a
|
|
@@ -3406,18 +3391,18 @@ const workflow = {
|
|
|
3406
3391
|
* record. (The per-task `spawnedInstances` field on the active stage
|
|
3407
3392
|
* only exists while that stage is current; history survives.) Strips
|
|
3408
3393
|
* the GDR URI on each `instanceRef` to a bare `_id`, fetches the
|
|
3409
|
-
* instances, drops any that aren't visible to this engine's
|
|
3394
|
+
* instances, drops any that aren't visible to this engine's tag, and
|
|
3410
3395
|
* returns them sorted by `startedAt` ascending.
|
|
3411
3396
|
*
|
|
3412
3397
|
* Pass `task` to restrict to a single spawning task on the parent.
|
|
3413
3398
|
*/
|
|
3414
3399
|
children: async (args) => {
|
|
3415
|
-
const { client,
|
|
3416
|
-
|
|
3417
|
-
const parent = await reload(client, instanceId,
|
|
3400
|
+
const { client, tag, instanceId, task } = args;
|
|
3401
|
+
validateTag(tag);
|
|
3402
|
+
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));
|
|
3418
3403
|
return ids.length === 0 ? [] : client.fetch(
|
|
3419
3404
|
`*[_id in $ids && ${tagScopeFilter()}] | order(startedAt asc)`,
|
|
3420
|
-
{ ids,
|
|
3405
|
+
{ ids, tag }
|
|
3421
3406
|
);
|
|
3422
3407
|
},
|
|
3423
3408
|
/**
|
|
@@ -3432,11 +3417,11 @@ const workflow = {
|
|
|
3432
3417
|
}
|
|
3433
3418
|
};
|
|
3434
3419
|
async function verifyDeployedDefinitionsInternal(args) {
|
|
3435
|
-
const { client,
|
|
3436
|
-
|
|
3420
|
+
const { client, tag, effectHandlers, missingHandler, logger } = args;
|
|
3421
|
+
validateTag(tag);
|
|
3437
3422
|
const log = logger("verifyDeployedDefinitions"), definitions = await client.fetch(
|
|
3438
3423
|
`*[_type == "${WORKFLOW_DEFINITION_TYPE}" && ${tagScopeFilter()}] | order(name asc, version asc)`,
|
|
3439
|
-
{
|
|
3424
|
+
{ tag }
|
|
3440
3425
|
), seen = [], missingByName = /* @__PURE__ */ new Map();
|
|
3441
3426
|
for (const def of definitions)
|
|
3442
3427
|
seen.push({ name: def.name, version: def.version, _id: def._id }), walkEffectNames(def, (name, location) => {
|
|
@@ -3485,7 +3470,7 @@ function walkEffectNames(def, visit) {
|
|
|
3485
3470
|
async function drainEffectsInternal(args) {
|
|
3486
3471
|
const {
|
|
3487
3472
|
client,
|
|
3488
|
-
|
|
3473
|
+
tag,
|
|
3489
3474
|
workflowResource,
|
|
3490
3475
|
resourceClients,
|
|
3491
3476
|
instanceId,
|
|
@@ -3496,10 +3481,10 @@ async function drainEffectsInternal(args) {
|
|
|
3496
3481
|
actor: drainerActor,
|
|
3497
3482
|
...args.access?.grants !== void 0 ? { grants: args.access.grants } : {}
|
|
3498
3483
|
};
|
|
3499
|
-
|
|
3484
|
+
validateTag(tag);
|
|
3500
3485
|
const log = logger("drainEffects"), drained = [], failed = [], skipped = [], skippedKeys = /* @__PURE__ */ new Set();
|
|
3501
3486
|
for (; ; ) {
|
|
3502
|
-
const before = await reload(client, instanceId,
|
|
3487
|
+
const before = await reload(client, instanceId, tag), candidate = before.pendingEffects.find(
|
|
3503
3488
|
(e) => e.claim === void 0 && !skippedKeys.has(e._key)
|
|
3504
3489
|
);
|
|
3505
3490
|
if (candidate === void 0) break;
|
|
@@ -3516,7 +3501,7 @@ async function drainEffectsInternal(args) {
|
|
|
3516
3501
|
});
|
|
3517
3502
|
await reportEffectOutcome({
|
|
3518
3503
|
client,
|
|
3519
|
-
|
|
3504
|
+
tag,
|
|
3520
3505
|
workflowResource,
|
|
3521
3506
|
...resourceClients !== void 0 ? { resourceClients } : {},
|
|
3522
3507
|
instanceId,
|
|
@@ -3586,7 +3571,7 @@ async function applyMissingHandler(policy, info, log) {
|
|
|
3586
3571
|
}
|
|
3587
3572
|
}
|
|
3588
3573
|
function createInstanceSession(args) {
|
|
3589
|
-
const { client,
|
|
3574
|
+
const { client, tag, clock } = args, clientForGdr = buildClientForGdr(client, args.resourceClients);
|
|
3590
3575
|
let instance = asHeldInstance(args.instance), overlay = /* @__PURE__ */ new Map(), heldGuards = [], committing = !1, buffered;
|
|
3591
3576
|
const selfUri = () => gdrFromResource(instance.workflowResource, instance._id), applyUpdate = (docs) => {
|
|
3592
3577
|
const next = /* @__PURE__ */ new Map();
|
|
@@ -3647,7 +3632,7 @@ function createInstanceSession(args) {
|
|
|
3647
3632
|
return commit(async (actor, held) => {
|
|
3648
3633
|
await assertInstanceWriteAllowed({ instance, guards: heldGuards, identity: actor.id });
|
|
3649
3634
|
const cascaded = await cascade(client, instance._id, actor, clientForGdr, clock, held);
|
|
3650
|
-
return instance = await reload(client, instance._id,
|
|
3635
|
+
return instance = await reload(client, instance._id, tag), { instance, cascaded, fired: cascaded > 0 };
|
|
3651
3636
|
});
|
|
3652
3637
|
},
|
|
3653
3638
|
fireAction({ task, action, params }) {
|
|
@@ -3664,7 +3649,7 @@ function createInstanceSession(args) {
|
|
|
3664
3649
|
...clock !== void 0 ? { clock } : {},
|
|
3665
3650
|
...params !== void 0 ? { params } : {}
|
|
3666
3651
|
}), cascaded = await cascade(client, instance._id, actor, clientForGdr, clock, held);
|
|
3667
|
-
return instance = await reload(client, instance._id,
|
|
3652
|
+
return instance = await reload(client, instance._id, tag), { instance, cascaded, fired: !0, ...ranOps !== void 0 ? { ranOps } : {} };
|
|
3668
3653
|
});
|
|
3669
3654
|
}
|
|
3670
3655
|
};
|
|
@@ -3692,11 +3677,11 @@ const defaultLoggerFactory = (name) => ({
|
|
|
3692
3677
|
}
|
|
3693
3678
|
};
|
|
3694
3679
|
function createEngine(args) {
|
|
3695
|
-
const { client, workflowResource,
|
|
3696
|
-
|
|
3680
|
+
const { client, workflowResource, resourceClients, clock, tag } = args;
|
|
3681
|
+
validateTag(tag);
|
|
3697
3682
|
const effectHandlers = args.effectHandlers ?? {}, missingHandler = args.missingHandler ?? "fail", logger = args.loggerFactory ?? defaultLoggerFactory, bind = (rest) => ({
|
|
3698
3683
|
client,
|
|
3699
|
-
|
|
3684
|
+
tag,
|
|
3700
3685
|
workflowResource,
|
|
3701
3686
|
...resourceClients !== void 0 ? { resourceClients } : {},
|
|
3702
3687
|
...clock !== void 0 ? { clock } : {},
|
|
@@ -3704,7 +3689,7 @@ function createEngine(args) {
|
|
|
3704
3689
|
});
|
|
3705
3690
|
return {
|
|
3706
3691
|
client,
|
|
3707
|
-
|
|
3692
|
+
tag,
|
|
3708
3693
|
workflowResource,
|
|
3709
3694
|
effectHandlers,
|
|
3710
3695
|
missingHandler,
|
|
@@ -3720,11 +3705,11 @@ function createEngine(args) {
|
|
|
3720
3705
|
setStage: (rest) => workflow.setStage(bind(rest)),
|
|
3721
3706
|
abortInstance: (rest) => workflow.abortInstance(bind(rest)),
|
|
3722
3707
|
deleteDefinition: (rest) => workflow.deleteDefinition(bind(rest)),
|
|
3723
|
-
getInstance: ({ instanceId }) => workflow.getInstance({ client,
|
|
3724
|
-
subscriptionDocumentsForInstance: ({ instanceId }) => workflow.getInstance({ client,
|
|
3708
|
+
getInstance: ({ instanceId }) => workflow.getInstance({ client, tag, workflowResource, instanceId }),
|
|
3709
|
+
subscriptionDocumentsForInstance: ({ instanceId }) => workflow.getInstance({ client, tag, workflowResource, instanceId }).then(subscriptionDocumentsForInstance),
|
|
3725
3710
|
instance: (instanceDoc, opts) => createInstanceSession({
|
|
3726
3711
|
client,
|
|
3727
|
-
|
|
3712
|
+
tag,
|
|
3728
3713
|
instance: instanceDoc,
|
|
3729
3714
|
...resourceClients !== void 0 ? { resourceClients } : {},
|
|
3730
3715
|
...clock !== void 0 ? { clock } : {},
|
|
@@ -3733,45 +3718,45 @@ function createEngine(args) {
|
|
|
3733
3718
|
}),
|
|
3734
3719
|
guardsForInstance: ({ instanceId }) => workflow.guardsForInstance({
|
|
3735
3720
|
client,
|
|
3736
|
-
|
|
3721
|
+
tag,
|
|
3737
3722
|
workflowResource,
|
|
3738
3723
|
instanceId,
|
|
3739
3724
|
...resourceClients !== void 0 ? { resourceClients } : {}
|
|
3740
3725
|
}),
|
|
3741
3726
|
guardsForDefinition: ({ definition }) => workflow.guardsForDefinition({
|
|
3742
3727
|
client,
|
|
3743
|
-
|
|
3728
|
+
tag,
|
|
3744
3729
|
workflowResource,
|
|
3745
3730
|
definition,
|
|
3746
3731
|
...resourceClients !== void 0 ? { resourceClients } : {}
|
|
3747
3732
|
}),
|
|
3748
3733
|
children: ({ instanceId, task }) => workflow.children({
|
|
3749
3734
|
client,
|
|
3750
|
-
|
|
3735
|
+
tag,
|
|
3751
3736
|
workflowResource,
|
|
3752
3737
|
instanceId,
|
|
3753
3738
|
...task !== void 0 ? { task } : {}
|
|
3754
3739
|
}),
|
|
3755
3740
|
query: ({ groq, params }) => workflow.query({
|
|
3756
3741
|
client,
|
|
3757
|
-
|
|
3742
|
+
tag,
|
|
3758
3743
|
workflowResource,
|
|
3759
3744
|
groq,
|
|
3760
3745
|
...params !== void 0 ? { params } : {}
|
|
3761
3746
|
}),
|
|
3762
3747
|
queryInScope: ({ instanceId, groq, params }) => workflow.queryInScope({
|
|
3763
3748
|
client,
|
|
3764
|
-
|
|
3749
|
+
tag,
|
|
3765
3750
|
workflowResource,
|
|
3766
3751
|
instanceId,
|
|
3767
3752
|
groq,
|
|
3768
3753
|
...params !== void 0 ? { params } : {},
|
|
3769
3754
|
...clock !== void 0 ? { clock } : {}
|
|
3770
3755
|
}),
|
|
3771
|
-
listPendingEffects: ({ instanceId }) => workflow.listPendingEffects({ client,
|
|
3756
|
+
listPendingEffects: ({ instanceId }) => workflow.listPendingEffects({ client, tag, workflowResource, instanceId }),
|
|
3772
3757
|
findPendingEffects: ({ instanceId, claimed, names }) => workflow.findPendingEffects({
|
|
3773
3758
|
client,
|
|
3774
|
-
|
|
3759
|
+
tag,
|
|
3775
3760
|
workflowResource,
|
|
3776
3761
|
instanceId,
|
|
3777
3762
|
...claimed !== void 0 ? { claimed } : {},
|
|
@@ -3779,7 +3764,7 @@ function createEngine(args) {
|
|
|
3779
3764
|
}),
|
|
3780
3765
|
drainEffects: ({ instanceId, access }) => drainEffectsInternal({
|
|
3781
3766
|
client,
|
|
3782
|
-
|
|
3767
|
+
tag,
|
|
3783
3768
|
workflowResource,
|
|
3784
3769
|
...resourceClients !== void 0 ? { resourceClients } : {},
|
|
3785
3770
|
instanceId,
|
|
@@ -3790,7 +3775,7 @@ function createEngine(args) {
|
|
|
3790
3775
|
}),
|
|
3791
3776
|
verifyDeployedDefinitions: () => verifyDeployedDefinitionsInternal({
|
|
3792
3777
|
client,
|
|
3793
|
-
|
|
3778
|
+
tag,
|
|
3794
3779
|
effectHandlers,
|
|
3795
3780
|
missingHandler,
|
|
3796
3781
|
logger
|
|
@@ -3798,7 +3783,7 @@ function createEngine(args) {
|
|
|
3798
3783
|
};
|
|
3799
3784
|
}
|
|
3800
3785
|
function docIdFor(def, target) {
|
|
3801
|
-
return definitionDocId(target.workflowResource,
|
|
3786
|
+
return definitionDocId(target.workflowResource, target.tag, def.name, def.version);
|
|
3802
3787
|
}
|
|
3803
3788
|
function diffStatus(existing, expected) {
|
|
3804
3789
|
return existing === void 0 ? "create" : isDefinitionUnchanged(existing, expected) ? "unchanged" : "update";
|
|
@@ -3808,7 +3793,7 @@ function diffEntry(def, existingRaw, target) {
|
|
|
3808
3793
|
...def,
|
|
3809
3794
|
_id: docId,
|
|
3810
3795
|
_type: WORKFLOW_DEFINITION_TYPE,
|
|
3811
|
-
|
|
3796
|
+
tag: target.tag
|
|
3812
3797
|
}, status = diffStatus(existingRaw, expected), existing = existingRaw ? stripSystemFields(existingRaw) : void 0;
|
|
3813
3798
|
return {
|
|
3814
3799
|
name: def.name,
|
|
@@ -4025,7 +4010,6 @@ export {
|
|
|
4025
4010
|
assigneesOf,
|
|
4026
4011
|
availableActions,
|
|
4027
4012
|
buildSnapshot,
|
|
4028
|
-
canonicalTag,
|
|
4029
4013
|
compileGuard,
|
|
4030
4014
|
computeDiffEntries,
|
|
4031
4015
|
contentReleaseName,
|
|
@@ -4071,7 +4055,7 @@ export {
|
|
|
4071
4055
|
subscriptionDocumentsForInstance,
|
|
4072
4056
|
tagScopeFilter,
|
|
4073
4057
|
validateDefinition,
|
|
4074
|
-
|
|
4058
|
+
validateTag,
|
|
4075
4059
|
verdictGuardsForInstance,
|
|
4076
4060
|
wallClock,
|
|
4077
4061
|
workflow
|