@fluidgrids/workflows 2026.1029.1 → 2026.1030.1

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.
Files changed (118) hide show
  1. package/README.md +112 -4
  2. package/dist/{activation-CESehfYi.d.cts → activation-DqUfpHzk.d.cts} +1 -1
  3. package/dist/{activation-BnVQMv9y.d.ts → activation-xpx1oWuo.d.ts} +1 -1
  4. package/dist/{chunk-MJ5TGYVG.js → chunk-2D3MYIIF.js} +969 -153
  5. package/dist/{chunk-2B37XAFQ.cjs → chunk-3U2NU7YC.cjs} +24 -11
  6. package/dist/{chunk-NEIUQASE.cjs → chunk-4QKB4ARC.cjs} +3 -3
  7. package/dist/{chunk-GBQ33SIZ.cjs → chunk-54FLQNUM.cjs} +12 -1
  8. package/dist/{chunk-2DDULZFM.js → chunk-5HIVIV53.js} +86 -75
  9. package/dist/chunk-5MFVJM76.js +1222 -0
  10. package/dist/{chunk-EWYADREB.cjs → chunk-672KMMBK.cjs} +2 -2
  11. package/dist/{chunk-KXJDRQ6G.js → chunk-6A2FGSUS.js} +22 -2
  12. package/dist/{chunk-OIX4O6UR.js → chunk-6OLN6BMB.js} +16 -3
  13. package/dist/{chunk-6FSHT5IL.js → chunk-7EZIANC7.js} +1 -1
  14. package/dist/chunk-A5SXCA62.cjs +93 -0
  15. package/dist/chunk-AC6ZEXVR.js +85 -0
  16. package/dist/{chunk-FWBRQWRX.js → chunk-AE5Q6ZAJ.js} +167 -10
  17. package/dist/{chunk-7ILGCUI6.js → chunk-C4F5KJTI.js} +142 -3
  18. package/dist/{chunk-WXXNCHUY.js → chunk-G5H32GIG.js} +1 -1
  19. package/dist/{chunk-OMY3CKUZ.cjs → chunk-GEQDGUGB.cjs} +1042 -226
  20. package/dist/{chunk-25BKWR2O.js → chunk-HCM7ZC7Q.js} +1 -1
  21. package/dist/{chunk-I47EENR4.cjs → chunk-HMZUGSMU.cjs} +673 -156
  22. package/dist/{chunk-NXFBVDOI.cjs → chunk-IQPXHQQQ.cjs} +8 -4
  23. package/dist/{chunk-RUQIMTN5.cjs → chunk-ISOIA7NV.cjs} +178 -15
  24. package/dist/chunk-JSC75O5C.cjs +167 -0
  25. package/dist/{chunk-BD7ZPG53.js → chunk-NWQ5WRLE.js} +10 -2
  26. package/dist/chunk-ODZ2IAR2.cjs +1247 -0
  27. package/dist/{chunk-FQSJI5NV.js → chunk-SR7TR5KX.js} +6 -2
  28. package/dist/{chunk-OKX3FYIM.cjs → chunk-TCTE7DX5.cjs} +3 -3
  29. package/dist/{chunk-3FIDHONL.cjs → chunk-TYF56RGB.cjs} +99 -80
  30. package/dist/{chunk-J3PYFGKA.cjs → chunk-VA4OFR72.cjs} +162 -4
  31. package/dist/chunk-VU5S5A7V.js +150 -0
  32. package/dist/{chunk-A36CCOWS.js → chunk-YEHR4NNE.js} +633 -128
  33. package/dist/{chunk-ELL2RBML.cjs → chunk-ZCGKGDCL.cjs} +23 -1
  34. package/dist/codegen/index.d.cts +2 -2
  35. package/dist/codegen/index.d.ts +2 -2
  36. package/dist/{collect-BTHjQaSp.d.ts → collect-6NIEufHd.d.ts} +20 -3
  37. package/dist/{collect-CSyOg5XC.d.cts → collect-CcTCKqx6.d.cts} +20 -3
  38. package/dist/{file-cgL9l9l8.d.cts → file-BxYpwjRQ.d.cts} +250 -15
  39. package/dist/{file-olQudcx5.d.ts → file-CFdPQJI9.d.ts} +250 -15
  40. package/dist/history/index.cjs +283 -106
  41. package/dist/history/index.d.cts +549 -10
  42. package/dist/history/index.d.ts +549 -10
  43. package/dist/history/index.js +5 -4
  44. package/dist/index.cjs +146 -53
  45. package/dist/index.d.cts +38 -14
  46. package/dist/index.d.ts +38 -14
  47. package/dist/index.js +6 -5
  48. package/dist/interceptors-CNcr2dlk.d.ts +159 -0
  49. package/dist/interceptors-CqkNZVfI.d.cts +159 -0
  50. package/dist/ir/index.cjs +339 -36
  51. package/dist/ir/index.d.cts +244 -8
  52. package/dist/ir/index.d.ts +244 -8
  53. package/dist/ir/index.js +306 -21
  54. package/dist/{lower-3S6PsqjJ.d.cts → lower-BtRfIW2A.d.cts} +23 -9
  55. package/dist/{lower-DmZpQ8hJ.d.ts → lower-CpsMFOFX.d.ts} +23 -9
  56. package/dist/{manifest-BJjrQt77.d.ts → manifest-D-I_twys.d.ts} +1 -1
  57. package/dist/{manifest-gRI2Q5Fj.d.cts → manifest-DahBQVM8.d.cts} +1 -1
  58. package/dist/node-evaluator-DGQDPSPI.cjs +24 -0
  59. package/dist/node-evaluator-LEEVD7H7.js +14 -0
  60. package/dist/payload-fields-BVRQn2yH.d.cts +122 -0
  61. package/dist/payload-fields-oOBWxDiG.d.ts +122 -0
  62. package/dist/quickjs/index.cjs +27 -27
  63. package/dist/quickjs/index.d.cts +6 -6
  64. package/dist/quickjs/index.d.ts +6 -6
  65. package/dist/quickjs/index.js +9 -9
  66. package/dist/roundtrip/index.cjs +72 -66
  67. package/dist/roundtrip/index.d.cts +25 -11
  68. package/dist/roundtrip/index.d.ts +25 -11
  69. package/dist/roundtrip/index.js +13 -11
  70. package/dist/runtime/index.cjs +19 -19
  71. package/dist/runtime/index.d.cts +139 -12
  72. package/dist/runtime/index.d.ts +139 -12
  73. package/dist/runtime/index.js +6 -6
  74. package/dist/testing/index.cjs +688 -121
  75. package/dist/testing/index.d.cts +174 -10
  76. package/dist/testing/index.d.ts +174 -10
  77. package/dist/testing/index.js +646 -82
  78. package/dist/{types-CnIOinoz.d.ts → types-Bv2i4cBX.d.cts} +126 -23
  79. package/dist/{types-CQKOhPTa.d.cts → types-DGx-b9eq.d.ts} +126 -23
  80. package/dist/{types-Bb2wRnJ5.d.cts → types-V7jEEUaL.d.cts} +1 -1
  81. package/dist/{types-Bb2wRnJ5.d.ts → types-V7jEEUaL.d.ts} +1 -1
  82. package/dist/{workflow-8uRU9rhL.d.ts → workflow-B18OeF7g.d.ts} +2 -2
  83. package/dist/{workflow-DWTPHFbt.d.ts → workflow-BGnv8SS6.d.ts} +261 -14
  84. package/dist/{workflow-CZOXUlQ5.d.cts → workflow-BJPFv3cp.d.cts} +2 -2
  85. package/dist/{workflow-O6e64ZcG.d.cts → workflow-DS32Gtws.d.cts} +261 -14
  86. package/fixtures/histories/activity-options-updated.history.json +159 -0
  87. package/fixtures/histories/activity-paused-unpaused.history.json +160 -0
  88. package/fixtures/histories/codec-opaque.history.json +229 -0
  89. package/fixtures/histories/dynamic-workflow.history.json +150 -0
  90. package/fixtures/histories/interceptor-headers.history.json +339 -0
  91. package/fixtures/histories/query-custom.history.json +213 -0
  92. package/fixtures/histories/query-default-handler.history.json +120 -0
  93. package/fixtures/histories/reset-forked-reapplied-signals.history.json +239 -0
  94. package/fixtures/histories/reset-reapplied-update-admitted.history.json +228 -0
  95. package/fixtures/histories/search-attributes-upserted.history.json +177 -0
  96. package/fixtures/histories/update-accepted-completed.history.json +45 -30
  97. package/fixtures/histories/update-default-handler.history.json +246 -0
  98. package/fixtures/histories/update-handler-awaits-activity.history.json +196 -0
  99. package/fixtures/histories/update-not-handled.history.json +138 -0
  100. package/fixtures/histories/update-rejected-no-event.history.json +190 -0
  101. package/fixtures/histories/update-with-start-admitted.history.json +150 -0
  102. package/fixtures/histories/user-activity-cancel.history.json +149 -0
  103. package/fixtures/histories/user-activity-retry.history.json +143 -0
  104. package/fixtures/histories/user-activity.history.json +149 -0
  105. package/package.json +1 -1
  106. package/schema/bridge-v2.schema.json +1062 -0
  107. package/schema/history-file.schema.json +255 -81
  108. package/schema/ir-v2.schema.json +246 -1
  109. package/schema/payload-fields.json +162 -0
  110. package/schema/run-event.schema.json +239 -80
  111. package/schema/workflow-command.schema.json +210 -84
  112. package/schema/workflow-task.schema.json +532 -167
  113. package/dist/chunk-6QPOJZT6.cjs +0 -1180
  114. package/dist/chunk-A2OHX3UQ.js +0 -1156
  115. package/dist/chunk-PWIUEWC3.js +0 -81
  116. package/dist/chunk-YHBVMOMK.cjs +0 -87
  117. package/dist/node-evaluator-SOADN23V.js +0 -14
  118. package/dist/node-evaluator-YGDEXK4U.cjs +0 -24
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var chunk3FIDHONL_cjs = require('./chunk-3FIDHONL.cjs');
3
+ var chunkTYF56RGB_cjs = require('./chunk-TYF56RGB.cjs');
4
4
 
5
5
  function failedTaskResult(cause, message) {
6
6
  return {
7
- protocol: chunk3FIDHONL_cjs.HISTORY_PROTOCOL,
7
+ protocol: chunkTYF56RGB_cjs.HISTORY_PROTOCOL,
8
8
  outcome: "failed",
9
9
  commands: [],
10
10
  failure: { cause, message },
@@ -82,16 +82,36 @@ var ApplicationError = class extends WorkflowFailure {
82
82
  }
83
83
  };
84
84
  var ActivityFailure = class extends WorkflowFailure {
85
- constructor(message, activityId, nodeType, operation, cause) {
85
+ constructor(message, activityId, nodeType, operation, cause, activityName) {
86
86
  super(message, cause instanceof WorkflowFailure ? cause.errorType : "UNKNOWN", { cause });
87
87
  this.activityId = activityId;
88
88
  this.nodeType = nodeType;
89
89
  this.operation = operation;
90
+ this.activityName = activityName;
90
91
  this.name = "ActivityFailure";
91
92
  }
92
93
  activityId;
93
94
  nodeType;
94
95
  operation;
96
+ activityName;
97
+ };
98
+ var ActivityPausedError = class extends ApplicationError {
99
+ constructor(message = "The activity was paused", details) {
100
+ super(message, {
101
+ type: "ActivityPausedError",
102
+ errorType: "TRANSIENT",
103
+ ...details !== void 0 ? { details } : {}
104
+ });
105
+ this.name = "ActivityPausedError";
106
+ }
107
+ };
108
+ var QueryHandlerSideEffect = class extends Error {
109
+ constructor(what) {
110
+ super(
111
+ `${what} is not allowed in a query handler or an update validator; they must not change the run`
112
+ );
113
+ this.name = "QueryHandlerSideEffect";
114
+ }
95
115
  };
96
116
  var ChildRunFailure = class extends WorkflowFailure {
97
117
  constructor(message, childId, childRunId, cause) {
@@ -230,4 +250,4 @@ function failureToError(failure, depth = 0) {
230
250
  return error;
231
251
  }
232
252
 
233
- export { ActivityFailure, ApplicationError, CancelledFailure, ChildRunFailure, DeterminismViolation, HistoryLimitExceeded, PhaseCFeatureError, ServerFailure, TerminatedFailure, TimeoutFailure, WorkflowFailure, defineQuery, defineSignal, defineUpdate, errorToFailure, failureToError, isCancellation, isRunFailure, signalName };
253
+ export { ActivityFailure, ActivityPausedError, ApplicationError, CancelledFailure, ChildRunFailure, DeterminismViolation, HistoryLimitExceeded, PhaseCFeatureError, QueryHandlerSideEffect, ServerFailure, TerminatedFailure, TimeoutFailure, WorkflowFailure, defineQuery, defineSignal, defineUpdate, errorToFailure, failureToError, isCancellation, isRunFailure, signalName };
@@ -1,7 +1,7 @@
1
- import { isTier1Workflow, isOperation } from './chunk-FQSJI5NV.js';
1
+ import { isTier1Workflow, isOperation } from './chunk-SR7TR5KX.js';
2
2
  import { BuilderError } from './chunk-JZ4TOOLN.js';
3
3
  import { isRecord, setOwn } from './chunk-PMCM2OH4.js';
4
- import { isDurableWorkflow, interfaceOf, toMs } from './chunk-7ILGCUI6.js';
4
+ import { isActivityImplementation, isDurableWorkflow, interfaceOf, toMs } from './chunk-C4F5KJTI.js';
5
5
 
6
6
  // src/builder/collect.ts
7
7
  var COLLECTION_FORMAT = "fluidgrids.tier1-collection";
@@ -55,9 +55,16 @@ function triggerOf(spec, where) {
55
55
  function collectWorkflowExports(modules) {
56
56
  const exportNames = /* @__PURE__ */ new Map();
57
57
  const durable = [];
58
+ const implementations = [];
59
+ const interceptorModules = [];
58
60
  for (const [module, namespace] of modules) {
61
+ if (Object.hasOwn(namespace, "interceptors")) interceptorModules.push(module);
59
62
  for (const exportName of Object.keys(namespace).sort()) {
60
63
  const value = namespace[exportName];
64
+ if (isActivityImplementation(value)) {
65
+ implementations.push({ module, exportName, name: value.name });
66
+ continue;
67
+ }
61
68
  if (!isDurableWorkflow(value) || exportNames.has(value)) continue;
62
69
  exportNames.set(value, exportName);
63
70
  const options = value.options;
@@ -74,6 +81,10 @@ function collectWorkflowExports(modules) {
74
81
  const trigger = triggerOf(options.trigger, `workflow("${value.name}")`);
75
82
  if (trigger) entry.trigger = trigger;
76
83
  const settings = runSettingsOf(options);
84
+ if (value.dynamic === true) {
85
+ entry.dynamic = true;
86
+ settings.features.push("dynamic");
87
+ }
77
88
  if (Object.keys(settings.config).length > 0) entry.config = settings.config;
78
89
  if (settings.features.length > 0) entry.features = settings.features;
79
90
  durable.push(entry);
@@ -100,7 +111,9 @@ function collectWorkflowExports(modules) {
100
111
  const collection = {
101
112
  format: COLLECTION_FORMAT,
102
113
  workflows,
103
- ...durable.length > 0 ? { durable } : {}
114
+ ...durable.length > 0 ? { durable } : {},
115
+ ...implementations.length > 0 ? { activityImplementations: implementations } : {},
116
+ ...interceptorModules.length > 0 ? { interceptorModules } : {}
104
117
  };
105
118
  return JSON.stringify(collection);
106
119
  }
@@ -1,4 +1,4 @@
1
- import { hashedProjection } from './chunk-BD7ZPG53.js';
1
+ import { hashedProjection } from './chunk-NWQ5WRLE.js';
2
2
  import { isRecord, deepEqual, ownValue } from './chunk-PMCM2OH4.js';
3
3
 
4
4
  // src/ir/diff.ts
@@ -0,0 +1,93 @@
1
+ 'use strict';
2
+
3
+ // src/history/allowlist.ts
4
+ var ACTIVITY_INTERNAL_ALLOWLIST = /* @__PURE__ */ new Set([
5
+ "internal:http",
6
+ "internal:datatable",
7
+ "internal:set",
8
+ "internal:code"
9
+ ]);
10
+ var ACTIVITY_NODE_DENYLIST = /* @__PURE__ */ new Set([
11
+ "internal:end",
12
+ "internal:if",
13
+ "internal:switch",
14
+ "internal:loop",
15
+ "internal:merge",
16
+ "internal:wait",
17
+ "internal:subworkflow",
18
+ "internal:code-workflow",
19
+ "internal:wait-for-signal",
20
+ "internal:send-and-wait",
21
+ "internal:respond-to-webhook",
22
+ "internal:failure-triage"
23
+ ]);
24
+ var ACTIVITY_NODE_ALLOWLIST = {
25
+ internal: ACTIVITY_INTERNAL_ALLOWLIST,
26
+ refused: ACTIVITY_NODE_DENYLIST,
27
+ /** Non-built-in node types (store and registry nodes) are allowed. */
28
+ external: "allowed"
29
+ };
30
+ var LEGACY_SHORT_NAMES = /* @__PURE__ */ new Set([
31
+ "if",
32
+ "switch",
33
+ "loop",
34
+ "merge",
35
+ "set",
36
+ "filter",
37
+ "aggregate",
38
+ "wait",
39
+ "noop",
40
+ "code",
41
+ "http",
42
+ "transform",
43
+ "validate",
44
+ "log",
45
+ "error",
46
+ "subworkflow",
47
+ "end",
48
+ "trigger",
49
+ "webhook",
50
+ "schedule",
51
+ "manual",
52
+ "api"
53
+ ]);
54
+ function canonicalType(nodeType) {
55
+ const lower = nodeType.trim().toLowerCase();
56
+ return LEGACY_SHORT_NAMES.has(lower) ? `internal:${lower}` : lower;
57
+ }
58
+ var ACTIVITY_ASYNC_COMPLETION_ALLOWLIST = /* @__PURE__ */ new Set([
59
+ "internal:send-and-wait"
60
+ ]);
61
+ function isActivityNodeTypeAllowed(nodeType, options = {}) {
62
+ if (typeof nodeType !== "string" || nodeType.trim() === "") return false;
63
+ const type = canonicalType(nodeType);
64
+ if (!type.startsWith("internal:")) return true;
65
+ if (options.asyncCompletion === true && ACTIVITY_ASYNC_COMPLETION_ALLOWLIST.has(type))
66
+ return true;
67
+ return ACTIVITY_INTERNAL_ALLOWLIST.has(type);
68
+ }
69
+ var ActivityNodeTypeNotAllowedError = class extends Error {
70
+ constructor(nodeType) {
71
+ super(
72
+ `${nodeType} cannot run as a durable activity: only store and registry nodes and internal:http, internal:datatable, internal:set and internal:code can`
73
+ );
74
+ this.nodeType = nodeType;
75
+ this.name = "ActivityNodeTypeNotAllowedError";
76
+ }
77
+ nodeType;
78
+ code = "durable.activityTypeNotAllowed";
79
+ errorType = "VALIDATION";
80
+ nonRetryable = true;
81
+ };
82
+ function assertActivityNodeType(nodeType, options = {}) {
83
+ if (!isActivityNodeTypeAllowed(nodeType, options))
84
+ throw new ActivityNodeTypeNotAllowedError(nodeType);
85
+ }
86
+
87
+ exports.ACTIVITY_ASYNC_COMPLETION_ALLOWLIST = ACTIVITY_ASYNC_COMPLETION_ALLOWLIST;
88
+ exports.ACTIVITY_INTERNAL_ALLOWLIST = ACTIVITY_INTERNAL_ALLOWLIST;
89
+ exports.ACTIVITY_NODE_ALLOWLIST = ACTIVITY_NODE_ALLOWLIST;
90
+ exports.ACTIVITY_NODE_DENYLIST = ACTIVITY_NODE_DENYLIST;
91
+ exports.ActivityNodeTypeNotAllowedError = ActivityNodeTypeNotAllowedError;
92
+ exports.assertActivityNodeType = assertActivityNodeType;
93
+ exports.isActivityNodeTypeAllowed = isActivityNodeTypeAllowed;
@@ -0,0 +1,85 @@
1
+ // src/history/allowlist.ts
2
+ var ACTIVITY_INTERNAL_ALLOWLIST = /* @__PURE__ */ new Set([
3
+ "internal:http",
4
+ "internal:datatable",
5
+ "internal:set",
6
+ "internal:code"
7
+ ]);
8
+ var ACTIVITY_NODE_DENYLIST = /* @__PURE__ */ new Set([
9
+ "internal:end",
10
+ "internal:if",
11
+ "internal:switch",
12
+ "internal:loop",
13
+ "internal:merge",
14
+ "internal:wait",
15
+ "internal:subworkflow",
16
+ "internal:code-workflow",
17
+ "internal:wait-for-signal",
18
+ "internal:send-and-wait",
19
+ "internal:respond-to-webhook",
20
+ "internal:failure-triage"
21
+ ]);
22
+ var ACTIVITY_NODE_ALLOWLIST = {
23
+ internal: ACTIVITY_INTERNAL_ALLOWLIST,
24
+ refused: ACTIVITY_NODE_DENYLIST,
25
+ /** Non-built-in node types (store and registry nodes) are allowed. */
26
+ external: "allowed"
27
+ };
28
+ var LEGACY_SHORT_NAMES = /* @__PURE__ */ new Set([
29
+ "if",
30
+ "switch",
31
+ "loop",
32
+ "merge",
33
+ "set",
34
+ "filter",
35
+ "aggregate",
36
+ "wait",
37
+ "noop",
38
+ "code",
39
+ "http",
40
+ "transform",
41
+ "validate",
42
+ "log",
43
+ "error",
44
+ "subworkflow",
45
+ "end",
46
+ "trigger",
47
+ "webhook",
48
+ "schedule",
49
+ "manual",
50
+ "api"
51
+ ]);
52
+ function canonicalType(nodeType) {
53
+ const lower = nodeType.trim().toLowerCase();
54
+ return LEGACY_SHORT_NAMES.has(lower) ? `internal:${lower}` : lower;
55
+ }
56
+ var ACTIVITY_ASYNC_COMPLETION_ALLOWLIST = /* @__PURE__ */ new Set([
57
+ "internal:send-and-wait"
58
+ ]);
59
+ function isActivityNodeTypeAllowed(nodeType, options = {}) {
60
+ if (typeof nodeType !== "string" || nodeType.trim() === "") return false;
61
+ const type = canonicalType(nodeType);
62
+ if (!type.startsWith("internal:")) return true;
63
+ if (options.asyncCompletion === true && ACTIVITY_ASYNC_COMPLETION_ALLOWLIST.has(type))
64
+ return true;
65
+ return ACTIVITY_INTERNAL_ALLOWLIST.has(type);
66
+ }
67
+ var ActivityNodeTypeNotAllowedError = class extends Error {
68
+ constructor(nodeType) {
69
+ super(
70
+ `${nodeType} cannot run as a durable activity: only store and registry nodes and internal:http, internal:datatable, internal:set and internal:code can`
71
+ );
72
+ this.nodeType = nodeType;
73
+ this.name = "ActivityNodeTypeNotAllowedError";
74
+ }
75
+ nodeType;
76
+ code = "durable.activityTypeNotAllowed";
77
+ errorType = "VALIDATION";
78
+ nonRetryable = true;
79
+ };
80
+ function assertActivityNodeType(nodeType, options = {}) {
81
+ if (!isActivityNodeTypeAllowed(nodeType, options))
82
+ throw new ActivityNodeTypeNotAllowedError(nodeType);
83
+ }
84
+
85
+ export { ACTIVITY_ASYNC_COMPLETION_ALLOWLIST, ACTIVITY_INTERNAL_ALLOWLIST, ACTIVITY_NODE_ALLOWLIST, ACTIVITY_NODE_DENYLIST, ActivityNodeTypeNotAllowedError, assertActivityNodeType, isActivityNodeTypeAllowed };
@@ -1,4 +1,5 @@
1
- import { PHASE_C_COMMANDS, PHASE_B_CORE_COMMANDS, PHASE_B_PARITY_COMMANDS, TERMINAL_COMMANDS, isActivityNodeTypeAllowed, isInputEvent, isCommandEvent } from './chunk-2DDULZFM.js';
1
+ import { isActivityNodeTypeAllowed } from './chunk-AC6ZEXVR.js';
2
+ import { PHASE_C_COMMANDS, PHASE_B_CORE_COMMANDS, PHASE_B_PARITY_COMMANDS, TERMINAL_COMMANDS, isInputEvent, isCommandEvent } from './chunk-5HIVIV53.js';
2
3
 
3
4
  // src/history/commands.ts
4
5
  var COMMAND_FEATURES = [
@@ -29,6 +30,39 @@ var PHASE_B_PARITY_FEATURES = /* @__PURE__ */ new Set([
29
30
  "parity.canOptions",
30
31
  "parity.workflowIdTarget"
31
32
  ]);
33
+ var PHASE_C_FEATURES = [
34
+ "c.updates",
35
+ "c.searchAttributes",
36
+ "c.userActivity"
37
+ ];
38
+ var PHASE_C_FEATURE_FLAGS = {
39
+ "c.updates": "fluidgrids.run-control",
40
+ "c.searchAttributes": "fluidgrids.search-attributes",
41
+ "c.userActivity": "fluidgrids.self-hosted-workers"
42
+ };
43
+ var CODE_FEATURE_FLAGS = {
44
+ localActivity: "fluidgrids.durable-parity",
45
+ externalCancel: "fluidgrids.durable-parity",
46
+ childOptions: "fluidgrids.durable-parity",
47
+ canOptions: "fluidgrids.durable-parity",
48
+ autoUpgrade: "fluidgrids.durable-parity",
49
+ runRetry: "fluidgrids.durable-parity",
50
+ timeouts: "fluidgrids.durable-parity",
51
+ userActivity: "fluidgrids.self-hosted-workers",
52
+ updates: "fluidgrids.run-control",
53
+ queries: "fluidgrids.run-control",
54
+ dynamic: "fluidgrids.run-control",
55
+ interceptors: "fluidgrids.run-control",
56
+ searchAttributes: "fluidgrids.search-attributes"
57
+ };
58
+ var PHASE_C_CODE_FEATURES = [
59
+ "userActivity",
60
+ "updates",
61
+ "queries",
62
+ "searchAttributes",
63
+ "dynamic",
64
+ "interceptors"
65
+ ];
32
66
  var CORE_CHILD_OPTIONS = /* @__PURE__ */ new Set([
33
67
  "parentClosePolicy",
34
68
  "cancellationType",
@@ -41,7 +75,9 @@ var CORE_CHILD_OPTIONS = /* @__PURE__ */ new Set([
41
75
  "startDelay",
42
76
  "executionTimeout",
43
77
  "runTimeout",
44
- "workflowTaskTimeout"
78
+ "workflowTaskTimeout",
79
+ "fairnessKey",
80
+ "fairnessWeight"
45
81
  ]);
46
82
  var CORE_CAN_OPTIONS = /* @__PURE__ */ new Set([
47
83
  "taskQueue",
@@ -68,6 +104,9 @@ function hasOtherKeys(value, allowed) {
68
104
  function commandFeatures(command) {
69
105
  const needed = /* @__PURE__ */ new Set();
70
106
  switch (command.type) {
107
+ case "SCHEDULE_ACTIVITY":
108
+ needed.add(command.kind === "user" ? "c.userActivity" : "core");
109
+ break;
71
110
  case "START_CHILD_RUN":
72
111
  needed.add("core");
73
112
  if (hasOtherKeys(command.options, CORE_CHILD_OPTIONS)) needed.add("parity.childOptions");
@@ -110,18 +149,40 @@ function isCommandEnabled(type, enabled = "core") {
110
149
  if (PHASE_B_CORE_COMMANDS.has(type)) return true;
111
150
  return enabled === "parity" && PHASE_B_PARITY_COMMANDS.has(type);
112
151
  }
152
+ function phaseCFeaturesOf(command) {
153
+ return commandFeatures(command).filter((feature) => feature.startsWith("c."));
154
+ }
113
155
  function isWorkflowCommandEnabled(command, enabled = "core") {
114
156
  if (typeof enabled === "string") {
157
+ if (phaseCFeaturesOf(command).length > 0) return false;
115
158
  if (command.type === "REQUEST_CANCEL_EXTERNAL_RUN" && "childId" in command.target) return true;
116
159
  return isCommandEnabled(command.type, enabled);
117
160
  }
118
161
  return commandFeatures(command).every((feature) => enabled.has(feature));
119
162
  }
163
+ function codeFeaturesEnabledBy(enabled) {
164
+ if (typeof enabled === "string") return [];
165
+ const flags = /* @__PURE__ */ new Set(["fluidgrids.durable-functions"]);
166
+ for (const feature of enabled) {
167
+ if (PHASE_B_PARITY_FEATURES.has(feature) && !PHASE_B_CORE_FEATURES.has(feature))
168
+ flags.add("fluidgrids.durable-parity");
169
+ const flag = PHASE_C_FEATURE_FLAGS[feature];
170
+ if (flag !== void 0) flags.add(flag);
171
+ }
172
+ return Object.keys(CODE_FEATURE_FLAGS).filter((feature) => flags.has(CODE_FEATURE_FLAGS[feature] ?? "")).sort();
173
+ }
120
174
  function unsupportedMessage(command, enabled = "core") {
121
- if (typeof enabled === "string") return `${command.type} is not supported in this release`;
122
- const missing = commandFeatures(command).filter((feature) => !enabled.has(feature));
123
- const parity = missing.filter((feature) => feature.startsWith("parity."));
124
- const flag = parity.length > 0 ? " (needs the fluidgrids.durable-parity flag)" : "";
175
+ const missing = typeof enabled === "string" ? phaseCFeaturesOf(command) : commandFeatures(command).filter((feature) => !enabled.has(feature));
176
+ if (missing.length === 0) return `${command.type} is not supported in this release`;
177
+ const flags = /* @__PURE__ */ new Set();
178
+ if (missing.some((feature) => feature.startsWith("parity.")))
179
+ flags.add("fluidgrids.durable-parity");
180
+ for (const feature of missing) {
181
+ const flag2 = PHASE_C_FEATURE_FLAGS[feature];
182
+ if (flag2 !== void 0) flags.add(flag2);
183
+ }
184
+ const names = [...flags];
185
+ const flag = names.length === 0 ? "" : ` (needs the ${names.join(" and ")} flag${names.length === 1 ? "" : "s"})`;
125
186
  return `${command.type} needs ${missing.join(", ")}, which this workspace does not enable${flag}`;
126
187
  }
127
188
  function isReliefCommand(command, lease) {
@@ -130,8 +191,9 @@ function isReliefCommand(command, lease) {
130
191
  return lease.grantedLocalActivityIds.includes(command.localActivityId);
131
192
  case "ACCEPT_UPDATE":
132
193
  case "REJECT_UPDATE":
133
- case "COMPLETE_UPDATE":
134
194
  return lease.deliveredUpdateIds.includes(command.updateId);
195
+ case "COMPLETE_UPDATE":
196
+ return true;
135
197
  default:
136
198
  return false;
137
199
  }
@@ -236,9 +298,19 @@ function initialRunState() {
236
298
  sideEffects: {},
237
299
  markers: {},
238
300
  signalsReceived: 0,
239
- context: {}
301
+ context: {},
302
+ updates: {},
303
+ searchAttributes: {}
240
304
  };
241
305
  }
306
+ function mergeSearchAttributes(current, entries) {
307
+ const out = { ...current };
308
+ for (const [key, value] of Object.entries(entries)) {
309
+ if (value === null) delete out[key];
310
+ else out[key] = value;
311
+ }
312
+ return out;
313
+ }
242
314
  function utf8Bytes(text) {
243
315
  let bytes = 0;
244
316
  for (let index = 0; index < text.length; index++) {
@@ -313,6 +385,8 @@ function applyEvent(state, event) {
313
385
  state.input = p["input"] ?? null;
314
386
  if (typeof p["context"] === "object" && p["context"] !== null && !Array.isArray(p["context"]))
315
387
  state.context = { ...p["context"] };
388
+ if (typeof p["searchAttributes"] === "object" && p["searchAttributes"] !== null && !Array.isArray(p["searchAttributes"]))
389
+ state.searchAttributes = mergeSearchAttributes({}, p["searchAttributes"]);
316
390
  break;
317
391
  case "WORKFLOW_TASK_SCHEDULED":
318
392
  state.task = { state: "SCHEDULED", taskId: str(p, "taskId"), attempt: state.task.attempt };
@@ -337,11 +411,14 @@ function applyEvent(state, event) {
337
411
  const id = str(p, "activityId");
338
412
  if (state.activities[id])
339
413
  throw new HistoryStateError(`Activity "${id}" is scheduled twice`, event.seq);
414
+ const user = p["kind"] === "user";
340
415
  state.activities[id] = {
341
416
  status: "SCHEDULED",
342
417
  attempt: 0,
418
+ kind: user ? "user" : "node",
343
419
  nodeType: str(p, "nodeType"),
344
420
  operation: str(p, "operation"),
421
+ ...user ? { activityName: str(p, "activityName"), taskQueue: str(p, "taskQueue") } : {},
345
422
  scheduledSeq: event.seq,
346
423
  ...typeof p["cancellationType"] === "string" ? { cancellationType: p["cancellationType"] } : {},
347
424
  ...typeof p["summary"] === "string" ? { summary: p["summary"] } : {}
@@ -490,6 +567,43 @@ function applyEvent(state, event) {
490
567
  case "MARKER_RECORDED":
491
568
  state.markers[str(p, "markerId")] = p["data"] ?? null;
492
569
  break;
570
+ case "UPDATE_ADMITTED": {
571
+ const id = str(p, "updateId");
572
+ if (state.updates[id])
573
+ throw new HistoryStateError(`Update "${id}" is admitted twice`, event.seq);
574
+ state.updates[id] = { status: "ADMITTED", name: str(p, "name"), seq: event.seq };
575
+ break;
576
+ }
577
+ case "UPDATE_ACCEPTED": {
578
+ const id = str(p, "updateId");
579
+ const found = state.updates[id];
580
+ if (found && found.status !== "ADMITTED")
581
+ throw new HistoryStateError(`Update "${id}" is accepted twice`, event.seq);
582
+ state.updates[id] = {
583
+ status: "ACCEPTED",
584
+ name: found?.name ?? str(p, "name"),
585
+ seq: found?.seq ?? event.seq
586
+ };
587
+ break;
588
+ }
589
+ case "UPDATE_COMPLETED": {
590
+ const id = str(p, "updateId");
591
+ const found = state.updates[id];
592
+ if (!found || found.status !== "ACCEPTED")
593
+ throw new HistoryStateError(
594
+ `UPDATE_COMPLETED for update "${id}" that is not accepted`,
595
+ event.seq
596
+ );
597
+ found.status = "COMPLETED";
598
+ if (failureOf(p)) found.failed = true;
599
+ break;
600
+ }
601
+ case "SEARCH_ATTRIBUTES_UPSERTED": {
602
+ const attributes = p["attributes"];
603
+ if (typeof attributes === "object" && attributes !== null && !Array.isArray(attributes))
604
+ state.searchAttributes = mergeSearchAttributes(state.searchAttributes, attributes);
605
+ break;
606
+ }
493
607
  case "CONTEXT_UPSERTED": {
494
608
  const entries = p["entries"];
495
609
  if (typeof entries === "object" && entries !== null && !Array.isArray(entries))
@@ -545,6 +659,11 @@ function payloadOf(command) {
545
659
  }
546
660
  return out;
547
661
  }
662
+ function completedPayload(command) {
663
+ if (command.failure !== void 0)
664
+ return { updateId: command.updateId, failure: command.failure };
665
+ return { updateId: command.updateId, result: command.result ?? null };
666
+ }
548
667
  function eventsForCommands(state, commands, context) {
549
668
  const issues = [];
550
669
  const events = [];
@@ -563,6 +682,8 @@ function eventsForCommands(state, commands, context) {
563
682
  const externals = new Set(Object.keys(state.externals));
564
683
  const sideEffects = new Set(Object.keys(state.sideEffects));
565
684
  const localActivities = new Set(Object.keys(state.localActivities));
685
+ const updates = new Map(Object.entries(state.updates).map(([id, u]) => [id, u.status]));
686
+ const answered = /* @__PURE__ */ new Set();
566
687
  let unsupported = false;
567
688
  commands.forEach((command, index) => {
568
689
  if (!isWorkflowCommandEnabled(command, context.enabled) && !(context.relief !== void 0 && isReliefCommand(command, context.relief))) {
@@ -577,7 +698,7 @@ function eventsForCommands(state, commands, context) {
577
698
  case "SCHEDULE_ACTIVITY":
578
699
  if (activities.has(command.activityId))
579
700
  reject(index, "activity.duplicate", `Activity "${command.activityId}" already exists`);
580
- if (!isActivityNodeTypeAllowed(command.nodeType))
701
+ if (command.kind === "node" && !isActivityNodeTypeAllowed(command.nodeType))
581
702
  reject(
582
703
  index,
583
704
  "durable.activityTypeNotAllowed",
@@ -674,6 +795,42 @@ function eventsForCommands(state, commands, context) {
674
795
  case "CONTINUE_AS_NEW":
675
796
  events.push({ ...base, type: "WORKFLOW_CONTINUED_AS_NEW", payload: payloadOf(command) });
676
797
  break;
798
+ case "UPSERT_SEARCH_ATTRIBUTES":
799
+ events.push({ ...base, type: "SEARCH_ATTRIBUTES_UPSERTED", payload: payloadOf(command) });
800
+ break;
801
+ case "ACCEPT_UPDATE":
802
+ case "REJECT_UPDATE": {
803
+ const id = command.updateId;
804
+ const status = updates.get(id);
805
+ const delivered = context.updates?.[id];
806
+ if (answered.has(id) || status !== void 0 && status !== "ADMITTED") {
807
+ reject(index, "update.answered", `Update "${id}" is already answered`);
808
+ break;
809
+ }
810
+ if (status === void 0 && delivered === void 0) {
811
+ reject(index, "update.unknown", `Update "${id}" was not delivered to this task`);
812
+ break;
813
+ }
814
+ answered.add(id);
815
+ if (command.type === "REJECT_UPDATE") break;
816
+ updates.set(id, "ACCEPTED");
817
+ const admitted = state.updates[id];
818
+ const payload = { updateId: id, name: admitted?.name ?? delivered?.name ?? "" };
819
+ if (delivered?.args !== void 0) payload["args"] = delivered.args;
820
+ if (delivered?.headers !== void 0) payload["headers"] = { ...delivered.headers };
821
+ events.push({ ...base, type: "UPDATE_ACCEPTED", payload });
822
+ break;
823
+ }
824
+ case "COMPLETE_UPDATE": {
825
+ const id = command.updateId;
826
+ if (updates.get(id) !== "ACCEPTED") {
827
+ reject(index, "update.notAccepted", `Update "${id}" is not accepted`);
828
+ break;
829
+ }
830
+ updates.set(id, "COMPLETED");
831
+ events.push({ ...base, type: "UPDATE_COMPLETED", payload: completedPayload(command) });
832
+ break;
833
+ }
677
834
  }
678
835
  });
679
836
  if (issues.length > 0)
@@ -717,4 +874,4 @@ function codeWorkflowParentClosePolicy(state) {
717
874
  var CHILD_DEFAULT_PARENT_CLOSE_POLICY = Object.freeze({ child: "TERMINATE", startChild: "ABANDON" });
718
875
  var CHILD_DEFAULT_CANCELLATION_TYPE = "WAIT_CANCELLATION_COMPLETED";
719
876
 
720
- export { CHILD_DEFAULT_CANCELLATION_TYPE, CHILD_DEFAULT_PARENT_CLOSE_POLICY, COMMAND_FEATURES, CORE_CAN_OPTIONS, CORE_CHILD_OPTIONS, HistoryStateError, PHASE_B_CORE_FEATURES, PHASE_B_PARITY_FEATURES, applyEvent, codeWorkflowParentClosePolicy, commandFeatures, continueAsNewRetryShape, eventsForCommands, hasUnprocessedInput, initialRunState, isActivityOpen, isChildOpen, isCommandEnabled, isReliefCommand, isWorkflowCommandEnabled, pendingCounts, projectRunState, splitActivations, taskCompletedEvents, unseenInputs, unsupportedMessage, utf8Bytes };
877
+ export { CHILD_DEFAULT_CANCELLATION_TYPE, CHILD_DEFAULT_PARENT_CLOSE_POLICY, CODE_FEATURE_FLAGS, COMMAND_FEATURES, CORE_CAN_OPTIONS, CORE_CHILD_OPTIONS, HistoryStateError, PHASE_B_CORE_FEATURES, PHASE_B_PARITY_FEATURES, PHASE_C_CODE_FEATURES, PHASE_C_FEATURES, PHASE_C_FEATURE_FLAGS, applyEvent, codeFeaturesEnabledBy, codeWorkflowParentClosePolicy, commandFeatures, continueAsNewRetryShape, eventsForCommands, hasUnprocessedInput, initialRunState, isActivityOpen, isChildOpen, isCommandEnabled, isReliefCommand, isWorkflowCommandEnabled, mergeSearchAttributes, pendingCounts, projectRunState, splitActivations, taskCompletedEvents, unseenInputs, unsupportedMessage, utf8Bytes };