@earendil-works/chord 1.0.4 → 1.2.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/CHANGELOG.md +20 -0
- package/README.md +77 -194
- package/dist/cell.d.ts +101 -0
- package/dist/cell.d.ts.map +1 -0
- package/dist/cell.js +316 -0
- package/dist/cell.js.map +1 -0
- package/dist/cluster.d.ts +26 -0
- package/dist/cluster.d.ts.map +1 -0
- package/dist/cluster.js +214 -0
- package/dist/cluster.js.map +1 -0
- package/dist/connection.d.ts +157 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +757 -0
- package/dist/connection.js.map +1 -0
- package/dist/context/index.d.ts +12 -1
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js.map +1 -1
- package/dist/contract.d.ts +133 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +157 -0
- package/dist/contract.js.map +1 -0
- package/dist/declare.d.ts +70 -0
- package/dist/declare.d.ts.map +1 -0
- package/dist/declare.js +22 -0
- package/dist/declare.js.map +1 -0
- package/dist/delta/apply-immutable-trusted.js.map +1 -1
- package/dist/delta/diff.d.ts +1 -1
- package/dist/delta/diff.d.ts.map +1 -1
- package/dist/delta/diff.js.map +1 -1
- package/dist/delta/index.d.ts +2 -2
- package/dist/delta/index.d.ts.map +1 -1
- package/dist/delta/index.js +41 -0
- package/dist/delta/index.js.map +1 -1
- package/dist/delta/revision-validator.d.ts +1 -1
- package/dist/delta/revision-validator.d.ts.map +1 -1
- package/dist/delta/revision-validator.js.map +1 -1
- package/dist/delta/tracker.d.ts +1 -1
- package/dist/delta/tracker.d.ts.map +1 -1
- package/dist/delta/tracker.js +40 -4
- package/dist/delta/tracker.js.map +1 -1
- package/dist/errors.d.ts +27 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +44 -0
- package/dist/errors.js.map +1 -0
- package/dist/host.d.ts +254 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +795 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +17 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/json.d.ts +9 -1
- package/dist/json.d.ts.map +1 -1
- package/dist/json.js.map +1 -1
- package/dist/link.d.ts +72 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +169 -0
- package/dist/link.js.map +1 -0
- package/dist/loader.d.ts +4 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +68 -0
- package/dist/loader.js.map +1 -0
- package/dist/manager.d.ts +115 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +319 -0
- package/dist/manager.js.map +1 -0
- package/dist/node.d.ts +3 -4
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +3 -2
- package/dist/node.js.map +1 -1
- package/dist/publish.d.ts +5 -0
- package/dist/publish.d.ts.map +1 -0
- package/dist/publish.js +40 -0
- package/dist/publish.js.map +1 -0
- package/dist/record.d.ts +320 -0
- package/dist/record.d.ts.map +1 -0
- package/dist/record.js +1292 -0
- package/dist/record.js.map +1 -0
- package/dist/registry.d.ts +25 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +6 -0
- package/dist/registry.js.map +1 -0
- package/dist/reload.d.ts +118 -0
- package/dist/reload.d.ts.map +1 -0
- package/dist/reload.js +589 -0
- package/dist/reload.js.map +1 -0
- package/dist/remote.d.ts +70 -0
- package/dist/remote.d.ts.map +1 -0
- package/dist/remote.js +308 -0
- package/dist/remote.js.map +1 -0
- package/dist/schema.d.ts +21 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +228 -0
- package/dist/schema.js.map +1 -0
- package/dist/state.d.ts +92 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/{services/state.js → state.js} +28 -138
- package/dist/state.js.map +1 -0
- package/dist/types.d.ts +62 -262
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/websocket.d.ts +16 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +15 -0
- package/dist/websocket.js.map +1 -0
- package/dist/wire.d.ts +135 -0
- package/dist/wire.d.ts.map +1 -0
- package/dist/wire.js +112 -0
- package/dist/wire.js.map +1 -0
- package/docs/guide.md +750 -0
- package/docs/spec.md +261 -0
- package/docs/tutorial.md +909 -0
- package/package.json +10 -11
- package/src/delta/README.md +5 -3
- package/dist/api.d.ts +0 -20
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js +0 -77
- package/dist/api.js.map +0 -1
- package/dist/bundler.d.ts +0 -6
- package/dist/bundler.d.ts.map +0 -1
- package/dist/bundler.js +0 -3
- package/dist/bundler.js.map +0 -1
- package/dist/facets/host.d.ts +0 -12
- package/dist/facets/host.d.ts.map +0 -1
- package/dist/facets/host.js +0 -763
- package/dist/facets/host.js.map +0 -1
- package/dist/facets/loader.d.ts +0 -3
- package/dist/facets/loader.d.ts.map +0 -1
- package/dist/facets/loader.js +0 -5
- package/dist/facets/loader.js.map +0 -1
- package/dist/node/bundle-loader.d.ts +0 -30
- package/dist/node/bundle-loader.d.ts.map +0 -1
- package/dist/node/bundle-loader.js +0 -377
- package/dist/node/bundle-loader.js.map +0 -1
- package/dist/node/bundle.d.ts +0 -26
- package/dist/node/bundle.d.ts.map +0 -1
- package/dist/node/bundle.js +0 -183
- package/dist/node/bundle.js.map +0 -1
- package/dist/node/manifest.d.ts +0 -36
- package/dist/node/manifest.d.ts.map +0 -1
- package/dist/node/manifest.js +0 -6
- package/dist/node/manifest.js.map +0 -1
- package/dist/node/package.d.ts +0 -15
- package/dist/node/package.d.ts.map +0 -1
- package/dist/node/package.js +0 -199
- package/dist/node/package.js.map +0 -1
- package/dist/services/consumer.d.ts +0 -11
- package/dist/services/consumer.d.ts.map +0 -1
- package/dist/services/consumer.js +0 -585
- package/dist/services/consumer.js.map +0 -1
- package/dist/services/errors.d.ts +0 -8
- package/dist/services/errors.d.ts.map +0 -1
- package/dist/services/errors.js +0 -22
- package/dist/services/errors.js.map +0 -1
- package/dist/services/handle.d.ts +0 -15
- package/dist/services/handle.d.ts.map +0 -1
- package/dist/services/handle.js +0 -101
- package/dist/services/handle.js.map +0 -1
- package/dist/services/instances.d.ts +0 -26
- package/dist/services/instances.d.ts.map +0 -1
- package/dist/services/instances.js +0 -140
- package/dist/services/instances.js.map +0 -1
- package/dist/services/loopback.d.ts +0 -5
- package/dist/services/loopback.d.ts.map +0 -1
- package/dist/services/loopback.js +0 -15
- package/dist/services/loopback.js.map +0 -1
- package/dist/services/provider.d.ts +0 -37
- package/dist/services/provider.d.ts.map +0 -1
- package/dist/services/provider.js +0 -521
- package/dist/services/provider.js.map +0 -1
- package/dist/services/state-codec.d.ts +0 -15
- package/dist/services/state-codec.d.ts.map +0 -1
- package/dist/services/state-codec.js +0 -133
- package/dist/services/state-codec.js.map +0 -1
- package/dist/services/state-internals.d.ts +0 -13
- package/dist/services/state-internals.d.ts.map +0 -1
- package/dist/services/state-internals.js +0 -10
- package/dist/services/state-internals.js.map +0 -1
- package/dist/services/state.d.ts +0 -28
- package/dist/services/state.d.ts.map +0 -1
- package/dist/services/state.js.map +0 -1
- package/dist/services/wire.d.ts +0 -63
- package/dist/services/wire.d.ts.map +0 -1
- package/dist/services/wire.js +0 -186
- package/dist/services/wire.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Replicated state: an immutable JSON value with ordered, serialized change notifications. Either authoritative and\n * mutable (`replicatedState(initial)`) or a publication-only view of an external revision source\n * (`replicatedState(source)`).\n */\nimport { BACKGROUND_CONTEXT, type Context } from \"./context/index.ts\";\nimport { type Draft, type Op, type Prepared, type Tracker, track } from \"./delta/index.ts\";\n\nexport interface ReplicatedStateDelivery {\n\treadonly kind: \"hydrate\" | \"update\";\n\treadonly sequence: number;\n}\n\nexport interface ReplicatedState<T> {\n\t/**\n\t * Contract-immutable value, or undefined until hydration. It is not frozen and may share containers with an\n\t * in-process provider; consumers must not mutate it. Later updates do not mutate previously returned values.\n\t */\n\treadonly value: T | undefined;\n\t/**\n\t * Each subscription serializes callbacks, awaiting hydration before updates. Values are immutable and may\n\t * share unchanged revision data. At most 100 deliveries wait behind the running callback; overflow keeps\n\t * only the newest pending value/context/delivery, so update sequences may skip. Failures are reported in\n\t * isolation and delivery continues. Unsubscribe discards pending work without aborting or joining a callback.\n\t */\n\tsubscribe(listener: (value: T, context: Context, delivery: ReplicatedStateDelivery) => Promise<void>): () => void;\n\tsubscribe(listener: (value: T, context: Context, delivery: ReplicatedStateDelivery) => void): () => void;\n}\n\nexport interface MutableReplicatedState<T extends object> extends ReplicatedState<T> {\n\treadonly value: T;\n\t/**\n\t * Atomically publish one synchronous overlay mutation. Draft handles are unusable after the callback returns.\n\t * Values placed through the draft are cloned by value; assigning `undefined` to an object property deletes it.\n\t */\n\tchange(context: Context, mutate: (draft: Draft<T>) => void): void;\n\t/**\n\t * Atomically take immutable ownership of an alias-free strict-JSON replacement.\n\t * The caller must not mutate the transferred root after this call.\n\t */\n\treplace(context: Context, value: T): void;\n}\n\n/** One immutable authoritative revision committed after an attachment snapshot. */\nexport interface ReplicatedStateSourceFrame<T> {\n\t/** Monotonic source cursor. The first frame after a snapshot must be `snapshot.cursor + 1`. */\n\treadonly cursor: number;\n\t/** The exact immutable value produced by this commit. */\n\treadonly value: T;\n\t/** The exact immutable operation batch that produced `value` from the preceding source revision. */\n\treadonly ops: readonly Op[];\n\treadonly context: Context;\n}\n\nexport interface ReplicatedStateSourceAttachment<T> {\n\t/** Fixed immutable snapshot captured at the atomic attachment boundary. */\n\treadonly snapshot: { readonly value: T; readonly cursor: number };\n\t/**\n\t * Install the sole listener and synchronously drain every buffered frame in source commit order.\n\t * This method is single-use. After it begins, every new committed frame must also be delivered in order\n\t * until disposal, including commits made reentrantly while a prior frame is being delivered.\n\t */\n\tactivate(listener: (frame: ReplicatedStateSourceFrame<T>) => void): void;\n\t/** Stop delivery and release source resources. Disposal must be idempotent. */\n\tdispose(): void;\n}\n\n/**\n * An authoritative immutable revision source.\n *\n * `attach()` must synchronously and atomically capture one snapshot and register the returned attachment to buffer\n * every later committed frame. The snapshot must include every commit before that boundary; buffered frames must\n * include every commit after it, with no overlap or gap. Snapshot values, frame values, and operation batches are\n * immutable and remain valid after delivery. Chord only publishes these references; it never applies or re-diffs them.\n */\nexport interface ReplicatedStateSource<T> {\n\tattach(): ReplicatedStateSourceAttachment<T>;\n}\n\nexport interface ReplicatedStateSourceOptions {\n\t/** Receives source-contract and publication-listener failures without throwing them into the source. */\n\treadonly onError?: (error: Error) => void;\n}\n\n/** A synchronously hydrated publication-only state backed by one source attachment. */\nexport interface AttachedReplicatedState<T> extends ReplicatedState<T> {\n\treadonly value: T;\n\t/** Idempotently release the source attachment. The last published value remains readable. */\n\tdispose(): void;\n}\n\n/** The void signature also accepts synchronous callbacks that return an ignored value. */\ntype StateListener<T> = (value: T, context: Context, delivery: ReplicatedStateDelivery) => void;\n\ntype StateDelivery<T> = {\n\treadonly value: T;\n\treadonly context: Context;\n\treadonly delivery: ReplicatedStateDelivery;\n};\n\n/** One public subscription, independent of producer and other subscriber progress. */\nclass StateSubscriber<T> {\n\treadonly #listener: StateListener<T>;\n\treadonly #reportError: (error: Error) => void;\n\treadonly #pending: StateDelivery<T>[] = [];\n\t#running = false;\n\t#started = false;\n\t#closed = false;\n\n\tconstructor(listener: StateListener<T>, reportError: (error: Error) => void) {\n\t\tthis.#listener = listener;\n\t\tthis.#reportError = reportError;\n\t}\n\n\tpush(frame: StateDelivery<T>): void {\n\t\tif (this.#closed) return;\n\t\tif (this.#pending.length === 100) {\n\t\t\t// A cold replica can queue updates reentrantly before this subscriber's first hydration starts.\n\t\t\tconst hydration = this.#started ? undefined : this.#pending[0];\n\t\t\tthis.#pending.length = 0;\n\t\t\tif (hydration !== undefined) this.#pending.push(hydration);\n\t\t}\n\t\tthis.#pending.push(frame);\n\t}\n\n\tdrain(): void {\n\t\tif (this.#running || this.#closed) return;\n\t\tthis.#running = true;\n\t\tfor (let frame = this.#pending.shift(); frame !== undefined; frame = this.#pending.shift()) {\n\t\t\tthis.#started = true;\n\t\t\ttry {\n\t\t\t\tconst result: unknown = this.#listener(frame.value, frame.context, frame.delivery);\n\t\t\t\tif (isPromiseLike(result)) {\n\t\t\t\t\tvoid Promise.resolve(result).then(\n\t\t\t\t\t\t() => this.#resume(),\n\t\t\t\t\t\t(error: unknown) => {\n\t\t\t\t\t\t\tthis.#report(error);\n\t\t\t\t\t\t\tthis.#resume();\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.#report(error);\n\t\t\t}\n\t\t}\n\t\tthis.#running = false;\n\t}\n\n\tclear(): void {\n\t\tthis.#pending.length = 0;\n\t}\n\n\tclose(): void {\n\t\tthis.#closed = true;\n\t\tthis.clear();\n\t}\n\n\t#resume(): void {\n\t\tthis.#running = false;\n\t\tthis.drain();\n\t}\n\n\t#report(error: unknown): void {\n\t\ttry {\n\t\t\tthis.#reportError(toError(error));\n\t\t} catch (reportError) {\n\t\t\treportErrorAsync(toError(reportError));\n\t\t}\n\t}\n}\n\ntype Publication<T> = {\n\treadonly value: T;\n\treadonly sequence: number;\n\treadonly context: Context;\n};\n\n/** Maintains local publication order independently of how revisions are produced. */\nclass ReplicatedStatePublisher<T> {\n\treadonly #listeners = new Map<StateSubscriber<T>, number>();\n\treadonly #reportError: (error: Error) => void;\n\treadonly #publications: Publication<T>[] = [];\n\t#value: T;\n\t#sequence = 0;\n\t#delivering = false;\n\n\tconstructor(initial: T, reportError: (error: Error) => void = reportErrorAsync) {\n\t\tthis.#value = initial;\n\t\tthis.#reportError = reportError;\n\t}\n\n\tget value(): T {\n\t\treturn this.#value;\n\t}\n\n\tsnapshot(): { readonly value: T; readonly sequence: number } {\n\t\treturn { value: this.#value, sequence: this.#sequence };\n\t}\n\n\tsubscribe(listener: StateListener<T>): () => void {\n\t\tconst { value, sequence } = this.snapshot();\n\t\tconst subscriber = new StateSubscriber(listener, this.#reportError);\n\t\tthis.#listeners.set(subscriber, sequence);\n\t\t// Hydration has no caller; it is delivered with the background context.\n\t\tsubscriber.push({ value, context: BACKGROUND_CONTEXT, delivery: { kind: \"hydrate\", sequence } });\n\t\tsubscriber.drain();\n\t\treturn () => {\n\t\t\tsubscriber.close();\n\t\t\tthis.#listeners.delete(subscriber);\n\t\t};\n\t}\n\n\t/** Publish an already-prepared immutable revision. Subscriber failures are reported, never thrown. */\n\tpublish(value: T, context: Context): void {\n\t\tthis.#value = value;\n\t\tthis.#sequence += 1;\n\t\tthis.#publications.push({ value, sequence: this.#sequence, context });\n\t\tif (this.#delivering) return;\n\n\t\tthis.#delivering = true;\n\t\ttry {\n\t\t\tfor (\n\t\t\t\tlet publication = this.#publications.shift();\n\t\t\t\tpublication !== undefined;\n\t\t\t\tpublication = this.#publications.shift()\n\t\t\t) {\n\t\t\t\tconst delivery = { kind: \"update\", sequence: publication.sequence } as const;\n\t\t\t\tfor (const [subscriber, hydratedSequence] of [...this.#listeners]) {\n\t\t\t\t\tif (publication.sequence <= hydratedSequence) continue;\n\t\t\t\t\tsubscriber.push({ value: publication.value, context: publication.context, delivery });\n\t\t\t\t\tsubscriber.drain();\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#delivering = false;\n\t\t}\n\t}\n}\n\nclass MutableReplicatedStateImpl<T extends object> implements MutableReplicatedState<T> {\n\treadonly #tracker: Tracker<T>;\n\treadonly #publisher: ReplicatedStatePublisher<T>;\n\t#changing = false;\n\n\tconstructor(initial: T) {\n\t\tthis.#tracker = track(initial);\n\t\tthis.#publisher = new ReplicatedStatePublisher(this.#tracker.value);\n\t}\n\n\tget value(): T {\n\t\treturn this.#tracker.value;\n\t}\n\n\tchange(context: Context, mutate: Parameters<MutableReplicatedState<T>[\"change\"]>[1]): void {\n\t\tif (this.#changing) throw new Error(\"Replicated state cannot be changed reentrantly from a change callback\");\n\t\tthis.#changing = true;\n\t\tlet prepared: Prepared<T>;\n\t\ttry {\n\t\t\tconst change = this.#tracker.beginChange();\n\t\t\ttry {\n\t\t\t\tconst outcome = (mutate as (draft: typeof change.state) => unknown)(change.state);\n\t\t\t\tif (isPromiseLike(outcome)) {\n\t\t\t\t\tvoid Promise.resolve(outcome).catch(() => undefined);\n\t\t\t\t\tthrow new TypeError(\"Replicated state change callbacks must be synchronous\");\n\t\t\t\t}\n\t\t\t\tprepared = change.prepare();\n\t\t\t} catch (error) {\n\t\t\t\tchange.abort();\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#changing = false;\n\t\t}\n\n\t\tthis.#tracker.adopt(prepared);\n\t\tif (prepared.ops.length > 0) this.#publisher.publish(prepared.value, context);\n\t}\n\n\treplace(context: Context, value: T): void {\n\t\tif (this.#changing) throw new Error(\"Replicated state cannot be replaced from a change callback\");\n\t\tconst prepared = this.#tracker.prepareReplace(value);\n\t\tthis.#tracker.adopt(prepared);\n\t\tif (prepared.ops.length > 0) this.#publisher.publish(prepared.value, context);\n\t}\n\n\tsubscribe(listener: StateListener<T>): () => void {\n\t\treturn this.#publisher.subscribe(listener);\n\t}\n}\n\nclass AttachedReplicatedStateImpl<T> implements AttachedReplicatedState<T> {\n\treadonly #publisher: ReplicatedStatePublisher<T>;\n\treadonly #attachment: ReplicatedStateSourceAttachment<T>;\n\treadonly #reportError: (error: Error) => void;\n\t#cursor: number;\n\t#disposed = false;\n\n\tconstructor(attachment: ReplicatedStateSourceAttachment<T>, options: ReplicatedStateSourceOptions) {\n\t\tconst { snapshot } = attachment;\n\t\tassertCursor(snapshot.cursor, \"snapshot\");\n\t\tthis.#attachment = attachment;\n\t\tthis.#cursor = snapshot.cursor;\n\t\tthis.#reportError = options.onError ?? reportErrorAsync;\n\t\tthis.#publisher = new ReplicatedStatePublisher(snapshot.value, (error) => this.#report(error));\n\t}\n\n\tget value(): T {\n\t\treturn this.#publisher.value;\n\t}\n\n\tsubscribe(listener: StateListener<T>): () => void {\n\t\treturn this.#publisher.subscribe(listener);\n\t}\n\n\tactivate(): void {\n\t\tthis.#attachment.activate((frame) => this.#receive(frame));\n\t}\n\n\tdispose(): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#disposed = true;\n\t\tthis.#attachment.dispose();\n\t}\n\n\t#receive(frame: ReplicatedStateSourceFrame<T>): void {\n\t\tif (this.#disposed) return;\n\t\ttry {\n\t\t\tassertCursor(frame.cursor, \"frame\");\n\t\t\tconst expected = this.#cursor + 1;\n\t\t\tif (frame.cursor !== expected) {\n\t\t\t\tthrow new Error(`Replicated state source cursor has a gap: expected ${expected}, received ${frame.cursor}`);\n\t\t\t}\n\t\t\tthis.#cursor = frame.cursor;\n\t\t\tthis.#publisher.publish(frame.value, frame.context);\n\t\t} catch (error) {\n\t\t\tthis.#fail(toError(error));\n\t\t}\n\t}\n\n\t#fail(error: Error): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#disposed = true;\n\t\ttry {\n\t\t\tthis.#attachment.dispose();\n\t\t} catch (disposeError) {\n\t\t\tthis.#report(new AggregateError([error, disposeError], \"Replicated state source contract failed\"));\n\t\t\treturn;\n\t\t}\n\t\tthis.#report(error);\n\t}\n\n\t#report(error: unknown): void {\n\t\ttry {\n\t\t\tthis.#reportError(toError(error));\n\t\t} catch (reportError) {\n\t\t\treportErrorAsync(toError(reportError));\n\t\t}\n\t}\n}\n\n/** Attach a publication-only replicated state to one authoritative immutable source stream. */\nfunction attachReplicatedStateSource<T>(\n\tsource: ReplicatedStateSource<T>,\n\toptions: ReplicatedStateSourceOptions = {},\n): AttachedReplicatedState<T> {\n\tconst attachment = source.attach();\n\ttry {\n\t\tconst state = new AttachedReplicatedStateImpl(attachment, options);\n\t\tstate.activate();\n\t\treturn state;\n\t} catch (error) {\n\t\ttry {\n\t\t\tattachment.dispose();\n\t\t} catch (disposeError) {\n\t\t\tthrow new AggregateError([error, disposeError], \"Failed to attach replicated state source\");\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction assertCursor(cursor: number, kind: \"snapshot\" | \"frame\"): void {\n\tif (!Number.isSafeInteger(cursor))\n\t\tthrow new TypeError(`Replicated state source ${kind} cursor must be a safe integer`);\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n\treturn (\n\t\t((typeof value === \"object\" && value !== null) || typeof value === \"function\") &&\n\t\ttypeof (value as { then?: unknown }).then === \"function\"\n\t);\n}\n\nfunction reportErrorAsync(error: Error): void {\n\tqueueMicrotask(() => {\n\t\tthrow error;\n\t});\n}\n\nfunction toError(error: unknown): Error {\n\treturn error instanceof Error ? error : new Error(String(error));\n}\n\nexport function replicatedState<T>(\n\tsource: ReplicatedStateSource<T>,\n\toptions?: ReplicatedStateSourceOptions,\n): AttachedReplicatedState<T>;\n/**\n * Create authoritative state by taking immutable ownership of an alias-free strict-JSON root.\n * The caller must not mutate `initial` after this call.\n */\nexport function replicatedState<T extends object>(initial: T): MutableReplicatedState<T>;\nexport function replicatedState(\n\tinitialOrSource: object | ReplicatedStateSource<unknown>,\n\toptions?: ReplicatedStateSourceOptions,\n): MutableReplicatedState<object> | AttachedReplicatedState<unknown> {\n\tif (isReplicatedStateSource(initialOrSource)) return attachReplicatedStateSource(initialOrSource, options);\n\treturn new MutableReplicatedStateImpl(initialOrSource);\n}\n\nfunction isReplicatedStateSource(value: object): value is ReplicatedStateSource<unknown> {\n\treturn typeof (value as { readonly attach?: unknown }).attach === \"function\";\n}\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,277 +1,77 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
export type
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
readonly
|
|
8
|
-
/**
|
|
9
|
-
readonly
|
|
10
|
-
}
|
|
11
|
-
/** Immutable invocation-scoped values passed explicitly through operations. */
|
|
12
|
-
export interface Context {
|
|
13
|
-
readonly abortSignal: AbortSignal | undefined;
|
|
14
|
-
value<T>(key: ContextKey<T>): T | undefined;
|
|
15
|
-
toString(): string;
|
|
16
|
-
}
|
|
17
|
-
export type JsonValue = null | boolean | number | string | JsonValue[] | {
|
|
18
|
-
[key: string]: JsonValue;
|
|
19
|
-
};
|
|
20
|
-
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
21
|
-
/** Strict-JSON representation of an application data type. Unknown payloads become JsonValue. */
|
|
22
|
-
export type JsonRepresentation<T> = IsAny<T> extends true ? JsonValue : unknown extends T ? JsonValue : T extends null | boolean | number | string ? T : T extends readonly (infer TItem)[] ? JsonRepresentation<TItem>[] : T extends object ? {
|
|
23
|
-
[TKey in keyof T]: JsonRepresentation<T[TKey]>;
|
|
24
|
-
} : never;
|
|
25
|
-
export interface ReplicatedStateDelivery {
|
|
26
|
-
readonly kind: "hydrate" | "update";
|
|
27
|
-
readonly sequence: number;
|
|
28
|
-
}
|
|
29
|
-
export interface ReplicatedState<T> {
|
|
30
|
-
/**
|
|
31
|
-
* Contract-immutable value, or undefined until hydration. It is not frozen and may share containers with an
|
|
32
|
-
* in-process provider; consumers must not mutate it. Later updates do not mutate previously returned values.
|
|
33
|
-
*/
|
|
34
|
-
readonly value: T | undefined;
|
|
35
|
-
/**
|
|
36
|
-
* Each subscription serializes callbacks, awaiting hydration before updates. Values are immutable and may
|
|
37
|
-
* share unchanged revision data. At most 100 deliveries wait behind the running callback; overflow keeps
|
|
38
|
-
* only the newest pending value/context/delivery, so update sequences may skip. Failures are reported in
|
|
39
|
-
* isolation and delivery continues. Unsubscribe discards pending work without aborting or joining a callback.
|
|
40
|
-
*/
|
|
41
|
-
subscribe(listener: (value: T, context: Context, delivery: ReplicatedStateDelivery) => Promise<void>): () => void;
|
|
42
|
-
subscribe(listener: (value: T, context: Context, delivery: ReplicatedStateDelivery) => void): () => void;
|
|
43
|
-
}
|
|
44
|
-
export interface MutableReplicatedState<T extends object> extends ReplicatedState<T> {
|
|
45
|
-
readonly value: T;
|
|
46
|
-
/**
|
|
47
|
-
* Atomically publish one synchronous overlay mutation. Draft handles are unusable after the callback returns.
|
|
48
|
-
* Values placed through the draft are cloned by value; assigning `undefined` to an object property deletes it.
|
|
49
|
-
*/
|
|
50
|
-
change(context: Context, mutate: (draft: Draft<T>) => void): void;
|
|
51
|
-
/**
|
|
52
|
-
* Atomically take immutable ownership of an alias-free strict-JSON replacement.
|
|
53
|
-
* The caller must not mutate the transferred root after this call.
|
|
54
|
-
*/
|
|
55
|
-
replace(context: Context, value: T): void;
|
|
56
|
-
}
|
|
57
|
-
/** One immutable authoritative revision committed after an attachment snapshot. */
|
|
58
|
-
export interface ReplicatedStateSourceFrame<T> {
|
|
59
|
-
/** Monotonic source cursor. The first frame after a snapshot must be `snapshot.cursor + 1`. */
|
|
60
|
-
readonly cursor: number;
|
|
61
|
-
/** The exact immutable value produced by this commit. */
|
|
62
|
-
readonly value: T;
|
|
63
|
-
/** The exact immutable operation batch that produced `value` from the preceding source revision. */
|
|
64
|
-
readonly ops: readonly Op[];
|
|
65
|
-
readonly context: Context;
|
|
66
|
-
}
|
|
67
|
-
export interface ReplicatedStateSourceAttachment<T> {
|
|
68
|
-
/** Fixed immutable snapshot captured at the atomic attachment boundary. */
|
|
69
|
-
readonly snapshot: {
|
|
70
|
-
readonly value: T;
|
|
71
|
-
readonly cursor: number;
|
|
72
|
-
};
|
|
73
|
-
/**
|
|
74
|
-
* Install the sole listener and synchronously drain every buffered frame in source commit order.
|
|
75
|
-
* This method is single-use. After it begins, every new committed frame must also be delivered in order
|
|
76
|
-
* until disposal, including commits made reentrantly while a prior frame is being delivered.
|
|
77
|
-
*/
|
|
78
|
-
activate(listener: (frame: ReplicatedStateSourceFrame<T>) => void): void;
|
|
79
|
-
/** Stop delivery and release source resources. Disposal must be idempotent. */
|
|
80
|
-
dispose(): void;
|
|
1
|
+
import type { AnyContract, Handle, InputOf } from "./contract.ts";
|
|
2
|
+
import type { Op } from "./delta/index.ts";
|
|
3
|
+
/** App-defined, JSON-serializable identity of a caller. Mapped to a record key by `createHost({ principalKey })`. */
|
|
4
|
+
export type Principal = unknown;
|
|
5
|
+
export interface GetOptions {
|
|
6
|
+
/** Principal the record is created for. Defaults to the host principal. */
|
|
7
|
+
readonly principal?: Principal;
|
|
8
|
+
/** Host name. Only the local host in phase 1a. */
|
|
9
|
+
readonly at?: string;
|
|
81
10
|
}
|
|
82
11
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* `attach()` must synchronously and atomically capture one snapshot and register the returned attachment to buffer
|
|
86
|
-
* every later committed frame. The snapshot must include every commit before that boundary; buffered frames must
|
|
87
|
-
* include every commit after it, with no overlap or gap. Snapshot values, frame values, and operation batches are
|
|
88
|
-
* immutable and remain valid after delivery. Chord only publishes these references; it never applies or re-diffs them.
|
|
12
|
+
* The explicit call context of one root (a short Chord call tree). Calls made with it carry its root id and epoch;
|
|
13
|
+
* `get` holds are released when the call that received this ctx settles.
|
|
89
14
|
*/
|
|
90
|
-
export interface
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
15
|
+
export interface Ctx {
|
|
16
|
+
readonly signal: AbortSignal;
|
|
17
|
+
readonly rootId: string;
|
|
18
|
+
readonly epoch: number;
|
|
19
|
+
readonly principal: Principal;
|
|
20
|
+
get<C extends AnyContract>(type: C, input: InputOf<C>, options?: GetOptions): Handle<C>;
|
|
21
|
+
}
|
|
22
|
+
export type StateEvent<T> = {
|
|
23
|
+
readonly type: "snap";
|
|
99
24
|
readonly value: T;
|
|
100
|
-
/** Idempotently release the source attachment. The last published value remains readable. */
|
|
101
|
-
dispose(): void;
|
|
102
|
-
}
|
|
103
|
-
declare const SERVICE_TYPE: unique symbol;
|
|
104
|
-
export type ServiceMode = "singleton" | "keyed";
|
|
105
|
-
/** Stable identity for one shared TypeScript service contract. */
|
|
106
|
-
export interface Service<T> {
|
|
107
|
-
readonly id: string;
|
|
108
|
-
/** Process-local services accept unrestricted object contracts and are never published remotely. */
|
|
109
|
-
readonly local: boolean;
|
|
110
|
-
readonly [SERVICE_TYPE]?: (value: T) => T;
|
|
111
|
-
}
|
|
112
|
-
/** JSON with readonly containers, such as other packages' recursive JSON types. */
|
|
113
|
-
type ReadonlyJsonValue = null | boolean | number | string | readonly ReadonlyJsonValue[] | {
|
|
114
|
-
readonly [key: string]: ReadonlyJsonValue;
|
|
115
|
-
};
|
|
116
|
-
type InvalidJsonPart<T> = IsAny<T> extends true ? T : unknown extends T ? never : [T] extends [ReadonlyJsonValue] ? never : InvalidJsonStructure<T>;
|
|
117
|
-
type InvalidJsonProperty<T> = [Exclude<T, undefined>] extends [never] ? T : InvalidJsonPart<Exclude<T, undefined>>;
|
|
118
|
-
type InvalidJsonStructure<T> = T extends null | boolean | number | string ? never : T extends readonly (infer TItem)[] ? InvalidJsonPart<TItem> : T extends (...args: never[]) => unknown ? T : T extends object ? {
|
|
119
|
-
[TKey in keyof T]-?: InvalidJsonProperty<T[TKey]>;
|
|
120
|
-
}[keyof T] : T;
|
|
121
|
-
type InvalidRemoteMember<T> = T extends ReplicatedState<infer TValue> ? InvalidJsonPart<TValue> extends never ? never : "state value is not JSON" : T extends (...args: [...infer TArgs, Context]) => Promise<infer TResult> ? InvalidJsonPart<TArgs[number]> extends never ? TResult extends void ? never : InvalidJsonPart<TResult> extends never ? never : "method result is not JSON or void" : "method argument is not JSON" : "member is not a remote method or ReplicatedState";
|
|
122
|
-
type InvalidRemoteMemberNames<T> = {
|
|
123
|
-
[TKey in keyof T]-?: InvalidRemoteMember<T[TKey]> extends never ? never : TKey;
|
|
124
|
-
}[keyof T];
|
|
125
|
-
export type RemoteServiceContract<T> = InvalidRemoteMemberNames<T> extends never ? T : never;
|
|
126
|
-
export interface ServiceSpawner<T> {
|
|
127
|
-
spawn(key: string, implementation: T): () => void;
|
|
128
|
-
}
|
|
129
|
-
export interface RemoteServices {
|
|
130
|
-
use<T>(service: Service<T>): T;
|
|
131
|
-
observe<T>(service: Service<T>, handler: (service: T, context: Context) => void | Promise<void>): () => void;
|
|
132
|
-
/** Wait until every currently acquired service has installed its initial snapshot. */
|
|
133
|
-
ready(context: Context): Promise<void>;
|
|
134
|
-
dispose(context: Context): Promise<void>;
|
|
135
|
-
}
|
|
136
|
-
export type ServiceCatalogueEntry = {
|
|
137
|
-
readonly serviceId: string;
|
|
138
|
-
readonly mode: ServiceMode;
|
|
139
|
-
};
|
|
140
|
-
export type ServiceInstanceAddress = {
|
|
141
|
-
readonly key: string;
|
|
142
|
-
readonly generation: number;
|
|
143
|
-
};
|
|
144
|
-
export type ServiceMemberSnapshot = {
|
|
145
|
-
readonly name: string;
|
|
146
|
-
readonly kind: "method";
|
|
147
25
|
} | {
|
|
148
|
-
readonly
|
|
149
|
-
readonly kind: "state";
|
|
150
|
-
readonly sequence: number;
|
|
151
|
-
readonly ops: readonly Op[];
|
|
152
|
-
};
|
|
153
|
-
export type ServiceInstanceSnapshot = {
|
|
154
|
-
readonly instance?: ServiceInstanceAddress;
|
|
155
|
-
readonly members: readonly ServiceMemberSnapshot[];
|
|
156
|
-
};
|
|
157
|
-
export type ServiceSubscriptionSnapshot = {
|
|
158
|
-
readonly serviceId: string;
|
|
159
|
-
readonly mode: ServiceMode;
|
|
160
|
-
readonly instances: readonly ServiceInstanceSnapshot[];
|
|
161
|
-
};
|
|
162
|
-
export type ServiceProviderUpdate = {
|
|
163
|
-
readonly type: "state";
|
|
164
|
-
readonly instance?: ServiceInstanceAddress;
|
|
165
|
-
readonly member: string;
|
|
166
|
-
readonly sequence: number;
|
|
26
|
+
readonly type: "ops";
|
|
167
27
|
readonly ops: readonly Op[];
|
|
168
|
-
|
|
169
|
-
/** Full subscription rebaseline after overflow; every state is a root replacement at its new sequence. */
|
|
170
|
-
| {
|
|
171
|
-
readonly type: "reset";
|
|
172
|
-
readonly snapshot: ServiceSubscriptionSnapshot;
|
|
173
|
-
} | {
|
|
174
|
-
readonly type: "unavailable";
|
|
175
|
-
} | {
|
|
176
|
-
readonly type: "replaced";
|
|
177
|
-
readonly snapshot: ServiceInstanceSnapshot;
|
|
178
|
-
} | {
|
|
179
|
-
readonly type: "spawned";
|
|
180
|
-
readonly instance: ServiceInstanceSnapshot;
|
|
28
|
+
readonly value: T;
|
|
181
29
|
} | {
|
|
182
|
-
readonly type: "
|
|
183
|
-
readonly
|
|
184
|
-
};
|
|
185
|
-
export type ServiceCall = {
|
|
186
|
-
readonly serviceId: string;
|
|
187
|
-
readonly instance?: ServiceInstanceAddress;
|
|
188
|
-
readonly member: string;
|
|
189
|
-
/** Borrowed immutable values. Chord validates but does not clone them. */
|
|
190
|
-
readonly args: readonly JsonValue[];
|
|
30
|
+
readonly type: "reset";
|
|
31
|
+
readonly value: T;
|
|
191
32
|
};
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
readonly
|
|
195
|
-
|
|
196
|
-
|
|
33
|
+
/** A readable state source: a cell, a derivation, or a handle's state member. Values are immutable by contract. */
|
|
34
|
+
export interface Readable<T> {
|
|
35
|
+
readonly value: T;
|
|
36
|
+
/** Called with the current value immediately, then with every new value. */
|
|
37
|
+
subscribe(listener: (value: T) => void): () => void;
|
|
38
|
+
/** Delta stream: a snapshot immediately, then ops, or a reset after a migration or rebind. */
|
|
39
|
+
events(listener: (event: StateEvent<T>) => void): () => void;
|
|
197
40
|
}
|
|
198
41
|
/**
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* Implementations choose transport, framing, routing, and envelope encoding. Values crossing this
|
|
202
|
-
* boundary must remain strict JSON. Chord does not clone values or require a particular application wire protocol;
|
|
203
|
-
* adapters own serialization and any isolation copies they require.
|
|
204
|
-
*
|
|
42
|
+
* What a behavior may expose as a state member: a cell, a derivation, or a held object's state member (whose value is
|
|
43
|
+
* `undefined` only while that object is loading; a record is live only after its holds are).
|
|
205
44
|
*/
|
|
206
|
-
export
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
readonly
|
|
215
|
-
readonly
|
|
216
|
-
|
|
217
|
-
readonly
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
provideMany<T>(service: Service<T>): ServiceSpawner<T>;
|
|
45
|
+
export type StateSource<T> = Readable<T> | Readable<T | undefined>;
|
|
46
|
+
declare const EXPOSED: unique symbol;
|
|
47
|
+
/** A local member backed by a resource (`self.expose(res.x)`): handles read the resource's value once live. */
|
|
48
|
+
export interface Exposed<T> {
|
|
49
|
+
readonly [EXPOSED]: T;
|
|
50
|
+
}
|
|
51
|
+
export type HandleStatus = "loading" | "live" | "released" | "gone";
|
|
52
|
+
export interface Shape {
|
|
53
|
+
readonly kind: string | undefined;
|
|
54
|
+
readonly members: readonly string[];
|
|
55
|
+
/** Fingerprint of the provider contract. */
|
|
56
|
+
readonly contract: string;
|
|
57
|
+
readonly epoch: number;
|
|
58
|
+
}
|
|
59
|
+
export interface HandleBase<C extends AnyContract> {
|
|
60
|
+
/** The consumer contract token this handle was bound with. */
|
|
61
|
+
readonly contract: C;
|
|
62
|
+
readonly status: HandleStatus;
|
|
63
|
+
readonly ready: Promise<void>;
|
|
64
|
+
readonly kind: string | undefined;
|
|
65
|
+
readonly shape: Shape | undefined;
|
|
66
|
+
/** Why the handle is gone, if it is. */
|
|
67
|
+
readonly error: unknown;
|
|
68
|
+
onShape(listener: (shape: Shape) => void): () => void;
|
|
231
69
|
/**
|
|
232
|
-
*
|
|
233
|
-
*
|
|
70
|
+
* Called after every status change (`loading` → `live`, `live` → `loading` while a link reconnects, `released`,
|
|
71
|
+
* `gone` with `error`). A UI watches for `gone` to `get` again.
|
|
234
72
|
*/
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
own(disposal: () => void | Promise<void>): void;
|
|
238
|
-
/** Register asynchronous initialization after dependencies are bound and ready. */
|
|
239
|
-
onActivate(callback: () => void | Promise<void>): void;
|
|
240
|
-
/** Register final facet teardown. */
|
|
241
|
-
onDeactivate(callback: () => void | Promise<void>): void;
|
|
242
|
-
}
|
|
243
|
-
export interface Facet {
|
|
244
|
-
readonly id: string;
|
|
245
|
-
setup(env: FacetEnvironment): void;
|
|
246
|
-
}
|
|
247
|
-
export interface RemoteServiceSource {
|
|
248
|
-
/** Whether this currently unavailable source may provisionally own absent requirements. */
|
|
249
|
-
readonly acceptsUnavailableServices: boolean;
|
|
250
|
-
catalogue(context: Context): Promise<readonly ServiceCatalogueEntry[]>;
|
|
251
|
-
open(options: {
|
|
252
|
-
readonly services: readonly {
|
|
253
|
-
readonly id: string;
|
|
254
|
-
}[];
|
|
255
|
-
assertAccess(): void;
|
|
256
|
-
onError(error: Error): void;
|
|
257
|
-
}): RemoteServices;
|
|
258
|
-
}
|
|
259
|
-
export interface FacetOptions {
|
|
260
|
-
readonly facets: readonly Facet[];
|
|
261
|
-
readonly serviceSources?: readonly RemoteServiceSource[];
|
|
262
|
-
readonly onError?: (error: Error) => void;
|
|
263
|
-
}
|
|
264
|
-
export interface FacetHost {
|
|
265
|
-
readonly services: RemoteServiceProvider;
|
|
266
|
-
/** Activate and replace facets with matching IDs without disconnecting consumer service handles. */
|
|
267
|
-
reload(facets: readonly Facet[]): Promise<void>;
|
|
268
|
-
dispose(): Promise<void>;
|
|
269
|
-
}
|
|
270
|
-
export interface LoadedFacets {
|
|
271
|
-
readonly facets: readonly Facet[];
|
|
272
|
-
dispose(): Promise<void>;
|
|
273
|
-
}
|
|
274
|
-
export interface FacetLoader {
|
|
275
|
-
load(): Promise<LoadedFacets>;
|
|
73
|
+
onStatus(listener: (status: HandleStatus, error: unknown) => void): () => void;
|
|
74
|
+
release(): void;
|
|
276
75
|
}
|
|
76
|
+
export {};
|
|
277
77
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Draft, Op } from \"./delta/index.ts\";\nimport type { RemoteServiceProvider } from \"./services/provider.ts\";\n\nexport type { RemoteServiceError } from \"./services/errors.ts\";\nexport type { RemoteServiceProvider } from \"./services/provider.ts\";\n\n/** Typed identity for one value carried by a {@link Context}. */\nexport interface ContextKey<T> {\n\treadonly token: symbol;\n\t/** Type-only marker that prevents keys with different value types from being interchangeable. */\n\treadonly valueType?: (value: T) => T;\n}\n\n/** Immutable invocation-scoped values passed explicitly through operations. */\nexport interface Context {\n\treadonly abortSignal: AbortSignal | undefined;\n\tvalue<T>(key: ContextKey<T>): T | undefined;\n\ttoString(): string;\n}\n\nexport type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue };\n\ntype IsAny<T> = 0 extends 1 & T ? true : false;\n\n/** Strict-JSON representation of an application data type. Unknown payloads become JsonValue. */\nexport type JsonRepresentation<T> = IsAny<T> extends true\n\t? JsonValue\n\t: unknown extends T\n\t\t? JsonValue\n\t\t: T extends null | boolean | number | string\n\t\t\t? T\n\t\t\t: T extends readonly (infer TItem)[]\n\t\t\t\t? JsonRepresentation<TItem>[]\n\t\t\t\t: T extends object\n\t\t\t\t\t? { [TKey in keyof T]: JsonRepresentation<T[TKey]> }\n\t\t\t\t\t: never;\n\nexport interface ReplicatedStateDelivery {\n\treadonly kind: \"hydrate\" | \"update\";\n\treadonly sequence: number;\n}\n\nexport interface ReplicatedState<T> {\n\t/**\n\t * Contract-immutable value, or undefined until hydration. It is not frozen and may share containers with an\n\t * in-process provider; consumers must not mutate it. Later updates do not mutate previously returned values.\n\t */\n\treadonly value: T | undefined;\n\t/**\n\t * Each subscription serializes callbacks, awaiting hydration before updates. Values are immutable and may\n\t * share unchanged revision data. At most 100 deliveries wait behind the running callback; overflow keeps\n\t * only the newest pending value/context/delivery, so update sequences may skip. Failures are reported in\n\t * isolation and delivery continues. Unsubscribe discards pending work without aborting or joining a callback.\n\t */\n\tsubscribe(listener: (value: T, context: Context, delivery: ReplicatedStateDelivery) => Promise<void>): () => void;\n\tsubscribe(listener: (value: T, context: Context, delivery: ReplicatedStateDelivery) => void): () => void;\n}\n\nexport interface MutableReplicatedState<T extends object> extends ReplicatedState<T> {\n\treadonly value: T;\n\t/**\n\t * Atomically publish one synchronous overlay mutation. Draft handles are unusable after the callback returns.\n\t * Values placed through the draft are cloned by value; assigning `undefined` to an object property deletes it.\n\t */\n\tchange(context: Context, mutate: (draft: Draft<T>) => void): void;\n\t/**\n\t * Atomically take immutable ownership of an alias-free strict-JSON replacement.\n\t * The caller must not mutate the transferred root after this call.\n\t */\n\treplace(context: Context, value: T): void;\n}\n\n/** One immutable authoritative revision committed after an attachment snapshot. */\nexport interface ReplicatedStateSourceFrame<T> {\n\t/** Monotonic source cursor. The first frame after a snapshot must be `snapshot.cursor + 1`. */\n\treadonly cursor: number;\n\t/** The exact immutable value produced by this commit. */\n\treadonly value: T;\n\t/** The exact immutable operation batch that produced `value` from the preceding source revision. */\n\treadonly ops: readonly Op[];\n\treadonly context: Context;\n}\n\nexport interface ReplicatedStateSourceAttachment<T> {\n\t/** Fixed immutable snapshot captured at the atomic attachment boundary. */\n\treadonly snapshot: { readonly value: T; readonly cursor: number };\n\t/**\n\t * Install the sole listener and synchronously drain every buffered frame in source commit order.\n\t * This method is single-use. After it begins, every new committed frame must also be delivered in order\n\t * until disposal, including commits made reentrantly while a prior frame is being delivered.\n\t */\n\tactivate(listener: (frame: ReplicatedStateSourceFrame<T>) => void): void;\n\t/** Stop delivery and release source resources. Disposal must be idempotent. */\n\tdispose(): void;\n}\n\n/**\n * An authoritative immutable revision source.\n *\n * `attach()` must synchronously and atomically capture one snapshot and register the returned attachment to buffer\n * every later committed frame. The snapshot must include every commit before that boundary; buffered frames must\n * include every commit after it, with no overlap or gap. Snapshot values, frame values, and operation batches are\n * immutable and remain valid after delivery. Chord only publishes these references; it never applies or re-diffs them.\n */\nexport interface ReplicatedStateSource<T> {\n\tattach(): ReplicatedStateSourceAttachment<T>;\n}\n\nexport interface ReplicatedStateSourceOptions {\n\t/** Receives source-contract and publication-listener failures without throwing them into the source. */\n\treadonly onError?: (error: Error) => void;\n}\n\n/** A synchronously hydrated publication-only state backed by one source attachment. */\nexport interface AttachedReplicatedState<T> extends ReplicatedState<T> {\n\treadonly value: T;\n\t/** Idempotently release the source attachment. The last published value remains readable. */\n\tdispose(): void;\n}\n\ndeclare const SERVICE_TYPE: unique symbol;\n\nexport type ServiceMode = \"singleton\" | \"keyed\";\n\n/** Stable identity for one shared TypeScript service contract. */\nexport interface Service<T> {\n\treadonly id: string;\n\t/** Process-local services accept unrestricted object contracts and are never published remotely. */\n\treadonly local: boolean;\n\treadonly [SERVICE_TYPE]?: (value: T) => T;\n}\n\n/** JSON with readonly containers, such as other packages' recursive JSON types. */\ntype ReadonlyJsonValue =\n\t| null\n\t| boolean\n\t| number\n\t| string\n\t| readonly ReadonlyJsonValue[]\n\t| { readonly [key: string]: ReadonlyJsonValue };\n\n// A type assignable to readonly JSON is valid as is. Walking a recursive JSON type instead, for example one with\n// readonly arrays, would never terminate.\ntype InvalidJsonPart<T> = IsAny<T> extends true\n\t? T\n\t: unknown extends T\n\t\t? never\n\t\t: [T] extends [ReadonlyJsonValue]\n\t\t\t? never\n\t\t\t: InvalidJsonStructure<T>;\n\ntype InvalidJsonProperty<T> = [Exclude<T, undefined>] extends [never] ? T : InvalidJsonPart<Exclude<T, undefined>>;\n\ntype InvalidJsonStructure<T> = T extends null | boolean | number | string\n\t? never\n\t: T extends readonly (infer TItem)[]\n\t\t? InvalidJsonPart<TItem>\n\t\t: T extends (...args: never[]) => unknown\n\t\t\t? T\n\t\t\t: T extends object\n\t\t\t\t? { [TKey in keyof T]-?: InvalidJsonProperty<T[TKey]> }[keyof T]\n\t\t\t\t: T;\n\ntype InvalidRemoteMember<T> = T extends ReplicatedState<infer TValue>\n\t? InvalidJsonPart<TValue> extends never\n\t\t? never\n\t\t: \"state value is not JSON\"\n\t: T extends (...args: [...infer TArgs, Context]) => Promise<infer TResult>\n\t\t? InvalidJsonPart<TArgs[number]> extends never\n\t\t\t? TResult extends void\n\t\t\t\t? never\n\t\t\t\t: InvalidJsonPart<TResult> extends never\n\t\t\t\t\t? never\n\t\t\t\t\t: \"method result is not JSON or void\"\n\t\t\t: \"method argument is not JSON\"\n\t\t: \"member is not a remote method or ReplicatedState\";\n\ntype InvalidRemoteMemberNames<T> = {\n\t[TKey in keyof T]-?: InvalidRemoteMember<T[TKey]> extends never ? never : TKey;\n}[keyof T];\n\nexport type RemoteServiceContract<T> = InvalidRemoteMemberNames<T> extends never ? T : never;\n\nexport interface ServiceSpawner<T> {\n\tspawn(key: string, implementation: T): () => void;\n}\n\nexport interface RemoteServices {\n\tuse<T>(service: Service<T>): T;\n\tobserve<T>(service: Service<T>, handler: (service: T, context: Context) => void | Promise<void>): () => void;\n\t/** Wait until every currently acquired service has installed its initial snapshot. */\n\tready(context: Context): Promise<void>;\n\tdispose(context: Context): Promise<void>;\n}\n\nexport type ServiceCatalogueEntry = {\n\treadonly serviceId: string;\n\treadonly mode: ServiceMode;\n};\n\nexport type ServiceInstanceAddress = {\n\treadonly key: string;\n\treadonly generation: number;\n};\n\nexport type ServiceMemberSnapshot =\n\t| { readonly name: string; readonly kind: \"method\" }\n\t| { readonly name: string; readonly kind: \"state\"; readonly sequence: number; readonly ops: readonly Op[] };\n\nexport type ServiceInstanceSnapshot = {\n\treadonly instance?: ServiceInstanceAddress;\n\treadonly members: readonly ServiceMemberSnapshot[];\n};\n\nexport type ServiceSubscriptionSnapshot = {\n\treadonly serviceId: string;\n\treadonly mode: ServiceMode;\n\treadonly instances: readonly ServiceInstanceSnapshot[];\n};\n\nexport type ServiceProviderUpdate =\n\t| {\n\t\t\treadonly type: \"state\";\n\t\t\treadonly instance?: ServiceInstanceAddress;\n\t\t\treadonly member: string;\n\t\t\treadonly sequence: number;\n\t\t\treadonly ops: readonly Op[];\n\t }\n\t/** Full subscription rebaseline after overflow; every state is a root replacement at its new sequence. */\n\t| { readonly type: \"reset\"; readonly snapshot: ServiceSubscriptionSnapshot }\n\t| { readonly type: \"unavailable\" }\n\t| { readonly type: \"replaced\"; readonly snapshot: ServiceInstanceSnapshot }\n\t| { readonly type: \"spawned\"; readonly instance: ServiceInstanceSnapshot }\n\t| { readonly type: \"closed\"; readonly instance: ServiceInstanceAddress };\n\nexport type ServiceCall = {\n\treadonly serviceId: string;\n\treadonly instance?: ServiceInstanceAddress;\n\treadonly member: string;\n\t/** Borrowed immutable values. Chord validates but does not clone them. */\n\treadonly args: readonly JsonValue[];\n};\n\nexport interface ServiceSubscription {\n\t/** Atomic baseline. Later updates buffer until activation, with a full reset on pending delivery 101. */\n\treadonly snapshot: ServiceSubscriptionSnapshot;\n\tactivate(): void;\n\tclose(context?: Context): void | Promise<void>;\n}\n\n/**\n * Pluggable wire boundary consumed by a remote service binding.\n *\n * Implementations choose transport, framing, routing, and envelope encoding. Values crossing this\n * boundary must remain strict JSON. Chord does not clone values or require a particular application wire protocol;\n * adapters own serialization and any isolation copies they require.\n *\n */\nexport interface RemoteServiceTransport {\n\tinvoke(call: ServiceCall, context: Context): Promise<JsonValue | undefined>;\n\tsubscribe(\n\t\tserviceId: string,\n\t\tmode: ServiceMode,\n\t\tlistener: (update: ServiceProviderUpdate, context: Context) => void,\n\t\tcontext: Context,\n\t): Promise<ServiceSubscription>;\n}\n\nexport interface RemoteServiceBindingOptions {\n\treadonly services: readonly { readonly id: string }[];\n\treadonly transport: RemoteServiceTransport;\n\treadonly bound?: boolean;\n\treadonly onError?: (error: Error) => void;\n\treadonly assertAccess?: () => void;\n}\n\nexport interface RemoteServiceBinding extends RemoteServices {\n\trebind(bound: boolean, context: Context): Promise<void>;\n}\n\nexport interface FacetEnvironment {\n\t/** Declare a hard dependency on one singleton service and return its stable handle. */\n\tuse<T>(service: Service<T>): T;\n\t/** Declare a hard dependency on a keyed service and observe each live instance. */\n\tobserve<T>(service: Service<T>, handler: (service: T, context: Context) => void | Promise<void>): void;\n\t/** Declare and install this facet's singleton implementation of a service. */\n\tprovide<T>(service: Service<T>, implementation: NoInfer<T>): void;\n\t/** Declare ownership of a multi-instance service and return its deferred spawning capability. */\n\tprovideMany<T>(service: Service<T>): ServiceSpawner<T>;\n\t/**\n\t * Create initialized mutable state by taking immutable ownership of an alias-free strict-JSON root.\n\t * The caller must not mutate `initial` after this call.\n\t */\n\treplicatedState<T extends object>(initial: T): MutableReplicatedState<T>;\n\t/** Give the facet ownership of a resource cleanup function. */\n\town(disposal: () => void | Promise<void>): void;\n\t/** Register asynchronous initialization after dependencies are bound and ready. */\n\tonActivate(callback: () => void | Promise<void>): void;\n\t/** Register final facet teardown. */\n\tonDeactivate(callback: () => void | Promise<void>): void;\n}\n\nexport interface Facet {\n\treadonly id: string;\n\tsetup(env: FacetEnvironment): void;\n}\n\nexport interface RemoteServiceSource {\n\t/** Whether this currently unavailable source may provisionally own absent requirements. */\n\treadonly acceptsUnavailableServices: boolean;\n\tcatalogue(context: Context): Promise<readonly ServiceCatalogueEntry[]>;\n\topen(options: {\n\t\treadonly services: readonly { readonly id: string }[];\n\t\tassertAccess(): void;\n\t\tonError(error: Error): void;\n\t}): RemoteServices;\n}\n\nexport interface FacetOptions {\n\treadonly facets: readonly Facet[];\n\treadonly serviceSources?: readonly RemoteServiceSource[];\n\treadonly onError?: (error: Error) => void;\n}\n\nexport interface FacetHost {\n\treadonly services: RemoteServiceProvider;\n\t/** Activate and replace facets with matching IDs without disconnecting consumer service handles. */\n\treload(facets: readonly Facet[]): Promise<void>;\n\tdispose(): Promise<void>;\n}\n\nexport interface LoadedFacets {\n\treadonly facets: readonly Facet[];\n\tdispose(): Promise<void>;\n}\n\nexport interface FacetLoader {\n\tload(): Promise<LoadedFacets>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AnyContract, Handle, InputOf } from \"./contract.ts\";\nimport type { Op } from \"./delta/index.ts\";\n\n/** App-defined, JSON-serializable identity of a caller. Mapped to a record key by `createHost({ principalKey })`. */\nexport type Principal = unknown;\n\nexport interface GetOptions {\n\t/** Principal the record is created for. Defaults to the host principal. */\n\treadonly principal?: Principal;\n\t/** Host name. Only the local host in phase 1a. */\n\treadonly at?: string;\n}\n\n/**\n * The explicit call context of one root (a short Chord call tree). Calls made with it carry its root id and epoch;\n * `get` holds are released when the call that received this ctx settles.\n */\nexport interface Ctx {\n\treadonly signal: AbortSignal;\n\treadonly rootId: string;\n\treadonly epoch: number;\n\treadonly principal: Principal;\n\tget<C extends AnyContract>(type: C, input: InputOf<C>, options?: GetOptions): Handle<C>;\n}\n\nexport type StateEvent<T> =\n\t| { readonly type: \"snap\"; readonly value: T }\n\t| { readonly type: \"ops\"; readonly ops: readonly Op[]; readonly value: T }\n\t| { readonly type: \"reset\"; readonly value: T };\n\n/** A readable state source: a cell, a derivation, or a handle's state member. Values are immutable by contract. */\nexport interface Readable<T> {\n\treadonly value: T;\n\t/** Called with the current value immediately, then with every new value. */\n\tsubscribe(listener: (value: T) => void): () => void;\n\t/** Delta stream: a snapshot immediately, then ops, or a reset after a migration or rebind. */\n\tevents(listener: (event: StateEvent<T>) => void): () => void;\n}\n\n/**\n * What a behavior may expose as a state member: a cell, a derivation, or a held object's state member (whose value is\n * `undefined` only while that object is loading; a record is live only after its holds are).\n */\nexport type StateSource<T> = Readable<T> | Readable<T | undefined>;\n\ndeclare const EXPOSED: unique symbol;\n\n/** A local member backed by a resource (`self.expose(res.x)`): handles read the resource's value once live. */\nexport interface Exposed<T> {\n\treadonly [EXPOSED]: T;\n}\n\nexport type HandleStatus = \"loading\" | \"live\" | \"released\" | \"gone\";\n\nexport interface Shape {\n\treadonly kind: string | undefined;\n\treadonly members: readonly string[];\n\t/** Fingerprint of the provider contract. */\n\treadonly contract: string;\n\treadonly epoch: number;\n}\n\nexport interface HandleBase<C extends AnyContract> {\n\t/** The consumer contract token this handle was bound with. */\n\treadonly contract: C;\n\treadonly status: HandleStatus;\n\treadonly ready: Promise<void>;\n\treadonly kind: string | undefined;\n\treadonly shape: Shape | undefined;\n\t/** Why the handle is gone, if it is. */\n\treadonly error: unknown;\n\tonShape(listener: (shape: Shape) => void): () => void;\n\t/**\n\t * Called after every status change (`loading` → `live`, `live` → `loading` while a link reconnects, `released`,\n\t * `gone` with `error`). A UI watches for `gone` to `get` again.\n\t */\n\tonStatus(listener: (status: HandleStatus, error: unknown) => void): () => void;\n\trelease(): void;\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AcceptOptions } from "./connection.ts";
|
|
2
|
+
import type { Host } from "./host.ts";
|
|
3
|
+
import { type WebSocketLike } from "./link.ts";
|
|
4
|
+
import type { Principal } from "./types.ts";
|
|
5
|
+
/** A WebSocket server (e.g. `ws`'s `WebSocketServer`), structurally: Chord does not depend on `ws`. */
|
|
6
|
+
export interface WebSocketServerLike<Request> {
|
|
7
|
+
on(event: "connection", listener: (socket: WebSocketLike, request: Request) => void): unknown;
|
|
8
|
+
}
|
|
9
|
+
/** WebSocket peers are always accepted as clients: no roots, no epochs, no reload votes, not addressable. */
|
|
10
|
+
export interface WebSocketAcceptOptions<Request> extends Omit<AcceptOptions, "principal" | "kind" | "name"> {
|
|
11
|
+
/** The authenticator: the principal of the connecting client, or undefined to refuse it. */
|
|
12
|
+
principal(request: Request): Principal | undefined | Promise<Principal | undefined>;
|
|
13
|
+
}
|
|
14
|
+
/** Accepts every connection of `server` on `host` as a client link stamped with the authenticated principal. */
|
|
15
|
+
export declare function acceptWebSockets<Request>(server: WebSocketServerLike<Request>, host: Host, options: WebSocketAcceptOptions<Request>): void;
|
|
16
|
+
//# sourceMappingURL=websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,KAAK,aAAa,EAAiB,MAAM,WAAW,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,uGAAuG;AACvG,MAAM,WAAW,mBAAmB,CAAC,OAAO;IAC3C,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC;CAC9F;AAED,6GAA6G;AAC7G,MAAM,WAAW,sBAAsB,CAAC,OAAO,CAAE,SAAQ,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;IAC1G,4FAA4F;IAC5F,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;CACpF;AAED,gHAAgH;AAChH,wBAAgB,gBAAgB,CAAC,OAAO,EACvC,MAAM,EAAE,mBAAmB,CAAC,OAAO,CAAC,EACpC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,sBAAsB,CAAC,OAAO,CAAC,GACtC,IAAI,CAYN"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { webSocketLink } from "./link.js";
|
|
2
|
+
/** Accepts every connection of `server` on `host` as a client link stamped with the authenticated principal. */
|
|
3
|
+
export function acceptWebSockets(server, host, options) {
|
|
4
|
+
server.on("connection", (socket, request) => {
|
|
5
|
+
// Wrap at once so frames sent while authenticating are queued, not lost.
|
|
6
|
+
const link = webSocketLink(socket);
|
|
7
|
+
Promise.resolve(options.principal(request)).then((principal) => {
|
|
8
|
+
if (principal === undefined)
|
|
9
|
+
link.close("unauthorized");
|
|
10
|
+
else
|
|
11
|
+
host.accept(link, { ...options, principal, kind: "client" });
|
|
12
|
+
}, () => link.close("authentication failed"));
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=websocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsB,aAAa,EAAE,MAAM,WAAW,CAAC;AAc9D,gHAAgH;AAChH,MAAM,UAAU,gBAAgB,CAC/B,MAAoC,EACpC,IAAU,EACV,OAAwC;IAExC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;QAC3C,yEAAyE;QACzE,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;QACnC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAC/C,CAAC,SAAS,EAAE,EAAE;YACb,IAAI,SAAS,KAAK,SAAS;gBAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;;gBACnD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnE,CAAC,EACD,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,CACzC,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { AcceptOptions } from \"./connection.ts\";\nimport type { Host } from \"./host.ts\";\nimport { type WebSocketLike, webSocketLink } from \"./link.ts\";\nimport type { Principal } from \"./types.ts\";\n\n/** A WebSocket server (e.g. `ws`'s `WebSocketServer`), structurally: Chord does not depend on `ws`. */\nexport interface WebSocketServerLike<Request> {\n\ton(event: \"connection\", listener: (socket: WebSocketLike, request: Request) => void): unknown;\n}\n\n/** WebSocket peers are always accepted as clients: no roots, no epochs, no reload votes, not addressable. */\nexport interface WebSocketAcceptOptions<Request> extends Omit<AcceptOptions, \"principal\" | \"kind\" | \"name\"> {\n\t/** The authenticator: the principal of the connecting client, or undefined to refuse it. */\n\tprincipal(request: Request): Principal | undefined | Promise<Principal | undefined>;\n}\n\n/** Accepts every connection of `server` on `host` as a client link stamped with the authenticated principal. */\nexport function acceptWebSockets<Request>(\n\tserver: WebSocketServerLike<Request>,\n\thost: Host,\n\toptions: WebSocketAcceptOptions<Request>,\n): void {\n\tserver.on(\"connection\", (socket, request) => {\n\t\t// Wrap at once so frames sent while authenticating are queued, not lost.\n\t\tconst link = webSocketLink(socket);\n\t\tPromise.resolve(options.principal(request)).then(\n\t\t\t(principal) => {\n\t\t\t\tif (principal === undefined) link.close(\"unauthorized\");\n\t\t\t\telse host.accept(link, { ...options, principal, kind: \"client\" });\n\t\t\t},\n\t\t\t() => link.close(\"authentication failed\"),\n\t\t);\n\t});\n}\n"]}
|