@earendil-works/chord 1.1.0 → 1.3.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.
Files changed (190) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/README.md +79 -195
  3. package/dist/cell.d.ts +122 -0
  4. package/dist/cell.d.ts.map +1 -0
  5. package/dist/cell.js +356 -0
  6. package/dist/cell.js.map +1 -0
  7. package/dist/cluster.d.ts +27 -0
  8. package/dist/cluster.d.ts.map +1 -0
  9. package/dist/cluster.js +230 -0
  10. package/dist/cluster.js.map +1 -0
  11. package/dist/connection.d.ts +270 -0
  12. package/dist/connection.d.ts.map +1 -0
  13. package/dist/connection.js +1216 -0
  14. package/dist/connection.js.map +1 -0
  15. package/dist/context/index.d.ts +12 -1
  16. package/dist/context/index.d.ts.map +1 -1
  17. package/dist/context/index.js.map +1 -1
  18. package/dist/contract.d.ts +208 -0
  19. package/dist/contract.d.ts.map +1 -0
  20. package/dist/contract.js +246 -0
  21. package/dist/contract.js.map +1 -0
  22. package/dist/declare.d.ts +33 -0
  23. package/dist/declare.d.ts.map +1 -0
  24. package/dist/declare.js +2 -0
  25. package/dist/declare.js.map +1 -0
  26. package/dist/delta/apply-immutable-trusted.js.map +1 -1
  27. package/dist/delta/diff.d.ts +1 -1
  28. package/dist/delta/diff.d.ts.map +1 -1
  29. package/dist/delta/diff.js.map +1 -1
  30. package/dist/delta/index.d.ts +4 -3
  31. package/dist/delta/index.d.ts.map +1 -1
  32. package/dist/delta/index.js +45 -0
  33. package/dist/delta/index.js.map +1 -1
  34. package/dist/delta/revision-validator.d.ts +1 -1
  35. package/dist/delta/revision-validator.d.ts.map +1 -1
  36. package/dist/delta/revision-validator.js.map +1 -1
  37. package/dist/delta/tracker.d.ts +1 -1
  38. package/dist/delta/tracker.d.ts.map +1 -1
  39. package/dist/delta/tracker.js +40 -4
  40. package/dist/delta/tracker.js.map +1 -1
  41. package/dist/errors.d.ts +28 -0
  42. package/dist/errors.d.ts.map +1 -0
  43. package/dist/errors.js +59 -0
  44. package/dist/errors.js.map +1 -0
  45. package/dist/host.d.ts +348 -0
  46. package/dist/host.d.ts.map +1 -0
  47. package/dist/host.js +1000 -0
  48. package/dist/host.js.map +1 -0
  49. package/dist/index.d.ts +17 -10
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +8 -8
  52. package/dist/index.js.map +1 -1
  53. package/dist/json.d.ts +9 -1
  54. package/dist/json.d.ts.map +1 -1
  55. package/dist/json.js.map +1 -1
  56. package/dist/link.d.ts +107 -0
  57. package/dist/link.d.ts.map +1 -0
  58. package/dist/link.js +355 -0
  59. package/dist/link.js.map +1 -0
  60. package/dist/loader.d.ts +4 -0
  61. package/dist/loader.d.ts.map +1 -0
  62. package/dist/loader.js +73 -0
  63. package/dist/loader.js.map +1 -0
  64. package/dist/manager.d.ts +115 -0
  65. package/dist/manager.d.ts.map +1 -0
  66. package/dist/manager.js +345 -0
  67. package/dist/manager.js.map +1 -0
  68. package/dist/node.d.ts +3 -4
  69. package/dist/node.d.ts.map +1 -1
  70. package/dist/node.js +3 -2
  71. package/dist/node.js.map +1 -1
  72. package/dist/object.d.ts +438 -0
  73. package/dist/object.d.ts.map +1 -0
  74. package/dist/object.js +1571 -0
  75. package/dist/object.js.map +1 -0
  76. package/dist/output.d.ts +85 -0
  77. package/dist/output.d.ts.map +1 -0
  78. package/dist/output.js +350 -0
  79. package/dist/output.js.map +1 -0
  80. package/dist/publish.d.ts +5 -0
  81. package/dist/publish.d.ts.map +1 -0
  82. package/dist/publish.js +40 -0
  83. package/dist/publish.js.map +1 -0
  84. package/dist/registry.d.ts +25 -0
  85. package/dist/registry.d.ts.map +1 -0
  86. package/dist/registry.js +6 -0
  87. package/dist/registry.js.map +1 -0
  88. package/dist/reload.d.ts +126 -0
  89. package/dist/reload.d.ts.map +1 -0
  90. package/dist/reload.js +653 -0
  91. package/dist/reload.js.map +1 -0
  92. package/dist/remote.d.ts +165 -0
  93. package/dist/remote.d.ts.map +1 -0
  94. package/dist/remote.js +612 -0
  95. package/dist/remote.js.map +1 -0
  96. package/dist/schema.d.ts +21 -0
  97. package/dist/schema.d.ts.map +1 -0
  98. package/dist/schema.js +228 -0
  99. package/dist/schema.js.map +1 -0
  100. package/dist/state.d.ts +92 -0
  101. package/dist/state.d.ts.map +1 -0
  102. package/dist/{services/state.js → state.js} +28 -138
  103. package/dist/state.js.map +1 -0
  104. package/dist/types.d.ts +69 -258
  105. package/dist/types.d.ts.map +1 -1
  106. package/dist/types.js.map +1 -1
  107. package/dist/websocket.d.ts +15 -0
  108. package/dist/websocket.d.ts.map +1 -0
  109. package/dist/websocket.js +16 -0
  110. package/dist/websocket.js.map +1 -0
  111. package/dist/wire.d.ts +216 -0
  112. package/dist/wire.d.ts.map +1 -0
  113. package/dist/wire.js +165 -0
  114. package/dist/wire.js.map +1 -0
  115. package/docs/guide.md +814 -0
  116. package/docs/spec.md +288 -0
  117. package/docs/tutorial.md +931 -0
  118. package/package.json +14 -10
  119. package/src/delta/README.md +5 -3
  120. package/dist/api.d.ts +0 -20
  121. package/dist/api.d.ts.map +0 -1
  122. package/dist/api.js +0 -77
  123. package/dist/api.js.map +0 -1
  124. package/dist/bundler.d.ts +0 -6
  125. package/dist/bundler.d.ts.map +0 -1
  126. package/dist/bundler.js +0 -3
  127. package/dist/bundler.js.map +0 -1
  128. package/dist/facets/host.d.ts +0 -12
  129. package/dist/facets/host.d.ts.map +0 -1
  130. package/dist/facets/host.js +0 -763
  131. package/dist/facets/host.js.map +0 -1
  132. package/dist/facets/loader.d.ts +0 -3
  133. package/dist/facets/loader.d.ts.map +0 -1
  134. package/dist/facets/loader.js +0 -5
  135. package/dist/facets/loader.js.map +0 -1
  136. package/dist/node/bundle-loader.d.ts +0 -30
  137. package/dist/node/bundle-loader.d.ts.map +0 -1
  138. package/dist/node/bundle-loader.js +0 -377
  139. package/dist/node/bundle-loader.js.map +0 -1
  140. package/dist/node/bundle.d.ts +0 -26
  141. package/dist/node/bundle.d.ts.map +0 -1
  142. package/dist/node/bundle.js +0 -183
  143. package/dist/node/bundle.js.map +0 -1
  144. package/dist/node/manifest.d.ts +0 -36
  145. package/dist/node/manifest.d.ts.map +0 -1
  146. package/dist/node/manifest.js +0 -6
  147. package/dist/node/manifest.js.map +0 -1
  148. package/dist/node/package.d.ts +0 -15
  149. package/dist/node/package.d.ts.map +0 -1
  150. package/dist/node/package.js +0 -199
  151. package/dist/node/package.js.map +0 -1
  152. package/dist/services/consumer.d.ts +0 -11
  153. package/dist/services/consumer.d.ts.map +0 -1
  154. package/dist/services/consumer.js +0 -585
  155. package/dist/services/consumer.js.map +0 -1
  156. package/dist/services/errors.d.ts +0 -8
  157. package/dist/services/errors.d.ts.map +0 -1
  158. package/dist/services/errors.js +0 -22
  159. package/dist/services/errors.js.map +0 -1
  160. package/dist/services/handle.d.ts +0 -15
  161. package/dist/services/handle.d.ts.map +0 -1
  162. package/dist/services/handle.js +0 -101
  163. package/dist/services/handle.js.map +0 -1
  164. package/dist/services/instances.d.ts +0 -26
  165. package/dist/services/instances.d.ts.map +0 -1
  166. package/dist/services/instances.js +0 -140
  167. package/dist/services/instances.js.map +0 -1
  168. package/dist/services/loopback.d.ts +0 -5
  169. package/dist/services/loopback.d.ts.map +0 -1
  170. package/dist/services/loopback.js +0 -15
  171. package/dist/services/loopback.js.map +0 -1
  172. package/dist/services/provider.d.ts +0 -37
  173. package/dist/services/provider.d.ts.map +0 -1
  174. package/dist/services/provider.js +0 -521
  175. package/dist/services/provider.js.map +0 -1
  176. package/dist/services/state-codec.d.ts +0 -15
  177. package/dist/services/state-codec.d.ts.map +0 -1
  178. package/dist/services/state-codec.js +0 -133
  179. package/dist/services/state-codec.js.map +0 -1
  180. package/dist/services/state-internals.d.ts +0 -13
  181. package/dist/services/state-internals.d.ts.map +0 -1
  182. package/dist/services/state-internals.js +0 -10
  183. package/dist/services/state-internals.js.map +0 -1
  184. package/dist/services/state.d.ts +0 -28
  185. package/dist/services/state.d.ts.map +0 -1
  186. package/dist/services/state.js.map +0 -1
  187. package/dist/services/wire.d.ts +0 -63
  188. package/dist/services/wire.d.ts.map +0 -1
  189. package/dist/services/wire.js +0 -186
  190. package/dist/services/wire.js.map +0 -1
package/dist/types.d.ts CHANGED
@@ -1,277 +1,88 @@
1
- import type { Draft, Op } from "./delta/index.ts";
2
- import type { RemoteServiceProvider } from "./services/provider.ts";
3
- export type { RemoteServiceError } from "./services/errors.ts";
4
- export type { RemoteServiceProvider } from "./services/provider.ts";
5
- /** Typed identity for one value carried by a {@link Context}. */
6
- export interface ContextKey<T> {
7
- readonly token: symbol;
8
- /** Type-only marker that prevents keys with different value types from being interchangeable. */
9
- readonly valueType?: (value: T) => T;
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;
1
+ import type { AnyContract, InputOf, Ref } from "./contract.ts";
2
+ import type { Op } from "./delta/index.ts";
3
+ /**
4
+ * Options of `get`. `P` is the app's principal type: a JSON-serializable identity of a caller, mapped to an object key
5
+ * by `createHost({ principalKey })`.
6
+ */
7
+ export interface GetOptions<P = unknown> {
8
+ /** Principal the object is created for. Defaults to the host's own principal (`createHost({ self })`). */
9
+ readonly principal?: P;
35
10
  /**
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.
11
+ * False: a method-only reference. It receives no state (unless another reference to the same object wants it), and
12
+ * is ready once its object is live.
40
13
  */
41
- subscribe(listener: (value: T, context: Context, delivery: ReplicatedStateDelivery) => Promise<void>): () => void;
42
- subscribe(listener: (value: T, context: Context, delivery: ReplicatedStateDelivery) => void): () => void;
14
+ readonly state?: boolean;
43
15
  }
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;
16
+ /**
17
+ * The explicit call context of one root (a short Chord call tree). Calls made with it carry its root id and code
18
+ * version; `get` references are released when the call that received this ctx settles.
19
+ */
20
+ export interface Ctx<P = unknown> {
21
+ readonly signal: AbortSignal;
22
+ readonly rootId: string;
23
+ readonly codeVersion: number;
24
+ /** Who the root acts as: the caller at ingress, the host's own principal inside objects. */
25
+ readonly principal: P;
51
26
  /**
52
- * Atomically take immutable ownership of an alias-free strict-JSON replacement.
53
- * The caller must not mutate the transferred root after this call.
27
+ * A reference for this call, released when the call settles. Resolves once it is ready: live, with every state
28
+ * member of its variant (unless `state: false`). Rejects with the activation error, `aborted` when the ctx is
29
+ * aborted or the call settles first, or `unavailable/ready_timeout` after the host's `readyTimeout`; the reference
30
+ * is released then.
54
31
  */
55
- replace(context: Context, value: T): void;
32
+ get<C extends AnyContract>(type: C, input: InputOf<C>, options?: GetOptions<P>): Promise<Ref<C>>;
56
33
  }
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. */
34
+ export type StateEvent<T> = {
35
+ readonly type: "snap";
62
36
  readonly value: T;
63
- /** The exact immutable operation batch that produced `value` from the preceding source revision. */
37
+ } | {
38
+ readonly type: "ops";
64
39
  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;
81
- }
82
- /**
83
- * An authoritative immutable revision source.
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.
89
- */
90
- export interface ReplicatedStateSource<T> {
91
- attach(): ReplicatedStateSourceAttachment<T>;
92
- }
93
- export interface ReplicatedStateSourceOptions {
94
- /** Receives source-contract and publication-listener failures without throwing them into the source. */
95
- readonly onError?: (error: Error) => void;
96
- }
97
- /** A synchronously hydrated publication-only state backed by one source attachment. */
98
- export interface AttachedReplicatedState<T> extends ReplicatedState<T> {
99
40
  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
41
  } | {
148
- readonly name: string;
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;
167
- readonly ops: readonly Op[];
168
- }
169
- /** Full subscription rebaseline after overflow; every state is a root replacement at its new sequence. */
170
- | {
171
42
  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;
181
- } | {
182
- readonly type: "closed";
183
- readonly instance: ServiceInstanceAddress;
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[];
43
+ readonly value: T;
191
44
  };
192
- export interface ServiceSubscription {
193
- /** Atomic baseline. Later updates buffer until activation, with a full reset on pending delivery 101. */
194
- readonly snapshot: ServiceSubscriptionSnapshot;
195
- activate(): void;
196
- close(context?: Context): void | Promise<void>;
45
+ /** A readable state source: a cell, a derivation, or a reference's state member. Values are immutable by contract. */
46
+ export interface Readable<T> {
47
+ readonly value: T;
48
+ /** Called with the current value immediately, then with every new value. */
49
+ subscribe(listener: (value: T) => void): () => void;
50
+ /** Delta stream: a snapshot immediately, then ops, or a reset after a migration or rebind. */
51
+ events(listener: (event: StateEvent<T>) => void): () => void;
197
52
  }
198
53
  /**
199
- * Pluggable wire boundary consumed by a remote service binding.
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
- *
54
+ * What an implementation may expose as a state member: a cell, a derivation, or a held object's state member (an
55
+ * object goes live only once the members it exposes have their values).
205
56
  */
206
- export interface RemoteServiceTransport {
207
- invoke(call: ServiceCall, context: Context): Promise<JsonValue | undefined>;
208
- subscribe(serviceId: string, mode: ServiceMode, listener: (update: ServiceProviderUpdate, context: Context) => void, context: Context): Promise<ServiceSubscription>;
209
- }
210
- export interface RemoteServiceBindingOptions {
211
- readonly services: readonly {
212
- readonly id: string;
213
- }[];
214
- readonly transport: RemoteServiceTransport;
215
- readonly bound?: boolean;
216
- readonly onError?: (error: Error) => void;
217
- readonly assertAccess?: () => void;
218
- }
219
- export interface RemoteServiceBinding extends RemoteServices {
220
- rebind(bound: boolean, context: Context): Promise<void>;
221
- }
222
- export interface FacetEnvironment {
223
- /** Declare a hard dependency on one singleton service and return its stable handle. */
224
- use<T>(service: Service<T>): T;
225
- /** Declare a hard dependency on a keyed service and observe each live instance. */
226
- observe<T>(service: Service<T>, handler: (service: T, context: Context) => void | Promise<void>): void;
227
- /** Declare and install this facet's singleton implementation of a service. */
228
- provide<T>(service: Service<T>, implementation: NoInfer<T>): void;
229
- /** Declare ownership of a multi-instance service and return its deferred spawning capability. */
230
- provideMany<T>(service: Service<T>): ServiceSpawner<T>;
57
+ export type StateSource<T> = Readable<T>;
58
+ declare const EXPOSED: unique symbol;
59
+ /** A local member backed by a resource (`self.expose(res.x)`): references read the resource's value once live. */
60
+ export interface Exposed<T> {
61
+ readonly [EXPOSED]: T;
62
+ }
63
+ export type RefStatus = "loading" | "live" | "released" | "gone";
64
+ export interface Shape {
65
+ readonly variant: string | undefined;
66
+ readonly members: readonly string[];
67
+ /** Fingerprint of the provider contract. */
68
+ readonly contract: string;
69
+ }
70
+ export interface RefBase<C extends AnyContract> {
71
+ /** The consumer contract token this reference was bound with. */
72
+ readonly contract: C;
73
+ readonly status: RefStatus;
74
+ readonly ready: Promise<void>;
75
+ readonly variant: string | undefined;
76
+ readonly shape: Shape | undefined;
77
+ /** Why the reference is gone, if it is. */
78
+ readonly error: unknown;
79
+ onShape(listener: (shape: Shape) => void): () => void;
231
80
  /**
232
- * Create initialized mutable state by taking immutable ownership of an alias-free strict-JSON root.
233
- * The caller must not mutate `initial` after this call.
81
+ * Called after every status change (`loading` → `live`, `live` → `loading` while a link reconnects, `released`,
82
+ * `gone` with `error`). A UI watches for `gone` to `get` again.
234
83
  */
235
- replicatedState<T extends object>(initial: T): MutableReplicatedState<T>;
236
- /** Give the facet ownership of a resource cleanup function. */
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>;
84
+ onStatus(listener: (status: RefStatus, error: unknown) => void): () => void;
85
+ release(): void;
276
86
  }
87
+ export {};
277
88
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
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, InputOf, Ref } from \"./contract.ts\";\nimport type { Op } from \"./delta/index.ts\";\n\n/**\n * Options of `get`. `P` is the app's principal type: a JSON-serializable identity of a caller, mapped to an object key\n * by `createHost({ principalKey })`.\n */\nexport interface GetOptions<P = unknown> {\n\t/** Principal the object is created for. Defaults to the host's own principal (`createHost({ self })`). */\n\treadonly principal?: P;\n\t/**\n\t * False: a method-only reference. It receives no state (unless another reference to the same object wants it), and\n\t * is ready once its object is live.\n\t */\n\treadonly state?: boolean;\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 code\n * version; `get` references are released when the call that received this ctx settles.\n */\nexport interface Ctx<P = unknown> {\n\treadonly signal: AbortSignal;\n\treadonly rootId: string;\n\treadonly codeVersion: number;\n\t/** Who the root acts as: the caller at ingress, the host's own principal inside objects. */\n\treadonly principal: P;\n\t/**\n\t * A reference for this call, released when the call settles. Resolves once it is ready: live, with every state\n\t * member of its variant (unless `state: false`). Rejects with the activation error, `aborted` when the ctx is\n\t * aborted or the call settles first, or `unavailable/ready_timeout` after the host's `readyTimeout`; the reference\n\t * is released then.\n\t */\n\tget<C extends AnyContract>(type: C, input: InputOf<C>, options?: GetOptions<P>): Promise<Ref<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 reference'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 an implementation may expose as a state member: a cell, a derivation, or a held object's state member (an\n * object goes live only once the members it exposes have their values).\n */\nexport type StateSource<T> = Readable<T>;\n\ndeclare const EXPOSED: unique symbol;\n\n/** A local member backed by a resource (`self.expose(res.x)`): references read the resource's value once live. */\nexport interface Exposed<T> {\n\treadonly [EXPOSED]: T;\n}\n\nexport type RefStatus = \"loading\" | \"live\" | \"released\" | \"gone\";\n\nexport interface Shape {\n\treadonly variant: string | undefined;\n\treadonly members: readonly string[];\n\t/** Fingerprint of the provider contract. */\n\treadonly contract: string;\n}\n\nexport interface RefBase<C extends AnyContract> {\n\t/** The consumer contract token this reference was bound with. */\n\treadonly contract: C;\n\treadonly status: RefStatus;\n\treadonly ready: Promise<void>;\n\treadonly variant: string | undefined;\n\treadonly shape: Shape | undefined;\n\t/** Why the reference 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: RefStatus, error: unknown) => void): () => void;\n\trelease(): void;\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import type { AcceptOptions } from "./connection.ts";
2
+ import type { Host } from "./host.ts";
3
+ import { type WebSocketLike } from "./link.ts";
4
+ /** A WebSocket server (e.g. `ws`'s `WebSocketServer`), structurally: Chord does not depend on `ws`. */
5
+ export interface WebSocketServerLike<Request> {
6
+ on(event: "connection", listener: (socket: WebSocketLike, request: Request) => void): unknown;
7
+ }
8
+ /** WebSocket peers are always accepted as clients: no roots, no code versions, no reload votes, not addressable. */
9
+ export interface WebSocketAcceptOptions<Request, P = unknown> extends Omit<AcceptOptions<P>, "principal" | "kind" | "name"> {
10
+ /** The authenticator: the principal of the connecting client, or undefined to refuse it. */
11
+ principal(request: Request): P | undefined | Promise<P | undefined>;
12
+ }
13
+ /** Accepts every connection of `server` on `host` as a client link stamped with the authenticated principal. */
14
+ export declare function acceptWebSockets<Request, P = unknown>(server: WebSocketServerLike<Request>, host: Host<P>, options: WebSocketAcceptOptions<Request, P>): void;
15
+ //# 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;AAE9D,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,oHAAoH;AACpH,MAAM,WAAW,sBAAsB,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAC3D,SAAQ,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;IAC7D,4FAA4F;IAC5F,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;CACpE;AAED,gHAAgH;AAChH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,EACpD,MAAM,EAAE,mBAAmB,CAAC,OAAO,CAAC,EACpC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EACb,OAAO,EAAE,sBAAsB,CAAC,OAAO,EAAE,CAAC,CAAC,GACzC,IAAI,CAaN"}
@@ -0,0 +1,16 @@
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. Large payloads go out deflated; clients
6
+ // may not send packed frames (a small message could inflate to anything).
7
+ const link = webSocketLink(socket, { compress: true, acceptPacked: false });
8
+ Promise.resolve(options.principal(request)).then((principal) => {
9
+ if (principal === undefined)
10
+ link.close("unauthorized");
11
+ else
12
+ host.accept(link, { ...options, principal, kind: "client" });
13
+ }, () => link.close("authentication failed"));
14
+ });
15
+ }
16
+ //# 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,IAAa,EACb,OAA2C;IAE3C,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;QAC3C,iHAAiH;QACjH,0EAA0E;QAC1E,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5E,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\";\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 code versions, no reload votes, not addressable. */\nexport interface WebSocketAcceptOptions<Request, P = unknown>\n\textends Omit<AcceptOptions<P>, \"principal\" | \"kind\" | \"name\"> {\n\t/** The authenticator: the principal of the connecting client, or undefined to refuse it. */\n\tprincipal(request: Request): P | undefined | Promise<P | undefined>;\n}\n\n/** Accepts every connection of `server` on `host` as a client link stamped with the authenticated principal. */\nexport function acceptWebSockets<Request, P = unknown>(\n\tserver: WebSocketServerLike<Request>,\n\thost: Host<P>,\n\toptions: WebSocketAcceptOptions<Request, P>,\n): void {\n\tserver.on(\"connection\", (socket, request) => {\n\t\t// Wrap at once so frames sent while authenticating are queued, not lost. Large payloads go out deflated; clients\n\t\t// may not send packed frames (a small message could inflate to anything).\n\t\tconst link = webSocketLink(socket, { compress: true, acceptPacked: false });\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"]}