@codemation/core 0.8.1 → 0.10.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 (100) hide show
  1. package/CHANGELOG.md +386 -0
  2. package/dist/{EngineRuntimeRegistration.types-BP6tsaNP.d.ts → EngineRuntimeRegistration.types-D1fyApMI.d.ts} +2 -2
  3. package/dist/{EngineWorkflowRunnerService-DzOCa1BW.d.cts → EngineRuntimeRegistration.types-pB3FnzqR.d.cts} +17 -17
  4. package/dist/{InMemoryRunDataFactory-1iz7_SnO.d.cts → InMemoryRunDataFactory-Xw7v4-sj.d.cts} +31 -29
  5. package/dist/InMemoryRunEventBusRegistry-VM3OWnHo.cjs +47 -0
  6. package/dist/InMemoryRunEventBusRegistry-VM3OWnHo.cjs.map +1 -0
  7. package/dist/InMemoryRunEventBusRegistry-sM4z4n_i.js +41 -0
  8. package/dist/InMemoryRunEventBusRegistry-sM4z4n_i.js.map +1 -0
  9. package/dist/{RunIntentService-BqhmdoA1.d.ts → RunIntentService-BE9CAkbf.d.ts} +966 -471
  10. package/dist/{RunIntentService-S-1lW-gS.d.cts → RunIntentService-siBSjaaY.d.cts} +859 -493
  11. package/dist/bootstrap/index.cjs +5 -2
  12. package/dist/bootstrap/index.d.cts +212 -135
  13. package/dist/bootstrap/index.d.ts +4 -4
  14. package/dist/bootstrap/index.js +3 -3
  15. package/dist/{bootstrap-Bx1u4cbS.cjs → bootstrap-Cm5ruQxx.cjs} +253 -2
  16. package/dist/bootstrap-Cm5ruQxx.cjs.map +1 -0
  17. package/dist/{bootstrap-BoknFKnw.js → bootstrap-D3r505ko.js} +236 -3
  18. package/dist/bootstrap-D3r505ko.js.map +1 -0
  19. package/dist/{index-CVs9rVhl.d.ts → index-DeLl1Tne.d.ts} +632 -230
  20. package/dist/index.cjs +323 -176
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +544 -91
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.js +299 -166
  25. package/dist/index.js.map +1 -1
  26. package/dist/{runtime-DUW6tIJ1.js → runtime-BGNbRnqs.js} +934 -75
  27. package/dist/runtime-BGNbRnqs.js.map +1 -0
  28. package/dist/{runtime-Dvo2ru5A.cjs → runtime-DKXJwTNv.cjs} +1028 -73
  29. package/dist/runtime-DKXJwTNv.cjs.map +1 -0
  30. package/dist/testing.cjs +4 -4
  31. package/dist/testing.cjs.map +1 -1
  32. package/dist/testing.d.cts +2 -2
  33. package/dist/testing.d.ts +2 -2
  34. package/dist/testing.js +3 -3
  35. package/package.json +7 -2
  36. package/src/ai/AiHost.ts +42 -14
  37. package/src/authoring/DefinedCollectionRegistry.ts +17 -0
  38. package/src/authoring/defineCollection.types.ts +181 -0
  39. package/src/authoring/definePollingTrigger.types.ts +396 -0
  40. package/src/authoring/definePollingTriggerInternals.ts +74 -0
  41. package/src/authoring/index.ts +19 -0
  42. package/src/bootstrap/index.ts +9 -0
  43. package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +8 -0
  44. package/src/browser.ts +1 -0
  45. package/src/contracts/CodemationTelemetryAttributeNames.ts +6 -0
  46. package/src/contracts/NoOpNodeExecutionTelemetry.ts +2 -11
  47. package/src/contracts/NoOpTelemetrySpanScope.ts +46 -10
  48. package/src/contracts/assertionTypes.ts +63 -0
  49. package/src/contracts/baseTypes.ts +12 -0
  50. package/src/contracts/collectionTypes.ts +44 -0
  51. package/src/contracts/credentialTypes.ts +23 -1
  52. package/src/contracts/executionPersistenceContracts.ts +30 -0
  53. package/src/contracts/index.ts +4 -0
  54. package/src/contracts/runTypes.ts +37 -1
  55. package/src/contracts/runtimeTypes.ts +42 -0
  56. package/src/contracts/telemetryTypes.ts +8 -0
  57. package/src/contracts/testTriggerTypes.ts +66 -0
  58. package/src/contracts/workflowTypes.ts +36 -7
  59. package/src/contracts.ts +59 -0
  60. package/src/events/ConnectionInvocationEventPublisher.ts +46 -0
  61. package/src/events/index.ts +1 -0
  62. package/src/events/runEvents.ts +74 -0
  63. package/src/execution/ChildExecutionScopeFactory.ts +55 -0
  64. package/src/execution/DefaultExecutionContextFactory.ts +6 -0
  65. package/src/execution/ExecutionTelemetryCostTrackingDecoratorFactory.ts +18 -0
  66. package/src/execution/NodeExecutor.ts +10 -2
  67. package/src/execution/NodeInstanceFactory.ts +13 -1
  68. package/src/execution/NodeInstantiationError.ts +16 -0
  69. package/src/execution/NodeRunStateWriter.ts +7 -0
  70. package/src/execution/NodeRunStateWriterFactory.ts +7 -0
  71. package/src/execution/WorkflowRunExecutionContextFactory.ts +3 -0
  72. package/src/execution/index.ts +2 -0
  73. package/src/index.ts +8 -0
  74. package/src/orchestration/AbortControllerFactory.ts +9 -0
  75. package/src/orchestration/NodeExecutionRequestHandlerService.ts +1 -0
  76. package/src/orchestration/RunContinuationService.ts +3 -0
  77. package/src/orchestration/RunStartService.ts +122 -3
  78. package/src/orchestration/TestSuiteOrchestrator.ts +350 -0
  79. package/src/orchestration/TestSuiteRunIdFactory.ts +11 -0
  80. package/src/orchestration/TriggerRuntimeService.ts +34 -7
  81. package/src/orchestration/index.ts +9 -0
  82. package/src/runtime/EngineFactory.ts +12 -0
  83. package/src/triggers/polling/PollingTriggerDedupWindow.ts +23 -0
  84. package/src/triggers/polling/PollingTriggerLogger.ts +18 -0
  85. package/src/triggers/polling/PollingTriggerRuntime.ts +122 -0
  86. package/src/triggers/polling/index.ts +5 -0
  87. package/src/types/index.ts +12 -9
  88. package/src/workflow/definition/NodeIterationIdFactory.ts +26 -0
  89. package/src/workflow/dsl/NodeIdSlugifier.ts +18 -0
  90. package/src/workflow/dsl/WorkflowBuilder.ts +71 -3
  91. package/src/workflow/dsl/WorkflowDefinitionError.ts +15 -0
  92. package/src/workflow/index.ts +3 -0
  93. package/dist/InMemoryRunEventBusRegistry-B0_C4OnP.cjs +0 -262
  94. package/dist/InMemoryRunEventBusRegistry-B0_C4OnP.cjs.map +0 -1
  95. package/dist/InMemoryRunEventBusRegistry-C2U83Hmv.js +0 -238
  96. package/dist/InMemoryRunEventBusRegistry-C2U83Hmv.js.map +0 -1
  97. package/dist/bootstrap-BoknFKnw.js.map +0 -1
  98. package/dist/bootstrap-Bx1u4cbS.cjs.map +0 -1
  99. package/dist/runtime-DUW6tIJ1.js.map +0 -1
  100. package/dist/runtime-Dvo2ru5A.cjs.map +0 -1
@@ -1,22 +1,25 @@
1
+ // Re-export pure-type contracts first (available via @codemation/core/contracts subpath)
2
+ export * from "../contracts";
3
+ export type { CollectionStore, CollectionsContext } from "../contracts/collectionTypes";
4
+
5
+ // Additional runtime exports not included in contracts (factory classes, DSL builders, etc.)
1
6
  export * from "../contracts/emitPorts";
2
7
  export * from "../contracts/itemMeta";
3
- export * from "../contracts/params";
4
8
  export * from "../contracts/itemExpr";
5
- export * from "../contracts/retryPolicySpec.types";
6
9
  export * from "../contracts/NoRetryPolicy";
7
10
  export * from "../contracts/RetryPolicy";
8
11
  export * from "../contracts/ExpRetryPolicy";
9
12
  export * from "../contracts/credentialTypes";
10
- export * from "../contracts/CostCatalogContract";
11
13
  export * from "../contracts/CostTrackingTelemetryContract";
12
14
  export * from "../contracts/NoOpCostTrackingTelemetry";
13
15
  export * from "../contracts/NoOpCostTrackingTelemetryFactory";
14
- export * from "../contracts/executionPersistenceContracts";
15
- export * from "../contracts/runtimeTypes";
16
- export * from "../contracts/telemetryTypes";
16
+ export * from "../contracts/NoOpExecutionTelemetryFactory";
17
17
  export * from "../contracts/runFinishedAtFactory";
18
- export * from "../contracts/runTypes";
19
- export * from "../contracts/webhookTypes";
20
- export * from "../contracts/workflowTypes";
21
18
  export * from "../contracts/workflowActivationPolicy";
19
+ // telemetryTypes and workflowTypes also have runtime exports (No-Op telemetry classes,
20
+ // attribute-name registries, `nodeRef` factory, unique-symbol type tags) — `contracts.ts`
21
+ // already re-exports them with `export type *` for the slim subpath; re-export with the
22
+ // full `export *` here so back-compat for `@codemation/core` (root) consumers is preserved.
23
+ export * from "../contracts/telemetryTypes";
24
+ export * from "../contracts/workflowTypes";
22
25
  export * from "../workflow";
@@ -0,0 +1,26 @@
1
+ import { randomUUID } from "node:crypto";
2
+
3
+ import type { NodeId } from "../../types";
4
+
5
+ /**
6
+ * Unique ids for one per-item iteration of a runnable node's execute loop.
7
+ *
8
+ * Activations are per-batch (one scheduled execution of a node, possibly with N items).
9
+ * Iterations refine that to one identifier per item-index inside the batch loop, so per-item
10
+ * connection invocations and telemetry can be grouped without time-window heuristics.
11
+ */
12
+ export class NodeIterationIdFactory {
13
+ static create(): string {
14
+ return `iter_${randomUUID()}`;
15
+ }
16
+
17
+ /** Deterministic id for tests when a stable sequence is needed. */
18
+ static createForTest(seed: string, sequence: number): string {
19
+ return `iter_${seed}_${sequence}`;
20
+ }
21
+
22
+ /** Deterministic id derived from a connection node id (for sub-agent / tool-call scopes). */
23
+ static createForConnection(connectionNodeId: NodeId, sequence: number): string {
24
+ return `iter_${connectionNodeId}_${sequence}`;
25
+ }
26
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Converts a human-readable node label into a stable, URL-safe identifier segment.
3
+ *
4
+ * Rules:
5
+ * - Lowercase the entire string.
6
+ * - Replace every run of characters outside `[a-z0-9]` with a single `-`.
7
+ * - Strip any leading or trailing `-` characters.
8
+ * - Return `""` for blank/empty input.
9
+ */
10
+ export const NodeIdSlugifier = {
11
+ slugify(label: string): string {
12
+ if (!label) return "";
13
+ return label
14
+ .toLowerCase()
15
+ .replace(/[^a-z0-9]+/g, "-")
16
+ .replace(/^-+|-+$/g, "");
17
+ },
18
+ };
@@ -10,13 +10,22 @@ import type {
10
10
  WorkflowId,
11
11
  } from "../../types";
12
12
 
13
+ import { AgentConfigInspector } from "../../ai/AgentConfigInspectorFactory";
14
+ import { AgentConnectionNodeCollector } from "../../ai/AgentConnectionNodeCollector";
13
15
  import { ChainCursor } from "./ChainCursorResolver";
16
+ import { NodeIdSlugifier } from "./NodeIdSlugifier";
17
+ import { WorkflowDefinitionError } from "./WorkflowDefinitionError";
14
18
  import type { AnyRunnableNodeConfig, AnyTriggerNodeConfig } from "./workflowBuilderTypes";
15
19
 
20
+ type NodeIdEntry = Readonly<{
21
+ nodeId: string;
22
+ tokenName: string;
23
+ label: string;
24
+ }>;
25
+
16
26
  export class WorkflowBuilder {
17
27
  private readonly nodes: NodeDefinition[] = [];
18
28
  private readonly edges: WorkflowDefinition["edges"] = [];
19
- private seq = 0;
20
29
 
21
30
  constructor(
22
31
  private readonly meta: { id: WorkflowId; name: string },
@@ -24,8 +33,7 @@ export class WorkflowBuilder {
24
33
  ) {}
25
34
 
26
35
  private add(config: NodeConfigBase): NodeRef {
27
- const tokenName = typeof config.type === "function" ? config.type.name : String(config.type);
28
- const id = config.id ?? `${tokenName}:${++this.seq}`;
36
+ const id = config.id ?? NodeIdSlugifier.slugify(config.name ?? "");
29
37
  this.nodes.push({ id, kind: config.kind, type: config.type, name: config.name, config });
30
38
  return { id, kind: config.kind, name: config.name };
31
39
  }
@@ -45,8 +53,68 @@ export class WorkflowBuilder {
45
53
  }
46
54
 
47
55
  build(): WorkflowDefinition {
56
+ this.validateNodeIds();
48
57
  return { ...this.meta, nodes: this.nodes, edges: this.edges };
49
58
  }
59
+
60
+ private validateNodeIds(): void {
61
+ const entries: NodeIdEntry[] = [];
62
+
63
+ for (const node of this.nodes) {
64
+ const tokenName = typeof node.type === "function" ? node.type.name : String(node.type);
65
+ entries.push({ nodeId: node.id, tokenName, label: node.name ?? "" });
66
+
67
+ if (AgentConfigInspector.isAgentNodeConfig(node.config)) {
68
+ for (const child of AgentConnectionNodeCollector.collect(node.id, node.config)) {
69
+ entries.push({ nodeId: child.nodeId, tokenName: child.typeName, label: child.name });
70
+ }
71
+ }
72
+ }
73
+
74
+ const emptyIds: NodeIdEntry[] = [];
75
+ const seenIds = new Map<string, NodeIdEntry>();
76
+ const duplicateIds: NodeIdEntry[] = [];
77
+
78
+ for (const entry of entries) {
79
+ if (!entry.nodeId) {
80
+ emptyIds.push(entry);
81
+ continue;
82
+ }
83
+ const existing = seenIds.get(entry.nodeId);
84
+ if (existing) {
85
+ if (!duplicateIds.includes(existing)) {
86
+ duplicateIds.push(existing);
87
+ }
88
+ duplicateIds.push(entry);
89
+ } else {
90
+ seenIds.set(entry.nodeId, entry);
91
+ }
92
+ }
93
+
94
+ if (emptyIds.length === 0 && duplicateIds.length === 0) {
95
+ return;
96
+ }
97
+
98
+ const lines: string[] = ["WorkflowBuilder.build() found invalid node ids:"];
99
+
100
+ if (emptyIds.length > 0) {
101
+ lines.push(" Empty ids (label is blank and no explicit id was given):");
102
+ for (const e of emptyIds) {
103
+ lines.push(` - type "${e.tokenName}" label "${e.label}"`);
104
+ }
105
+ }
106
+
107
+ if (duplicateIds.length > 0) {
108
+ lines.push(" Duplicate ids:");
109
+ for (const e of duplicateIds) {
110
+ lines.push(` - id "${e.nodeId}" type "${e.tokenName}" label "${e.label}"`);
111
+ }
112
+ }
113
+
114
+ lines.push(" Fix: set an explicit `id:` on each offending node config.");
115
+
116
+ throw new WorkflowDefinitionError(lines.join("\n"));
117
+ }
50
118
  }
51
119
 
52
120
  export { ChainCursor } from "./ChainCursorResolver";
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Thrown by {@link WorkflowBuilder.build} when the workflow definition is structurally invalid.
3
+ *
4
+ * Common causes:
5
+ * - A node has an empty effective id (label is blank and no explicit `id` was given).
6
+ * - Two or more nodes share the same effective id (label slugs collide or explicit ids clash).
7
+ *
8
+ * Fix: provide an explicit `id:` on the offending node configs.
9
+ */
10
+ export class WorkflowDefinitionError extends Error {
11
+ constructor(message: string) {
12
+ super(message);
13
+ this.name = "WorkflowDefinitionError";
14
+ }
15
+ }
@@ -1,10 +1,13 @@
1
1
  export { WorkflowBuilder } from "./dsl/WorkflowBuilder";
2
+ export { WorkflowDefinitionError } from "./dsl/WorkflowDefinitionError";
3
+ export { NodeIdSlugifier } from "./dsl/NodeIdSlugifier";
2
4
  export { ChainCursor } from "./dsl/ChainCursorResolver";
3
5
  export { WhenBuilder } from "./dsl/WhenBuilder";
4
6
  export * from "./dsl/workflowBuilderTypes";
5
7
 
6
8
  export { ConnectionInvocationIdFactory } from "./definition/ConnectionInvocationIdFactory";
7
9
  export { ConnectionNodeIdFactory } from "./definition/ConnectionNodeIdFactory";
10
+ export { NodeIterationIdFactory } from "./definition/NodeIterationIdFactory";
8
11
  export { WorkflowExecutableNodeClassifier } from "./definition/WorkflowExecutableNodeClassifier";
9
12
  export * from "./definition/WorkflowExecutableNodeClassifierFactory";
10
13
 
@@ -1,262 +0,0 @@
1
-
2
- //#region src/workflow/dsl/WhenBuilder.ts
3
- var WhenBuilder = class WhenBuilder {
4
- constructor(wf, from, branchPort) {
5
- this.wf = wf;
6
- this.from = from;
7
- this.branchPort = branchPort;
8
- }
9
- addBranch(steps) {
10
- const created = [];
11
- let prev = null;
12
- for (const cfg of steps) {
13
- const ref = this.wf.add(cfg);
14
- created.push(ref);
15
- if (!prev) this.wf.connect(this.from, ref, this.branchPort, "in");
16
- else this.wf.connect(prev, ref, "main", "in");
17
- prev = ref;
18
- }
19
- for (const cfg of steps) {
20
- const maybe = cfg;
21
- if (!Array.isArray(maybe.upstreamRefs) || maybe.upstreamRefs.length === 0) continue;
22
- maybe.upstreamRefs = maybe.upstreamRefs.map((r) => {
23
- if (typeof r !== "string") return r;
24
- const nodeId = created[parseInt(r.slice(1), 10)]?.id;
25
- return nodeId ? { nodeId } : { nodeId: r };
26
- });
27
- }
28
- return this;
29
- }
30
- when = (branch, steps, ...more) => {
31
- const list = Array.isArray(steps) ? steps : [steps, ...more];
32
- const port = branch ? "true" : "false";
33
- const b = new WhenBuilder(this.wf, this.from, port);
34
- b.addBranch(list);
35
- return b;
36
- };
37
- build() {
38
- return this.wf.build();
39
- }
40
- };
41
-
42
- //#endregion
43
- //#region src/workflow/dsl/ChainCursorResolver.ts
44
- var ChainCursor = class ChainCursor {
45
- constructor(wf, endpoints) {
46
- this.wf = wf;
47
- this.endpoints = endpoints;
48
- }
49
- then(config) {
50
- const next = this.wf.add(config);
51
- const inputPortHint = this.resolveSharedInputPortHint();
52
- for (const e of this.endpoints) this.wf.connect(e.node, next, e.output);
53
- return new ChainCursor(this.wf, [{
54
- node: next,
55
- output: "main",
56
- ...inputPortHint ? { inputPortHint } : {}
57
- }]);
58
- }
59
- thenIntoInputHints(config) {
60
- const next = this.wf.add(config);
61
- for (const e of this.endpoints) this.wf.connect(e.node, next, e.output, e.inputPortHint ?? "in");
62
- return new ChainCursor(this.wf, [{
63
- node: next,
64
- output: "main"
65
- }]);
66
- }
67
- when = ((arg1, steps, ...more) => {
68
- if (this.endpoints.length !== 1) throw new Error("ChainCursor.when(...) is only supported from a single cursor endpoint");
69
- const cursor = this.endpoints[0].node;
70
- if (typeof arg1 === "boolean") {
71
- const list = Array.isArray(steps) ? steps : steps ? [steps, ...more] : more;
72
- const port = arg1 ? "true" : "false";
73
- const b = new WhenBuilder(this.wf, cursor, port);
74
- b.addBranch(list);
75
- return b;
76
- }
77
- const branches = arg1;
78
- const wfAny = this.wf;
79
- const buildBranch = (port, branchSteps) => {
80
- const list = branchSteps ?? [];
81
- let prev = null;
82
- for (const cfg of list) {
83
- const ref = wfAny.add(cfg);
84
- if (!prev) wfAny.connect(cursor, ref, port, "in");
85
- else wfAny.connect(prev, ref, "main", "in");
86
- prev = ref;
87
- }
88
- if (!prev) return {
89
- end: cursor,
90
- endOutput: port,
91
- inputPortHint: port
92
- };
93
- return {
94
- end: prev,
95
- endOutput: "main",
96
- inputPortHint: port
97
- };
98
- };
99
- const t = buildBranch("true", branches.true);
100
- const f = buildBranch("false", branches.false);
101
- return new ChainCursor(this.wf, [{
102
- node: t.end,
103
- output: t.endOutput,
104
- inputPortHint: t.inputPortHint
105
- }, {
106
- node: f.end,
107
- output: f.endOutput,
108
- inputPortHint: f.inputPortHint
109
- }]);
110
- });
111
- route(branches) {
112
- if (this.endpoints.length !== 1) throw new Error("ChainCursor.route(...) is only supported from a single cursor endpoint");
113
- const cursor = this.endpoints[0];
114
- const nextEndpoints = [];
115
- for (const [port, branchFactory] of Object.entries(branches)) {
116
- if (!branchFactory) continue;
117
- const builtBranch = branchFactory(new ChainCursor(this.wf, [{
118
- node: cursor.node,
119
- output: port,
120
- inputPortHint: port
121
- }]));
122
- if (!builtBranch) continue;
123
- nextEndpoints.push(...builtBranch.endpoints);
124
- }
125
- return new ChainCursor(this.wf, nextEndpoints);
126
- }
127
- build() {
128
- return this.wf.build();
129
- }
130
- resolveSharedInputPortHint() {
131
- const first = this.endpoints[0]?.inputPortHint;
132
- if (!first) return;
133
- return this.endpoints.every((endpoint) => endpoint.inputPortHint === first) ? first : void 0;
134
- }
135
- };
136
-
137
- //#endregion
138
- //#region src/workflow/dsl/WorkflowBuilder.ts
139
- var WorkflowBuilder = class {
140
- nodes = [];
141
- edges = [];
142
- seq = 0;
143
- constructor(meta, options) {
144
- this.meta = meta;
145
- this.options = options;
146
- }
147
- add(config) {
148
- const tokenName = typeof config.type === "function" ? config.type.name : String(config.type);
149
- const id = config.id ?? `${tokenName}:${++this.seq}`;
150
- this.nodes.push({
151
- id,
152
- kind: config.kind,
153
- type: config.type,
154
- name: config.name,
155
- config
156
- });
157
- return {
158
- id,
159
- kind: config.kind,
160
- name: config.name
161
- };
162
- }
163
- connect(from, to, fromOutput = "main", toInput = "in") {
164
- this.edges.push({
165
- from: {
166
- nodeId: from.id,
167
- output: fromOutput
168
- },
169
- to: {
170
- nodeId: to.id,
171
- input: toInput
172
- }
173
- });
174
- }
175
- trigger(config) {
176
- const ref = this.add(config);
177
- return new ChainCursor(this, [{
178
- node: ref,
179
- output: "main"
180
- }]);
181
- }
182
- start(config) {
183
- const ref = this.add(config);
184
- return new ChainCursor(this, [{
185
- node: ref,
186
- output: "main"
187
- }]);
188
- }
189
- build() {
190
- return {
191
- ...this.meta,
192
- nodes: this.nodes,
193
- edges: this.edges
194
- };
195
- }
196
- };
197
-
198
- //#endregion
199
- //#region src/events/InMemoryRunEventSubscription.ts
200
- var InMemoryRunEventSubscription = class {
201
- constructor(onClose) {
202
- this.onClose = onClose;
203
- }
204
- async close() {
205
- this.onClose();
206
- }
207
- };
208
-
209
- //#endregion
210
- //#region src/events/InMemoryRunEventBusRegistry.ts
211
- var InMemoryRunEventBus = class {
212
- globalListeners = /* @__PURE__ */ new Set();
213
- listenersByWorkflowId = /* @__PURE__ */ new Map();
214
- async publish(event) {
215
- for (const listener of this.globalListeners) listener(event);
216
- for (const listener of this.listenersByWorkflowId.get(event.workflowId) ?? []) listener(event);
217
- }
218
- async subscribe(onEvent) {
219
- this.globalListeners.add(onEvent);
220
- return new InMemoryRunEventSubscription(() => {
221
- this.globalListeners.delete(onEvent);
222
- });
223
- }
224
- async subscribeToWorkflow(workflowId, onEvent) {
225
- const existing = this.listenersByWorkflowId.get(workflowId) ?? /* @__PURE__ */ new Set();
226
- existing.add(onEvent);
227
- this.listenersByWorkflowId.set(workflowId, existing);
228
- return new InMemoryRunEventSubscription(() => {
229
- const listeners = this.listenersByWorkflowId.get(workflowId);
230
- if (!listeners) return;
231
- listeners.delete(onEvent);
232
- if (listeners.size === 0) this.listenersByWorkflowId.delete(workflowId);
233
- });
234
- }
235
- };
236
-
237
- //#endregion
238
- Object.defineProperty(exports, 'ChainCursor', {
239
- enumerable: true,
240
- get: function () {
241
- return ChainCursor;
242
- }
243
- });
244
- Object.defineProperty(exports, 'InMemoryRunEventBus', {
245
- enumerable: true,
246
- get: function () {
247
- return InMemoryRunEventBus;
248
- }
249
- });
250
- Object.defineProperty(exports, 'WhenBuilder', {
251
- enumerable: true,
252
- get: function () {
253
- return WhenBuilder;
254
- }
255
- });
256
- Object.defineProperty(exports, 'WorkflowBuilder', {
257
- enumerable: true,
258
- get: function () {
259
- return WorkflowBuilder;
260
- }
261
- });
262
- //# sourceMappingURL=InMemoryRunEventBusRegistry-B0_C4OnP.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"InMemoryRunEventBusRegistry-B0_C4OnP.cjs","names":["wf: WorkflowBuilder","from: NodeRef","branchPort: OutputPortKey","created: NodeRef[]","prev: NodeRef | null","port: OutputPortKey","wf: WorkflowBuilder","endpoints: ReadonlyArray<ChainCursorEndpoint>","port: OutputPortKey","prev: NodeRef | null","nextEndpoints: ChainCursorEndpoint[]","meta: { id: WorkflowId; name: string }","options?: Readonly<Record<string, never>>","onClose: () => void"],"sources":["../src/workflow/dsl/WhenBuilder.ts","../src/workflow/dsl/ChainCursorResolver.ts","../src/workflow/dsl/WorkflowBuilder.ts","../src/events/InMemoryRunEventSubscription.ts","../src/events/InMemoryRunEventBusRegistry.ts"],"sourcesContent":["import type { NodeId, NodeRef, OutputPortKey, UpstreamRefPlaceholder, WorkflowDefinition } from \"../../types\";\n\nimport { WorkflowBuilder } from \"./WorkflowBuilder\";\nimport type { AnyRunnableNodeConfig, BooleanWhenOverloads, ValidStepSequence } from \"./workflowBuilderTypes\";\n\nexport class WhenBuilder<TCurrentJson> {\n constructor(\n private readonly wf: WorkflowBuilder,\n private readonly from: NodeRef,\n private readonly branchPort: OutputPortKey,\n ) {}\n\n addBranch<TSteps extends ReadonlyArray<AnyRunnableNodeConfig>>(\n steps: TSteps & ValidStepSequence<TCurrentJson, TSteps>,\n ): this {\n const created: NodeRef[] = [];\n\n let prev: NodeRef | null = null;\n for (const cfg of steps) {\n const ref = (this.wf as any).add(cfg) as NodeRef;\n created.push(ref);\n if (!prev) (this.wf as any).connect(this.from, ref, this.branchPort, \"in\");\n else (this.wf as any).connect(prev, ref, \"main\", \"in\");\n prev = ref;\n }\n\n for (const cfg of steps) {\n const maybe = cfg as unknown as { upstreamRefs?: Array<{ nodeId: NodeId } | UpstreamRefPlaceholder> };\n if (!Array.isArray(maybe.upstreamRefs) || maybe.upstreamRefs.length === 0) continue;\n\n maybe.upstreamRefs = maybe.upstreamRefs.map((r) => {\n if (typeof r !== \"string\") return r;\n const idx = parseInt(r.slice(1), 10);\n const nodeId = created[idx]?.id;\n return nodeId ? { nodeId } : { nodeId: r };\n });\n }\n\n return this;\n }\n\n readonly when: BooleanWhenOverloads<TCurrentJson, WhenBuilder<TCurrentJson>> = (\n branch: boolean,\n steps: ReadonlyArray<AnyRunnableNodeConfig> | AnyRunnableNodeConfig,\n ...more: AnyRunnableNodeConfig[]\n ): WhenBuilder<TCurrentJson> => {\n const list = Array.isArray(steps) ? steps : [steps, ...more];\n const port: OutputPortKey = branch ? \"true\" : \"false\";\n const b = new WhenBuilder<TCurrentJson>(this.wf, this.from, port);\n b.addBranch(list);\n return b;\n };\n\n build(): WorkflowDefinition {\n return this.wf.build();\n }\n}\n","import type {\n InputPortKey,\n NodeRef,\n OutputPortKey,\n RunnableNodeConfig,\n RunnableNodeOutputJson,\n WorkflowDefinition,\n} from \"../../types\";\n\nimport { WorkflowBuilder } from \"./WorkflowBuilder\";\nimport { WhenBuilder } from \"./WhenBuilder\";\nimport type {\n AnyRunnableNodeConfig,\n BooleanWhenOverloads,\n BranchOutputGuard,\n BranchStepsArg,\n StepSequenceOutput,\n} from \"./workflowBuilderTypes\";\n\ntype ChainCursorEndpoint = Readonly<{ node: NodeRef; output: OutputPortKey; inputPortHint?: InputPortKey }>;\n\ntype ChainCursorWhenOverloads<TCurrentJson> = BooleanWhenOverloads<TCurrentJson, WhenBuilder<TCurrentJson>> & {\n <\n TTrueSteps extends ReadonlyArray<AnyRunnableNodeConfig> | undefined,\n TFalseSteps extends ReadonlyArray<AnyRunnableNodeConfig> | undefined,\n >(\n branches: Readonly<{\n true?: TTrueSteps extends ReadonlyArray<AnyRunnableNodeConfig> ? BranchStepsArg<TCurrentJson, TTrueSteps> : never;\n false?: TFalseSteps extends ReadonlyArray<AnyRunnableNodeConfig>\n ? BranchStepsArg<TCurrentJson, TFalseSteps>\n : never;\n }> &\n BranchOutputGuard<TCurrentJson, TTrueSteps, TFalseSteps>,\n ): ChainCursor<StepSequenceOutput<TCurrentJson, TTrueSteps>>;\n};\n\nexport class ChainCursor<TCurrentJson> {\n constructor(\n private readonly wf: WorkflowBuilder,\n private readonly endpoints: ReadonlyArray<ChainCursorEndpoint>,\n ) {}\n\n then<TOutputJson, TConfig extends RunnableNodeConfig<TCurrentJson, TOutputJson>>(\n config: TConfig,\n ): ChainCursor<RunnableNodeOutputJson<TConfig>> {\n const next = (this.wf as any).add(config) as NodeRef;\n const inputPortHint = this.resolveSharedInputPortHint();\n for (const e of this.endpoints) {\n (this.wf as any).connect(e.node, next, e.output);\n }\n return new ChainCursor<RunnableNodeOutputJson<TConfig>>(this.wf, [\n { node: next, output: \"main\", ...(inputPortHint ? { inputPortHint } : {}) },\n ]);\n }\n\n thenIntoInputHints<TOutputJson, TConfig extends RunnableNodeConfig<any, TOutputJson>>(\n config: TConfig,\n ): ChainCursor<RunnableNodeOutputJson<TConfig>> {\n const next = (this.wf as any).add(config) as NodeRef;\n for (const e of this.endpoints) {\n (this.wf as any).connect(e.node, next, e.output, e.inputPortHint ?? \"in\");\n }\n return new ChainCursor<RunnableNodeOutputJson<TConfig>>(this.wf, [{ node: next, output: \"main\" }]);\n }\n\n readonly when: ChainCursorWhenOverloads<TCurrentJson> = ((\n arg1:\n | boolean\n | Readonly<{ true?: ReadonlyArray<AnyRunnableNodeConfig>; false?: ReadonlyArray<AnyRunnableNodeConfig> }>,\n steps?: ReadonlyArray<AnyRunnableNodeConfig> | AnyRunnableNodeConfig,\n ...more: AnyRunnableNodeConfig[]\n ): WhenBuilder<TCurrentJson> | ChainCursor<TCurrentJson> => {\n if (this.endpoints.length !== 1) {\n throw new Error(\"ChainCursor.when(...) is only supported from a single cursor endpoint\");\n }\n const cursor = this.endpoints[0]!.node;\n\n if (typeof arg1 === \"boolean\") {\n const list = Array.isArray(steps) ? steps : steps ? [steps, ...more] : more;\n const port: OutputPortKey = arg1 ? \"true\" : \"false\";\n const b = new WhenBuilder<TCurrentJson>(this.wf, cursor, port);\n b.addBranch(list);\n return b;\n }\n\n const branches = arg1;\n const wfAny = this.wf as any;\n\n const buildBranch = (\n port: OutputPortKey,\n branchSteps: ReadonlyArray<AnyRunnableNodeConfig> | undefined,\n ): Readonly<{ end: NodeRef; endOutput: OutputPortKey; inputPortHint: InputPortKey }> => {\n const list = branchSteps ?? [];\n let prev: NodeRef | null = null;\n for (const cfg of list) {\n const ref = wfAny.add(cfg) as NodeRef;\n if (!prev) wfAny.connect(cursor, ref, port, \"in\");\n else wfAny.connect(prev, ref, \"main\", \"in\");\n prev = ref;\n }\n if (!prev) return { end: cursor, endOutput: port, inputPortHint: port };\n return { end: prev, endOutput: \"main\", inputPortHint: port };\n };\n\n const t = buildBranch(\"true\", branches.true);\n const f = buildBranch(\"false\", branches.false);\n return new ChainCursor<TCurrentJson>(this.wf, [\n { node: t.end, output: t.endOutput, inputPortHint: t.inputPortHint },\n { node: f.end, output: f.endOutput, inputPortHint: f.inputPortHint },\n ]);\n }) as ChainCursorWhenOverloads<TCurrentJson>;\n\n route<TNextJson>(\n branches: Readonly<\n Record<OutputPortKey, (branch: ChainCursor<TCurrentJson>) => ChainCursor<TNextJson> | undefined>\n >,\n ): ChainCursor<TNextJson> {\n if (this.endpoints.length !== 1) {\n throw new Error(\"ChainCursor.route(...) is only supported from a single cursor endpoint\");\n }\n const cursor = this.endpoints[0]!;\n const nextEndpoints: ChainCursorEndpoint[] = [];\n for (const [port, branchFactory] of Object.entries(branches)) {\n if (!branchFactory) {\n continue;\n }\n const branch = new ChainCursor<TCurrentJson>(this.wf, [{ node: cursor.node, output: port, inputPortHint: port }]);\n const builtBranch = branchFactory(branch);\n if (!builtBranch) {\n continue;\n }\n nextEndpoints.push(...builtBranch.endpoints);\n }\n return new ChainCursor<TNextJson>(this.wf, nextEndpoints);\n }\n\n build(): WorkflowDefinition {\n return this.wf.build();\n }\n\n private resolveSharedInputPortHint(): InputPortKey | undefined {\n const first = this.endpoints[0]?.inputPortHint;\n if (!first) {\n return undefined;\n }\n return this.endpoints.every((endpoint) => endpoint.inputPortHint === first) ? first : undefined;\n }\n}\n","import type {\n InputPortKey,\n NodeConfigBase,\n NodeDefinition,\n NodeRef,\n OutputPortKey,\n RunnableNodeOutputJson,\n TriggerNodeOutputJson,\n WorkflowDefinition,\n WorkflowId,\n} from \"../../types\";\n\nimport { ChainCursor } from \"./ChainCursorResolver\";\nimport type { AnyRunnableNodeConfig, AnyTriggerNodeConfig } from \"./workflowBuilderTypes\";\n\nexport class WorkflowBuilder {\n private readonly nodes: NodeDefinition[] = [];\n private readonly edges: WorkflowDefinition[\"edges\"] = [];\n private seq = 0;\n\n constructor(\n private readonly meta: { id: WorkflowId; name: string },\n private readonly options?: Readonly<Record<string, never>>,\n ) {}\n\n private add(config: NodeConfigBase): NodeRef {\n const tokenName = typeof config.type === \"function\" ? config.type.name : String(config.type);\n const id = config.id ?? `${tokenName}:${++this.seq}`;\n this.nodes.push({ id, kind: config.kind, type: config.type, name: config.name, config });\n return { id, kind: config.kind, name: config.name };\n }\n\n private connect(from: NodeRef, to: NodeRef, fromOutput: OutputPortKey = \"main\", toInput: InputPortKey = \"in\"): void {\n this.edges.push({ from: { nodeId: from.id, output: fromOutput }, to: { nodeId: to.id, input: toInput } });\n }\n\n trigger<TConfig extends AnyTriggerNodeConfig>(config: TConfig): ChainCursor<TriggerNodeOutputJson<TConfig>> {\n const ref = this.add(config);\n return new ChainCursor<TriggerNodeOutputJson<TConfig>>(this, [{ node: ref, output: \"main\" }]);\n }\n\n start<TConfig extends AnyRunnableNodeConfig>(config: TConfig): ChainCursor<RunnableNodeOutputJson<TConfig>> {\n const ref = this.add(config);\n return new ChainCursor<RunnableNodeOutputJson<TConfig>>(this, [{ node: ref, output: \"main\" }]);\n }\n\n build(): WorkflowDefinition {\n return { ...this.meta, nodes: this.nodes, edges: this.edges };\n }\n}\n\nexport { ChainCursor } from \"./ChainCursorResolver\";\nexport { WhenBuilder } from \"./WhenBuilder\";\n","import type { RunEventSubscription } from \"./runEvents\";\n\nexport class InMemoryRunEventSubscription implements RunEventSubscription {\n constructor(private readonly onClose: () => void) {}\n\n async close(): Promise<void> {\n this.onClose();\n }\n}\n","import type { WorkflowId } from \"../types\";\n\nimport type { RunEvent, RunEventBus, RunEventSubscription } from \"./runEvents\";\n\nimport { InMemoryRunEventSubscription } from \"./InMemoryRunEventSubscription\";\n\nexport class InMemoryRunEventBus implements RunEventBus {\n private readonly globalListeners = new Set<(event: RunEvent) => void>();\n private readonly listenersByWorkflowId = new Map<WorkflowId, Set<(event: RunEvent) => void>>();\n\n async publish(event: RunEvent): Promise<void> {\n for (const listener of this.globalListeners) listener(event);\n for (const listener of this.listenersByWorkflowId.get(event.workflowId) ?? []) listener(event);\n }\n\n async subscribe(onEvent: (event: RunEvent) => void): Promise<RunEventSubscription> {\n this.globalListeners.add(onEvent);\n return new InMemoryRunEventSubscription(() => {\n this.globalListeners.delete(onEvent);\n });\n }\n\n async subscribeToWorkflow(workflowId: WorkflowId, onEvent: (event: RunEvent) => void): Promise<RunEventSubscription> {\n const existing = this.listenersByWorkflowId.get(workflowId) ?? new Set<(event: RunEvent) => void>();\n existing.add(onEvent);\n this.listenersByWorkflowId.set(workflowId, existing);\n\n return new InMemoryRunEventSubscription(() => {\n const listeners = this.listenersByWorkflowId.get(workflowId);\n if (!listeners) return;\n listeners.delete(onEvent);\n if (listeners.size === 0) this.listenersByWorkflowId.delete(workflowId);\n });\n }\n}\n\nexport { InMemoryRunEventSubscription } from \"./InMemoryRunEventSubscription\";\n"],"mappings":"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"}