@spine-event-engine/server 2.0.0-snapshot.22 → 2.0.0-snapshot.24
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 +104 -7
- package/REFERENCE.md +272 -31
- package/dist/agent/agent-admission.d.ts +80 -0
- package/dist/agent/agent-admission.d.ts.map +1 -0
- package/dist/agent/agent-admission.js +127 -0
- package/dist/agent/agent-admission.js.map +1 -0
- package/dist/agent/agent-ai-binding.d.ts +24 -0
- package/dist/agent/agent-ai-binding.d.ts.map +1 -0
- package/dist/agent/agent-ai-binding.js +48 -0
- package/dist/agent/agent-ai-binding.js.map +1 -0
- package/dist/agent/agent-ai-runtime.d.ts +76 -0
- package/dist/agent/agent-ai-runtime.d.ts.map +1 -0
- package/dist/agent/agent-ai-runtime.js +1269 -0
- package/dist/agent/agent-ai-runtime.js.map +1 -0
- package/dist/agent/agent-execution-capacity.d.ts +43 -0
- package/dist/agent/agent-execution-capacity.d.ts.map +1 -0
- package/dist/agent/agent-execution-capacity.js +147 -0
- package/dist/agent/agent-execution-capacity.js.map +1 -0
- package/dist/agent/agent-execution-fault.d.ts +18 -0
- package/dist/agent/agent-execution-fault.d.ts.map +1 -0
- package/dist/agent/agent-execution-fault.js +31 -0
- package/dist/agent/agent-execution-fault.js.map +1 -0
- package/dist/agent/agent-execution-session.d.ts +103 -0
- package/dist/agent/agent-execution-session.d.ts.map +1 -0
- package/dist/agent/agent-execution-session.js +238 -0
- package/dist/agent/agent-execution-session.js.map +1 -0
- package/dist/agent/agent-history.d.ts +148 -0
- package/dist/agent/agent-history.d.ts.map +1 -0
- package/dist/agent/agent-history.js +340 -0
- package/dist/agent/agent-history.js.map +1 -0
- package/dist/agent/agent-interaction-audit.d.ts +58 -0
- package/dist/agent/agent-interaction-audit.d.ts.map +1 -0
- package/dist/agent/agent-interaction-audit.js +114 -0
- package/dist/agent/agent-interaction-audit.js.map +1 -0
- package/dist/agent/agent-interaction-events.d.ts +40 -0
- package/dist/agent/agent-interaction-events.d.ts.map +1 -0
- package/dist/agent/agent-interaction-events.js +129 -0
- package/dist/agent/agent-interaction-events.js.map +1 -0
- package/dist/agent/agent-mcp-budget.d.ts +125 -0
- package/dist/agent/agent-mcp-budget.d.ts.map +1 -0
- package/dist/agent/agent-mcp-budget.js +566 -0
- package/dist/agent/agent-mcp-budget.js.map +1 -0
- package/dist/agent/agent-mcp-host.d.ts +125 -0
- package/dist/agent/agent-mcp-host.d.ts.map +1 -0
- package/dist/agent/agent-mcp-host.js +15 -0
- package/dist/agent/agent-mcp-host.js.map +1 -0
- package/dist/agent/agent-mcp-runtime.d.ts +199 -0
- package/dist/agent/agent-mcp-runtime.d.ts.map +1 -0
- package/dist/agent/agent-mcp-runtime.js +621 -0
- package/dist/agent/agent-mcp-runtime.js.map +1 -0
- package/dist/agent/agent-model-selection.d.ts +129 -0
- package/dist/agent/agent-model-selection.d.ts.map +1 -0
- package/dist/agent/agent-model-selection.js +342 -0
- package/dist/agent/agent-model-selection.js.map +1 -0
- package/dist/agent/agent-read-runtime.d.ts +70 -0
- package/dist/agent/agent-read-runtime.d.ts.map +1 -0
- package/dist/agent/agent-read-runtime.js +320 -0
- package/dist/agent/agent-read-runtime.js.map +1 -0
- package/dist/agent/agent-revisions.d.ts +35 -0
- package/dist/agent/agent-revisions.d.ts.map +1 -0
- package/dist/agent/agent-revisions.js +133 -0
- package/dist/agent/agent-revisions.js.map +1 -0
- package/dist/agent/agent-scheduler.d.ts +99 -0
- package/dist/agent/agent-scheduler.d.ts.map +1 -0
- package/dist/agent/agent-scheduler.js +398 -0
- package/dist/agent/agent-scheduler.js.map +1 -0
- package/dist/bus/command-bus.d.ts +62 -0
- package/dist/bus/command-bus.d.ts.map +1 -1
- package/dist/bus/command-bus.js +51 -2
- package/dist/bus/command-bus.js.map +1 -1
- package/dist/bus/event-bus.d.ts +101 -2
- package/dist/bus/event-bus.d.ts.map +1 -1
- package/dist/bus/event-bus.js +74 -13
- package/dist/bus/event-bus.js.map +1 -1
- package/dist/bus/saved-dispatcher-binding.d.ts +53 -0
- package/dist/bus/saved-dispatcher-binding.d.ts.map +1 -0
- package/dist/bus/saved-dispatcher-binding.js +27 -0
- package/dist/bus/saved-dispatcher-binding.js.map +1 -0
- package/dist/context/bounded-context.d.ts +45 -12
- package/dist/context/bounded-context.d.ts.map +1 -1
- package/dist/context/bounded-context.js +306 -86
- package/dist/context/bounded-context.js.map +1 -1
- package/dist/context/entity-inbox.d.ts.map +1 -1
- package/dist/context/entity-inbox.js +21 -7
- package/dist/context/entity-inbox.js.map +1 -1
- package/dist/context/local-inbox-handoff.d.ts +1 -0
- package/dist/context/local-inbox-handoff.d.ts.map +1 -1
- package/dist/context/local-inbox-handoff.js +31 -1
- package/dist/context/local-inbox-handoff.js.map +1 -1
- package/dist/context/projection-handoff.d.ts.map +1 -1
- package/dist/context/projection-handoff.js +2 -0
- package/dist/context/projection-handoff.js.map +1 -1
- package/dist/context/tenant-index.d.ts +25 -0
- package/dist/context/tenant-index.d.ts.map +1 -1
- package/dist/context/tenant-index.js +45 -1
- package/dist/context/tenant-index.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 +15 -0
- package/dist/delivery/delivery-run-control.d.ts.map +1 -1
- 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 +150 -22
- package/dist/delivery/delivery-supervisor.js.map +1 -1
- package/dist/delivery/delivery.d.ts.map +1 -1
- package/dist/delivery/delivery.js +128 -54
- package/dist/delivery/delivery.js.map +1 -1
- package/dist/delivery/inbox-storage.d.ts +8 -11
- package/dist/delivery/inbox-storage.d.ts.map +1 -1
- package/dist/delivery/inbox-storage.js +33 -76
- 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 +10 -13
- package/dist/delivery/inbox.js.map +1 -1
- package/dist/delivery/reception-observation.d.ts +56 -0
- package/dist/delivery/reception-observation.d.ts.map +1 -0
- package/dist/delivery/reception-observation.js +67 -0
- package/dist/delivery/reception-observation.js.map +1 -0
- package/dist/entity/entity.d.ts +82 -3
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +121 -22
- package/dist/entity/entity.js.map +1 -1
- package/dist/handler/generated-handler-registry.js +8 -3
- package/dist/handler/generated-handler-registry.js.map +1 -1
- package/dist/handler/handler-metadata.d.ts +17 -1
- package/dist/handler/handler-metadata.d.ts.map +1 -1
- package/dist/handler/handler-metadata.js +10 -4
- package/dist/handler/handler-metadata.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/repository/commit-fence.d.ts +11 -0
- package/dist/repository/commit-fence.d.ts.map +1 -1
- package/dist/repository/commit-fence.js +13 -0
- package/dist/repository/commit-fence.js.map +1 -1
- package/dist/repository/repository.d.ts +221 -13
- package/dist/repository/repository.d.ts.map +1 -1
- package/dist/repository/repository.js +2323 -134
- package/dist/repository/repository.js.map +1 -1
- package/dist/runtime/runtime.d.ts +11 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +13 -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 +3 -10
- package/dist/runtime/signal-metadata.js.map +1 -1
- package/dist/runtime/signal-publisher.d.ts +14 -30
- package/dist/runtime/signal-publisher.d.ts.map +1 -1
- package/dist/runtime/signal-publisher.js +75 -47
- package/dist/runtime/signal-publisher.js.map +1 -1
- package/dist/runtime/standalone-handler-runtime.d.ts +7 -0
- package/dist/runtime/standalone-handler-runtime.d.ts.map +1 -1
- package/dist/runtime/standalone-handler-runtime.js +118 -11
- package/dist/runtime/standalone-handler-runtime.js.map +1 -1
- package/dist/server/environment-delivery-worker.d.ts.map +1 -1
- package/dist/server/environment-delivery-worker.js +305 -5
- package/dist/server/environment-delivery-worker.js.map +1 -1
- 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 +467 -177
- 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-log.d.ts.map +1 -1
- package/dist/server/server-log.js +4 -0
- package/dist/server/server-log.js.map +1 -1
- package/dist/server/server.d.ts +9 -0
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +33 -8
- package/dist/server/server.js.map +1 -1
- package/dist/services/spine-services.d.ts.map +1 -1
- package/dist/services/spine-services.js +200 -72
- 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/subscription-observer.d.ts.map +1 -1
- package/dist/stand/subscription-observer.js +7 -0
- package/dist/stand/subscription-observer.js.map +1 -1
- package/dist/stand/subscription-runtime.d.ts +18 -1
- package/dist/stand/subscription-runtime.d.ts.map +1 -1
- package/dist/stand/subscription-runtime.js +32 -4
- package/dist/stand/subscription-runtime.js.map +1 -1
- package/dist/testing/index.d.ts +57 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +88 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -13
|
@@ -16,17 +16,26 @@ import { access, realpath } from "node:fs/promises";
|
|
|
16
16
|
import { isAbsolute, relative, resolve, sep } from "node:path";
|
|
17
17
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
18
18
|
import { clone, create, getOption, hasOption } from "@bufbuild/protobuf";
|
|
19
|
+
import { freezeRegistry, isAiModel, registryOptions } from "@spine-event-engine/ai/spi/runtime";
|
|
19
20
|
import { TypeUrls } from "@spine-event-engine/core";
|
|
20
21
|
import { EventSchema, EventContextSchema, BoundedContextNameSchema, TenantIdSchema, } from "@spine-event-engine/proto";
|
|
21
22
|
import { SPI_type, internal_all, internal_type } from "@spine-event-engine/proto";
|
|
22
|
-
import { ColumnTypes, EventStore, InMemoryStorageFactory, RecordColumn, } from "@spine-event-engine/storage";
|
|
23
|
-
import { TenantBoundary } from "@spine-event-engine/storage/provider";
|
|
23
|
+
import { ColumnTypes, EventStore, InMemoryStorageFactory, RecordColumn, StorageGroup, } from "@spine-event-engine/storage";
|
|
24
|
+
import { AgentExecutionStorageFactories, AgentHistoryStorageFactories, TenantBoundary, } from "@spine-event-engine/storage/provider";
|
|
25
|
+
/**
|
|
26
|
+
* Storage family shared by paired System Event publication and trusted reads.
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
export const systemEventGroup = new StorageGroup("spine_system_events");
|
|
24
30
|
import { CommandBus, commandBusAccess } from "../bus/command-bus.js";
|
|
25
|
-
import { EventBus, eventBusAccess, } from "../bus/event-bus.js";
|
|
31
|
+
import { EventBus, eventBusAccess, isSystemEventSchema, } from "../bus/event-bus.js";
|
|
26
32
|
import { DeliveryReadiness, } from "./local-inbox-handoff.js";
|
|
27
33
|
import { LocalEntityInbox } from "./entity-inbox.js";
|
|
28
34
|
import { LocalProjectionInbox } from "./projection-handoff.js";
|
|
29
35
|
import { TenantIndexes } from "./tenant-index.js";
|
|
36
|
+
import { EffectiveTenants } from "./effective-tenant.js";
|
|
37
|
+
import { AgentScheduler } from "../agent/agent-scheduler.js";
|
|
38
|
+
import { AgentExecutionCapacity } from "../agent/agent-execution-capacity.js";
|
|
30
39
|
import { Repository, repositoryAccess, } from "../repository/repository.js";
|
|
31
40
|
import { GeneratedRegistryDiscovery } from "../handler/generated-registry-discovery.js";
|
|
32
41
|
import { HandlerRegistryIngestor, } from "../handler/generated-handler-registry.js";
|
|
@@ -81,6 +90,8 @@ const contextSubscriptionRuntimes = new WeakMap();
|
|
|
81
90
|
const contextLoggers = new WeakMap();
|
|
82
91
|
const contextSignalPublishers = new WeakMap();
|
|
83
92
|
const contextEventBuses = new WeakMap();
|
|
93
|
+
const contextRepositoryViews = new WeakMap();
|
|
94
|
+
const issuedRepositoryViews = new WeakMap();
|
|
84
95
|
const closingContexts = new WeakSet();
|
|
85
96
|
const contextClosePhases = new WeakMap();
|
|
86
97
|
const contextIntegrations = new WeakMap();
|
|
@@ -106,9 +117,12 @@ export class BoundedContext {
|
|
|
106
117
|
#registeredRepositories = [];
|
|
107
118
|
#repositoryViews = new Set();
|
|
108
119
|
#storageFactory;
|
|
120
|
+
#ai;
|
|
109
121
|
#stand;
|
|
110
122
|
#systemStand;
|
|
111
123
|
#subscriptionRuntime;
|
|
124
|
+
#agentScheduler;
|
|
125
|
+
#agentErrors = [];
|
|
112
126
|
#closed;
|
|
113
127
|
/**
|
|
114
128
|
* Registers the framework-only construction hook for this module.
|
|
@@ -132,6 +146,7 @@ export class BoundedContext {
|
|
|
132
146
|
this.#systemStand = input.systemStand;
|
|
133
147
|
this.#subscriptionRuntime = input.subscriptionRuntime;
|
|
134
148
|
this.#storageFactory = input.storageFactory;
|
|
149
|
+
this.#ai = input.ai;
|
|
135
150
|
this.#deliveryStrategy = ContextParts.snapshotDeliveryStrategy(input.deliveryStrategy);
|
|
136
151
|
this.#commandEndpoint = Object.freeze({
|
|
137
152
|
acceptedCommandTypes: () => this.#commandBus.acceptedCommandTypes(),
|
|
@@ -146,8 +161,56 @@ export class BoundedContext {
|
|
|
146
161
|
this.#projectionInbox = delivery.projectionInbox;
|
|
147
162
|
this.#installReferences(input, delivery);
|
|
148
163
|
this.#registerAndStart(input.repositories, delivery.tenantIndex);
|
|
164
|
+
this.#startAgentScheduler(delivery.tenantIndex);
|
|
149
165
|
Object.freeze(this);
|
|
150
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Starts bounded indexed discovery for registered Agent repositories.
|
|
169
|
+
*/
|
|
170
|
+
#startAgentScheduler(tenantIndex) {
|
|
171
|
+
if (this.#ai === undefined)
|
|
172
|
+
return;
|
|
173
|
+
const repositories = [...this.#repositoryViews].filter((entry) => entry.entityFamily === "agent");
|
|
174
|
+
if (repositories.length === 0)
|
|
175
|
+
return;
|
|
176
|
+
this.#agentScheduler = new AgentScheduler({
|
|
177
|
+
repositories: repositories.length,
|
|
178
|
+
page: (after, signal) => tenantIndex.page({
|
|
179
|
+
count: 16,
|
|
180
|
+
signal,
|
|
181
|
+
...(after === undefined ? {} : { after }),
|
|
182
|
+
}),
|
|
183
|
+
scope: (id, index) => {
|
|
184
|
+
const repository = repositories[index];
|
|
185
|
+
if (repository === undefined)
|
|
186
|
+
throw new Error("Agent repository scope is unavailable.");
|
|
187
|
+
return this.#agentScope(repository, tenantIndex.tenantMode === "single-tenant" ? undefined : id);
|
|
188
|
+
},
|
|
189
|
+
}, AgentExecutionCapacity.for(this.#ai), (error) => {
|
|
190
|
+
if (this.#agentErrors.length < 32)
|
|
191
|
+
this.#agentErrors.push(error);
|
|
192
|
+
});
|
|
193
|
+
this.#agentScheduler.start();
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Builds one scan scope from an accepted handoff or a catalog sweep.
|
|
197
|
+
*
|
|
198
|
+
* @param repository Registered Agent repository.
|
|
199
|
+
* @param tenantId Accepted tenant, absent only in a single-tenant Bounded Context.
|
|
200
|
+
* @returns The matching indexed provider scan scope.
|
|
201
|
+
*/
|
|
202
|
+
#agentScope(repository, tenantId) {
|
|
203
|
+
const effective = EffectiveTenants.current(this.#snapshot.tenantMode === "multitenant", tenantId);
|
|
204
|
+
return {
|
|
205
|
+
id: JSON.stringify([
|
|
206
|
+
this.#snapshot.name.value,
|
|
207
|
+
String(TenantBoundary.from(effective).key),
|
|
208
|
+
repository.stateFullTypeName,
|
|
209
|
+
]),
|
|
210
|
+
pending: (after, count) => repositoryAccess.pendingAcceptedAgents(repository, tenantId, after, count),
|
|
211
|
+
run: (key, signal) => repositoryAccess.runAcceptedAgent(repository, tenantId, key, signal),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
151
214
|
/**
|
|
152
215
|
* Creates tenant-aware Inboxes and their shared readiness signal.
|
|
153
216
|
*
|
|
@@ -174,6 +237,7 @@ export class BoundedContext {
|
|
|
174
237
|
*/
|
|
175
238
|
#installReferences(input, delivery) {
|
|
176
239
|
contextEventBuses.set(this, [this.#eventBus, this.#systemEventBus]);
|
|
240
|
+
contextRepositoryViews.set(this, this.#repositoryViews);
|
|
177
241
|
eventSubscribers.set(this, (typeUrl, subscriber) => eventBusAccess.subscribe(this.#eventBus, typeUrl, subscriber));
|
|
178
242
|
systemEventPosters.set(this, (event) => this.#publisher.publishSystemEvent(event));
|
|
179
243
|
contextSystemPairings.set(this, ContextParts.createSystemPairing(this.#snapshot, input.systemSpec));
|
|
@@ -236,10 +300,27 @@ export class BoundedContext {
|
|
|
236
300
|
}
|
|
237
301
|
}
|
|
238
302
|
#prepareRepositories(repositories) {
|
|
303
|
+
const registration = this.#repositoryRegistration();
|
|
304
|
+
const preparedRepositories = [];
|
|
305
|
+
try {
|
|
306
|
+
for (const repository of repositories) {
|
|
307
|
+
preparedRepositories.push(ContextParts.prepareRepositoryForContext(repository, registration));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
this.#failRegistration(error, preparedRepositories);
|
|
312
|
+
}
|
|
313
|
+
return preparedRepositories;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Builds callbacks shared by every repository prepared for this Bounded Context.
|
|
317
|
+
*/
|
|
318
|
+
#repositoryRegistration() {
|
|
239
319
|
const registration = {
|
|
240
320
|
name: ContextParts.cloneName(this.#snapshot.name),
|
|
241
321
|
storageContext: ContextParts.createStorageMode(this.#snapshot.spec),
|
|
242
322
|
storageFactory: this.#storageFactory,
|
|
323
|
+
...(this.#ai === undefined ? {} : { ai: this.#ai }),
|
|
243
324
|
stand: this.#stand,
|
|
244
325
|
entityInbox: this.#entityInbox,
|
|
245
326
|
projectionInbox: this.#projectionInbox,
|
|
@@ -250,17 +331,20 @@ export class BoundedContext {
|
|
|
250
331
|
registerSystemEventSchema: (schema) => {
|
|
251
332
|
eventBusAccess.registerSchemas(this.#systemEventBus, [schema]);
|
|
252
333
|
},
|
|
334
|
+
publishAgentEvent: (event) => event.context?.rejection === undefined
|
|
335
|
+
? this.#publisher.publishEvent(event)
|
|
336
|
+
: this.#publisher.publishRejectionEvent(event),
|
|
337
|
+
prepareSavedCommand: (command) => commandBusAccess.prepareSaved(this.#commandBus, command),
|
|
338
|
+
publishSavedCommand: (command, plan) => commandBusAccess.postSavedFollowUp(this.#commandBus, command, plan),
|
|
339
|
+
publishAgentSystemEvent: (event) => this.#publisher.publishSystemEvent(event),
|
|
340
|
+
recordAcceptedSaved: (signal) => {
|
|
341
|
+
this.#publisher.recordAcceptedSaved(signal);
|
|
342
|
+
},
|
|
343
|
+
wakeAcceptedAgent: (repository, tenantId) => {
|
|
344
|
+
this.#agentScheduler?.wake(this.#agentScope(repository, tenantId));
|
|
345
|
+
},
|
|
253
346
|
};
|
|
254
|
-
|
|
255
|
-
try {
|
|
256
|
-
for (const repository of repositories) {
|
|
257
|
-
preparedRepositories.push(ContextParts.prepareRepositoryForContext(repository, registration));
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
catch (error) {
|
|
261
|
-
this.#failRegistration(error, preparedRepositories);
|
|
262
|
-
}
|
|
263
|
-
return preparedRepositories;
|
|
347
|
+
return registration;
|
|
264
348
|
}
|
|
265
349
|
#failRegistration(error, preparedRepositories) {
|
|
266
350
|
const closeErrors = ContextParts.closePreparedRepositories(preparedRepositories);
|
|
@@ -357,7 +441,33 @@ export class BoundedContext {
|
|
|
357
441
|
* @returns Returns immutable repository views.
|
|
358
442
|
*/
|
|
359
443
|
registeredRepositories() {
|
|
360
|
-
|
|
444
|
+
const originals = [...this.#repositoryViews];
|
|
445
|
+
return this.#registeredRepositories.map((snapshot, index) => {
|
|
446
|
+
const repository = originals[index];
|
|
447
|
+
if (repository === undefined)
|
|
448
|
+
throw new Error("Registered repository view disappeared.");
|
|
449
|
+
const view = ContextParts.createRepositoryView(snapshot);
|
|
450
|
+
issuedRepositoryViews.set(view, { context: this, repository });
|
|
451
|
+
return view;
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Returns the repository already registered for an exact Entity constructor.
|
|
456
|
+
* This trusted server-side lookup does not load Entity state or open storage.
|
|
457
|
+
*
|
|
458
|
+
* @typeParam EntityType Concrete Entity constructor registered in this Bounded Context.
|
|
459
|
+
* @param entityType Exact Entity class supplied to this Bounded Context's builder.
|
|
460
|
+
* @returns The existing typed repository for that Entity class.
|
|
461
|
+
* @throws When the constructor is absent or the Bounded Context is closing.
|
|
462
|
+
*/
|
|
463
|
+
getRepository(entityType) {
|
|
464
|
+
if (closingContexts.has(this))
|
|
465
|
+
throw new Error("Bounded Context is closing.");
|
|
466
|
+
for (const repository of this.#repositoryViews) {
|
|
467
|
+
if (repository.entityType === entityType)
|
|
468
|
+
return repository;
|
|
469
|
+
}
|
|
470
|
+
throw new Error("Entity constructor is not registered in this Bounded Context.");
|
|
361
471
|
}
|
|
362
472
|
/**
|
|
363
473
|
* Clears and locally replays every registered Projection from already-stored events.
|
|
@@ -374,7 +484,7 @@ export class BoundedContext {
|
|
|
374
484
|
* - single-tenant contexts reject `tenantId`;
|
|
375
485
|
* - multitenant contexts require the exact non-blank `tenantId`;
|
|
376
486
|
* - process-local sequential execution on the same EventBus runtime queue as
|
|
377
|
-
* live event intake
|
|
487
|
+
* live event intake.
|
|
378
488
|
*
|
|
379
489
|
* Unsupported boundary:
|
|
380
490
|
* - Delivery jobs, schedulers, inbox lifecycle, retries, and transport
|
|
@@ -416,14 +526,8 @@ export class BoundedContext {
|
|
|
416
526
|
});
|
|
417
527
|
}
|
|
418
528
|
/**
|
|
419
|
-
* Closes this context's buses, Stand,
|
|
420
|
-
*
|
|
421
|
-
* Close is idempotent and returns the same close outcome on repeated calls.
|
|
422
|
-
* The context attempts every close hook; when any hook fails, the
|
|
423
|
-
* returned promise rejects with an `AggregateError` after the remaining hooks
|
|
424
|
-
* have also been attempted.
|
|
425
|
-
*
|
|
426
|
-
* @returns A promise that settles after all resources close.
|
|
529
|
+
* Closes this context's buses, Stand, repository storage, and runtime bindings.
|
|
530
|
+
* @returns Completion or an aggregate of close failures.
|
|
427
531
|
*/
|
|
428
532
|
close() {
|
|
429
533
|
this.#beginClose();
|
|
@@ -431,10 +535,11 @@ export class BoundedContext {
|
|
|
431
535
|
return this.#closed;
|
|
432
536
|
}
|
|
433
537
|
/**
|
|
434
|
-
* Stops admission
|
|
538
|
+
* Stops external admission while accepted follow-ups drain.
|
|
435
539
|
*/
|
|
436
540
|
#beginClose() {
|
|
437
541
|
closingContexts.add(this);
|
|
542
|
+
this.#agentScheduler?.stop();
|
|
438
543
|
this.#publisher.beginClose();
|
|
439
544
|
commandBusAccess.beginClose(this.#commandBus);
|
|
440
545
|
eventBusAccess.beginClose(this.#eventBus);
|
|
@@ -446,9 +551,10 @@ export class BoundedContext {
|
|
|
446
551
|
* @returns Completion after the context's accepted work settles.
|
|
447
552
|
*/
|
|
448
553
|
async #drainWork() {
|
|
554
|
+
this.#beginClose();
|
|
449
555
|
const errors = [];
|
|
450
|
-
await
|
|
451
|
-
await
|
|
556
|
+
await this.#closePart(() => ContextParts.closeIntegration(this), errors);
|
|
557
|
+
await this.#closePart(() => ContextParts.drainContextWork(this.#commandBus, this.#eventBus, this.#systemEventBus, this.#publisher), errors);
|
|
452
558
|
if (errors.length > 0)
|
|
453
559
|
throw new AggregateError(errors, "BoundedContext drain failed.");
|
|
454
560
|
}
|
|
@@ -459,18 +565,13 @@ export class BoundedContext {
|
|
|
459
565
|
*/
|
|
460
566
|
async #closeOnce() {
|
|
461
567
|
const errors = [];
|
|
462
|
-
await
|
|
463
|
-
this.#
|
|
464
|
-
await
|
|
465
|
-
await
|
|
466
|
-
this.#
|
|
467
|
-
await
|
|
468
|
-
await
|
|
469
|
-
await ContextParts.closeContextPart(() => eventBusAccess.finishClose(this.#systemEventBus), errors);
|
|
470
|
-
await ContextParts.closeContextPart(() => this.#stand.close(), errors);
|
|
471
|
-
await ContextParts.closeContextPart(() => this.#systemStand.close(), errors);
|
|
472
|
-
await ContextParts.closeContextPart(() => this.#subscriptionRuntime.finishClose(), errors);
|
|
473
|
-
await ContextParts.closeContextPart(() => {
|
|
568
|
+
await this.#closePart(() => this.#agentScheduler?.close(), errors);
|
|
569
|
+
await this.#closePart(() => this.#drainWork(), errors);
|
|
570
|
+
await this.#closeBuses(errors);
|
|
571
|
+
await this.#closePart(() => this.#stand.close(), errors);
|
|
572
|
+
await this.#closePart(() => this.#systemStand.close(), errors);
|
|
573
|
+
await this.#closePart(() => this.#subscriptionRuntime.finishClose(), errors);
|
|
574
|
+
await this.#closePart(() => {
|
|
474
575
|
ContextParts.requireTenantIndex(this).close();
|
|
475
576
|
}, errors);
|
|
476
577
|
await this.#closeRepositories(errors);
|
|
@@ -480,6 +581,21 @@ export class BoundedContext {
|
|
|
480
581
|
}
|
|
481
582
|
ContextParts.clearContextMetadata(this);
|
|
482
583
|
}
|
|
584
|
+
/**
|
|
585
|
+
* Closes bus intake and subscription drains before the Stands.
|
|
586
|
+
*
|
|
587
|
+
* @param errors Collects independent close failures.
|
|
588
|
+
* @returns Completion after bounded bus close attempts.
|
|
589
|
+
*/
|
|
590
|
+
async #closeBuses(errors) {
|
|
591
|
+
this.#publisher.finishClose();
|
|
592
|
+
await this.#closePart(() => commandBusAccess.finishClose(this.#commandBus), errors);
|
|
593
|
+
await this.#closePart(() => eventBusAccess.finishClose(this.#eventBus), errors);
|
|
594
|
+
this.#subscriptionRuntime.beginClose();
|
|
595
|
+
await this.#closePart(() => eventBusAccess.drain(this.#systemEventBus), errors);
|
|
596
|
+
await this.#closePart(() => this.#subscriptionRuntime.drainClose(), errors);
|
|
597
|
+
await this.#closePart(() => eventBusAccess.finishClose(this.#systemEventBus), errors);
|
|
598
|
+
}
|
|
483
599
|
/**
|
|
484
600
|
* Clears repository runtime registration after Stand closure.
|
|
485
601
|
*
|
|
@@ -487,17 +603,41 @@ export class BoundedContext {
|
|
|
487
603
|
*/
|
|
488
604
|
async #closeRepositories(errors) {
|
|
489
605
|
for (const repository of this.#repositoryViews) {
|
|
490
|
-
await
|
|
606
|
+
await this.#closePart(() => {
|
|
491
607
|
repositoryAccess.clearRuntime(repository);
|
|
492
608
|
registeredRepositories.delete(repository);
|
|
493
609
|
}, errors);
|
|
494
610
|
}
|
|
495
611
|
}
|
|
612
|
+
/**
|
|
613
|
+
* Calls a close action and collects its failure before later cleanup.
|
|
614
|
+
* @param work Close action.
|
|
615
|
+
* @param errors Collects close failures.
|
|
616
|
+
*/
|
|
617
|
+
async #closePart(work, errors) {
|
|
618
|
+
await ContextParts.closeContextPart(work, errors);
|
|
619
|
+
}
|
|
496
620
|
}
|
|
497
621
|
/**
|
|
498
622
|
* Exposes framework-only operations for built contexts and their builders.
|
|
499
623
|
*/
|
|
500
624
|
export const boundedContextAccess = Object.freeze({
|
|
625
|
+
/**
|
|
626
|
+
* Resolves a view only within the Bounded Context that issued it.
|
|
627
|
+
*
|
|
628
|
+
* @param context Built Bounded Context that registered the repository.
|
|
629
|
+
* @param view Candidate original or issued view.
|
|
630
|
+
* @returns Registered repository, or undefined for a foreign view.
|
|
631
|
+
*/
|
|
632
|
+
resolveRepository(context, view) {
|
|
633
|
+
const originals = contextRepositoryViews.get(context);
|
|
634
|
+
if (originals?.has(view))
|
|
635
|
+
return view;
|
|
636
|
+
const issued = issuedRepositoryViews.get(view);
|
|
637
|
+
return issued?.context === context && originals?.has(issued.repository)
|
|
638
|
+
? issued.repository
|
|
639
|
+
: undefined;
|
|
640
|
+
},
|
|
501
641
|
beginClose(context) {
|
|
502
642
|
const phase = contextClosePhases.get(context);
|
|
503
643
|
if (phase === undefined)
|
|
@@ -543,12 +683,12 @@ export const boundedContextAccess = Object.freeze({
|
|
|
543
683
|
value !== null &&
|
|
544
684
|
builderBuilds.has(value));
|
|
545
685
|
},
|
|
546
|
-
build(builder, defaultStorageFactory) {
|
|
686
|
+
build(builder, defaultStorageFactory, defaultAi) {
|
|
547
687
|
const build = builderBuilds.get(builder);
|
|
548
688
|
if (build === undefined) {
|
|
549
689
|
throw new TypeError("Builder access requires a BoundedContextBuilder instance.");
|
|
550
690
|
}
|
|
551
|
-
return build(defaultStorageFactory);
|
|
691
|
+
return build(defaultStorageFactory, defaultAi);
|
|
552
692
|
},
|
|
553
693
|
subscribeToEvent(context, typeUrl, subscriber) {
|
|
554
694
|
const subscribe = eventSubscribers.get(context);
|
|
@@ -627,6 +767,7 @@ export class BoundedContextBuilder {
|
|
|
627
767
|
#generatedRepositoryOptions = new Map();
|
|
628
768
|
#deliveryStrategy = UniformAcrossAllShards.singleShard();
|
|
629
769
|
#storageFactory;
|
|
770
|
+
#aiRegistry;
|
|
630
771
|
#subscriptionRegistry;
|
|
631
772
|
#persistSystemEvents = false;
|
|
632
773
|
#generatedRegistryRoot;
|
|
@@ -645,7 +786,7 @@ export class BoundedContextBuilder {
|
|
|
645
786
|
constructor(specSnapshot, token) {
|
|
646
787
|
ContextParts.requireFrameworkConstructionToken(token, "BoundedContextBuilder instances are framework-owned.");
|
|
647
788
|
this.#specSnapshot = ContextParts.cloneSpecSnapshot(specSnapshot);
|
|
648
|
-
builderBuilds.set(this, (defaultStorageFactory) => this.#buildAsyncWith(defaultStorageFactory));
|
|
789
|
+
builderBuilds.set(this, (defaultStorageFactory, defaultAi) => this.#buildAsyncWith(defaultStorageFactory, defaultAi));
|
|
649
790
|
Object.freeze(this);
|
|
650
791
|
}
|
|
651
792
|
/**
|
|
@@ -722,6 +863,7 @@ export class BoundedContextBuilder {
|
|
|
722
863
|
* A standalone commander requires generated receiver metadata and therefore
|
|
723
864
|
* this builder's `buildAsync()` path. It installs its Command and Event sides
|
|
724
865
|
* exactly once.
|
|
866
|
+
*
|
|
725
867
|
* @returns This builder for further configuration.
|
|
726
868
|
*/
|
|
727
869
|
addCommandDispatcher(dispatcher) {
|
|
@@ -747,6 +889,7 @@ export class BoundedContextBuilder {
|
|
|
747
889
|
*
|
|
748
890
|
* @param dispatcher Raw event dispatcher, or a standalone reactor/subscriber.
|
|
749
891
|
* Standalone receivers require generated receiver metadata and `buildAsync()`.
|
|
892
|
+
*
|
|
750
893
|
* @returns This builder for further configuration.
|
|
751
894
|
*/
|
|
752
895
|
addEventDispatcher(dispatcher) {
|
|
@@ -791,6 +934,16 @@ export class BoundedContextBuilder {
|
|
|
791
934
|
this.#storageFactory = storageFactory;
|
|
792
935
|
return this;
|
|
793
936
|
}
|
|
937
|
+
/**
|
|
938
|
+
* Sets the application AI registry before this Bounded Context is built.
|
|
939
|
+
*
|
|
940
|
+
* @param registry Factory-created deployment registry.
|
|
941
|
+
* @returns This builder.
|
|
942
|
+
*/
|
|
943
|
+
withAi(registry) {
|
|
944
|
+
this.#aiRegistry = registry;
|
|
945
|
+
return this;
|
|
946
|
+
}
|
|
794
947
|
/**
|
|
795
948
|
* Persists internal system events in the paired System Context storage.
|
|
796
949
|
*
|
|
@@ -846,7 +999,7 @@ export class BoundedContextBuilder {
|
|
|
846
999
|
throw new Error("Standalone generated handlers require buildAsync().");
|
|
847
1000
|
}
|
|
848
1001
|
ContextParts.rejectSyncEntityAssembly(this.#entityTypes);
|
|
849
|
-
return this.#buildWith([...this.#repositories], this.#storageFactory ?? new InMemoryStorageFactory());
|
|
1002
|
+
return this.#buildWith([...this.#repositories], this.#storageFactory ?? new InMemoryStorageFactory(), [], this.#aiRegistry);
|
|
850
1003
|
}
|
|
851
1004
|
/**
|
|
852
1005
|
* Builds a context after loading generated metadata for added entity classes
|
|
@@ -861,10 +1014,10 @@ export class BoundedContextBuilder {
|
|
|
861
1014
|
async buildAsync() {
|
|
862
1015
|
return this.#buildAsyncWith();
|
|
863
1016
|
}
|
|
864
|
-
async #buildAsyncWith(defaultStorageFactory) {
|
|
1017
|
+
async #buildAsyncWith(defaultStorageFactory, defaultAi) {
|
|
865
1018
|
const generated = await this.#loadGeneratedArtifacts([...this.#entityTypes]);
|
|
866
1019
|
const repositories = [...this.#repositories, ...generated.repositories];
|
|
867
|
-
const context = this.#buildWith(repositories, this.#storageFactory ?? defaultStorageFactory ?? new InMemoryStorageFactory(), generated.standalone);
|
|
1020
|
+
const context = this.#buildWith(repositories, this.#storageFactory ?? defaultStorageFactory ?? new InMemoryStorageFactory(), generated.standalone, this.#aiRegistry ?? defaultAi);
|
|
868
1021
|
try {
|
|
869
1022
|
await ContextParts.integrationReady(context);
|
|
870
1023
|
}
|
|
@@ -879,19 +1032,22 @@ export class BoundedContextBuilder {
|
|
|
879
1032
|
}
|
|
880
1033
|
return context;
|
|
881
1034
|
}
|
|
882
|
-
#buildWith(repositories, storageFactory, standalone = []) {
|
|
1035
|
+
#buildWith(repositories, storageFactory, standalone = [], ai) {
|
|
883
1036
|
const resources = this.#subscriptionRegistry === undefined ? {} : { registry: this.#subscriptionRegistry };
|
|
884
1037
|
this.#subscriptionRegistry = undefined;
|
|
885
1038
|
const registeredRepositories = [...repositories];
|
|
886
1039
|
try {
|
|
887
|
-
return this.#assembleContext(registeredRepositories, storageFactory, standalone, resources);
|
|
1040
|
+
return this.#assembleContext(registeredRepositories, storageFactory, standalone, resources, ai);
|
|
888
1041
|
}
|
|
889
1042
|
catch (error) {
|
|
890
1043
|
return this.#failBuild(resources, error);
|
|
891
1044
|
}
|
|
892
1045
|
}
|
|
893
|
-
#assembleContext(repositories, storageFactory, standalone, resources) {
|
|
1046
|
+
#assembleContext(repositories, storageFactory, standalone, resources, ai) {
|
|
894
1047
|
ContextParts.preflightRepositories(repositories);
|
|
1048
|
+
this.#preflightAgents(repositories, storageFactory, ai);
|
|
1049
|
+
if (ai !== undefined)
|
|
1050
|
+
freezeRegistry(ai);
|
|
895
1051
|
const dispatchers = this.#buildDispatchers(repositories);
|
|
896
1052
|
const buses = this.#buildBuses(repositories, storageFactory, dispatchers, resources);
|
|
897
1053
|
const standaloneEvent = this.#installStandalone(standalone, buses);
|
|
@@ -902,13 +1058,56 @@ export class BoundedContextBuilder {
|
|
|
902
1058
|
...ContextParts.standaloneProducedEventSchemas(standalone),
|
|
903
1059
|
]);
|
|
904
1060
|
const running = this.#buildRuntime(storageFactory, buses, resources);
|
|
905
|
-
const context = this.#createContext(repositories, storageFactory, buses, running);
|
|
1061
|
+
const context = this.#createContext(repositories, storageFactory, buses, running, ai);
|
|
906
1062
|
ContextParts.attachIntegration(context, buses.eventBus, buses.systemSpec, ContextParts.externalEventSchemas([
|
|
907
1063
|
...dispatchers.domain,
|
|
908
1064
|
...(standaloneEvent === undefined ? [] : [standaloneEvent]),
|
|
909
1065
|
]));
|
|
910
1066
|
return context;
|
|
911
1067
|
}
|
|
1068
|
+
/**
|
|
1069
|
+
* Rejects missing Agent prerequisites before repository intake is installed.
|
|
1070
|
+
*
|
|
1071
|
+
* @param repositories Repositories selected for this Bounded Context.
|
|
1072
|
+
* @param storageFactory Provider supplying mandatory Agent records.
|
|
1073
|
+
* @param ai Effective Bounded Context or server registry.
|
|
1074
|
+
*/
|
|
1075
|
+
#preflightAgents(repositories, storageFactory, ai) {
|
|
1076
|
+
const agents = repositories.filter((repository) => repository.entityFamily === "agent");
|
|
1077
|
+
if (agents.length === 0)
|
|
1078
|
+
return;
|
|
1079
|
+
if (ai === undefined)
|
|
1080
|
+
throw new TypeError("Agent registration requires an AI registry.");
|
|
1081
|
+
registryOptions(ai);
|
|
1082
|
+
if (!this.#persistSystemEvents)
|
|
1083
|
+
throw new TypeError("Agent registration requires persisted System Events.");
|
|
1084
|
+
if (!AgentHistoryStorageFactories.supports(storageFactory))
|
|
1085
|
+
throw new TypeError("Agent registration requires indexed history storage.");
|
|
1086
|
+
if (!AgentExecutionStorageFactories.supports(storageFactory))
|
|
1087
|
+
throw new TypeError("Agent registration requires durable execution storage.");
|
|
1088
|
+
this.#checkAgentOutputBindings(agents);
|
|
1089
|
+
for (const repository of agents) {
|
|
1090
|
+
const config = repositoryAccess.agentConfiguration(repository);
|
|
1091
|
+
if (config.codeRevision === undefined || config.codeRevision.trim() === "")
|
|
1092
|
+
throw new TypeError("Agent registration requires a code revision.");
|
|
1093
|
+
if (config.ai === undefined)
|
|
1094
|
+
throw new TypeError("Agent registration requires repository capabilities.");
|
|
1095
|
+
if (config.ai.models.some((model) => !isAiModel(model)))
|
|
1096
|
+
throw new TypeError("Agent repository capabilities must be factory-created models.");
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Rejects Agent outcomes whose raw matching dispatcher cannot bind a saved plan.
|
|
1101
|
+
*/
|
|
1102
|
+
#checkAgentOutputBindings(agents) {
|
|
1103
|
+
const rawCommands = new Set([...this.#commandDispatchers].flatMap((dispatcher) => dispatcher.messageSchemas().map((schema) => TypeUrls.derive(schema))));
|
|
1104
|
+
for (const repository of agents) {
|
|
1105
|
+
if (repositoryAccess
|
|
1106
|
+
.producedCommandSchemas(repository)
|
|
1107
|
+
.some((schema) => rawCommands.has(TypeUrls.derive(schema))))
|
|
1108
|
+
throw new TypeError("Agent Command output requires a durable dispatcher binding.");
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
912
1111
|
#buildDispatchers(repositories) {
|
|
913
1112
|
const event = [
|
|
914
1113
|
...ContextParts.repositoryEventDispatchers(repositories),
|
|
@@ -949,7 +1148,7 @@ export class BoundedContextBuilder {
|
|
|
949
1148
|
#buildSystemBuses(storageFactory, dispatchers, resources) {
|
|
950
1149
|
const systemSpec = ContextParts.createSystemSpec(this.#specSnapshot, this.#persistSystemEvents);
|
|
951
1150
|
const systemEventStore = systemSpec.storesEvents
|
|
952
|
-
? new EventStore(ContextParts.createStorageMode(systemSpec), storageFactory)
|
|
1151
|
+
? new EventStore(ContextParts.createStorageMode(systemSpec), storageFactory, systemEventGroup)
|
|
953
1152
|
: undefined;
|
|
954
1153
|
if (systemEventStore !== undefined)
|
|
955
1154
|
resources.systemEventStore = systemEventStore;
|
|
@@ -998,8 +1197,8 @@ export class BoundedContextBuilder {
|
|
|
998
1197
|
resources.runtime = runtime;
|
|
999
1198
|
return { stand, registry, runtime };
|
|
1000
1199
|
}
|
|
1001
|
-
#createContext(repositories, storageFactory, buses, running) {
|
|
1002
|
-
return ContextParts.createBoundedContext(this.#specSnapshot,
|
|
1200
|
+
#createContext(repositories, storageFactory, buses, running, ai) {
|
|
1201
|
+
return ContextParts.createBoundedContext(this.#specSnapshot, storageFactory, repositories, this.#deliveryStrategy, buses, running, ai);
|
|
1003
1202
|
}
|
|
1004
1203
|
#failBuild(resources, error) {
|
|
1005
1204
|
const cleanupErrors = [];
|
|
@@ -1271,40 +1470,45 @@ const ContextParts = Object.freeze({
|
|
|
1271
1470
|
* Creates a bounded context from assembled runtime components.
|
|
1272
1471
|
*
|
|
1273
1472
|
* @param specSnapshot Context configuration.
|
|
1274
|
-
* @param commandBus Command dispatch bus.
|
|
1275
|
-
* @param eventBus Domain event bus.
|
|
1276
|
-
* @param systemEventBus System event bus.
|
|
1277
|
-
* @param publisher Signal publisher.
|
|
1278
|
-
* @param stand Domain read-side Stand.
|
|
1279
|
-
* @param systemStand System read-side Stand.
|
|
1280
|
-
* @param runtime Subscription runtime.
|
|
1281
|
-
* @param systemSpec Paired System specification.
|
|
1282
1473
|
* @param storageFactory Storage provider.
|
|
1283
1474
|
* @param repositories Registered repository views.
|
|
1284
1475
|
* @param deliveryStrategy Delivery sharding strategy.
|
|
1476
|
+
* @param buses Prepared domain and System buses.
|
|
1477
|
+
* @param running Prepared Stand and subscription runtime.
|
|
1478
|
+
* @param ai Effective AI registry when Agent repositories are present.
|
|
1285
1479
|
* @returns Constructed bounded context.
|
|
1286
1480
|
*/
|
|
1287
|
-
createBoundedContext(specSnapshot,
|
|
1481
|
+
createBoundedContext(specSnapshot, storageFactory, repositories, deliveryStrategy, buses, running, ai) {
|
|
1288
1482
|
return constructBoundedContext({
|
|
1289
|
-
snapshot:
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
stand,
|
|
1299
|
-
systemStand,
|
|
1300
|
-
subscriptionRuntime: runtime,
|
|
1301
|
-
systemSpec,
|
|
1483
|
+
snapshot: ContextParts.snapshotFor(specSnapshot),
|
|
1484
|
+
commandBus: buses.commandBus,
|
|
1485
|
+
eventBus: buses.eventBus,
|
|
1486
|
+
systemEventBus: buses.systemEventBus,
|
|
1487
|
+
publisher: buses.publisher,
|
|
1488
|
+
stand: running.stand,
|
|
1489
|
+
systemStand: buses.systemStand,
|
|
1490
|
+
subscriptionRuntime: running.runtime,
|
|
1491
|
+
systemSpec: buses.systemSpec,
|
|
1302
1492
|
storageFactory,
|
|
1303
1493
|
repositories,
|
|
1304
1494
|
deliveryStrategy,
|
|
1495
|
+
...(ai === undefined ? {} : { ai }),
|
|
1305
1496
|
token: frameworkConstructionToken,
|
|
1306
1497
|
});
|
|
1307
1498
|
},
|
|
1499
|
+
/**
|
|
1500
|
+
* Captures public context identity from the build specification.
|
|
1501
|
+
*
|
|
1502
|
+
* @param specSnapshot Prepared context specification.
|
|
1503
|
+
* @returns Immutable context metadata input.
|
|
1504
|
+
*/
|
|
1505
|
+
snapshotFor(specSnapshot) {
|
|
1506
|
+
return {
|
|
1507
|
+
name: specSnapshot.name,
|
|
1508
|
+
tenantMode: ContextParts.toTenantMode(specSnapshot.multitenant),
|
|
1509
|
+
spec: specSnapshot,
|
|
1510
|
+
};
|
|
1511
|
+
},
|
|
1308
1512
|
/**
|
|
1309
1513
|
* Creates the storage mode represented by a context snapshot.
|
|
1310
1514
|
*
|
|
@@ -2070,7 +2274,7 @@ const ContextParts = Object.freeze({
|
|
|
2070
2274
|
*/
|
|
2071
2275
|
isSystemEventDispatcher(dispatcher) {
|
|
2072
2276
|
const schemas = [...dispatcher.messageSchemas()];
|
|
2073
|
-
const systemSchemas = schemas.filter(
|
|
2277
|
+
const systemSchemas = schemas.filter(isSystemEventSchema);
|
|
2074
2278
|
if (systemSchemas.length > 0 && systemSchemas.length !== schemas.length) {
|
|
2075
2279
|
throw new Error("An EventDispatcher cannot mix domain and system event schemas.");
|
|
2076
2280
|
}
|
|
@@ -2272,17 +2476,7 @@ const ContextParts = Object.freeze({
|
|
|
2272
2476
|
ContextParts.requireRepositoryInstance(repository, "BoundedContext repository registration");
|
|
2273
2477
|
const snapshot = ContextParts.repositorySnapshot(repository);
|
|
2274
2478
|
ContextParts.rejectRegisteredRepository(repository);
|
|
2275
|
-
|
|
2276
|
-
context: registration.storageContext,
|
|
2277
|
-
storageFactory: registration.storageFactory,
|
|
2278
|
-
stand: registration.stand,
|
|
2279
|
-
signalMetadata: new SignalMetadata(),
|
|
2280
|
-
entityInbox: registration.entityInbox,
|
|
2281
|
-
projectionInbox: registration.projectionInbox,
|
|
2282
|
-
publisher: registration.publisher,
|
|
2283
|
-
registerEventSchema: registration.registerEventSchema,
|
|
2284
|
-
registerSystemEventSchema: registration.registerSystemEventSchema,
|
|
2285
|
-
});
|
|
2479
|
+
ContextParts.bindRepositoryRuntime(repository, registration);
|
|
2286
2480
|
const entityInboxTarget = repositoryAccess.entityInboxTarget(repository);
|
|
2287
2481
|
const projectionInboxTarget = repositoryAccess.projectionInboxTarget(repository);
|
|
2288
2482
|
return {
|
|
@@ -2298,6 +2492,32 @@ const ContextParts = Object.freeze({
|
|
|
2298
2492
|
},
|
|
2299
2493
|
};
|
|
2300
2494
|
},
|
|
2495
|
+
/**
|
|
2496
|
+
* Binds Bounded Context services to a prepared repository before target registration.
|
|
2497
|
+
*
|
|
2498
|
+
* @param repository Prepared repository receiving runtime services.
|
|
2499
|
+
* @param registration Bounded Context services and schemas.
|
|
2500
|
+
*/
|
|
2501
|
+
bindRepositoryRuntime(repository, registration) {
|
|
2502
|
+
repositoryAccess.bindRuntime(repository, {
|
|
2503
|
+
context: registration.storageContext,
|
|
2504
|
+
storageFactory: registration.storageFactory,
|
|
2505
|
+
...(registration.ai === undefined ? {} : { ai: registration.ai }),
|
|
2506
|
+
stand: registration.stand,
|
|
2507
|
+
signalMetadata: new SignalMetadata(),
|
|
2508
|
+
entityInbox: registration.entityInbox,
|
|
2509
|
+
projectionInbox: registration.projectionInbox,
|
|
2510
|
+
publisher: registration.publisher,
|
|
2511
|
+
registerEventSchema: registration.registerEventSchema,
|
|
2512
|
+
registerSystemEventSchema: registration.registerSystemEventSchema,
|
|
2513
|
+
publishAgentEvent: registration.publishAgentEvent,
|
|
2514
|
+
prepareSavedCommand: registration.prepareSavedCommand,
|
|
2515
|
+
publishSavedCommand: registration.publishSavedCommand,
|
|
2516
|
+
publishAgentSystemEvent: registration.publishAgentSystemEvent,
|
|
2517
|
+
recordAcceptedSaved: registration.recordAcceptedSaved,
|
|
2518
|
+
wakeAcceptedAgent: registration.wakeAcceptedAgent,
|
|
2519
|
+
});
|
|
2520
|
+
},
|
|
2301
2521
|
/**
|
|
2302
2522
|
* Captures repository metadata needed for context registration.
|
|
2303
2523
|
*
|