@earendil-works/chord 1.2.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 (86) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +14 -13
  3. package/dist/cell.d.ts +30 -9
  4. package/dist/cell.d.ts.map +1 -1
  5. package/dist/cell.js +52 -12
  6. package/dist/cell.js.map +1 -1
  7. package/dist/cluster.d.ts +4 -3
  8. package/dist/cluster.d.ts.map +1 -1
  9. package/dist/cluster.js +58 -42
  10. package/dist/cluster.js.map +1 -1
  11. package/dist/connection.d.ts +171 -58
  12. package/dist/connection.d.ts.map +1 -1
  13. package/dist/connection.js +676 -217
  14. package/dist/connection.js.map +1 -1
  15. package/dist/contract.d.ts +120 -45
  16. package/dist/contract.d.ts.map +1 -1
  17. package/dist/contract.js +104 -15
  18. package/dist/contract.js.map +1 -1
  19. package/dist/declare.d.ts +11 -48
  20. package/dist/declare.d.ts.map +1 -1
  21. package/dist/declare.js +1 -21
  22. package/dist/declare.js.map +1 -1
  23. package/dist/delta/index.d.ts +2 -1
  24. package/dist/delta/index.d.ts.map +1 -1
  25. package/dist/delta/index.js +4 -0
  26. package/dist/delta/index.js.map +1 -1
  27. package/dist/errors.d.ts +4 -3
  28. package/dist/errors.d.ts.map +1 -1
  29. package/dist/errors.js +15 -0
  30. package/dist/errors.js.map +1 -1
  31. package/dist/host.d.ts +214 -120
  32. package/dist/host.d.ts.map +1 -1
  33. package/dist/host.js +446 -241
  34. package/dist/host.js.map +1 -1
  35. package/dist/index.d.ts +8 -8
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +4 -4
  38. package/dist/index.js.map +1 -1
  39. package/dist/link.d.ts +47 -12
  40. package/dist/link.d.ts.map +1 -1
  41. package/dist/link.js +200 -14
  42. package/dist/link.js.map +1 -1
  43. package/dist/loader.d.ts.map +1 -1
  44. package/dist/loader.js +7 -2
  45. package/dist/loader.js.map +1 -1
  46. package/dist/manager.d.ts.map +1 -1
  47. package/dist/manager.js +35 -9
  48. package/dist/manager.js.map +1 -1
  49. package/dist/object.d.ts +438 -0
  50. package/dist/object.d.ts.map +1 -0
  51. package/dist/{record.js → object.js} +614 -335
  52. package/dist/object.js.map +1 -0
  53. package/dist/output.d.ts +85 -0
  54. package/dist/output.d.ts.map +1 -0
  55. package/dist/output.js +350 -0
  56. package/dist/output.js.map +1 -0
  57. package/dist/registry.d.ts +3 -3
  58. package/dist/registry.d.ts.map +1 -1
  59. package/dist/registry.js +1 -1
  60. package/dist/registry.js.map +1 -1
  61. package/dist/reload.d.ts +35 -27
  62. package/dist/reload.d.ts.map +1 -1
  63. package/dist/reload.js +256 -192
  64. package/dist/reload.js.map +1 -1
  65. package/dist/remote.d.ts +130 -35
  66. package/dist/remote.d.ts.map +1 -1
  67. package/dist/remote.js +493 -189
  68. package/dist/remote.js.map +1 -1
  69. package/dist/types.d.ts +39 -28
  70. package/dist/types.d.ts.map +1 -1
  71. package/dist/types.js.map +1 -1
  72. package/dist/websocket.d.ts +4 -5
  73. package/dist/websocket.d.ts.map +1 -1
  74. package/dist/websocket.js +3 -2
  75. package/dist/websocket.js.map +1 -1
  76. package/dist/wire.d.ts +210 -129
  77. package/dist/wire.d.ts.map +1 -1
  78. package/dist/wire.js +108 -55
  79. package/dist/wire.js.map +1 -1
  80. package/docs/guide.md +267 -203
  81. package/docs/spec.md +141 -114
  82. package/docs/tutorial.md +257 -235
  83. package/package.json +6 -1
  84. package/dist/record.d.ts +0 -320
  85. package/dist/record.d.ts.map +0 -1
  86. package/dist/record.js.map +0 -1
package/dist/cluster.js CHANGED
@@ -3,12 +3,12 @@ import { beginReload, endReload, reloadError } from "./reload.js";
3
3
  import { toWireError } from "./wire.js";
4
4
  // Cross-host reload, coordinated by the server (the host without a parent):
5
5
  // server: prepare itself and send `prepare` to every synced child host; collect votes
6
- // all ok: the server installs its new epoch, sends `commit` to every child, and only then starts what may make
7
- // new-epoch calls (tasks, listener and registry callbacks). Links are FIFO, so a child commits before it
8
- // can receive any frame of a root started in the new epoch.
6
+ // all ok: the server installs its new code version, sends `commit` to every child, and only then starts what may make
7
+ // new-code-version calls (tasks, listener and registry callbacks). Links are FIFO, so a child commits before it
8
+ // can receive any frame of a root started in the new code version.
9
9
  // any failure or missed vote deadline: `abort` everywhere; each host rolls back to where it was.
10
10
  // Clients (browsers) are not participants: they see shape/reset pushes, or `upgrade_required`.
11
- // A child that connects behind the server's epoch is fenced and reconciled with the same protocol.
11
+ // A child that connects behind the server's code version is fenced and reconciled with the same protocol.
12
12
  let reloadSeq = 0;
13
13
  const modulesFor = (remote, hostName) => {
14
14
  let best;
@@ -31,33 +31,39 @@ function awaitVote(connection, id, deadline) {
31
31
  return vote.finally(() => clearTimeout(timer));
32
32
  }
33
33
  export async function runClusterReload(host, plugins, options) {
34
- // Fenced children (behind, being reconciled) are not participants; they reconcile to the new epoch afterwards.
35
- const participants = [...host.connections].filter((connection) => connection.role === "downstream" && connection.peer.kind === "host" && connection.open && connection.synced);
36
- const epoch = host.peekNextEpoch();
37
- const reload = await beginReload(host, plugins, options, epoch);
38
- const id = ++reloadSeq;
39
- const deadline = options.voteDeadline ?? (options.gateDeadline ?? 5000) + (options.retireDeadline ?? 5000) + 5000;
40
- const votes = participants.map((connection) => {
41
- const name = connection.name ?? "child";
42
- const vote = awaitVote(connection, id, deadline);
43
- connection.send({
44
- t: "prepare",
45
- reload: id,
46
- epoch,
47
- plugins: modulesFor(options.remote, name),
48
- options: {
49
- remove: modulesFor(options.remoteRemove, name),
50
- gateDeadline: options.gateDeadline,
51
- retireDeadline: options.retireDeadline,
52
- },
53
- });
54
- return vote.then((report) => [name, report], (error) => {
55
- const cause = reloadError(error);
56
- throw new ChordError(cause.code, `${name}: ${cause.message}`, { cause, reason: cause.reason });
57
- });
58
- });
59
- let local = false;
34
+ // Participants are the children in step now. Fenced children (behind, being reconciled) reconcile to the new code
35
+ // version afterwards; a child whose hello arrives while the reload runs is synced or reconciled once it ends
36
+ // (`HostImpl.peerHello`).
37
+ const synced = [...host.connections].filter((connection) => connection.role === "downstream" && connection.peer.kind === "host" && connection.open && connection.synced);
38
+ const codeVersion = host.peekNextCodeVersion();
39
+ const reload = await beginReload(host, plugins, options, codeVersion);
60
40
  try {
41
+ // Retire first: its `retire` frames reach every child before `prepare` (FIFO), so a child never retires a code
42
+ // version this host still runs roots of.
43
+ await reload.waitForRetirement();
44
+ const participants = synced.filter((connection) => connection.open);
45
+ const id = ++reloadSeq;
46
+ const deadline = options.voteDeadline ?? (options.gateDeadline ?? 5000) + (options.retireDeadline ?? 5000) + 5000;
47
+ const votes = participants.map((connection) => {
48
+ const name = connection.name ?? "child";
49
+ const vote = awaitVote(connection, id, deadline);
50
+ connection.send({
51
+ t: "prepare",
52
+ reload: id,
53
+ codeVersion,
54
+ plugins: modulesFor(options.remote, name),
55
+ options: {
56
+ remove: modulesFor(options.remoteRemove, name),
57
+ gateDeadline: options.gateDeadline,
58
+ retireDeadline: options.retireDeadline,
59
+ },
60
+ });
61
+ return vote.then((report) => [name, report], (error) => {
62
+ const cause = reloadError(error);
63
+ throw new ChordError(cause.code, `${name}: ${cause.message}`, { cause, reason: cause.reason });
64
+ });
65
+ });
66
+ let local = false;
61
67
  const results = await Promise.allSettled([
62
68
  reload.prepare().then(() => {
63
69
  local = true;
@@ -77,7 +83,7 @@ export async function runClusterReload(host, plugins, options) {
77
83
  const report = reload.commit(() => {
78
84
  for (const connection of participants) {
79
85
  connection.send({ t: "commit", reload: id });
80
- connection.peerEpoch = epoch;
86
+ connection.peerCodeVersion = codeVersion;
81
87
  }
82
88
  });
83
89
  host.rememberRemoteModules(options.remote, options.remoteRemove);
@@ -96,36 +102,46 @@ export async function runClusterReload(host, plugins, options) {
96
102
  }
97
103
  }
98
104
  /**
99
- * Brings a child that connected behind this host's epoch up to it: a reload of the child's modules (the ones
100
- * cluster reloads gave its name) to this host's current epoch, prepared, voted and committed like a cluster reload.
101
- * Until then the child is fenced: nothing is routed to it. The child's old code is never relabeled as a newer epoch.
105
+ * Brings a child that connected behind this host's code version up to it: a reload of the child's modules (the ones
106
+ * cluster reloads gave its name) to this host's current code version, prepared, voted and committed like a cluster
107
+ * reload. Until then the child is fenced: nothing is routed to it. The child's old code is never relabeled as a newer
108
+ * code version.
102
109
  */
103
110
  export async function reconcileChild(host, connection) {
104
111
  for (;;) {
105
- const epoch = host.current.id;
106
112
  if (!connection.open)
107
113
  return;
108
- if (connection.peerEpoch === epoch) {
109
- connection.markSynced(epoch);
114
+ // Not during a reload of this host: the child is not one of its participants, so whatever it would be synced to
115
+ // now may be superseded by that reload's commit. Recheck once it ended.
116
+ if (host.reloading) {
117
+ await host.whenReloadEnded();
118
+ continue;
119
+ }
120
+ const codeVersion = host.current.id;
121
+ if (connection.peerCodeVersion === codeVersion) {
122
+ connection.markSynced(codeVersion);
123
+ host.announceRetired(connection);
110
124
  return;
111
125
  }
126
+ // Before `prepare`: the child's prepare first retires its previous code version, which waits for this permission.
127
+ host.announceRetired(connection);
112
128
  const id = ++reloadSeq;
113
129
  const vote = awaitVote(connection, id, 30_000);
114
130
  connection.send({
115
131
  t: "prepare",
116
132
  reload: id,
117
- epoch,
133
+ codeVersion,
118
134
  plugins: modulesFor(host.remoteModules, connection.name),
119
135
  options: { remove: modulesFor(host.remoteRemoved, connection.name) },
120
136
  });
121
137
  await vote;
122
- if (host.current.id !== epoch) {
123
- // This host moved on meanwhile: abort and try again with the newer epoch.
138
+ if (host.current.id !== codeVersion) {
139
+ // This host moved on meanwhile: abort and try again with the newer code version.
124
140
  connection.send({ t: "abort", reload: id });
125
141
  continue;
126
142
  }
127
143
  connection.send({ t: "commit", reload: id });
128
- connection.peerEpoch = epoch;
144
+ connection.peerCodeVersion = codeVersion;
129
145
  }
130
146
  }
131
147
  /**
@@ -189,7 +205,7 @@ export class ChildReloads {
189
205
  async #run(operation, connection, frame) {
190
206
  const cancelled = () => new ChordError("aborted", "reload aborted by the server", { reason: "aborted" });
191
207
  try {
192
- operation.reload = await beginReload(this.#host, frame.plugins, frame.options, frame.epoch);
208
+ operation.reload = await beginReload(this.#host, frame.plugins, frame.options, frame.codeVersion);
193
209
  if (operation.cancelled)
194
210
  throw cancelled();
195
211
  operation.state = "preparing";
@@ -1 +1 @@
1
- {"version":3,"file":"cluster.js","sourceRoot":"","sources":["../src/cluster.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Connection } from \"./connection.ts\";\nimport { ChordError } from \"./errors.ts\";\nimport type { HostImpl, PluginRef } from \"./host.ts\";\nimport { beginReload, endReload, type Reload, type ReloadOptions, type ReloadReport, reloadError } from \"./reload.ts\";\nimport { type Frame, toWireError } from \"./wire.ts\";\n\n// Cross-host reload, coordinated by the server (the host without a parent):\n// server: prepare itself and send `prepare` to every synced child host; collect votes\n// all ok: the server installs its new epoch, sends `commit` to every child, and only then starts what may make\n// new-epoch calls (tasks, listener and registry callbacks). Links are FIFO, so a child commits before it\n// can receive any frame of a root started in the new epoch.\n// any failure or missed vote deadline: `abort` everywhere; each host rolls back to where it was.\n// Clients (browsers) are not participants: they see shape/reset pushes, or `upgrade_required`.\n// A child that connects behind the server's epoch is fenced and reconciled with the same protocol.\n\nlet reloadSeq = 0;\n\nconst modulesFor = (remote: ReloadOptions[\"remote\"], hostName: string | undefined): string[] => {\n\tlet best: [string, readonly string[]] | undefined;\n\tfor (const entry of Object.entries(remote ?? {})) {\n\t\tif (hostName?.startsWith(entry[0]) && (best === undefined || entry[0].length > best[0].length)) best = entry;\n\t}\n\treturn [...(best?.[1] ?? [])];\n};\n\n/** A vote, or its rejection after `deadline` milliseconds. */\nfunction awaitVote(connection: Connection, id: number, deadline: number): Promise<unknown> {\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tconst vote = new Promise<unknown>((resolve, reject) => {\n\t\tconnection.votes.set(id, { resolve, reject });\n\t\ttimer = setTimeout(() => {\n\t\t\tconnection.votes.delete(id);\n\t\t\treject(new ChordError(\"aborted\", `votes missing after ${deadline} ms`, { reason: \"vote_deadline\" }));\n\t\t}, deadline);\n\t});\n\treturn vote.finally(() => clearTimeout(timer));\n}\n\nexport async function runClusterReload(\n\thost: HostImpl,\n\tplugins: readonly PluginRef[],\n\toptions: ReloadOptions,\n): Promise<ReloadReport> {\n\t// Fenced children (behind, being reconciled) are not participants; they reconcile to the new epoch afterwards.\n\tconst participants = [...host.connections].filter(\n\t\t(connection) =>\n\t\t\tconnection.role === \"downstream\" && connection.peer.kind === \"host\" && connection.open && connection.synced,\n\t);\n\tconst epoch = host.peekNextEpoch();\n\tconst reload = await beginReload(host, plugins, options, epoch);\n\tconst id = ++reloadSeq;\n\tconst deadline = options.voteDeadline ?? (options.gateDeadline ?? 5000) + (options.retireDeadline ?? 5000) + 5000;\n\tconst votes = participants.map((connection) => {\n\t\tconst name = connection.name ?? \"child\";\n\t\tconst vote = awaitVote(connection, id, deadline);\n\t\tconnection.send({\n\t\t\tt: \"prepare\",\n\t\t\treload: id,\n\t\t\tepoch,\n\t\t\tplugins: modulesFor(options.remote, name),\n\t\t\toptions: {\n\t\t\t\tremove: modulesFor(options.remoteRemove, name),\n\t\t\t\tgateDeadline: options.gateDeadline,\n\t\t\t\tretireDeadline: options.retireDeadline,\n\t\t\t},\n\t\t});\n\t\treturn vote.then(\n\t\t\t(report) => [name, report as ReloadReport | undefined] as const,\n\t\t\t(error: unknown) => {\n\t\t\t\tconst cause = reloadError(error);\n\t\t\t\tthrow new ChordError(cause.code, `${name}: ${cause.message}`, { cause, reason: cause.reason });\n\t\t\t},\n\t\t);\n\t});\n\tlet local = false;\n\ttry {\n\t\tconst results = await Promise.allSettled([\n\t\t\treload.prepare().then(() => {\n\t\t\t\tlocal = true;\n\t\t\t}),\n\t\t\t...votes,\n\t\t]);\n\t\tconst failed = results.find((result) => result.status === \"rejected\");\n\t\tif (failed !== undefined) {\n\t\t\tfor (const connection of participants) {\n\t\t\t\tconnection.votes.delete(id);\n\t\t\t\tconnection.send({ t: \"abort\", reload: id });\n\t\t\t}\n\t\t\tif (local) await reload.rollback();\n\t\t\tthrow failed.reason;\n\t\t}\n\t\tconst report = reload.commit(() => {\n\t\t\tfor (const connection of participants) {\n\t\t\t\tconnection.send({ t: \"commit\", reload: id });\n\t\t\t\tconnection.peerEpoch = epoch;\n\t\t\t}\n\t\t});\n\t\thost.rememberRemoteModules(options.remote, options.remoteRemove);\n\t\tconst children: Record<string, ReloadReport> = {};\n\t\tfor (const result of results.slice(1)) {\n\t\t\tif (result.status !== \"fulfilled\") continue;\n\t\t\tconst [name, child] = result.value as readonly [string, ReloadReport | undefined];\n\t\t\tif (child !== undefined) children[name] = child;\n\t\t}\n\t\treturn { ...report, children };\n\t} finally {\n\t\tendReload(host);\n\t}\n}\n\n/**\n * Brings a child that connected behind this host's epoch up to it: a reload of the child's modules (the ones\n * cluster reloads gave its name) to this host's current epoch, prepared, voted and committed like a cluster reload.\n * Until then the child is fenced: nothing is routed to it. The child's old code is never relabeled as a newer epoch.\n */\nexport async function reconcileChild(host: HostImpl, connection: Connection): Promise<void> {\n\tfor (;;) {\n\t\tconst epoch = host.current.id;\n\t\tif (!connection.open) return;\n\t\tif (connection.peerEpoch === epoch) {\n\t\t\tconnection.markSynced(epoch);\n\t\t\treturn;\n\t\t}\n\t\tconst id = ++reloadSeq;\n\t\tconst vote = awaitVote(connection, id, 30_000);\n\t\tconnection.send({\n\t\t\tt: \"prepare\",\n\t\t\treload: id,\n\t\t\tepoch,\n\t\t\tplugins: modulesFor(host.remoteModules, connection.name),\n\t\t\toptions: { remove: modulesFor(host.remoteRemoved, connection.name) },\n\t\t});\n\t\tawait vote;\n\t\tif (host.current.id !== epoch) {\n\t\t\t// This host moved on meanwhile: abort and try again with the newer epoch.\n\t\t\tconnection.send({ t: \"abort\", reload: id });\n\t\t\tcontinue;\n\t\t}\n\t\tconnection.send({ t: \"commit\", reload: id });\n\t\tconnection.peerEpoch = epoch;\n\t}\n}\n\n/** One prepare the child received, registered before its first await so an abort or disconnect is never lost. */\ninterface ChildOperation {\n\treadonly id: number;\n\treload: Reload | undefined;\n\tstate: \"loading\" | \"preparing\" | \"prepared\";\n\tcancelled: boolean;\n}\n\n/**\n * The child side: prepare and vote, then wait for the server's commit or abort. An abort or a lost parent link can\n * arrive at any point: while loading modules, while preparing (pending opens close themselves when they complete),\n * or after the vote. The operation is unwound once its pending work settles, and the reload slot is freed.\n */\nexport class ChildReloads {\n\treadonly #host: HostImpl;\n\t#operation: ChildOperation | undefined;\n\n\tconstructor(host: HostImpl) {\n\t\tthis.#host = host;\n\t}\n\n\thandle(connection: Connection, frame: Extract<Frame, { t: \"prepare\" | \"commit\" | \"abort\" }>): void {\n\t\tif (frame.t === \"prepare\") {\n\t\t\tif (this.#operation !== undefined) {\n\t\t\t\tconst error = new ChordError(\"unavailable\", \"a reload is already running\", { reason: \"reload_running\" });\n\t\t\t\tconnection.send({ t: \"vote\", reload: frame.reload, error: toWireError(error) });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst operation: ChildOperation = { id: frame.reload, reload: undefined, state: \"loading\", cancelled: false };\n\t\t\tthis.#operation = operation;\n\t\t\tthis.#run(operation, connection, frame).catch((error: unknown) => this.#host.report(error));\n\t\t\treturn;\n\t\t}\n\t\tconst operation = this.#operation;\n\t\tif (operation === undefined || operation.id !== frame.reload) return;\n\t\tif (frame.t === \"abort\") {\n\t\t\tthis.#cancel(operation);\n\t\t\treturn;\n\t\t}\n\t\tif (operation.state !== \"prepared\") return;\n\t\tthis.#operation = undefined;\n\t\ttry {\n\t\t\toperation.reload?.commit();\n\t\t} finally {\n\t\t\tendReload(this.#host);\n\t\t}\n\t}\n\n\t/** The parent link died: nobody will commit, so roll back (now, or once pending work settles). */\n\tparentLost(): void {\n\t\tif (this.#operation !== undefined) this.#cancel(this.#operation);\n\t}\n\n\t#cancel(operation: ChildOperation): void {\n\t\toperation.cancelled = true;\n\t\tif (operation.state !== \"prepared\") {\n\t\t\t// Loading or preparing: make prepare fail now; #run unwinds when it settles.\n\t\t\toperation.reload?.rollback().catch((error: unknown) => this.#host.report(error));\n\t\t\treturn;\n\t\t}\n\t\tthis.#operation = undefined;\n\t\toperation.reload\n\t\t\t?.rollback()\n\t\t\t.catch((error: unknown) => this.#host.report(error))\n\t\t\t.finally(() => endReload(this.#host));\n\t}\n\n\tasync #run(\n\t\toperation: ChildOperation,\n\t\tconnection: Connection,\n\t\tframe: Extract<Frame, { t: \"prepare\" }>,\n\t): Promise<void> {\n\t\tconst cancelled = (): ChordError =>\n\t\t\tnew ChordError(\"aborted\", \"reload aborted by the server\", { reason: \"aborted\" });\n\t\ttry {\n\t\t\toperation.reload = await beginReload(this.#host, frame.plugins, frame.options, frame.epoch);\n\t\t\tif (operation.cancelled) throw cancelled();\n\t\t\toperation.state = \"preparing\";\n\t\t\tawait operation.reload.prepare();\n\t\t\tif (operation.cancelled) throw cancelled();\n\t\t\toperation.state = \"prepared\";\n\t\t\tconnection.send({ t: \"vote\", reload: frame.reload, report: operation.reload.summary() });\n\t\t} catch (error) {\n\t\t\tif (operation.reload !== undefined) {\n\t\t\t\tawait operation.reload.rollback().catch((cleanup: unknown) => this.#host.report(cleanup));\n\t\t\t\tendReload(this.#host);\n\t\t\t}\n\t\t\tif (this.#operation === operation) this.#operation = undefined;\n\t\t\tif (!operation.cancelled) connection.send({ t: \"vote\", reload: frame.reload, error: toWireError(error) });\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"cluster.js","sourceRoot":"","sources":["../src/cluster.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Connection } from \"./connection.ts\";\nimport { ChordError } from \"./errors.ts\";\nimport type { HostImpl, PluginRef } from \"./host.ts\";\nimport { beginReload, endReload, type Reload, type ReloadOptions, type ReloadReport, reloadError } from \"./reload.ts\";\nimport { type Frame, toWireError } from \"./wire.ts\";\n\n// Cross-host reload, coordinated by the server (the host without a parent):\n// server: prepare itself and send `prepare` to every synced child host; collect votes\n// all ok: the server installs its new code version, sends `commit` to every child, and only then starts what may make\n// new-code-version calls (tasks, listener and registry callbacks). Links are FIFO, so a child commits before it\n// can receive any frame of a root started in the new code version.\n// any failure or missed vote deadline: `abort` everywhere; each host rolls back to where it was.\n// Clients (browsers) are not participants: they see shape/reset pushes, or `upgrade_required`.\n// A child that connects behind the server's code version is fenced and reconciled with the same protocol.\n\nlet reloadSeq = 0;\n\nconst modulesFor = (remote: ReloadOptions[\"remote\"], hostName: string | undefined): string[] => {\n\tlet best: [string, readonly string[]] | undefined;\n\tfor (const entry of Object.entries(remote ?? {})) {\n\t\tif (hostName?.startsWith(entry[0]) && (best === undefined || entry[0].length > best[0].length)) best = entry;\n\t}\n\treturn [...(best?.[1] ?? [])];\n};\n\n/** A vote, or its rejection after `deadline` milliseconds. */\nfunction awaitVote(connection: Connection, id: number, deadline: number): Promise<unknown> {\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tconst vote = new Promise<unknown>((resolve, reject) => {\n\t\tconnection.votes.set(id, { resolve, reject });\n\t\ttimer = setTimeout(() => {\n\t\t\tconnection.votes.delete(id);\n\t\t\treject(new ChordError(\"aborted\", `votes missing after ${deadline} ms`, { reason: \"vote_deadline\" }));\n\t\t}, deadline);\n\t});\n\treturn vote.finally(() => clearTimeout(timer));\n}\n\nexport async function runClusterReload(\n\thost: HostImpl,\n\tplugins: readonly PluginRef[],\n\toptions: ReloadOptions,\n): Promise<ReloadReport> {\n\t// Participants are the children in step now. Fenced children (behind, being reconciled) reconcile to the new code\n\t// version afterwards; a child whose hello arrives while the reload runs is synced or reconciled once it ends\n\t// (`HostImpl.peerHello`).\n\tconst synced = [...host.connections].filter(\n\t\t(connection) =>\n\t\t\tconnection.role === \"downstream\" && connection.peer.kind === \"host\" && connection.open && connection.synced,\n\t);\n\tconst codeVersion = host.peekNextCodeVersion();\n\tconst reload = await beginReload(host, plugins, options, codeVersion);\n\ttry {\n\t\t// Retire first: its `retire` frames reach every child before `prepare` (FIFO), so a child never retires a code\n\t\t// version this host still runs roots of.\n\t\tawait reload.waitForRetirement();\n\t\tconst participants = synced.filter((connection) => connection.open);\n\t\tconst id = ++reloadSeq;\n\t\tconst deadline = options.voteDeadline ?? (options.gateDeadline ?? 5000) + (options.retireDeadline ?? 5000) + 5000;\n\t\tconst votes = participants.map((connection) => {\n\t\t\tconst name = connection.name ?? \"child\";\n\t\t\tconst vote = awaitVote(connection, id, deadline);\n\t\t\tconnection.send({\n\t\t\t\tt: \"prepare\",\n\t\t\t\treload: id,\n\t\t\t\tcodeVersion,\n\t\t\t\tplugins: modulesFor(options.remote, name),\n\t\t\t\toptions: {\n\t\t\t\t\tremove: modulesFor(options.remoteRemove, name),\n\t\t\t\t\tgateDeadline: options.gateDeadline,\n\t\t\t\t\tretireDeadline: options.retireDeadline,\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn vote.then(\n\t\t\t\t(report) => [name, report as ReloadReport | undefined] as const,\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tconst cause = reloadError(error);\n\t\t\t\t\tthrow new ChordError(cause.code, `${name}: ${cause.message}`, { cause, reason: cause.reason });\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t\tlet local = false;\n\t\tconst results = await Promise.allSettled([\n\t\t\treload.prepare().then(() => {\n\t\t\t\tlocal = true;\n\t\t\t}),\n\t\t\t...votes,\n\t\t]);\n\t\tconst failed = results.find((result) => result.status === \"rejected\");\n\t\tif (failed !== undefined) {\n\t\t\tfor (const connection of participants) {\n\t\t\t\tconnection.votes.delete(id);\n\t\t\t\tconnection.send({ t: \"abort\", reload: id });\n\t\t\t}\n\t\t\tif (local) await reload.rollback();\n\t\t\tthrow failed.reason;\n\t\t}\n\t\tconst report = reload.commit(() => {\n\t\t\tfor (const connection of participants) {\n\t\t\t\tconnection.send({ t: \"commit\", reload: id });\n\t\t\t\tconnection.peerCodeVersion = codeVersion;\n\t\t\t}\n\t\t});\n\t\thost.rememberRemoteModules(options.remote, options.remoteRemove);\n\t\tconst children: Record<string, ReloadReport> = {};\n\t\tfor (const result of results.slice(1)) {\n\t\t\tif (result.status !== \"fulfilled\") continue;\n\t\t\tconst [name, child] = result.value as readonly [string, ReloadReport | undefined];\n\t\t\tif (child !== undefined) children[name] = child;\n\t\t}\n\t\treturn { ...report, children };\n\t} finally {\n\t\tendReload(host);\n\t}\n}\n\n/**\n * Brings a child that connected behind this host's code version up to it: a reload of the child's modules (the ones\n * cluster reloads gave its name) to this host's current code version, prepared, voted and committed like a cluster\n * reload. Until then the child is fenced: nothing is routed to it. The child's old code is never relabeled as a newer\n * code version.\n */\nexport async function reconcileChild(host: HostImpl, connection: Connection): Promise<void> {\n\tfor (;;) {\n\t\tif (!connection.open) return;\n\t\t// Not during a reload of this host: the child is not one of its participants, so whatever it would be synced to\n\t\t// now may be superseded by that reload's commit. Recheck once it ended.\n\t\tif (host.reloading) {\n\t\t\tawait host.whenReloadEnded();\n\t\t\tcontinue;\n\t\t}\n\t\tconst codeVersion = host.current.id;\n\t\tif (connection.peerCodeVersion === codeVersion) {\n\t\t\tconnection.markSynced(codeVersion);\n\t\t\thost.announceRetired(connection);\n\t\t\treturn;\n\t\t}\n\t\t// Before `prepare`: the child's prepare first retires its previous code version, which waits for this permission.\n\t\thost.announceRetired(connection);\n\t\tconst id = ++reloadSeq;\n\t\tconst vote = awaitVote(connection, id, 30_000);\n\t\tconnection.send({\n\t\t\tt: \"prepare\",\n\t\t\treload: id,\n\t\t\tcodeVersion,\n\t\t\tplugins: modulesFor(host.remoteModules, connection.name),\n\t\t\toptions: { remove: modulesFor(host.remoteRemoved, connection.name) },\n\t\t});\n\t\tawait vote;\n\t\tif (host.current.id !== codeVersion) {\n\t\t\t// This host moved on meanwhile: abort and try again with the newer code version.\n\t\t\tconnection.send({ t: \"abort\", reload: id });\n\t\t\tcontinue;\n\t\t}\n\t\tconnection.send({ t: \"commit\", reload: id });\n\t\tconnection.peerCodeVersion = codeVersion;\n\t}\n}\n\n/** One prepare the child received, registered before its first await so an abort or disconnect is never lost. */\ninterface ChildOperation {\n\treadonly id: number;\n\treload: Reload | undefined;\n\tstate: \"loading\" | \"preparing\" | \"prepared\";\n\tcancelled: boolean;\n}\n\n/**\n * The child side: prepare and vote, then wait for the server's commit or abort. An abort or a lost parent link can\n * arrive at any point: while loading modules, while preparing (pending opens close themselves when they complete),\n * or after the vote. The operation is unwound once its pending work settles, and the reload slot is freed.\n */\nexport class ChildReloads {\n\treadonly #host: HostImpl;\n\t#operation: ChildOperation | undefined;\n\n\tconstructor(host: HostImpl) {\n\t\tthis.#host = host;\n\t}\n\n\thandle(connection: Connection, frame: Extract<Frame, { t: \"prepare\" | \"commit\" | \"abort\" }>): void {\n\t\tif (frame.t === \"prepare\") {\n\t\t\tif (this.#operation !== undefined) {\n\t\t\t\tconst error = new ChordError(\"unavailable\", \"a reload is already running\", { reason: \"reload_running\" });\n\t\t\t\tconnection.send({ t: \"vote\", reload: frame.reload, error: toWireError(error) });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst operation: ChildOperation = { id: frame.reload, reload: undefined, state: \"loading\", cancelled: false };\n\t\t\tthis.#operation = operation;\n\t\t\tthis.#run(operation, connection, frame).catch((error: unknown) => this.#host.report(error));\n\t\t\treturn;\n\t\t}\n\t\tconst operation = this.#operation;\n\t\tif (operation === undefined || operation.id !== frame.reload) return;\n\t\tif (frame.t === \"abort\") {\n\t\t\tthis.#cancel(operation);\n\t\t\treturn;\n\t\t}\n\t\tif (operation.state !== \"prepared\") return;\n\t\tthis.#operation = undefined;\n\t\ttry {\n\t\t\toperation.reload?.commit();\n\t\t} finally {\n\t\t\tendReload(this.#host);\n\t\t}\n\t}\n\n\t/** The parent link died: nobody will commit, so roll back (now, or once pending work settles). */\n\tparentLost(): void {\n\t\tif (this.#operation !== undefined) this.#cancel(this.#operation);\n\t}\n\n\t#cancel(operation: ChildOperation): void {\n\t\toperation.cancelled = true;\n\t\tif (operation.state !== \"prepared\") {\n\t\t\t// Loading or preparing: make prepare fail now; #run unwinds when it settles.\n\t\t\toperation.reload?.rollback().catch((error: unknown) => this.#host.report(error));\n\t\t\treturn;\n\t\t}\n\t\tthis.#operation = undefined;\n\t\toperation.reload\n\t\t\t?.rollback()\n\t\t\t.catch((error: unknown) => this.#host.report(error))\n\t\t\t.finally(() => endReload(this.#host));\n\t}\n\n\tasync #run(\n\t\toperation: ChildOperation,\n\t\tconnection: Connection,\n\t\tframe: Extract<Frame, { t: \"prepare\" }>,\n\t): Promise<void> {\n\t\tconst cancelled = (): ChordError =>\n\t\t\tnew ChordError(\"aborted\", \"reload aborted by the server\", { reason: \"aborted\" });\n\t\ttry {\n\t\t\toperation.reload = await beginReload(this.#host, frame.plugins, frame.options, frame.codeVersion);\n\t\t\tif (operation.cancelled) throw cancelled();\n\t\t\toperation.state = \"preparing\";\n\t\t\tawait operation.reload.prepare();\n\t\t\tif (operation.cancelled) throw cancelled();\n\t\t\toperation.state = \"prepared\";\n\t\t\tconnection.send({ t: \"vote\", reload: frame.reload, report: operation.reload.summary() });\n\t\t} catch (error) {\n\t\t\tif (operation.reload !== undefined) {\n\t\t\t\tawait operation.reload.rollback().catch((cleanup: unknown) => this.#host.report(cleanup));\n\t\t\t\tendReload(this.#host);\n\t\t\t}\n\t\t\tif (this.#operation === operation) this.#operation = undefined;\n\t\t\tif (!operation.cancelled) connection.send({ t: \"vote\", reload: frame.reload, error: toWireError(error) });\n\t\t}\n\t}\n}\n"]}
@@ -1,82 +1,152 @@
1
+ import { type Encoder } from "./delta/index.ts";
1
2
  import type { HostImpl } from "./host.ts";
2
- import type { Link } from "./link.ts";
3
- import { HandleImpl } from "./record.ts";
4
- import type { RemoteChannel, RemoteHandle, StateSink } from "./remote.ts";
5
- import type { Principal } from "./types.ts";
3
+ import { type Link } from "./link.ts";
4
+ import { RefImpl } from "./object.ts";
5
+ import type { RemoteBinding, RemoteChannel } from "./remote.ts";
6
+ import type { StateEvent } from "./types.ts";
6
7
  import { type Frame, type RootRef } from "./wire.ts";
7
8
  export interface LinkOptions {
8
9
  /** Milliseconds between pings (default 15000). */
9
10
  readonly pingInterval?: number;
10
11
  /** Close the link when nothing arrived for this long (default 45000). Everything held through it is released. */
11
12
  readonly pingTimeout?: number;
13
+ /**
14
+ * Unacknowledged frame bytes (JSON text length) beyond which state frames wait for the peer (default 256 KiB). Only
15
+ * applies when both ends acknowledge frames and the link reports sizes; `Infinity` never holds state back.
16
+ */
17
+ readonly window?: number;
18
+ /**
19
+ * Bytes of state ops that may wait for the peer on this link (default 4 windows). Beyond, the oldest waiting streams
20
+ * are replaced by their current value (a reset), so memory stays bounded however long the peer stalls.
21
+ */
22
+ readonly pendingCap?: number;
23
+ /**
24
+ * The peer speaks another link protocol version (`peer`: undefined if it did not say): the link closes, and should
25
+ * not be reconnected with the same code. A browser reloads its page, for instance.
26
+ */
27
+ readonly onProtocolMismatch?: (versions: {
28
+ readonly local: number;
29
+ readonly peer: number | undefined;
30
+ }) => void;
12
31
  }
13
- export interface AcceptOptions extends LinkOptions {
32
+ type StateFrame = Extract<Frame, {
33
+ t: "state";
34
+ }>;
35
+ /**
36
+ * How a waiting stream recovers when its ops must be dropped: the provider resends the current value as a reset at
37
+ * flush; a relay (which has no value) asks downstream for one.
38
+ */
39
+ type Overflow = {
40
+ readonly resend: () => void;
41
+ } | {
42
+ readonly resync: () => void;
43
+ };
44
+ export interface AcceptOptions<P = unknown> extends LinkOptions {
14
45
  /** The principal of whatever connects, from the app's authenticator. Every request on the link acts as it. */
15
- readonly principal: Principal;
46
+ readonly principal: P;
16
47
  /**
17
- * What the peer is, decided here and never by its `hello`: `client` (default; a browser: no roots, no epochs, not
18
- * a reload participant, not addressable) or `host` (a child host; needs `name`).
48
+ * What the peer is, decided here and never by its `hello`: `client` (default; a browser: no roots, no code versions,
49
+ * not a reload participant, not addressable) or `host` (a child host; needs `name`).
19
50
  */
20
51
  readonly kind?: "host" | "client";
21
52
  /** A child host's name: its hello must match, and it is reachable `at` this name. */
22
53
  readonly name?: string;
23
54
  /** On `invalidatePrincipal`: a new principal keeps the link, `undefined` closes it (default: close). */
24
- readonly restamp?: (principal: Principal) => Principal | undefined;
55
+ restamp?(principal: P): P | undefined;
56
+ /**
57
+ * Calls the peer may have in progress on this link (default: no limit). Further ones never run: they are answered
58
+ * at once with `unavailable` (reason `too_many_calls`), and the link stays open.
59
+ */
60
+ readonly maxCalls?: number;
25
61
  }
26
62
  export interface Peer {
27
63
  readonly kind: "host" | "client";
28
64
  /** Configured (downstream hosts) or announced by the trusted parent (upstream). */
29
65
  readonly name: string | undefined;
30
66
  }
31
- /** A hold the peer made on this host: served locally or relayed to another link. */
32
- type Served = {
67
+ /** A state member's stream to the consumer: its subscription and delta encoder. */
68
+ interface Feed {
69
+ unsubscribe: () => void;
70
+ encoder: Encoder;
71
+ /** Events that arrived while a unit or reset was being built (replayed after it is sent). */
72
+ buffer: StateEvent<unknown>[] | undefined;
73
+ }
74
+ /** A hold the peer made on this host and serves locally. */
75
+ interface ServedLocal {
33
76
  readonly kind: "local";
34
- readonly handle: HandleImpl;
35
- readonly principal: Principal;
36
- readonly feeds: Set<number>;
37
- } | {
77
+ readonly id: number;
78
+ readonly ref: RefImpl;
79
+ readonly principal: unknown;
80
+ /** The client connection it comes from (see `Frame` hold `origin`); undefined for a host's own holds. */
81
+ readonly origin: string | undefined;
82
+ /** The consumer wants state (hold without `state: false`, or `sub`). */
83
+ wantsState: boolean;
84
+ /** The consumer had values before (re-hold): its first unit waits for the window like any other. */
85
+ readonly again: boolean;
86
+ /** A unit was sent. */
87
+ unitSent: boolean;
88
+ /** The members whose snapshot the consumer has, with their streams. */
89
+ readonly feeds: Map<string, Feed>;
90
+ }
91
+ /** A hold the peer made on this host: served locally or relayed to another link. */
92
+ type Served = ServedLocal | {
38
93
  readonly kind: "relay";
39
- readonly relay: RelayHold;
94
+ readonly relay: RelayRef;
40
95
  };
41
96
  type Pending = {
42
97
  readonly resolve: (value: unknown) => void;
43
98
  readonly reject: (error: unknown) => void;
44
99
  };
45
100
  /**
46
- * A hold relayed from an origin link to a downstream link. It owns everything done through it: subscriptions and
47
- * calls queued while the route resolves, and the downstream twins once forwarded. `close` undoes all of it exactly
48
- * once (cancels calls downstream, drops subscriptions, releases the downstream hold, rejects waiters).
101
+ * A hold relayed from an origin link to a downstream link. It owns everything done through it: state and calls queued
102
+ * while the route resolves, and the downstream twins once forwarded. `close` undoes all of it exactly once (cancels
103
+ * calls downstream, drops what waits for the origin, releases the downstream hold, rejects waiters).
49
104
  */
50
- export declare class RelayHold {
105
+ export declare class RelayRef {
51
106
  #private;
52
107
  readonly origin: Connection;
53
108
  readonly frame: Extract<Frame, {
54
109
  t: "hold";
55
110
  }>;
56
- readonly principal: Principal;
57
- readonly client: boolean;
111
+ readonly principal: unknown;
112
+ /** The client connection the hold comes from (forwarded downstream); undefined for a host's own holds. */
113
+ readonly originTag: string | undefined;
58
114
  /** The origin's authorization generation when the hold arrived; a revocation bumps it. */
59
115
  readonly generation: number;
60
116
  down: Connection | undefined;
61
117
  downId: number;
62
118
  closed: boolean;
119
+ /** The origin wants state (forwarded as `state: false`, `sub`, `unsub`). */
120
+ stateWanted: boolean;
121
+ /** The members of the first unit, still to forward past the origin's window. */
122
+ urgent: Set<string> | undefined;
123
+ /** Members whose ops this relay dropped: downstream ops are ignored until their reset arrives. */
124
+ readonly awaiting: Set<string>;
63
125
  readonly calls: Map<number, RelayCall>;
64
- readonly subs: Map<number, {
65
- readonly member: string;
66
- downId: number | undefined;
67
- }>;
68
126
  constructor(origin: Connection, frame: Extract<Frame, {
69
127
  t: "hold";
70
- }>, principal: Principal, client: boolean);
128
+ }>, principal: unknown, originTag: string | undefined);
71
129
  get originId(): number;
130
+ get client(): boolean;
72
131
  /** Still authorized as it was when it arrived. */
73
132
  get current(): boolean;
74
133
  /** The downstream connection once the route resolved; rejects if the relay closes first. */
75
134
  ready(): Promise<Connection>;
76
- /** Forwards the hold (and what queued meanwhile) to `down`. */
135
+ /** Forwards the hold to `down`. */
77
136
  open(down: Connection): void;
78
- subscribe(originSubId: number, member: string): void;
79
- unsubscribe(originSubId: number, forward?: boolean): void;
137
+ /** The origin starts or stops the hold's state. */
138
+ wantState(wanted: boolean): void;
139
+ /**
140
+ * The origin could not keep up and dropped what waited for member `m` (or asked for it again): ask downstream for a
141
+ * reset, and ignore its ops until the reset arrives.
142
+ */
143
+ resync(m: string): void;
144
+ /** A shape from downstream: forwarded at once; the members of the first unit then skip the origin's window. */
145
+ shape(frame: Extract<Frame, {
146
+ t: "shape";
147
+ }>): void;
148
+ /** A state frame from downstream. */
149
+ state(frame: StateFrame): void;
80
150
  /**
81
151
  * Closes the relay. `releaseDown`: the downstream hold is still there (origin released, disconnected, or was
82
152
  * revoked): cancel its calls and release it. `notify`: tell the origin the hold is gone.
@@ -89,15 +159,52 @@ export declare class RelayHold {
89
159
  /** One relayed call: settles once, by result, cancellation or the relay closing; removes both mappings. */
90
160
  export declare class RelayCall {
91
161
  #private;
92
- readonly relay: RelayHold;
162
+ readonly relay: RelayRef;
93
163
  readonly originId: number;
94
164
  readonly downId: number;
95
- constructor(relay: RelayHold, originId: number, downId: number, pending: Pending);
165
+ constructor(relay: RelayRef, originId: number, downId: number, pending: Pending);
96
166
  finish(error: unknown, value?: unknown): void;
97
167
  /** Cancels downstream (when the downstream hold still exists) and settles with `error`. */
98
168
  cancel(error: unknown, forward: boolean): void;
99
169
  }
100
- /** One end of a link on a host: consumer of remote handles, provider for the peer's holds, and relay. */
170
+ /**
171
+ * One end of a link on a host: consumer of remote references, provider for the peer's holds, and relay.
172
+ *
173
+ * State
174
+ * -----
175
+ *
176
+ * A hold implies the state of its variant (unless it says `state: false`). The provider answers with a unit: the shape,
177
+ * then a snapshot of each state member the consumer does not have yet (`shape.state` lists them), then the members'
178
+ * ops and resets. A reload or a variant change sends another unit with the members that are new; members that left the
179
+ * variant stop. The consumer applies a shape once its snapshots are here (`RemoteBinding`).
180
+ *
181
+ * Flow control
182
+ * ------------
183
+ *
184
+ * Problem: state is pushed as fast as it changes, but a peer may read slowly (a phone behind a relay), and a relay may
185
+ * hide that: Cloudflare forwards to browsers without backpressure. Everything sent then queues in front of the next
186
+ * call result. Example: a browser opens three long transcripts (500 KiB of snapshots each) over a 5 Mbit/s path; a
187
+ * result sent next waits 2.4 s, and the snapshot of a transcript the user already left is still sent in full.
188
+ *
189
+ * Solution: the peer acknowledges what it processed (`ack`, a cumulative frame count), and the sender counts the sizes
190
+ * of the frames not yet acknowledged. While they exceed the window, state waits here in slots, flushed in creation
191
+ * order as acknowledgements come:
192
+ * - a member's stream has one slot: ops are appended (encoded batches of one stream may be concatenated, see
193
+ * `encoder`), a snapshot, reset or error replaces it;
194
+ * - a hold's unit has one slot, built lazily from the current values when it is sent, so a newer unit merges into it;
195
+ * while it waits, the members it introduces have no stream yet.
196
+ *
197
+ * The first unit of a hold that is not a re-hold (`again`) is sent at once, past the window: a `get` waits for it, and
198
+ * must not wait behind other holds' state. Results, shapes, gone, reload control and pings are sent at once too: they
199
+ * are bounded by the requests the peer makes. Hence the one ordering exception of a link: while state waits, a result
200
+ * can arrive before state changes made before it. Frames of one stream stay in order.
201
+ *
202
+ * Waiting ops are capped per link (`pendingCap`): beyond, the oldest streams are replaced by their current value (a
203
+ * reset built at flush), or, on a relay, by a reset asked of the provider (`resync`), so memory stays bounded however
204
+ * long the peer stalls. The window bounds what is unacknowledged when a frame is sent, so one frame (a large snapshot)
205
+ * may exceed it. Both hellos must announce `acks`; with an older peer nothing is acknowledged and nothing waits. Links
206
+ * that do not report sizes (IPC) never fill the window.
207
+ */
101
208
  export declare class Connection implements RemoteChannel {
102
209
  #private;
103
210
  readonly host: HostImpl;
@@ -105,53 +212,59 @@ export declare class Connection implements RemoteChannel {
105
212
  /** `upstream`: the link to this host's parent. `downstream`: a link this host accepted. */
106
213
  readonly role: "upstream" | "downstream";
107
214
  readonly peer: Peer;
108
- principal: Principal;
109
- readonly restamp: ((principal: Principal) => Principal | undefined) | undefined;
215
+ /** A client connection's opaque id: holds that come over it (directly or relayed) carry it as their `origin`. */
216
+ readonly originId: string | undefined;
217
+ principal: unknown;
218
+ readonly restamp: ((principal: unknown) => unknown | undefined) | undefined;
110
219
  /** Bumped when the stamped principal is revoked or re-stamped: relays from before are refused. */
111
220
  generation: number;
112
- /** The epoch a downstream host peer runs (from its hello, then from commits). */
113
- peerEpoch: number | undefined;
114
- /** A downstream host peer is usable once it runs this host's current epoch (see `HostImpl.peerHello`). */
221
+ /** The code version a downstream host peer runs (from its hello, then from commits). */
222
+ peerCodeVersion: number | undefined;
223
+ /** A downstream host peer is usable once it runs this host's current code version (see `HostImpl.peerHello`). */
115
224
  synced: boolean;
116
- /** Epochs this child announced while behind this host (fenced): this host never ran them. */
117
- readonly fencedEpochs: Set<number>;
118
- readonly remotes: Map<number, RemoteHandle>;
225
+ /** Code versions this child announced while behind this host (fenced): this host never ran them. */
226
+ readonly fencedCodeVersions: Set<number>;
227
+ readonly remotes: Map<number, RemoteBinding>;
119
228
  readonly calls: Map<number, Pending>;
120
- readonly subs: Map<number, (frame: StateSink) => void>;
121
229
  readonly served: Map<number, Served>;
122
230
  readonly incoming: Map<number, AbortController>;
123
- readonly feeds: Map<number, () => void>;
124
- /** Origin side of relays: the peer's sub ids that are relayed. */
125
- readonly relaySubs: Map<number, RelayHold>;
126
- readonly relayedHolds: Map<number, RelayHold>;
231
+ readonly relayedRefs: Map<number, RelayRef>;
127
232
  readonly relayedCalls: Map<number, RelayCall>;
128
- readonly relayedSubs: Map<number, {
129
- readonly relay: RelayHold;
130
- readonly originSubId: number;
131
- }>;
132
233
  /** Reload votes awaited from this (child) peer. */
133
234
  readonly votes: Map<number, Pending>;
134
235
  constructor(host: HostImpl, link: Link, config: {
135
236
  readonly role: "upstream" | "downstream";
136
- readonly principal: Principal;
237
+ readonly principal: unknown;
137
238
  readonly peer: Peer;
138
- readonly restamp?: (principal: Principal) => Principal | undefined;
239
+ readonly originId?: string;
240
+ readonly restamp?: (principal: unknown) => unknown | undefined;
241
+ readonly maxCalls?: number;
139
242
  } & LinkOptions);
140
243
  get open(): boolean;
141
244
  /** The peer's name: configured for downstream hosts, announced by the parent upstream. */
142
245
  get name(): string | undefined;
143
246
  send(frame: Frame): void;
247
+ /** Sends a state frame, or keeps it waiting (see the class comment). */
248
+ sendState(frame: StateFrame, overflow: Overflow): void;
249
+ /** Forgets what waits for a stream that ended. */
250
+ dropState(hold: number, m: string): void;
251
+ /** Forgets everything that waits for a hold (released, closed, or its state stopped). */
252
+ dropHoldState(hold: number): void;
253
+ /** What waits for the peer: slots and bytes of ops (for tests and diagnostics). */
254
+ get waiting(): {
255
+ readonly slots: number;
256
+ readonly bytes: number;
257
+ };
144
258
  nextId(): number;
145
- /** Resolves once the peer is usable (a host peer runs this host's epoch); rejects if the link closes first. */
259
+ /** Resolves once the peer is usable (a host peer runs this host's code version); rejects if the link closes first. */
146
260
  whenSynced(): Promise<void>;
147
- markSynced(epoch: number): void;
261
+ markSynced(codeVersion: number): void;
148
262
  /** Revokes the stamped principal: relays made under it close at once (also those still resolving a route). */
149
- revoke(next: Principal | undefined): void;
150
- hold(handle: RemoteHandle): number;
263
+ revoke(next: unknown | undefined): void;
264
+ hold(binding: RemoteBinding, again: boolean): number;
151
265
  release(id: number): void;
266
+ wantState(hold: number, wanted: boolean): void;
152
267
  call(hold: number, member: string, args: unknown, root: RootRef | undefined, signal: AbortSignal): Promise<unknown>;
153
- sub(hold: number, member: string, sink: (frame: StateSink) => void): number;
154
- unsub(id: number): void;
155
268
  }
156
269
  export {};
157
270
  //# sourceMappingURL=connection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}