@earendil-works/chord 0.87.1 → 0.99.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
@@ -276,6 +276,23 @@ class KeyedBinding {
|
|
|
276
276
|
return;
|
|
277
277
|
try {
|
|
278
278
|
switch (update.type) {
|
|
279
|
+
case "reset": {
|
|
280
|
+
validateResetSnapshot(update.snapshot, this.#service.id, "keyed");
|
|
281
|
+
const snapshots = new Map(update.snapshot.instances.map((snapshot) => [snapshot.instance.key, snapshot]));
|
|
282
|
+
for (const instance of [...this.#instances.values()]) {
|
|
283
|
+
if (snapshots.get(instance.key)?.instance?.generation !== instance.generation) {
|
|
284
|
+
this.#instances.remove(instance);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
for (const snapshot of snapshots.values()) {
|
|
288
|
+
const instance = this.#instances.get(snapshot.instance.key);
|
|
289
|
+
if (instance === undefined)
|
|
290
|
+
this.#spawn(snapshot, context);
|
|
291
|
+
else
|
|
292
|
+
instance.facade.install(snapshot, context);
|
|
293
|
+
}
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
279
296
|
case "unavailable":
|
|
280
297
|
case "replaced":
|
|
281
298
|
throw new Error("Keyed service received a singleton lifecycle update");
|
|
@@ -459,7 +476,15 @@ export class RemoteServiceBindingImpl {
|
|
|
459
476
|
if (!binding.active || binding.revision !== revision)
|
|
460
477
|
return;
|
|
461
478
|
try {
|
|
462
|
-
if (update.type === "
|
|
479
|
+
if (update.type === "reset") {
|
|
480
|
+
validateResetSnapshot(update.snapshot, serviceId, "singleton");
|
|
481
|
+
const snapshot = update.snapshot.instances[0];
|
|
482
|
+
if (snapshot === undefined)
|
|
483
|
+
binding.facade.clear();
|
|
484
|
+
else
|
|
485
|
+
binding.facade.install(snapshot, context);
|
|
486
|
+
}
|
|
487
|
+
else if (update.type === "unavailable") {
|
|
463
488
|
binding.facade.clear();
|
|
464
489
|
}
|
|
465
490
|
else if (update.type === "replaced") {
|
|
@@ -510,6 +535,29 @@ export class RemoteServiceBindingImpl {
|
|
|
510
535
|
this.#modes.set(serviceId, mode);
|
|
511
536
|
}
|
|
512
537
|
}
|
|
538
|
+
function validateResetSnapshot(snapshot, serviceId, mode) {
|
|
539
|
+
if (snapshot.serviceId !== serviceId ||
|
|
540
|
+
snapshot.mode !== mode ||
|
|
541
|
+
(mode === "singleton" && snapshot.instances.length > 1)) {
|
|
542
|
+
throw new Error("Remote service reset has the wrong service or mode");
|
|
543
|
+
}
|
|
544
|
+
const keys = new Set();
|
|
545
|
+
for (const instance of snapshot.instances) {
|
|
546
|
+
if (mode === "singleton" ? instance.instance !== undefined : instance.instance === undefined) {
|
|
547
|
+
throw new Error("Remote service reset has an invalid instance address");
|
|
548
|
+
}
|
|
549
|
+
if (instance.instance !== undefined) {
|
|
550
|
+
if (keys.has(instance.instance.key))
|
|
551
|
+
throw new Error("Remote service reset repeats an instance key");
|
|
552
|
+
keys.add(instance.instance.key);
|
|
553
|
+
}
|
|
554
|
+
for (const member of instance.members) {
|
|
555
|
+
if (member.kind === "state" && (member.ops.length !== 1 || member.ops[0]?.[0] !== "r")) {
|
|
556
|
+
throw new Error("Remote service reset must contain full root replacements");
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
513
561
|
function validateMembers(members) {
|
|
514
562
|
const result = new Map();
|
|
515
563
|
for (const member of members) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consumer.js","sourceRoot":"","sources":["../../src/services/consumer.ts"],"names":[],"mappings":"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","sourcesContent":["import { awaitWithContext, BACKGROUND_CONTEXT } from \"../context/index.ts\";\nimport type { Op } from \"../delta/index.ts\";\nimport type {\n\tContext,\n\tJsonValue,\n\tRemoteServiceBinding,\n\tRemoteServiceBindingOptions,\n\tRemoteServiceTransport,\n\tService,\n\tServiceInstanceAddress,\n\tServiceInstanceSnapshot,\n\tServiceMemberSnapshot,\n\tServiceProviderUpdate,\n\tServiceSubscription,\n} from \"../types.ts\";\nimport { RemoteServiceError } from \"./errors.ts\";\nimport { ServiceSlot } from \"./handle.ts\";\nimport { InstanceDirectory, type InstanceDirectoryEntry } from \"./instances.ts\";\nimport { ReplicatedStateReplica, serviceDeliveryContext } from \"./state.ts\";\n\ntype ErrorReporter = (error: Error) => void;\ntype ServiceMemberKind = ServiceMemberSnapshot[\"kind\"];\n\nclass MemberSlot {\n\treadonly #serviceId: string;\n\treadonly #member: string;\n\treadonly #invoke: (args: readonly JsonValue[], context: Context) => Promise<JsonValue | undefined>;\n\treadonly #state: ReplicatedStateReplica;\n\treadonly #isActive: () => boolean;\n\treadonly #assertAccess: () => void;\n\treadonly value: unknown;\n\t#kind: ServiceMemberKind | undefined;\n\t#expectedKind: ServiceMemberKind | undefined;\n\n\tconstructor(\n\t\tserviceId: string,\n\t\tmember: string,\n\t\tinvoke: (args: readonly JsonValue[], context: Context) => Promise<JsonValue | undefined>,\n\t\tisActive: () => boolean,\n\t\tassertAccess: () => void,\n\t\treportError: ErrorReporter,\n\t) {\n\t\tthis.#serviceId = serviceId;\n\t\tthis.#member = member;\n\t\tthis.#invoke = invoke;\n\t\tthis.#isActive = isActive;\n\t\tthis.#assertAccess = assertAccess;\n\t\tthis.#state = new ReplicatedStateReplica(reportError);\n\t\tconst callable = (): void => {};\n\t\tthis.value = new Proxy(callable, {\n\t\t\tapply: (_target, _thisArg, args) => this.#call(args),\n\t\t\tget: (_target, property) => {\n\t\t\t\tif (property === \"value\") {\n\t\t\t\t\tthis.#assertAccess();\n\t\t\t\t\tthis.#expect(\"state\");\n\t\t\t\t\treturn this.#state.value;\n\t\t\t\t}\n\t\t\t\tif (property === \"subscribe\") return this.#subscribe.bind(this);\n\t\t\t\tif (property === Symbol.toStringTag) return \"RemoteServiceMember\";\n\t\t\t\tif (property === \"then\") return undefined;\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t});\n\t}\n\n\tsetDescription(kind: ServiceMemberKind): void {\n\t\tif (this.#kind !== undefined && this.#kind !== kind) {\n\t\t\tthrow new Error(`Remote service member ${this.#serviceId}.${this.#member} changed kind`);\n\t\t}\n\t\tthis.#kind = kind;\n\t\tif (this.#expectedKind !== undefined && this.#expectedKind !== kind) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_member_mismatch\",\n\t\t\t\t`Remote service member ${this.#serviceId}.${this.#member} is ${kind}, not ${this.#expectedKind}`,\n\t\t\t);\n\t\t}\n\t}\n\n\thydrate(sequence: number, ops: readonly Op[], context: Context): void {\n\t\tthis.setDescription(\"state\");\n\t\tthis.#state.hydrate(sequence, ops, context);\n\t}\n\n\tupdate(sequence: number, ops: readonly Op[], context: Context): void {\n\t\tthis.setDescription(\"state\");\n\t\tthis.#state.update(sequence, ops, context);\n\t}\n\n\tclear(): void {\n\t\tthis.#state.clear();\n\t}\n\n\t#subscribe(listener: (value: JsonValue, context: Context) => void): () => void {\n\t\tthis.#assertAccess();\n\t\tif (typeof listener !== \"function\") {\n\t\t\tthrow new TypeError(\"Replicated state subscription listener must be a function\");\n\t\t}\n\t\tthis.#expect(\"state\");\n\t\treturn this.#state.subscribe(listener);\n\t}\n\n\t#expect(kind: ServiceMemberKind): void {\n\t\tif (this.#expectedKind !== undefined && this.#expectedKind !== kind) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_member_mismatch\",\n\t\t\t\t`Remote service member ${this.#serviceId}.${this.#member} was used as two different kinds`,\n\t\t\t);\n\t\t}\n\t\tthis.#expectedKind = kind;\n\t\tif (this.#kind !== undefined && this.#kind !== kind) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_member_mismatch\",\n\t\t\t\t`Remote service member ${this.#serviceId}.${this.#member} is ${this.#kind}, not ${kind}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t#call(args: unknown[]): Promise<JsonValue | undefined> {\n\t\tthis.#assertAccess();\n\t\tthis.#expect(\"method\");\n\t\tif (!this.#isActive()) {\n\t\t\treturn Promise.reject(\n\t\t\t\tnew RemoteServiceError(\"service_stale_instance\", `Remote service ${this.#serviceId} binding is closed`),\n\t\t\t);\n\t\t}\n\t\tconst context = args.at(-1);\n\t\tif (!isContext(context)) {\n\t\t\treturn Promise.reject(\n\t\t\t\tnew RemoteServiceError(\n\t\t\t\t\t\"service_invalid_value\",\n\t\t\t\t\t`Remote service method ${this.#serviceId}.${this.#member} requires a trailing Context`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tconst businessArgs = args.slice(0, -1) as JsonValue[];\n\t\treturn this.#invoke(businessArgs, context);\n\t}\n}\n\nclass ServiceFacade {\n\treadonly #serviceId: string;\n\treadonly #address: ServiceInstanceAddress | undefined;\n\treadonly #transport: RemoteServiceTransport;\n\treadonly #reportError: ErrorReporter;\n\treadonly #slots = new Map<string, MemberSlot>();\n\treadonly #descriptions = new Map<string, ServiceMemberKind>();\n\treadonly #isActive: () => boolean;\n\treadonly #assertAccess: () => void;\n\treadonly proxy: object;\n\n\tconstructor(\n\t\tserviceId: string,\n\t\taddress: ServiceInstanceAddress | undefined,\n\t\ttransport: RemoteServiceTransport,\n\t\tisActive: () => boolean,\n\t\tassertAccess: () => void,\n\t\treportError: ErrorReporter,\n\t) {\n\t\tthis.#serviceId = serviceId;\n\t\tthis.#address = address;\n\t\tthis.#transport = transport;\n\t\tthis.#isActive = isActive;\n\t\tthis.#assertAccess = assertAccess;\n\t\tthis.#reportError = reportError;\n\t\tthis.proxy = new Proxy(Object.create(null) as object, {\n\t\t\tget: (_target, property) => {\n\t\t\t\tif (typeof property !== \"string\") return undefined;\n\t\t\t\treturn this.#slot(property).value;\n\t\t\t},\n\t\t});\n\t}\n\n\tinstall(snapshot: ServiceInstanceSnapshot, context: Context): void {\n\t\tif (!sameAddress(snapshot.instance, this.#address))\n\t\t\tthrow new Error(\"Remote service snapshot has the wrong address\");\n\t\tconst members = validateMembers(snapshot.members);\n\t\tfor (const name of this.#slots.keys()) {\n\t\t\tif (!members.has(name)) {\n\t\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\t\"service_member_not_found\",\n\t\t\t\t\t`Unknown remote service member ${this.#serviceId}.${name}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthis.#descriptions.clear();\n\t\tfor (const [name, member] of members) this.#descriptions.set(name, member.kind);\n\t\tfor (const member of members.values()) {\n\t\t\tconst slot = this.#slots.get(member.name);\n\t\t\tif (member.kind === \"state\") {\n\t\t\t\t(slot ?? this.#slot(member.name)).hydrate(member.sequence, member.ops, context);\n\t\t\t} else {\n\t\t\t\tslot?.setDescription(member.kind);\n\t\t\t}\n\t\t}\n\t}\n\n\tupdate(member: string, sequence: number, ops: readonly Op[], context: Context): void {\n\t\tif (this.#descriptions.get(member) !== \"state\") {\n\t\t\tthrow new Error(`Remote service update targets non-state member ${this.#serviceId}.${member}`);\n\t\t}\n\t\tthis.#slot(member).update(sequence, ops, context);\n\t}\n\n\tclear(): void {\n\t\tfor (const slot of this.#slots.values()) slot.clear();\n\t}\n\n\t#slot(member: string): MemberSlot {\n\t\tlet slot = this.#slots.get(member);\n\t\tif (slot !== undefined) return slot;\n\t\tslot = new MemberSlot(\n\t\t\tthis.#serviceId,\n\t\t\tmember,\n\t\t\t(args, context) =>\n\t\t\t\tthis.#transport.invoke(\n\t\t\t\t\t{\n\t\t\t\t\t\tserviceId: this.#serviceId,\n\t\t\t\t\t\t...(this.#address === undefined ? {} : { instance: this.#address }),\n\t\t\t\t\t\tmember,\n\t\t\t\t\t\targs,\n\t\t\t\t\t},\n\t\t\t\t\tcontext,\n\t\t\t\t),\n\t\t\tthis.#isActive,\n\t\t\tthis.#assertAccess,\n\t\t\tthis.#reportError,\n\t\t);\n\t\tconst kind = this.#descriptions.get(member);\n\t\tif (kind !== undefined) slot.setDescription(kind);\n\t\tthis.#slots.set(member, slot);\n\t\treturn slot;\n\t}\n}\n\ninterface SingletonBinding {\n\tfacade: ServiceFacade;\n\tsubscription?: ServiceSubscription;\n\tstarting?: Promise<void>;\n\tactive: boolean;\n\trevision: number;\n}\n\ninterface KeyedInstance extends InstanceDirectoryEntry {\n\treadonly facade: ServiceFacade;\n}\n\nclass KeyedBinding<T> {\n\treadonly #service: Service<T>;\n\treadonly #transport: RemoteServiceTransport;\n\treadonly #reportError: ErrorReporter;\n\treadonly #assertAccess: () => void;\n\treadonly #onEmpty: () => void;\n\treadonly #instances: InstanceDirectory<KeyedInstance>;\n\t#subscription: ServiceSubscription | undefined;\n\t#starting: Promise<void> | undefined;\n\t#closed = false;\n\t#bound: boolean;\n\t#revision = 0;\n\n\tconstructor(\n\t\tservice: Service<T>,\n\t\ttransport: RemoteServiceTransport,\n\t\treportError: ErrorReporter,\n\t\tassertAccess: () => void,\n\t\tonEmpty: () => void,\n\t\tbound: boolean,\n\t) {\n\t\tthis.#service = service;\n\t\tthis.#transport = transport;\n\t\tthis.#reportError = reportError;\n\t\tthis.#assertAccess = assertAccess;\n\t\tthis.#onEmpty = onEmpty;\n\t\tthis.#bound = bound;\n\t\tthis.#instances = new InstanceDirectory({ ready: false, onError: reportError });\n\t}\n\n\tobserve(handler: (service: T, context: Context) => void | Promise<void>): () => void {\n\t\tif (this.#closed) throw new Error(\"Remote keyed service binding is closed\");\n\t\tlet stopped = false;\n\t\tconst stop = this.#instances.observe<T>((service, context) => {\n\t\t\tconst slot = new ServiceSlot(this.#service.id, true);\n\t\t\tvoid slot.bind(service as object);\n\t\t\treturn handler(\n\t\t\t\tslot.view<T>(() => {\n\t\t\t\t\tthis.#assertAccess();\n\t\t\t\t\tif (stopped || context.abortSignal?.aborted) {\n\t\t\t\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\t\t\t\"service_stale_instance\",\n\t\t\t\t\t\t\t`Remote service ${this.#service.id} observation is closed`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\tcontext,\n\t\t\t);\n\t\t});\n\t\tif (this.#bound && this.#starting === undefined) {\n\t\t\tconst revision = this.#revision;\n\t\t\tconst starting = this.#start(revision);\n\t\t\tthis.#starting = starting;\n\t\t\tvoid starting.catch((error: unknown) => {\n\t\t\t\tif (!this.#closed && this.#revision === revision && this.#bound) this.#reportError(toError(error));\n\t\t\t});\n\t\t}\n\t\treturn () => {\n\t\t\tif (stopped) return;\n\t\t\tstopped = true;\n\t\t\tstop();\n\t\t\tif (this.#instances.observerCount === 0) this.#onEmpty();\n\t\t};\n\t}\n\n\tasync rebind(bound: boolean, context: Context): Promise<void> {\n\t\tif (this.#closed) return;\n\t\tthis.#bound = bound;\n\t\tconst revision = ++this.#revision;\n\t\tawait this.#reset(context, false);\n\t\tif (this.#closed || this.#revision !== revision || this.#bound !== bound) return;\n\t\tif (bound && this.#instances.observerCount > 0) {\n\t\t\tconst starting = this.#start(revision);\n\t\t\tthis.#starting = starting;\n\t\t\tawait starting;\n\t\t}\n\t}\n\n\tready(): Promise<void> {\n\t\treturn this.#starting ?? Promise.resolve();\n\t}\n\n\tasync close(context: Context): Promise<void> {\n\t\tif (this.#closed) return;\n\t\tthis.#closed = true;\n\t\tthis.#revision += 1;\n\t\tawait this.#reset(context, true);\n\t\tthis.#instances.dispose();\n\t}\n\n\tasync #reset(context: Context, waitForStarting: boolean): Promise<void> {\n\t\tthis.#instances.reset();\n\t\tconst starting = this.#starting;\n\t\tthis.#starting = undefined;\n\t\tconst subscription = this.#subscription;\n\t\tthis.#subscription = undefined;\n\t\tawait Promise.all([\n\t\t\twaitForStarting ? starting?.catch(() => {}) : undefined,\n\t\t\tsubscription === undefined ? undefined : subscription.close(context),\n\t\t]);\n\t}\n\n\tasync #start(revision: number): Promise<void> {\n\t\tconst subscription = await this.#transport.subscribe(\n\t\t\tthis.#service.id,\n\t\t\t\"keyed\",\n\t\t\t(update, context) => {\n\t\t\t\tif (this.#revision === revision) this.#update(update, context);\n\t\t\t},\n\t\t\tBACKGROUND_CONTEXT,\n\t\t);\n\t\tif (this.#closed || !this.#bound || this.#revision !== revision) {\n\t\t\tawait subscription.close(BACKGROUND_CONTEXT);\n\t\t\treturn;\n\t\t}\n\t\tthis.#subscription = subscription;\n\t\tif (subscription.snapshot.mode !== \"keyed\" || subscription.snapshot.serviceId !== this.#service.id) {\n\t\t\tthrow new Error(`Remote service ${this.#service.id} returned the wrong keyed snapshot`);\n\t\t}\n\t\tfor (const snapshot of subscription.snapshot.instances) this.#spawn(snapshot, serviceDeliveryContext());\n\t\tsubscription.activate();\n\t\tthis.#instances.ready();\n\t}\n\n\t#update(update: ServiceProviderUpdate, context: Context): void {\n\t\tif (this.#closed) return;\n\t\ttry {\n\t\t\tswitch (update.type) {\n\t\t\t\tcase \"unavailable\":\n\t\t\t\tcase \"replaced\":\n\t\t\t\t\tthrow new Error(\"Keyed service received a singleton lifecycle update\");\n\t\t\t\tcase \"spawned\":\n\t\t\t\t\tthis.#spawn(update.instance, context);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"closed\": {\n\t\t\t\t\tconst instance = this.#instances.get(update.instance.key);\n\t\t\t\t\tif (instance?.generation === update.instance.generation) this.#instances.remove(instance);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"state\": {\n\t\t\t\t\tif (update.instance === undefined) throw new Error(\"Keyed state update has no instance address\");\n\t\t\t\t\tconst instance = this.#instances.get(update.instance.key);\n\t\t\t\t\tif (instance?.generation !== update.instance.generation) return;\n\t\t\t\t\tinstance.facade.update(update.member, update.sequence, update.ops, context);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.#reportError(toError(error));\n\t\t}\n\t}\n\n\t#spawn(snapshot: ServiceInstanceSnapshot, context: Context): void {\n\t\tconst address = snapshot.instance;\n\t\tif (address === undefined) throw new Error(\"Keyed service instance snapshot has no address\");\n\t\tlet active = true;\n\t\tconst facade = new ServiceFacade(\n\t\t\tthis.#service.id,\n\t\t\taddress,\n\t\t\tthis.#transport,\n\t\t\t() => active && !this.#closed,\n\t\t\tthis.#assertAccess,\n\t\t\tthis.#reportError,\n\t\t);\n\t\tfacade.install(snapshot, context);\n\t\tthis.#instances.replace({\n\t\t\tkey: address.key,\n\t\t\tgeneration: address.generation,\n\t\t\tservice: facade.proxy,\n\t\t\tfacade,\n\t\t\tdeactivate: () => {\n\t\t\t\tactive = false;\n\t\t\t\tfacade.clear();\n\t\t\t},\n\t\t});\n\t}\n}\n\nexport class RemoteServiceBindingImpl implements RemoteServiceBinding {\n\treadonly #transport: RemoteServiceTransport;\n\treadonly #allowlist = new Set<string>();\n\treadonly #reportError: ErrorReporter;\n\treadonly #modes = new Map<string, \"singleton\" | \"keyed\">();\n\treadonly #assertAccess: () => void;\n\treadonly #singletons = new Map<string, SingletonBinding>();\n\treadonly #keyed = new Map<string, KeyedBinding<unknown>>();\n\t#bound: boolean;\n\t#readinessRevision = 0;\n\t#bindingTransition = Promise.resolve();\n\t#disposed = false;\n\n\tconstructor(options: RemoteServiceBindingOptions) {\n\t\tthis.#transport = options.transport;\n\t\tconst ids = options.services.map(({ id }) => id);\n\t\tif (new Set(ids).size !== ids.length) throw new TypeError(\"Remote service binding has duplicate service IDs\");\n\t\tfor (const id of ids) this.#allowlist.add(id);\n\t\tthis.#reportError = options.onError ?? (() => {});\n\t\tthis.#assertAccess = options.assertAccess ?? (() => {});\n\t\tthis.#bound = options.bound ?? true;\n\t}\n\n\tuse<T>(service: Service<T>): T {\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAvailable(service.id, \"singleton\");\n\t\tlet binding = this.#singletons.get(service.id);\n\t\tif (binding !== undefined) return binding.facade.proxy as T;\n\t\tbinding = { facade: undefined as unknown as ServiceFacade, active: true, revision: 0 };\n\t\tbinding.facade = new ServiceFacade(\n\t\t\tservice.id,\n\t\t\tundefined,\n\t\t\tthis.#transport,\n\t\t\t() => binding!.active && !this.#disposed && this.#bound,\n\t\t\t() => this.#assertHandleAccess(),\n\t\t\tthis.#reportError,\n\t\t);\n\t\tthis.#singletons.set(service.id, binding);\n\t\tthis.#readinessRevision += 1;\n\t\tif (this.#bound) {\n\t\t\tconst revision = binding.revision;\n\t\t\tconst starting = this.#startSingleton(service.id, binding, revision);\n\t\t\tbinding.starting = starting;\n\t\t\tvoid starting.catch((error: unknown) => {\n\t\t\t\tif (binding.active && binding.revision === revision && !this.#disposed && this.#bound) {\n\t\t\t\t\tthis.#reportError(toError(error));\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn binding.facade.proxy as T;\n\t}\n\n\tobserve<T>(service: Service<T>, handler: (service: T, context: Context) => void | Promise<void>): () => void {\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAvailable(service.id, \"keyed\");\n\t\tlet binding = this.#keyed.get(service.id) as KeyedBinding<T> | undefined;\n\t\tif (binding === undefined) {\n\t\t\tbinding = new KeyedBinding(\n\t\t\t\tservice,\n\t\t\t\tthis.#transport,\n\t\t\t\tthis.#reportError,\n\t\t\t\t() => this.#assertHandleAccess(),\n\t\t\t\t() => {\n\t\t\t\t\tif (this.#keyed.get(service.id) !== binding) return;\n\t\t\t\t\tthis.#keyed.delete(service.id);\n\t\t\t\t\tthis.#readinessRevision += 1;\n\t\t\t\t\tvoid binding!.close(BACKGROUND_CONTEXT).catch(this.#reportError);\n\t\t\t\t},\n\t\t\t\tthis.#bound,\n\t\t\t);\n\t\t\tthis.#keyed.set(service.id, binding as KeyedBinding<unknown>);\n\t\t\tthis.#readinessRevision += 1;\n\t\t}\n\t\treturn binding.observe(handler);\n\t}\n\n\tasync ready(context: Context): Promise<void> {\n\t\tif (this.#disposed) throw new Error(\"Remote service binding is disposed\");\n\t\twhile (true) {\n\t\t\tconst revision = this.#readinessRevision;\n\t\t\tconst starts = [\n\t\t\t\tthis.#bindingTransition,\n\t\t\t\t...[...this.#singletons.values()].flatMap((binding) =>\n\t\t\t\t\tbinding.starting === undefined ? [] : [binding.starting],\n\t\t\t\t),\n\t\t\t\t...[...this.#keyed.values()].map((binding) => binding.ready()),\n\t\t\t];\n\t\t\tawait awaitWithContext(\n\t\t\t\tPromise.all(starts).then(() => undefined),\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tif (this.#disposed) throw new Error(\"Remote service binding is disposed\");\n\t\t\tif (revision === this.#readinessRevision) return;\n\t\t}\n\t}\n\n\tasync rebind(bound: boolean, context: Context): Promise<void> {\n\t\tif (this.#disposed) throw new Error(\"Remote service binding is disposed\");\n\t\tthis.#bound = bound;\n\t\tthis.#readinessRevision += 1;\n\t\tconst transitions: Promise<void>[] = [];\n\t\tfor (const [serviceId, binding] of this.#singletons) {\n\t\t\tbinding.revision += 1;\n\t\t\tbinding.facade.clear();\n\t\t\tconst subscription = binding.subscription;\n\t\t\tdelete binding.subscription;\n\t\t\tconst revision = binding.revision;\n\t\t\tconst starting = (async () => {\n\t\t\t\tawait subscription?.close(context);\n\t\t\t\tif (bound) await this.#startSingleton(serviceId, binding, revision);\n\t\t\t})();\n\t\t\tbinding.starting = starting;\n\t\t\ttransitions.push(starting);\n\t\t}\n\t\tfor (const binding of this.#keyed.values()) transitions.push(binding.rebind(bound, context));\n\t\tconst completion = (async () => {\n\t\t\tconst results = await Promise.allSettled(transitions);\n\t\t\tconst errors = results.filter((result): result is PromiseRejectedResult => result.status === \"rejected\");\n\t\t\tif (errors.length > 0)\n\t\t\t\tthrow new AggregateError(\n\t\t\t\t\terrors.map(({ reason }) => reason),\n\t\t\t\t\t\"Failed to rebind services\",\n\t\t\t\t);\n\t\t})();\n\t\tthis.#bindingTransition = completion;\n\t\tawait completion;\n\t}\n\n\tasync dispose(context: Context): Promise<void> {\n\t\tif (this.#disposed) return;\n\t\tthis.#disposed = true;\n\t\tconst closes: Promise<void>[] = [];\n\t\tfor (const binding of this.#singletons.values()) {\n\t\t\tbinding.active = false;\n\t\t\tbinding.facade.clear();\n\t\t\tif (binding.starting) closes.push(binding.starting.catch(() => {}));\n\t\t\tif (binding.subscription) closes.push(Promise.resolve(binding.subscription.close(context)));\n\t\t}\n\t\tfor (const binding of this.#keyed.values()) closes.push(binding.close(context));\n\t\tthis.#singletons.clear();\n\t\tthis.#keyed.clear();\n\t\tconst results = await Promise.allSettled(closes);\n\t\tconst errors = results.filter((result): result is PromiseRejectedResult => result.status === \"rejected\");\n\t\tif (errors.length > 0)\n\t\t\tthrow new AggregateError(\n\t\t\t\terrors.map(({ reason }) => reason),\n\t\t\t\t\"Failed to dispose services\",\n\t\t\t);\n\t}\n\n\tasync #startSingleton(serviceId: string, binding: SingletonBinding, revision: number): Promise<void> {\n\t\tconst subscription = await this.#transport.subscribe(\n\t\t\tserviceId,\n\t\t\t\"singleton\",\n\t\t\t(update, context) => {\n\t\t\t\tif (!binding.active || binding.revision !== revision) return;\n\t\t\t\ttry {\n\t\t\t\t\tif (update.type === \"unavailable\") {\n\t\t\t\t\t\tbinding.facade.clear();\n\t\t\t\t\t} else if (update.type === \"replaced\") {\n\t\t\t\t\t\tif (update.snapshot.instance !== undefined) {\n\t\t\t\t\t\t\tthrow new Error(\"Singleton replacement has an instance address\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbinding.facade.install(update.snapshot, context);\n\t\t\t\t\t} else if (update.type === \"state\" && update.instance === undefined) {\n\t\t\t\t\t\tbinding.facade.update(update.member, update.sequence, update.ops, context);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.#reportError(toError(error));\n\t\t\t\t}\n\t\t\t},\n\t\t\tBACKGROUND_CONTEXT,\n\t\t);\n\t\tif (!binding.active || this.#disposed || !this.#bound || binding.revision !== revision) {\n\t\t\tawait subscription.close(BACKGROUND_CONTEXT);\n\t\t\treturn;\n\t\t}\n\t\tbinding.subscription = subscription;\n\t\tconst snapshot = subscription.snapshot;\n\t\tif (snapshot.mode !== \"singleton\" || snapshot.serviceId !== serviceId || snapshot.instances.length !== 1) {\n\t\t\tthrow new Error(`Remote service ${serviceId} returned an invalid singleton snapshot`);\n\t\t}\n\t\tbinding.facade.install(snapshot.instances[0]!, serviceDeliveryContext());\n\t\tsubscription.activate();\n\t}\n\n\t#assertHandleAccess(): void {\n\t\tif (this.#disposed) throw new Error(\"Remote service binding is disposed\");\n\t\tthis.#assertAccess();\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#assertAvailable(serviceId: string, mode: \"singleton\" | \"keyed\"): void {\n\t\tif (this.#disposed) throw new Error(\"Remote service binding is disposed\");\n\t\tif (!this.#allowlist.has(serviceId)) {\n\t\t\tthrow new RemoteServiceError(\"service_not_allowed\", `Remote service ${serviceId} is not allowlisted`);\n\t\t}\n\t\tconst existing = this.#modes.get(serviceId);\n\t\tif (existing !== undefined && existing !== mode) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_mode_mismatch\",\n\t\t\t\t`Remote service ${serviceId} is already used as ${existing}`,\n\t\t\t);\n\t\t}\n\t\tthis.#modes.set(serviceId, mode);\n\t}\n}\n\nfunction validateMembers(members: readonly ServiceMemberSnapshot[]): ReadonlyMap<string, ServiceMemberSnapshot> {\n\tconst result = new Map<string, ServiceMemberSnapshot>();\n\tfor (const member of members) {\n\t\tif (member.name.length === 0 || result.has(member.name)) {\n\t\t\tthrow new Error(\"Remote service has invalid member descriptions\");\n\t\t}\n\t\tresult.set(member.name, member);\n\t}\n\treturn result;\n}\n\nfunction sameAddress(left: ServiceInstanceAddress | undefined, right: ServiceInstanceAddress | undefined): boolean {\n\tif (left === undefined || right === undefined) return left === right;\n\treturn left.key === right.key && left.generation === right.generation;\n}\n\nfunction isContext(value: unknown): value is Context {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tconst candidate = value as Partial<Context>;\n\treturn typeof candidate.value === \"function\" && typeof candidate.toString === \"function\";\n}\n\nfunction toError(error: unknown): Error {\n\treturn error instanceof Error ? error : new Error(String(error));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"consumer.js","sourceRoot":"","sources":["../../src/services/consumer.ts"],"names":[],"mappings":"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","sourcesContent":["import { awaitWithContext, BACKGROUND_CONTEXT } from \"../context/index.ts\";\nimport type { Op } from \"../delta/index.ts\";\nimport type {\n\tContext,\n\tJsonValue,\n\tRemoteServiceBinding,\n\tRemoteServiceBindingOptions,\n\tRemoteServiceTransport,\n\tReplicatedState,\n\tService,\n\tServiceInstanceAddress,\n\tServiceInstanceSnapshot,\n\tServiceMemberSnapshot,\n\tServiceProviderUpdate,\n\tServiceSubscription,\n\tServiceSubscriptionSnapshot,\n} from \"../types.ts\";\nimport { RemoteServiceError } from \"./errors.ts\";\nimport { ServiceSlot } from \"./handle.ts\";\nimport { InstanceDirectory, type InstanceDirectoryEntry } from \"./instances.ts\";\nimport { ReplicatedStateReplica, serviceDeliveryContext } from \"./state.ts\";\n\ntype ErrorReporter = (error: Error) => void;\ntype ServiceMemberKind = ServiceMemberSnapshot[\"kind\"];\n\nclass MemberSlot {\n\treadonly #serviceId: string;\n\treadonly #member: string;\n\treadonly #invoke: (args: readonly JsonValue[], context: Context) => Promise<JsonValue | undefined>;\n\treadonly #state: ReplicatedStateReplica;\n\treadonly #isActive: () => boolean;\n\treadonly #assertAccess: () => void;\n\treadonly value: unknown;\n\t#kind: ServiceMemberKind | undefined;\n\t#expectedKind: ServiceMemberKind | undefined;\n\n\tconstructor(\n\t\tserviceId: string,\n\t\tmember: string,\n\t\tinvoke: (args: readonly JsonValue[], context: Context) => Promise<JsonValue | undefined>,\n\t\tisActive: () => boolean,\n\t\tassertAccess: () => void,\n\t\treportError: ErrorReporter,\n\t) {\n\t\tthis.#serviceId = serviceId;\n\t\tthis.#member = member;\n\t\tthis.#invoke = invoke;\n\t\tthis.#isActive = isActive;\n\t\tthis.#assertAccess = assertAccess;\n\t\tthis.#state = new ReplicatedStateReplica(reportError);\n\t\tconst callable = (): void => {};\n\t\tthis.value = new Proxy(callable, {\n\t\t\tapply: (_target, _thisArg, args) => this.#call(args),\n\t\t\tget: (_target, property) => {\n\t\t\t\tif (property === \"value\") {\n\t\t\t\t\tthis.#assertAccess();\n\t\t\t\t\tthis.#expect(\"state\");\n\t\t\t\t\treturn this.#state.value;\n\t\t\t\t}\n\t\t\t\tif (property === \"subscribe\") return this.#subscribe.bind(this);\n\t\t\t\tif (property === Symbol.toStringTag) return \"RemoteServiceMember\";\n\t\t\t\tif (property === \"then\") return undefined;\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t});\n\t}\n\n\tsetDescription(kind: ServiceMemberKind): void {\n\t\tif (this.#kind !== undefined && this.#kind !== kind) {\n\t\t\tthrow new Error(`Remote service member ${this.#serviceId}.${this.#member} changed kind`);\n\t\t}\n\t\tthis.#kind = kind;\n\t\tif (this.#expectedKind !== undefined && this.#expectedKind !== kind) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_member_mismatch\",\n\t\t\t\t`Remote service member ${this.#serviceId}.${this.#member} is ${kind}, not ${this.#expectedKind}`,\n\t\t\t);\n\t\t}\n\t}\n\n\thydrate(sequence: number, ops: readonly Op[], context: Context): void {\n\t\tthis.setDescription(\"state\");\n\t\tthis.#state.hydrate(sequence, ops, context);\n\t}\n\n\tupdate(sequence: number, ops: readonly Op[], context: Context): void {\n\t\tthis.setDescription(\"state\");\n\t\tthis.#state.update(sequence, ops, context);\n\t}\n\n\tclear(): void {\n\t\tthis.#state.clear();\n\t}\n\n\t#subscribe(listener: Parameters<ReplicatedState<JsonValue>[\"subscribe\"]>[0]): () => void {\n\t\tthis.#assertAccess();\n\t\tif (typeof listener !== \"function\") {\n\t\t\tthrow new TypeError(\"Replicated state subscription listener must be a function\");\n\t\t}\n\t\tthis.#expect(\"state\");\n\t\treturn this.#state.subscribe(listener);\n\t}\n\n\t#expect(kind: ServiceMemberKind): void {\n\t\tif (this.#expectedKind !== undefined && this.#expectedKind !== kind) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_member_mismatch\",\n\t\t\t\t`Remote service member ${this.#serviceId}.${this.#member} was used as two different kinds`,\n\t\t\t);\n\t\t}\n\t\tthis.#expectedKind = kind;\n\t\tif (this.#kind !== undefined && this.#kind !== kind) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_member_mismatch\",\n\t\t\t\t`Remote service member ${this.#serviceId}.${this.#member} is ${this.#kind}, not ${kind}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t#call(args: unknown[]): Promise<JsonValue | undefined> {\n\t\tthis.#assertAccess();\n\t\tthis.#expect(\"method\");\n\t\tif (!this.#isActive()) {\n\t\t\treturn Promise.reject(\n\t\t\t\tnew RemoteServiceError(\"service_stale_instance\", `Remote service ${this.#serviceId} binding is closed`),\n\t\t\t);\n\t\t}\n\t\tconst context = args.at(-1);\n\t\tif (!isContext(context)) {\n\t\t\treturn Promise.reject(\n\t\t\t\tnew RemoteServiceError(\n\t\t\t\t\t\"service_invalid_value\",\n\t\t\t\t\t`Remote service method ${this.#serviceId}.${this.#member} requires a trailing Context`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tconst businessArgs = args.slice(0, -1) as JsonValue[];\n\t\treturn this.#invoke(businessArgs, context);\n\t}\n}\n\nclass ServiceFacade {\n\treadonly #serviceId: string;\n\treadonly #address: ServiceInstanceAddress | undefined;\n\treadonly #transport: RemoteServiceTransport;\n\treadonly #reportError: ErrorReporter;\n\treadonly #slots = new Map<string, MemberSlot>();\n\treadonly #descriptions = new Map<string, ServiceMemberKind>();\n\treadonly #isActive: () => boolean;\n\treadonly #assertAccess: () => void;\n\treadonly proxy: object;\n\n\tconstructor(\n\t\tserviceId: string,\n\t\taddress: ServiceInstanceAddress | undefined,\n\t\ttransport: RemoteServiceTransport,\n\t\tisActive: () => boolean,\n\t\tassertAccess: () => void,\n\t\treportError: ErrorReporter,\n\t) {\n\t\tthis.#serviceId = serviceId;\n\t\tthis.#address = address;\n\t\tthis.#transport = transport;\n\t\tthis.#isActive = isActive;\n\t\tthis.#assertAccess = assertAccess;\n\t\tthis.#reportError = reportError;\n\t\tthis.proxy = new Proxy(Object.create(null) as object, {\n\t\t\tget: (_target, property) => {\n\t\t\t\tif (typeof property !== \"string\") return undefined;\n\t\t\t\treturn this.#slot(property).value;\n\t\t\t},\n\t\t});\n\t}\n\n\tinstall(snapshot: ServiceInstanceSnapshot, context: Context): void {\n\t\tif (!sameAddress(snapshot.instance, this.#address))\n\t\t\tthrow new Error(\"Remote service snapshot has the wrong address\");\n\t\tconst members = validateMembers(snapshot.members);\n\t\tfor (const name of this.#slots.keys()) {\n\t\t\tif (!members.has(name)) {\n\t\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\t\"service_member_not_found\",\n\t\t\t\t\t`Unknown remote service member ${this.#serviceId}.${name}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthis.#descriptions.clear();\n\t\tfor (const [name, member] of members) this.#descriptions.set(name, member.kind);\n\t\tfor (const member of members.values()) {\n\t\t\tconst slot = this.#slots.get(member.name);\n\t\t\tif (member.kind === \"state\") {\n\t\t\t\t(slot ?? this.#slot(member.name)).hydrate(member.sequence, member.ops, context);\n\t\t\t} else {\n\t\t\t\tslot?.setDescription(member.kind);\n\t\t\t}\n\t\t}\n\t}\n\n\tupdate(member: string, sequence: number, ops: readonly Op[], context: Context): void {\n\t\tif (this.#descriptions.get(member) !== \"state\") {\n\t\t\tthrow new Error(`Remote service update targets non-state member ${this.#serviceId}.${member}`);\n\t\t}\n\t\tthis.#slot(member).update(sequence, ops, context);\n\t}\n\n\tclear(): void {\n\t\tfor (const slot of this.#slots.values()) slot.clear();\n\t}\n\n\t#slot(member: string): MemberSlot {\n\t\tlet slot = this.#slots.get(member);\n\t\tif (slot !== undefined) return slot;\n\t\tslot = new MemberSlot(\n\t\t\tthis.#serviceId,\n\t\t\tmember,\n\t\t\t(args, context) =>\n\t\t\t\tthis.#transport.invoke(\n\t\t\t\t\t{\n\t\t\t\t\t\tserviceId: this.#serviceId,\n\t\t\t\t\t\t...(this.#address === undefined ? {} : { instance: this.#address }),\n\t\t\t\t\t\tmember,\n\t\t\t\t\t\targs,\n\t\t\t\t\t},\n\t\t\t\t\tcontext,\n\t\t\t\t),\n\t\t\tthis.#isActive,\n\t\t\tthis.#assertAccess,\n\t\t\tthis.#reportError,\n\t\t);\n\t\tconst kind = this.#descriptions.get(member);\n\t\tif (kind !== undefined) slot.setDescription(kind);\n\t\tthis.#slots.set(member, slot);\n\t\treturn slot;\n\t}\n}\n\ninterface SingletonBinding {\n\tfacade: ServiceFacade;\n\tsubscription?: ServiceSubscription;\n\tstarting?: Promise<void>;\n\tactive: boolean;\n\trevision: number;\n}\n\ninterface KeyedInstance extends InstanceDirectoryEntry {\n\treadonly facade: ServiceFacade;\n}\n\nclass KeyedBinding<T> {\n\treadonly #service: Service<T>;\n\treadonly #transport: RemoteServiceTransport;\n\treadonly #reportError: ErrorReporter;\n\treadonly #assertAccess: () => void;\n\treadonly #onEmpty: () => void;\n\treadonly #instances: InstanceDirectory<KeyedInstance>;\n\t#subscription: ServiceSubscription | undefined;\n\t#starting: Promise<void> | undefined;\n\t#closed = false;\n\t#bound: boolean;\n\t#revision = 0;\n\n\tconstructor(\n\t\tservice: Service<T>,\n\t\ttransport: RemoteServiceTransport,\n\t\treportError: ErrorReporter,\n\t\tassertAccess: () => void,\n\t\tonEmpty: () => void,\n\t\tbound: boolean,\n\t) {\n\t\tthis.#service = service;\n\t\tthis.#transport = transport;\n\t\tthis.#reportError = reportError;\n\t\tthis.#assertAccess = assertAccess;\n\t\tthis.#onEmpty = onEmpty;\n\t\tthis.#bound = bound;\n\t\tthis.#instances = new InstanceDirectory({ ready: false, onError: reportError });\n\t}\n\n\tobserve(handler: (service: T, context: Context) => void | Promise<void>): () => void {\n\t\tif (this.#closed) throw new Error(\"Remote keyed service binding is closed\");\n\t\tlet stopped = false;\n\t\tconst stop = this.#instances.observe<T>((service, context) => {\n\t\t\tconst slot = new ServiceSlot(this.#service.id, true);\n\t\t\tvoid slot.bind(service as object);\n\t\t\treturn handler(\n\t\t\t\tslot.view<T>(() => {\n\t\t\t\t\tthis.#assertAccess();\n\t\t\t\t\tif (stopped || context.abortSignal?.aborted) {\n\t\t\t\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\t\t\t\"service_stale_instance\",\n\t\t\t\t\t\t\t`Remote service ${this.#service.id} observation is closed`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\tcontext,\n\t\t\t);\n\t\t});\n\t\tif (this.#bound && this.#starting === undefined) {\n\t\t\tconst revision = this.#revision;\n\t\t\tconst starting = this.#start(revision);\n\t\t\tthis.#starting = starting;\n\t\t\tvoid starting.catch((error: unknown) => {\n\t\t\t\tif (!this.#closed && this.#revision === revision && this.#bound) this.#reportError(toError(error));\n\t\t\t});\n\t\t}\n\t\treturn () => {\n\t\t\tif (stopped) return;\n\t\t\tstopped = true;\n\t\t\tstop();\n\t\t\tif (this.#instances.observerCount === 0) this.#onEmpty();\n\t\t};\n\t}\n\n\tasync rebind(bound: boolean, context: Context): Promise<void> {\n\t\tif (this.#closed) return;\n\t\tthis.#bound = bound;\n\t\tconst revision = ++this.#revision;\n\t\tawait this.#reset(context, false);\n\t\tif (this.#closed || this.#revision !== revision || this.#bound !== bound) return;\n\t\tif (bound && this.#instances.observerCount > 0) {\n\t\t\tconst starting = this.#start(revision);\n\t\t\tthis.#starting = starting;\n\t\t\tawait starting;\n\t\t}\n\t}\n\n\tready(): Promise<void> {\n\t\treturn this.#starting ?? Promise.resolve();\n\t}\n\n\tasync close(context: Context): Promise<void> {\n\t\tif (this.#closed) return;\n\t\tthis.#closed = true;\n\t\tthis.#revision += 1;\n\t\tawait this.#reset(context, true);\n\t\tthis.#instances.dispose();\n\t}\n\n\tasync #reset(context: Context, waitForStarting: boolean): Promise<void> {\n\t\tthis.#instances.reset();\n\t\tconst starting = this.#starting;\n\t\tthis.#starting = undefined;\n\t\tconst subscription = this.#subscription;\n\t\tthis.#subscription = undefined;\n\t\tawait Promise.all([\n\t\t\twaitForStarting ? starting?.catch(() => {}) : undefined,\n\t\t\tsubscription === undefined ? undefined : subscription.close(context),\n\t\t]);\n\t}\n\n\tasync #start(revision: number): Promise<void> {\n\t\tconst subscription = await this.#transport.subscribe(\n\t\t\tthis.#service.id,\n\t\t\t\"keyed\",\n\t\t\t(update, context) => {\n\t\t\t\tif (this.#revision === revision) this.#update(update, context);\n\t\t\t},\n\t\t\tBACKGROUND_CONTEXT,\n\t\t);\n\t\tif (this.#closed || !this.#bound || this.#revision !== revision) {\n\t\t\tawait subscription.close(BACKGROUND_CONTEXT);\n\t\t\treturn;\n\t\t}\n\t\tthis.#subscription = subscription;\n\t\tif (subscription.snapshot.mode !== \"keyed\" || subscription.snapshot.serviceId !== this.#service.id) {\n\t\t\tthrow new Error(`Remote service ${this.#service.id} returned the wrong keyed snapshot`);\n\t\t}\n\t\tfor (const snapshot of subscription.snapshot.instances) this.#spawn(snapshot, serviceDeliveryContext());\n\t\tsubscription.activate();\n\t\tthis.#instances.ready();\n\t}\n\n\t#update(update: ServiceProviderUpdate, context: Context): void {\n\t\tif (this.#closed) return;\n\t\ttry {\n\t\t\tswitch (update.type) {\n\t\t\t\tcase \"reset\": {\n\t\t\t\t\tvalidateResetSnapshot(update.snapshot, this.#service.id, \"keyed\");\n\t\t\t\t\tconst snapshots = new Map(\n\t\t\t\t\t\tupdate.snapshot.instances.map((snapshot) => [snapshot.instance!.key, snapshot]),\n\t\t\t\t\t);\n\t\t\t\t\tfor (const instance of [...this.#instances.values()]) {\n\t\t\t\t\t\tif (snapshots.get(instance.key)?.instance?.generation !== instance.generation) {\n\t\t\t\t\t\t\tthis.#instances.remove(instance);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (const snapshot of snapshots.values()) {\n\t\t\t\t\t\tconst instance = this.#instances.get(snapshot.instance!.key);\n\t\t\t\t\t\tif (instance === undefined) this.#spawn(snapshot, context);\n\t\t\t\t\t\telse instance.facade.install(snapshot, context);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"unavailable\":\n\t\t\t\tcase \"replaced\":\n\t\t\t\t\tthrow new Error(\"Keyed service received a singleton lifecycle update\");\n\t\t\t\tcase \"spawned\":\n\t\t\t\t\tthis.#spawn(update.instance, context);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"closed\": {\n\t\t\t\t\tconst instance = this.#instances.get(update.instance.key);\n\t\t\t\t\tif (instance?.generation === update.instance.generation) this.#instances.remove(instance);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"state\": {\n\t\t\t\t\tif (update.instance === undefined) throw new Error(\"Keyed state update has no instance address\");\n\t\t\t\t\tconst instance = this.#instances.get(update.instance.key);\n\t\t\t\t\tif (instance?.generation !== update.instance.generation) return;\n\t\t\t\t\tinstance.facade.update(update.member, update.sequence, update.ops, context);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.#reportError(toError(error));\n\t\t}\n\t}\n\n\t#spawn(snapshot: ServiceInstanceSnapshot, context: Context): void {\n\t\tconst address = snapshot.instance;\n\t\tif (address === undefined) throw new Error(\"Keyed service instance snapshot has no address\");\n\t\tlet active = true;\n\t\tconst facade = new ServiceFacade(\n\t\t\tthis.#service.id,\n\t\t\taddress,\n\t\t\tthis.#transport,\n\t\t\t() => active && !this.#closed,\n\t\t\tthis.#assertAccess,\n\t\t\tthis.#reportError,\n\t\t);\n\t\tfacade.install(snapshot, context);\n\t\tthis.#instances.replace({\n\t\t\tkey: address.key,\n\t\t\tgeneration: address.generation,\n\t\t\tservice: facade.proxy,\n\t\t\tfacade,\n\t\t\tdeactivate: () => {\n\t\t\t\tactive = false;\n\t\t\t\tfacade.clear();\n\t\t\t},\n\t\t});\n\t}\n}\n\nexport class RemoteServiceBindingImpl implements RemoteServiceBinding {\n\treadonly #transport: RemoteServiceTransport;\n\treadonly #allowlist = new Set<string>();\n\treadonly #reportError: ErrorReporter;\n\treadonly #modes = new Map<string, \"singleton\" | \"keyed\">();\n\treadonly #assertAccess: () => void;\n\treadonly #singletons = new Map<string, SingletonBinding>();\n\treadonly #keyed = new Map<string, KeyedBinding<unknown>>();\n\t#bound: boolean;\n\t#readinessRevision = 0;\n\t#bindingTransition = Promise.resolve();\n\t#disposed = false;\n\n\tconstructor(options: RemoteServiceBindingOptions) {\n\t\tthis.#transport = options.transport;\n\t\tconst ids = options.services.map(({ id }) => id);\n\t\tif (new Set(ids).size !== ids.length) throw new TypeError(\"Remote service binding has duplicate service IDs\");\n\t\tfor (const id of ids) this.#allowlist.add(id);\n\t\tthis.#reportError = options.onError ?? (() => {});\n\t\tthis.#assertAccess = options.assertAccess ?? (() => {});\n\t\tthis.#bound = options.bound ?? true;\n\t}\n\n\tuse<T>(service: Service<T>): T {\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAvailable(service.id, \"singleton\");\n\t\tlet binding = this.#singletons.get(service.id);\n\t\tif (binding !== undefined) return binding.facade.proxy as T;\n\t\tbinding = { facade: undefined as unknown as ServiceFacade, active: true, revision: 0 };\n\t\tbinding.facade = new ServiceFacade(\n\t\t\tservice.id,\n\t\t\tundefined,\n\t\t\tthis.#transport,\n\t\t\t() => binding!.active && !this.#disposed && this.#bound,\n\t\t\t() => this.#assertHandleAccess(),\n\t\t\tthis.#reportError,\n\t\t);\n\t\tthis.#singletons.set(service.id, binding);\n\t\tthis.#readinessRevision += 1;\n\t\tif (this.#bound) {\n\t\t\tconst revision = binding.revision;\n\t\t\tconst starting = this.#startSingleton(service.id, binding, revision);\n\t\t\tbinding.starting = starting;\n\t\t\tvoid starting.catch((error: unknown) => {\n\t\t\t\tif (binding.active && binding.revision === revision && !this.#disposed && this.#bound) {\n\t\t\t\t\tthis.#reportError(toError(error));\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn binding.facade.proxy as T;\n\t}\n\n\tobserve<T>(service: Service<T>, handler: (service: T, context: Context) => void | Promise<void>): () => void {\n\t\tthis.#assertRemotable(service);\n\t\tthis.#assertAvailable(service.id, \"keyed\");\n\t\tlet binding = this.#keyed.get(service.id) as KeyedBinding<T> | undefined;\n\t\tif (binding === undefined) {\n\t\t\tbinding = new KeyedBinding(\n\t\t\t\tservice,\n\t\t\t\tthis.#transport,\n\t\t\t\tthis.#reportError,\n\t\t\t\t() => this.#assertHandleAccess(),\n\t\t\t\t() => {\n\t\t\t\t\tif (this.#keyed.get(service.id) !== binding) return;\n\t\t\t\t\tthis.#keyed.delete(service.id);\n\t\t\t\t\tthis.#readinessRevision += 1;\n\t\t\t\t\tvoid binding!.close(BACKGROUND_CONTEXT).catch(this.#reportError);\n\t\t\t\t},\n\t\t\t\tthis.#bound,\n\t\t\t);\n\t\t\tthis.#keyed.set(service.id, binding as KeyedBinding<unknown>);\n\t\t\tthis.#readinessRevision += 1;\n\t\t}\n\t\treturn binding.observe(handler);\n\t}\n\n\tasync ready(context: Context): Promise<void> {\n\t\tif (this.#disposed) throw new Error(\"Remote service binding is disposed\");\n\t\twhile (true) {\n\t\t\tconst revision = this.#readinessRevision;\n\t\t\tconst starts = [\n\t\t\t\tthis.#bindingTransition,\n\t\t\t\t...[...this.#singletons.values()].flatMap((binding) =>\n\t\t\t\t\tbinding.starting === undefined ? [] : [binding.starting],\n\t\t\t\t),\n\t\t\t\t...[...this.#keyed.values()].map((binding) => binding.ready()),\n\t\t\t];\n\t\t\tawait awaitWithContext(\n\t\t\t\tPromise.all(starts).then(() => undefined),\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tif (this.#disposed) throw new Error(\"Remote service binding is disposed\");\n\t\t\tif (revision === this.#readinessRevision) return;\n\t\t}\n\t}\n\n\tasync rebind(bound: boolean, context: Context): Promise<void> {\n\t\tif (this.#disposed) throw new Error(\"Remote service binding is disposed\");\n\t\tthis.#bound = bound;\n\t\tthis.#readinessRevision += 1;\n\t\tconst transitions: Promise<void>[] = [];\n\t\tfor (const [serviceId, binding] of this.#singletons) {\n\t\t\tbinding.revision += 1;\n\t\t\tbinding.facade.clear();\n\t\t\tconst subscription = binding.subscription;\n\t\t\tdelete binding.subscription;\n\t\t\tconst revision = binding.revision;\n\t\t\tconst starting = (async () => {\n\t\t\t\tawait subscription?.close(context);\n\t\t\t\tif (bound) await this.#startSingleton(serviceId, binding, revision);\n\t\t\t})();\n\t\t\tbinding.starting = starting;\n\t\t\ttransitions.push(starting);\n\t\t}\n\t\tfor (const binding of this.#keyed.values()) transitions.push(binding.rebind(bound, context));\n\t\tconst completion = (async () => {\n\t\t\tconst results = await Promise.allSettled(transitions);\n\t\t\tconst errors = results.filter((result): result is PromiseRejectedResult => result.status === \"rejected\");\n\t\t\tif (errors.length > 0)\n\t\t\t\tthrow new AggregateError(\n\t\t\t\t\terrors.map(({ reason }) => reason),\n\t\t\t\t\t\"Failed to rebind services\",\n\t\t\t\t);\n\t\t})();\n\t\tthis.#bindingTransition = completion;\n\t\tawait completion;\n\t}\n\n\tasync dispose(context: Context): Promise<void> {\n\t\tif (this.#disposed) return;\n\t\tthis.#disposed = true;\n\t\tconst closes: Promise<void>[] = [];\n\t\tfor (const binding of this.#singletons.values()) {\n\t\t\tbinding.active = false;\n\t\t\tbinding.facade.clear();\n\t\t\tif (binding.starting) closes.push(binding.starting.catch(() => {}));\n\t\t\tif (binding.subscription) closes.push(Promise.resolve(binding.subscription.close(context)));\n\t\t}\n\t\tfor (const binding of this.#keyed.values()) closes.push(binding.close(context));\n\t\tthis.#singletons.clear();\n\t\tthis.#keyed.clear();\n\t\tconst results = await Promise.allSettled(closes);\n\t\tconst errors = results.filter((result): result is PromiseRejectedResult => result.status === \"rejected\");\n\t\tif (errors.length > 0)\n\t\t\tthrow new AggregateError(\n\t\t\t\terrors.map(({ reason }) => reason),\n\t\t\t\t\"Failed to dispose services\",\n\t\t\t);\n\t}\n\n\tasync #startSingleton(serviceId: string, binding: SingletonBinding, revision: number): Promise<void> {\n\t\tconst subscription = await this.#transport.subscribe(\n\t\t\tserviceId,\n\t\t\t\"singleton\",\n\t\t\t(update, context) => {\n\t\t\t\tif (!binding.active || binding.revision !== revision) return;\n\t\t\t\ttry {\n\t\t\t\t\tif (update.type === \"reset\") {\n\t\t\t\t\t\tvalidateResetSnapshot(update.snapshot, serviceId, \"singleton\");\n\t\t\t\t\t\tconst snapshot = update.snapshot.instances[0];\n\t\t\t\t\t\tif (snapshot === undefined) binding.facade.clear();\n\t\t\t\t\t\telse binding.facade.install(snapshot, context);\n\t\t\t\t\t} else if (update.type === \"unavailable\") {\n\t\t\t\t\t\tbinding.facade.clear();\n\t\t\t\t\t} else if (update.type === \"replaced\") {\n\t\t\t\t\t\tif (update.snapshot.instance !== undefined) {\n\t\t\t\t\t\t\tthrow new Error(\"Singleton replacement has an instance address\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbinding.facade.install(update.snapshot, context);\n\t\t\t\t\t} else if (update.type === \"state\" && update.instance === undefined) {\n\t\t\t\t\t\tbinding.facade.update(update.member, update.sequence, update.ops, context);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.#reportError(toError(error));\n\t\t\t\t}\n\t\t\t},\n\t\t\tBACKGROUND_CONTEXT,\n\t\t);\n\t\tif (!binding.active || this.#disposed || !this.#bound || binding.revision !== revision) {\n\t\t\tawait subscription.close(BACKGROUND_CONTEXT);\n\t\t\treturn;\n\t\t}\n\t\tbinding.subscription = subscription;\n\t\tconst snapshot = subscription.snapshot;\n\t\tif (snapshot.mode !== \"singleton\" || snapshot.serviceId !== serviceId || snapshot.instances.length !== 1) {\n\t\t\tthrow new Error(`Remote service ${serviceId} returned an invalid singleton snapshot`);\n\t\t}\n\t\tbinding.facade.install(snapshot.instances[0]!, serviceDeliveryContext());\n\t\tsubscription.activate();\n\t}\n\n\t#assertHandleAccess(): void {\n\t\tif (this.#disposed) throw new Error(\"Remote service binding is disposed\");\n\t\tthis.#assertAccess();\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#assertAvailable(serviceId: string, mode: \"singleton\" | \"keyed\"): void {\n\t\tif (this.#disposed) throw new Error(\"Remote service binding is disposed\");\n\t\tif (!this.#allowlist.has(serviceId)) {\n\t\t\tthrow new RemoteServiceError(\"service_not_allowed\", `Remote service ${serviceId} is not allowlisted`);\n\t\t}\n\t\tconst existing = this.#modes.get(serviceId);\n\t\tif (existing !== undefined && existing !== mode) {\n\t\t\tthrow new RemoteServiceError(\n\t\t\t\t\"service_mode_mismatch\",\n\t\t\t\t`Remote service ${serviceId} is already used as ${existing}`,\n\t\t\t);\n\t\t}\n\t\tthis.#modes.set(serviceId, mode);\n\t}\n}\n\nfunction validateResetSnapshot(\n\tsnapshot: ServiceSubscriptionSnapshot,\n\tserviceId: string,\n\tmode: \"singleton\" | \"keyed\",\n): void {\n\tif (\n\t\tsnapshot.serviceId !== serviceId ||\n\t\tsnapshot.mode !== mode ||\n\t\t(mode === \"singleton\" && snapshot.instances.length > 1)\n\t) {\n\t\tthrow new Error(\"Remote service reset has the wrong service or mode\");\n\t}\n\tconst keys = new Set<string>();\n\tfor (const instance of snapshot.instances) {\n\t\tif (mode === \"singleton\" ? instance.instance !== undefined : instance.instance === undefined) {\n\t\t\tthrow new Error(\"Remote service reset has an invalid instance address\");\n\t\t}\n\t\tif (instance.instance !== undefined) {\n\t\t\tif (keys.has(instance.instance.key)) throw new Error(\"Remote service reset repeats an instance key\");\n\t\t\tkeys.add(instance.instance.key);\n\t\t}\n\t\tfor (const member of instance.members) {\n\t\t\tif (member.kind === \"state\" && (member.ops.length !== 1 || member.ops[0]?.[0] !== \"r\")) {\n\t\t\t\tthrow new Error(\"Remote service reset must contain full root replacements\");\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction validateMembers(members: readonly ServiceMemberSnapshot[]): ReadonlyMap<string, ServiceMemberSnapshot> {\n\tconst result = new Map<string, ServiceMemberSnapshot>();\n\tfor (const member of members) {\n\t\tif (member.name.length === 0 || result.has(member.name)) {\n\t\t\tthrow new Error(\"Remote service has invalid member descriptions\");\n\t\t}\n\t\tresult.set(member.name, member);\n\t}\n\treturn result;\n}\n\nfunction sameAddress(left: ServiceInstanceAddress | undefined, right: ServiceInstanceAddress | undefined): boolean {\n\tif (left === undefined || right === undefined) return left === right;\n\treturn left.key === right.key && left.generation === right.generation;\n}\n\nfunction isContext(value: unknown): value is Context {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tconst candidate = value as Partial<Context>;\n\treturn typeof candidate.value === \"function\" && typeof candidate.toString === \"function\";\n}\n\nfunction toError(error: unknown): Error {\n\treturn error instanceof Error ? error : new Error(String(error));\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/services/errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/services/errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,YACtC,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,EACzB,4BAA4B,EAC5B,wBAAwB,EACxB,uBAAuB,CACd,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,sBAAsB,CAExF;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;IAEtC,YAAY,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,EAIxD;CACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/services/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACzC,qBAAqB;IACrB,mBAAmB;IACnB,uBAAuB;IACvB,0BAA0B;IAC1B,yBAAyB;IACzB,4BAA4B;IAC5B,wBAAwB;IACxB,uBAAuB;CACd,CAAC;AAIX,MAAM,UAAU,wBAAwB,CAAC,KAAc
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/services/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACzC,qBAAqB;IACrB,mBAAmB;IACnB,uBAAuB;IACvB,0BAA0B;IAC1B,yBAAyB;IACzB,4BAA4B;IAC5B,wBAAwB;IACxB,uBAAuB;CACd,CAAC;AAIX,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACtD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,0BAA0B,CAAC,QAAQ,CAAC,KAA+B,CAAC,CAAC;AAC1G,CAAC;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IACnC,IAAI,CAAyB;IAEtC,YAAY,IAA4B,EAAE,OAAe;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;CACD","sourcesContent":["export const REMOTE_SERVICE_ERROR_CODES = [\n\t\"service_not_allowed\",\n\t\"service_not_found\",\n\t\"service_mode_mismatch\",\n\t\"service_member_not_found\",\n\t\"service_member_mismatch\",\n\t\"service_instance_not_found\",\n\t\"service_stale_instance\",\n\t\"service_invalid_value\",\n] as const;\n\nexport type RemoteServiceErrorCode = (typeof REMOTE_SERVICE_ERROR_CODES)[number];\n\nexport function isRemoteServiceErrorCode(value: unknown): value is RemoteServiceErrorCode {\n\treturn typeof value === \"string\" && REMOTE_SERVICE_ERROR_CODES.includes(value as RemoteServiceErrorCode);\n}\n\nexport class RemoteServiceError extends Error {\n\treadonly code: RemoteServiceErrorCode;\n\n\tconstructor(code: RemoteServiceErrorCode, message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"RemoteServiceError\";\n\t\tthis.code = code;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle.d.ts","sourceRoot":"","sources":["../../src/services/handle.ts"],"names":[],"mappings":"AAAA,UAAU,aAAa;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAID,mEAAmE;AACnE,qBAAa,WAAW;;IAKvB,YAAY,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAGlD;IAED,IAAI,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,IAAI,GAAG,CAAC,CAEnC;IAED,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAEjC;IAED,MAAM,IAAI,IAAI,CAEb;IAED,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,GAAG,aAAa,CAQtE;CACD"
|
|
1
|
+
{"version":3,"file":"handle.d.ts","sourceRoot":"","sources":["../../src/services/handle.ts"],"names":[],"mappings":"AAAA,UAAU,aAAa;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAID,mEAAmE;AACnE,qBAAa,WAAW;;IAKvB,YAAY,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAGlD;IAED,IAAI,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,IAAI,GAAG,CAAC,CAEnC;IAED,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAEjC;IAED,MAAM,IAAI,IAAI,CAEb;IAED,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,GAAG,aAAa,CAQtE;CACD"}
|
package/dist/services/handle.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
var _a;
|
|
1
2
|
/** Host-owned mutable target with consumer-owned guarded views. */
|
|
2
3
|
export class ServiceSlot {
|
|
3
4
|
#serviceId;
|
|
@@ -87,12 +88,13 @@ class ValueView {
|
|
|
87
88
|
return current;
|
|
88
89
|
let child = this.#children.get(property);
|
|
89
90
|
if (child === undefined) {
|
|
90
|
-
child = new
|
|
91
|
+
child = new _a(resolve, true);
|
|
91
92
|
this.#children.set(property, child);
|
|
92
93
|
}
|
|
93
94
|
return child.proxy;
|
|
94
95
|
}
|
|
95
96
|
}
|
|
97
|
+
_a = ValueView;
|
|
96
98
|
function isObject(value) {
|
|
97
99
|
return (typeof value === "object" && value !== null) || typeof value === "function";
|
|
98
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle.js","sourceRoot":"","sources":["../../src/services/handle.ts"],"names":[],"mappings":"AAOA,mEAAmE;AACnE,MAAM,OAAO,WAAW;IACd,UAAU,CAAS;IACnB,YAAY,CAAU;IAC/B,eAAe,CAAqB;IAEpC,YAAY,SAAiB,EAAE,WAAoB
|
|
1
|
+
{"version":3,"file":"handle.js","sourceRoot":"","sources":["../../src/services/handle.ts"],"names":[],"mappings":"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","sourcesContent":["interface ResolvedValue {\n\treadonly value: unknown;\n\treadonly receiver: object;\n}\n\ntype ValueResolver = () => ResolvedValue;\n\n/** Host-owned mutable target with consumer-owned guarded views. */\nexport class ServiceSlot {\n\treadonly #serviceId: string;\n\treadonly #wrapObjects: boolean;\n\t#implementation: object | undefined;\n\n\tconstructor(serviceId: string, wrapObjects: boolean) {\n\t\tthis.#serviceId = serviceId;\n\t\tthis.#wrapObjects = wrapObjects;\n\t}\n\n\tview<T>(assertAccess: () => void): T {\n\t\treturn new ServiceView(this, assertAccess, this.#wrapObjects).proxy as T;\n\t}\n\n\tbind(implementation: object): void {\n\t\tthis.#implementation = implementation;\n\t}\n\n\tunbind(): void {\n\t\tthis.#implementation = undefined;\n\t}\n\n\tresolve(property: PropertyKey, assertAccess: () => void): ResolvedValue {\n\t\tassertAccess();\n\t\tconst implementation = this.#implementation;\n\t\tif (implementation === undefined) throw new Error(`Service ${this.#serviceId} is disconnected`);\n\t\treturn {\n\t\t\tvalue: Reflect.get(implementation, property, implementation),\n\t\t\treceiver: implementation,\n\t\t};\n\t}\n}\n\nclass ServiceView {\n\treadonly #slot: ServiceSlot;\n\treadonly #assertAccess: () => void;\n\treadonly #wrapObjects: boolean;\n\treadonly #members = new Map<PropertyKey, ValueView>();\n\treadonly proxy: object;\n\n\tconstructor(slot: ServiceSlot, assertAccess: () => void, wrapObjects: boolean) {\n\t\tthis.#slot = slot;\n\t\tthis.#assertAccess = assertAccess;\n\t\tthis.#wrapObjects = wrapObjects;\n\t\tthis.proxy = new Proxy(Object.create(null) as object, {\n\t\t\tget: (_target, property) => this.#getMember(property),\n\t\t});\n\t}\n\n\t#getMember(property: PropertyKey): unknown {\n\t\tconst resolve = (): ResolvedValue => this.#slot.resolve(property, this.#assertAccess);\n\t\tconst current = resolve().value;\n\t\tif (!isObject(current) || (typeof current !== \"function\" && !this.#wrapObjects)) return current;\n\t\tlet member = this.#members.get(property);\n\t\tif (member === undefined) {\n\t\t\tmember = new ValueView(resolve, typeof current === \"function\");\n\t\t\tthis.#members.set(property, member);\n\t\t}\n\t\treturn member.proxy;\n\t}\n}\n\nclass ValueView {\n\treadonly #resolve: ValueResolver;\n\treadonly #children = new Map<PropertyKey, ValueView>();\n\treadonly proxy: object;\n\n\tconstructor(resolve: ValueResolver, callable: boolean) {\n\t\tthis.#resolve = resolve;\n\t\tconst target: object = callable ? () => undefined : Object.create(null);\n\t\tthis.proxy = new Proxy(target, {\n\t\t\tapply: (_target, _thisArg, args) => this.#invoke(args),\n\t\t\tget: (_target, property) => this.#get(property),\n\t\t});\n\t}\n\n\t#invoke(args: unknown[]): unknown {\n\t\tconst { value, receiver } = this.#resolve();\n\t\tif (typeof value !== \"function\") throw new TypeError(\"Service member is not callable\");\n\t\treturn Reflect.apply(value, receiver, args);\n\t}\n\n\t#get(property: PropertyKey): unknown {\n\t\tconst resolve = (): ResolvedValue => {\n\t\t\tconst parent = this.#resolve();\n\t\t\tif (!isObject(parent.value)) throw new TypeError(\"Service member does not have properties\");\n\t\t\treturn {\n\t\t\t\tvalue: Reflect.get(parent.value, property, parent.value),\n\t\t\t\treceiver: parent.value,\n\t\t\t};\n\t\t};\n\t\tconst current = resolve().value;\n\t\tif (typeof current !== \"function\") return current;\n\t\tlet child = this.#children.get(property);\n\t\tif (child === undefined) {\n\t\t\tchild = new ValueView(resolve, true);\n\t\t\tthis.#children.set(property, child);\n\t\t}\n\t\treturn child.proxy;\n\t}\n}\n\nfunction isObject(value: unknown): value is object {\n\treturn (typeof value === \"object\" && value !== null) || typeof value === \"function\";\n}\n"]}
|
|
@@ -13,6 +13,7 @@ export declare class InstanceDirectory<TEntry extends InstanceDirectoryEntry> {
|
|
|
13
13
|
readonly onError: (error: Error) => void;
|
|
14
14
|
});
|
|
15
15
|
get observerCount(): number;
|
|
16
|
+
values(): IterableIterator<TEntry>;
|
|
16
17
|
get(key: string): TEntry | undefined;
|
|
17
18
|
insert(entry: TEntry): void;
|
|
18
19
|
replace(entry: TEntry): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../src/services/instances.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,UAAU,IAAI,IAAI,CAAC;CACnB;AAQD,wFAAwF;AACxF,qBAAa,iBAAiB,CAAC,MAAM,SAAS,sBAAsB;;IAOnE,YAAY,OAAO,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;KAAE,EAGzF;IAED,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnC;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAO1B;IAED,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAW3B;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG1B;IAED,KAAK,IAAI,IAAI,CAKZ;IAED,KAAK,IAAI,IAAI,CAIZ;IAED,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAkBtF;IAED,OAAO,IAAI,IAAI,CAad;CAgCD"
|
|
1
|
+
{"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../src/services/instances.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,UAAU,IAAI,IAAI,CAAC;CACnB;AAQD,wFAAwF;AACxF,qBAAa,iBAAiB,CAAC,MAAM,SAAS,sBAAsB;;IAOnE,YAAY,OAAO,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;KAAE,EAGzF;IAED,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAEjC;IAED,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnC;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAO1B;IAED,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAW3B;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG1B;IAED,KAAK,IAAI,IAAI,CAKZ;IAED,KAAK,IAAI,IAAI,CAIZ;IAED,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAkBtF;IAED,OAAO,IAAI,IAAI,CAad;CAgCD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instances.js","sourceRoot":"","sources":["../../src/services/instances.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAgBrE,wFAAwF;AACxF,MAAM,OAAO,iBAAiB;IACpB,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IACrC,UAAU,GAAG,IAAI,GAAG,EAAY,CAAC;IACjC,YAAY,CAAyB;IAC9C,MAAM,CAAU;IAChB,SAAS,GAAG,KAAK,CAAC;IAElB,YAAY,OAA8E
|
|
1
|
+
{"version":3,"file":"instances.js","sourceRoot":"","sources":["../../src/services/instances.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAgBrE,wFAAwF;AACxF,MAAM,OAAO,iBAAiB;IACpB,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IACrC,UAAU,GAAG,IAAI,GAAG,EAAY,CAAC;IACjC,YAAY,CAAyB;IAC9C,MAAM,CAAU;IAChB,SAAS,GAAG,KAAK,CAAC;IAElB,YAAY,OAA8E;QACzF,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IACrC,CAAC;IAED,IAAI,aAAa;QAChB,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED,MAAM;QACL,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC/B,CAAC;IAED,GAAG,CAAC,GAAW;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,CAAC,KAAa;QACnB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,sDAAsD,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACpC,IAAI,IAAI,CAAC,MAAM;YAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,CAAC,KAAa;QACpB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,IAAI,QAAQ,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,EAAE,CAAC;gBAC9C,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACpC,IAAI,IAAI,CAAC,MAAM;YAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,KAAa;QACnB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK;YAAE,OAAO;QACnD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACnE,CAAC;IAED,KAAK;QACJ,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,CAAI,OAA+D;QACzE,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAa;YAC1B,OAAO,EAAE,OAA8B;YACvC,KAAK,EAAE,IAAI,GAAG,EAAE;YAChB,MAAM,EAAE,KAAK;SACb,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;gBAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,GAAG,EAAE;YACX,IAAI,QAAQ,CAAC,MAAM;gBAAE,OAAO;YAC5B,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC;YACvB,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE;gBAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1D,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC;IACH,CAAC;IAED,OAAO;QACN,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC;YACvB,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE;gBAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1D,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;YACjD,KAAK,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,OAAO,CAAC,KAAa;QACpB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK;YAAE,OAAO;QACnD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChC,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;YACpC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACF,CAAC;IAED,SAAS,CAAC,KAAa;QACtB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,CAAC,QAAkB,EAAE,KAAa;QACvC,IAAI,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO;QACzD,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;QAC3D,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC;YACJ,KAAK,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;gBACvF,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO;oBAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO;gBAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACtE,CAAC;IACF,CAAC;IAED,aAAa;QACZ,IAAI,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC5E,CAAC;CACD;AAED,SAAS,OAAO,CAAC,KAAc;IAC9B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAClE,CAAC","sourcesContent":["import { BACKGROUND_CONTEXT, withCancel } from \"../context/index.ts\";\nimport type { Context } from \"../types.ts\";\n\nexport interface InstanceDirectoryEntry {\n\treadonly key: string;\n\treadonly generation: number;\n\treadonly service: object;\n\tdeactivate(): void;\n}\n\ninterface Observer {\n\treadonly handler: (service: object, context: Context) => void | Promise<void>;\n\treadonly tasks: Map<InstanceDirectoryEntry, { readonly cancel: (reason?: unknown) => void }>;\n\tclosed: boolean;\n}\n\n/** Owns keyed instance lifetime and the cancellable tasks observing those instances. */\nexport class InstanceDirectory<TEntry extends InstanceDirectoryEntry> {\n\treadonly #entries = new Map<string, TEntry>();\n\treadonly #observers = new Set<Observer>();\n\treadonly #reportError: (error: Error) => void;\n\t#ready: boolean;\n\t#disposed = false;\n\n\tconstructor(options: { readonly ready: boolean; readonly onError: (error: Error) => void }) {\n\t\tthis.#ready = options.ready;\n\t\tthis.#reportError = options.onError;\n\t}\n\n\tget observerCount(): number {\n\t\treturn this.#observers.size;\n\t}\n\n\tvalues(): IterableIterator<TEntry> {\n\t\treturn this.#entries.values();\n\t}\n\n\tget(key: string): TEntry | undefined {\n\t\treturn this.#entries.get(key);\n\t}\n\n\tinsert(entry: TEntry): void {\n\t\tthis.#assertActive();\n\t\tif (this.#entries.has(entry.key)) {\n\t\t\tthrow new Error(`Keyed service already has a live instance with key ${entry.key}`);\n\t\t}\n\t\tthis.#entries.set(entry.key, entry);\n\t\tif (this.#ready) this.#startAll(entry);\n\t}\n\n\treplace(entry: TEntry): void {\n\t\tthis.#assertActive();\n\t\tconst previous = this.#entries.get(entry.key);\n\t\tif (previous !== undefined) {\n\t\t\tif (previous.generation === entry.generation) {\n\t\t\t\tthrow new Error(\"Keyed service repeated a live generation\");\n\t\t\t}\n\t\t\tthis.#remove(previous);\n\t\t}\n\t\tthis.#entries.set(entry.key, entry);\n\t\tif (this.#ready) this.#startAll(entry);\n\t}\n\n\tremove(entry: TEntry): void {\n\t\tif (this.#entries.get(entry.key) !== entry) return;\n\t\tthis.#remove(entry);\n\t}\n\n\tready(): void {\n\t\tthis.#assertActive();\n\t\tif (this.#ready) return;\n\t\tthis.#ready = true;\n\t\tfor (const entry of this.#entries.values()) this.#startAll(entry);\n\t}\n\n\treset(): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#ready = false;\n\t\tfor (const entry of [...this.#entries.values()]) this.#remove(entry);\n\t}\n\n\tobserve<T>(handler: (service: T, context: Context) => void | Promise<void>): () => void {\n\t\tthis.#assertActive();\n\t\tconst observer: Observer = {\n\t\t\thandler: handler as Observer[\"handler\"],\n\t\t\ttasks: new Map(),\n\t\t\tclosed: false,\n\t\t};\n\t\tthis.#observers.add(observer);\n\t\tif (this.#ready) {\n\t\t\tfor (const entry of this.#entries.values()) this.#start(observer, entry);\n\t\t}\n\t\treturn () => {\n\t\t\tif (observer.closed) return;\n\t\t\tobserver.closed = true;\n\t\t\tfor (const task of observer.tasks.values()) task.cancel();\n\t\t\tobserver.tasks.clear();\n\t\t\tthis.#observers.delete(observer);\n\t\t};\n\t}\n\n\tdispose(): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#disposed = true;\n\t\tfor (const observer of this.#observers) {\n\t\t\tobserver.closed = true;\n\t\t\tfor (const task of observer.tasks.values()) task.cancel();\n\t\t\tobserver.tasks.clear();\n\t\t}\n\t\tthis.#observers.clear();\n\t\tfor (const entry of [...this.#entries.values()]) {\n\t\t\tentry.deactivate();\n\t\t}\n\t\tthis.#entries.clear();\n\t}\n\n\t#remove(entry: TEntry): void {\n\t\tif (this.#entries.get(entry.key) !== entry) return;\n\t\tthis.#entries.delete(entry.key);\n\t\tentry.deactivate();\n\t\tfor (const observer of this.#observers) {\n\t\t\tobserver.tasks.get(entry)?.cancel();\n\t\t\tobserver.tasks.delete(entry);\n\t\t}\n\t}\n\n\t#startAll(entry: TEntry): void {\n\t\tfor (const observer of this.#observers) this.#start(observer, entry);\n\t}\n\n\t#start(observer: Observer, entry: TEntry): void {\n\t\tif (observer.closed || observer.tasks.has(entry)) return;\n\t\tconst { context, cancel } = withCancel(BACKGROUND_CONTEXT);\n\t\tobserver.tasks.set(entry, { cancel });\n\t\ttry {\n\t\t\tvoid Promise.resolve(observer.handler(entry.service, context)).catch((error: unknown) => {\n\t\t\t\tif (!context.abortSignal?.aborted) this.#reportError(toError(error));\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (!context.abortSignal?.aborted) this.#reportError(toError(error));\n\t\t}\n\t}\n\n\t#assertActive(): void {\n\t\tif (this.#disposed) throw new Error(\"Keyed service directory is disposed\");\n\t}\n}\n\nfunction toError(error: unknown): Error {\n\treturn error instanceof Error ? error : new Error(String(error));\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loopback.d.ts","sourceRoot":"","sources":["../../src/services/loopback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3D,kFAAkF;AAClF,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,qBAAqB,GAAG,sBAAsB,CAYtG"
|
|
1
|
+
{"version":3,"file":"loopback.d.ts","sourceRoot":"","sources":["../../src/services/loopback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3D,kFAAkF;AAClF,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,qBAAqB,GAAG,sBAAsB,CAYtG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loopback.js","sourceRoot":"","sources":["../../src/services/loopback.ts"],"names":[],"mappings":"AAGA,kFAAkF;AAClF,MAAM,UAAU,8BAA8B,CAAC,QAA+B
|
|
1
|
+
{"version":3,"file":"loopback.js","sourceRoot":"","sources":["../../src/services/loopback.ts"],"names":[],"mappings":"AAGA,kFAAkF;AAClF,MAAM,UAAU,8BAA8B,CAAC,QAA+B;IAC7E,OAAO;QACN,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;QACzD,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YAC9C,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YACnE,OAAO;gBACN,QAAQ,EAAE,YAAY,CAAC,QAAQ;gBAC/B,QAAQ,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE;gBACvC,KAAK,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE;aACjC,CAAC;QACH,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["import type { RemoteServiceTransport } from \"../types.ts\";\nimport type { RemoteServiceProvider } from \"./provider.ts\";\n\n/** Connects a provider to a binding without changing remote service semantics. */\nexport function createLoopbackServiceTransport(provider: RemoteServiceProvider): RemoteServiceTransport {\n\treturn {\n\t\tinvoke: (call, context) => provider.invoke(call, context),\n\t\tsubscribe: async (serviceId, mode, listener) => {\n\t\t\tconst subscription = provider.subscribe(serviceId, mode, listener);\n\t\t\treturn {\n\t\t\t\tsnapshot: subscription.snapshot,\n\t\t\t\tactivate: () => subscription.activate(),\n\t\t\t\tclose: () => subscription.close(),\n\t\t\t};\n\t\t},\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/services/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,OAAO,EACP,SAAS,EACT,qBAAqB,EACrB,OAAO,EACP,WAAW,EACX,qBAAqB,EAIrB,WAAW,EACX,qBAAqB,EACrB,mBAAmB,EAEnB,MAAM,aAAa,CAAC;AAoCrB,UAAU,yBAAyB;IAClC,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACpE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;CAC3B;AAYD,MAAM,MAAM,sBAAsB,GAAG,CACpC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,OAAO,KACZ,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,yFAAyF;AACzF,MAAM,WAAW,qBAAqB;IACrC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAC7G,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,qBAAa,qBAAqB;;IAKjC,YAAY,OAAO,EAAE,SAAS,CAAC,yBAAyB,GAAG;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,EAuBpF;IAED,IAAI,SAAS,IAAI,SAAS,qBAAqB,EAAE,CAEhD;IAED,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAavF;IAED,yFAAyF;IACzF,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAWrC;IAED,0EAA0E;IAC1E,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAOnG;IAED,iFAAiF;IACjF,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAiBvF;IAED,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAS7B;IAED,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CA6BxG;IAEK,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAuBhF;IAED,SAAS,CACR,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GACjE,mBAAmB,CA4CrB;IAED,OAAO,IAAI,IAAI,CAuCd;CAgKD;AA4CD,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,qBAAqB,GAAG,qBAAqB,CAoClG;AAED,wBAAgB,mCAAmC,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI,CAEpG","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.d.ts","sourceRoot":"","sources":["../../src/services/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,OAAO,EACP,SAAS,EACT,qBAAqB,EACrB,OAAO,EACP,WAAW,EACX,qBAAqB,EAIrB,WAAW,EACX,qBAAqB,EACrB,mBAAmB,EAEnB,MAAM,aAAa,CAAC;AAqCrB,UAAU,yBAAyB;IAClC,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACpE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;CAC3B;AAYD,MAAM,MAAM,sBAAsB,GAAG,CACpC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,OAAO,KACZ,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,yFAAyF;AACzF,MAAM,WAAW,qBAAqB;IACrC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAC7G,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,qBAAa,qBAAqB;;IAKjC,YAAY,OAAO,EAAE,SAAS,CAAC,yBAAyB,GAAG;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,EAuBpF;IAED,IAAI,SAAS,IAAI,SAAS,qBAAqB,EAAE,CAEhD;IAED,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAavF;IAED,yFAAyF;IACzF,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAWrC;IAED,0EAA0E;IAC1E,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAOnG;IAED,iFAAiF;IACjF,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAiBvF;IAED,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAS7B;IAED,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CA6BxG;IAEK,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAuBhF;IAED,SAAS,CACR,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GACjE,mBAAmB,CAiCrB;IAED,OAAO,IAAI,IAAI,CAuCd;CAmKD;AAqED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,qBAAqB,GAAG,qBAAqB,CAoClG;AAED,wBAAgB,mCAAmC,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI,CAEpG"}
|