@adonis-agora/durable 0.10.0 → 0.11.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 (163) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/assets/dashboard.html +116 -3
  3. package/dist/commands/durable_worker.d.ts +25 -0
  4. package/dist/commands/durable_worker.d.ts.map +1 -0
  5. package/dist/commands/durable_worker.js +113 -0
  6. package/dist/commands/durable_worker.js.map +1 -0
  7. package/dist/commands/main.d.ts +6 -5
  8. package/dist/commands/main.d.ts.map +1 -1
  9. package/dist/commands/main.js +11 -4
  10. package/dist/commands/main.js.map +1 -1
  11. package/dist/providers/dashboard_provider.d.ts +37 -0
  12. package/dist/providers/dashboard_provider.d.ts.map +1 -1
  13. package/dist/providers/dashboard_provider.js +98 -9
  14. package/dist/providers/dashboard_provider.js.map +1 -1
  15. package/dist/providers/durable_provider.d.ts +24 -16
  16. package/dist/providers/durable_provider.d.ts.map +1 -1
  17. package/dist/providers/durable_provider.js +195 -20
  18. package/dist/providers/durable_provider.js.map +1 -1
  19. package/dist/src/config_types.d.ts +92 -0
  20. package/dist/src/config_types.d.ts.map +1 -0
  21. package/dist/src/config_types.js +2 -0
  22. package/dist/src/config_types.js.map +1 -0
  23. package/dist/src/dashboard/compat-view.d.ts +13 -0
  24. package/dist/src/dashboard/compat-view.d.ts.map +1 -0
  25. package/dist/src/dashboard/compat-view.js +32 -0
  26. package/dist/src/dashboard/compat-view.js.map +1 -0
  27. package/dist/src/dashboard/compat.d.ts +76 -0
  28. package/dist/src/dashboard/compat.d.ts.map +1 -0
  29. package/dist/src/dashboard/compat.js +130 -0
  30. package/dist/src/dashboard/compat.js.map +1 -0
  31. package/dist/src/dashboard/diagnostics-recorder.d.ts +59 -0
  32. package/dist/src/dashboard/diagnostics-recorder.d.ts.map +1 -0
  33. package/dist/src/dashboard/diagnostics-recorder.js +75 -0
  34. package/dist/src/dashboard/diagnostics-recorder.js.map +1 -0
  35. package/dist/src/dashboard/gateway-adapter.d.ts +37 -0
  36. package/dist/src/dashboard/gateway-adapter.d.ts.map +1 -0
  37. package/dist/src/dashboard/gateway-adapter.js +49 -0
  38. package/dist/src/dashboard/gateway-adapter.js.map +1 -0
  39. package/dist/src/dashboard/handlers.d.ts +31 -8
  40. package/dist/src/dashboard/handlers.d.ts.map +1 -1
  41. package/dist/src/dashboard/handlers.js +2 -1
  42. package/dist/src/dashboard/handlers.js.map +1 -1
  43. package/dist/src/dashboard/index.d.ts +10 -3
  44. package/dist/src/dashboard/index.d.ts.map +1 -1
  45. package/dist/src/dashboard/index.js +8 -2
  46. package/dist/src/dashboard/index.js.map +1 -1
  47. package/dist/src/define_config.d.ts +31 -5
  48. package/dist/src/define_config.d.ts.map +1 -1
  49. package/dist/src/define_config.js +4 -3
  50. package/dist/src/define_config.js.map +1 -1
  51. package/dist/src/dispatch-routing.d.ts +105 -0
  52. package/dist/src/dispatch-routing.d.ts.map +1 -0
  53. package/dist/src/dispatch-routing.js +114 -0
  54. package/dist/src/dispatch-routing.js.map +1 -0
  55. package/dist/src/engine.d.ts +65 -2
  56. package/dist/src/engine.d.ts.map +1 -1
  57. package/dist/src/engine.js +131 -3
  58. package/dist/src/engine.js.map +1 -1
  59. package/dist/src/handshake/descriptor.d.ts +128 -0
  60. package/dist/src/handshake/descriptor.d.ts.map +1 -0
  61. package/dist/src/handshake/descriptor.js +133 -0
  62. package/dist/src/handshake/descriptor.js.map +1 -0
  63. package/dist/src/handshake/negotiate.d.ts +83 -0
  64. package/dist/src/handshake/negotiate.d.ts.map +1 -0
  65. package/dist/src/handshake/negotiate.js +108 -0
  66. package/dist/src/handshake/negotiate.js.map +1 -0
  67. package/dist/src/handshake/routing.d.ts +51 -0
  68. package/dist/src/handshake/routing.d.ts.map +1 -0
  69. package/dist/src/handshake/routing.js +57 -0
  70. package/dist/src/handshake/routing.js.map +1 -0
  71. package/dist/src/index.d.ts +14 -2
  72. package/dist/src/index.d.ts.map +1 -1
  73. package/dist/src/index.js +12 -1
  74. package/dist/src/index.js.map +1 -1
  75. package/dist/src/interfaces.d.ts +168 -2
  76. package/dist/src/interfaces.d.ts.map +1 -1
  77. package/dist/src/remote-workflow-executor.d.ts +25 -1
  78. package/dist/src/remote-workflow-executor.d.ts.map +1 -1
  79. package/dist/src/remote-workflow-executor.js +41 -0
  80. package/dist/src/remote-workflow-executor.js.map +1 -1
  81. package/dist/src/role_bindings.d.ts +85 -0
  82. package/dist/src/role_bindings.d.ts.map +1 -0
  83. package/dist/src/role_bindings.js +73 -0
  84. package/dist/src/role_bindings.js.map +1 -0
  85. package/dist/src/run-gateway/interface.d.ts +89 -0
  86. package/dist/src/run-gateway/interface.d.ts.map +1 -0
  87. package/dist/src/run-gateway/interface.js +2 -0
  88. package/dist/src/run-gateway/interface.js.map +1 -0
  89. package/dist/src/run-gateway/proxy-run-gateway.d.ts +84 -0
  90. package/dist/src/run-gateway/proxy-run-gateway.d.ts.map +1 -0
  91. package/dist/src/run-gateway/proxy-run-gateway.js +142 -0
  92. package/dist/src/run-gateway/proxy-run-gateway.js.map +1 -0
  93. package/dist/src/run-gateway/run-request-responder.d.ts +67 -0
  94. package/dist/src/run-gateway/run-request-responder.d.ts.map +1 -0
  95. package/dist/src/run-gateway/run-request-responder.js +228 -0
  96. package/dist/src/run-gateway/run-request-responder.js.map +1 -0
  97. package/dist/src/run-gateway/store-run-gateway.d.ts +90 -0
  98. package/dist/src/run-gateway/store-run-gateway.d.ts.map +1 -0
  99. package/dist/src/run-gateway/store-run-gateway.js +80 -0
  100. package/dist/src/run-gateway/store-run-gateway.js.map +1 -0
  101. package/dist/src/run-gateway/tenant-auth.d.ts +19 -0
  102. package/dist/src/run-gateway/tenant-auth.d.ts.map +1 -0
  103. package/dist/src/run-gateway/tenant-auth.js +71 -0
  104. package/dist/src/run-gateway/tenant-auth.js.map +1 -0
  105. package/dist/src/services/main.d.ts +16 -3
  106. package/dist/src/services/main.d.ts.map +1 -1
  107. package/dist/src/services/main.js +23 -4
  108. package/dist/src/services/main.js.map +1 -1
  109. package/dist/src/step-name-symbol.d.ts +3 -0
  110. package/dist/src/step-name-symbol.d.ts.map +1 -1
  111. package/dist/src/step-name-symbol.js.map +1 -1
  112. package/dist/src/step-ref.d.ts +4 -0
  113. package/dist/src/step-ref.d.ts.map +1 -1
  114. package/dist/src/step-ref.js +2 -0
  115. package/dist/src/step-ref.js.map +1 -1
  116. package/dist/src/transports/bullmq/bullmq-transport.d.ts +130 -0
  117. package/dist/src/transports/bullmq/bullmq-transport.d.ts.map +1 -0
  118. package/dist/src/transports/bullmq/bullmq-transport.js +562 -0
  119. package/dist/src/transports/bullmq/bullmq-transport.js.map +1 -0
  120. package/dist/src/transports/bullmq/deps.d.ts +59 -0
  121. package/dist/src/transports/bullmq/deps.d.ts.map +1 -0
  122. package/dist/src/transports/bullmq/deps.js +41 -0
  123. package/dist/src/transports/bullmq/deps.js.map +1 -0
  124. package/dist/src/transports/bullmq/index.d.ts +5 -0
  125. package/dist/src/transports/bullmq/index.d.ts.map +1 -0
  126. package/dist/src/transports/bullmq/index.js +5 -0
  127. package/dist/src/transports/bullmq/index.js.map +1 -0
  128. package/dist/src/transports/bullmq/naming.d.ts +71 -0
  129. package/dist/src/transports/bullmq/naming.d.ts.map +1 -0
  130. package/dist/src/transports/bullmq/naming.js +101 -0
  131. package/dist/src/transports/bullmq/naming.js.map +1 -0
  132. package/dist/src/transports/bullmq/serialization.d.ts +56 -0
  133. package/dist/src/transports/bullmq/serialization.d.ts.map +1 -0
  134. package/dist/src/transports/bullmq/serialization.js +101 -0
  135. package/dist/src/transports/bullmq/serialization.js.map +1 -0
  136. package/dist/src/transports/factory.d.ts +31 -0
  137. package/dist/src/transports/factory.d.ts.map +1 -1
  138. package/dist/src/transports/factory.js +21 -0
  139. package/dist/src/transports/factory.js.map +1 -1
  140. package/dist/src/worker-runtime/index.d.ts +22 -0
  141. package/dist/src/worker-runtime/index.d.ts.map +1 -0
  142. package/dist/src/worker-runtime/index.js +27 -0
  143. package/dist/src/worker-runtime/index.js.map +1 -0
  144. package/dist/src/worker-runtime/naming.d.ts +24 -0
  145. package/dist/src/worker-runtime/naming.d.ts.map +1 -0
  146. package/dist/src/worker-runtime/naming.js +28 -0
  147. package/dist/src/worker-runtime/naming.js.map +1 -0
  148. package/dist/src/worker-runtime/registry.d.ts +81 -0
  149. package/dist/src/worker-runtime/registry.d.ts.map +1 -0
  150. package/dist/src/worker-runtime/registry.js +44 -0
  151. package/dist/src/worker-runtime/registry.js.map +1 -0
  152. package/dist/src/worker-runtime/worker-runtime.d.ts +155 -0
  153. package/dist/src/worker-runtime/worker-runtime.d.ts.map +1 -0
  154. package/dist/src/worker-runtime/worker-runtime.js +265 -0
  155. package/dist/src/worker-runtime/worker-runtime.js.map +1 -0
  156. package/dist/src/workflow-ctx.d.ts.map +1 -1
  157. package/dist/src/workflow-ctx.js +3 -0
  158. package/dist/src/workflow-ctx.js.map +1 -1
  159. package/dist/src/workflow-turn.d.ts +167 -0
  160. package/dist/src/workflow-turn.d.ts.map +1 -0
  161. package/dist/src/workflow-turn.js +372 -0
  162. package/dist/src/workflow-turn.js.map +1 -0
  163. package/package.json +7 -1
@@ -1,17 +1,23 @@
1
1
  import type { ApplicationService } from '@adonisjs/core/types';
2
2
  /**
3
- * Wires `@adonis-agora/durable` into the AdonisJS application: binds a singleton
4
- * {@link WorkflowEngine} built from `config/durable.ts`.
3
+ * Wires `@adonis-agora/durable` into the AdonisJS application, branching on the config's `role` (design
4
+ * §5) so a **store-less cluster** boots per role:
5
5
  *
6
- * Defaults to an in-process store + transport (single-process, zero infra). Pick a `transport` /
7
- * `store` by name from the config's `transports` / `stores` maps to run cross-process or persist
8
- * durably; each selected driver's peer dependency is imported lazily inside its factory thunk, only
9
- * when that driver is chosen. When `@adonis-agora/context` is installed, the originating
10
- * tenant/user/correlation carrier is attached to each dispatched task (best-effort, read structurally
11
- * from the global accessor slot — no hard dependency). When `@adonis-agora/diagnostics-otel` (and an OTel SDK
12
- * such as `@adonisjs/otel`) is installed, each dispatched task is stamped with the active OTel
13
- * `traceparent` so a worker continues the trace.
6
+ * - **`standalone`** (default a config with no `role` lands here, byte-identical to today): the
7
+ * store-backed {@link WorkflowEngine} + a {@link StoreRunGateway} + the embedded worker (app/steps
8
+ * served in-process) + the engine's in-process run dispatcher.
9
+ * - **`control-plane`**: the same store-backed engine + `StoreRunGateway`, but a PURE coordinator — no
10
+ * embedded worker (app/steps are NOT served here) and a no-op run dispatcher (a started run stays
11
+ * `pending` for the poll loop). When the transport carries the P4 methods, a
12
+ * {@link RunRequestResponder} is bound + started so tenant pods can round-trip to it.
13
+ * - **`tenant`**: NO store-backed engine and NO store binding (structural isolation, design §5) — a
14
+ * {@link ProxyRunGateway} (read/control/start over the wire) plus, for a worker pod, a
15
+ * {@link WorkerRuntime} the `durable:worker` command drives.
14
16
  *
17
+ * `services/main` exposes the ACTIVE role's {@link RunGateway} under {@link DURABLE_RUN_GATEWAY}, so
18
+ * app/dashboard code is identical whether or not a store is present.
19
+ *
20
+ * Store roles keep the historical binding, so nothing that resolves the engine directly changes:
15
21
  * ```ts
16
22
  * const engine = await app.container.make(WorkflowEngine)
17
23
  * engine.register('order', '1', async (ctx) => { ... })
@@ -25,14 +31,15 @@ export default class DurableProvider {
25
31
  register(): void;
26
32
  /**
27
33
  * Auto-register the `app/workflows` convention so users never call `engine.register(...)` by hand
28
- * (mirrors `@adonisjs/queue`'s `app/jobs`). Opt-out with `config.workflowsPath = false`.
34
+ * (mirrors `@adonisjs/queue`'s `app/jobs`), then serve `app/steps` for the embedded worker
35
+ * (`standalone` only), then bring up the {@link RunRequestResponder} on a P4-capable transport.
29
36
  *
30
37
  * Prefers the **build-time barrel** generated by the Assembler `init` hook
31
38
  * (`@adonis-agora/durable/hooks/workflows` → `.adonisjs/durable/workflows.js`): registering from it
32
- * avoids any runtime `readdir`. When that barrel is absent (the hook isn't registered in
33
- * `adonisrc.ts`, or it hasn't been generated yet) it FALLS BACK to the runtime directory scan, so
34
- * apps that don't opt into the hook keep working unchanged. The low-level
35
- * `engine.register(name, version, fn)` remains the escape hatch.
39
+ * avoids any runtime `readdir`. When that barrel is absent it FALLS BACK to the runtime directory scan.
40
+ *
41
+ * A `tenant` pod owns no engine, so boot is a no-op for it (a worker pod registers `app/steps` on the
42
+ * container-bound {@link WorkerRuntime} from the `durable:worker` command instead).
36
43
  */
37
44
  boot(): Promise<void>;
38
45
  /**
@@ -40,7 +47,8 @@ export default class DurableProvider {
40
47
  * but only when diagnostics is actually installed (its emit slot is populated at module load).
41
48
  * Gating on the slot avoids eagerly constructing the engine when diagnostics is absent; when it is
42
49
  * present, this makes durable runs visible to `onDiagnostic`, Telescope, the relays and OTel with
43
- * zero config. No hard dependency on `@adonis-agora/diagnostics`.
50
+ * zero config. No hard dependency on `@adonis-agora/diagnostics`. A `tenant` pod owns no engine, so this
51
+ * is a no-op for it.
44
52
  */
45
53
  ready(): Promise<void>;
46
54
  shutdown(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"durable_provider.d.ts","sourceRoot":"","sources":["../../providers/durable_provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAwC/D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,OAAO,OAAO,eAAe;;IAKtB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,QAAQ;IA6CR;;;;;;;;;;OAUG;IACG,IAAI;IA6GV;;;;;;OAMG;IACG,KAAK;IAOL,QAAQ;CAUf"}
1
+ {"version":3,"file":"durable_provider.d.ts","sourceRoot":"","sources":["../../providers/durable_provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AA8D/D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,OAAO,OAAO,eAAe;;IAQtB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,QAAQ;IA+LR;;;;;;;;;;;OAWG;IACG,IAAI;IAsIV;;;;;;;OAOG;IACG,KAAK;IASL,QAAQ;CAcf"}
@@ -1,5 +1,7 @@
1
1
  import { pathToFileURL } from 'node:url';
2
- import { InMemoryStateStore, InMemoryTransport, WorkflowEngine, attachDurableDiagnostics, registerStepsFromBarrel, registerStepsFromDir, registerWorkflowsFromBarrel, registerWorkflowsFromDir, } from '../src/index.js';
2
+ import { InMemoryStateStore, InMemoryTransport, ProxyRunGateway, RunRequestResponder, StoreRunGateway, WorkflowEngine, attachDurableDiagnostics, registerStepsFromBarrel, registerStepsFromDir, registerWorkflowsFromBarrel, registerWorkflowsFromDir, } from '../src/index.js';
3
+ import { DURABLE_RUN_GATEWAY, DURABLE_RUN_REQUEST_RESPONDER, DURABLE_TRANSPORT, DURABLE_WORKER_RUNTIME, NOOP_RUN_DISPATCHER, descriptorRedisFrom, hasProxyCapability, hasResponderCapability, } from '../src/role_bindings.js';
4
+ import { NoopWorkerRegistry, RedisWorkerRegistry, WorkerRuntime, } from '../src/worker-runtime/index.js';
3
5
  const CONTEXT_ACCESSOR = Symbol.for('@agora/context:accessor');
4
6
  /**
5
7
  * Global slot `@adonis-agora/diagnostics-otel` publishes its `otelTraceparent` under: a
@@ -11,18 +13,24 @@ const OTEL_TRACEPARENT = Symbol.for('@agora/otel:traceparent');
11
13
  /** `@adonis-agora/diagnostics`'s emit capability slot (set at that package's module load when installed). */
12
14
  const DIAGNOSTICS_EMIT = Symbol.for('@agora/diagnostics:emit');
13
15
  /**
14
- * Wires `@adonis-agora/durable` into the AdonisJS application: binds a singleton
15
- * {@link WorkflowEngine} built from `config/durable.ts`.
16
+ * Wires `@adonis-agora/durable` into the AdonisJS application, branching on the config's `role` (design
17
+ * §5) so a **store-less cluster** boots per role:
16
18
  *
17
- * Defaults to an in-process store + transport (single-process, zero infra). Pick a `transport` /
18
- * `store` by name from the config's `transports` / `stores` maps to run cross-process or persist
19
- * durably; each selected driver's peer dependency is imported lazily inside its factory thunk, only
20
- * when that driver is chosen. When `@adonis-agora/context` is installed, the originating
21
- * tenant/user/correlation carrier is attached to each dispatched task (best-effort, read structurally
22
- * from the global accessor slot — no hard dependency). When `@adonis-agora/diagnostics-otel` (and an OTel SDK
23
- * such as `@adonisjs/otel`) is installed, each dispatched task is stamped with the active OTel
24
- * `traceparent` so a worker continues the trace.
19
+ * - **`standalone`** (default a config with no `role` lands here, byte-identical to today): the
20
+ * store-backed {@link WorkflowEngine} + a {@link StoreRunGateway} + the embedded worker (app/steps
21
+ * served in-process) + the engine's in-process run dispatcher.
22
+ * - **`control-plane`**: the same store-backed engine + `StoreRunGateway`, but a PURE coordinator — no
23
+ * embedded worker (app/steps are NOT served here) and a no-op run dispatcher (a started run stays
24
+ * `pending` for the poll loop). When the transport carries the P4 methods, a
25
+ * {@link RunRequestResponder} is bound + started so tenant pods can round-trip to it.
26
+ * - **`tenant`**: NO store-backed engine and NO store binding (structural isolation, design §5) — a
27
+ * {@link ProxyRunGateway} (read/control/start over the wire) plus, for a worker pod, a
28
+ * {@link WorkerRuntime} the `durable:worker` command drives.
25
29
  *
30
+ * `services/main` exposes the ACTIVE role's {@link RunGateway} under {@link DURABLE_RUN_GATEWAY}, so
31
+ * app/dashboard code is identical whether or not a store is present.
32
+ *
33
+ * Store roles keep the historical binding, so nothing that resolves the engine directly changes:
26
34
  * ```ts
27
35
  * const engine = await app.container.make(WorkflowEngine)
28
36
  * engine.register('order', '1', async (ctx) => { ... })
@@ -34,12 +42,70 @@ export default class DurableProvider {
34
42
  #detachDiagnostics = null;
35
43
  #transport = null;
36
44
  #controlPlane = null;
45
+ #responder = null;
46
+ /** Memoized tenant transport so the ProxyRunGateway + WorkerRuntime share ONE broker connection. */
47
+ #tenantTransportPromise = null;
37
48
  constructor(app) {
38
49
  this.app = app;
39
50
  }
40
51
  register() {
52
+ const config = this.app.config.get('durable', {});
53
+ const role = config.role ?? 'standalone';
54
+ if (role === 'tenant') {
55
+ this.#registerTenantRole(config);
56
+ }
57
+ else {
58
+ this.#registerStoreRole(config, role);
59
+ }
60
+ }
61
+ // ---------------------------------------------------------------------------
62
+ // store roles — standalone / control-plane
63
+ // ---------------------------------------------------------------------------
64
+ /** Bind the store-backed engine, its {@link StoreRunGateway}, and (P4-capable transports) the
65
+ * operator-side {@link RunRequestResponder}. Shared by `standalone` and `control-plane`. */
66
+ #registerStoreRole(config, role) {
67
+ // The active RunGateway = the store-backed gateway wrapping the local engine (design §8).
68
+ this.app.container.singleton(DURABLE_RUN_GATEWAY, async () => {
69
+ const engine = await this.app.container.make(WorkflowEngine);
70
+ return new StoreRunGateway(engine, { role });
71
+ });
72
+ // Operator-side responder. Only meaningful when the transport carries the P4 store-less methods
73
+ // (broker transports only); returns `null` otherwise. `boot()` gates on the SAME capability, so this
74
+ // factory is only ever resolved when it can produce a live responder.
75
+ this.app.container.singleton(DURABLE_RUN_REQUEST_RESPONDER, async () => {
76
+ const engine = await this.app.container.make(WorkflowEngine);
77
+ const transport = this.#transport;
78
+ if (!hasResponderCapability(transport))
79
+ return null;
80
+ const gateway = await this.app.container.make(DURABLE_RUN_GATEWAY);
81
+ const verifyTenant = config.verifyTenant;
82
+ return new RunRequestResponder(transport, gateway, {
83
+ ...(verifyTenant ? { verifyTenant } : {}),
84
+ // Republish the engine's lifecycle events, scoped by namespace, so tenants can live-tail.
85
+ subscribeEngineEvents: (listener) => engine.subscribe(listener),
86
+ });
87
+ });
88
+ // Publish the engine's task transport so the store-agnostic dashboard fleet-health panel can enumerate
89
+ // the LIVE worker fleet off it (design §10). Resolving the engine first guarantees `#transport` is set
90
+ // (the engine factory assigns it). A broker transport carries `listWorkerGroups`/`listWorkerDescriptors`;
91
+ // an in-process one doesn't, so the panel degrades to diagnostics-only — no special-casing needed here.
92
+ this.app.container.singleton(DURABLE_TRANSPORT, async () => {
93
+ await this.app.container.make(WorkflowEngine);
94
+ // Non-null after the engine factory ran; `#resolveTransport` always yields a transport (in-memory
95
+ // default when none is configured).
96
+ return this.#transport;
97
+ });
98
+ // Register the engine LAST: a naive/legacy container double (see durable_provider.spec) captures a
99
+ // SINGLE factory, overwritten on each singleton() call, so binding WorkflowEngine last keeps
100
+ // make(WorkflowEngine) resolving the engine. The real AdonisJS container is key-aware — order is
101
+ // irrelevant there; this only shields the test double.
102
+ this.#registerEngine(config, role);
103
+ }
104
+ /** Bind the store-backed {@link WorkflowEngine} singleton (today's build), applying the role's run
105
+ * dispatcher default: `control-plane` gets the no-op dispatcher (pure coordinator); `standalone`
106
+ * keeps the engine's in-process default (embedded worker). An explicit `config.runDispatcher` wins. */
107
+ #registerEngine(config, role) {
41
108
  this.app.container.singleton(WorkflowEngine, async () => {
42
- const config = this.app.config.get('durable', {});
43
109
  const accessor = globalThis[CONTEXT_ACCESSOR];
44
110
  const otelTraceparent = globalThis[OTEL_TRACEPARENT];
45
111
  const ctx = { app: this.app };
@@ -63,7 +129,14 @@ export default class DurableProvider {
63
129
  ...(config.compensationRetries !== undefined
64
130
  ? { compensationRetries: config.compensationRetries }
65
131
  : {}),
66
- ...(config.runDispatcher ? { runDispatcher: config.runDispatcher } : {}),
132
+ // Where a freshly-started run executes: explicit config wins; else `control-plane` leaves it
133
+ // pending for the poll loop (no inline execution), and `standalone` uses the engine's in-process
134
+ // default (embedded worker).
135
+ ...(config.runDispatcher
136
+ ? { runDispatcher: config.runDispatcher }
137
+ : role === 'control-plane'
138
+ ? { runDispatcher: NOOP_RUN_DISPATCHER }
139
+ : {}),
67
140
  // Best-effort context propagation from @adonis-agora/context (no hard dep): pass the opaque
68
141
  // carrier through verbatim. The carrier is producer-owned and shape-opaque; the worker's
69
142
  // scope slot round-trips the whole snapshot via Context.run, so no field-picking is needed.
@@ -74,19 +147,91 @@ export default class DurableProvider {
74
147
  return new WorkflowEngine(deps);
75
148
  });
76
149
  }
150
+ // ---------------------------------------------------------------------------
151
+ // tenant role — store-less (no engine, no store binding)
152
+ // ---------------------------------------------------------------------------
153
+ /**
154
+ * Bind the store-less objects for a `tenant` pod (design §5): a {@link ProxyRunGateway} (every
155
+ * read/control/start round-trips over the wire) and a {@link WorkerRuntime} for a worker pod. NO
156
+ * {@link WorkflowEngine} and NO store binding are registered — resolving either throws, which is the
157
+ * container layer of the three-layer structural isolation (type · container · object).
158
+ */
159
+ #registerTenantRole(config) {
160
+ this.app.container.singleton(DURABLE_RUN_GATEWAY, async () => {
161
+ const transport = await this.#tenantTransport(config);
162
+ if (!hasProxyCapability(transport)) {
163
+ throw new Error(`@agora/durable: role 'tenant' needs a transport with the P4 store-less methods (dispatchStartRun/dispatchRunRequest/onRunReply/onTenantEvent); the selected transport ("${config.transport}") does not expose them.`);
164
+ }
165
+ return new ProxyRunGateway(transport, {
166
+ partition: config.partition,
167
+ ...(config.tenant?.token !== undefined ? { token: config.tenant.token } : {}),
168
+ ...(config.requestTimeoutMs !== undefined
169
+ ? { requestTimeoutMs: config.requestTimeoutMs }
170
+ : {}),
171
+ });
172
+ });
173
+ this.app.container.singleton(DURABLE_WORKER_RUNTIME, async () => {
174
+ const transport = await this.#tenantTransport(config);
175
+ if (typeof transport.handle !== 'function') {
176
+ throw new Error(`@agora/durable: role 'tenant' worker needs a transport that can serve handlers (handle()); the selected transport ("${config.transport}") cannot.`);
177
+ }
178
+ return new WorkerRuntime({
179
+ transport: transport,
180
+ partition: config.partition,
181
+ ...(config.namespace !== undefined ? { namespace: config.namespace } : {}),
182
+ ...(config.instanceId !== undefined ? { instanceId: config.instanceId } : {}),
183
+ ...(config.capabilities !== undefined ? { capabilities: config.capabilities } : {}),
184
+ registry: this.#buildWorkerRegistry(transport),
185
+ });
186
+ });
187
+ }
188
+ /**
189
+ * Build the descriptor/heartbeat registry for a tenant worker: a real {@link RedisWorkerRegistry} when
190
+ * the transport can mint a descriptor-Redis client (design §7.2), else the {@link NoopWorkerRegistry}
191
+ * (the descriptor is still built + observable, just not published to the shared Redis).
192
+ */
193
+ #buildWorkerRegistry(transport) {
194
+ const redis = descriptorRedisFrom(transport);
195
+ if (redis)
196
+ return new RedisWorkerRegistry(redis, { ownsConnection: true });
197
+ // TODO(integrator): expose `createDescriptorRedis()` on the tenant broker transport
198
+ // (e.g. BullMQTransport, keyed off the same connection its queues use) so a real pod advertises its
199
+ // descriptor + heartbeat on the shared Redis instead of falling back to the no-op registry.
200
+ return new NoopWorkerRegistry();
201
+ }
202
+ /** Build the tenant transport ONCE and memoize it, so the ProxyRunGateway and the WorkerRuntime share
203
+ * one broker connection (and one set of P4 consumers). Held on {@link #transport} for clean shutdown. */
204
+ #tenantTransport(config) {
205
+ if (!this.#tenantTransportPromise) {
206
+ this.#tenantTransportPromise = (async () => {
207
+ const transport = await this.#resolveTransport(config, { app: this.app });
208
+ transport.useNamespace?.(config.namespace ?? 'default');
209
+ this.#transport = transport;
210
+ return transport;
211
+ })();
212
+ }
213
+ return this.#tenantTransportPromise;
214
+ }
215
+ // ---------------------------------------------------------------------------
216
+ // boot — auto-registration + responder bring-up (store roles)
217
+ // ---------------------------------------------------------------------------
77
218
  /**
78
219
  * Auto-register the `app/workflows` convention so users never call `engine.register(...)` by hand
79
- * (mirrors `@adonisjs/queue`'s `app/jobs`). Opt-out with `config.workflowsPath = false`.
220
+ * (mirrors `@adonisjs/queue`'s `app/jobs`), then serve `app/steps` for the embedded worker
221
+ * (`standalone` only), then bring up the {@link RunRequestResponder} on a P4-capable transport.
80
222
  *
81
223
  * Prefers the **build-time barrel** generated by the Assembler `init` hook
82
224
  * (`@adonis-agora/durable/hooks/workflows` → `.adonisjs/durable/workflows.js`): registering from it
83
- * avoids any runtime `readdir`. When that barrel is absent (the hook isn't registered in
84
- * `adonisrc.ts`, or it hasn't been generated yet) it FALLS BACK to the runtime directory scan, so
85
- * apps that don't opt into the hook keep working unchanged. The low-level
86
- * `engine.register(name, version, fn)` remains the escape hatch.
225
+ * avoids any runtime `readdir`. When that barrel is absent it FALLS BACK to the runtime directory scan.
226
+ *
227
+ * A `tenant` pod owns no engine, so boot is a no-op for it (a worker pod registers `app/steps` on the
228
+ * container-bound {@link WorkerRuntime} from the `durable:worker` command instead).
87
229
  */
88
230
  async boot() {
89
231
  const config = this.app.config.get('durable', {});
232
+ const role = config.role ?? 'standalone';
233
+ if (role === 'tenant')
234
+ return;
90
235
  if (config.workflowsPath === false)
91
236
  return;
92
237
  const engine = await this.app.container.make(WorkflowEngine);
@@ -99,7 +244,29 @@ export default class DurableProvider {
99
244
  const dir = this.app.makePath(config.workflowsPath ?? 'app/workflows');
100
245
  await registerWorkflowsFromDir(engine, dir);
101
246
  }
102
- await this.#registerSteps(config);
247
+ // Embedded worker: only `standalone` serves step bodies in-process (design §3). A `control-plane` is
248
+ // a pure coordinator — its step bodies run on separate tenant worker pods — so it does NOT serve
249
+ // app/steps.
250
+ if (role === 'standalone')
251
+ await this.#registerSteps(config);
252
+ await this.#startResponder();
253
+ }
254
+ /**
255
+ * Bring up the operator-side {@link RunRequestResponder} so tenant pods can round-trip read/control/
256
+ * start to this control plane — but only when the transport actually carries the P4 methods (in-process
257
+ * transports do not). The capability gate here means the responder binding is never resolved on a
258
+ * non-P4 transport, so a legacy container double never sees it.
259
+ */
260
+ async #startResponder() {
261
+ // Idempotent (singleton) — also guarantees the transport exists before the capability probe.
262
+ await this.app.container.make(WorkflowEngine);
263
+ if (!hasResponderCapability(this.#transport))
264
+ return;
265
+ const responder = (await this.app.container.make(DURABLE_RUN_REQUEST_RESPONDER));
266
+ if (!responder)
267
+ return;
268
+ responder.start();
269
+ this.#responder = responder;
103
270
  }
104
271
  /**
105
272
  * Auto-register the `app/steps` convention: every `@Step` class / `defineStep(...)` handler is
@@ -194,9 +361,13 @@ export default class DurableProvider {
194
361
  * but only when diagnostics is actually installed (its emit slot is populated at module load).
195
362
  * Gating on the slot avoids eagerly constructing the engine when diagnostics is absent; when it is
196
363
  * present, this makes durable runs visible to `onDiagnostic`, Telescope, the relays and OTel with
197
- * zero config. No hard dependency on `@adonis-agora/diagnostics`.
364
+ * zero config. No hard dependency on `@adonis-agora/diagnostics`. A `tenant` pod owns no engine, so this
365
+ * is a no-op for it.
198
366
  */
199
367
  async ready() {
368
+ const config = this.app.config.get('durable', {});
369
+ if ((config.role ?? 'standalone') === 'tenant')
370
+ return;
200
371
  const emit = globalThis[DIAGNOSTICS_EMIT];
201
372
  if (typeof emit !== 'function')
202
373
  return;
@@ -204,11 +375,15 @@ export default class DurableProvider {
204
375
  this.#detachDiagnostics = attachDurableDiagnostics(engine);
205
376
  }
206
377
  async shutdown() {
378
+ // Stop republishing tenant events before the transport connections drop.
379
+ this.#responder?.stop();
380
+ this.#responder = null;
207
381
  this.#detachDiagnostics?.();
208
382
  this.#detachDiagnostics = null;
209
383
  // Release the transport's broker workers / queues / connections so a deploy hands off cleanly.
210
384
  await this.#transport?.close?.();
211
385
  this.#transport = null;
386
+ this.#tenantTransportPromise = null;
212
387
  // Tear down the control plane's subscriber connection (Redis pub/sub) on the way out.
213
388
  await this.#controlPlane?.close?.();
214
389
  this.#controlPlane = null;
@@ -1 +1 @@
1
- {"version":3,"file":"durable_provider.js","sourceRoot":"","sources":["../../providers/durable_provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"durable_provider.js","sourceRoot":"","sources":["../../providers/durable_provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import type { BaseDurableConfig } from './define_config.js';
2
+ /**
3
+ * Role-discriminated config members for `config/durable.ts` (see
4
+ * `docs/superpowers/specs/2026-07-17-store-less-cluster-design.md` §5). The engine's topology is
5
+ * selected explicitly by `role` — never inferred — and TypeScript narrows the accepted shape on the
6
+ * `role` literal so an invalid combination (a store-less `tenant` pod that names a store) is a
7
+ * **compile error**, not a runtime assertion.
8
+ *
9
+ * These members are additive over {@link BaseDurableConfig} (today's field-for-field config): every
10
+ * existing field stays available on every role, so a config written before roles existed keeps
11
+ * type-checking and behaving identically (it lands on {@link StandaloneConfig}, the default).
12
+ */
13
+ /**
14
+ * The identity a {@link TenantVerifier} derives from a tenant's signed claim — the trust output the
15
+ * `RunRequestResponder` uses to force `namespace`/ownership on a store-less pod's requests (spec §9).
16
+ * Types only for this wave; the verification logic lands in a later wave.
17
+ */
18
+ export interface VerifiedTenant {
19
+ /** The tenant/partition the token authenticates as — the responder trusts THIS, never the body. */
20
+ tenant: string;
21
+ /** Capabilities the token grants, if the issuer scopes them. */
22
+ capabilities?: string[] | undefined;
23
+ }
24
+ /**
25
+ * Verifies a tenant's signed claim on the **responder** side (a `control-plane`), returning the
26
+ * {@link VerifiedTenant} it authenticates as — or `null`/throwing to reject a tampered/invalid token.
27
+ * A control-plane *verifies* tokens; it does not *carry* one (that is {@link TenantConfig.tenant}).
28
+ * Typed here so the config compiles; the actual signature check is a later wave (spec §9).
29
+ */
30
+ export type TenantVerifier = (input: {
31
+ /** The signed token presented on the request (absent when a pod runs token-less on prefix isolation alone). */
32
+ token?: string | undefined;
33
+ /** The tenant the request *claims* to be — advisory only; the verifier derives the real one. */
34
+ tenant?: string | undefined;
35
+ }) => VerifiedTenant | null | Promise<VerifiedTenant | null>;
36
+ /**
37
+ * Single-process engine: a control-plane **plus an embedded worker** (spec §3). The default role, so
38
+ * a config with no `role` lands here — reproducing today's single-process behavior byte-for-byte.
39
+ * `store`/`transport` stay optional (omitting them selects the in-memory store/transport — the
40
+ * zero-infra default), unlike the coordinator roles.
41
+ */
42
+ export interface StandaloneConfig extends BaseDurableConfig {
43
+ /** Optional here so a config with no `role` still type-checks and defaults to `'standalone'`. */
44
+ role?: 'standalone';
45
+ }
46
+ /**
47
+ * Pure coordinator (spec §3): owns the store, dispatches/recovers/times-out/responds, but runs **no**
48
+ * embedded worker (bodies execute on separate `tenant` worker pods). It must own a store and a
49
+ * transport, so both are required here.
50
+ */
51
+ export interface ControlPlaneConfig extends BaseDurableConfig {
52
+ role: 'control-plane';
53
+ /** A coordinator owns durable state — required (a key of {@link BaseDurableConfig.stores}). */
54
+ store: string;
55
+ /** Required — the broker the coordinator dispatches over (a key of {@link BaseDurableConfig.transports}). */
56
+ transport: string;
57
+ /**
58
+ * Responder-side verifier for tenant tokens on incoming `RunRequest`/`StartRunMessage` (spec §9).
59
+ * The control-plane *verifies* a token and derives the tenant from it; it does not carry one. Typed
60
+ * only for this wave — the verification logic is a later wave.
61
+ */
62
+ verifyTenant?: TenantVerifier;
63
+ }
64
+ /**
65
+ * Store-less "thin" pod (spec §3): a worker (`durable:worker`) or an api/dashboard pod. It NEVER owns
66
+ * a store — everything round-trips over the wire via the `ProxyRunGateway`. That isolation is a
67
+ * **compile-time fact**: `store`/`stores` are `never`, so `defineConfig({ role: 'tenant', store })`
68
+ * fails to type-check.
69
+ */
70
+ export interface TenantConfig extends BaseDurableConfig {
71
+ role: 'tenant';
72
+ /**
73
+ * FORBIDDEN — a store-less pod may not name a store. `never` makes any `store` value a compile
74
+ * error, so tenant isolation is enforced by the type system, not a runtime `if (this.store)`.
75
+ */
76
+ store?: never;
77
+ /** FORBIDDEN — likewise no store map on a store-less pod. */
78
+ stores?: never;
79
+ /** Required — the broker a tenant pod dispatches/consumes over. */
80
+ transport: string;
81
+ /** Required — which tenant this pod is; suffixes its `<name>@<tenant>` routing tokens (spec §6.1). */
82
+ partition: string;
83
+ /** The pod's signed claim, presented on every wire request (verified by the control-plane, spec §9). */
84
+ tenant?: {
85
+ token?: string;
86
+ };
87
+ /** Extra advertised features beyond registered handler names (spec §7 capability negotiation). */
88
+ capabilities?: string[];
89
+ /** `ProxyRunGateway` request timeout (ms) for a proxied read/control round-trip (spec §8). */
90
+ requestTimeoutMs?: number;
91
+ }
92
+ //# sourceMappingURL=config_types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config_types.d.ts","sourceRoot":"","sources":["../../src/config_types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;;;;;;;;;GAUG;AAEH;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,mGAAmG;IACnG,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CACrC;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE;IACnC,+GAA+G;IAC/G,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,gGAAgG;IAChG,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,KAAK,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD,iGAAiG;IACjG,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,IAAI,EAAE,eAAe,CAAC;IACtB,+FAA+F;IAC/F,KAAK,EAAE,MAAM,CAAC;IACd,6GAA6G;IAC7G,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,cAAc,CAAC;CAC/B;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAa,SAAQ,iBAAiB;IACrD,IAAI,EAAE,QAAQ,CAAC;IACf;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,6DAA6D;IAC7D,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,sGAAsG;IACtG,SAAS,EAAE,MAAM,CAAC;IAClB,wGAAwG;IACxG,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,kGAAkG;IAClG,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,8FAA8F;IAC9F,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config_types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config_types.js","sourceRoot":"","sources":["../../src/config_types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import type { NegotiationOutcome } from '../handshake/negotiate.js';
2
+ /**
3
+ * Pure presentation helpers for the fleet-health panel, shared as the single source of truth between the
4
+ * server-side `compat` handler and the dashboard's inline renderer (which mirrors these byte-for-byte).
5
+ * Kept here — not inline in the HTML — so the mapping is unit-testable and can't silently drift.
6
+ */
7
+ /** CSS class for a negotiation outcome's badge (mirrors the `.c-*` classes in `dashboard.html`). */
8
+ export declare function outcomeClass(outcome: NegotiationOutcome): string;
9
+ /** Human label for a negotiation outcome (the badge text). */
10
+ export declare function outcomeLabel(outcome: NegotiationOutcome): string;
11
+ /** Render a protocol band `[min, max]` compactly: `v1` for a single major, `v1–2` for a range. */
12
+ export declare function formatProtocolRange(range: [number, number]): string;
13
+ //# sourceMappingURL=compat-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compat-view.d.ts","sourceRoot":"","sources":["../../../src/dashboard/compat-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;;;GAIG;AAEH,oGAAoG;AACpG,wBAAgB,YAAY,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAShE;AAED,8DAA8D;AAC9D,wBAAgB,YAAY,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAShE;AAED,kGAAkG;AAClG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAEnE"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Pure presentation helpers for the fleet-health panel, shared as the single source of truth between the
3
+ * server-side `compat` handler and the dashboard's inline renderer (which mirrors these byte-for-byte).
4
+ * Kept here — not inline in the HTML — so the mapping is unit-testable and can't silently drift.
5
+ */
6
+ /** CSS class for a negotiation outcome's badge (mirrors the `.c-*` classes in `dashboard.html`). */
7
+ export function outcomeClass(outcome) {
8
+ switch (outcome) {
9
+ case 'compatible':
10
+ return 'c-ok';
11
+ case 'degraded':
12
+ return 'c-degraded';
13
+ case 'incompatible':
14
+ return 'c-bad';
15
+ }
16
+ }
17
+ /** Human label for a negotiation outcome (the badge text). */
18
+ export function outcomeLabel(outcome) {
19
+ switch (outcome) {
20
+ case 'compatible':
21
+ return 'compatible';
22
+ case 'degraded':
23
+ return 'degraded';
24
+ case 'incompatible':
25
+ return 'incompatible';
26
+ }
27
+ }
28
+ /** Render a protocol band `[min, max]` compactly: `v1` for a single major, `v1–2` for a range. */
29
+ export function formatProtocolRange(range) {
30
+ return range[0] === range[1] ? `v${range[0]}` : `v${range[0]}–${range[1]}`;
31
+ }
32
+ //# sourceMappingURL=compat-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compat-view.js","sourceRoot":"","sources":["../../../src/dashboard/compat-view.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,oGAAoG;AACpG,MAAM,UAAU,YAAY,CAAC,OAA2B;IACtD,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,YAAY;YACf,OAAO,MAAM,CAAC;QAChB,KAAK,UAAU;YACb,OAAO,YAAY,CAAC;QACtB,KAAK,cAAc;YACjB,OAAO,OAAO,CAAC;IACnB,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,YAAY,CAAC,OAA2B;IACtD,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,YAAY;YACf,OAAO,YAAY,CAAC;QACtB,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QACpB,KAAK,cAAc;YACjB,OAAO,cAAc,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,mBAAmB,CAAC,KAAuB;IACzD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7E,CAAC"}