@spine-event-engine/server 2.0.0-snapshot.26 → 2.0.0-snapshot.29
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 +61 -8
- package/REFERENCE.md +267 -45
- package/dist/agent/agent-live-ai-runtime.d.ts +1 -1
- package/dist/agent/agent-live-ai-runtime.js +1 -1
- package/dist/agent/agent-live-budget.d.ts +1 -1
- package/dist/agent/agent-live-budget.js +1 -1
- package/dist/agent/agent-live-read-runtime.d.ts +1 -1
- package/dist/agent/agent-live-read-runtime.js +1 -1
- package/dist/browser/browser-admission.d.ts +47 -0
- package/dist/browser/browser-admission.d.ts.map +1 -0
- package/dist/browser/browser-admission.js +200 -0
- package/dist/browser/browser-admission.js.map +1 -0
- package/dist/browser/browser-server.d.ts +14 -7
- package/dist/browser/browser-server.d.ts.map +1 -1
- package/dist/browser/browser-server.js +462 -129
- package/dist/browser/browser-server.js.map +1 -1
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/options.d.ts +48 -2
- package/dist/browser/options.d.ts.map +1 -1
- package/dist/bus/command-bus.d.ts +6 -1
- package/dist/bus/command-bus.d.ts.map +1 -1
- package/dist/bus/command-bus.js +6 -1
- package/dist/bus/command-bus.js.map +1 -1
- package/dist/bus/event-bus.d.ts +6 -1
- package/dist/bus/event-bus.d.ts.map +1 -1
- package/dist/bus/event-bus.js +6 -1
- package/dist/bus/event-bus.js.map +1 -1
- package/dist/context/bounded-context.d.ts +30 -28
- package/dist/context/bounded-context.d.ts.map +1 -1
- package/dist/context/bounded-context.js +137 -83
- package/dist/context/bounded-context.js.map +1 -1
- package/dist/context/entity-inbox.d.ts +12 -17
- package/dist/context/entity-inbox.d.ts.map +1 -1
- package/dist/context/entity-inbox.js +106 -120
- package/dist/context/entity-inbox.js.map +1 -1
- package/dist/context/local-inbox-handoff.d.ts +13 -13
- package/dist/context/local-inbox-handoff.d.ts.map +1 -1
- package/dist/context/local-inbox-handoff.js +60 -32
- package/dist/context/local-inbox-handoff.js.map +1 -1
- package/dist/context/persistent-tenant-index.d.ts +81 -0
- package/dist/context/persistent-tenant-index.d.ts.map +1 -0
- package/dist/context/persistent-tenant-index.js +270 -0
- package/dist/context/persistent-tenant-index.js.map +1 -0
- package/dist/context/projection-handoff.d.ts +13 -11
- package/dist/context/projection-handoff.d.ts.map +1 -1
- package/dist/context/projection-handoff.js +77 -34
- package/dist/context/projection-handoff.js.map +1 -1
- package/dist/context/tenant-index.d.ts +7 -6
- package/dist/context/tenant-index.d.ts.map +1 -1
- package/dist/context/tenant-index.js +2 -188
- package/dist/context/tenant-index.js.map +1 -1
- package/dist/context/tenant-unknown-error.d.ts +2 -2
- package/dist/context/tenant-unknown-error.d.ts.map +1 -1
- package/dist/context/tenant-unknown-error.js +4 -1
- package/dist/context/tenant-unknown-error.js.map +1 -1
- package/dist/delivery/delivery-builder.d.ts +8 -7
- package/dist/delivery/delivery-builder.d.ts.map +1 -1
- package/dist/delivery/delivery-builder.js +2 -2
- package/dist/delivery/delivery-builder.js.map +1 -1
- package/dist/delivery/delivery-ports.d.ts +2 -2
- package/dist/delivery/delivery-supervisor.d.ts.map +1 -1
- package/dist/delivery/delivery-supervisor.js +12 -3
- package/dist/delivery/delivery-supervisor.js.map +1 -1
- package/dist/delivery/delivery.d.ts +4 -3
- package/dist/delivery/delivery.d.ts.map +1 -1
- package/dist/delivery/delivery.js +87 -38
- package/dist/delivery/delivery.js.map +1 -1
- package/dist/delivery/inbox-retention.d.ts +7 -0
- package/dist/delivery/inbox-retention.d.ts.map +1 -0
- package/dist/delivery/inbox-retention.js +29 -0
- package/dist/delivery/inbox-retention.js.map +1 -0
- package/dist/delivery/inbox-storage.d.ts +2 -2
- package/dist/delivery/inbox-storage.d.ts.map +1 -1
- package/dist/delivery/inbox-storage.js +32 -8
- package/dist/delivery/inbox-storage.js.map +1 -1
- package/dist/delivery/inbox.d.ts +5 -9
- package/dist/delivery/inbox.d.ts.map +1 -1
- package/dist/delivery/inbox.js +4 -6
- package/dist/delivery/inbox.js.map +1 -1
- package/dist/delivery/reception-observation.d.ts +3 -3
- package/dist/delivery/reception-observation.js +2 -2
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/repository/command-routing.d.ts +1 -1
- package/dist/repository/command-routing.js +1 -1
- package/dist/repository/event-routing.d.ts +1 -1
- package/dist/repository/event-routing.js +1 -1
- package/dist/repository/repository.d.ts +25 -33
- package/dist/repository/repository.d.ts.map +1 -1
- package/dist/repository/repository.js +245 -230
- package/dist/repository/repository.js.map +1 -1
- package/dist/repository/state-update-routing.d.ts +1 -1
- package/dist/repository/state-update-routing.js +1 -1
- package/dist/runtime/signal-publisher.d.ts +23 -8
- package/dist/runtime/signal-publisher.d.ts.map +1 -1
- package/dist/runtime/signal-publisher.js +11 -8
- package/dist/runtime/signal-publisher.js.map +1 -1
- package/dist/server/node-coordinator.d.ts.map +1 -1
- package/dist/server/node-coordinator.js +220 -54
- package/dist/server/node-coordinator.js.map +1 -1
- package/dist/server/server-environment.d.ts +6 -5
- package/dist/server/server-environment.d.ts.map +1 -1
- package/dist/server/server-environment.js +13 -9
- package/dist/server/server-environment.js.map +1 -1
- package/dist/server/server.js +1 -0
- package/dist/server/server.js.map +1 -1
- package/dist/services/app-query-execution.js +2 -2
- package/dist/services/app-query-execution.js.map +1 -1
- package/dist/services/native-operation.d.ts +34 -0
- package/dist/services/native-operation.d.ts.map +1 -0
- package/dist/services/native-operation.js +77 -0
- package/dist/services/native-operation.js.map +1 -0
- package/dist/services/spine-services.d.ts +6 -0
- package/dist/services/spine-services.d.ts.map +1 -1
- package/dist/services/spine-services.js +128 -30
- package/dist/services/spine-services.js.map +1 -1
- package/dist/services/trusted-reader-ingress.d.ts +23 -5
- package/dist/services/trusted-reader-ingress.d.ts.map +1 -1
- package/dist/services/trusted-reader-ingress.js +18 -5
- package/dist/services/trusted-reader-ingress.js.map +1 -1
- package/dist/spi/delivery.d.ts +1 -0
- package/dist/spi/delivery.d.ts.map +1 -1
- package/dist/spi/delivery.js +1 -0
- package/dist/spi/delivery.js.map +1 -1
- package/dist/stand/stand.d.ts +1 -1
- package/dist/stand/stand.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +16 -14
|
@@ -17,10 +17,11 @@ import { deliveryTenantKey } from "../delivery/delivery-tenant.js";
|
|
|
17
17
|
import { Delivery } from "../delivery/delivery.js";
|
|
18
18
|
import { receptionObservation } from "../delivery/reception-observation.js";
|
|
19
19
|
import { ShardIndex } from "../delivery/shard-index.js";
|
|
20
|
+
import { UniformAcrossAllShards } from "../delivery/delivery-builder.js";
|
|
20
21
|
import { DeliveryReadiness, InboxHandoff, } from "./local-inbox-handoff.js";
|
|
21
22
|
const projectionLabels = ["UPDATE_SUBSCRIBER"];
|
|
22
23
|
/**
|
|
23
|
-
* Persists and
|
|
24
|
+
* Persists and delivers delivery rows for projection subscribers.
|
|
24
25
|
*/
|
|
25
26
|
export class LocalProjectionInbox {
|
|
26
27
|
#contextName;
|
|
@@ -28,35 +29,39 @@ export class LocalProjectionInbox {
|
|
|
28
29
|
#endpoints = new Map();
|
|
29
30
|
#readiness;
|
|
30
31
|
#onAdmit;
|
|
32
|
+
/**
|
|
33
|
+
* Selects a shard for each routed Projection target.
|
|
34
|
+
*/
|
|
35
|
+
#strategy;
|
|
31
36
|
#inFlightHandoffs = new Map();
|
|
32
37
|
#inFlightMessageIds = new Set();
|
|
33
38
|
#acknowledgedMessageIds = new Set();
|
|
34
39
|
#nextVersion = 0n;
|
|
35
40
|
/**
|
|
36
41
|
* Creates a local projection inbox.
|
|
37
|
-
* @param contextName Names the
|
|
42
|
+
* @param contextName Names the Bounded Context using this inbox.
|
|
38
43
|
* @param readiness Coordinates delivery readiness after persistence.
|
|
39
|
-
* @param onAdmit Checks current tenant membership before persistence or
|
|
44
|
+
* @param onAdmit Checks current tenant membership before persistence or delivery.
|
|
45
|
+
* @param strategy Selects a shard for each routed Projection target.
|
|
40
46
|
*/
|
|
41
|
-
constructor(contextName, readiness = new DeliveryReadiness(), onAdmit = () => Promise.resolve()) {
|
|
47
|
+
constructor(contextName, readiness = new DeliveryReadiness(), onAdmit = () => Promise.resolve(), strategy = UniformAcrossAllShards.singleShard()) {
|
|
42
48
|
this.#contextName = contextName;
|
|
43
49
|
this.#readiness =
|
|
44
50
|
readiness instanceof DeliveryReadiness ? readiness : new DeliveryReadiness(readiness);
|
|
45
51
|
this.#onAdmit = onAdmit;
|
|
52
|
+
this.#strategy = strategy;
|
|
46
53
|
}
|
|
47
54
|
/**
|
|
48
|
-
* Registers a target that
|
|
55
|
+
* Registers a target that delivers projection messages.
|
|
49
56
|
* @param target Handles messages for one projection type.
|
|
50
57
|
*/
|
|
51
58
|
register(target) {
|
|
52
59
|
this.#targets.set(target.targetTypeUrl, target);
|
|
53
|
-
this.#endpoints.set(target.targetTypeUrl, Object.freeze(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}),
|
|
59
|
-
]));
|
|
60
|
+
this.#endpoints.set(target.targetTypeUrl, Object.freeze(Array.from({ length: this.#strategy.shardCount }, (_, index) => InboxHandoff.endpoint({
|
|
61
|
+
label: projectionLabels[0],
|
|
62
|
+
inboxId: { targetTypeUrl: target.targetTypeUrl },
|
|
63
|
+
shard: new ShardIndex(index, this.#strategy.shardCount),
|
|
64
|
+
}))));
|
|
60
65
|
}
|
|
61
66
|
/**
|
|
62
67
|
* Lists endpoints registered for projection delivery.
|
|
@@ -67,40 +72,56 @@ export class LocalProjectionInbox {
|
|
|
67
72
|
}
|
|
68
73
|
/**
|
|
69
74
|
* Dispatches a durable inbox row through its projection target.
|
|
70
|
-
* @param message Contains the persisted
|
|
75
|
+
* @param message Contains the persisted Inbox row to deliver.
|
|
71
76
|
* @param deliveryTenantId Identifies the tenant that owns the row when present.
|
|
72
|
-
* @returns A promise that resolves after the inbox row is
|
|
77
|
+
* @returns A promise that resolves after the inbox row is delivered.
|
|
73
78
|
*/
|
|
74
|
-
|
|
75
|
-
return this.#
|
|
79
|
+
deliver(message, deliveryTenantId) {
|
|
80
|
+
return this.#deliver(message, deliveryTenantId);
|
|
76
81
|
}
|
|
77
82
|
/**
|
|
78
|
-
* Persists
|
|
79
|
-
* @param delivery Stores and
|
|
83
|
+
* Persists one projection Inbox message and schedules eligible delivery.
|
|
84
|
+
* @param delivery Stores the Inbox row and schedules eligible delivery.
|
|
80
85
|
* @param input Describes the message to persist.
|
|
81
86
|
* @param deliveryTenantId Identifies the tenant that owns the message when present.
|
|
82
|
-
* @returns Resolves
|
|
87
|
+
* @returns Resolves after the Inbox row is persisted and eligible delivery is scheduled.
|
|
83
88
|
*/
|
|
84
89
|
async receive(delivery, input, deliveryTenantId) {
|
|
90
|
+
const routedInput = this.#route(input);
|
|
85
91
|
const routed = this.#readiness.route(delivery);
|
|
86
92
|
return await InboxHandoff.coordinate({
|
|
87
93
|
handoffs: this.#inFlightHandoffs,
|
|
88
|
-
key: InboxHandoff.key(
|
|
89
|
-
onHandoff: () => this.#
|
|
94
|
+
key: InboxHandoff.key(routedInput, deliveryTenantId),
|
|
95
|
+
onHandoff: () => this.#receiveAndSchedule(routed, routedInput, deliveryTenantId),
|
|
90
96
|
});
|
|
91
97
|
}
|
|
92
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Persists one Projection row and schedules eligible delivery separately.
|
|
100
|
+
*
|
|
101
|
+
* @param delivery Delivery used for the stored row.
|
|
102
|
+
* @param input Projection Inbox input.
|
|
103
|
+
* @param deliveryTenantId Tenant selected for the row.
|
|
104
|
+
* @returns The accepted Inbox receipt.
|
|
105
|
+
*/
|
|
106
|
+
async #receiveAndSchedule(delivery, input, deliveryTenantId) {
|
|
93
107
|
await this.#onAdmit(deliveryTenantId);
|
|
94
108
|
const written = await this.#writeInboxRow(delivery, input);
|
|
95
109
|
this.#trackMessage(written.message);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
finally {
|
|
110
|
+
const processing = this.#drainWritten(delivery, written.message, deliveryTenantId);
|
|
111
|
+
void processing
|
|
112
|
+
.finally(() => {
|
|
101
113
|
this.#untrackMessage(written.message);
|
|
102
|
-
}
|
|
114
|
+
})
|
|
115
|
+
.catch(() => undefined);
|
|
116
|
+
return written.message;
|
|
103
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Persists a routed Projection row with its selected shard.
|
|
120
|
+
*
|
|
121
|
+
* @param delivery Delivery containing the Inbox storage.
|
|
122
|
+
* @param input Projection input with its selected shard.
|
|
123
|
+
* @returns The stored Inbox receipt.
|
|
124
|
+
*/
|
|
104
125
|
#writeInboxRow(delivery, input) {
|
|
105
126
|
return delivery.inbox.receive({
|
|
106
127
|
inboxId: input.inboxId,
|
|
@@ -111,7 +132,6 @@ export class LocalProjectionInbox {
|
|
|
111
132
|
whenReceived: Time.currentTime(),
|
|
112
133
|
version: this.#takeVersion(),
|
|
113
134
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
114
|
-
...(input.keepUntil === undefined ? {} : { keepUntil: input.keepUntil }),
|
|
115
135
|
});
|
|
116
136
|
}
|
|
117
137
|
async #drainWritten(delivery, message, deliveryTenantId) {
|
|
@@ -127,14 +147,14 @@ export class LocalProjectionInbox {
|
|
|
127
147
|
delivery,
|
|
128
148
|
received: message,
|
|
129
149
|
node: this.#contextName,
|
|
130
|
-
|
|
150
|
+
onDispatch: (next) => this.#deliver(next, deliveryTenantId),
|
|
131
151
|
acceptMessage: (next) => deliveryTenantKey(next) === deliveryTenantKey(message) &&
|
|
132
152
|
(InboxHandoff.sameMessageId(next.id, message.id) ||
|
|
133
153
|
(next.label === "UPDATE_SUBSCRIBER" && this.#targets.has(next.inboxId.targetTypeUrl))),
|
|
134
154
|
onResolved: (next) => {
|
|
135
155
|
this.#recordAcknowledgement(next);
|
|
136
156
|
},
|
|
137
|
-
|
|
157
|
+
deliveryFailureMessage: "Projection inbox delivery failed.",
|
|
138
158
|
skippedMessage: "Projection inbox delivery was skipped before the target row was delivered.",
|
|
139
159
|
unfinishedMessage: "Projection inbox delivery did not reach the target row before the local drain finished.",
|
|
140
160
|
};
|
|
@@ -159,7 +179,25 @@ export class LocalProjectionInbox {
|
|
|
159
179
|
this.#nextVersion += 1n;
|
|
160
180
|
return this.#nextVersion;
|
|
161
181
|
}
|
|
162
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Selects a shard from the routed Projection ID and state type.
|
|
184
|
+
*
|
|
185
|
+
* @param input Projection update before shard selection.
|
|
186
|
+
* @returns The update with its configured shard.
|
|
187
|
+
*/
|
|
188
|
+
#route(input) {
|
|
189
|
+
return Object.freeze({
|
|
190
|
+
...input,
|
|
191
|
+
shard: this.#strategy.shardFor(input.inboxId.targetId, input.inboxId.targetTypeUrl),
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Validates a stored row against the current shard policy before dispatch.
|
|
196
|
+
*
|
|
197
|
+
* @param message Stored Projection row.
|
|
198
|
+
* @param deliveryTenantId Tenant selected for delivery when present.
|
|
199
|
+
*/
|
|
200
|
+
async #deliver(message, deliveryTenantId) {
|
|
163
201
|
receptionObservation.markManaged();
|
|
164
202
|
_a.#assert(message);
|
|
165
203
|
await this.#onAdmit(deliveryTenantId);
|
|
@@ -167,14 +205,19 @@ export class LocalProjectionInbox {
|
|
|
167
205
|
if (target === undefined) {
|
|
168
206
|
throw new Error(`BoundedContext delivery has no projection subscriber target for "${message.inboxId.targetTypeUrl}".`);
|
|
169
207
|
}
|
|
170
|
-
|
|
208
|
+
const expectedShard = this.#strategy.shardFor(message.inboxId.targetId, message.inboxId.targetTypeUrl);
|
|
209
|
+
if (message.shard.index !== expectedShard.index ||
|
|
210
|
+
message.shard.ofTotal !== expectedShard.ofTotal) {
|
|
211
|
+
throw new Error("Projection Inbox delivery stored shard does not match the routed target.");
|
|
212
|
+
}
|
|
213
|
+
await target.deliver(message, deliveryTenantId);
|
|
171
214
|
}
|
|
172
215
|
static #assert(message) {
|
|
173
216
|
if (message.label !== "UPDATE_SUBSCRIBER") {
|
|
174
217
|
throw new Error(`BoundedContext delivery has no handler for inbox label "${message.label}".`);
|
|
175
218
|
}
|
|
176
219
|
if (message.status !== "TO_DELIVER") {
|
|
177
|
-
throw new Error(`BoundedContext delivery cannot
|
|
220
|
+
throw new Error(`BoundedContext delivery cannot deliver projection inbox message with status "${message.status}".`);
|
|
178
221
|
}
|
|
179
222
|
}
|
|
180
223
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projection-handoff.js","sourceRoot":"","sources":["../../src/context/projection-handoff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAE5E,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"projection-handoff.js","sourceRoot":"","sources":["../../src/context/projection-handoff.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { TenantId } from "@spine-event-engine/proto";
|
|
2
|
-
import type {
|
|
3
|
-
import { type TenantCatalogCursor, type TenantCatalogRead, type TenantCatalogSignal } from "@spine-event-engine/storage/provider";
|
|
2
|
+
import type { TenantCatalogCursor, TenantCatalogRead, TenantCatalogSignal } from "@spine-event-engine/storage/provider";
|
|
4
3
|
/**
|
|
5
4
|
* Finite read request for a live tenant index.
|
|
6
5
|
*/
|
|
@@ -63,9 +62,11 @@ export interface TenantIndexPage {
|
|
|
63
62
|
readonly hasMore: boolean;
|
|
64
63
|
}
|
|
65
64
|
/**
|
|
66
|
-
*
|
|
65
|
+
* Selects single-tenant execution without a tenant directory.
|
|
67
66
|
*/
|
|
68
|
-
export declare const
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
export declare const SINGLE_TENANT: unique symbol;
|
|
68
|
+
/**
|
|
69
|
+
* Selects single-tenant execution or an application-supplied directory.
|
|
70
|
+
*/
|
|
71
|
+
export type TenantIndexSetting = typeof SINGLE_TENANT | TenantIndex;
|
|
71
72
|
//# sourceMappingURL=tenant-index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant-index.d.ts","sourceRoot":"","sources":["../../src/context/tenant-index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"tenant-index.d.ts","sourceRoot":"","sources":["../../src/context/tenant-index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,sCAAsC,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,WAAW;IAG1B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/C;;;;OAIG;IACH,GAAG,IAAI,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC,CAAC;IAEpC;;;;;OAKG;IACH,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAEzD;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,SAAS,QAAQ,EAAE,CAAC;IAElC;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAEnC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,OAAO,MAAgC,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,aAAa,GAAG,WAAW,CAAC"}
|
|
@@ -11,194 +11,8 @@
|
|
|
11
11
|
* or implied. See the License for the specific language governing permissions and limitations under
|
|
12
12
|
* the License.
|
|
13
13
|
*/
|
|
14
|
-
import { TenantBoundary, TenantCatalogReads, } from "@spine-event-engine/storage/provider";
|
|
15
14
|
/**
|
|
16
|
-
*
|
|
15
|
+
* Selects single-tenant execution without a tenant directory.
|
|
17
16
|
*/
|
|
18
|
-
export const
|
|
19
|
-
/**
|
|
20
|
-
* Selects a provider catalog when available without creating records.
|
|
21
|
-
*
|
|
22
|
-
* @param factory Environment storage factory.
|
|
23
|
-
* @returns One live index for the environment lifetime.
|
|
24
|
-
*/
|
|
25
|
-
fromFactory(factory) {
|
|
26
|
-
const provider = factory;
|
|
27
|
-
return typeof provider.tenantCatalog === "function"
|
|
28
|
-
? new StorageTenantIndex(provider.tenantCatalog())
|
|
29
|
-
: new MemoryTenantIndex();
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
/**
|
|
33
|
-
* Adapts a provider catalog to the public live membership contract.
|
|
34
|
-
*/
|
|
35
|
-
class StorageTenantIndex {
|
|
36
|
-
catalog;
|
|
37
|
-
/**
|
|
38
|
-
* Binds the index to a provider catalog.
|
|
39
|
-
*
|
|
40
|
-
* @param catalog Provider catalog retained by its storage factory.
|
|
41
|
-
*/
|
|
42
|
-
constructor(catalog) {
|
|
43
|
-
this.catalog = catalog;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Checks membership through the catalog.
|
|
47
|
-
*
|
|
48
|
-
* @param tenantId Tenant to inspect.
|
|
49
|
-
* @returns Live catalog membership.
|
|
50
|
-
*/
|
|
51
|
-
async contains(tenantId) {
|
|
52
|
-
return this.catalog.contains(TenantBoundary.from(tenantId));
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Lists complete named tenant identities.
|
|
56
|
-
*
|
|
57
|
-
* @returns Complete named tenant identities.
|
|
58
|
-
*/
|
|
59
|
-
async all() {
|
|
60
|
-
return Object.freeze((await this.catalog.all()).map((boundary) => this.named(boundary)));
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Reads a finite provider page.
|
|
64
|
-
*
|
|
65
|
-
* @param request Finite provider page.
|
|
66
|
-
* @returns Complete tenant page.
|
|
67
|
-
*/
|
|
68
|
-
async page(request) {
|
|
69
|
-
TenantCatalogReads.require(request);
|
|
70
|
-
const page = await this.catalog.page(request);
|
|
71
|
-
request.signal.throwIfAborted();
|
|
72
|
-
return {
|
|
73
|
-
ids: page.boundaries.map((boundary) => this.named(boundary)),
|
|
74
|
-
...(page.after === undefined ? {} : { after: page.after }),
|
|
75
|
-
hasMore: page.hasMore,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Registers a tenant through the provider catalog.
|
|
80
|
-
*
|
|
81
|
-
* @param tenantId Tenant to register.
|
|
82
|
-
* @returns Provider confirmation.
|
|
83
|
-
*/
|
|
84
|
-
async keep(tenantId) {
|
|
85
|
-
return this.catalog.keep(TenantBoundary.from(tenantId));
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Validates a named provider boundary.
|
|
89
|
-
*
|
|
90
|
-
* @param boundary Provider boundary.
|
|
91
|
-
* @returns Its complete named identity.
|
|
92
|
-
*/
|
|
93
|
-
named(boundary) {
|
|
94
|
-
if (boundary.single || boundary.tenantId === undefined)
|
|
95
|
-
throw new Error("Multitenant provider catalog returned a single-tenant boundary.");
|
|
96
|
-
return boundary.tenantId;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Retains explicit membership when a custom factory has no catalog.
|
|
101
|
-
*/
|
|
102
|
-
class MemoryTenantIndex {
|
|
103
|
-
#tenants = new Map();
|
|
104
|
-
#order = [];
|
|
105
|
-
#identity = {};
|
|
106
|
-
/**
|
|
107
|
-
* Checks explicit memory membership.
|
|
108
|
-
*
|
|
109
|
-
* @param tenantId Tenant to inspect.
|
|
110
|
-
* @returns Explicit membership.
|
|
111
|
-
*/
|
|
112
|
-
contains(tenantId) {
|
|
113
|
-
return Promise.resolve().then(() => this.#tenants.has(String(TenantBoundary.from(tenantId).key)));
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Lists detached complete tenant identities.
|
|
117
|
-
*
|
|
118
|
-
* @returns Detached complete tenant identities.
|
|
119
|
-
*/
|
|
120
|
-
all() {
|
|
121
|
-
return Promise.resolve(Object.freeze(this.#order.map((boundary) => boundary.tenantId)));
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Reads a bounded page without copying the full directory.
|
|
125
|
-
*
|
|
126
|
-
* @param request Finite page request.
|
|
127
|
-
* @returns Bounded membership page.
|
|
128
|
-
*/
|
|
129
|
-
page(request) {
|
|
130
|
-
return Promise.resolve().then(() => this.readPage(request));
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Reads one page after promise admission.
|
|
134
|
-
*
|
|
135
|
-
* @param request Finite page request.
|
|
136
|
-
* @returns Bounded membership page.
|
|
137
|
-
*/
|
|
138
|
-
readPage(request) {
|
|
139
|
-
TenantCatalogReads.require(request);
|
|
140
|
-
const cursor = request.after;
|
|
141
|
-
if (cursor !== undefined && !(cursor instanceof MemoryTenantIndexCursor))
|
|
142
|
-
throw new TypeError("TenantIndex continuation is invalid.");
|
|
143
|
-
const state = cursor?.position(this.#identity);
|
|
144
|
-
const start = state?.index ?? 0;
|
|
145
|
-
const length = state?.length ?? this.#order.length;
|
|
146
|
-
const end = Math.min(length, start + request.count);
|
|
147
|
-
request.signal.throwIfAborted();
|
|
148
|
-
return {
|
|
149
|
-
ids: this.#order.slice(start, end).map((boundary) => boundary.tenantId),
|
|
150
|
-
...(end < length ? { after: new MemoryTenantIndexCursor(this.#identity, end, length) } : {}),
|
|
151
|
-
hasMore: end < length,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Registers one detached complete tenant identity.
|
|
156
|
-
*
|
|
157
|
-
* @param tenantId Tenant to register.
|
|
158
|
-
* @returns Visible membership completion.
|
|
159
|
-
*/
|
|
160
|
-
keep(tenantId) {
|
|
161
|
-
return Promise.resolve().then(() => {
|
|
162
|
-
const boundary = TenantBoundary.from(tenantId);
|
|
163
|
-
const key = String(boundary.key);
|
|
164
|
-
if (this.#tenants.has(key))
|
|
165
|
-
return;
|
|
166
|
-
this.#tenants.set(key, boundary);
|
|
167
|
-
this.#order.push(boundary);
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Instance-bound continuation for a transient in-memory index.
|
|
173
|
-
*/
|
|
174
|
-
class MemoryTenantIndexCursor {
|
|
175
|
-
[Symbol.toStringTag] = "TenantCatalogCursor";
|
|
176
|
-
#identity;
|
|
177
|
-
#index;
|
|
178
|
-
#length;
|
|
179
|
-
/**
|
|
180
|
-
* Captures one finite sweep position.
|
|
181
|
-
*
|
|
182
|
-
* @param identity Index identity.
|
|
183
|
-
* @param index Next position.
|
|
184
|
-
* @param length Sweep length.
|
|
185
|
-
*/
|
|
186
|
-
constructor(identity, index, length) {
|
|
187
|
-
this.#identity = identity;
|
|
188
|
-
this.#index = index;
|
|
189
|
-
this.#length = length;
|
|
190
|
-
Object.freeze(this);
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Verifies the issuing index before returning the sweep position.
|
|
194
|
-
*
|
|
195
|
-
* @param identity Expected index identity.
|
|
196
|
-
* @returns Finite sweep position.
|
|
197
|
-
*/
|
|
198
|
-
position(identity) {
|
|
199
|
-
if (this.#identity !== identity)
|
|
200
|
-
throw new TypeError("TenantIndex continuation is invalid.");
|
|
201
|
-
return { index: this.#index, length: this.#length };
|
|
202
|
-
}
|
|
203
|
-
}
|
|
17
|
+
export const SINGLE_TENANT = Symbol("SINGLE_TENANT");
|
|
204
18
|
//# sourceMappingURL=tenant-index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant-index.js","sourceRoot":"","sources":["../../src/context/tenant-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"tenant-index.js","sourceRoot":"","sources":["../../src/context/tenant-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAkFH;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAkB,MAAM,CAAC,eAAe,CAAC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TenantId } from "@spine-event-engine/proto";
|
|
2
|
-
import type
|
|
2
|
+
import { type TenantIndexSetting } from "./tenant-index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Identifies a complete tenant absent from a receiving Bounded Context's live index.
|
|
5
5
|
*/
|
|
@@ -28,6 +28,6 @@ export declare class TenantUnknownError extends Error {
|
|
|
28
28
|
* Checks a receiving context's current membership after shape validation.
|
|
29
29
|
*/
|
|
30
30
|
export declare const TenantAdmissions: Readonly<{
|
|
31
|
-
require(index:
|
|
31
|
+
require(index: TenantIndexSetting, contextName: string, multitenant: boolean, tenantId?: TenantId): Promise<void>;
|
|
32
32
|
}>;
|
|
33
33
|
//# sourceMappingURL=tenant-unknown-error.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant-unknown-error.d.ts","sourceRoot":"","sources":["../../src/context/tenant-unknown-error.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"tenant-unknown-error.d.ts","sourceRoot":"","sources":["../../src/context/tenant-unknown-error.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE3E;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;;IAgBzC,QAAQ,CAAC,WAAW,EAAE,MAAM;IAf9B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAG,gBAAgB,CAAU;IAI1C;;;;;OAKG;gBAED,QAAQ,EAAE,QAAQ,EACT,WAAW,EAAE,MAAM;IAW9B;;;;OAIG;IACH,IAAI,QAAQ,IAAI,QAAQ,CAEvB;CACF;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC;IACtC,OAAO,CACL,KAAK,EAAE,kBAAkB,EACzB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,OAAO,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB,CAwBC,CAAC"}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* the License.
|
|
13
13
|
*/
|
|
14
14
|
import { TenantBoundary } from "@spine-event-engine/storage/provider";
|
|
15
|
+
import { SINGLE_TENANT } from "./tenant-index.js";
|
|
15
16
|
/**
|
|
16
17
|
* Identifies a complete tenant absent from a receiving Bounded Context's live index.
|
|
17
18
|
*/
|
|
@@ -53,7 +54,7 @@ export const TenantAdmissions = Object.freeze({
|
|
|
53
54
|
/**
|
|
54
55
|
* Requires live membership before tenant-specific work.
|
|
55
56
|
*
|
|
56
|
-
* @param index Receiving Bounded Context's effective
|
|
57
|
+
* @param index Receiving Bounded Context's marker or effective directory.
|
|
57
58
|
* @param contextName Diagnostic context name.
|
|
58
59
|
* @param multitenant Whether a tenant identity applies.
|
|
59
60
|
* @param tenantId Complete supplied tenant identity, when applicable.
|
|
@@ -67,6 +68,8 @@ export const TenantAdmissions = Object.freeze({
|
|
|
67
68
|
}
|
|
68
69
|
if (tenantId === undefined)
|
|
69
70
|
throw new Error(`Multitenant storage "${contextName}" requires context.tenantId.`);
|
|
71
|
+
if (index === SINGLE_TENANT)
|
|
72
|
+
throw new Error(`Multitenant storage "${contextName}" requires a tenant index.`);
|
|
70
73
|
const boundary = TenantBoundary.from(tenantId);
|
|
71
74
|
if (!(await index.contains(boundary.tenantId)))
|
|
72
75
|
throw new TenantUnknownError(boundary.tenantId, contextName);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant-unknown-error.js","sourceRoot":"","sources":["../../src/context/tenant-unknown-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"tenant-unknown-error.js","sourceRoot":"","sources":["../../src/context/tenant-unknown-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,aAAa,EAA2B,MAAM,mBAAmB,CAAC;AAE3E;;GAEG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAgBhC;IAfX;;OAEG;IACM,IAAI,GAAG,gBAAyB,CAAC;IAEjC,OAAO,CAAyC;IAEzD;;;;;OAKG;IACH,YACE,QAAkB,EACT,WAAmB;QAE5B,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAClC,MAAM,KAAK,GACT,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QACvF,KAAK,CAAC,WAAW,KAAK,2BAA2B,WAAW,GAAG,CAAC,CAAC;QANxD,gBAAW,GAAX,WAAW,CAAQ;QAO5B,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC/B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAOxB,MAAM,CAAC,MAAM,CAAC;IACjB;;;;;;;;OAQG;IACH,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ;QACrD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,QAAQ,KAAK,SAAS;gBACxB,MAAM,IAAI,KAAK,CAAC,0BAA0B,WAAW,qCAAqC,CAAC,CAAC;YAC9F,OAAO;QACT,CAAC;QACD,IAAI,QAAQ,KAAK,SAAS;YACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,WAAW,8BAA8B,CAAC,CAAC;QACrF,IAAI,KAAK,KAAK,aAAa;YACzB,MAAM,IAAI,KAAK,CAAC,wBAAwB,WAAW,4BAA4B,CAAC,CAAC;QACnF,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,IAAI,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -36,7 +36,7 @@ export interface DeliveryControls {
|
|
|
36
36
|
*/
|
|
37
37
|
export declare const deliveryControls: DeliveryControls;
|
|
38
38
|
/**
|
|
39
|
-
* Assigns
|
|
39
|
+
* Assigns Aggregate, Process Manager, and Projection receivers to delivery shards.
|
|
40
40
|
*/
|
|
41
41
|
export interface DeliveryStrategy {
|
|
42
42
|
/**
|
|
@@ -44,13 +44,14 @@ export interface DeliveryStrategy {
|
|
|
44
44
|
*/
|
|
45
45
|
readonly shardCount: number;
|
|
46
46
|
/**
|
|
47
|
-
* Returns the shard for one
|
|
47
|
+
* Returns the shard for one routed receiver ID and its Entity state type.
|
|
48
48
|
*
|
|
49
49
|
* The supplied `Any` contains the typed ID's type URL and bytes. Treat it as
|
|
50
|
-
* immutable typed identity, not as a display string.
|
|
50
|
+
* immutable typed identity, not as a display string. `targetType` is the
|
|
51
|
+
* receiver state message's type URL, rather than the incoming signal type.
|
|
51
52
|
*
|
|
52
|
-
* @param targetId The
|
|
53
|
-
* @param targetType The
|
|
53
|
+
* @param targetId The routed receiver identity.
|
|
54
|
+
* @param targetType The receiver Entity state type URL.
|
|
54
55
|
* @returns The durable shard for the target.
|
|
55
56
|
*/
|
|
56
57
|
shardFor(targetId: Any, targetType: string): ShardIndex;
|
|
@@ -86,8 +87,8 @@ export declare class UniformAcrossAllShards implements DeliveryStrategy {
|
|
|
86
87
|
/**
|
|
87
88
|
* Determines a stable shard from a target identity.
|
|
88
89
|
*
|
|
89
|
-
* @param targetId The
|
|
90
|
-
* @param targetType The
|
|
90
|
+
* @param targetId The routed receiver identity.
|
|
91
|
+
* @param targetType The receiver Entity state type URL.
|
|
91
92
|
* @returns The stable shard for the target.
|
|
92
93
|
*/
|
|
93
94
|
shardFor(targetId: Any, targetType: string): ShardIndex;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery-builder.d.ts","sourceRoot":"","sources":["../../src/delivery/delivery-builder.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAGnE,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAc9C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAG/B;;;;;OAKG;IACH,MAAM,CACJ,QAAQ,EAAE,QAAQ,GACjB,CAAC,CAAC,OAAO,EAAE,qBAAqB,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,SAAS,CAAC;IAE7E;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAErE;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,QAAQ,CAAC;CAC1C;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,gBAiB7B,CAAC;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAG/B;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B
|
|
1
|
+
{"version":3,"file":"delivery-builder.d.ts","sourceRoot":"","sources":["../../src/delivery/delivery-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -83,8 +83,8 @@ export class UniformAcrossAllShards {
|
|
|
83
83
|
/**
|
|
84
84
|
* Determines a stable shard from a target identity.
|
|
85
85
|
*
|
|
86
|
-
* @param targetId The
|
|
87
|
-
* @param targetType The
|
|
86
|
+
* @param targetId The routed receiver identity.
|
|
87
|
+
* @param targetType The receiver Entity state type URL.
|
|
88
88
|
* @returns The stable shard for the target.
|
|
89
89
|
*/
|
|
90
90
|
shardFor(targetId, targetType) {
|