@codemation/core 1.0.1 → 2.0.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.
Files changed (86) hide show
  1. package/CHANGELOG.md +293 -0
  2. package/dist/{EngineRuntimeRegistration.types-kxQA5NLt.d.ts → EngineRuntimeRegistration.types-D1fyApMI.d.ts} +2 -2
  3. package/dist/{EngineWorkflowRunnerService-Ba2AvBnL.d.cts → EngineRuntimeRegistration.types-pB3FnzqR.d.cts} +17 -17
  4. package/dist/{InMemoryRunDataFactory-Ou4tQUOS.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-dteLjNiT.d.ts → RunIntentService-BE9CAkbf.d.ts} +602 -213
  10. package/dist/{RunIntentService-Dyh_dH0k.d.cts → RunIntentService-siBSjaaY.d.cts} +430 -125
  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-Cko6udwL.cjs → bootstrap-Cm5ruQxx.cjs} +253 -3
  16. package/dist/bootstrap-Cm5ruQxx.cjs.map +1 -0
  17. package/dist/{bootstrap-CL68rqWg.js → bootstrap-D3r505ko.js} +236 -4
  18. package/dist/bootstrap-D3r505ko.js.map +1 -0
  19. package/dist/{index-CyfGTfU1.d.ts → index-DeLl1Tne.d.ts} +574 -242
  20. package/dist/index.cjs +328 -180
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +441 -103
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.js +305 -163
  25. package/dist/index.js.map +1 -1
  26. package/dist/{runtime-284ok0cm.js → runtime-BGNbRnqs.js} +764 -75
  27. package/dist/runtime-BGNbRnqs.js.map +1 -0
  28. package/dist/{runtime-B3Og-_St.cjs → runtime-DKXJwTNv.cjs} +841 -80
  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/authoring/DefinedCollectionRegistry.ts +17 -0
  37. package/src/authoring/defineCollection.types.ts +181 -0
  38. package/src/authoring/definePollingTrigger.types.ts +396 -0
  39. package/src/authoring/definePollingTriggerInternals.ts +74 -0
  40. package/src/authoring/index.ts +19 -0
  41. package/src/bootstrap/index.ts +9 -0
  42. package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +5 -1
  43. package/src/contracts/assertionTypes.ts +63 -0
  44. package/src/contracts/baseTypes.ts +12 -0
  45. package/src/contracts/collectionTypes.ts +44 -0
  46. package/src/contracts/credentialTypes.ts +23 -1
  47. package/src/contracts/index.ts +4 -0
  48. package/src/contracts/runTypes.ts +27 -1
  49. package/src/contracts/runtimeTypes.ts +34 -0
  50. package/src/contracts/testTriggerTypes.ts +66 -0
  51. package/src/contracts/workflowTypes.ts +30 -7
  52. package/src/contracts.ts +59 -0
  53. package/src/events/runEvents.ts +49 -0
  54. package/src/execution/ChildExecutionScopeFactory.ts +4 -7
  55. package/src/execution/DefaultExecutionContextFactory.ts +6 -0
  56. package/src/execution/NodeInstanceFactory.ts +13 -1
  57. package/src/execution/NodeInstantiationError.ts +16 -0
  58. package/src/execution/WorkflowRunExecutionContextFactory.ts +3 -0
  59. package/src/execution/index.ts +1 -0
  60. package/src/index.ts +7 -0
  61. package/src/orchestration/AbortControllerFactory.ts +9 -0
  62. package/src/orchestration/NodeExecutionRequestHandlerService.ts +1 -0
  63. package/src/orchestration/RunContinuationService.ts +3 -0
  64. package/src/orchestration/RunStartService.ts +114 -2
  65. package/src/orchestration/TestSuiteOrchestrator.ts +350 -0
  66. package/src/orchestration/TestSuiteRunIdFactory.ts +11 -0
  67. package/src/orchestration/TriggerRuntimeService.ts +34 -7
  68. package/src/orchestration/index.ts +9 -0
  69. package/src/runtime/EngineFactory.ts +11 -0
  70. package/src/triggers/polling/PollingTriggerDedupWindow.ts +23 -0
  71. package/src/triggers/polling/PollingTriggerLogger.ts +18 -0
  72. package/src/triggers/polling/PollingTriggerRuntime.ts +122 -0
  73. package/src/triggers/polling/index.ts +5 -0
  74. package/src/types/index.ts +12 -9
  75. package/src/workflow/dsl/NodeIdSlugifier.ts +18 -0
  76. package/src/workflow/dsl/WorkflowBuilder.ts +71 -3
  77. package/src/workflow/dsl/WorkflowDefinitionError.ts +15 -0
  78. package/src/workflow/index.ts +2 -0
  79. package/dist/InMemoryRunEventBusRegistry-B0_C4OnP.cjs +0 -262
  80. package/dist/InMemoryRunEventBusRegistry-B0_C4OnP.cjs.map +0 -1
  81. package/dist/InMemoryRunEventBusRegistry-C2U83Hmv.js +0 -238
  82. package/dist/InMemoryRunEventBusRegistry-C2U83Hmv.js.map +0 -1
  83. package/dist/bootstrap-CL68rqWg.js.map +0 -1
  84. package/dist/bootstrap-Cko6udwL.cjs.map +0 -1
  85. package/dist/runtime-284ok0cm.js.map +0 -1
  86. package/dist/runtime-B3Og-_St.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,298 @@
1
1
  # @codemation/core
2
2
 
3
+ ## 2.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [#102](https://github.com/MadeRelevant/codemation/pull/102) [`6566d55`](https://github.com/MadeRelevant/codemation/commit/6566d55c829f6631357ac95052b0852e86092ac5) Thanks [@cblokland90](https://github.com/cblokland90)! - **Breaking change:** Default node ids in `WorkflowBuilder` now derive from a slug of the node's label (`config.name`) instead of a sequential counter (`${tokenName}:${seq}`).
8
+
9
+ Previously, adding or reordering nodes changed their auto-assigned ids, silently orphaning credential bindings stored in the database (keyed by `workflowId + nodeId + slotKey`). The new scheme makes ids stable across reorders and inserts.
10
+
11
+ **Migration required:** Any existing credential bindings keyed by the old `${tokenName}:${seq}` format will appear unbound after this change. Users must re-bind credentials manually in the workflow editor. To avoid disruption, add an explicit `id:` field to node configs before upgrading — explicit ids are unaffected by this change and take priority over the label slug.
12
+
13
+ **Validation added:** `WorkflowBuilder.build()` now throws `WorkflowDefinitionError` if any node has an empty effective id (blank label + no explicit id) or if two nodes share the same effective id. Fix: provide a unique `id:` on the offending node configs.
14
+
15
+ ### Minor Changes
16
+
17
+ - [#111](https://github.com/MadeRelevant/codemation/pull/111) [`a77505f`](https://github.com/MadeRelevant/codemation/commit/a77505f331d7d3892f3c1c8f19dc37952b4d96bd) Thanks [@cblokland90](https://github.com/cblokland90)! - Add `definePollingTrigger` helper for declarative polling trigger authoring.
18
+
19
+ Plugin authors can now define polling triggers with a single `definePollingTrigger({...})` call instead of manually wiring `PollingTriggerRuntime` + `RunnableNodeConfig` + `@node` class pairs. The helper synthesises both the trigger config class and the runtime adapter, handles internal dedup-key bookkeeping, and exposes a `poll()` test seam for unit testing without spinning up the runtime.
20
+
21
+ - [#101](https://github.com/MadeRelevant/codemation/pull/101) [`2c0723f`](https://github.com/MadeRelevant/codemation/commit/2c0723fb1670e842c272939b5db73d4b95b25535) Thanks [@cblokland90](https://github.com/cblokland90)! - Add collections: declare typed Postgres/SQLite-backed data tables in the codemation config via `defineCollection({...})`. Schema sync runs at runtime startup behind an advisory lock (Postgres) or in-process mutex (SQLite).
22
+
23
+ Workflow access:
24
+ - `ctx.collections.<name>.crud(...)` from inside custom node code
25
+ - Six new canvas nodes: `CollectionInsert`, `CollectionGet`, `CollectionFindOne`, `CollectionList`, `CollectionUpdate`, `CollectionDelete`
26
+
27
+ Operator surfaces:
28
+ - HTTP API at `/collections/*`
29
+ - CLI: `codemation collections list|show|rows|get|insert|update|delete|sync`
30
+ - UI at `/collections`
31
+
32
+ Destructive schema changes (column drops, type changes) require `CODEMATION_COLLECTIONS_ALLOW_DESTRUCTIVE=1`.
33
+
34
+ Out of scope (separate PRs):
35
+ - Real leader election (advisory lock at boot is sufficient for sync; trigger double-firing during container swap is unaddressed)
36
+ - Admin-role gating on the UI
37
+ - Runtime user-defined schemas (Airtable-style)
38
+ - Joins, aggregates, query DSL beyond indexed-field equality
39
+
40
+ - [#109](https://github.com/MadeRelevant/codemation/pull/109) [`fb9f7fe`](https://github.com/MadeRelevant/codemation/commit/fb9f7fed9bf5a3d6b0c5f78a30027be3ab7bcaca) Thanks [@cblokland90](https://github.com/cblokland90)! - OAuth2 plugin authors can now declare `authorizeUrl` / `tokenUrl` (with `{publicFieldKey}` template substitution) directly on a credential type's `auth` definition — no core change required to add a new provider. Migrated `@codemation/core-nodes-msgraph` to use this for Microsoft tenant-templated URLs (fixes "Unsupported OAuth2 provider id: microsoft" on connect).
41
+
42
+ Removed dead `@codemation/core-nodes-gmail` devDep from `@codemation/host` and the matching `serverExternalPackages` entry from `@codemation/next-host` so plugin-author `pnpm dev` no longer rebuilds gmail when working on an unrelated plugin.
43
+
44
+ Softened the credentials UI's "Not set in host env: …" message: it's now an informational tip with neutral styling (was destructive/error styling), since the field works perfectly fine when filled in manually.
45
+
46
+ - [#101](https://github.com/MadeRelevant/codemation/pull/101) [`2c0723f`](https://github.com/MadeRelevant/codemation/commit/2c0723fb1670e842c272939b5db73d4b95b25535) Thanks [@cblokland90](https://github.com/cblokland90)! - Add collections authoring API: `defineCollection()` for declaring typed data tables, `DefinedCollectionRegistry` for registration, and `CollectionStore` contract for runtime access. Includes column DSL (`c.text()`, `c.int()`, etc.) with validation for field/index names and reserved fields.
47
+
48
+ - [#108](https://github.com/MadeRelevant/codemation/pull/108) [`781c146`](https://github.com/MadeRelevant/codemation/commit/781c146eb9d8bb8bdbc1963ea2a4b9abe4b7bfbf) Thanks [@cblokland90](https://github.com/cblokland90)! - Extract generic polling-trigger machinery from gmail into core and expose it via setup context.
49
+
50
+ **`@codemation/core`** — new polling-trigger API
51
+ - New `PollingTriggerRuntime` class: owns the set-interval loop, overlap guard, and state persistence via `TriggerSetupStateRepository`. Plugin authors no longer need to implement these themselves.
52
+ - New `PollingTriggerDedupWindow` class: merges processed-ID sets with a configurable cap (default 2000). Prevents unbounded memory growth across polling cycles.
53
+ - New `PollingTriggerHandle` interface exposed on `TriggerSetupContext.polling`: pre-binds trigger id, emit, and registerCleanup so plugin code only supplies `intervalMs` and `runCycle`. The handle also carries a `.dedup` reference for message-level deduplication.
54
+ - `EngineDeps.pollingTriggerLogger` optional field: hosts may wire a real logger; defaults to a no-op.
55
+ - `PollingTriggerRuntime`, `PollingTriggerDedupWindow`, and `NoOpPollingTriggerLogger` are exported from the main `@codemation/core` barrel.
56
+ - ESLint `allowedConstructorNames` extended to include `AbortController` (a global built-in, not a DI-managed class).
57
+
58
+ **`@codemation/core-nodes-gmail`** — internal refactor, no external API change
59
+ - `GmailPollingTriggerRuntime` deleted; loop/overlap-guard/persistence now come from the core runtime.
60
+ - `GmailPollingService.poll` renamed to `runCycle`; repo injection and `persist()` method removed; dedup delegated to `PollingTriggerDedupWindow`.
61
+ - `OnNewGmailTriggerNode.setup` now calls `ctx.polling.start(...)` instead of `gmailPollingTriggerRuntime.ensureStarted(...)`.
62
+ - `GmailNodeTokens.RuntimeLogger` token removed (no longer needed).
63
+
64
+ - [#100](https://github.com/MadeRelevant/codemation/pull/100) [`11616ae`](https://github.com/MadeRelevant/codemation/commit/11616aefb91d4b96b7eb9af4b935eec055a8a7bb) Thanks [@cblokland90](https://github.com/cblokland90)! - Foundation for first-class **workflow testing**: a TestTrigger node, an IsTestRun branching node, an Assertion node, a `TestSuiteOrchestrator` service that fans one workflow run per yielded fixture item, host-side persistence (Prisma `TestSuiteRun` + `TestAssertion` tables, repositories, `TestRunnerService`), and a per-suite event tracker that records assertions and node coverage. HTTP routes and the canvas Tests tab (next-host) ship in follow-up slices.
65
+
66
+ **What this slice adds**
67
+ - **`@codemation/core` — additive contract changes**
68
+ - `RunExecutionOptions.testContext?: { testSuiteRunId; testCaseIndex }` — set by the orchestrator on each test-case run; threaded through `ExecutionContext` so nodes can read it as `ctx.testContext`. Propagates to subworkflow runs via `ParentExecutionRef.testContext` + `EngineExecutionLimitsPolicy.mergeExecutionOptionsForNewRun`, so assertions emitted by subworkflows land under the correct parent test case.
69
+ - `TriggerNodeConfig.triggerKind?: "live" | "test"` — `"test"` triggers are skipped by `TriggerRuntimeService` (live activation, webhooks, polling) and are only invoked by the orchestrator.
70
+ - `NodeConfigBase.emitsAssertions?: true` — marker the host-side `TestAssertionPersister` (next slice) keys off when subscribing to `nodeCompleted`.
71
+ - New `AssertionResult` type (`pass | fail | error`, plus `score`, `expected`, `actual`, `message`, `details`) — the stable shape every assertion node emits on `main`.
72
+ - New `TestTriggerNodeConfig` + `TestTriggerSetupContext` — author callback signature returns `AsyncIterable<Item>` and exposes credential resolution + an `AbortSignal`.
73
+ - New `RunEvent` kinds: `testSuiteStarted`, `testCaseStarted`, `testCaseCompleted`, `testSuiteFinished` (with terminal status `succeeded | failed | partial | cancelled | errored`).
74
+ - New `TestSuiteOrchestrator` service in `orchestration/` — drives the iterator, applies a per-suite concurrency semaphore (default 4), dispatches one `engine.runWorkflow(...)` per item with `executionOptions.testContext` set, awaits terminal status, and publishes lifecycle events on the existing `RunEventBus`. No persistence, no HTTP — pure engine logic so tests can drive it via in-memory deps.
75
+ - `TestSuiteRunIdFactory`, `AbortControllerFactory` — DI-friendly minters used by the orchestrator.
76
+ - **`@codemation/core-nodes` — three new nodes**
77
+ - **`TestTrigger`** / `TestTriggerNode`: drop on the canvas alongside live triggers. `setup` is a no-op; `execute` is a passthrough. The author's `generateItems` is consumed by the orchestrator.
78
+ - **`IsTestRun`** / `IsTestRunNode`: per-item router with `true` / `false` ports. Routes to `true` iff `ctx.testContext` is set — lets workflows skip real side-effects in test runs (e.g. don't actually send the reply).
79
+ - **`Assertion`** / `AssertionNode`: generic callback-style assertion node. Author returns `Promise<AssertionResult[]>` per item; the node emits one workflow `Item` per result. Sets `emitsAssertions: true` so the host persister can identify it.
80
+ - Declarative shorthands (`StringEqualsAssertionNode`, `JudgeByAgentAssertionNode`) intentionally deferred — the generic callback node covers Phase 1 and the declarative variants compose on top.
81
+ - **`@codemation/host` — persistence + orchestration + HTTP**
82
+ - **Prisma schema**: new `TestSuiteRun` and `TestAssertion` tables in both Postgres and SQLite mirrors. Adds `Run.testSuiteRunId` (FK with `ON DELETE SET NULL`) and `Run.testCaseIndex` (indexed for join + ordering). Workflow definition itself is **not** FK'd — workflows live in code; `TestSuiteRun.triggerNodeName` is snapshotted at creation so historical viewing survives node renames/deletions.
83
+ - **`TestSuiteRunRepository`** + **`TestAssertionRepository`** domain interfaces with Prisma + in-memory adapters.
84
+ - **`TestRunnerService`** (host application layer) — single facade for "start a test suite": creates the persistence row, drives the orchestrator, awaits, finalizes counts + coverage. Subscribes to `RunEventBus.subscribeToWorkflow` only for the lifetime of one suite (no global subscriber, no shared mutable state across concurrent suites).
85
+ - **`TestSuiteRunTracker`** + **`TestSuiteRunTrackerFactory`** — per-suite event accumulator. Two-stage event buffering tolerates inline runners that emit `nodeCompleted` synchronously inside `runWorkflow` (before the orchestrator publishes `testCaseStarted`); without it, fast/in-memory engines drop assertions silently.
86
+ - **`AssertionResultGuard`** — type-guard the tracker uses to skip junk output if a misconfigured `emitsAssertions: true` node emits non-assertion items (defensive, not crash-on-bad-input).
87
+ - **HTTP routes** (Hono, all behind the existing session-verifier middleware):
88
+ - `POST /api/workflows/:workflowId/test-suite-runs` body `{ triggerNodeId, concurrency? }` → 201 with `{ testSuiteRunId, status, totalCases, passedCases, failedCases }`
89
+ - `GET /api/workflows/:workflowId/test-suite-runs` → list summaries
90
+ - `GET /api/test-suite-runs/:id` → detail (including `concurrency`, `nodeCoverage`, `errorMessage`)
91
+ - `GET /api/test-suite-runs/:id/assertions` → all assertions across the suite's child runs
92
+ - `GET /api/runs/:runId/assertions` → assertions for one child run
93
+ - Paths exposed through `ApiPaths.workflowTestSuiteRuns/testSuiteRun/testSuiteRunAssertions/runAssertions` so the next-host React Query layer can call them by helper instead of string literals.
94
+ - **DI bootstrap** in `AppContainerFactory`: registers all new singletons (factories, mappers, guard, repository selector, route handler + registrar) and wires Prisma vs in-memory `TestSuiteRunRepository` / `TestAssertionRepository` based on `appConfig.persistence.kind` (mirroring the existing `WorkflowRunRepository` selection). `TestSuiteOrchestrator` itself is registered via a tsyringe factory that injects `Engine` + the engine-side `RunEventBus` + a fresh `CredentialResolverFactory(CredentialSessionService)`.
95
+ - **DTOs** in `application/contracts/TestingContracts.ts`: `StartTestSuiteRunRequest/Response`, `TestSuiteRunSummaryDto`, `TestSuiteRunDetailDto`, `TestAssertionDto`. Mappers (`TestSuiteRunSummaryMapper`, `TestAssertionMapper`) translate persistence records → wire shape.
96
+ - **WebSocket / event narrowing** — `WorkflowWebsocketServer` and one integration test reader updated to type-narrow on the new test-suite event kinds (which carry `testSuiteRunId` rather than `runId`).
97
+
98
+ **Tests**
99
+ - `TestSuiteOrchestrator` unit suite (6 tests): per-item dispatch with `testContext`, partial-pass aggregation, lifecycle event emission, concurrency cap, `errored` status when `generateItems` throws, rejection of non-test triggers.
100
+ - Node unit suite (6 tests): TestTrigger passthrough + `triggerKind === "test"`, IsTestRun routing on both branches, AssertionNode emitting one item per result, `emitsAssertions === true`.
101
+ - `TestRunnerService` integration suite (2 tests): creates the persistence row, finalizes counts + coverage, persists 3 `TestAssertion` rows from a 2-case suite (one passing, one failing); rejects non-test triggers without leaving a phantom row.
102
+ - **`@codemation/next-host` — Tests tab UI**
103
+ - **Third canvas tab** ("Tests") next to Live workflow / Executions, mutually exclusive with both. Local React state for now (Phase 1) — promotion to the URL codec is a Phase 2 cleanup once the UX is settled.
104
+ - **`TestsPanel`** — top-level container with a trigger picker (shadcn `Select` populated from workflow nodes whose `triggerKind === "test"`), a "Run tests" CTA wired through `useStartTestSuiteRunMutation`, a left list of past suite runs, and a right detail panel.
105
+ - **`TestSuitePassRateChart`** — recharts line chart of pass rate over time across this workflow's suite runs. Carries an explicit `rolling-input` label so authors don't read trends as agent regressions when the underlying fixtures drift (Phase 2 ships snapshots).
106
+ - **`TestSuiteRunsList`** + **`TestSuiteRunStatusBadge`** — list rows + colored status badges (`running` / `succeeded` / `partial` / `failed` / `cancelled` / `errored`).
107
+ - **`TestSuiteRunDetailPanel`** — header with pass-rate + counts + concurrency + nodes-covered + (when set) an `errorMessage` callout; the body is a per-run grouped assertions list.
108
+ - **`TestAssertionsList`** + **`TestAssertionRow`** — each assertion shows status badge, optional score, optional `expected`/`actual` JSON viewers side-by-side.
109
+ - **React Query hooks** (`testSuiteHooks.ts`) cover all four GET endpoints plus the start mutation, with cache invalidation on `workflowTestSuiteRunsQueryKey` after a successful run.
110
+ - **WorkflowNodeDto** + **mapper additions** (host + next-host's `PersistedWorkflowSnapshotMapper`) propagate `triggerKind` to the wire shape so the Tests panel can identify test triggers without server round-trips. Both mappers default omitted values to `"live"` to keep the wire DTO consistent.
111
+
112
+ **Not in this slice (planned follow-ups)**
113
+ - Test-input snapshots (Phase 2 — Phase 1 inputs are always live; UI carries a "rolling-input" label so charts aren't read as agent regressions).
114
+ - Declarative assertion family (StringEquals, JsonPath, JudgeByAgent helpers — generic callback `Assertion` covers Phase 1).
115
+ - Cancellation endpoint (`POST /api/test-suite-runs/:id/cancel`) — orchestrator already supports `AbortSignal` cancellation; the HTTP surface for it is deferred until the UI surfaces it.
116
+ - Realtime updates on the Tests panel — currently the suite list refetches on mutation success; live `testSuite*` events arrive via the existing realtime bridge but the Tests panel doesn't subscribe yet.
117
+ - URL codec entry for `pane=tests` so suite drilldowns are deep-linkable (currently in-memory React state).
118
+ - Coverage heatmap overlay on the canvas itself.
119
+
120
+ The contract additions are **strictly additive**; no existing API surface changed shape.
121
+
122
+ ### Patch Changes
123
+
124
+ - [#110](https://github.com/MadeRelevant/codemation/pull/110) [`4902978`](https://github.com/MadeRelevant/codemation/commit/49029782243ece59ab6aa5bb46396db445cad47c) Thanks [@cblokland90](https://github.com/cblokland90)! - Add per-package `test:unit` scripts so Turbo can address each package individually for affected-only filtering. No runtime changes — dev-tooling only.
125
+
126
+ - [#100](https://github.com/MadeRelevant/codemation/pull/100) [`11616ae`](https://github.com/MadeRelevant/codemation/commit/11616aefb91d4b96b7eb9af4b935eec055a8a7bb) Thanks [@cblokland90](https://github.com/cblokland90)! - Major dev-server startup-time and bundle-size improvements, plus dev-CLI hardening.
127
+
128
+ **Why this matters**
129
+
130
+ Before this work, opening the workflow detail page on a 4-cpu / 8-GB WSL box would
131
+ OOM-kill `next-server` mid-compile (~5 GB peak RSS). After: the page cold-compiles in
132
+ **5.5 s** with peak **1.8 GB** and the dev server stays comfortably alive. The dev CLI
133
+ also boots significantly faster and survives consumer-source errors without tearing
134
+ the whole session down.
135
+
136
+ **Hard numbers**
137
+ - Workflow page Turbopack RSS peak: **5.0 GB → 1.8 GB** (-64%)
138
+ - Workflow page cold compile time: **~14 s → ~5.5 s**
139
+ - Lucide-react files in workflow page bundle: **1,713 → 74** (-95.7%)
140
+ - Host package typecheck: **17.5 s / 4,093 files / 2.1 GB → 8.8 s / 2,806 files / 1.9 GB**
141
+ - Host source tree: **-112,492 lines** of generated Prisma `.d.ts`
142
+ - Host circular dep cycles: **92 → 21**
143
+ - Core circular dep cycles: **53 → 50**
144
+
145
+ **`@codemation/next-host`**
146
+ - New `WorkflowCanvasLucideIconRegistry` — curated 18-icon set used by core node plugins.
147
+ Replaces `lucide-react/dynamic` (which forced bundling of all 1,713 icons because it
148
+ loads them by string at runtime). Workflows using `icon: "lucide:<unknown>"` now fall
149
+ back to the `Boxes` icon and emit a one-time `console.warn`. **Plugin authors needing
150
+ custom icons must ship SVG via `builtin:` / `si:` / URL tokens.**
151
+ - New slim subpath exports on `@codemation/host`: **`@codemation/host/dto`**,
152
+ **`@codemation/host/mapping`**, plus extensions to **`@codemation/host/client`**.
153
+ All 65 deep `@codemation/host-src/*` imports replaced; `@codemation/host-src/*`
154
+ tsconfig path removed. Prevents the UI from dragging the heavy host runtime graph
155
+ through Turbopack on every UI route compile.
156
+ - 42 lucide-react named imports rewritten to per-icon deep imports
157
+ (`lucide-react/dist/esm/icons/<kebab>`).
158
+ - Workflow detail page lazy-loads `WorkflowDetailScreenTestsView` and the
159
+ Monaco-backed `WorkflowJsonEditorDialog`.
160
+ - Removed `@codemation/core` and `@codemation/host` from `transpilePackages` and
161
+ dropped the corresponding root-barrel tsconfig paths so Next loads them from
162
+ compiled `dist/` instead of TypeScript source.
163
+ - Dev: `EdgeSessionVerifier` resolves `/api/auth/session` via
164
+ `x-forwarded-host` (the dev gateway) instead of `request.nextUrl.origin` (Next's
165
+ loopback). Previously the auth-check fetch looped back into Next, forcing
166
+ Turbopack to compile the catch-all `/api/[[...path]]` route on every page load.
167
+
168
+ **`@codemation/host`**
169
+ - Generated Prisma clients (`prisma-client`, `prisma-postgresql-client`,
170
+ `prisma-sqlite-client`) moved out of `src/infrastructure/persistence/generated/`
171
+ to `prisma-generated/` (sibling of `src/`). They're still typechecked and bundled
172
+ by the host build, but no longer pollute the public source surface that downstream
173
+ packages walk.
174
+ - New **`@codemation/host/dto`**, **`@codemation/host/mapping`** subpath exports
175
+ re-exposing only the contract DTO types and presentation factories the UI needs.
176
+ The existing **`@codemation/host/client`** subpath gained `ApiPaths`,
177
+ `BrowserLoggerFactory`, `logLevelPolicyFactory`, `InAppCallbackUrlPolicy`, and
178
+ `Logger` so the UI no longer needs deep imports.
179
+
180
+ **`@codemation/core`**
181
+ - New **`@codemation/core/contracts`** subpath — re-exports only pure-type contracts
182
+ (`assertionTypes`, `runTypes`, `workflowTypes`, etc.) using `export type *`. Type-only
183
+ consumers can import from here to avoid dragging the workflow DSL runtime into their
184
+ compile graph. Existing `@codemation/core` (root barrel) is unchanged for backwards
185
+ compatibility.
186
+ - Extracted `core/src/contracts/baseTypes.ts` (six fundamental id types) to break a
187
+ long-standing `credentialTypes ↔ workflowTypes` cycle.
188
+
189
+ **`@codemation/cli` — dev-CLI hardening**
190
+ - **`DevHttpProbe`**: TCP-listener probe replaces the HTTP-response probe, so a slow
191
+ Next dev cold compile no longer SIGTERMs the dev tree.
192
+ - **Single-runtime swap** in `runQueuedRebuild`: stops the old in-process runtime
193
+ before creating the new one, freeing ~1.5 GB during dev source-changes. Consumer
194
+ errors are now non-fatal — the gateway returns 503 and the dev session stays up
195
+ until the next save fixes the build.
196
+ - **Workspace-plugin watch is now opt-in** via `CODEMATION_DEV_WATCH_PLUGINS=true`.
197
+ By default `pnpm dev` no longer spawns `tsdown --watch` for each workspace plugin
198
+ (saves ~500 MB baseline + the rebuild-loop pressure). Plugins still load from
199
+ their existing `dist/` output; opt in only when actively editing a plugin's source.
200
+ - **`DevSourceWatcher`**: 75 ms → 750 ms debounce so a single `tsdown` rebuild collapses
201
+ into one runtime swap. Defense-in-depth ignore re-check at the event handler (chokidar
202
+ doesn't always re-evaluate `ignored` for files created post-start). 20 s startup grace
203
+ period to drop initial-build noise.
204
+ - **Workspace plugin watch root** narrowed from `dist/` to the plugin's entry file —
205
+ tsdown rewrites the entry once per real build, so one watch event per build instead of
206
+ a dozen.
207
+ - Removed `--conditions=development` from the Next-host's `NODE_OPTIONS`. Previously
208
+ this resolved `@codemation/{core,host}` to TypeScript source; combined with
209
+ `transpilePackages` it forced Turbopack to walk the full source tree on every
210
+ UI route compile.
211
+
212
+ **Architectural guard rails (no behavior change, prevent regressions)**
213
+ - ESLint `no-restricted-imports` blocks `@codemation/host-src/*` and root
214
+ `@codemation/host` from `next-host` UI; blocks `prisma-generated/*` outside host's
215
+ persistence layer.
216
+ - New **`dependency-cruiser`** config + `pnpm depcruise` script.
217
+ - New **`knip`** config + `pnpm lint:knip` script.
218
+ - New `tooling/scripts/check-circular-deps.mjs` + `pnpm lint:circular` wired into
219
+ `pnpm lint` with frozen baselines (core: 50, host: 21, core-nodes: 73).
220
+ - **`@next/bundle-analyzer`** wired up; `pnpm analyze` available for on-demand
221
+ inspection (uses `next experimental-analyze` for Turbopack-mode introspection).
222
+ - New `AGENTS.md` "Cross-package imports" section documenting the slim-subpath
223
+ discipline and the rationale for it.
224
+
225
+ The contract additions are strictly additive; no existing API surface changed shape.
226
+
227
+ - [#112](https://github.com/MadeRelevant/codemation/pull/112) [`6fc7d3f`](https://github.com/MadeRelevant/codemation/commit/6fc7d3fe95f8d88386c16971fffa8dd3faa7704f) Thanks [@cblokland90](https://github.com/cblokland90)! - Surface workflow-planning errors in the node inspector instead of swallowing them as `[codemation-http] unhandled route error`. When `NodeInstanceFactory` fails to instantiate a node (e.g. tsyringe `TypeInfo not known` for a constructor param), the offending `nodeId` is preserved via a new `NodeInstantiationError`, and `RunStartService` now persists a failed run with the error attached to that node — same shape execution errors already use, so the UI shows `name`/`message`/`stack` in the node "output" panel.
228
+
229
+ - [#100](https://github.com/MadeRelevant/codemation/pull/100) [`11616ae`](https://github.com/MadeRelevant/codemation/commit/11616aefb91d4b96b7eb9af4b935eec055a8a7bb) Thanks [@cblokland90](https://github.com/cblokland90)! - Workflow Testing UI polish and end-to-end correctness fixes.
230
+
231
+ **`@codemation/next-host`** — Tests UI
232
+ - Fix `Maximum update depth exceeded` on the Tests panel. The trends chart was receiving a
233
+ fresh `[]` reference per render (`?? []` inline) which made recharts' internal effects loop;
234
+ every `?? EMPTY_*` fallback the chart consumes is now a module-scoped stable reference.
235
+ - Fix the same loop class on the canvas-play-dropdown → Tests path. The auto-start `useEffect`
236
+ had `startMutation` (a react-query mutation result, unstable per render) in its deps array,
237
+ which re-fired the mutation on every render. Now uses a ref keyed on `autoStartTriggerNodeId`
238
+ with explicit reset when the prop clears.
239
+ - Fix the canvas inspector showing `{ "json": {...} }` for historical / test-suite child runs.
240
+ `WorkflowDetailPresenter.jsonValueToMainItems` was wrapping every array entry as
241
+ `{ json: <entry> }`, but trigger outputs are persisted **already-Item-shaped**, producing
242
+ `{json: {json: {...}}}`. Detects already-Item entries and passes them through.
243
+ - Surface assertion-rollup-corrected status on the executions list. New `RunSummary.testCaseStatus`
244
+ is preferred over engine `status` so a test-case run whose assertions failed shows as
245
+ **failed** instead of "completed" (engine status is unchanged — only the UI display).
246
+ - Tabs no longer overlap the test-cases detail panel — moved from absolute positioning to a flow
247
+ header in the Tests view.
248
+ - Filter strip above the case tree-table: All / Passing / Failing / Errored / In flight, with
249
+ live counts. Empty buckets are disabled so users can't filter into a confusing empty state.
250
+ - Collapse all / Expand all controls on the case tree-table; expansion state lifted from
251
+ per-row `useState` to the table so broadcasts work. Auto-open-on-failure heuristic still fires
252
+ per-row but only the first time each run id appears, so a row the user explicitly collapsed
253
+ stays collapsed when realtime updates stream in.
254
+ - Trend chart x-axis is now numeric `idx` with subsampled ticks (~5 evenly-spaced labels) and
255
+ time-aware formatting (`HH:MM` when all runs share a day, `M/D HH:MM` across days).
256
+ - Status icon expanded to cover the full case-status union (`succeeded` / `failed` / `errored` /
257
+ `cancelled` / `running` / `queued`) with distinct icons and colors.
258
+
259
+ **`@codemation/host`** — Testing framework correctness
260
+ - Fix `TestSuiteRunTracker` race that left the last test case stuck on `testCaseStatus="running"`
261
+ and the suite counters off by one. The bus dispatched events fire-and-forget; `finalize` ran
262
+ before in-flight handlers wrote their `updateTestCaseStatus` calls. Tracker now serializes
263
+ events through a `processingTail` chain and `finalize` awaits it before reading
264
+ `listChildRuns`.
265
+ - Initialize `Run.testCaseStatus` to `"running"` at row creation when `executionOptions.testContext`
266
+ is present. Previously the tracker's `persistCaseStarted` raced the engine inserting the row
267
+ and silently swallowed P2025 — the suite-detail page never showed a "running" transition.
268
+ - `TestSuiteChildRunDto` exposes the new `testCaseStatus?: TestCaseRunStatus` field; mapper
269
+ narrows the persistence string through a known-statuses guard.
270
+ - `PrismaWorkflowRunRepository.listRuns` threads `testCaseStatus` into `RunSummary` so the
271
+ executions list can render the corrected outcome.
272
+
273
+ **`@codemation/core`**
274
+ - `RunSummary` gains an optional `testCaseStatus?: TestCaseRunStatus`. Additive, non-breaking.
275
+
276
+ **Dev experience**
277
+ - `pnpm dev` (root) now runs `tsdown --watch` for `@codemation/host` alongside `test-dev` under
278
+ `concurrently`, so host source edits rebuild `dist/` automatically. Without this, host changes
279
+ were invisible to the running Next dev server (which deliberately resolves host from `dist/`
280
+ to keep Turbopack memory bounded on 8 GB WSL boxes), forcing a manual
281
+ `pnpm --filter @codemation/host build` after every host edit.
282
+
283
+ **Documentation**
284
+ - Top-level `docs/workflow-testing.md` and the `codemation-workflow-dsl` skill reference
285
+ rewritten for the score-based assertion model (`score: 0..1` + `passThreshold?` + `errored?`),
286
+ with examples for boolean assertions, continuous metrics, and judge-by-agent assertions.
287
+
288
+ **Tests**
289
+ - New HTTP-driven e2e suite (`packages/host/test/e2e/testSuiteRunHttpFlow.e2e.test.ts`) drives
290
+ the full real-orchestrator + real-Prisma + real-engine lifecycle through `POST` →
291
+ `GET /api/test-suite-runs/:id` → child runs → assertions, asserting the partial-suite
292
+ outcome with assertion-rollup downgrade.
293
+ - New unit tests cover the case-status filter engine, the historical-run double-wrap regression,
294
+ and the chart prop-stability regression class.
295
+
3
296
  ## 1.0.1
4
297
 
5
298
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { Li as DependencyContainer, Nr as WebhookTriggerRoutingDiagnostics, gr as TriggerRuntimeDiagnostics, jr as WebhookTriggerMatcher, na as EngineExecutionLimitsPolicyConfig, vn as WorkflowPolicyRuntimeDefaults } from "./RunIntentService-dteLjNiT.js";
1
+ import { Mr as WebhookTriggerMatcher, Pr as WebhookTriggerRoutingDiagnostics, Ta as DependencyContainer, Wa as EngineExecutionLimitsPolicyConfig, _r as TriggerRuntimeDiagnostics, vn as WorkflowPolicyRuntimeDefaults } from "./RunIntentService-BE9CAkbf.js";
2
2
 
3
3
  //#region src/bootstrap/runtime/EngineRuntimeRegistration.types.d.ts
4
4
 
@@ -41,4 +41,4 @@ interface EngineRuntimeRegistrationOptions {
41
41
  }
42
42
  //#endregion
43
43
  export { TriggerRuntimeDiagnosticsProvider as n, WebhookTriggerMatcherProvider as r, EngineRuntimeRegistrationOptions as t };
44
- //# sourceMappingURL=EngineRuntimeRegistration.types-kxQA5NLt.d.ts.map
44
+ //# sourceMappingURL=EngineRuntimeRegistration.types-D1fyApMI.d.ts.map
@@ -1,4 +1,4 @@
1
- import { Cr as DependencyContainer, E as NodeId, Hr as EngineExecutionLimitsPolicyConfig, I as ParentExecutionRef, X as WorkflowDefinition, _n as WebhookTriggerMatcher, b as NodeConfigBase, ci as PersistedWorkflowSnapshot, cn as WorkflowRepository, f as Items, it as WorkflowPolicyRuntimeDefaults, li as PersistedWorkflowSnapshotNode, nn as TriggerRuntimeDiagnostics, nt as WorkflowId, r as Engine, ui as PersistedWorkflowTokenRegistryLike, vi as RunResult, yn as WebhookTriggerRoutingDiagnostics } from "./RunIntentService-Dyh_dH0k.cjs";
1
+ import { Br as PersistedWorkflowTokenRegistryLike, Fi as NodeId, G as WorkflowDefinition, Jr as RunResult, M as ParentExecutionRef, Q as WorkflowPolicyRuntimeDefaults, Ri as WorkflowId, Rr as PersistedWorkflowSnapshot, Zt as TriggerRuntimeDiagnostics, ai as DependencyContainer, d as Items, fn as WebhookTriggerMatcher, mn as WebhookTriggerRoutingDiagnostics, r as Engine, rn as WorkflowRepository, wi as EngineExecutionLimitsPolicyConfig, y as NodeConfigBase, zr as PersistedWorkflowSnapshotNode } from "./RunIntentService-siBSjaaY.cjs";
2
2
 
3
3
  //#region src/workflowSnapshots/WorkflowSnapshotCodec.d.ts
4
4
  declare class WorkflowSnapshotCodec {
@@ -18,6 +18,20 @@ declare class WorkflowSnapshotCodec {
18
18
  private asRecord;
19
19
  }
20
20
  //#endregion
21
+ //#region src/runtime/EngineWorkflowRunnerService.d.ts
22
+ declare class EngineWorkflowRunnerService {
23
+ private readonly engine;
24
+ private readonly workflowRepository;
25
+ constructor(engine: Engine, workflowRepository: WorkflowRepository);
26
+ runById(args: {
27
+ workflowId: WorkflowId;
28
+ startAt?: NodeId;
29
+ items: Items;
30
+ parent?: ParentExecutionRef;
31
+ }): Promise<RunResult>;
32
+ private findDefaultStartNodeId;
33
+ }
34
+ //#endregion
21
35
  //#region src/bootstrap/runtime/EngineRuntimeRegistration.types.d.ts
22
36
  /**
23
37
  * Creates the webhook route matcher used by {@link import("../api/Engine").Engine}.
@@ -57,19 +71,5 @@ interface EngineRuntimeRegistrationOptions {
57
71
  workflowPolicyRuntimeDefaults?: WorkflowPolicyRuntimeDefaults;
58
72
  }
59
73
  //#endregion
60
- //#region src/runtime/EngineWorkflowRunnerService.d.ts
61
- declare class EngineWorkflowRunnerService {
62
- private readonly engine;
63
- private readonly workflowRepository;
64
- constructor(engine: Engine, workflowRepository: WorkflowRepository);
65
- runById(args: {
66
- workflowId: WorkflowId;
67
- startAt?: NodeId;
68
- items: Items;
69
- parent?: ParentExecutionRef;
70
- }): Promise<RunResult>;
71
- private findDefaultStartNodeId;
72
- }
73
- //#endregion
74
- export { WorkflowSnapshotCodec as a, WebhookTriggerMatcherProvider as i, EngineRuntimeRegistrationOptions as n, TriggerRuntimeDiagnosticsProvider as r, EngineWorkflowRunnerService as t };
75
- //# sourceMappingURL=EngineWorkflowRunnerService-Ba2AvBnL.d.cts.map
74
+ export { WorkflowSnapshotCodec as a, EngineWorkflowRunnerService as i, TriggerRuntimeDiagnosticsProvider as n, WebhookTriggerMatcherProvider as r, EngineRuntimeRegistrationOptions as t };
75
+ //# sourceMappingURL=EngineRuntimeRegistration.types-pB3FnzqR.d.cts.map
@@ -1,4 +1,4 @@
1
- import { At as ExecutionBinaryService, B as RunDataSnapshot, Cn as ExecutionTelemetryFactory, Ct as BinaryStorageReadResult, E as NodeId, Et as BinaryStorageWriteResult, Ht as NodeExecutionContext, I as ParentExecutionRef, Kt as NodeExecutionStatePublisher, L as PersistedRunPolicySnapshot, Mt as ExecutionContextFactory, St as BinaryStorage, U as RunnableNodeConfig, V as RunId, Vt as NodeBinaryAttachmentService, Yn as CostTrackingUsageRecord, a as BinaryAttachment, j as NodeOutputs, jt as ExecutionContext, mr as CredentialSessionService, nt as WorkflowId, qn as CostTrackingTelemetryFactory, u as Item, v as MutableRunData, wt as BinaryStorageStatResult, xt as BinaryBody, y as NodeActivationId, yt as RetryPolicySpec, z as RunDataFactory } from "./RunIntentService-Dyh_dH0k.cjs";
1
+ import { $r as RunTestContext, Bt as NodeExecutionStatePublisher, Et as ExecutionContextFactory, F as RunDataSnapshot, Fi as NodeId, Ft as NodeBinaryAttachmentService, Hn as CostTrackingTelemetryFactory, I as RunId, It as NodeExecutionContext, Kn as CollectionsContext, M as ParentExecutionRef, N as PersistedRunPolicySnapshot, O as NodeOutputs, P as RunDataFactory, R as RunnableNodeConfig, Ri as WorkflowId, Tt as ExecutionContext, Wn as CostTrackingUsageRecord, _ as MutableRunData, _t as BinaryStorageReadResult, a as BinaryAttachment, bt as BinaryStorageWriteResult, dr as CredentialSessionService, gt as BinaryStorage, ht as BinaryBody, l as Item, pt as RetryPolicySpec, v as NodeActivationId, vn as ExecutionTelemetryFactory, vt as BinaryStorageStatResult, wt as ExecutionBinaryService } from "./RunIntentService-siBSjaaY.cjs";
2
2
 
3
3
  //#region src/contracts/CostCatalogContract.d.ts
4
4
  interface CostCatalogEntry {
@@ -22,6 +22,31 @@ declare class CredentialResolverFactory {
22
22
  create(workflowId: WorkflowId, nodeId: NodeId, config?: NodeExecutionContext["config"]): NodeExecutionContext["getCredential"];
23
23
  }
24
24
  //#endregion
25
+ //#region src/binaries/UnavailableBinaryStorage.d.ts
26
+ declare class UnavailableBinaryStorage implements BinaryStorage {
27
+ readonly driverName = "unavailable";
28
+ write(): Promise<never>;
29
+ openReadStream(): Promise<undefined>;
30
+ stat(): Promise<{
31
+ exists: false;
32
+ }>;
33
+ delete(): Promise<void>;
34
+ }
35
+ //#endregion
36
+ //#region src/binaries/DefaultExecutionBinaryServiceFactory.d.ts
37
+ declare class DefaultExecutionBinaryService implements ExecutionBinaryService {
38
+ private readonly storage;
39
+ private readonly workflowId;
40
+ private readonly runId;
41
+ private readonly now;
42
+ constructor(storage: BinaryStorage, workflowId: WorkflowId, runId: RunId, now: () => Date);
43
+ forNode(args: {
44
+ nodeId: NodeId;
45
+ activationId: NodeActivationId;
46
+ }): NodeBinaryAttachmentService;
47
+ openReadStream(attachment: BinaryAttachment): Promise<BinaryStorageReadResult | undefined>;
48
+ }
49
+ //#endregion
25
50
  //#region src/execution/asyncSleeper.types.d.ts
26
51
  interface AsyncSleeper {
27
52
  sleep(ms: number): Promise<void>;
@@ -38,8 +63,9 @@ declare class DefaultExecutionContextFactory implements ExecutionContextFactory
38
63
  private readonly telemetryFactory;
39
64
  private readonly costTrackingFactory;
40
65
  private readonly currentDate;
66
+ private readonly collections?;
41
67
  private readonly telemetryDecoratorFactory;
42
- constructor(binaryStorage?: BinaryStorage, telemetryFactory?: ExecutionTelemetryFactory, costTrackingFactory?: CostTrackingTelemetryFactory, currentDate?: () => Date);
68
+ constructor(binaryStorage?: BinaryStorage, telemetryFactory?: ExecutionTelemetryFactory, costTrackingFactory?: CostTrackingTelemetryFactory, currentDate?: () => Date, collections?: CollectionsContext | undefined);
43
69
  create(args: {
44
70
  runId: RunId;
45
71
  workflowId: WorkflowId;
@@ -52,6 +78,7 @@ declare class DefaultExecutionContextFactory implements ExecutionContextFactory
52
78
  nodeState?: NodeExecutionStatePublisher;
53
79
  telemetry?: ExecutionContext["telemetry"];
54
80
  getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
81
+ testContext?: RunTestContext;
55
82
  }): ExecutionContext;
56
83
  }
57
84
  //#endregion
@@ -84,31 +111,6 @@ declare class RunnableOutputBehaviorResolver {
84
111
  private isKeepBinariesEnabled;
85
112
  }
86
113
  //#endregion
87
- //#region src/binaries/UnavailableBinaryStorage.d.ts
88
- declare class UnavailableBinaryStorage implements BinaryStorage {
89
- readonly driverName = "unavailable";
90
- write(): Promise<never>;
91
- openReadStream(): Promise<undefined>;
92
- stat(): Promise<{
93
- exists: false;
94
- }>;
95
- delete(): Promise<void>;
96
- }
97
- //#endregion
98
- //#region src/binaries/DefaultExecutionBinaryServiceFactory.d.ts
99
- declare class DefaultExecutionBinaryService implements ExecutionBinaryService {
100
- private readonly storage;
101
- private readonly workflowId;
102
- private readonly runId;
103
- private readonly now;
104
- constructor(storage: BinaryStorage, workflowId: WorkflowId, runId: RunId, now: () => Date);
105
- forNode(args: {
106
- nodeId: NodeId;
107
- activationId: NodeActivationId;
108
- }): NodeBinaryAttachmentService;
109
- openReadStream(attachment: BinaryAttachment): Promise<BinaryStorageReadResult | undefined>;
110
- }
111
- //#endregion
112
114
  //#region src/runStorage/InMemoryBinaryStorageRegistry.d.ts
113
115
  declare class InMemoryBinaryStorage implements BinaryStorage {
114
116
  readonly driverName = "memory";
@@ -127,5 +129,5 @@ declare class InMemoryRunDataFactory implements RunDataFactory {
127
129
  create(initial?: Record<NodeId, NodeOutputs>): MutableRunData;
128
130
  }
129
131
  //#endregion
130
- export { RunnableOutputBehavior as a, InProcessRetryRunner as c, AsyncSleeper as d, CredentialResolverFactory as f, UnavailableBinaryStorage as i, DefaultExecutionContextFactory as l, CostCatalogEntry as m, InMemoryBinaryStorage as n, RunnableOutputBehaviorResolver as o, CostCatalog as p, DefaultExecutionBinaryService as r, ItemExprResolver as s, InMemoryRunDataFactory as t, DefaultAsyncSleeper as u };
131
- //# sourceMappingURL=InMemoryRunDataFactory-Ou4tQUOS.d.cts.map
132
+ export { ItemExprResolver as a, DefaultAsyncSleeper as c, UnavailableBinaryStorage as d, CredentialResolverFactory as f, RunnableOutputBehaviorResolver as i, AsyncSleeper as l, CostCatalogEntry as m, InMemoryBinaryStorage as n, InProcessRetryRunner as o, CostCatalog as p, RunnableOutputBehavior as r, DefaultExecutionContextFactory as s, InMemoryRunDataFactory as t, DefaultExecutionBinaryService as u };
133
+ //# sourceMappingURL=InMemoryRunDataFactory-Xw7v4-sj.d.cts.map
@@ -0,0 +1,47 @@
1
+
2
+ //#region src/events/InMemoryRunEventSubscription.ts
3
+ var InMemoryRunEventSubscription = class {
4
+ constructor(onClose) {
5
+ this.onClose = onClose;
6
+ }
7
+ async close() {
8
+ this.onClose();
9
+ }
10
+ };
11
+
12
+ //#endregion
13
+ //#region src/events/InMemoryRunEventBusRegistry.ts
14
+ var InMemoryRunEventBus = class {
15
+ globalListeners = /* @__PURE__ */ new Set();
16
+ listenersByWorkflowId = /* @__PURE__ */ new Map();
17
+ async publish(event) {
18
+ for (const listener of this.globalListeners) listener(event);
19
+ for (const listener of this.listenersByWorkflowId.get(event.workflowId) ?? []) listener(event);
20
+ }
21
+ async subscribe(onEvent) {
22
+ this.globalListeners.add(onEvent);
23
+ return new InMemoryRunEventSubscription(() => {
24
+ this.globalListeners.delete(onEvent);
25
+ });
26
+ }
27
+ async subscribeToWorkflow(workflowId, onEvent) {
28
+ const existing = this.listenersByWorkflowId.get(workflowId) ?? /* @__PURE__ */ new Set();
29
+ existing.add(onEvent);
30
+ this.listenersByWorkflowId.set(workflowId, existing);
31
+ return new InMemoryRunEventSubscription(() => {
32
+ const listeners = this.listenersByWorkflowId.get(workflowId);
33
+ if (!listeners) return;
34
+ listeners.delete(onEvent);
35
+ if (listeners.size === 0) this.listenersByWorkflowId.delete(workflowId);
36
+ });
37
+ }
38
+ };
39
+
40
+ //#endregion
41
+ Object.defineProperty(exports, 'InMemoryRunEventBus', {
42
+ enumerable: true,
43
+ get: function () {
44
+ return InMemoryRunEventBus;
45
+ }
46
+ });
47
+ //# sourceMappingURL=InMemoryRunEventBusRegistry-VM3OWnHo.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InMemoryRunEventBusRegistry-VM3OWnHo.cjs","names":["onClose: () => void"],"sources":["../src/events/InMemoryRunEventSubscription.ts","../src/events/InMemoryRunEventBusRegistry.ts"],"sourcesContent":["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":";;AAEA,IAAa,+BAAb,MAA0E;CACxE,YAAY,AAAiBA,SAAqB;EAArB;;CAE7B,MAAM,QAAuB;AAC3B,OAAK,SAAS;;;;;;ACAlB,IAAa,sBAAb,MAAwD;CACtD,AAAiB,kCAAkB,IAAI,KAAgC;CACvE,AAAiB,wCAAwB,IAAI,KAAiD;CAE9F,MAAM,QAAQ,OAAgC;AAC5C,OAAK,MAAM,YAAY,KAAK,gBAAiB,UAAS,MAAM;AAC5D,OAAK,MAAM,YAAY,KAAK,sBAAsB,IAAI,MAAM,WAAW,IAAI,EAAE,CAAE,UAAS,MAAM;;CAGhG,MAAM,UAAU,SAAmE;AACjF,OAAK,gBAAgB,IAAI,QAAQ;AACjC,SAAO,IAAI,mCAAmC;AAC5C,QAAK,gBAAgB,OAAO,QAAQ;IACpC;;CAGJ,MAAM,oBAAoB,YAAwB,SAAmE;EACnH,MAAM,WAAW,KAAK,sBAAsB,IAAI,WAAW,oBAAI,IAAI,KAAgC;AACnG,WAAS,IAAI,QAAQ;AACrB,OAAK,sBAAsB,IAAI,YAAY,SAAS;AAEpD,SAAO,IAAI,mCAAmC;GAC5C,MAAM,YAAY,KAAK,sBAAsB,IAAI,WAAW;AAC5D,OAAI,CAAC,UAAW;AAChB,aAAU,OAAO,QAAQ;AACzB,OAAI,UAAU,SAAS,EAAG,MAAK,sBAAsB,OAAO,WAAW;IACvE"}
@@ -0,0 +1,41 @@
1
+ //#region src/events/InMemoryRunEventSubscription.ts
2
+ var InMemoryRunEventSubscription = class {
3
+ constructor(onClose) {
4
+ this.onClose = onClose;
5
+ }
6
+ async close() {
7
+ this.onClose();
8
+ }
9
+ };
10
+
11
+ //#endregion
12
+ //#region src/events/InMemoryRunEventBusRegistry.ts
13
+ var InMemoryRunEventBus = class {
14
+ globalListeners = /* @__PURE__ */ new Set();
15
+ listenersByWorkflowId = /* @__PURE__ */ new Map();
16
+ async publish(event) {
17
+ for (const listener of this.globalListeners) listener(event);
18
+ for (const listener of this.listenersByWorkflowId.get(event.workflowId) ?? []) listener(event);
19
+ }
20
+ async subscribe(onEvent) {
21
+ this.globalListeners.add(onEvent);
22
+ return new InMemoryRunEventSubscription(() => {
23
+ this.globalListeners.delete(onEvent);
24
+ });
25
+ }
26
+ async subscribeToWorkflow(workflowId, onEvent) {
27
+ const existing = this.listenersByWorkflowId.get(workflowId) ?? /* @__PURE__ */ new Set();
28
+ existing.add(onEvent);
29
+ this.listenersByWorkflowId.set(workflowId, existing);
30
+ return new InMemoryRunEventSubscription(() => {
31
+ const listeners = this.listenersByWorkflowId.get(workflowId);
32
+ if (!listeners) return;
33
+ listeners.delete(onEvent);
34
+ if (listeners.size === 0) this.listenersByWorkflowId.delete(workflowId);
35
+ });
36
+ }
37
+ };
38
+
39
+ //#endregion
40
+ export { InMemoryRunEventBus as t };
41
+ //# sourceMappingURL=InMemoryRunEventBusRegistry-sM4z4n_i.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InMemoryRunEventBusRegistry-sM4z4n_i.js","names":["onClose: () => void"],"sources":["../src/events/InMemoryRunEventSubscription.ts","../src/events/InMemoryRunEventBusRegistry.ts"],"sourcesContent":["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":";AAEA,IAAa,+BAAb,MAA0E;CACxE,YAAY,AAAiBA,SAAqB;EAArB;;CAE7B,MAAM,QAAuB;AAC3B,OAAK,SAAS;;;;;;ACAlB,IAAa,sBAAb,MAAwD;CACtD,AAAiB,kCAAkB,IAAI,KAAgC;CACvE,AAAiB,wCAAwB,IAAI,KAAiD;CAE9F,MAAM,QAAQ,OAAgC;AAC5C,OAAK,MAAM,YAAY,KAAK,gBAAiB,UAAS,MAAM;AAC5D,OAAK,MAAM,YAAY,KAAK,sBAAsB,IAAI,MAAM,WAAW,IAAI,EAAE,CAAE,UAAS,MAAM;;CAGhG,MAAM,UAAU,SAAmE;AACjF,OAAK,gBAAgB,IAAI,QAAQ;AACjC,SAAO,IAAI,mCAAmC;AAC5C,QAAK,gBAAgB,OAAO,QAAQ;IACpC;;CAGJ,MAAM,oBAAoB,YAAwB,SAAmE;EACnH,MAAM,WAAW,KAAK,sBAAsB,IAAI,WAAW,oBAAI,IAAI,KAAgC;AACnG,WAAS,IAAI,QAAQ;AACrB,OAAK,sBAAsB,IAAI,YAAY,SAAS;AAEpD,SAAO,IAAI,mCAAmC;GAC5C,MAAM,YAAY,KAAK,sBAAsB,IAAI,WAAW;AAC5D,OAAI,CAAC,UAAW;AAChB,aAAU,OAAO,QAAQ;AACzB,OAAI,UAAU,SAAS,EAAG,MAAK,sBAAsB,OAAO,WAAW;IACvE"}