@earendil-works/chord 0.87.1 → 0.99.1
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 +80 -27
- package/dist/api.d.ts +6 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +8 -3
- package/dist/api.js.map +1 -1
- package/dist/bundler.d.ts.map +1 -1
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js.map +1 -1
- package/dist/delta/apply-immutable-trusted.d.ts +4 -0
- package/dist/delta/apply-immutable-trusted.d.ts.map +1 -0
- package/dist/delta/apply-immutable-trusted.js +127 -0
- package/dist/delta/apply-immutable-trusted.js.map +1 -0
- package/dist/{state → delta}/diff.d.ts +1 -1
- package/dist/delta/diff.d.ts.map +1 -0
- package/dist/delta/diff.js +433 -0
- package/dist/delta/diff.js.map +1 -0
- package/dist/delta/draft.d.ts +5 -0
- package/dist/delta/draft.d.ts.map +1 -0
- package/dist/delta/draft.js +2 -0
- package/dist/delta/draft.js.map +1 -0
- package/dist/delta/index.d.ts +11 -21
- package/dist/delta/index.d.ts.map +1 -1
- package/dist/delta/index.js +43 -1341
- package/dist/delta/index.js.map +1 -1
- package/dist/delta/revision-validator.d.ts +7 -0
- package/dist/delta/revision-validator.d.ts.map +1 -0
- package/dist/delta/revision-validator.js +71 -0
- package/dist/delta/revision-validator.js.map +1 -0
- package/dist/delta/tracker.d.ts +26 -0
- package/dist/delta/tracker.d.ts.map +1 -0
- package/dist/delta/tracker.js +2069 -0
- package/dist/delta/tracker.js.map +1 -0
- package/dist/facets/host.d.ts.map +1 -1
- package/dist/facets/host.js.map +1 -1
- package/dist/facets/loader.d.ts.map +1 -1
- package/dist/facets/loader.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/json.d.ts +6 -0
- package/dist/json.d.ts.map +1 -1
- package/dist/json.js +73 -6
- package/dist/json.js.map +1 -1
- package/dist/node/bundle-loader.d.ts.map +1 -1
- package/dist/node/bundle-loader.js.map +1 -1
- package/dist/node/bundle.d.ts.map +1 -1
- package/dist/node/bundle.js.map +1 -1
- package/dist/node/manifest.d.ts.map +1 -1
- package/dist/node/package.d.ts.map +1 -1
- package/dist/node/package.js.map +1 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/services/consumer.d.ts.map +1 -1
- package/dist/services/consumer.js +49 -1
- package/dist/services/consumer.js.map +1 -1
- package/dist/services/errors.d.ts.map +1 -1
- package/dist/services/errors.js.map +1 -1
- package/dist/services/handle.d.ts.map +1 -1
- package/dist/services/handle.js +3 -1
- package/dist/services/handle.js.map +1 -1
- package/dist/services/instances.d.ts +1 -0
- package/dist/services/instances.d.ts.map +1 -1
- package/dist/services/instances.js +3 -0
- package/dist/services/instances.js.map +1 -1
- package/dist/services/loopback.d.ts.map +1 -1
- package/dist/services/loopback.js.map +1 -1
- package/dist/services/provider.d.ts.map +1 -1
- package/dist/services/provider.js +48 -29
- package/dist/services/provider.js.map +1 -1
- package/dist/services/state-codec.d.ts.map +1 -1
- package/dist/services/state-codec.js +18 -0
- package/dist/services/state-codec.js.map +1 -1
- package/dist/services/state-internals.d.ts +5 -2
- package/dist/services/state-internals.d.ts.map +1 -1
- package/dist/services/state-internals.js.map +1 -1
- package/dist/services/state.d.ts +8 -3
- package/dist/services/state.d.ts.map +1 -1
- package/dist/services/state.js +288 -88
- package/dist/services/state.js.map +1 -1
- package/dist/services/wire.d.ts +3 -0
- package/dist/services/wire.d.ts.map +1 -1
- package/dist/services/wire.js +13 -0
- package/dist/services/wire.js.map +1 -1
- package/dist/types.d.ts +74 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +3 -3
- package/src/delta/README.md +143 -360
- package/dist/state/diff.d.ts.map +0 -1
- package/dist/state/diff.js +0 -259
- package/dist/state/diff.js.map +0 -1
- package/dist/state/draft.d.ts +0 -13
- package/dist/state/draft.d.ts.map +0 -1
- package/dist/state/draft.js +0 -540
- package/dist/state/draft.js.map +0 -1
- package/dist/state/value.d.ts +0 -9
- package/dist/state/value.d.ts.map +0 -1
- package/dist/state/value.js +0 -175
- package/dist/state/value.js.map +0 -1
|
@@ -159,6 +159,7 @@ export class RemoteServiceProvider {
|
|
|
159
159
|
buffer: [],
|
|
160
160
|
snapshotSequences: new Map(),
|
|
161
161
|
active: false,
|
|
162
|
+
draining: false,
|
|
162
163
|
terminated: false,
|
|
163
164
|
closed: false,
|
|
164
165
|
};
|
|
@@ -171,22 +172,7 @@ export class RemoteServiceProvider {
|
|
|
171
172
|
if (subscriber.closed || subscriber.active)
|
|
172
173
|
return;
|
|
173
174
|
subscriber.active = true;
|
|
174
|
-
|
|
175
|
-
try {
|
|
176
|
-
for (const entry of subscriber.buffer.splice(0)) {
|
|
177
|
-
try {
|
|
178
|
-
listener(entry.update, entry.context);
|
|
179
|
-
}
|
|
180
|
-
catch (error) {
|
|
181
|
-
errors.push(error);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
finally {
|
|
186
|
-
if (subscriber.terminated)
|
|
187
|
-
subscriber.closed = true;
|
|
188
|
-
}
|
|
189
|
-
throwCollectedErrors(errors, "Failed to activate remote service subscription");
|
|
175
|
+
throwCollectedErrors(drainSubscriber(subscriber), "Failed to activate remote service subscription");
|
|
190
176
|
},
|
|
191
177
|
close: () => {
|
|
192
178
|
if (subscriber.closed)
|
|
@@ -229,7 +215,7 @@ export class RemoteServiceProvider {
|
|
|
229
215
|
}
|
|
230
216
|
}
|
|
231
217
|
for (const subscriber of registration.subscribers) {
|
|
232
|
-
if (subscriber.active) {
|
|
218
|
+
if (subscriber.active && !subscriber.draining) {
|
|
233
219
|
subscriber.closed = true;
|
|
234
220
|
subscriber.buffer.length = 0;
|
|
235
221
|
}
|
|
@@ -326,11 +312,12 @@ export class RemoteServiceProvider {
|
|
|
326
312
|
members.push({ name, kind: "method" });
|
|
327
313
|
}
|
|
328
314
|
else {
|
|
315
|
+
const snapshot = member.state.snapshot();
|
|
329
316
|
members.push({
|
|
330
317
|
name,
|
|
331
318
|
kind: "state",
|
|
332
|
-
sequence:
|
|
333
|
-
ops: [["r",
|
|
319
|
+
sequence: snapshot.sequence,
|
|
320
|
+
ops: [["r", snapshot.value]],
|
|
334
321
|
});
|
|
335
322
|
}
|
|
336
323
|
}
|
|
@@ -344,21 +331,24 @@ export class RemoteServiceProvider {
|
|
|
344
331
|
return;
|
|
345
332
|
const deliveryContext = context ?? serviceDeliveryContext();
|
|
346
333
|
const errors = [];
|
|
347
|
-
|
|
334
|
+
const subscribers = [...registration.subscribers];
|
|
335
|
+
// Queue for everyone before invoking user code, including reentrant publications.
|
|
336
|
+
for (const subscriber of subscribers) {
|
|
348
337
|
if (subscriber.closed || updateCoveredBySnapshot(subscriber.snapshotSequences, update))
|
|
349
338
|
continue;
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
subscriber.buffer.
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
subscriber.listener(entry.update, entry.context);
|
|
339
|
+
if (subscriber.buffer.length === 100) {
|
|
340
|
+
const snapshot = this.#snapshot(registration);
|
|
341
|
+
subscriber.buffer.length = 0;
|
|
342
|
+
subscriber.snapshotSequences.clear();
|
|
343
|
+
recordSnapshotSequences(subscriber.snapshotSequences, snapshot.instances);
|
|
344
|
+
subscriber.buffer.push({ update: { type: "reset", snapshot }, context: deliveryContext });
|
|
357
345
|
}
|
|
358
|
-
|
|
359
|
-
|
|
346
|
+
else {
|
|
347
|
+
subscriber.buffer.push({ update, context: deliveryContext });
|
|
360
348
|
}
|
|
361
349
|
}
|
|
350
|
+
for (const subscriber of subscribers)
|
|
351
|
+
errors.push(...drainSubscriber(subscriber));
|
|
362
352
|
throwCollectedErrors(errors, `Failed to publish remote service ${registration.serviceId} update`);
|
|
363
353
|
}
|
|
364
354
|
#assertRemotable(service) {
|
|
@@ -375,6 +365,31 @@ export class RemoteServiceProvider {
|
|
|
375
365
|
throw new Error("Remote service provider is disposed");
|
|
376
366
|
}
|
|
377
367
|
}
|
|
368
|
+
function drainSubscriber(subscriber) {
|
|
369
|
+
if (!subscriber.active || subscriber.closed || subscriber.draining)
|
|
370
|
+
return [];
|
|
371
|
+
const errors = [];
|
|
372
|
+
subscriber.draining = true;
|
|
373
|
+
try {
|
|
374
|
+
while (!subscriber.closed) {
|
|
375
|
+
const entry = subscriber.buffer.shift();
|
|
376
|
+
if (entry === undefined)
|
|
377
|
+
break;
|
|
378
|
+
try {
|
|
379
|
+
subscriber.listener(entry.update, entry.context);
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
errors.push(error);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
finally {
|
|
387
|
+
subscriber.draining = false;
|
|
388
|
+
if (subscriber.terminated)
|
|
389
|
+
subscriber.closed = true;
|
|
390
|
+
}
|
|
391
|
+
return errors;
|
|
392
|
+
}
|
|
378
393
|
function recordSnapshotSequences(sequences, instances) {
|
|
379
394
|
for (const instance of instances) {
|
|
380
395
|
for (const member of instance.members) {
|
|
@@ -395,6 +410,10 @@ function updateCoveredBySnapshot(sequences, update) {
|
|
|
395
410
|
sequences.delete(key);
|
|
396
411
|
return false;
|
|
397
412
|
}
|
|
413
|
+
case "reset":
|
|
414
|
+
sequences.clear();
|
|
415
|
+
recordSnapshotSequences(sequences, update.snapshot.instances);
|
|
416
|
+
return false;
|
|
398
417
|
case "replaced":
|
|
399
418
|
sequences.clear();
|
|
400
419
|
recordSnapshotSequences(sequences, [update.snapshot]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/services/provider.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tContext,\n\tJsonValue,\n\tRemoteServiceContract,\n\tService,\n\tServiceCall,\n\tServiceCatalogueEntry,\n\tServiceInstanceAddress,\n\tServiceInstanceSnapshot,\n\tServiceMemberSnapshot,\n\tServiceMode,\n\tServiceProviderUpdate,\n\tServiceSubscription,\n\tServiceSubscriptionSnapshot,\n} from \"../types.ts\";\nimport { RemoteServiceError } from \"./errors.ts\";\nimport { serviceDeliveryContext } from \"./state.ts\";\nimport { getReplicatedStateInternals, type ReplicatedStateInternals } from \"./state-internals.ts\";\nimport { decodeServiceControlCall } from \"./wire.ts\";\n\ntype RemoteMethod = (...args: unknown[]) => unknown;\n\ntype InstanceMember =\n\t| { readonly kind: \"method\"; readonly method: RemoteMethod }\n\t| { readonly kind: \"state\"; readonly state: ReplicatedStateInternals };\n\ntype ServiceMemberKind = InstanceMember[\"kind\"];\n\ninterface ClassifiedRemoteServiceImplementation {\n\treadonly implementation: object;\n\treadonly members: Map<string, InstanceMember>;\n}\n\ninterface ProviderInstance {\n\treadonly address?: ServiceInstanceAddress;\n\treadonly implementation: object;\n\treadonly members: ReadonlyMap<string, InstanceMember>;\n\treadonly removeMemberListeners: readonly (() => void)[];\n\tactive: boolean;\n}\n\ninterface ProviderSubscriber {\n\treadonly listener: (update: ServiceProviderUpdate, context: Context) => void;\n\treadonly buffer: { readonly update: ServiceProviderUpdate; readonly context: Context }[];\n\treadonly snapshotSequences: Map<string, number>;\n\tactive: boolean;\n\tterminated: boolean;\n\tclosed: boolean;\n}\n\ninterface ServiceProviderDefinition {\n\treadonly service: { readonly id: string; readonly local?: boolean };\n\treadonly mode: ServiceMode;\n}\n\ninterface ServiceRegistration {\n\treadonly serviceId: string;\n\treadonly mode: ServiceMode;\n\tsingleton?: ProviderInstance;\n\tsingletonShape?: ReadonlyMap<string, ServiceMemberKind>;\n\treadonly instances: Map<string, ProviderInstance>;\n\treadonly generations: Map<string, number>;\n\treadonly subscribers: Set<ProviderSubscriber>;\n}\n\nexport type ServiceUpdatePublisher = (\n\tsubscriptionId: string,\n\tupdate: ServiceProviderUpdate,\n\tcontext: Context,\n) => void | Promise<void>;\n\n/** Hosts one provider for one remote consumer and owns that consumer's subscriptions. */\nexport interface RemoteServiceEndpoint {\n\tinvoke(call: ServiceCall, publish: ServiceUpdatePublisher, context: Context): Promise<JsonValue | undefined>;\n\tdispose(): void;\n}\n\nexport class RemoteServiceProvider {\n\treadonly #catalogue: readonly ServiceCatalogueEntry[];\n\treadonly #registrations = new Map<string, ServiceRegistration>();\n\t#disposed = false;\n\n\tconstructor(entries: readonly (ServiceProviderDefinition | { readonly id: string })[]) {\n\t\tconst definitions = entries.map(\n\t\t\t(entry): ServiceProviderDefinition => (\"service\" in entry ? entry : { service: entry, mode: \"singleton\" }),\n\t\t);\n\t\tfor (const { service } of definitions) {\n\t\t\tif (\"local\" in service && service.local === true) {\n\t\t\t\tthrow new TypeError(`Local service ${service.id} cannot be published remotely`);\n\t\t\t}\n\t\t}\n\t\tconst ids = definitions.map(({ service }) => service.id);\n\t\tif (new Set(ids).size !== ids.length) throw new TypeError(\"Remote service catalogue contains duplicate IDs\");\n\t\tthis.#catalogue = Object.freeze(\n\t\t\tdefinitions.map(({ service, mode }) => Object.freeze({ serviceId: service.id, mode })),\n\t\t);\n\t\tfor (const { service, mode } of definitions) {\n\t\t\tthis.#registrations.set(service.id, {\n\t\t\t\tserviceId: service.id,\n\t\t\t\tmode,\n\t\t\t\tinstances: new Map(),\n\t\t\t\tgenerations: new Map(),\n\t\t\t\tsubscribers: new Set(),\n\t\t\t});\n\t\t}\n\t}\n\n\tget catalogue(): readonly ServiceCatalogueEntry[] {\n\t\treturn this.#catalogue;\n\t}\n\n\tprovide<T>(service: Service<T>, implementation: NoInfer<RemoteServiceContract<T>>): void {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tconst registration = this.#registration(service.id, \"singleton\");\n\t\tif (registration.singleton !== undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_mode_mismatch\", `Remote service ${service.id} already has a provider`);\n\t\t}\n\t\tconst classified = classifyRemoteServiceImplementation(registration.serviceId, implementation);\n\t\tconst shape = serviceMemberShape(classified.members);\n\t\tthis.#assertSingletonShape(registration, shape);\n\t\tregistration.singleton = this.#createInstance(registration, classified, undefined);\n\t\tregistration.singletonShape = shape;\n\t}\n\n\t/** Disconnect one singleton while preserving active subscriptions and remote facades. */\n\twithdraw<T>(service: Service<T>): void {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tconst registration = this.#registration(service.id, \"singleton\");\n\t\tconst previous = registration.singleton;\n\t\tif (previous === undefined) return;\n\t\tprevious.active = false;\n\t\tfor (const remove of previous.removeMemberListeners) remove();\n\t\tdelete registration.singleton;\n\t\tthis.#emit(registration, { type: \"unavailable\" });\n\t}\n\n\t/** Check a singleton replacement without changing the active provider. */\n\tvalidateReplacement<T>(service: Service<T>, implementation: NoInfer<RemoteServiceContract<T>>): void {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tconst registration = this.#registration(service.id, \"singleton\");\n\t\tconst classified = classifyRemoteServiceImplementation(registration.serviceId, implementation);\n\t\tthis.#assertSingletonShape(registration, serviceMemberShape(classified.members));\n\t}\n\n\t/** Replace one singleton without making its stable remote facade unavailable. */\n\treplace<T>(service: Service<T>, implementation: NoInfer<RemoteServiceContract<T>>): void {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tconst registration = this.#registration(service.id, \"singleton\");\n\t\tconst classified = classifyRemoteServiceImplementation(registration.serviceId, implementation);\n\t\tconst shape = serviceMemberShape(classified.members);\n\t\tthis.#assertSingletonShape(registration, shape);\n\t\tconst replacement = this.#createInstance(registration, classified, undefined);\n\t\tconst previous = registration.singleton;\n\t\tif (previous !== undefined) {\n\t\t\tprevious.active = false;\n\t\t\tfor (const remove of previous.removeMemberListeners) remove();\n\t\t}\n\t\tregistration.singleton = replacement;\n\t\tregistration.singletonShape = shape;\n\t\tthis.#emit(registration, { type: \"replaced\", snapshot: this.#snapshotInstance(replacement) });\n\t}\n\n\tuse<T>(service: Service<T>): T {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tconst registration = this.#registrations.get(service.id);\n\t\tif (registration?.mode !== \"singleton\" || registration.singleton === undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_not_found\", `Remote service ${service.id} has no local provider`);\n\t\t}\n\t\treturn registration.singleton.implementation as T;\n\t}\n\n\tspawn<T>(service: Service<T>, key: string, implementation: NoInfer<RemoteServiceContract<T>>): () => void {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tif (key.length === 0) throw new TypeError(\"Remote service instance key must not be empty\");\n\t\tconst registration = this.#registration(service.id, \"keyed\");\n\t\tif (registration.instances.has(key)) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_mode_mismatch\",\n\t\t\t\t`Remote service ${service.id} already has a live instance with key ${key}`,\n\t\t\t);\n\t\t}\n\t\tconst generation = (registration.generations.get(key) ?? 0) + 1;\n\t\tregistration.generations.set(key, generation);\n\t\tconst address = { key, generation } satisfies ServiceInstanceAddress;\n\t\tconst classified = classifyRemoteServiceImplementation(registration.serviceId, implementation);\n\t\tconst instance = this.#createInstance(registration, classified, address);\n\t\tregistration.instances.set(key, instance);\n\t\tthis.#emit(registration, { type: \"spawned\", instance: this.#snapshotInstance(instance) });\n\t\tlet closed = false;\n\t\treturn () => {\n\t\t\tif (closed) return;\n\t\t\tclosed = true;\n\t\t\tif (registration.instances.get(key) !== instance) return;\n\t\t\tinstance.active = false;\n\t\t\tfor (const remove of instance.removeMemberListeners) remove();\n\t\t\tregistration.instances.delete(key);\n\t\t\tthis.#emit(registration, { type: \"closed\", instance: address });\n\t\t};\n\t}\n\n\tasync invoke(call: ServiceCall, context: Context): Promise<JsonValue | undefined> {\n\t\tthis.#assertActive();\n\t\tthis.#assertAllowed(call.serviceId);\n\t\tconst registration = this.#registrations.get(call.serviceId);\n\t\tif (registration === undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_not_found\", `Unknown remote service ${call.serviceId}`);\n\t\t}\n\t\tconst instance = this.#resolveInstance(registration, call.instance);\n\t\tconst member = instance.members.get(call.member);\n\t\tif (member === undefined) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_member_not_found\",\n\t\t\t\t`Unknown remote service member ${call.serviceId}.${call.member}`,\n\t\t\t);\n\t\t}\n\t\tif (member.kind !== \"method\") {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_member_mismatch\",\n\t\t\t\t`Remote service member ${call.serviceId}.${call.member} is not a method`,\n\t\t\t);\n\t\t}\n\t\tconst result: unknown = await Reflect.apply(member.method, instance.implementation, [...call.args, context]);\n\t\treturn result as JsonValue | undefined;\n\t}\n\n\tsubscribe(\n\t\tserviceId: string,\n\t\tmode: ServiceMode,\n\t\tlistener: (update: ServiceProviderUpdate, context: Context) => void,\n\t): ServiceSubscription {\n\t\tthis.#assertActive();\n\t\tthis.#assertAllowed(serviceId);\n\t\tconst registration = this.#registration(serviceId, mode);\n\t\tif (registration.mode === \"singleton\" && registration.singleton === undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_not_found\", `Remote service ${serviceId} has no provider`);\n\t\t}\n\t\tconst subscriber: ProviderSubscriber = {\n\t\t\tlistener,\n\t\t\tbuffer: [],\n\t\t\tsnapshotSequences: new Map(),\n\t\t\tactive: false,\n\t\t\tterminated: false,\n\t\t\tclosed: false,\n\t\t};\n\t\tregistration.subscribers.add(subscriber);\n\t\tconst snapshot = this.#snapshot(registration);\n\t\trecordSnapshotSequences(subscriber.snapshotSequences, snapshot.instances);\n\t\treturn {\n\t\t\tsnapshot,\n\t\t\tactivate: () => {\n\t\t\t\tif (subscriber.closed || subscriber.active) return;\n\t\t\t\tsubscriber.active = true;\n\t\t\t\tconst errors: unknown[] = [];\n\t\t\t\ttry {\n\t\t\t\t\tfor (const entry of subscriber.buffer.splice(0)) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlistener(entry.update, entry.context);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\terrors.push(error);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\tif (subscriber.terminated) subscriber.closed = true;\n\t\t\t\t}\n\t\t\t\tthrowCollectedErrors(errors, \"Failed to activate remote service subscription\");\n\t\t\t},\n\t\t\tclose: () => {\n\t\t\t\tif (subscriber.closed) return;\n\t\t\t\tsubscriber.closed = true;\n\t\t\t\tsubscriber.buffer.length = 0;\n\t\t\t\tregistration.subscribers.delete(subscriber);\n\t\t\t},\n\t\t};\n\t}\n\n\tdispose(): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#disposed = true;\n\t\tconst errors: unknown[] = [];\n\t\tfor (const registration of this.#registrations.values()) {\n\t\t\tconst singleton = registration.singleton;\n\t\t\tif (singleton !== undefined) {\n\t\t\t\tsingleton.active = false;\n\t\t\t\tfor (const remove of singleton.removeMemberListeners) remove();\n\t\t\t\tdelete registration.singleton;\n\t\t\t\ttry {\n\t\t\t\t\tthis.#emit(registration, { type: \"unavailable\" });\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const [key, instance] of [...registration.instances]) {\n\t\t\t\tinstance.active = false;\n\t\t\t\tfor (const remove of instance.removeMemberListeners) remove();\n\t\t\t\tregistration.instances.delete(key);\n\t\t\t\ttry {\n\t\t\t\t\tthis.#emit(registration, { type: \"closed\", instance: instance.address! });\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const subscriber of registration.subscribers) {\n\t\t\t\tif (subscriber.active) {\n\t\t\t\t\tsubscriber.closed = true;\n\t\t\t\t\tsubscriber.buffer.length = 0;\n\t\t\t\t} else {\n\t\t\t\t\tsubscriber.terminated = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tregistration.subscribers.clear();\n\t\t}\n\t\tthis.#registrations.clear();\n\t\tif (errors.length === 1) throw errors[0];\n\t\tif (errors.length > 1) throw new AggregateError(errors, \"Failed to dispose remote service provider\");\n\t}\n\n\t#registration(serviceId: string, mode: ServiceMode): ServiceRegistration {\n\t\tconst registration = this.#registrations.get(serviceId);\n\t\tif (registration === undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_not_found\", `Unknown remote service ${serviceId}`);\n\t\t}\n\t\tif (registration.mode !== mode) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_mode_mismatch\",\n\t\t\t\t`Remote service ${serviceId} is ${registration.mode}, not ${mode}`,\n\t\t\t);\n\t\t}\n\t\treturn registration;\n\t}\n\n\t#createInstance(\n\t\tregistration: ServiceRegistration,\n\t\tclassified: ClassifiedRemoteServiceImplementation,\n\t\taddress: ServiceInstanceAddress | undefined,\n\t): ProviderInstance {\n\t\tconst removeMemberListeners: (() => void)[] = [];\n\t\tconst instance: ProviderInstance = {\n\t\t\t...(address === undefined ? {} : { address }),\n\t\t\timplementation: classified.implementation,\n\t\t\tmembers: classified.members,\n\t\t\tremoveMemberListeners,\n\t\t\tactive: true,\n\t\t};\n\t\tfor (const [name, member] of classified.members) {\n\t\t\tif (member.kind !== \"state\") continue;\n\t\t\tremoveMemberListeners.push(\n\t\t\t\tmember.state.subscribe((ops, sequence, context) => {\n\t\t\t\t\tif (!instance.active) return;\n\t\t\t\t\tthis.#emit(\n\t\t\t\t\t\tregistration,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"state\",\n\t\t\t\t\t\t\t...(address === undefined ? {} : { instance: address }),\n\t\t\t\t\t\t\tmember: name,\n\t\t\t\t\t\t\tsequence,\n\t\t\t\t\t\t\tops,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t);\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn instance;\n\t}\n\n\t#assertSingletonShape(registration: ServiceRegistration, replacement: ReadonlyMap<string, ServiceMemberKind>): void {\n\t\tconst current = registration.singletonShape;\n\t\tif (current === undefined || sameServiceMemberShape(current, replacement)) return;\n\t\tthrow new RemoteServiceError(\n\t\t\t\"service_member_mismatch\",\n\t\t\t`Remote service ${registration.serviceId} replacement must preserve its member shape`,\n\t\t);\n\t}\n\n\t#resolveInstance(registration: ServiceRegistration, address: ServiceInstanceAddress | undefined): ProviderInstance {\n\t\tif (registration.mode === \"singleton\") {\n\t\t\tif (address !== undefined) {\n\t\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\t\"service_mode_mismatch\",\n\t\t\t\t\t`Remote service ${registration.serviceId} is singleton`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (registration.singleton === undefined) {\n\t\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\t\"service_not_found\",\n\t\t\t\t\t`Remote service ${registration.serviceId} has no provider`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn registration.singleton;\n\t\t}\n\t\tif (address === undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_mode_mismatch\", `Remote service ${registration.serviceId} is keyed`);\n\t\t}\n\t\tconst instance = registration.instances.get(address.key);\n\t\tif (instance === undefined) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_instance_not_found\",\n\t\t\t\t`Remote service ${registration.serviceId} has no instance ${address.key}`,\n\t\t\t);\n\t\t}\n\t\tif (instance.address?.generation !== address.generation) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_stale_instance\",\n\t\t\t\t`Remote service ${registration.serviceId} instance ${address.key} is stale`,\n\t\t\t);\n\t\t}\n\t\treturn instance;\n\t}\n\n\t#snapshot(registration: ServiceRegistration): ServiceSubscriptionSnapshot {\n\t\tconst instances =\n\t\t\tregistration.mode === \"singleton\"\n\t\t\t\t? registration.singleton\n\t\t\t\t\t? [this.#snapshotInstance(registration.singleton)]\n\t\t\t\t\t: []\n\t\t\t\t: [...registration.instances.values()]\n\t\t\t\t\t\t.sort((left, right) => left.address!.key.localeCompare(right.address!.key))\n\t\t\t\t\t\t.map((instance) => this.#snapshotInstance(instance));\n\t\treturn { serviceId: registration.serviceId, mode: registration.mode, instances };\n\t}\n\n\t#snapshotInstance(instance: ProviderInstance): ServiceInstanceSnapshot {\n\t\tconst members: ServiceMemberSnapshot[] = [];\n\t\tfor (const [name, member] of instance.members) {\n\t\t\tif (member.kind === \"method\") {\n\t\t\t\tmembers.push({ name, kind: \"method\" });\n\t\t\t} else {\n\t\t\t\tmembers.push({\n\t\t\t\t\tname,\n\t\t\t\t\tkind: \"state\",\n\t\t\t\t\tsequence: member.state.sequence,\n\t\t\t\t\tops: [[\"r\", member.state.value as JsonValue]],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\t...(instance.address === undefined ? {} : { instance: instance.address }),\n\t\t\tmembers,\n\t\t};\n\t}\n\n\t#emit(registration: ServiceRegistration, update: ServiceProviderUpdate, context?: Context): void {\n\t\tif (registration.subscribers.size === 0) return;\n\t\tconst deliveryContext = context ?? serviceDeliveryContext();\n\t\tconst errors: unknown[] = [];\n\t\tfor (const subscriber of registration.subscribers) {\n\t\t\tif (subscriber.closed || updateCoveredBySnapshot(subscriber.snapshotSequences, update)) continue;\n\t\t\tconst entry = { update, context: deliveryContext };\n\t\t\tif (!subscriber.active) {\n\t\t\t\tsubscriber.buffer.push(entry);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tsubscriber.listener(entry.update, entry.context);\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\tthrowCollectedErrors(errors, `Failed to publish remote service ${registration.serviceId} update`);\n\t}\n\n\t#assertRemotable(service: { readonly id: string; readonly local: boolean }): void {\n\t\tif (service.local) throw new RemoteServiceError(\"service_not_allowed\", `Service ${service.id} is process-local`);\n\t}\n\n\t#assertAllowed(serviceId: string): void {\n\t\tif (!this.#registrations.has(serviceId)) {\n\t\t\tthrow new RemoteServiceError(\"service_not_allowed\", `Remote service ${serviceId} is not allowlisted`);\n\t\t}\n\t}\n\n\t#assertActive(): void {\n\t\tif (this.#disposed) throw new Error(\"Remote service provider is disposed\");\n\t}\n}\n\nfunction recordSnapshotSequences(sequences: Map<string, number>, instances: readonly ServiceInstanceSnapshot[]): void {\n\tfor (const instance of instances) {\n\t\tfor (const member of instance.members) {\n\t\t\tif (member.kind === \"state\") sequences.set(stateMemberKey(instance.instance, member.name), member.sequence);\n\t\t}\n\t}\n}\n\nfunction updateCoveredBySnapshot(sequences: Map<string, number>, update: ServiceProviderUpdate): boolean {\n\tswitch (update.type) {\n\t\tcase \"state\": {\n\t\t\tconst key = stateMemberKey(update.instance, update.member);\n\t\t\tconst sequence = sequences.get(key);\n\t\t\tif (sequence === undefined) return false;\n\t\t\tif (update.sequence <= sequence) return true;\n\t\t\tsequences.delete(key);\n\t\t\treturn false;\n\t\t}\n\t\tcase \"replaced\":\n\t\t\tsequences.clear();\n\t\t\trecordSnapshotSequences(sequences, [update.snapshot]);\n\t\t\treturn false;\n\t\tcase \"spawned\":\n\t\t\trecordSnapshotSequences(sequences, [update.instance]);\n\t\t\treturn false;\n\t\tcase \"unavailable\":\n\t\t\tsequences.clear();\n\t\t\treturn false;\n\t\tcase \"closed\": {\n\t\t\tconst prefix = `${JSON.stringify([update.instance.key, update.instance.generation]).slice(0, -1)},`;\n\t\t\tfor (const key of sequences.keys()) {\n\t\t\t\tif (key.startsWith(prefix)) sequences.delete(key);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n\nfunction stateMemberKey(instance: ServiceInstanceAddress | undefined, member: string): string {\n\treturn JSON.stringify(instance === undefined ? [member] : [instance.key, instance.generation, member]);\n}\n\nexport function createRemoteServiceEndpoint(provider: RemoteServiceProvider): RemoteServiceEndpoint {\n\tconst subscriptions = new Map<string, ServiceSubscription>();\n\tlet disposed = false;\n\n\treturn {\n\t\tasync invoke(call, publish, context) {\n\t\t\tif (disposed) throw new Error(\"Remote service endpoint is disposed\");\n\t\t\tconst control = decodeServiceControlCall(call);\n\t\t\tif (control?.type === \"catalogue\") return provider.catalogue as unknown as JsonValue;\n\t\t\tif (control?.type === \"subscribe\") {\n\t\t\t\tif (subscriptions.has(control.subscriptionId)) {\n\t\t\t\t\tthrow new Error(\"Service subscription ID is already active\");\n\t\t\t\t}\n\t\t\t\tconst subscription = provider.subscribe(control.serviceId, control.mode, (update, updateContext) => {\n\t\t\t\t\tvoid Promise.resolve(publish(control.subscriptionId, update, updateContext)).catch(() => {});\n\t\t\t\t});\n\t\t\t\tsubscriptions.set(control.subscriptionId, subscription);\n\t\t\t\tsubscription.activate();\n\t\t\t\treturn subscription.snapshot as unknown as JsonValue;\n\t\t\t}\n\t\t\tif (control?.type === \"unsubscribe\") {\n\t\t\t\tconst subscription = subscriptions.get(control.subscriptionId);\n\t\t\t\tif (subscription === undefined) throw new Error(\"Service subscription was not found\");\n\t\t\t\tsubscription.close();\n\t\t\t\tsubscriptions.delete(control.subscriptionId);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn provider.invoke(call, context);\n\t\t},\n\t\tdispose() {\n\t\t\tif (disposed) return;\n\t\t\tdisposed = true;\n\t\t\tfor (const subscription of subscriptions.values()) subscription.close();\n\t\t\tsubscriptions.clear();\n\t\t},\n\t};\n}\n\nexport function validateRemoteServiceImplementation(serviceId: string, implementation: unknown): void {\n\tvoid classifyRemoteServiceImplementation(serviceId, implementation);\n}\n\nfunction classifyRemoteServiceImplementation(\n\tserviceId: string,\n\timplementation: unknown,\n): ClassifiedRemoteServiceImplementation {\n\tif (typeof implementation !== \"object\" || implementation === null || Array.isArray(implementation)) {\n\t\tthrow new TypeError(`Remote service ${serviceId} implementation must be an object`);\n\t}\n\tconst members = new Map<string, InstanceMember>();\n\tfor (const name of Object.keys(implementation).sort()) {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(implementation, name);\n\t\tif (descriptor === undefined || !(\"value\" in descriptor)) {\n\t\t\tthrow new TypeError(`Remote service member ${serviceId}.${name} must be a data property`);\n\t\t}\n\t\tif (typeof descriptor.value === \"function\") {\n\t\t\tmembers.set(name, { kind: \"method\", method: descriptor.value as RemoteMethod });\n\t\t\tcontinue;\n\t\t}\n\t\tconst state = getReplicatedStateInternals(descriptor.value);\n\t\tif (state !== undefined) {\n\t\t\tmembers.set(name, { kind: \"state\", state });\n\t\t\tcontinue;\n\t\t}\n\t\tthrow new TypeError(`Remote service member ${serviceId}.${name} is not remotely exposable`);\n\t}\n\tif (members.size === 0) throw new TypeError(`Remote service ${serviceId} has no members`);\n\treturn { implementation, members };\n}\n\nfunction throwCollectedErrors(errors: readonly unknown[], message: string): void {\n\tif (errors.length === 1) throw errors[0];\n\tif (errors.length > 1) throw new AggregateError(errors, message);\n}\n\nfunction serviceMemberShape(members: ReadonlyMap<string, InstanceMember>): ReadonlyMap<string, ServiceMemberKind> {\n\treturn new Map([...members].map(([name, member]) => [name, member.kind]));\n}\n\nfunction sameServiceMemberShape(\n\tleft: ReadonlyMap<string, ServiceMemberKind>,\n\tright: ReadonlyMap<string, ServiceMemberKind>,\n): boolean {\n\treturn left.size === right.size && [...left].every(([name, kind]) => right.get(name) === kind);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/services/provider.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAiC,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AA4DrD,MAAM,OAAO,qBAAqB;IACxB,UAAU,CAAmC;IAC7C,cAAc,GAAG,IAAI,GAAG,EAA+B,CAAC;IACjE,SAAS,GAAG,KAAK,CAAC;IAElB,YAAY,OAAyE;QACpF,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAC9B,CAAC,KAAK,EAA6B,EAAE,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAC1G,CAAC;QACF,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,WAAW,EAAE,CAAC;YACvC,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;gBAClD,MAAM,IAAI,SAAS,CAAC,iBAAiB,OAAO,CAAC,EAAE,+BAA+B,CAAC,CAAC;YACjF,CAAC;QACF,CAAC;QACD,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACzD,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,MAAM;YAAE,MAAM,IAAI,SAAS,CAAC,iDAAiD,CAAC,CAAC;QAC7G,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAC9B,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CACtF,CAAC;QACF,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC;YAC7C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE;gBACnC,SAAS,EAAE,OAAO,CAAC,EAAE;gBACrB,IAAI;gBACJ,SAAS,EAAE,IAAI,GAAG,EAAE;gBACpB,WAAW,EAAE,IAAI,GAAG,EAAE;gBACtB,WAAW,EAAE,IAAI,GAAG,EAAE;aACtB,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED,IAAI,SAAS;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;IAED,OAAO,CAAI,OAAmB,EAAE,cAAiD;QAChF,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QACjE,IAAI,YAAY,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAC1C,MAAM,IAAI,kBAAkB,CAAC,uBAAuB,EAAE,kBAAkB,OAAO,CAAC,EAAE,yBAAyB,CAAC,CAAC;QAC9G,CAAC;QACD,MAAM,UAAU,GAAG,mCAAmC,CAAC,YAAY,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAC/F,MAAM,KAAK,GAAG,kBAAkB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAChD,YAAY,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QACnF,YAAY,CAAC,cAAc,GAAG,KAAK,CAAC;IACrC,CAAC;IAED,yFAAyF;IACzF,QAAQ,CAAI,OAAmB;QAC9B,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC;QACxC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO;QACnC,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC;QACxB,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,qBAAqB;YAAE,MAAM,EAAE,CAAC;QAC9D,OAAO,YAAY,CAAC,SAAS,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,0EAA0E;IAC1E,mBAAmB,CAAI,OAAmB,EAAE,cAAiD;QAC5F,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,mCAAmC,CAAC,YAAY,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAC/F,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,kBAAkB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,iFAAiF;IACjF,OAAO,CAAI,OAAmB,EAAE,cAAiD;QAChF,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,mCAAmC,CAAC,YAAY,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAC/F,MAAM,KAAK,GAAG,kBAAkB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAC9E,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC;QACxC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC;YACxB,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,qBAAqB;gBAAE,MAAM,EAAE,CAAC;QAC/D,CAAC;QACD,YAAY,CAAC,SAAS,GAAG,WAAW,CAAC;QACrC,YAAY,CAAC,cAAc,GAAG,KAAK,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,GAAG,CAAI,OAAmB;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACzD,IAAI,YAAY,EAAE,IAAI,KAAK,WAAW,IAAI,YAAY,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAChF,MAAM,IAAI,kBAAkB,CAAC,mBAAmB,EAAE,kBAAkB,OAAO,CAAC,EAAE,wBAAwB,CAAC,CAAC;QACzG,CAAC;QACD,OAAO,YAAY,CAAC,SAAS,CAAC,cAAmB,CAAC;IACnD,CAAC;IAED,KAAK,CAAI,OAAmB,EAAE,GAAW,EAAE,cAAiD;QAC3F,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,+CAA+C,CAAC,CAAC;QAC3F,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7D,IAAI,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,kBAAkB,CAC3B,uBAAuB,EACvB,kBAAkB,OAAO,CAAC,EAAE,yCAAyC,GAAG,EAAE,CAC1E,CAAC;QACH,CAAC;QACD,MAAM,UAAU,GAAG,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAChE,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,UAAU,EAAmC,CAAC;QACrE,MAAM,UAAU,GAAG,mCAAmC,CAAC,YAAY,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAC/F,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QACzE,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1F,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,OAAO,GAAG,EAAE;YACX,IAAI,MAAM;gBAAE,OAAO;YACnB,MAAM,GAAG,IAAI,CAAC;YACd,IAAI,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ;gBAAE,OAAO;YACzD,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC;YACxB,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,qBAAqB;gBAAE,MAAM,EAAE,CAAC;YAC9D,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACjE,CAAC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAiB,EAAE,OAAgB;QAC/C,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,kBAAkB,CAAC,mBAAmB,EAAE,0BAA0B,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,kBAAkB,CAC3B,0BAA0B,EAC1B,iCAAiC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,CAChE,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,kBAAkB,CAC3B,yBAAyB,EACzB,yBAAyB,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,kBAAkB,CACxE,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAY,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7G,OAAO,MAA+B,CAAC;IACxC,CAAC;IAED,SAAS,CACR,SAAiB,EACjB,IAAiB,EACjB,QAAmE;QAEnE,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACzD,IAAI,YAAY,CAAC,IAAI,KAAK,WAAW,IAAI,YAAY,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAC/E,MAAM,IAAI,kBAAkB,CAAC,mBAAmB,EAAE,kBAAkB,SAAS,kBAAkB,CAAC,CAAC;QAClG,CAAC;QACD,MAAM,UAAU,GAAuB;YACtC,QAAQ;YACR,MAAM,EAAE,EAAE;YACV,iBAAiB,EAAE,IAAI,GAAG,EAAE;YAC5B,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,KAAK;YACjB,MAAM,EAAE,KAAK;SACb,CAAC;QACF,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAC9C,uBAAuB,CAAC,UAAU,CAAC,iBAAiB,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC1E,OAAO;YACN,QAAQ;YACR,QAAQ,EAAE,GAAG,EAAE;gBACd,IAAI,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM;oBAAE,OAAO;gBACnD,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC;gBACzB,oBAAoB,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,gDAAgD,CAAC,CAAC;YACrG,CAAC;YACD,KAAK,EAAE,GAAG,EAAE;gBACX,IAAI,UAAU,CAAC,MAAM;oBAAE,OAAO;gBAC9B,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC;gBACzB,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;gBAC7B,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC7C,CAAC;SACD,CAAC;IACH,CAAC;IAED,OAAO;QACN,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC;YACzD,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC;YACzC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC7B,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC;gBACzB,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,qBAAqB;oBAAE,MAAM,EAAE,CAAC;gBAC/D,OAAO,YAAY,CAAC,SAAS,CAAC;gBAC9B,IAAI,CAAC;oBACJ,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;gBACnD,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpB,CAAC;YACF,CAAC;YACD,KAAK,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3D,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC;gBACxB,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,qBAAqB;oBAAE,MAAM,EAAE,CAAC;gBAC9D,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACnC,IAAI,CAAC;oBACJ,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,OAAQ,EAAE,CAAC,CAAC;gBAC3E,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpB,CAAC;YACF,CAAC;YACD,KAAK,MAAM,UAAU,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;gBACnD,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;oBAC/C,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC;oBACzB,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;gBAC9B,CAAC;qBAAM,CAAC;oBACP,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC;gBAC9B,CAAC;YACF,CAAC;YACD,YAAY,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QAClC,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,IAAI,cAAc,CAAC,MAAM,EAAE,2CAA2C,CAAC,CAAC;IACtG,CAAC;IAED,aAAa,CAAC,SAAiB,EAAE,IAAiB;QACjD,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,kBAAkB,CAAC,mBAAmB,EAAE,0BAA0B,SAAS,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,IAAI,YAAY,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAChC,MAAM,IAAI,kBAAkB,CAC3B,uBAAuB,EACvB,kBAAkB,SAAS,OAAO,YAAY,CAAC,IAAI,SAAS,IAAI,EAAE,CAClE,CAAC;QACH,CAAC;QACD,OAAO,YAAY,CAAC;IACrB,CAAC;IAED,eAAe,CACd,YAAiC,EACjC,UAAiD,EACjD,OAA2C;QAE3C,MAAM,qBAAqB,GAAmB,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAqB;YAClC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;YAC7C,cAAc,EAAE,UAAU,CAAC,cAAc;YACzC,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,qBAAqB;YACrB,MAAM,EAAE,IAAI;SACZ,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YACjD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;gBAAE,SAAS;YACtC,qBAAqB,CAAC,IAAI,CACzB,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;gBACjD,IAAI,CAAC,QAAQ,CAAC,MAAM;oBAAE,OAAO;gBAC7B,IAAI,CAAC,KAAK,CACT,YAAY,EACZ;oBACC,IAAI,EAAE,OAAO;oBACb,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;oBACvD,MAAM,EAAE,IAAI;oBACZ,QAAQ;oBACR,GAAG;iBACH,EACD,OAAO,CACP,CAAC;YACH,CAAC,CAAC,CACF,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,qBAAqB,CAAC,YAAiC,EAAE,WAAmD;QAC3G,MAAM,OAAO,GAAG,YAAY,CAAC,cAAc,CAAC;QAC5C,IAAI,OAAO,KAAK,SAAS,IAAI,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC;YAAE,OAAO;QAClF,MAAM,IAAI,kBAAkB,CAC3B,yBAAyB,EACzB,kBAAkB,YAAY,CAAC,SAAS,6CAA6C,CACrF,CAAC;IACH,CAAC;IAED,gBAAgB,CAAC,YAAiC,EAAE,OAA2C;QAC9F,IAAI,YAAY,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACvC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC3B,MAAM,IAAI,kBAAkB,CAC3B,uBAAuB,EACvB,kBAAkB,YAAY,CAAC,SAAS,eAAe,CACvD,CAAC;YACH,CAAC;YACD,IAAI,YAAY,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC1C,MAAM,IAAI,kBAAkB,CAC3B,mBAAmB,EACnB,kBAAkB,YAAY,CAAC,SAAS,kBAAkB,CAC1D,CAAC;YACH,CAAC;YACD,OAAO,YAAY,CAAC,SAAS,CAAC;QAC/B,CAAC;QACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,kBAAkB,CAAC,uBAAuB,EAAE,kBAAkB,YAAY,CAAC,SAAS,WAAW,CAAC,CAAC;QAC5G,CAAC;QACD,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACzD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,IAAI,kBAAkB,CAC3B,4BAA4B,EAC5B,kBAAkB,YAAY,CAAC,SAAS,oBAAoB,OAAO,CAAC,GAAG,EAAE,CACzE,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;YACzD,MAAM,IAAI,kBAAkB,CAC3B,wBAAwB,EACxB,kBAAkB,YAAY,CAAC,SAAS,aAAa,OAAO,CAAC,GAAG,WAAW,CAC3E,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,SAAS,CAAC,YAAiC;QAC1C,MAAM,SAAS,GACd,YAAY,CAAC,IAAI,KAAK,WAAW;YAChC,CAAC,CAAC,YAAY,CAAC,SAAS;gBACvB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;gBAClD,CAAC,CAAC,EAAE;YACL,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;iBACnC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,OAAQ,CAAC,GAAG,CAAC,CAAC;iBAC1E,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzD,OAAO,EAAE,SAAS,EAAE,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;IAClF,CAAC;IAED,iBAAiB,CAAC,QAA0B;QAC3C,MAAM,OAAO,GAA4B,EAAE,CAAC;QAC5C,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC/C,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC9B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YACxC,CAAC;iBAAM,CAAC;gBACP,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACzC,OAAO,CAAC,IAAI,CAAC;oBACZ,IAAI;oBACJ,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,QAAQ,CAAC,QAAQ;oBAC3B,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,KAAkB,CAAC,CAAC;iBACzC,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;QACD,OAAO;YACN,GAAG,CAAC,QAAQ,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;YACzE,OAAO;SACP,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAiC,EAAE,MAA6B,EAAE,OAAiB;QACxF,IAAI,YAAY,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO;QAChD,MAAM,eAAe,GAAG,OAAO,IAAI,sBAAsB,EAAE,CAAC;QAC5D,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,CAAC,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;QAClD,kFAAkF;QAClF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACtC,IAAI,UAAU,CAAC,MAAM,IAAI,uBAAuB,CAAC,UAAU,CAAC,iBAAiB,EAAE,MAAM,CAAC;gBAAE,SAAS;YACjG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;gBAC9C,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;gBAC7B,UAAU,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;gBACrC,uBAAuB,CAAC,UAAU,CAAC,iBAAiB,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;gBAC1E,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;YAC3F,CAAC;iBAAM,CAAC;gBACP,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;YAC9D,CAAC;QACF,CAAC;QACD,KAAK,MAAM,UAAU,IAAI,WAAW;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC;QAClF,oBAAoB,CAAC,MAAM,EAAE,oCAAoC,YAAY,CAAC,SAAS,SAAS,CAAC,CAAC;IACnG,CAAC;IAED,gBAAgB,CAAC,OAAyD;QACzE,IAAI,OAAO,CAAC,KAAK;YAAE,MAAM,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,WAAW,OAAO,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAClH,CAAC;IAED,cAAc,CAAC,SAAiB;QAC/B,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,kBAAkB,SAAS,qBAAqB,CAAC,CAAC;QACvG,CAAC;IACF,CAAC;IAED,aAAa;QACZ,IAAI,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC5E,CAAC;CACD;AAED,SAAS,eAAe,CAAC,UAA8B;IACtD,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IAC9E,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,UAAU,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC;QACJ,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACxC,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM;YAC/B,IAAI,CAAC;gBACJ,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAClD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;QACF,CAAC;IACF,CAAC;YAAS,CAAC;QACV,UAAU,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC5B,IAAI,UAAU,CAAC,UAAU;YAAE,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC;IACrD,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,uBAAuB,CAAC,SAA8B,EAAE,SAA6C;IAC7G,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QAClC,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACvC,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;gBAAE,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7G,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,uBAAuB,CAAC,SAA8B,EAAE,MAA6B;IAC7F,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,OAAO,EAAE,CAAC;YACd,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAC3D,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,QAAQ,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YACzC,IAAI,MAAM,CAAC,QAAQ,IAAI,QAAQ;gBAAE,OAAO,IAAI,CAAC;YAC7C,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACtB,OAAO,KAAK,CAAC;QACd,CAAC;QACD,KAAK,OAAO;YACX,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,uBAAuB,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC9D,OAAO,KAAK,CAAC;QACd,KAAK,UAAU;YACd,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,uBAAuB,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YACtD,OAAO,KAAK,CAAC;QACd,KAAK,SAAS;YACb,uBAAuB,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YACtD,OAAO,KAAK,CAAC;QACd,KAAK,aAAa;YACjB,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,OAAO,KAAK,CAAC;QACd,KAAK,QAAQ,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YACpG,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;gBACpC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;oBAAE,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,cAAc,CAAC,QAA4C,EAAE,MAAc;IACnF,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AACxG,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,QAA+B;IAC1E,MAAM,aAAa,GAAG,IAAI,GAAG,EAA+B,CAAC;IAC7D,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,OAAO;QACN,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO;YAClC,IAAI,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACrE,MAAM,OAAO,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;YAC/C,IAAI,OAAO,EAAE,IAAI,KAAK,WAAW;gBAAE,OAAO,QAAQ,CAAC,SAAiC,CAAC;YACrF,IAAI,OAAO,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;gBACnC,IAAI,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;oBAC/C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;gBAC9D,CAAC;gBACD,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE;oBAClG,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBAC9F,CAAC,CAAC,CAAC;gBACH,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;gBACxD,YAAY,CAAC,QAAQ,EAAE,CAAC;gBACxB,OAAO,YAAY,CAAC,QAAgC,CAAC;YACtD,CAAC;YACD,IAAI,OAAO,EAAE,IAAI,KAAK,aAAa,EAAE,CAAC;gBACrC,MAAM,YAAY,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;gBAC/D,IAAI,YAAY,KAAK,SAAS;oBAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;gBACtF,YAAY,CAAC,KAAK,EAAE,CAAC;gBACrB,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;gBAC7C,OAAO,SAAS,CAAC;YAClB,CAAC;YACD,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvC,CAAC;QACD,OAAO;YACN,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,KAAK,MAAM,YAAY,IAAI,aAAa,CAAC,MAAM,EAAE;gBAAE,YAAY,CAAC,KAAK,EAAE,CAAC;YACxE,aAAa,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;KACD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mCAAmC,CAAC,SAAiB,EAAE,cAAuB;IAC7F,KAAK,mCAAmC,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,mCAAmC,CAC3C,SAAiB,EACjB,cAAuB;IAEvB,IAAI,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QACpG,MAAM,IAAI,SAAS,CAAC,kBAAkB,SAAS,mCAAmC,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAClD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACvD,MAAM,UAAU,GAAG,MAAM,CAAC,wBAAwB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACzE,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,IAAI,UAAU,CAAC,EAAE,CAAC;YAC1D,MAAM,IAAI,SAAS,CAAC,yBAAyB,SAAS,IAAI,IAAI,0BAA0B,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,KAAqB,EAAE,CAAC,CAAC;YAChF,SAAS;QACV,CAAC;QACD,MAAM,KAAK,GAAG,2BAA2B,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5C,SAAS;QACV,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,yBAAyB,SAAS,IAAI,IAAI,4BAA4B,CAAC,CAAC;IAC7F,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,kBAAkB,SAAS,iBAAiB,CAAC,CAAC;IAC1F,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC;AACpC,CAAC;AAED,SAAS,oBAAoB,CAAC,MAA0B,EAAE,OAAe;IACxE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;IACzC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,kBAAkB,CAAC,OAA4C;IACvE,OAAO,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,sBAAsB,CAC9B,IAA4C,EAC5C,KAA6C;IAE7C,OAAO,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;AAChG,CAAC","sourcesContent":["import type {\n\tContext,\n\tJsonValue,\n\tRemoteServiceContract,\n\tService,\n\tServiceCall,\n\tServiceCatalogueEntry,\n\tServiceInstanceAddress,\n\tServiceInstanceSnapshot,\n\tServiceMemberSnapshot,\n\tServiceMode,\n\tServiceProviderUpdate,\n\tServiceSubscription,\n\tServiceSubscriptionSnapshot,\n} from \"../types.ts\";\nimport { RemoteServiceError } from \"./errors.ts\";\nimport { serviceDeliveryContext } from \"./state.ts\";\nimport { getReplicatedStateInternals, type ReplicatedStateInternals } from \"./state-internals.ts\";\nimport { decodeServiceControlCall } from \"./wire.ts\";\n\ntype RemoteMethod = (...args: unknown[]) => unknown;\n\ntype InstanceMember =\n\t| { readonly kind: \"method\"; readonly method: RemoteMethod }\n\t| { readonly kind: \"state\"; readonly state: ReplicatedStateInternals };\n\ntype ServiceMemberKind = InstanceMember[\"kind\"];\n\ninterface ClassifiedRemoteServiceImplementation {\n\treadonly implementation: object;\n\treadonly members: Map<string, InstanceMember>;\n}\n\ninterface ProviderInstance {\n\treadonly address?: ServiceInstanceAddress;\n\treadonly implementation: object;\n\treadonly members: ReadonlyMap<string, InstanceMember>;\n\treadonly removeMemberListeners: readonly (() => void)[];\n\tactive: boolean;\n}\n\ninterface ProviderSubscriber {\n\treadonly listener: (update: ServiceProviderUpdate, context: Context) => void;\n\treadonly buffer: { readonly update: ServiceProviderUpdate; readonly context: Context }[];\n\treadonly snapshotSequences: Map<string, number>;\n\tactive: boolean;\n\tdraining: boolean;\n\tterminated: boolean;\n\tclosed: boolean;\n}\n\ninterface ServiceProviderDefinition {\n\treadonly service: { readonly id: string; readonly local?: boolean };\n\treadonly mode: ServiceMode;\n}\n\ninterface ServiceRegistration {\n\treadonly serviceId: string;\n\treadonly mode: ServiceMode;\n\tsingleton?: ProviderInstance;\n\tsingletonShape?: ReadonlyMap<string, ServiceMemberKind>;\n\treadonly instances: Map<string, ProviderInstance>;\n\treadonly generations: Map<string, number>;\n\treadonly subscribers: Set<ProviderSubscriber>;\n}\n\nexport type ServiceUpdatePublisher = (\n\tsubscriptionId: string,\n\tupdate: ServiceProviderUpdate,\n\tcontext: Context,\n) => void | Promise<void>;\n\n/** Hosts one provider for one remote consumer and owns that consumer's subscriptions. */\nexport interface RemoteServiceEndpoint {\n\tinvoke(call: ServiceCall, publish: ServiceUpdatePublisher, context: Context): Promise<JsonValue | undefined>;\n\tdispose(): void;\n}\n\nexport class RemoteServiceProvider {\n\treadonly #catalogue: readonly ServiceCatalogueEntry[];\n\treadonly #registrations = new Map<string, ServiceRegistration>();\n\t#disposed = false;\n\n\tconstructor(entries: readonly (ServiceProviderDefinition | { readonly id: string })[]) {\n\t\tconst definitions = entries.map(\n\t\t\t(entry): ServiceProviderDefinition => (\"service\" in entry ? entry : { service: entry, mode: \"singleton\" }),\n\t\t);\n\t\tfor (const { service } of definitions) {\n\t\t\tif (\"local\" in service && service.local === true) {\n\t\t\t\tthrow new TypeError(`Local service ${service.id} cannot be published remotely`);\n\t\t\t}\n\t\t}\n\t\tconst ids = definitions.map(({ service }) => service.id);\n\t\tif (new Set(ids).size !== ids.length) throw new TypeError(\"Remote service catalogue contains duplicate IDs\");\n\t\tthis.#catalogue = Object.freeze(\n\t\t\tdefinitions.map(({ service, mode }) => Object.freeze({ serviceId: service.id, mode })),\n\t\t);\n\t\tfor (const { service, mode } of definitions) {\n\t\t\tthis.#registrations.set(service.id, {\n\t\t\t\tserviceId: service.id,\n\t\t\t\tmode,\n\t\t\t\tinstances: new Map(),\n\t\t\t\tgenerations: new Map(),\n\t\t\t\tsubscribers: new Set(),\n\t\t\t});\n\t\t}\n\t}\n\n\tget catalogue(): readonly ServiceCatalogueEntry[] {\n\t\treturn this.#catalogue;\n\t}\n\n\tprovide<T>(service: Service<T>, implementation: NoInfer<RemoteServiceContract<T>>): void {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tconst registration = this.#registration(service.id, \"singleton\");\n\t\tif (registration.singleton !== undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_mode_mismatch\", `Remote service ${service.id} already has a provider`);\n\t\t}\n\t\tconst classified = classifyRemoteServiceImplementation(registration.serviceId, implementation);\n\t\tconst shape = serviceMemberShape(classified.members);\n\t\tthis.#assertSingletonShape(registration, shape);\n\t\tregistration.singleton = this.#createInstance(registration, classified, undefined);\n\t\tregistration.singletonShape = shape;\n\t}\n\n\t/** Disconnect one singleton while preserving active subscriptions and remote facades. */\n\twithdraw<T>(service: Service<T>): void {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tconst registration = this.#registration(service.id, \"singleton\");\n\t\tconst previous = registration.singleton;\n\t\tif (previous === undefined) return;\n\t\tprevious.active = false;\n\t\tfor (const remove of previous.removeMemberListeners) remove();\n\t\tdelete registration.singleton;\n\t\tthis.#emit(registration, { type: \"unavailable\" });\n\t}\n\n\t/** Check a singleton replacement without changing the active provider. */\n\tvalidateReplacement<T>(service: Service<T>, implementation: NoInfer<RemoteServiceContract<T>>): void {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tconst registration = this.#registration(service.id, \"singleton\");\n\t\tconst classified = classifyRemoteServiceImplementation(registration.serviceId, implementation);\n\t\tthis.#assertSingletonShape(registration, serviceMemberShape(classified.members));\n\t}\n\n\t/** Replace one singleton without making its stable remote facade unavailable. */\n\treplace<T>(service: Service<T>, implementation: NoInfer<RemoteServiceContract<T>>): void {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tconst registration = this.#registration(service.id, \"singleton\");\n\t\tconst classified = classifyRemoteServiceImplementation(registration.serviceId, implementation);\n\t\tconst shape = serviceMemberShape(classified.members);\n\t\tthis.#assertSingletonShape(registration, shape);\n\t\tconst replacement = this.#createInstance(registration, classified, undefined);\n\t\tconst previous = registration.singleton;\n\t\tif (previous !== undefined) {\n\t\t\tprevious.active = false;\n\t\t\tfor (const remove of previous.removeMemberListeners) remove();\n\t\t}\n\t\tregistration.singleton = replacement;\n\t\tregistration.singletonShape = shape;\n\t\tthis.#emit(registration, { type: \"replaced\", snapshot: this.#snapshotInstance(replacement) });\n\t}\n\n\tuse<T>(service: Service<T>): T {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tconst registration = this.#registrations.get(service.id);\n\t\tif (registration?.mode !== \"singleton\" || registration.singleton === undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_not_found\", `Remote service ${service.id} has no local provider`);\n\t\t}\n\t\treturn registration.singleton.implementation as T;\n\t}\n\n\tspawn<T>(service: Service<T>, key: string, implementation: NoInfer<RemoteServiceContract<T>>): () => void {\n\t\tthis.#assertActive();\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAllowed(service.id);\n\t\tif (key.length === 0) throw new TypeError(\"Remote service instance key must not be empty\");\n\t\tconst registration = this.#registration(service.id, \"keyed\");\n\t\tif (registration.instances.has(key)) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_mode_mismatch\",\n\t\t\t\t`Remote service ${service.id} already has a live instance with key ${key}`,\n\t\t\t);\n\t\t}\n\t\tconst generation = (registration.generations.get(key) ?? 0) + 1;\n\t\tregistration.generations.set(key, generation);\n\t\tconst address = { key, generation } satisfies ServiceInstanceAddress;\n\t\tconst classified = classifyRemoteServiceImplementation(registration.serviceId, implementation);\n\t\tconst instance = this.#createInstance(registration, classified, address);\n\t\tregistration.instances.set(key, instance);\n\t\tthis.#emit(registration, { type: \"spawned\", instance: this.#snapshotInstance(instance) });\n\t\tlet closed = false;\n\t\treturn () => {\n\t\t\tif (closed) return;\n\t\t\tclosed = true;\n\t\t\tif (registration.instances.get(key) !== instance) return;\n\t\t\tinstance.active = false;\n\t\t\tfor (const remove of instance.removeMemberListeners) remove();\n\t\t\tregistration.instances.delete(key);\n\t\t\tthis.#emit(registration, { type: \"closed\", instance: address });\n\t\t};\n\t}\n\n\tasync invoke(call: ServiceCall, context: Context): Promise<JsonValue | undefined> {\n\t\tthis.#assertActive();\n\t\tthis.#assertAllowed(call.serviceId);\n\t\tconst registration = this.#registrations.get(call.serviceId);\n\t\tif (registration === undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_not_found\", `Unknown remote service ${call.serviceId}`);\n\t\t}\n\t\tconst instance = this.#resolveInstance(registration, call.instance);\n\t\tconst member = instance.members.get(call.member);\n\t\tif (member === undefined) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_member_not_found\",\n\t\t\t\t`Unknown remote service member ${call.serviceId}.${call.member}`,\n\t\t\t);\n\t\t}\n\t\tif (member.kind !== \"method\") {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_member_mismatch\",\n\t\t\t\t`Remote service member ${call.serviceId}.${call.member} is not a method`,\n\t\t\t);\n\t\t}\n\t\tconst result: unknown = await Reflect.apply(member.method, instance.implementation, [...call.args, context]);\n\t\treturn result as JsonValue | undefined;\n\t}\n\n\tsubscribe(\n\t\tserviceId: string,\n\t\tmode: ServiceMode,\n\t\tlistener: (update: ServiceProviderUpdate, context: Context) => void,\n\t): ServiceSubscription {\n\t\tthis.#assertActive();\n\t\tthis.#assertAllowed(serviceId);\n\t\tconst registration = this.#registration(serviceId, mode);\n\t\tif (registration.mode === \"singleton\" && registration.singleton === undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_not_found\", `Remote service ${serviceId} has no provider`);\n\t\t}\n\t\tconst subscriber: ProviderSubscriber = {\n\t\t\tlistener,\n\t\t\tbuffer: [],\n\t\t\tsnapshotSequences: new Map(),\n\t\t\tactive: false,\n\t\t\tdraining: false,\n\t\t\tterminated: false,\n\t\t\tclosed: false,\n\t\t};\n\t\tregistration.subscribers.add(subscriber);\n\t\tconst snapshot = this.#snapshot(registration);\n\t\trecordSnapshotSequences(subscriber.snapshotSequences, snapshot.instances);\n\t\treturn {\n\t\t\tsnapshot,\n\t\t\tactivate: () => {\n\t\t\t\tif (subscriber.closed || subscriber.active) return;\n\t\t\t\tsubscriber.active = true;\n\t\t\t\tthrowCollectedErrors(drainSubscriber(subscriber), \"Failed to activate remote service subscription\");\n\t\t\t},\n\t\t\tclose: () => {\n\t\t\t\tif (subscriber.closed) return;\n\t\t\t\tsubscriber.closed = true;\n\t\t\t\tsubscriber.buffer.length = 0;\n\t\t\t\tregistration.subscribers.delete(subscriber);\n\t\t\t},\n\t\t};\n\t}\n\n\tdispose(): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#disposed = true;\n\t\tconst errors: unknown[] = [];\n\t\tfor (const registration of this.#registrations.values()) {\n\t\t\tconst singleton = registration.singleton;\n\t\t\tif (singleton !== undefined) {\n\t\t\t\tsingleton.active = false;\n\t\t\t\tfor (const remove of singleton.removeMemberListeners) remove();\n\t\t\t\tdelete registration.singleton;\n\t\t\t\ttry {\n\t\t\t\t\tthis.#emit(registration, { type: \"unavailable\" });\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const [key, instance] of [...registration.instances]) {\n\t\t\t\tinstance.active = false;\n\t\t\t\tfor (const remove of instance.removeMemberListeners) remove();\n\t\t\t\tregistration.instances.delete(key);\n\t\t\t\ttry {\n\t\t\t\t\tthis.#emit(registration, { type: \"closed\", instance: instance.address! });\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const subscriber of registration.subscribers) {\n\t\t\t\tif (subscriber.active && !subscriber.draining) {\n\t\t\t\t\tsubscriber.closed = true;\n\t\t\t\t\tsubscriber.buffer.length = 0;\n\t\t\t\t} else {\n\t\t\t\t\tsubscriber.terminated = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tregistration.subscribers.clear();\n\t\t}\n\t\tthis.#registrations.clear();\n\t\tif (errors.length === 1) throw errors[0];\n\t\tif (errors.length > 1) throw new AggregateError(errors, \"Failed to dispose remote service provider\");\n\t}\n\n\t#registration(serviceId: string, mode: ServiceMode): ServiceRegistration {\n\t\tconst registration = this.#registrations.get(serviceId);\n\t\tif (registration === undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_not_found\", `Unknown remote service ${serviceId}`);\n\t\t}\n\t\tif (registration.mode !== mode) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_mode_mismatch\",\n\t\t\t\t`Remote service ${serviceId} is ${registration.mode}, not ${mode}`,\n\t\t\t);\n\t\t}\n\t\treturn registration;\n\t}\n\n\t#createInstance(\n\t\tregistration: ServiceRegistration,\n\t\tclassified: ClassifiedRemoteServiceImplementation,\n\t\taddress: ServiceInstanceAddress | undefined,\n\t): ProviderInstance {\n\t\tconst removeMemberListeners: (() => void)[] = [];\n\t\tconst instance: ProviderInstance = {\n\t\t\t...(address === undefined ? {} : { address }),\n\t\t\timplementation: classified.implementation,\n\t\t\tmembers: classified.members,\n\t\t\tremoveMemberListeners,\n\t\t\tactive: true,\n\t\t};\n\t\tfor (const [name, member] of classified.members) {\n\t\t\tif (member.kind !== \"state\") continue;\n\t\t\tremoveMemberListeners.push(\n\t\t\t\tmember.state.subscribe((ops, sequence, context) => {\n\t\t\t\t\tif (!instance.active) return;\n\t\t\t\t\tthis.#emit(\n\t\t\t\t\t\tregistration,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"state\",\n\t\t\t\t\t\t\t...(address === undefined ? {} : { instance: address }),\n\t\t\t\t\t\t\tmember: name,\n\t\t\t\t\t\t\tsequence,\n\t\t\t\t\t\t\tops,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t);\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn instance;\n\t}\n\n\t#assertSingletonShape(registration: ServiceRegistration, replacement: ReadonlyMap<string, ServiceMemberKind>): void {\n\t\tconst current = registration.singletonShape;\n\t\tif (current === undefined || sameServiceMemberShape(current, replacement)) return;\n\t\tthrow new RemoteServiceError(\n\t\t\t\"service_member_mismatch\",\n\t\t\t`Remote service ${registration.serviceId} replacement must preserve its member shape`,\n\t\t);\n\t}\n\n\t#resolveInstance(registration: ServiceRegistration, address: ServiceInstanceAddress | undefined): ProviderInstance {\n\t\tif (registration.mode === \"singleton\") {\n\t\t\tif (address !== undefined) {\n\t\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\t\"service_mode_mismatch\",\n\t\t\t\t\t`Remote service ${registration.serviceId} is singleton`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (registration.singleton === undefined) {\n\t\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\t\"service_not_found\",\n\t\t\t\t\t`Remote service ${registration.serviceId} has no provider`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn registration.singleton;\n\t\t}\n\t\tif (address === undefined) {\n\t\t\tthrow new RemoteServiceError(\"service_mode_mismatch\", `Remote service ${registration.serviceId} is keyed`);\n\t\t}\n\t\tconst instance = registration.instances.get(address.key);\n\t\tif (instance === undefined) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_instance_not_found\",\n\t\t\t\t`Remote service ${registration.serviceId} has no instance ${address.key}`,\n\t\t\t);\n\t\t}\n\t\tif (instance.address?.generation !== address.generation) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_stale_instance\",\n\t\t\t\t`Remote service ${registration.serviceId} instance ${address.key} is stale`,\n\t\t\t);\n\t\t}\n\t\treturn instance;\n\t}\n\n\t#snapshot(registration: ServiceRegistration): ServiceSubscriptionSnapshot {\n\t\tconst instances =\n\t\t\tregistration.mode === \"singleton\"\n\t\t\t\t? registration.singleton\n\t\t\t\t\t? [this.#snapshotInstance(registration.singleton)]\n\t\t\t\t\t: []\n\t\t\t\t: [...registration.instances.values()]\n\t\t\t\t\t\t.sort((left, right) => left.address!.key.localeCompare(right.address!.key))\n\t\t\t\t\t\t.map((instance) => this.#snapshotInstance(instance));\n\t\treturn { serviceId: registration.serviceId, mode: registration.mode, instances };\n\t}\n\n\t#snapshotInstance(instance: ProviderInstance): ServiceInstanceSnapshot {\n\t\tconst members: ServiceMemberSnapshot[] = [];\n\t\tfor (const [name, member] of instance.members) {\n\t\t\tif (member.kind === \"method\") {\n\t\t\t\tmembers.push({ name, kind: \"method\" });\n\t\t\t} else {\n\t\t\t\tconst snapshot = member.state.snapshot();\n\t\t\t\tmembers.push({\n\t\t\t\t\tname,\n\t\t\t\t\tkind: \"state\",\n\t\t\t\t\tsequence: snapshot.sequence,\n\t\t\t\t\tops: [[\"r\", snapshot.value as JsonValue]],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\t...(instance.address === undefined ? {} : { instance: instance.address }),\n\t\t\tmembers,\n\t\t};\n\t}\n\n\t#emit(registration: ServiceRegistration, update: ServiceProviderUpdate, context?: Context): void {\n\t\tif (registration.subscribers.size === 0) return;\n\t\tconst deliveryContext = context ?? serviceDeliveryContext();\n\t\tconst errors: unknown[] = [];\n\t\tconst subscribers = [...registration.subscribers];\n\t\t// Queue for everyone before invoking user code, including reentrant publications.\n\t\tfor (const subscriber of subscribers) {\n\t\t\tif (subscriber.closed || updateCoveredBySnapshot(subscriber.snapshotSequences, update)) continue;\n\t\t\tif (subscriber.buffer.length === 100) {\n\t\t\t\tconst snapshot = this.#snapshot(registration);\n\t\t\t\tsubscriber.buffer.length = 0;\n\t\t\t\tsubscriber.snapshotSequences.clear();\n\t\t\t\trecordSnapshotSequences(subscriber.snapshotSequences, snapshot.instances);\n\t\t\t\tsubscriber.buffer.push({ update: { type: \"reset\", snapshot }, context: deliveryContext });\n\t\t\t} else {\n\t\t\t\tsubscriber.buffer.push({ update, context: deliveryContext });\n\t\t\t}\n\t\t}\n\t\tfor (const subscriber of subscribers) errors.push(...drainSubscriber(subscriber));\n\t\tthrowCollectedErrors(errors, `Failed to publish remote service ${registration.serviceId} update`);\n\t}\n\n\t#assertRemotable(service: { readonly id: string; readonly local: boolean }): void {\n\t\tif (service.local) throw new RemoteServiceError(\"service_not_allowed\", `Service ${service.id} is process-local`);\n\t}\n\n\t#assertAllowed(serviceId: string): void {\n\t\tif (!this.#registrations.has(serviceId)) {\n\t\t\tthrow new RemoteServiceError(\"service_not_allowed\", `Remote service ${serviceId} is not allowlisted`);\n\t\t}\n\t}\n\n\t#assertActive(): void {\n\t\tif (this.#disposed) throw new Error(\"Remote service provider is disposed\");\n\t}\n}\n\nfunction drainSubscriber(subscriber: ProviderSubscriber): unknown[] {\n\tif (!subscriber.active || subscriber.closed || subscriber.draining) return [];\n\tconst errors: unknown[] = [];\n\tsubscriber.draining = true;\n\ttry {\n\t\twhile (!subscriber.closed) {\n\t\t\tconst entry = subscriber.buffer.shift();\n\t\t\tif (entry === undefined) break;\n\t\t\ttry {\n\t\t\t\tsubscriber.listener(entry.update, entry.context);\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tsubscriber.draining = false;\n\t\tif (subscriber.terminated) subscriber.closed = true;\n\t}\n\treturn errors;\n}\n\nfunction recordSnapshotSequences(sequences: Map<string, number>, instances: readonly ServiceInstanceSnapshot[]): void {\n\tfor (const instance of instances) {\n\t\tfor (const member of instance.members) {\n\t\t\tif (member.kind === \"state\") sequences.set(stateMemberKey(instance.instance, member.name), member.sequence);\n\t\t}\n\t}\n}\n\nfunction updateCoveredBySnapshot(sequences: Map<string, number>, update: ServiceProviderUpdate): boolean {\n\tswitch (update.type) {\n\t\tcase \"state\": {\n\t\t\tconst key = stateMemberKey(update.instance, update.member);\n\t\t\tconst sequence = sequences.get(key);\n\t\t\tif (sequence === undefined) return false;\n\t\t\tif (update.sequence <= sequence) return true;\n\t\t\tsequences.delete(key);\n\t\t\treturn false;\n\t\t}\n\t\tcase \"reset\":\n\t\t\tsequences.clear();\n\t\t\trecordSnapshotSequences(sequences, update.snapshot.instances);\n\t\t\treturn false;\n\t\tcase \"replaced\":\n\t\t\tsequences.clear();\n\t\t\trecordSnapshotSequences(sequences, [update.snapshot]);\n\t\t\treturn false;\n\t\tcase \"spawned\":\n\t\t\trecordSnapshotSequences(sequences, [update.instance]);\n\t\t\treturn false;\n\t\tcase \"unavailable\":\n\t\t\tsequences.clear();\n\t\t\treturn false;\n\t\tcase \"closed\": {\n\t\t\tconst prefix = `${JSON.stringify([update.instance.key, update.instance.generation]).slice(0, -1)},`;\n\t\t\tfor (const key of sequences.keys()) {\n\t\t\t\tif (key.startsWith(prefix)) sequences.delete(key);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n\nfunction stateMemberKey(instance: ServiceInstanceAddress | undefined, member: string): string {\n\treturn JSON.stringify(instance === undefined ? [member] : [instance.key, instance.generation, member]);\n}\n\nexport function createRemoteServiceEndpoint(provider: RemoteServiceProvider): RemoteServiceEndpoint {\n\tconst subscriptions = new Map<string, ServiceSubscription>();\n\tlet disposed = false;\n\n\treturn {\n\t\tasync invoke(call, publish, context) {\n\t\t\tif (disposed) throw new Error(\"Remote service endpoint is disposed\");\n\t\t\tconst control = decodeServiceControlCall(call);\n\t\t\tif (control?.type === \"catalogue\") return provider.catalogue as unknown as JsonValue;\n\t\t\tif (control?.type === \"subscribe\") {\n\t\t\t\tif (subscriptions.has(control.subscriptionId)) {\n\t\t\t\t\tthrow new Error(\"Service subscription ID is already active\");\n\t\t\t\t}\n\t\t\t\tconst subscription = provider.subscribe(control.serviceId, control.mode, (update, updateContext) => {\n\t\t\t\t\tvoid Promise.resolve(publish(control.subscriptionId, update, updateContext)).catch(() => {});\n\t\t\t\t});\n\t\t\t\tsubscriptions.set(control.subscriptionId, subscription);\n\t\t\t\tsubscription.activate();\n\t\t\t\treturn subscription.snapshot as unknown as JsonValue;\n\t\t\t}\n\t\t\tif (control?.type === \"unsubscribe\") {\n\t\t\t\tconst subscription = subscriptions.get(control.subscriptionId);\n\t\t\t\tif (subscription === undefined) throw new Error(\"Service subscription was not found\");\n\t\t\t\tsubscription.close();\n\t\t\t\tsubscriptions.delete(control.subscriptionId);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn provider.invoke(call, context);\n\t\t},\n\t\tdispose() {\n\t\t\tif (disposed) return;\n\t\t\tdisposed = true;\n\t\t\tfor (const subscription of subscriptions.values()) subscription.close();\n\t\t\tsubscriptions.clear();\n\t\t},\n\t};\n}\n\nexport function validateRemoteServiceImplementation(serviceId: string, implementation: unknown): void {\n\tvoid classifyRemoteServiceImplementation(serviceId, implementation);\n}\n\nfunction classifyRemoteServiceImplementation(\n\tserviceId: string,\n\timplementation: unknown,\n): ClassifiedRemoteServiceImplementation {\n\tif (typeof implementation !== \"object\" || implementation === null || Array.isArray(implementation)) {\n\t\tthrow new TypeError(`Remote service ${serviceId} implementation must be an object`);\n\t}\n\tconst members = new Map<string, InstanceMember>();\n\tfor (const name of Object.keys(implementation).sort()) {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(implementation, name);\n\t\tif (descriptor === undefined || !(\"value\" in descriptor)) {\n\t\t\tthrow new TypeError(`Remote service member ${serviceId}.${name} must be a data property`);\n\t\t}\n\t\tif (typeof descriptor.value === \"function\") {\n\t\t\tmembers.set(name, { kind: \"method\", method: descriptor.value as RemoteMethod });\n\t\t\tcontinue;\n\t\t}\n\t\tconst state = getReplicatedStateInternals(descriptor.value);\n\t\tif (state !== undefined) {\n\t\t\tmembers.set(name, { kind: \"state\", state });\n\t\t\tcontinue;\n\t\t}\n\t\tthrow new TypeError(`Remote service member ${serviceId}.${name} is not remotely exposable`);\n\t}\n\tif (members.size === 0) throw new TypeError(`Remote service ${serviceId} has no members`);\n\treturn { implementation, members };\n}\n\nfunction throwCollectedErrors(errors: readonly unknown[], message: string): void {\n\tif (errors.length === 1) throw errors[0];\n\tif (errors.length > 1) throw new AggregateError(errors, message);\n}\n\nfunction serviceMemberShape(members: ReadonlyMap<string, InstanceMember>): ReadonlyMap<string, ServiceMemberKind> {\n\treturn new Map([...members].map(([name, member]) => [name, member.kind]));\n}\n\nfunction sameServiceMemberShape(\n\tleft: ReadonlyMap<string, ServiceMemberKind>,\n\tright: ReadonlyMap<string, ServiceMemberKind>,\n): boolean {\n\treturn left.size === right.size && [...left].every(([name, kind]) => right.get(name) === kind);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-codec.d.ts","sourceRoot":"","sources":["../../src/services/state-codec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGX,qBAAqB,EACrB,2BAA2B,EAC3B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,yBAAyB,EAAE,+BAA+B,EAAE,MAAM,WAAW,CAAC;AAE5F,0FAA0F;AAC1F,MAAM,WAAW,mBAAmB;IACnC,cAAc,CAAC,QAAQ,EAAE,2BAA2B,GAAG,+BAA+B,CAAC;IACvF,YAAY,CAAC,MAAM,EAAE,qBAAqB,GAAG,yBAAyB,CAAC;CACvE;AAED,0FAA0F;AAC1F,MAAM,WAAW,mBAAmB;IACnC,cAAc,CAAC,QAAQ,EAAE,+BAA+B,GAAG,2BAA2B,CAAC;IACvF,YAAY,CAAC,MAAM,EAAE,yBAAyB,GAAG,qBAAqB,CAAC;CACvE;AAwCD,wBAAgB,yBAAyB,IAAI,mBAAmB,
|
|
1
|
+
{"version":3,"file":"state-codec.d.ts","sourceRoot":"","sources":["../../src/services/state-codec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGX,qBAAqB,EACrB,2BAA2B,EAC3B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,yBAAyB,EAAE,+BAA+B,EAAE,MAAM,WAAW,CAAC;AAE5F,0FAA0F;AAC1F,MAAM,WAAW,mBAAmB;IACnC,cAAc,CAAC,QAAQ,EAAE,2BAA2B,GAAG,+BAA+B,CAAC;IACvF,YAAY,CAAC,MAAM,EAAE,qBAAqB,GAAG,yBAAyB,CAAC;CACvE;AAED,0FAA0F;AAC1F,MAAM,WAAW,mBAAmB;IACnC,cAAc,CAAC,QAAQ,EAAE,+BAA+B,GAAG,2BAA2B,CAAC;IACvF,YAAY,CAAC,MAAM,EAAE,yBAAyB,GAAG,qBAAqB,CAAC;CACvE;AAwCD,wBAAgB,yBAAyB,IAAI,mBAAmB,CAqC/D;AAED,wBAAgB,yBAAyB,IAAI,mBAAmB,CAqC/D"}
|
|
@@ -41,6 +41,15 @@ export function createServiceStateEncoder() {
|
|
|
41
41
|
},
|
|
42
42
|
encodeUpdate(update) {
|
|
43
43
|
switch (update.type) {
|
|
44
|
+
case "reset":
|
|
45
|
+
codecs.reset();
|
|
46
|
+
return {
|
|
47
|
+
...update,
|
|
48
|
+
snapshot: {
|
|
49
|
+
...update.snapshot,
|
|
50
|
+
instances: update.snapshot.instances.map((instance) => encodeInstance(instance, codecs)),
|
|
51
|
+
},
|
|
52
|
+
};
|
|
44
53
|
case "state":
|
|
45
54
|
return { ...update, ops: codecs.get(update.instance, update.member).encode(update.ops) };
|
|
46
55
|
case "replaced":
|
|
@@ -70,6 +79,15 @@ export function createServiceStateDecoder() {
|
|
|
70
79
|
},
|
|
71
80
|
decodeUpdate(update) {
|
|
72
81
|
switch (update.type) {
|
|
82
|
+
case "reset":
|
|
83
|
+
codecs.reset();
|
|
84
|
+
return {
|
|
85
|
+
...update,
|
|
86
|
+
snapshot: {
|
|
87
|
+
...update.snapshot,
|
|
88
|
+
instances: update.snapshot.instances.map((instance) => decodeInstance(instance, codecs)),
|
|
89
|
+
},
|
|
90
|
+
};
|
|
73
91
|
case "state":
|
|
74
92
|
return { ...update, ops: codecs.get(update.instance, update.member).decode(update.ops) };
|
|
75
93
|
case "replaced":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-codec.js","sourceRoot":"","sources":["../../src/services/state-codec.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Decoder, decoder, type Encoder, encoder } from \"../delta/index.ts\";\nimport type {\n\tServiceInstanceAddress,\n\tServiceInstanceSnapshot,\n\tServiceProviderUpdate,\n\tServiceSubscriptionSnapshot,\n} from \"../types.ts\";\nimport type { WireServiceProviderUpdate, WireServiceSubscriptionSnapshot } from \"./wire.ts\";\n\n/** Stateful operation encoders for every replicated state in one service subscription. */\nexport interface ServiceStateEncoder {\n\tencodeSnapshot(snapshot: ServiceSubscriptionSnapshot): WireServiceSubscriptionSnapshot;\n\tencodeUpdate(update: ServiceProviderUpdate): WireServiceProviderUpdate;\n}\n\n/** Stateful operation decoders for every replicated state in one service subscription. */\nexport interface ServiceStateDecoder {\n\tdecodeSnapshot(snapshot: WireServiceSubscriptionSnapshot): ServiceSubscriptionSnapshot;\n\tdecodeUpdate(update: WireServiceProviderUpdate): ServiceProviderUpdate;\n}\n\ninterface CodecEntry<C> {\n\treadonly instance: ServiceInstanceAddress | undefined;\n\treadonly codec: C;\n}\n\nclass StateCodecRegistry<C> {\n\treadonly #create: () => C;\n\treadonly #entries = new Map<string, CodecEntry<C>>();\n\n\tconstructor(create: () => C) {\n\t\tthis.#create = create;\n\t}\n\n\treset(): void {\n\t\tthis.#entries.clear();\n\t}\n\n\tadd(instance: ServiceInstanceAddress | undefined, member: string): C {\n\t\tconst key = stateKey(instance, member);\n\t\tif (this.#entries.has(key)) throw new Error(`Duplicate service state ${describeState(instance, member)}`);\n\t\tconst codec = this.#create();\n\t\tthis.#entries.set(key, { instance, codec });\n\t\treturn codec;\n\t}\n\n\tget(instance: ServiceInstanceAddress | undefined, member: string): C {\n\t\tconst codec = this.#entries.get(stateKey(instance, member))?.codec;\n\t\tif (codec === undefined) throw new Error(`Unknown service state ${describeState(instance, member)}`);\n\t\treturn codec;\n\t}\n\n\tremoveInstance(instance: ServiceInstanceAddress): void {\n\t\tfor (const [key, entry] of this.#entries) {\n\t\t\tif (sameAddress(entry.instance, instance)) this.#entries.delete(key);\n\t\t}\n\t}\n}\n\nexport function createServiceStateEncoder(): ServiceStateEncoder {\n\tconst codecs = new StateCodecRegistry<Encoder>(encoder);\n\treturn {\n\t\tencodeSnapshot(snapshot) {\n\t\t\tcodecs.reset();\n\t\t\treturn {\n\t\t\t\t...snapshot,\n\t\t\t\tinstances: snapshot.instances.map((instance) => encodeInstance(instance, codecs)),\n\t\t\t};\n\t\t},\n\t\tencodeUpdate(update) {\n\t\t\tswitch (update.type) {\n\t\t\t\tcase \"state\":\n\t\t\t\t\treturn { ...update, ops: codecs.get(update.instance, update.member).encode(update.ops) };\n\t\t\t\tcase \"replaced\":\n\t\t\t\t\tcodecs.reset();\n\t\t\t\t\treturn { ...update, snapshot: encodeInstance(update.snapshot, codecs) };\n\t\t\t\tcase \"spawned\":\n\t\t\t\t\treturn { ...update, instance: encodeInstance(update.instance, codecs) };\n\t\t\t\tcase \"unavailable\":\n\t\t\t\t\tcodecs.reset();\n\t\t\t\t\treturn update;\n\t\t\t\tcase \"closed\":\n\t\t\t\t\tcodecs.removeInstance(update.instance);\n\t\t\t\t\treturn update;\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport function createServiceStateDecoder(): ServiceStateDecoder {\n\tconst codecs = new StateCodecRegistry<Decoder>(decoder);\n\treturn {\n\t\tdecodeSnapshot(snapshot) {\n\t\t\tcodecs.reset();\n\t\t\treturn {\n\t\t\t\t...snapshot,\n\t\t\t\tinstances: snapshot.instances.map((instance) => decodeInstance(instance, codecs)),\n\t\t\t};\n\t\t},\n\t\tdecodeUpdate(update) {\n\t\t\tswitch (update.type) {\n\t\t\t\tcase \"state\":\n\t\t\t\t\treturn { ...update, ops: codecs.get(update.instance, update.member).decode(update.ops) };\n\t\t\t\tcase \"replaced\":\n\t\t\t\t\tcodecs.reset();\n\t\t\t\t\treturn { ...update, snapshot: decodeInstance(update.snapshot, codecs) };\n\t\t\t\tcase \"spawned\":\n\t\t\t\t\treturn { ...update, instance: decodeInstance(update.instance, codecs) };\n\t\t\t\tcase \"unavailable\":\n\t\t\t\t\tcodecs.reset();\n\t\t\t\t\treturn update;\n\t\t\t\tcase \"closed\":\n\t\t\t\t\tcodecs.removeInstance(update.instance);\n\t\t\t\t\treturn update;\n\t\t\t}\n\t\t},\n\t};\n}\n\nfunction encodeInstance(\n\tinstance: ServiceInstanceSnapshot,\n\tcodecs: StateCodecRegistry<Encoder>,\n): WireServiceSubscriptionSnapshot[\"instances\"][number] {\n\treturn {\n\t\t...instance,\n\t\tmembers: instance.members.map((member) =>\n\t\t\tmember.kind === \"state\"\n\t\t\t\t? { ...member, ops: codecs.add(instance.instance, member.name).encode(member.ops) }\n\t\t\t\t: member,\n\t\t),\n\t};\n}\n\nfunction decodeInstance(\n\tinstance: WireServiceSubscriptionSnapshot[\"instances\"][number],\n\tcodecs: StateCodecRegistry<Decoder>,\n): ServiceInstanceSnapshot {\n\treturn {\n\t\t...instance,\n\t\tmembers: instance.members.map((member) =>\n\t\t\tmember.kind === \"state\"\n\t\t\t\t? { ...member, ops: codecs.add(instance.instance, member.name).decode(member.ops) }\n\t\t\t\t: member,\n\t\t),\n\t};\n}\n\nfunction stateKey(instance: ServiceInstanceAddress | undefined, member: string): string {\n\treturn JSON.stringify([instance?.key ?? null, instance?.generation ?? null, member]);\n}\n\nfunction sameAddress(left: ServiceInstanceAddress | undefined, right: ServiceInstanceAddress): boolean {\n\treturn left?.key === right.key && left.generation === right.generation;\n}\n\nfunction describeState(instance: ServiceInstanceAddress | undefined, member: string): string {\n\treturn instance === undefined ? member : `${instance.key}@${instance.generation}.${member}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"state-codec.js","sourceRoot":"","sources":["../../src/services/state-codec.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Decoder, decoder, type Encoder, encoder } from \"../delta/index.ts\";\nimport type {\n\tServiceInstanceAddress,\n\tServiceInstanceSnapshot,\n\tServiceProviderUpdate,\n\tServiceSubscriptionSnapshot,\n} from \"../types.ts\";\nimport type { WireServiceProviderUpdate, WireServiceSubscriptionSnapshot } from \"./wire.ts\";\n\n/** Stateful operation encoders for every replicated state in one service subscription. */\nexport interface ServiceStateEncoder {\n\tencodeSnapshot(snapshot: ServiceSubscriptionSnapshot): WireServiceSubscriptionSnapshot;\n\tencodeUpdate(update: ServiceProviderUpdate): WireServiceProviderUpdate;\n}\n\n/** Stateful operation decoders for every replicated state in one service subscription. */\nexport interface ServiceStateDecoder {\n\tdecodeSnapshot(snapshot: WireServiceSubscriptionSnapshot): ServiceSubscriptionSnapshot;\n\tdecodeUpdate(update: WireServiceProviderUpdate): ServiceProviderUpdate;\n}\n\ninterface CodecEntry<C> {\n\treadonly instance: ServiceInstanceAddress | undefined;\n\treadonly codec: C;\n}\n\nclass StateCodecRegistry<C> {\n\treadonly #create: () => C;\n\treadonly #entries = new Map<string, CodecEntry<C>>();\n\n\tconstructor(create: () => C) {\n\t\tthis.#create = create;\n\t}\n\n\treset(): void {\n\t\tthis.#entries.clear();\n\t}\n\n\tadd(instance: ServiceInstanceAddress | undefined, member: string): C {\n\t\tconst key = stateKey(instance, member);\n\t\tif (this.#entries.has(key)) throw new Error(`Duplicate service state ${describeState(instance, member)}`);\n\t\tconst codec = this.#create();\n\t\tthis.#entries.set(key, { instance, codec });\n\t\treturn codec;\n\t}\n\n\tget(instance: ServiceInstanceAddress | undefined, member: string): C {\n\t\tconst codec = this.#entries.get(stateKey(instance, member))?.codec;\n\t\tif (codec === undefined) throw new Error(`Unknown service state ${describeState(instance, member)}`);\n\t\treturn codec;\n\t}\n\n\tremoveInstance(instance: ServiceInstanceAddress): void {\n\t\tfor (const [key, entry] of this.#entries) {\n\t\t\tif (sameAddress(entry.instance, instance)) this.#entries.delete(key);\n\t\t}\n\t}\n}\n\nexport function createServiceStateEncoder(): ServiceStateEncoder {\n\tconst codecs = new StateCodecRegistry<Encoder>(encoder);\n\treturn {\n\t\tencodeSnapshot(snapshot) {\n\t\t\tcodecs.reset();\n\t\t\treturn {\n\t\t\t\t...snapshot,\n\t\t\t\tinstances: snapshot.instances.map((instance) => encodeInstance(instance, codecs)),\n\t\t\t};\n\t\t},\n\t\tencodeUpdate(update) {\n\t\t\tswitch (update.type) {\n\t\t\t\tcase \"reset\":\n\t\t\t\t\tcodecs.reset();\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...update,\n\t\t\t\t\t\tsnapshot: {\n\t\t\t\t\t\t\t...update.snapshot,\n\t\t\t\t\t\t\tinstances: update.snapshot.instances.map((instance) => encodeInstance(instance, codecs)),\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\tcase \"state\":\n\t\t\t\t\treturn { ...update, ops: codecs.get(update.instance, update.member).encode(update.ops) };\n\t\t\t\tcase \"replaced\":\n\t\t\t\t\tcodecs.reset();\n\t\t\t\t\treturn { ...update, snapshot: encodeInstance(update.snapshot, codecs) };\n\t\t\t\tcase \"spawned\":\n\t\t\t\t\treturn { ...update, instance: encodeInstance(update.instance, codecs) };\n\t\t\t\tcase \"unavailable\":\n\t\t\t\t\tcodecs.reset();\n\t\t\t\t\treturn update;\n\t\t\t\tcase \"closed\":\n\t\t\t\t\tcodecs.removeInstance(update.instance);\n\t\t\t\t\treturn update;\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport function createServiceStateDecoder(): ServiceStateDecoder {\n\tconst codecs = new StateCodecRegistry<Decoder>(decoder);\n\treturn {\n\t\tdecodeSnapshot(snapshot) {\n\t\t\tcodecs.reset();\n\t\t\treturn {\n\t\t\t\t...snapshot,\n\t\t\t\tinstances: snapshot.instances.map((instance) => decodeInstance(instance, codecs)),\n\t\t\t};\n\t\t},\n\t\tdecodeUpdate(update) {\n\t\t\tswitch (update.type) {\n\t\t\t\tcase \"reset\":\n\t\t\t\t\tcodecs.reset();\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...update,\n\t\t\t\t\t\tsnapshot: {\n\t\t\t\t\t\t\t...update.snapshot,\n\t\t\t\t\t\t\tinstances: update.snapshot.instances.map((instance) => decodeInstance(instance, codecs)),\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\tcase \"state\":\n\t\t\t\t\treturn { ...update, ops: codecs.get(update.instance, update.member).decode(update.ops) };\n\t\t\t\tcase \"replaced\":\n\t\t\t\t\tcodecs.reset();\n\t\t\t\t\treturn { ...update, snapshot: decodeInstance(update.snapshot, codecs) };\n\t\t\t\tcase \"spawned\":\n\t\t\t\t\treturn { ...update, instance: decodeInstance(update.instance, codecs) };\n\t\t\t\tcase \"unavailable\":\n\t\t\t\t\tcodecs.reset();\n\t\t\t\t\treturn update;\n\t\t\t\tcase \"closed\":\n\t\t\t\t\tcodecs.removeInstance(update.instance);\n\t\t\t\t\treturn update;\n\t\t\t}\n\t\t},\n\t};\n}\n\nfunction encodeInstance(\n\tinstance: ServiceInstanceSnapshot,\n\tcodecs: StateCodecRegistry<Encoder>,\n): WireServiceSubscriptionSnapshot[\"instances\"][number] {\n\treturn {\n\t\t...instance,\n\t\tmembers: instance.members.map((member) =>\n\t\t\tmember.kind === \"state\"\n\t\t\t\t? { ...member, ops: codecs.add(instance.instance, member.name).encode(member.ops) }\n\t\t\t\t: member,\n\t\t),\n\t};\n}\n\nfunction decodeInstance(\n\tinstance: WireServiceSubscriptionSnapshot[\"instances\"][number],\n\tcodecs: StateCodecRegistry<Decoder>,\n): ServiceInstanceSnapshot {\n\treturn {\n\t\t...instance,\n\t\tmembers: instance.members.map((member) =>\n\t\t\tmember.kind === \"state\"\n\t\t\t\t? { ...member, ops: codecs.add(instance.instance, member.name).decode(member.ops) }\n\t\t\t\t: member,\n\t\t),\n\t};\n}\n\nfunction stateKey(instance: ServiceInstanceAddress | undefined, member: string): string {\n\treturn JSON.stringify([instance?.key ?? null, instance?.generation ?? null, member]);\n}\n\nfunction sameAddress(left: ServiceInstanceAddress | undefined, right: ServiceInstanceAddress): boolean {\n\treturn left?.key === right.key && left.generation === right.generation;\n}\n\nfunction describeState(instance: ServiceInstanceAddress | undefined, member: string): string {\n\treturn instance === undefined ? member : `${instance.key}@${instance.generation}.${member}`;\n}\n"]}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { Op } from "../delta/index.ts";
|
|
2
2
|
import type { Context } from "../types.ts";
|
|
3
3
|
export interface ReplicatedStateInternals {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/** Atomically capture the immutable value and its matching publication sequence. */
|
|
5
|
+
snapshot(): {
|
|
6
|
+
readonly value: unknown;
|
|
7
|
+
readonly sequence: number;
|
|
8
|
+
};
|
|
6
9
|
subscribe(listener: (ops: readonly Op[], sequence: number, context: Context) => void): () => void;
|
|
7
10
|
}
|
|
8
11
|
export declare function registerReplicatedStateInternals(value: object, internals: ReplicatedStateInternals): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-internals.d.ts","sourceRoot":"","sources":["../../src/services/state-internals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,wBAAwB;IACxC,QAAQ,
|
|
1
|
+
{"version":3,"file":"state-internals.d.ts","sourceRoot":"","sources":["../../src/services/state-internals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,wBAAwB;IACxC,oFAAoF;IACpF,QAAQ,IAAI;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,SAAS,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAClG;AAID,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,wBAAwB,GAAG,IAAI,CAEzG;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,GAAG,SAAS,CAGhG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-internals.js","sourceRoot":"","sources":["../../src/services/state-internals.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,GAAG,IAAI,OAAO,EAAoC,CAAC;AAEhE,MAAM,UAAU,gCAAgC,CAAC,KAAa,EAAE,SAAmC
|
|
1
|
+
{"version":3,"file":"state-internals.js","sourceRoot":"","sources":["../../src/services/state-internals.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,GAAG,IAAI,OAAO,EAAoC,CAAC;AAEhE,MAAM,UAAU,gCAAgC,CAAC,KAAa,EAAE,SAAmC;IAClG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,KAAc;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAClE,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC","sourcesContent":["import type { Op } from \"../delta/index.ts\";\nimport type { Context } from \"../types.ts\";\n\nexport interface ReplicatedStateInternals {\n\t/** Atomically capture the immutable value and its matching publication sequence. */\n\tsnapshot(): { readonly value: unknown; readonly sequence: number };\n\tsubscribe(listener: (ops: readonly Op[], sequence: number, context: Context) => void): () => void;\n}\n\nconst sources = new WeakMap<object, ReplicatedStateInternals>();\n\nexport function registerReplicatedStateInternals(value: object, internals: ReplicatedStateInternals): void {\n\tsources.set(value, internals);\n}\n\nexport function getReplicatedStateInternals(value: unknown): ReplicatedStateInternals | undefined {\n\tif (typeof value !== \"object\" || value === null) return undefined;\n\treturn sources.get(value);\n}\n"]}
|
package/dist/services/state.d.ts
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
import { type Op } from "../delta/index.ts";
|
|
2
|
-
import type { Context, JsonValue, MutableReplicatedState, ReplicatedState, ReplicatedStateDelivery } from "../types.ts";
|
|
2
|
+
import type { AttachedReplicatedState, Context, JsonValue, MutableReplicatedState, ReplicatedState, ReplicatedStateDelivery, ReplicatedStateSource, ReplicatedStateSourceOptions } from "../types.ts";
|
|
3
|
+
/** The void signature also accepts synchronous callbacks that return an ignored value. */
|
|
4
|
+
type StateListener<T> = (value: T, context: Context, delivery: ReplicatedStateDelivery) => void;
|
|
3
5
|
export declare class MutableReplicatedStateImpl<T extends object> implements MutableReplicatedState<T> {
|
|
4
6
|
#private;
|
|
5
7
|
constructor(initial: T);
|
|
6
8
|
get value(): T;
|
|
7
9
|
change(context: Context, mutate: Parameters<MutableReplicatedState<T>["change"]>[1]): void;
|
|
8
10
|
replace(context: Context, value: T): void;
|
|
9
|
-
subscribe(listener:
|
|
11
|
+
subscribe(listener: StateListener<T>): () => void;
|
|
10
12
|
}
|
|
13
|
+
/** Attach a publication-only replicated state to one authoritative immutable source stream. */
|
|
14
|
+
export declare function attachReplicatedStateSource<T>(source: ReplicatedStateSource<T>, options?: ReplicatedStateSourceOptions): AttachedReplicatedState<T>;
|
|
11
15
|
/** A cold read-only state used by service consumers until a complete snapshot arrives. */
|
|
12
16
|
export declare class ReplicatedStateReplica<T extends JsonValue = JsonValue> implements ReplicatedState<T> {
|
|
13
17
|
#private;
|
|
14
18
|
constructor(reportError: (error: Error) => void);
|
|
15
19
|
get value(): T | undefined;
|
|
16
|
-
subscribe(listener:
|
|
20
|
+
subscribe(listener: StateListener<T>): () => void;
|
|
17
21
|
hydrate(sequence: number, ops: readonly Op[], context: Context): void;
|
|
18
22
|
update(sequence: number, ops: readonly Op[], context: Context): void;
|
|
19
23
|
clear(): void;
|
|
20
24
|
}
|
|
21
25
|
/** @internal Context for synthetic service deliveries without a caller. */
|
|
22
26
|
export declare function serviceDeliveryContext(): Context;
|
|
27
|
+
export {};
|
|
23
28
|
//# sourceMappingURL=state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/services/state.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/services/state.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,KAAK,EAAE,EAAsC,MAAM,mBAAmB,CAAC;AAExG,OAAO,KAAK,EACX,uBAAuB,EACvB,OAAO,EACP,SAAS,EACT,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EAGrB,4BAA4B,EAC5B,MAAM,aAAa,CAAC;AAGrB,0FAA0F;AAC1F,KAAK,aAAa,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,uBAAuB,KAAK,IAAI,CAAC;AAqKhG,qBAAa,0BAA0B,CAAC,CAAC,SAAS,MAAM,CAAE,YAAW,sBAAsB,CAAC,CAAC,CAAC;;IAK7F,YAAY,OAAO,EAAE,CAAC,EAOrB;IAED,IAAI,KAAK,IAAI,CAAC,CAEb;IAED,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CA2BzF;IAED,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CASxC;IAED,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAEhD;CACD;AA8ED,+FAA+F;AAC/F,wBAAgB,2BAA2B,CAAC,CAAC,EAC5C,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,EAChC,OAAO,GAAE,4BAAiC,GACxC,uBAAuB,CAAC,CAAC,CAAC,CAc5B;AAED,0FAA0F;AAC1F,qBAAa,sBAAsB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,CAAE,YAAW,eAAe,CAAC,CAAC,CAAC;;IAOjG,YAAY,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAE9C;IAED,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAEzB;IAED,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAehD;IAED,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAYpE;IAED,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAkBnE;IAED,KAAK,IAAI,IAAI,CAIZ;CAUD;AAED,2EAA2E;AAC3E,wBAAgB,sBAAsB,IAAI,OAAO,CAGhD"}
|