@spine-event-engine/server 2.0.0-snapshot.23 → 2.0.0-snapshot.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -11
- package/REFERENCE.md +278 -141
- package/dist/agent/agent-acceptance-receipts.d.ts +69 -0
- package/dist/agent/agent-acceptance-receipts.d.ts.map +1 -0
- package/dist/agent/agent-acceptance-receipts.js +198 -0
- package/dist/agent/agent-acceptance-receipts.js.map +1 -0
- package/dist/agent/agent-execution-capacity.d.ts +37 -9
- package/dist/agent/agent-execution-capacity.d.ts.map +1 -1
- package/dist/agent/agent-execution-capacity.js +73 -15
- package/dist/agent/agent-execution-capacity.js.map +1 -1
- package/dist/agent/agent-history.d.ts +15 -10
- package/dist/agent/agent-history.d.ts.map +1 -1
- package/dist/agent/agent-history.js +26 -14
- package/dist/agent/agent-history.js.map +1 -1
- package/dist/agent/agent-live-ai-audit.d.ts +95 -0
- package/dist/agent/agent-live-ai-audit.d.ts.map +1 -0
- package/dist/agent/agent-live-ai-audit.js +290 -0
- package/dist/agent/agent-live-ai-audit.js.map +1 -0
- package/dist/agent/agent-live-ai-runtime.d.ts +300 -0
- package/dist/agent/agent-live-ai-runtime.d.ts.map +1 -0
- package/dist/agent/agent-live-ai-runtime.js +611 -0
- package/dist/agent/agent-live-ai-runtime.js.map +1 -0
- package/dist/agent/agent-live-audit.d.ts +67 -0
- package/dist/agent/agent-live-audit.d.ts.map +1 -0
- package/dist/agent/agent-live-audit.js +121 -0
- package/dist/agent/agent-live-audit.js.map +1 -0
- package/dist/agent/agent-live-budget.d.ts +84 -0
- package/dist/agent/agent-live-budget.d.ts.map +1 -0
- package/dist/agent/agent-live-budget.js +161 -0
- package/dist/agent/agent-live-budget.js.map +1 -0
- package/dist/agent/agent-live-fault.d.ts +18 -0
- package/dist/agent/agent-live-fault.d.ts.map +1 -0
- package/dist/agent/{agent-execution-fault.js → agent-live-fault.js} +7 -7
- package/dist/agent/agent-live-fault.js.map +1 -0
- package/dist/agent/agent-live-inputs.d.ts +74 -0
- package/dist/agent/agent-live-inputs.d.ts.map +1 -0
- package/dist/agent/agent-live-inputs.js +15 -0
- package/dist/agent/agent-live-inputs.js.map +1 -0
- package/dist/agent/agent-live-interaction-events.d.ts +46 -0
- package/dist/agent/agent-live-interaction-events.d.ts.map +1 -0
- package/dist/agent/agent-live-interaction-events.js +104 -0
- package/dist/agent/agent-live-interaction-events.js.map +1 -0
- package/dist/agent/agent-live-mcp-controls.d.ts +129 -0
- package/dist/agent/agent-live-mcp-controls.d.ts.map +1 -0
- package/dist/agent/agent-live-mcp-controls.js +228 -0
- package/dist/agent/agent-live-mcp-controls.js.map +1 -0
- package/dist/agent/agent-live-mcp-host.d.ts +88 -0
- package/dist/agent/agent-live-mcp-host.d.ts.map +1 -0
- package/dist/agent/{agent-mcp-host.js → agent-live-mcp-host.js} +1 -1
- package/dist/agent/agent-live-mcp-host.js.map +1 -0
- package/dist/agent/{agent-mcp-runtime.d.ts → agent-live-mcp-runtime.d.ts} +6 -6
- package/dist/agent/agent-live-mcp-runtime.d.ts.map +1 -0
- package/dist/agent/{agent-mcp-runtime.js → agent-live-mcp-runtime.js} +13 -42
- package/dist/agent/agent-live-mcp-runtime.js.map +1 -0
- package/dist/agent/agent-live-read-runtime.d.ts +61 -0
- package/dist/agent/agent-live-read-runtime.d.ts.map +1 -0
- package/dist/agent/agent-live-read-runtime.js +121 -0
- package/dist/agent/agent-live-read-runtime.js.map +1 -0
- package/dist/agent/agent-model-selection.d.ts +21 -34
- package/dist/agent/agent-model-selection.d.ts.map +1 -1
- package/dist/agent/agent-model-selection.js +61 -78
- package/dist/agent/agent-model-selection.js.map +1 -1
- package/dist/bus/command-bus.d.ts +14 -18
- package/dist/bus/command-bus.d.ts.map +1 -1
- package/dist/bus/command-bus.js +31 -48
- package/dist/bus/command-bus.js.map +1 -1
- package/dist/bus/event-bus.d.ts +82 -104
- package/dist/bus/event-bus.d.ts.map +1 -1
- package/dist/bus/event-bus.js +87 -127
- package/dist/bus/event-bus.js.map +1 -1
- package/dist/context/bounded-context.d.ts +143 -91
- package/dist/context/bounded-context.d.ts.map +1 -1
- package/dist/context/bounded-context.js +753 -359
- package/dist/context/bounded-context.js.map +1 -1
- package/dist/context/entity-inbox.d.ts +7 -2
- package/dist/context/entity-inbox.d.ts.map +1 -1
- package/dist/context/entity-inbox.js +43 -20
- package/dist/context/entity-inbox.js.map +1 -1
- package/dist/context/local-inbox-handoff.d.ts +35 -34
- package/dist/context/local-inbox-handoff.d.ts.map +1 -1
- package/dist/context/local-inbox-handoff.js +123 -135
- package/dist/context/local-inbox-handoff.js.map +1 -1
- package/dist/context/projection-handoff.d.ts +2 -2
- package/dist/context/projection-handoff.d.ts.map +1 -1
- package/dist/context/projection-handoff.js +12 -8
- package/dist/context/projection-handoff.js.map +1 -1
- package/dist/context/tenant-index.d.ts +36 -31
- package/dist/context/tenant-index.d.ts.map +1 -1
- package/dist/context/tenant-index.js +123 -125
- package/dist/context/tenant-index.js.map +1 -1
- package/dist/context/tenant-unknown-error.d.ts +33 -0
- package/dist/context/tenant-unknown-error.d.ts.map +1 -0
- package/dist/context/tenant-unknown-error.js +75 -0
- package/dist/context/tenant-unknown-error.js.map +1 -0
- package/dist/delivery/agent-delivery-scope.d.ts +66 -0
- package/dist/delivery/agent-delivery-scope.d.ts.map +1 -0
- package/dist/delivery/agent-delivery-scope.js +44 -0
- package/dist/delivery/agent-delivery-scope.js.map +1 -0
- package/dist/delivery/delivery-builder.d.ts +25 -1
- package/dist/delivery/delivery-builder.d.ts.map +1 -1
- package/dist/delivery/delivery-builder.js +89 -0
- package/dist/delivery/delivery-builder.js.map +1 -1
- package/dist/delivery/delivery-monitor.d.ts +12 -9
- package/dist/delivery/delivery-monitor.d.ts.map +1 -1
- package/dist/delivery/delivery-monitor.js +15 -9
- package/dist/delivery/delivery-monitor.js.map +1 -1
- package/dist/delivery/delivery-ports.d.ts +6 -13
- package/dist/delivery/delivery-ports.d.ts.map +1 -1
- package/dist/delivery/delivery-run-control.d.ts +21 -0
- package/dist/delivery/delivery-run-control.d.ts.map +1 -1
- package/dist/delivery/delivery-run-control.js +10 -0
- package/dist/delivery/delivery-run-control.js.map +1 -1
- package/dist/delivery/delivery-supervisor.d.ts +33 -5
- package/dist/delivery/delivery-supervisor.d.ts.map +1 -1
- package/dist/delivery/delivery-supervisor.js +178 -26
- package/dist/delivery/delivery-supervisor.js.map +1 -1
- package/dist/delivery/delivery-tenant.d.ts +17 -0
- package/dist/delivery/delivery-tenant.d.ts.map +1 -0
- package/dist/delivery/delivery-tenant.js +50 -0
- package/dist/delivery/delivery-tenant.js.map +1 -0
- package/dist/delivery/delivery.d.ts +96 -2
- package/dist/delivery/delivery.d.ts.map +1 -1
- package/dist/delivery/delivery.js +803 -89
- package/dist/delivery/delivery.js.map +1 -1
- package/dist/delivery/inbox-records.d.ts.map +1 -1
- package/dist/delivery/inbox-records.js +9 -16
- package/dist/delivery/inbox-records.js.map +1 -1
- package/dist/delivery/inbox-storage.d.ts +14 -11
- package/dist/delivery/inbox-storage.d.ts.map +1 -1
- package/dist/delivery/inbox-storage.js +72 -78
- package/dist/delivery/inbox-storage.js.map +1 -1
- package/dist/delivery/inbox.d.ts +9 -12
- package/dist/delivery/inbox.d.ts.map +1 -1
- package/dist/delivery/inbox.js +13 -15
- package/dist/delivery/inbox.js.map +1 -1
- package/dist/delivery/reception-observation.d.ts +64 -0
- package/dist/delivery/reception-observation.d.ts.map +1 -0
- package/dist/delivery/reception-observation.js +78 -0
- package/dist/delivery/reception-observation.js.map +1 -0
- package/dist/delivery/sharded-work-registry.d.ts +6 -0
- package/dist/delivery/sharded-work-registry.d.ts.map +1 -1
- package/dist/delivery/sharded-work-registry.js +41 -4
- package/dist/delivery/sharded-work-registry.js.map +1 -1
- package/dist/entity/entity-storage-descriptor.d.ts.map +1 -1
- package/dist/entity/entity-storage-descriptor.js +7 -4
- package/dist/entity/entity-storage-descriptor.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/integration/external-messages.d.ts.map +1 -1
- package/dist/integration/external-messages.js +9 -15
- package/dist/integration/external-messages.js.map +1 -1
- package/dist/integration/integration-broker.d.ts.map +1 -1
- package/dist/integration/integration-broker.js +112 -6
- package/dist/integration/integration-broker.js.map +1 -1
- package/dist/integration/third-party-context.d.ts.map +1 -1
- package/dist/integration/third-party-context.js +7 -10
- package/dist/integration/third-party-context.js.map +1 -1
- package/dist/repository/primitive-id.js +26 -11
- package/dist/repository/primitive-id.js.map +1 -1
- package/dist/repository/repository.d.ts +33 -62
- package/dist/repository/repository.d.ts.map +1 -1
- package/dist/repository/repository.js +1475 -1827
- package/dist/repository/repository.js.map +1 -1
- package/dist/runtime/runtime.d.ts +24 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +31 -0
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/signal-metadata.d.ts.map +1 -1
- package/dist/runtime/signal-metadata.js +8 -15
- package/dist/runtime/signal-metadata.js.map +1 -1
- package/dist/runtime/signal-publisher.d.ts +8 -36
- package/dist/runtime/signal-publisher.d.ts.map +1 -1
- package/dist/runtime/signal-publisher.js +68 -61
- package/dist/runtime/signal-publisher.js.map +1 -1
- package/dist/runtime/standalone-handler-runtime.d.ts +0 -7
- package/dist/runtime/standalone-handler-runtime.d.ts.map +1 -1
- package/dist/runtime/standalone-handler-runtime.js +14 -130
- package/dist/runtime/standalone-handler-runtime.js.map +1 -1
- package/dist/server/managed-delivery-gate.d.ts +34 -0
- package/dist/server/managed-delivery-gate.d.ts.map +1 -0
- package/dist/server/managed-delivery-gate.js +70 -0
- package/dist/server/managed-delivery-gate.js.map +1 -0
- package/dist/server/managed-server-application.d.ts +2 -2
- package/dist/server/managed-server-application.d.ts.map +1 -1
- package/dist/server/managed-server-application.js +471 -178
- package/dist/server/managed-server-application.js.map +1 -1
- package/dist/server/node-coordinator.d.ts +14 -0
- package/dist/server/node-coordinator.d.ts.map +1 -1
- package/dist/server/node-coordinator.js +266 -45
- package/dist/server/node-coordinator.js.map +1 -1
- package/dist/server/server-environment.d.ts +203 -25
- package/dist/server/server-environment.d.ts.map +1 -1
- package/dist/server/server-environment.js +661 -133
- package/dist/server/server-environment.js.map +1 -1
- package/dist/server/server-log.d.ts +7 -0
- package/dist/server/server-log.d.ts.map +1 -1
- package/dist/server/server-log.js +18 -1
- package/dist/server/server-log.js.map +1 -1
- package/dist/server/server.d.ts +18 -32
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +62 -203
- package/dist/server/server.js.map +1 -1
- package/dist/services/spine-services.d.ts +1 -1
- package/dist/services/spine-services.d.ts.map +1 -1
- package/dist/services/spine-services.js +399 -370
- package/dist/services/spine-services.js.map +1 -1
- package/dist/stand/event-origin-filter.d.ts +16 -0
- package/dist/stand/event-origin-filter.d.ts.map +1 -0
- package/dist/stand/event-origin-filter.js +124 -0
- package/dist/stand/event-origin-filter.js.map +1 -0
- package/dist/stand/stand.d.ts +14 -0
- package/dist/stand/stand.d.ts.map +1 -1
- package/dist/stand/stand.js +53 -9
- package/dist/stand/stand.js.map +1 -1
- package/dist/stand/subscription-observer.d.ts.map +1 -1
- package/dist/stand/subscription-observer.js +61 -40
- package/dist/stand/subscription-observer.js.map +1 -1
- package/dist/stand/subscription-registry.d.ts +6 -2
- package/dist/stand/subscription-registry.d.ts.map +1 -1
- package/dist/stand/subscription-registry.js +15 -11
- package/dist/stand/subscription-registry.js.map +1 -1
- package/dist/stand/subscription-runtime.d.ts +23 -4
- package/dist/stand/subscription-runtime.d.ts.map +1 -1
- package/dist/stand/subscription-runtime.js +84 -13
- package/dist/stand/subscription-runtime.js.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +3 -2
- package/dist/testing/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -15
- package/dist/agent/agent-admission.d.ts +0 -80
- package/dist/agent/agent-admission.d.ts.map +0 -1
- package/dist/agent/agent-admission.js +0 -127
- package/dist/agent/agent-admission.js.map +0 -1
- package/dist/agent/agent-ai-runtime.d.ts +0 -76
- package/dist/agent/agent-ai-runtime.d.ts.map +0 -1
- package/dist/agent/agent-ai-runtime.js +0 -1269
- package/dist/agent/agent-ai-runtime.js.map +0 -1
- package/dist/agent/agent-execution-fault.d.ts +0 -18
- package/dist/agent/agent-execution-fault.d.ts.map +0 -1
- package/dist/agent/agent-execution-fault.js.map +0 -1
- package/dist/agent/agent-execution-session.d.ts +0 -103
- package/dist/agent/agent-execution-session.d.ts.map +0 -1
- package/dist/agent/agent-execution-session.js +0 -238
- package/dist/agent/agent-execution-session.js.map +0 -1
- package/dist/agent/agent-interaction-audit.d.ts +0 -58
- package/dist/agent/agent-interaction-audit.d.ts.map +0 -1
- package/dist/agent/agent-interaction-audit.js +0 -114
- package/dist/agent/agent-interaction-audit.js.map +0 -1
- package/dist/agent/agent-interaction-events.d.ts +0 -40
- package/dist/agent/agent-interaction-events.d.ts.map +0 -1
- package/dist/agent/agent-interaction-events.js +0 -129
- package/dist/agent/agent-interaction-events.js.map +0 -1
- package/dist/agent/agent-mcp-budget.d.ts +0 -125
- package/dist/agent/agent-mcp-budget.d.ts.map +0 -1
- package/dist/agent/agent-mcp-budget.js +0 -566
- package/dist/agent/agent-mcp-budget.js.map +0 -1
- package/dist/agent/agent-mcp-host.d.ts +0 -125
- package/dist/agent/agent-mcp-host.d.ts.map +0 -1
- package/dist/agent/agent-mcp-host.js.map +0 -1
- package/dist/agent/agent-mcp-runtime.d.ts.map +0 -1
- package/dist/agent/agent-mcp-runtime.js.map +0 -1
- package/dist/agent/agent-read-runtime.d.ts +0 -70
- package/dist/agent/agent-read-runtime.d.ts.map +0 -1
- package/dist/agent/agent-read-runtime.js +0 -320
- package/dist/agent/agent-read-runtime.js.map +0 -1
- package/dist/agent/agent-revisions.d.ts +0 -35
- package/dist/agent/agent-revisions.d.ts.map +0 -1
- package/dist/agent/agent-revisions.js +0 -133
- package/dist/agent/agent-revisions.js.map +0 -1
- package/dist/agent/agent-scheduler.d.ts +0 -99
- package/dist/agent/agent-scheduler.d.ts.map +0 -1
- package/dist/agent/agent-scheduler.js +0 -398
- package/dist/agent/agent-scheduler.js.map +0 -1
- package/dist/bus/saved-dispatcher-binding.d.ts +0 -96
- package/dist/bus/saved-dispatcher-binding.d.ts.map +0 -1
- package/dist/bus/saved-dispatcher-binding.js +0 -35
- package/dist/bus/saved-dispatcher-binding.js.map +0 -1
- package/dist/delivery/delivery-run-coordinator.d.ts +0 -218
- package/dist/delivery/delivery-run-coordinator.d.ts.map +0 -1
- package/dist/delivery/delivery-run-coordinator.js +0 -609
- package/dist/delivery/delivery-run-coordinator.js.map +0 -1
- package/dist/delivery/parked-delivery-obligations.d.ts +0 -182
- package/dist/delivery/parked-delivery-obligations.d.ts.map +0 -1
- package/dist/delivery/parked-delivery-obligations.js +0 -390
- package/dist/delivery/parked-delivery-obligations.js.map +0 -1
- package/dist/server/environment-attachment.d.ts +0 -356
- package/dist/server/environment-attachment.d.ts.map +0 -1
- package/dist/server/environment-attachment.js +0 -2062
- package/dist/server/environment-attachment.js.map +0 -1
- package/dist/server/environment-delivery-records.d.ts +0 -77
- package/dist/server/environment-delivery-records.d.ts.map +0 -1
- package/dist/server/environment-delivery-records.js +0 -282
- package/dist/server/environment-delivery-records.js.map +0 -1
- package/dist/server/environment-delivery-worker.d.ts +0 -161
- package/dist/server/environment-delivery-worker.d.ts.map +0 -1
- package/dist/server/environment-delivery-worker.js +0 -673
- package/dist/server/environment-delivery-worker.js.map +0 -1
package/REFERENCE.md
CHANGED
|
@@ -33,7 +33,7 @@ versioned registries are rejected and must be regenerated.
|
|
|
33
33
|
Generated standalone handlers extend `AbstractAssignee`, `AbstractCommander`,
|
|
34
34
|
`AbstractEventReactor`, or `AbstractEventSubscriber`. Register instances with
|
|
35
35
|
`addAssignee()`, `addCommandDispatcher()`, or `addEventDispatcher()` as their
|
|
36
|
-
role requires, then use `
|
|
36
|
+
role requires, then use `build()` to load generated receiver metadata and
|
|
37
37
|
match the exact constructor. Assignees consume Commands and produce Events;
|
|
38
38
|
commanders consume Commands, Events, or rejections and produce Commands;
|
|
39
39
|
reactors consume Events or rejections and may produce Events; subscribers
|
|
@@ -139,7 +139,8 @@ valid event with no interested external receptor is simply not delivered.
|
|
|
139
139
|
## Server environment facilities
|
|
140
140
|
|
|
141
141
|
`ServerEnvironment.instance()` is a process-wide singleton. Production
|
|
142
|
-
resolution requires
|
|
142
|
+
resolution requires the complete application schema registry; storage defaults to
|
|
143
|
+
in-memory when `storageFactory` is omitted:
|
|
143
144
|
|
|
144
145
|
```ts
|
|
145
146
|
import { EnvironmentType, ServerEnvironment } from "@spine-event-engine/server";
|
|
@@ -153,9 +154,52 @@ ServerEnvironment.when(EnvironmentType.Production).use({
|
|
|
153
154
|
storageFactory,
|
|
154
155
|
typeRegistry,
|
|
155
156
|
});
|
|
157
|
+
await ServerEnvironment.instance().completeSetup();
|
|
156
158
|
```
|
|
157
159
|
|
|
158
|
-
`
|
|
160
|
+
Call `completeSetup()` explicitly before building any Bounded Context. It
|
|
161
|
+
checks the storage connection, initializes integration transport, and opens the
|
|
162
|
+
shared Delivery. Concurrent callers join one setup attempt; a failed attempt
|
|
163
|
+
closes acquired facilities and prevents context assembly. Building a context
|
|
164
|
+
does not start setup. The environment logs an INFO message after each successful
|
|
165
|
+
phase without implying that every Entity model has been prepared.
|
|
166
|
+
|
|
167
|
+
`BoundedContextBuilder.build({ createStorageStructures, startSubscriptionMonitoring })`
|
|
168
|
+
awaits both model preparation and the first subscription reconciliation by
|
|
169
|
+
default. Each option can be set to `false` independently. A deferred phase runs
|
|
170
|
+
before the first valid Command, Event, query, subscription operation, or Inbox
|
|
171
|
+
replay for the receiving context; lazy multitenant preparation selects only that
|
|
172
|
+
input's currently registered tenant. A failed lazy attempt rejects its current
|
|
173
|
+
input and can be retried by a later input. Monitoring requires the shared
|
|
174
|
+
subscription registry, so `startSubscriptionMonitoring: true` prepares that
|
|
175
|
+
registry even when `createStorageStructures: false`; it does not prepare all
|
|
176
|
+
tenant Entity families. An eager required preparation or initial monitoring
|
|
177
|
+
failure stops accepting new input and triggers attempt-all cleanup.
|
|
178
|
+
After a successful first pass, a failed periodic reconciliation logs a WARN
|
|
179
|
+
with the context name and bounded error name or code, leaves unaffected observers active,
|
|
180
|
+
and retries on the existing ten-second schedule. Closing the context cancels
|
|
181
|
+
the timer and drains an admitted pass before detaching observers.
|
|
182
|
+
|
|
183
|
+
`context.runtime.createStorageStructures(...tenantIds)` and
|
|
184
|
+
`context.runtime.checkStructureCompatibility(...tenantIds)` prepare declared
|
|
185
|
+
Record, Entity, history, and Agent audit structures through the configured
|
|
186
|
+
provider. The check is read-only; a successful provider check also satisfies
|
|
187
|
+
later creation readiness. Explicit IDs must be registered in the context's
|
|
188
|
+
effective tenant index. With no IDs, a multitenant context traverses its current
|
|
189
|
+
index in finite pages; a single-tenant context prepares its neutral destination
|
|
190
|
+
without registering a synthetic tenant. `context.runtime.startSubscriptionMonitoring()`
|
|
191
|
+
performs the first registry pass independently of per-tenant Entity preparation.
|
|
192
|
+
The environment's no-argument structure methods include both kinds of completed,
|
|
193
|
+
open context. With explicit IDs, they select only matching multitenant contexts,
|
|
194
|
+
respect each `withTenantIndex` override, and reject an ID absent from all current
|
|
195
|
+
indexes before provider work. They validate every supplied ID before preparing
|
|
196
|
+
any structures. Database-backed providers require an existing database; these
|
|
197
|
+
calls do not provision one or register a tenant. Required explicit provider or initial-monitor
|
|
198
|
+
failure stops new input and triggers automatic cleanup. Unknown or malformed IDs,
|
|
199
|
+
directory lookup failure, and local API misuse reject only that operation;
|
|
200
|
+
lazy first-input provider failures remain request-local and retryable.
|
|
201
|
+
|
|
202
|
+
`storageFactory` supplies records and events to every context. `typeRegistry` is the complete
|
|
159
203
|
application schema universe used by `ThirdPartyContext` to encode outgoing
|
|
160
204
|
imported events. An optional `integrationChannelFactory` overrides the
|
|
161
205
|
process-wide private
|
|
@@ -164,6 +208,26 @@ contexts share one in-memory factory, including in production. Local and test
|
|
|
164
208
|
environments default storage in memory and use the core registry only as a
|
|
165
209
|
fallback; those defaults are not production configuration.
|
|
166
210
|
|
|
211
|
+
`tenantIndex` selects a live application membership directory. When omitted,
|
|
212
|
+
the environment uses its storage factory's native catalog where available, or
|
|
213
|
+
a transient in-memory index for a custom factory without a catalog. The
|
|
214
|
+
transient index lasts only for this environment instance. `contains()` checks
|
|
215
|
+
membership without preparing storage; `keep()` makes a registration visible to
|
|
216
|
+
later reads and may reject for a read-only catalog. PostgreSQL and MySQL
|
|
217
|
+
catalogs expose only configured tenant entries: `keep()` is idempotent for
|
|
218
|
+
those entries and rejects unknown IDs. A dynamic SQL tenant resolver does not
|
|
219
|
+
register or enumerate tenants. Single-tenant contexts do not insert a synthetic
|
|
220
|
+
member into this directory.
|
|
221
|
+
|
|
222
|
+
Multitenant receiving contexts check current index membership before Command,
|
|
223
|
+
Event, query, direct repository/history, and subscription work. Inbox persistence
|
|
224
|
+
and later replay check separately, so removing a tenant prevents saved work from
|
|
225
|
+
restoring it. Input does not call `keep()` implicitly. A confirmed missing member
|
|
226
|
+
raises `TenantUnknownError` with the complete tenant ID and context name; native
|
|
227
|
+
services return `NotFound` with a structured `spine.base.Error` detail whose type
|
|
228
|
+
is `TENANT_UNKNOWN`. Lookup failures remain operational errors. Single-tenant
|
|
229
|
+
work does not consult the directory.
|
|
230
|
+
|
|
167
231
|
To override the default channel factory, add
|
|
168
232
|
`integrationChannelFactory: customFactory` to the same settings object.
|
|
169
233
|
|
|
@@ -265,8 +329,8 @@ callbacks receive that scope as their third argument while they run.
|
|
|
265
329
|
|
|
266
330
|
For contexts registered with one `Server`, the target Entity's type URL selects
|
|
267
331
|
its context. No context name or network request is required. The Server rejects
|
|
268
|
-
duplicate Entity type registrations before
|
|
269
|
-
|
|
332
|
+
duplicate Entity type registrations before opening the listener, identifying
|
|
333
|
+
the type and both contexts. Contexts used without a
|
|
270
334
|
Server retain local querying; separate Servers do not share query routes.
|
|
271
335
|
|
|
272
336
|
Cross-context targets must declare `query` or `full` visibility. This applies
|
|
@@ -282,9 +346,11 @@ partition in a multitenant destination. The query never replaces the tenant to
|
|
|
282
346
|
suit the target. A valid query with no matching record keeps its ordinary empty
|
|
283
347
|
result (`undefined` from `findById()`). Reads remain eventually consistent.
|
|
284
348
|
|
|
285
|
-
Routes are available before
|
|
286
|
-
|
|
287
|
-
|
|
349
|
+
Routes are available before ordinary Inbox work resumes. An accepted Agent
|
|
350
|
+
interaction never resumes after interruption; a fresh signal starts fresh work.
|
|
351
|
+
Server shutdown drains admitted handlers across contexts before closing any
|
|
352
|
+
target read-side; failed startup validation participates in context and
|
|
353
|
+
resource cleanup.
|
|
288
354
|
|
|
289
355
|
```ts
|
|
290
356
|
import type { Message } from "@bufbuild/protobuf";
|
|
@@ -506,7 +572,7 @@ const repository = new Repository<typeof ApprovalCoordinator>({
|
|
|
506
572
|
schema: CoordinationStateSchema,
|
|
507
573
|
handlers: handlers as EntityHandlersMetadata<ApprovalCoordinator, typeof CoordinationStateSchema>,
|
|
508
574
|
});
|
|
509
|
-
const context = BoundedContext.singleTenant("Projects").add(repository).build();
|
|
575
|
+
const context = await BoundedContext.singleTenant("Projects").add(repository).build();
|
|
510
576
|
await context.commandBus().post(
|
|
511
577
|
SignalEnvelopes.command({
|
|
512
578
|
context: create(CommandContextSchema),
|
|
@@ -521,7 +587,7 @@ The generated record declares `ApproveProjectSchema` as the input and
|
|
|
521
587
|
manual decorator materialization, constructs the output-bearing metadata.
|
|
522
588
|
Application builds emit the record to
|
|
523
589
|
`generated/handler/generated-handler-registry.js`; those applications use
|
|
524
|
-
`
|
|
590
|
+
`build()` with their compiled package root.
|
|
525
591
|
|
|
526
592
|
One `@Where({ eventField, equals })` equality filter may narrow an event- or
|
|
527
593
|
rejection-consuming `@Subscribe`, `@React`, or `@Command` handler after type
|
|
@@ -531,18 +597,24 @@ repeated declarations fail closed. It is not an alternative routing mechanism.
|
|
|
531
597
|
Configure logging through `ServerEnvironment` when assembling the server. The
|
|
532
598
|
server installs that logger into its runtime components, where warnings and
|
|
533
599
|
failures carry operation context. Durable facts belong in events or storage.
|
|
534
|
-
|
|
535
|
-
path, so handler effects must be
|
|
600
|
+
Ordinary Aggregate, Process Manager, and Projection Inbox replay sends persisted
|
|
601
|
+
accepted work through the normal handler path, so those handler effects must be
|
|
602
|
+
replay-safe. An accepted Agent interaction is recorded by its receipt and is
|
|
603
|
+
never re-executed after interruption.
|
|
536
604
|
|
|
537
605
|
## Context assembly and entities
|
|
538
606
|
|
|
539
607
|
Create a context with `BoundedContext.singleTenant(name)` or
|
|
540
608
|
`BoundedContext.multitenant(name)`. Names are immutable. Use
|
|
541
|
-
`
|
|
609
|
+
`ServerEnvironment.when(type).use({ storageFactory: factory })` before explicit
|
|
610
|
+
environment setup to supply record/event storage to all contexts.
|
|
611
|
+
`withTenantIndex(index)` selects a different live membership directory for one
|
|
612
|
+
context; `context.tenantIndex` and `ServerEnvironment.instance().tenantIndex`
|
|
613
|
+
return the configured objects. Closing a context does not close either index.
|
|
542
614
|
`withGeneratedRegistryRoot(root)` enables framework discovery of the generated
|
|
543
615
|
handler registry for classes registered with `add(EntityClass)`;
|
|
544
|
-
`
|
|
545
|
-
explicit `Repository` registration. A built context contains `CommandBus`,
|
|
616
|
+
`build()` asynchronously performs that discovery and assembly, including
|
|
617
|
+
explicit `Repository` registration. Await it before using the context. A built context contains `CommandBus`,
|
|
546
618
|
`EventBus`, `Stand`, repositories, and its storage lifecycle.
|
|
547
619
|
Trusted server-side code can call `context.getRepository(EntityClass)` to obtain
|
|
548
620
|
the already registered repository for that exact constructor. The lookup does
|
|
@@ -654,24 +726,24 @@ start a new autonomous Entity loop.
|
|
|
654
726
|
### Configuration
|
|
655
727
|
|
|
656
728
|
Register a factory-created `AiRegistry`, enable `persistSystemEvents()`, and
|
|
657
|
-
configure `
|
|
729
|
+
configure `ai.models` for each Agent repository. Use
|
|
658
730
|
an empty `models` array when that Agent has no model calls. Readiness requires
|
|
659
|
-
indexed Agent history and
|
|
731
|
+
indexed Agent history and atomic live Agent commits from the selected provider.
|
|
660
732
|
The [Support Bounded Context](../../examples/support/src/index.ts) uses generated
|
|
661
733
|
registration with these options.
|
|
662
734
|
|
|
663
735
|
Configuration has these scopes:
|
|
664
736
|
|
|
665
|
-
| Scope | Setting
|
|
666
|
-
| --------------- |
|
|
667
|
-
|
|
|
668
|
-
| Bounded Context | `BoundedContextBuilder.withAi(registry)`
|
|
669
|
-
| Repository | `ai.defaultModels`
|
|
670
|
-
| Repository | `ai.allowedModels`
|
|
671
|
-
| Repository | `ai.resolveModel`
|
|
672
|
-
| Repository | `ai.authorizeSelection`
|
|
673
|
-
| Repository | `ai.invocationLimits`
|
|
674
|
-
| Instance | `this.ai.select(kind, ref)`
|
|
737
|
+
| Scope | Setting | Effect |
|
|
738
|
+
| --------------- | ------------------------------------------ | ---------------------------------------------------------------- |
|
|
739
|
+
| Environment | `ServerEnvironment.when(type).use({ ai })` | Default registry for Bounded Contexts. |
|
|
740
|
+
| Bounded Context | `BoundedContextBuilder.withAi(registry)` | Overrides environment AI for one Bounded Context. |
|
|
741
|
+
| Repository | `ai.defaultModels` | Generation and decision defaults before the registry's defaults. |
|
|
742
|
+
| Repository | `ai.allowedModels` | Deployment references the Agent may use. |
|
|
743
|
+
| Repository | `ai.resolveModel` | Optional accepted-source choice before the Agent handler. |
|
|
744
|
+
| Repository | `ai.authorizeSelection` | Authorizes explicit choices and staged preference changes. |
|
|
745
|
+
| Repository | `ai.invocationLimits` | Limits that can narrow the registry's whole-signal limits. |
|
|
746
|
+
| Instance | `this.ai.select(kind, ref)` | A saved preference applied to later accepted signals. |
|
|
675
747
|
|
|
676
748
|
A prebuilt Bounded Context already has its registry; adding it to a server does not
|
|
677
749
|
reconfigure it. An instance preference takes precedence over its repository
|
|
@@ -687,7 +759,7 @@ signal; `undefined` preserves it. This allows an Agent without a configured
|
|
|
687
759
|
default to start after a deployment is appended to the bound registry. The
|
|
688
760
|
runtime checks repository allowlists, capabilities and `authorizeSelection`
|
|
689
761
|
before saving the selection and connection identity. A saved selection is reused
|
|
690
|
-
|
|
762
|
+
for the current signal. Resolver and authorization callbacks receive linked cancellation
|
|
691
763
|
and the smaller of the invocation deadline and registry hook timeout. An
|
|
692
764
|
effective `this.ai.select()` change, including reset to inheritance, is
|
|
693
765
|
authorized before the Entity transition and preference Events commit; a no-op
|
|
@@ -702,59 +774,30 @@ See [adapter configuration](../ai-vercel-ax/README.md).
|
|
|
702
774
|
|
|
703
775
|
### Acceptance and completion
|
|
704
776
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
Bounded Contexts using
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
starts, recovery continues with the saved deadline and counts. The same deadline
|
|
713
|
-
bounds an awaited application handler. Expiry or Bounded Context shutdown ends that wait
|
|
714
|
-
and prevents late handler results from changing Entity state or emitting signals;
|
|
715
|
-
it cannot stop arbitrary application JavaScript or undo external effects.
|
|
716
|
-
|
|
717
|
-
Newly accepted work supplies its repository and tenant to prompt discovery.
|
|
718
|
-
Periodic discovery reads tenant pages and constructs repository scopes as they
|
|
719
|
-
are needed. It retains at most one page of 16 tenants, four periodic scan scopes,
|
|
720
|
-
and 64 scopes awaiting a prompt scan. A turn requests at most one tenant page
|
|
721
|
-
and reads at most four pending-work pages. It does not load the complete tenant
|
|
722
|
-
catalog or retain a scan position for every tenant.
|
|
723
|
-
|
|
724
|
-
A sweep finishes before another begins. The next starts no earlier than five
|
|
725
|
-
seconds after the preceding sweep started, measured by `Time`; longer sweeps
|
|
726
|
-
restart after completion. This lets discovery reach tenants near the end of a
|
|
727
|
-
large catalog and find later admissions on the next sweep. Periodic scans keep
|
|
728
|
-
their turn during new arrivals, including while execution capacity is full.
|
|
729
|
-
A pending catalog request does not block prompt scans of known scopes.
|
|
730
|
-
|
|
731
|
-
Bounded Context shutdown stops waiting for discovery reads even if a provider ignores
|
|
732
|
-
cancellation. Late results cannot submit work or restart scanning. Built-in
|
|
733
|
-
adapters use their available cancellation and timeout controls; detaching the
|
|
734
|
-
scheduler does not guarantee cancellation of an already issued native request.
|
|
777
|
+
An accepted signal and recipient are admitted through ordinary Delivery. A
|
|
778
|
+
typed receipt prevents a duplicate signal from starting the same Agent turn.
|
|
779
|
+
Within one process, live capacity serializes turns for one Agent instance and
|
|
780
|
+
permits different instances up to configured limits. The shared registry's
|
|
781
|
+
capacity applies across Bounded Contexts using that registry. A waiting signal
|
|
782
|
+
stays in the ordinary Inbox until capacity can admit it; capacity release wakes
|
|
783
|
+
the ordinary Delivery worker. There is no Agent-specific discovery scheduler.
|
|
735
784
|
|
|
736
785
|
The signal's matching handlers share one Entity draft. Each handler can await
|
|
737
|
-
`this.ai.invoke()` through the protected Spine facade. Calls in one handler
|
|
738
|
-
be sequential and finish before it returns. Requests, results and
|
|
739
|
-
validation failures are saved as
|
|
740
|
-
state, Version,
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
Downstream delivery is at least once: a recipient or standalone callback may be
|
|
753
|
-
called again with the same envelope. Application effects must account for that.
|
|
754
|
-
Generated repository and standalone receivers have the required binding metadata.
|
|
755
|
-
Matching raw custom dispatchers without that metadata are rejected for Agent
|
|
756
|
-
output; unrelated dispatchers and ordinary non-Agent posting keep their usual
|
|
757
|
-
behavior.
|
|
786
|
+
`this.ai.invoke()` through the protected Spine facade. Calls in one handler
|
|
787
|
+
must be sequential and finish before it returns. Requests, results, and
|
|
788
|
+
validation failures are saved as audited history while work progresses. The
|
|
789
|
+
final accepted state, Version, preference changes, and Agent history use an
|
|
790
|
+
atomic live Agent commit. Outgoing Commands enter ordinary command delivery;
|
|
791
|
+
there is no saved Agent-private list to finish after a restart. Emitted domain Events
|
|
792
|
+
enter immutable Agent history before normal EventBus publication. A no-op or
|
|
793
|
+
preference-only turn can commit without a state Version increase. Waiting for a
|
|
794
|
+
provider does not hold a database transaction open.
|
|
795
|
+
|
|
796
|
+
An admitted turn uses a current session and cancellation guard. Shutdown drains
|
|
797
|
+
tracked work and prevents late results from changing Entity state or emitting
|
|
798
|
+
signals. It cannot undo external effects already performed by application code.
|
|
799
|
+
A restarted process can read retained receipts and audit history, but it does
|
|
800
|
+
not replay a model response or re-enter an interrupted Agent handler.
|
|
758
801
|
|
|
759
802
|
### Retained history
|
|
760
803
|
|
|
@@ -774,7 +817,7 @@ persistent provider when records must survive process termination.
|
|
|
774
817
|
All methods return newest entries first. A request supplies positive `pageSize`
|
|
775
818
|
and an optional opaque cursor; `nextCursor` continues toward older entries.
|
|
776
819
|
There is no fixed 100-item or page-byte ceiling. Reads made during a handler count
|
|
777
|
-
toward any configured invocation limits for recorded reads
|
|
820
|
+
toward any configured invocation limits for recorded reads. Ordering
|
|
778
821
|
uses the full Spine `Time` timestamp, category and existing record ID. There is
|
|
779
822
|
no repository-managed history counter. Cursors cannot be transferred across
|
|
780
823
|
Agents, tenants, categories or conversations.
|
|
@@ -794,19 +837,15 @@ For a trusted application bridge, `context.getRepository(AgentClass)` returns
|
|
|
794
837
|
the registered Agent `Repository`, which exposes
|
|
795
838
|
`agentHistory(id, scope)` with the same four history methods and page contracts.
|
|
796
839
|
The scope is explicit: pass `{}` in a single-tenant Bounded Context or
|
|
797
|
-
`{ tenantId }` in a multitenant Bounded Context.
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
Agent claim time, the execution becomes `terminated` with one
|
|
807
|
-
`AgentInvocationTerminated` System Event carrying `MODEL_USE_DENIED`. No Agent
|
|
808
|
-
handler runs and no application-domain result Event is emitted. Callback
|
|
809
|
-
exceptions and infrastructure failures remain distinct from this denial.
|
|
840
|
+
`{ tenantId }` in a multitenant Bounded Context. Reads use indexed storage
|
|
841
|
+
without restoring an Agent. The application bridge must authorize access;
|
|
842
|
+
actor metadata does not grant read permission.
|
|
843
|
+
|
|
844
|
+
If a selected model's `authorizeUse` callback explicitly returns `false`
|
|
845
|
+
before the handler, the turn records one `AgentInvocationTerminated` System
|
|
846
|
+
Event carrying `MODEL_USE_DENIED`. No handler runs, no application-domain
|
|
847
|
+
result Event is invented, and other failures remain distinct. Applications
|
|
848
|
+
may correlate this fact with the original source through paged Agent history.
|
|
810
849
|
|
|
811
850
|
## Signals, validation, and rejection behavior
|
|
812
851
|
|
|
@@ -814,8 +853,10 @@ exceptions and infrastructure failures remain distinct from this denial.
|
|
|
814
853
|
before dispatcher or repository handler code runs. It raises the framework's
|
|
815
854
|
command-validation failure, which `SpineServices` maps to
|
|
816
855
|
`COMMAND_VALIDATION_ERROR` with a packed `spine.validation.ValidationError`.
|
|
817
|
-
Entity transition validation failures map to
|
|
818
|
-
`COMMAND_STATE_TRANSITION_VALIDATION_FAILED` with the same detail type.
|
|
856
|
+
Entity transition validation failures that escape service processing map to
|
|
857
|
+
`COMMAND_STATE_TRANSITION_VALIDATION_FAILED` with the same detail type. Managed
|
|
858
|
+
reception of ordinary Entity work sends post-handler transition rejection to `DeliveryMonitor`;
|
|
859
|
+
its default action acknowledges the failed input without storing invalid state.
|
|
819
860
|
Framework-created runtime command and event metadata uses fresh Node secure
|
|
820
861
|
UUIDs; fixed IDs belong only to existing source envelopes retained through the
|
|
821
862
|
normal origin chain.
|
|
@@ -856,6 +897,21 @@ a starting time, and has no durable operation identity, progress, Inbox
|
|
|
856
897
|
catch-up delivery, restart, resumption, or historical/live coordination. It is
|
|
857
898
|
not JVM-equivalent Projection catch-up.
|
|
858
899
|
|
|
900
|
+
Event Topics accept `include_all` or equality filters on the complete
|
|
901
|
+
`context.past_message` Origin. The filter value must be a valid packed
|
|
902
|
+
`spine.core.Origin`; other Event field paths, operators, ID filters, empty
|
|
903
|
+
filter trees, and malformed values are rejected. Existing composite-filter
|
|
904
|
+
limits apply. This is the immediate previous signal, not any ancestor in a
|
|
905
|
+
causal chain. Tenant isolation remains independent of the filter.
|
|
906
|
+
|
|
907
|
+
Origin filters use Protobuf value equality for the entire supported message,
|
|
908
|
+
including actor context and grand-origin. Packed `Any` payloads retain their
|
|
909
|
+
exact type URL and bytes. Expected Origins with unknown fields in their nested
|
|
910
|
+
message structure are unsupported and rejected; actual Origins with such
|
|
911
|
+
unknown fields cannot match. This avoids silently ignoring fields while keeping
|
|
912
|
+
the same equality semantics as Spine JVM for supported filters. The same rule
|
|
913
|
+
applies to direct and stored subscription definitions.
|
|
914
|
+
|
|
859
915
|
Active subscription streams and queues are process-local. `Stand` serves
|
|
860
916
|
authoritative queries from current state and Entity subscriptions observe
|
|
861
917
|
committed `EntityStateChanged` messages on the paired System Context EventBus,
|
|
@@ -881,7 +937,8 @@ group of complete server replicas when the framework handles process shutdown.
|
|
|
881
937
|
and installs no process signal handlers; that host closes the returned handle.
|
|
882
938
|
Both require a positive safe-integer
|
|
883
939
|
`processCount` and an ESM `moduleUrl`; it never derives a process count from
|
|
884
|
-
the machine. Its optional `host` and required
|
|
940
|
+
the machine. Its optional `host` and required `port` (zero selects an OS-assigned
|
|
941
|
+
port) bind the public
|
|
885
942
|
Coordinator listener. Every child executes that same module and calls the
|
|
886
943
|
module's `createServer({ host: "127.0.0.1", port: 0 })`. The child reports its
|
|
887
944
|
actual loopback endpoint only after its local readiness gates settle. The parent
|
|
@@ -900,11 +957,24 @@ inspect CPU availability and does not constrain the application's independently
|
|
|
900
957
|
chosen `DeliveryStrategy` or shard count. Direct `Server.run()` and browser
|
|
901
958
|
hosting remain independent of managed Node deployment.
|
|
902
959
|
|
|
960
|
+
Managed close drains Delivery before cancelling subscription relays. Child listeners
|
|
961
|
+
remain available through relay cancellation, and final child close follows relay
|
|
962
|
+
cleanup. A failed cleanup phase can be retried. Private child acknowledgement
|
|
963
|
+
and process reaping retain their finite process-control graces. A permanently
|
|
964
|
+
blocked application effect can keep explicit close pending.
|
|
965
|
+
|
|
903
966
|
If no child is READY, Command and Query return gRPC `UNAVAILABLE`. The
|
|
904
967
|
Coordinator does not enter application intake and does not retry the selected
|
|
905
968
|
call on a sibling child. Subscription fan-out follows current READY members;
|
|
906
969
|
later and replacement members attach the retained subscription before managed
|
|
907
970
|
admission.
|
|
971
|
+
Each native child sends a response-only successful activation ACK after its
|
|
972
|
+
listener attaches. The Coordinator waits for every required child ACK before
|
|
973
|
+
emitting one ACK with the logical public subscription ID and Topic; a child
|
|
974
|
+
failure before readiness cancels admitted siblings. Business updates do not
|
|
975
|
+
serve as readiness signals, and later joining children do not emit another
|
|
976
|
+
logical ACK. An ACK confirms attachment, not durable replay or delivery of
|
|
977
|
+
future updates.
|
|
908
978
|
|
|
909
979
|
`ServerOptions` is native-only: it configures contexts, resources, services,
|
|
910
980
|
and the native listener. It has no `browser` option and the root package does
|
|
@@ -991,7 +1061,9 @@ delivery, global update ordering, nor cluster-complete notification delivery.
|
|
|
991
1061
|
## Delivery and environment
|
|
992
1062
|
|
|
993
1063
|
`Inbox`, `InboxStorage`, `ShardIndex`, and `ShardedWorkRegistry` provide the
|
|
994
|
-
local durable-row abstraction.
|
|
1064
|
+
local durable-row abstraction. Inbox and shard storage require a single-tenant
|
|
1065
|
+
Delivery storage context shared by all tenants; the packed signal supplies
|
|
1066
|
+
the dispatch tenant. Read limits are 1–1000; work leases are
|
|
995
1067
|
1000–2147483647 ms. Framework replay supports command handling, projection
|
|
996
1068
|
updates, and process-manager reactions. Callbacks are at-least-once/replay-safe:
|
|
997
1069
|
lost renewal can prevent stale finalization but cannot undo a callback already
|
|
@@ -1019,31 +1091,63 @@ absent or elapsed (`keepUntil <= now`). Delivery skips per-record mutation check
|
|
|
1019
1091
|
and deletion attempts for rows whose deadline is still in the future. Cleanup
|
|
1020
1092
|
and retained-row duplicate recognition use the same applicable clock. Eligible
|
|
1021
1093
|
rows still receive final time and shard checks before deletion.
|
|
1022
|
-
Direct local storage
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1094
|
+
Direct local storage checks the supplied delivered status and deadline again,
|
|
1095
|
+
then deletes by ID while the operation is active. It does not re-read the stored
|
|
1096
|
+
row or compare its snapshot, and the shard session is not checked again after
|
|
1097
|
+
deletion. A row changed between the checks and deletion can therefore be
|
|
1098
|
+
removed. Cancellation stops subsequent cleanup attempts; deletions already
|
|
1099
|
+
completed remain. The remote adapter sends a separate bounded removal request,
|
|
1100
|
+
without an atomic compare-and-delete guarantee from this client. Pending,
|
|
1101
|
+
retryable, non-delivered, and still-protected rows are skipped by cleanup. There
|
|
1102
|
+
is no additional retention configuration, timer, or scheduler.
|
|
1103
|
+
|
|
1104
|
+
Configure one Delivery strategy for the environment before setup. It maps
|
|
1105
|
+
targets to shards across all contexts; the default is one shard. For example:
|
|
1032
1106
|
|
|
1033
1107
|
```ts
|
|
1034
|
-
import {
|
|
1108
|
+
import {
|
|
1109
|
+
BoundedContext,
|
|
1110
|
+
EnvironmentType,
|
|
1111
|
+
ServerEnvironment,
|
|
1112
|
+
UniformAcrossAllShards,
|
|
1113
|
+
} from "@spine-event-engine/server";
|
|
1035
1114
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1115
|
+
ServerEnvironment.when(EnvironmentType.Local).use({
|
|
1116
|
+
deliveryStrategy: UniformAcrossAllShards.forNumber(3),
|
|
1117
|
+
});
|
|
1118
|
+
await ServerEnvironment.instance().completeSetup();
|
|
1119
|
+
const context = await BoundedContext.singleTenant("Tasks").build();
|
|
1039
1120
|
```
|
|
1040
1121
|
|
|
1041
1122
|
Aggregate commands and Process Manager or Agent commands/events derive their target shard
|
|
1042
1123
|
internally and persist their envelope in the target Entity Inbox before any
|
|
1043
|
-
handler runs.
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1124
|
+
handler runs. Projection input uses the same environment Delivery and shared
|
|
1125
|
+
Inbox, with its separate recipient identity.
|
|
1126
|
+
|
|
1127
|
+
Local posting waits for the result of that signal's delivery attempt. For an
|
|
1128
|
+
Agent, successful acceptance and Inbox acknowledgement let posting finish while
|
|
1129
|
+
the live handler continues. If Agent execution capacity is unavailable, the input
|
|
1130
|
+
stays pending and the local call reports the existing command-posting error.
|
|
1131
|
+
|
|
1132
|
+
With remote Delivery and its environment supervisor, posting completes after the
|
|
1133
|
+
remote Inbox accepts the input and the shard notification is submitted. Processing
|
|
1134
|
+
may still be pending on another process. For example, importing an Event can return
|
|
1135
|
+
while another process holds its shard; the Projection update arrives after that
|
|
1136
|
+
process can dispatch the Event. Reception alone does not acknowledge delivery,
|
|
1137
|
+
create an Agent acceptance receipt, or prove that a handler ran.
|
|
1138
|
+
|
|
1139
|
+
A rejected remote receive operation rejects posting. If a local notification
|
|
1140
|
+
observer fails after reception succeeds, the failure is logged and the existing
|
|
1141
|
+
notifications and safety scan can find the pending work. The environment selects
|
|
1142
|
+
this behavior from its installed supervision; contexts have no attachment step or
|
|
1143
|
+
completion switch. Supplying custom ports without a source does not install remote
|
|
1144
|
+
supervision. Explicit `Delivery.run()` still returns the actual run result,
|
|
1145
|
+
including `SKIPPED` when another process is handling the shard.
|
|
1146
|
+
For ordinary Entity Inbox work, post-handler output and transition validation
|
|
1147
|
+
failures reach the reception monitor. Pre-handler input and routing errors and
|
|
1148
|
+
storage failures remain outside that monitor. Accepted Agent work has already
|
|
1149
|
+
acknowledged its Inbox row and does not enter this reception action. A detached
|
|
1150
|
+
run that throws emits a contained terminal error without exposing its message.
|
|
1047
1151
|
|
|
1048
1152
|
`DeliveryBuilder` constructs a controlled `Delivery`; `DeliverySupervisor`
|
|
1049
1153
|
receives `{ source, delivery, onMessage }`, manages bounded shard notifications
|
|
@@ -1053,6 +1157,11 @@ before source client/storage. `DeliverySource` is not configured on
|
|
|
1053
1157
|
durable supervisor state, topology failover, exactly-once effects, or automatic
|
|
1054
1158
|
retry of unknown remote mutations.
|
|
1055
1159
|
|
|
1160
|
+
Direct `DeliverySupervisor.close({ graceMs })` stops new admission and source
|
|
1161
|
+
activity. Its `graceMs` defaults to 30,000 ms and bounds active-work grace and
|
|
1162
|
+
release cleanup separately. After those waits, close may still await entered
|
|
1163
|
+
work that has not settled; it is not a hard total close deadline.
|
|
1164
|
+
|
|
1056
1165
|
Each Inbox read is bounded to one page. That bound does not limit the total
|
|
1057
1166
|
pending work: an active drain continues from the last row read until that scan
|
|
1058
1167
|
ends. It restarts from the beginning only if the completed scan delivered
|
|
@@ -1073,35 +1182,63 @@ the remote server.
|
|
|
1073
1182
|
`DeliveryMonitor` is an instantiable, customizable policy seam exposing
|
|
1074
1183
|
asynchronous continuation, start/completion, failed-reception, pickup-failure,
|
|
1075
1184
|
and already-picked hooks.
|
|
1076
|
-
`FailedReception` supplies
|
|
1077
|
-
`repeatDispatching()`
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1185
|
+
`FailedReception` supplies `markDelivered()` and immediate
|
|
1186
|
+
`repeatDispatching()` actions for failed processing. The default marks a failed
|
|
1187
|
+
reception delivered; independent targets continue. A custom monitor may repeat
|
|
1188
|
+
the dispatch and is consulted again if that attempt fails. Monitor and selected
|
|
1189
|
+
action errors propagate. A successful handler followed by a failed acknowledgement
|
|
1190
|
+
retries acknowledgement up to three times without deliberately rerunning the
|
|
1191
|
+
handler. Exhausted acknowledgement leaves the row pending and does not call the
|
|
1192
|
+
reception monitor. A custom reception action that completes normally completes
|
|
1193
|
+
delivery and the enclosing stage acknowledges the row. An action that rejects
|
|
1194
|
+
propagates its error and leaves the row `TO_DELIVER`. `markDelivered()` does not
|
|
1195
|
+
mean domain processing succeeded.
|
|
1196
|
+
Managed repository replay sends actual handler failures to the monitor while
|
|
1197
|
+
storage and replay infrastructure errors propagate. A direct `onMessage` callback
|
|
1198
|
+
is treated as the endpoint. Handler effects and acknowledgement are separate,
|
|
1199
|
+
so a crash between them may redeliver.
|
|
1200
|
+
The framework adds no persisted attempts, quarantine, dead-letter, receipt, or
|
|
1201
|
+
marker policy. The supervisor rescans pending shards every 10 seconds by default;
|
|
1202
|
+
the stale-session threshold is separately 60 seconds.
|
|
1203
|
+
After a failed finite run, release-generated remote observations of that shard
|
|
1204
|
+
are held locally until the next periodic rescan, preventing an immediate
|
|
1205
|
+
self-triggered retry loop. Explicit notifications remain admissible. A newly
|
|
1206
|
+
enqueued remote row on that shard may wait for the next rescan; other shards
|
|
1207
|
+
continue, and other processes may each attempt the failed row before applying
|
|
1208
|
+
local suppression. This timing is not a delivery deadline.
|
|
1209
|
+
|
|
1210
|
+
`BoundedContext.close()` stops external admission, drains accepted framework
|
|
1211
|
+
work, and then closes buses, subscriptions, Stands, and repository bindings.
|
|
1212
|
+
Cleanup failures are aggregated and may be retried. A committed Entity Event,
|
|
1213
|
+
reactor or Process Manager Event, and System Event receives one first-publication
|
|
1214
|
+
attempt; a contained failure is logged and does not schedule publication again.
|
|
1215
|
+
Persisted System Events use a storage group derived from their System Context
|
|
1216
|
+
name and role, separate from domain Event history. Command acceptance
|
|
1217
|
+
alone does not promise recipient completion. Processing retries for Inbox rows
|
|
1218
|
+
and acknowledgement recovery remain separate Delivery behavior.
|
|
1081
1219
|
|
|
1082
1220
|
`Environment` resolves the Node `local` or `production` profile once from
|
|
1083
1221
|
`NODE_ENV`. `ServerEnvironment` resolves configured facilities once for that
|
|
1084
|
-
profile and exposes its `storageFactory`,
|
|
1085
|
-
`
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
environment: attachment supervisors and their source reads belong to that facility.
|
|
1222
|
+
profile and exposes its `storageFactory`, `tenantIndex`, `nodeId`, and
|
|
1223
|
+
`close()` lifecycle. A healthy close with active contexts rejects without
|
|
1224
|
+
teardown; after required startup failure, close joins automatic cleanup and
|
|
1225
|
+
reports the original cause plus cleanup failures. After explicit
|
|
1226
|
+
`completeSetup()`, its `delivery` property
|
|
1227
|
+
is the usable shared public `Delivery` facade. A Bounded Context cannot build
|
|
1228
|
+
before setup, and a server does not start setup on the application's behalf.
|
|
1229
|
+
Neither API authenticates requests or supplies remote topology or a deployment
|
|
1230
|
+
policy.
|
|
1231
|
+
|
|
1232
|
+
`ServerEnvironmentDelivery` supplies an optional remote facility with `open()`,
|
|
1233
|
+
`inbox`, and `workRegistry` ports. Setup opens it once before creating the
|
|
1234
|
+
shared Delivery; failure closes acquired facilities. Its optional `source`
|
|
1235
|
+
supports remote shard snapshots and notifications through the environment's
|
|
1236
|
+
single supervisor. Local Delivery uses the environment's configured storage
|
|
1237
|
+
factory for its shared Inbox and work registry; the default factory is in-memory.
|
|
1238
|
+
Contexts register recipients with the same Delivery and never close that shared
|
|
1239
|
+
facility individually. Environment shutdown stops intake, drains local admitted
|
|
1240
|
+
work, then closes shared Delivery and configured facilities. Pending remote rows
|
|
1241
|
+
do not make a closing context wait indefinitely for other processes to finish.
|
|
1105
1242
|
|
|
1106
1243
|
## Signal identity and Aggregate semantics
|
|
1107
1244
|
|