@catalyst-cloud/sdk 0.6.0 → 0.8.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 (74) hide show
  1. package/README.md +92 -0
  2. package/dist/browser.d.ts +9 -0
  3. package/dist/browser.d.ts.map +1 -0
  4. package/dist/browser.js +24 -0
  5. package/dist/browser.js.map +1 -0
  6. package/dist/live-sync-client.d.ts +203 -13
  7. package/dist/live-sync-client.d.ts.map +1 -1
  8. package/dist/live-sync-client.js +605 -50
  9. package/dist/live-sync-client.js.map +1 -1
  10. package/dist/replica/browser/apply.d.ts +29 -0
  11. package/dist/replica/browser/apply.d.ts.map +1 -0
  12. package/dist/replica/browser/apply.js +59 -0
  13. package/dist/replica/browser/apply.js.map +1 -0
  14. package/dist/replica/browser/browser-lock.d.ts +25 -0
  15. package/dist/replica/browser/browser-lock.d.ts.map +1 -0
  16. package/dist/replica/browser/browser-lock.js +91 -0
  17. package/dist/replica/browser/browser-lock.js.map +1 -0
  18. package/dist/replica/browser/browser-replica.d.ts +237 -0
  19. package/dist/replica/browser/browser-replica.d.ts.map +1 -0
  20. package/dist/replica/browser/browser-replica.js +952 -0
  21. package/dist/replica/browser/browser-replica.js.map +1 -0
  22. package/dist/replica/browser/db.worker.d.ts +2 -0
  23. package/dist/replica/browser/db.worker.d.ts.map +1 -0
  24. package/dist/replica/browser/db.worker.js +40 -0
  25. package/dist/replica/browser/db.worker.js.map +1 -0
  26. package/dist/replica/browser/delta-queue.d.ts +187 -0
  27. package/dist/replica/browser/delta-queue.d.ts.map +1 -0
  28. package/dist/replica/browser/delta-queue.js +328 -0
  29. package/dist/replica/browser/delta-queue.js.map +1 -0
  30. package/dist/replica/browser/ports.d.ts +39 -0
  31. package/dist/replica/browser/ports.d.ts.map +1 -0
  32. package/dist/replica/browser/ports.js +144 -0
  33. package/dist/replica/browser/ports.js.map +1 -0
  34. package/dist/replica/browser/protocol.d.ts +129 -0
  35. package/dist/replica/browser/protocol.d.ts.map +1 -0
  36. package/dist/replica/browser/protocol.js +12 -0
  37. package/dist/replica/browser/protocol.js.map +1 -0
  38. package/dist/replica/browser/seed-read-gate.d.ts +13 -0
  39. package/dist/replica/browser/seed-read-gate.d.ts.map +1 -0
  40. package/dist/replica/browser/seed-read-gate.js +36 -0
  41. package/dist/replica/browser/seed-read-gate.js.map +1 -0
  42. package/dist/replica/browser/seed-session.d.ts +23 -0
  43. package/dist/replica/browser/seed-session.d.ts.map +1 -0
  44. package/dist/replica/browser/seed-session.js +57 -0
  45. package/dist/replica/browser/seed-session.js.map +1 -0
  46. package/dist/replica/browser/snapshot-stream.d.ts +24 -0
  47. package/dist/replica/browser/snapshot-stream.d.ts.map +1 -0
  48. package/dist/replica/browser/snapshot-stream.js +113 -0
  49. package/dist/replica/browser/snapshot-stream.js.map +1 -0
  50. package/dist/replica/browser/sqlite-db.d.ts +9 -0
  51. package/dist/replica/browser/sqlite-db.d.ts.map +1 -0
  52. package/dist/replica/browser/sqlite-db.js +28 -0
  53. package/dist/replica/browser/sqlite-db.js.map +1 -0
  54. package/dist/replica/browser/support.d.ts +2 -0
  55. package/dist/replica/browser/support.d.ts.map +1 -0
  56. package/dist/replica/browser/support.js +30 -0
  57. package/dist/replica/browser/support.js.map +1 -0
  58. package/dist/replica/browser/validate.d.ts +17 -0
  59. package/dist/replica/browser/validate.d.ts.map +1 -0
  60. package/dist/replica/browser/validate.js +47 -0
  61. package/dist/replica/browser/validate.js.map +1 -0
  62. package/dist/replica/browser/worker-core.d.ts +10 -0
  63. package/dist/replica/browser/worker-core.d.ts.map +1 -0
  64. package/dist/replica/browser/worker-core.js +181 -0
  65. package/dist/replica/browser/worker-core.js.map +1 -0
  66. package/dist/replica/catalyst-replica.d.ts +34 -10
  67. package/dist/replica/catalyst-replica.d.ts.map +1 -1
  68. package/dist/replica/catalyst-replica.js +195 -83
  69. package/dist/replica/catalyst-replica.js.map +1 -1
  70. package/dist/replica/migration-shape.d.ts +11 -0
  71. package/dist/replica/migration-shape.d.ts.map +1 -0
  72. package/dist/replica/migration-shape.js +25 -0
  73. package/dist/replica/migration-shape.js.map +1 -0
  74. package/package.json +16 -3
package/README.md CHANGED
@@ -127,6 +127,98 @@ void client.start(); // never await in the browser
127
127
 
128
128
  Requires a platform `WebSocket` (browser, Bun, or Node ≥22). On older Node, inject a `wsFactory` that wraps the [`ws`](https://www.npmjs.com/package/ws) package.
129
129
 
130
+ ### Browser — managed OPFS replica (`/browser`)
131
+
132
+ `BrowserReplica` is the browser twin of `/node`'s `CatalystReplica`: an OPFS-persisted SQLite replica
133
+ in a dedicated Web Worker, seeded from `/snapshot` in bounded streamed batches, kept live off the same
134
+ change feed, and read through the same `@catalyst-cloud/read-model` views — no hand-written worker,
135
+ apply, or seeding code in your app.
136
+
137
+ ```ts
138
+ import {
139
+ BrowserReplica,
140
+ isBrowserReplicaSupported,
141
+ type ReplicaStatus,
142
+ } from "@catalyst-cloud/sdk/browser";
143
+
144
+ let status: ReplicaStatus = "loading";
145
+
146
+ if (isBrowserReplicaSupported()) {
147
+ const replica = new BrowserReplica(
148
+ {
149
+ onChanged: () => void refreshList(), // after the seed and after every applied delta drain
150
+ onStatus: (s) => {
151
+ status = s; // "loading" | "live" | "reconnecting" | "error" | "secondary" | …
152
+ setBadge(s);
153
+ },
154
+ },
155
+ {
156
+ baseUrl: "/api/v1", // same-origin, cookie-authed; accountId optional
157
+ // REQUIRED. The OPFS database is shared by every replica on the origin and a warm cursor skips
158
+ // the snapshot, so without a fence a change of signed-in user serves the PREVIOUS user's rows.
159
+ // Pass a stable per-user id from your session — e.g. the WorkOS `user.id`. It never leaves the
160
+ // browser; it is only compared against the value stamped in the local DB, and a mismatch wipes
161
+ // the replica and forces a re-seed.
162
+ identity: session.user.id,
163
+ },
164
+ );
165
+ // AWAIT it. start() suspends on the Web Lock before the worker exists, so a query issued against a
166
+ // not-yet-started replica rejects with "replica client closed".
167
+ await replica.start(); // resolves once seeded — or immediately, with status "secondary"
168
+
169
+ // Another tab already owns the origin's replica. That is a normal outcome, not an error: this tab
170
+ // should read via its usual fetch path and leave the local DB alone.
171
+ if (status !== "secondary") {
172
+ const rows = await replica.queryIssues(); // read-model IssueView[], served locally
173
+ }
174
+ // replica.close() on teardown — cooperatively releases the OPFS handles, then terminates the worker
175
+ }
176
+ ```
177
+
178
+ `status` above is whatever your `onStatus` handler last recorded. `start()` REJECTS if the boot fails
179
+ (bad origin, missing worker chunk, OPFS unavailable) — it does not resolve into a broken state, so a
180
+ `try`/`catch` around it is where you surface the error to the user.
181
+
182
+ Built in, because browsers need them:
183
+
184
+ - **Single-owner election** (Web Locks): OPFS SAHPool is single-connection-per-origin, so exactly one
185
+ tab boots the replica; every other tab gets status `"secondary"` (a clean state, not an error) and
186
+ should read via its normal fetch path.
187
+ - **Backpressure**: live deltas are coalesced into batched, single-flight applies with a bounded
188
+ buffer; a backlog too deep to replay escalates to a fresh snapshot instead of growing.
189
+
190
+ **Peer dependency**: install [`@sqlite.org/sqlite-wasm`](https://www.npmjs.com/package/@sqlite.org/sqlite-wasm)
191
+ yourself — the SDK never bundles the wasm.
192
+
193
+ **Bundlers**: the worker is created with `new Worker(new URL("./db.worker.js", import.meta.url),
194
+ { type: "module" })`, which Vite, webpack 5, and Rollup detect statically and split into its own chunk
195
+ (nothing wasm-related touches your main bundle; `/node` consumers never see it at all). Notes:
196
+
197
+ - **Vite**: works out of the box in `build`. In dev, if pre-bundling interferes with the worker URL,
198
+ add `optimizeDeps: { exclude: ["@catalyst-cloud/sdk"] }`.
199
+ - **webpack 5 / Rollup**: the `new Worker(new URL(...))` syntax is supported natively (Rollup needs
200
+ worker support in your config, e.g. `@surma/rollup-plugin-off-main-thread` or equivalent).
201
+ - **Exotic bundlers**: pass `createWorker` in `BrowserReplicaOptions` and construct the worker
202
+ however your toolchain requires. The worker module is published at the dedicated subpath
203
+ **`@catalyst-cloud/sdk/browser/db-worker`** — that specifier is the supported entry point:
204
+
205
+ ```ts
206
+ // Vite
207
+ import DbWorker from "@catalyst-cloud/sdk/browser/db-worker?worker";
208
+ createWorker: () => new DbWorker();
209
+
210
+ // webpack 5 / anything that resolves a bare specifier to a URL
211
+ createWorker: () =>
212
+ new Worker(
213
+ new URL("@catalyst-cloud/sdk/browser/db-worker", import.meta.url),
214
+ { type: "module" },
215
+ );
216
+ ```
217
+
218
+ The worker is a **side-effect module** (it registers a message handler and exports nothing), so it
219
+ is listed in the package's `sideEffects` array — do not configure your bundler to tree-shake it, or
220
+ it will load and register nothing and every replica call will hang.
221
+
130
222
  ## API
131
223
 
132
224
  | Export | What it is |
@@ -0,0 +1,9 @@
1
+ export { BrowserReplica, streamSeedIntoWorker, type BrowserReplicaOptions, type ReplicaHandlers, type ReplicaStatus, } from "./replica/browser/browser-replica.js";
2
+ export { isBrowserReplicaSupported } from "./replica/browser/support.js";
3
+ export { acquireReplicaLock, type ReplicaLockHandle, type ReplicaLockOptions, } from "./replica/browser/browser-lock.js";
4
+ export { DeltaQueue, MAX_APPLY_BATCH_ROWS, MAX_INBOX_DEPTH, type SeqChange, type DeltaQueueOptions, } from "./replica/browser/delta-queue.js";
5
+ export { streamSnapshotBatches, SEED_BATCH_ROWS } from "./replica/browser/snapshot-stream.js";
6
+ export type { WireChange, ReplicaRequest, ReplicaResponse, Envelope, ResultMap, ApplyChangesResult, } from "./replica/browser/protocol.js";
7
+ export { LiveSyncClient, type AuthStrategy, type LiveSyncStatus, type LogLevel, type WebSocketLike, type WebSocketFactory, } from "./live-sync-client.js";
8
+ export { ENTITY_NAMES, CHANGE_OPS, type AccountId, type EntityName, type ChangeOp, type ChangeFrame, } from "./types.js";
9
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAgBA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAEzE,OAAO,EACL,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,eAAe,EACf,KAAK,SAAS,EACd,KAAK,iBAAiB,GACvB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAE9F,YAAY,EACV,UAAU,EACV,cAAc,EACd,eAAe,EACf,QAAQ,EACR,SAAS,EACT,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EACL,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,YAAY,EACZ,UAAU,EACV,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,24 @@
1
+ // @catalyst-cloud/sdk/browser — the managed replica for the browser (CTC-114, milestone 2 of the
2
+ // managed-replica roadmap; ADR-0002).
3
+ //
4
+ // `BrowserReplica` is the browser twin of `/node`'s CatalystReplica behind ONE import: claim
5
+ // single-ownership of the origin's replica (Web Locks — a losing tab degrades to "secondary", never a
6
+ // red error), open + migrate an OPFS SAHPool SQLite DB inside a dedicated Worker, stream-seed
7
+ // /snapshot in bounded batches, subscribe to the live change feed (the SDK's LiveSyncClient) through a
8
+ // coalescing, depth-bounded delta queue, and serve the @catalyst-cloud/read-model `build*View`
9
+ // queries over it — the "same query, four runtimes" proof, in the browser.
10
+ //
11
+ // BUNDLER CONTRACT: the worker is reached via `new Worker(new URL("./db.worker.js",
12
+ // import.meta.url), { type: "module" })`, which Vite, webpack 5 and Rollup detect statically and emit
13
+ // as a separate chunk; `@sqlite.org/sqlite-wasm` is a PEER dependency resolved by the consumer inside
14
+ // that chunk. Import this subpath ONLY from browser code — the root ("@catalyst-cloud/sdk") stays the
15
+ // transport-only isomorphic surface, and '/node' never pulls any of this into a node bundle.
16
+ export { BrowserReplica, streamSeedIntoWorker, } from "./replica/browser/browser-replica.js";
17
+ export { isBrowserReplicaSupported } from "./replica/browser/support.js";
18
+ export { acquireReplicaLock, } from "./replica/browser/browser-lock.js";
19
+ export { DeltaQueue, MAX_APPLY_BATCH_ROWS, MAX_INBOX_DEPTH, } from "./replica/browser/delta-queue.js";
20
+ export { streamSnapshotBatches, SEED_BATCH_ROWS } from "./replica/browser/snapshot-stream.js";
21
+ // Re-export the transport surface so a consumer can stay on one import.
22
+ export { LiveSyncClient, } from "./live-sync-client.js";
23
+ export { ENTITY_NAMES, CHANGE_OPS, } from "./types.js";
24
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,sCAAsC;AACtC,EAAE;AACF,6FAA6F;AAC7F,sGAAsG;AACtG,8FAA8F;AAC9F,uGAAuG;AACvG,+FAA+F;AAC/F,2EAA2E;AAC3E,EAAE;AACF,oFAAoF;AACpF,sGAAsG;AACtG,sGAAsG;AACtG,sGAAsG;AACtG,6FAA6F;AAE7F,OAAO,EACL,cAAc,EACd,oBAAoB,GAIrB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAEzE,OAAO,EACL,kBAAkB,GAGnB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,eAAe,GAGhB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAW9F,wEAAwE;AACxE,OAAO,EACL,cAAc,GAMf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,YAAY,EACZ,UAAU,GAKX,MAAM,YAAY,CAAC"}
@@ -45,8 +45,20 @@ export interface LiveSyncClientOptions {
45
45
  * verbatim (path-preserving). A trailing slash is trimmed.
46
46
  */
47
47
  baseUrl: string;
48
- /** The tenant id = the mirror's name; sent as `?account=` on the connect URL. */
49
- accountId: string;
48
+ /**
49
+ * The tenant id = the mirror's name; sent as `?account=` on the connect URL.
50
+ *
51
+ * OPTIONAL, and omitting it is the browser default: the OPEN read plane scopes a cookie-authed
52
+ * connection to the session user's own tenant, and an explicit account is the tenant-SWITCHER path.
53
+ * When absent the parameter is omitted entirely rather than serialized as `?account=` — an empty
54
+ * value is not a mirror name, and freezing it into the wire contract would leave the one nearby
55
+ * server-side fallback that a bare empty value can reach (`adminAccountScope`'s `|| "tenant-0"`)
56
+ * cross-tenant-shaped.
57
+ *
58
+ * REQUIRED for `auth: {kind:"token"}` — a host has no session to fall back to, so the constructor
59
+ * throws rather than letting it fail later as an opaque server 401.
60
+ */
61
+ accountId?: string;
50
62
  /**
51
63
  * The connect route. Default "/connect"; the service dual-serves it at "/api/v1/connect" too, so a
52
64
  * path-prefixed `baseUrl` ("…/api/v1") with the default "/connect" resolves to "…/api/v1/connect".
@@ -58,9 +70,26 @@ export interface LiveSyncClientOptions {
58
70
  * Re-seed the consumer's store from a full snapshot and resolve to the FRESH cursor. Called on a
59
71
  * `{type:"resync"}` underflow frame and (optionally) before the first connect. The host pulls
60
72
  * /snapshot into bun:sqlite; the browser re-runs its OPFS seed(). The client closes the socket
61
- * before calling this so no live frame interleaves with the seed.
73
+ * before calling this so no live frame interleaves with the seed. The await is bounded by
74
+ * {@link reseedTimeoutMs} (CTC-281) — a hanging reseed is abandoned (its late settle discarded)
75
+ * and the client re-enters the backoff path, so this callback can never wedge the transport; still,
76
+ * bound your own I/O (as the replica's seedFromSnapshot does) so a dead fetch fails fast, not at
77
+ * the backstop.
78
+ *
79
+ * `signal` ABORTS when the transport gives up on this attempt — the {@link reseedTimeoutMs}
80
+ * deadline expiring, or `stop()` (CTC-114 review round 10). Honour it: the transport considers the
81
+ * attempt over the moment it fires, and RECONNECTS. A callback that keeps writing after that is a
82
+ * second writer racing the socket the transport just reopened — the browser replica's concrete
83
+ * failure was frames delivered past the abandoned seed's cursor being dropped by its paused queue,
84
+ * after which a late seed completion left the socket advanced over a hole that later deltas sealed
85
+ * permanently.
86
+ *
87
+ * This is why "abandon" alone was not enough. Two layers bounding one operation with NO
88
+ * cancellation link between them is the defect; the signal is the link. Optional parameter, so
89
+ * existing zero-arg callbacks still typecheck — but a consumer that ignores it keeps the old
90
+ * two-writer hazard.
62
91
  */
63
- reseed: () => Promise<number>;
92
+ reseed: (signal?: AbortSignal) => Promise<number>;
64
93
  /**
65
94
  * Read the consumer's durable cursor (the last applied feed seq), or null/undefined if it has
66
95
  * never seeded. Drives the `{type:"sync", after}` catch-up request. Return `null` to send
@@ -93,6 +122,37 @@ export interface LiveSyncClientOptions {
93
122
  * socket half-open and force-reconnecting through the normal backoff path. Default `15_000`.
94
123
  */
95
124
  pongTimeoutMs?: number;
125
+ /**
126
+ * Connect/open deadline (CTC-281): how long (ms) after constructing a socket to wait for `onopen`
127
+ * before treating the attempt as failed (tear the socket down, status "reconnecting", backoff
128
+ * reconnect). Without it, a TCP-connect or HTTP-upgrade stall that never fires open/close/error
129
+ * (undici sets no upgrade deadline; injected impls are trusted blindly) wedges the client in
130
+ * "connecting" with ZERO pending timers — restart-only. Default `20_000`; `0` disables.
131
+ */
132
+ openTimeoutMs?: number;
133
+ /**
134
+ * Re-seed deadline (CTC-281): how long (ms) to wait for the injected {@link reseed} callback to
135
+ * settle before abandoning the attempt (status "reconnecting", backoff reconnect; the abandoned
136
+ * reseed's late settle is discarded). While resyncing the client holds NO socket and suppresses
137
+ * scheduleReconnect, so an unbounded reseed hang was a zero-timer restart-only wedge — the exact
138
+ * ticket-ask-3 state. A TOTAL-duration backstop, deliberately generous: the replica's
139
+ * seedFromSnapshot already fails fast on a dead stream via its own IDLE abort
140
+ * (`snapshotIdleTimeoutMs`); this bound exists for reseed impls with no bound of their own (e.g. a
141
+ * browser OPFS seed over a default fetch). Raise it if a legitimate full seed can stream longer.
142
+ * Default `600_000` (10 min); `0` disables.
143
+ */
144
+ reseedTimeoutMs?: number;
145
+ /**
146
+ * How long a CANCELLED reseed gets to unwind before the transport settles and reconnects anyway.
147
+ * Default 250ms; the value must cover the consumer's OWN cleanup bound (CTC-114 review round 14).
148
+ *
149
+ * Reconnecting before the consumer has unwound is not merely early: its store may still be latched,
150
+ * so replayed frames are refused while this client's `deliveredSeq` advances over them — and the
151
+ * next frame it does accept carries the durable cursor past the gap, permanently. The transport
152
+ * cannot know how long a given consumer takes to unwind, so the consumer sets this. The browser
153
+ * replica raises it to cover its worker-RPC deadline, since its cleanup is a `seedAbort` RPC.
154
+ */
155
+ cancelCleanupGraceMs?: number;
96
156
  /**
97
157
  * Gap detection (CTL-1402): how long (ms) to wait for a `{type:"sync"}` gap re-request to finish
98
158
  * redelivering the detected hole before retrying (or, once {@link gapRetryLimit} re-requests have
@@ -134,7 +194,7 @@ export declare function stripTrailingSlashes(s: string): string;
134
194
  export declare function buildConnectUrl(opts: {
135
195
  baseUrl: string;
136
196
  connectPath: string;
137
- accountId: string;
197
+ accountId?: string;
138
198
  auth: AuthStrategy;
139
199
  }): string;
140
200
  export declare class LiveSyncClient {
@@ -151,6 +211,9 @@ export declare class LiveSyncClient {
151
211
  private readonly maxBackoffMs;
152
212
  private readonly pingIntervalMs;
153
213
  private readonly pongTimeoutMs;
214
+ private readonly openTimeoutMs;
215
+ private readonly reseedTimeoutMs;
216
+ private readonly cancelCleanupGraceMs;
154
217
  private readonly gapTimeoutMs;
155
218
  private readonly gapRetryLimit;
156
219
  private readonly wsFactory;
@@ -158,6 +221,36 @@ export declare class LiveSyncClient {
158
221
  private readonly telemetryConfig;
159
222
  private ws;
160
223
  private stopped;
224
+ /**
225
+ * Has start() been entered? `stopped` alone cannot answer this — it is false BEFORE the first
226
+ * start() as well as during a run, so every "am I running?" guard read true on a client that had
227
+ * never booted. Only the public `requestResync()` can reach that window (CTC-114 review round 5):
228
+ * it would reseed and open a socket with no lifecycle deferred and no telemetry resolved, and the
229
+ * later real start() would then openSocket() again — overwriting `this.ws`, so the first socket
230
+ * kept delivering duplicate frames and could no longer be closed through the stored reference.
231
+ */
232
+ private started;
233
+ /** The in-flight boot task, or null once it settles — `requestResync()` serializes behind it. */
234
+ private bootTask;
235
+ /** Settles an in-flight `boundedReseed` wrapper on stop(), so an awaited resync cannot hang. */
236
+ private abandonReseed;
237
+ /**
238
+ * The in-flight resync, so a concurrent caller AWAITS it instead of being handed an
239
+ * already-resolved promise and acting on a store still being rebuilt (round 10).
240
+ */
241
+ private activeResync;
242
+ /** Did the boot this request waited on perform a COLD re-seed? Only then may it be absorbed. */
243
+ private bootColdSeeded;
244
+ /**
245
+ * Did the last boot REJECT? Latched until the next `start()` (CTC-114 review round 9).
246
+ *
247
+ * Round 8 read the failure from the awaited `bootTask`, but that handle is nulled once the boot
248
+ * settles — so a `requestResync()` arriving after that microtask found no record of the failure,
249
+ * with `started` still true and `stopped` still false, and sailed past the guard into a reseed that
250
+ * could open a live socket under an application already told startup had failed. The outcome has to
251
+ * outlive the handle.
252
+ */
253
+ private bootFailed;
161
254
  private resyncing;
162
255
  private backoff;
163
256
  private reconnectTimer;
@@ -191,11 +284,36 @@ export declare class LiveSyncClient {
191
284
  private pingSentAt;
192
285
  /** Client-lifetime: consecutive opened-then-never-ponged connections. Reset to 0 by ANY pong. */
193
286
  private probeFailures;
194
- /** Client-lifetime: after PROBE_FAILURE_LIMIT never-ponged connections we stop pinging for good
195
- * (an old server without auto-pong), degrading to close/error-only detection. */
196
- private watchdogDisabled;
287
+ /** Client-lifetime until a pong: after PROBE_FAILURE_LIMIT never-ponged connections the watchdog
288
+ * DEGRADES to a {@link DEGRADED_PROBE_MULTIPLIER}x-slower re-probe (an old server without auto-pong)
289
+ * — it never turns off outright, so detection is never a restart-only casualty (CTC-281). Only
290
+ * reachable while pong capability is UNPROVEN ({@link pongEverObserved}); the first pong clears it. */
291
+ private watchdogDegraded;
292
+ /** Client-lifetime pong latch (CTC-281): has ANY connection EVER answered a ping? Once true, the
293
+ * server's auto-pong capability is PROVEN for good — a later never-ponged connection is a liveness
294
+ * failure (the incident's open-but-silent socket), never feature-detect evidence, so the watchdog
295
+ * can no longer even degrade itself. PER-PROCESS by design — which is exactly why the degrade must
296
+ * be soft (see {@link DEGRADED_PROBE_MULTIPLIER}): a restart mid-incident resets this latch. */
297
+ private pongEverObserved;
197
298
  private pingTimer;
198
299
  private pongDeadline;
300
+ /** Per-CONNECTION connect/open deadline (CTC-281): armed when the socket is constructed, cleared on
301
+ * open/close/teardown. The only timer pending between openSocket() and onopen — the guarantee that
302
+ * a never-firing ws impl cannot leave the client wedged in "connecting" with nothing scheduled. */
303
+ private connectTimer;
304
+ /** Per-CONNECTION onerror→onclose fallback (CTC-281): armed by onerror, fires forceReconnect once
305
+ * if the impl never follows error with close (undici #3697/#3546). Cleared on open/close/teardown. */
306
+ private errorFallbackTimer;
307
+ /** Per-CONNECTION: has THIS socket fired onopen? The connect-deadline's late-timer guard (a
308
+ * throttled background tab can fire the deadline after onopen already ran and cleared it). */
309
+ private socketOpened;
310
+ /** The pending reseed deadline (CTC-281) — the timer that makes "resyncing" (no socket, reconnect
311
+ * suppressed) a bounded state instead of a restart-only wedge. Cleared when the reseed settles in
312
+ * time and by stop() (ask 4: stop() leaves NOTHING pending). At most one reseed is ever in flight:
313
+ * `resyncing` guards the resync path, and the boot cold seed SETS that same flag for its duration.
314
+ * (It used to rely on "the boot seed runs before any socket exists" — true only while a resync
315
+ * needed a server frame. The public `requestResync()` added in 0.8.0 needs no socket.) */
316
+ private reseedTimer;
199
317
  constructor(opts: LiveSyncClientOptions);
200
318
  /**
201
319
  * Start the client: seed first if the consumer has no cursor, then open the live socket and keep it
@@ -208,6 +326,13 @@ export declare class LiveSyncClient {
208
326
  stop(): void;
209
327
  /** The ws(s):// URL this client opens, for diagnostics/tests. Re-derived from the options. */
210
328
  connectUrl(): string;
329
+ /**
330
+ * The tenant label for telemetry. Attributes are `Record<string, string>`, and an empty string reads
331
+ * as a MISSING attribute in Loki/Tempo — which silently merges every session-scoped browser client
332
+ * into one unlabelled bucket. `"session"` names the case instead: this client is scoped to whatever
333
+ * tenant the cookie resolves to.
334
+ */
335
+ private get tenantAttr();
211
336
  private setStatus;
212
337
  private openSocket;
213
338
  /** End the in-flight connect span exactly once (idempotent — nulls the handle). */
@@ -263,6 +388,45 @@ export declare class LiveSyncClient {
263
388
  /** Drop all gap state (pending hole + timer) — on (re)open and on the resync/re-seed path, both of
264
389
  * which re-request/rebuild from the durable cursor and so supersede any pending re-request. */
265
390
  private clearGapState;
391
+ private clearReseedTimer;
392
+ /**
393
+ * Run the injected reseed() bounded by {@link LiveSyncClientOptions.reseedTimeoutMs} (CTC-281).
394
+ * The injected callback is a trust boundary like the ws impl: while it runs there is NO socket and
395
+ * scheduleReconnect is suppressed, so an unbounded await here was the last zero-timer wedge — the
396
+ * deadline below is the pending timer that upholds the header invariant for the "resyncing" state.
397
+ * On timeout the attempt is both CANCELLED and abandoned (CTC-114 review round 10). It used to be
398
+ * abandoned only, justified as "the callback owns its own I/O bounds" — but the callback owning
399
+ * bounds is exactly what makes a SECOND, independent deadline here dangerous. The browser seed is
400
+ * bounded by network idleness and by per-RPC worker deadlines, both of which a legitimately slow
401
+ * ~100 MB snapshot satisfies indefinitely; this total deadline could therefore fire on a seed that
402
+ * was making honest progress, whereupon the transport reconnected while the callback kept writing.
403
+ * Frames past the abandoned seed's cursor were then accepted by the socket and discarded by the
404
+ * replica's paused queue, and a late seed completion left the socket advanced over a hole that
405
+ * later deltas sealed for good.
406
+ *
407
+ * So the deadline now fires an AbortSignal FIRST and rejects second: whoever is told the attempt is
408
+ * over is also told to stop. A late settle is still discarded via the `settled` latch, and a late
409
+ * REJECTION is still swallowed so it can never surface as an unhandled rejection.
410
+ */
411
+ private boundedReseed;
412
+ /**
413
+ * Ask the client to drop the socket, re-seed, and reconnect from the fresh cursor — the same path a
414
+ * server `{type:"resync"}` frame drives, exposed for a consumer that discovers ON ITS OWN SIDE that
415
+ * its store can no longer be caught up by deltas.
416
+ *
417
+ * The browser replica is the motivating caller: when its delta queue overflows (or its applies keep
418
+ * rejecting) the buffered frames are dropped, so the transport's notion of what has been delivered is
419
+ * now ahead of what the store actually holds. Re-seeding through here — rather than calling the
420
+ * `reseed` callback directly — is what makes that safe: this CLOSES THE SOCKET FIRST, so no live
421
+ * frame interleaves with the snapshot and lands in the window that is in neither the snapshot nor the
422
+ * store.
423
+ *
424
+ * Delegates to the existing resync path in full — same `resyncing` re-entrancy guard, same
425
+ * `boundedReseed` deadline, same span, same failure→backoff behaviour. NEVER rejects: a failed
426
+ * re-seed is already handled internally by re-entering the reconnect path, and this is called from
427
+ * event handlers and `void` contexts where a rejection would surface as an unhandled promise.
428
+ */
429
+ requestResync(): Promise<void>;
266
430
  /**
267
431
  * Cursor underflow: the deltas we need were evicted from the service's retained change buffer. Close the socket
268
432
  * (so no live frame interleaves with the re-seed), re-seed via the injected callback, then reconnect
@@ -270,6 +434,21 @@ export declare class LiveSyncClient {
270
434
  * frame and suppresses scheduleReconnect for the duration so we reopen exactly once.
271
435
  */
272
436
  private handleResync;
437
+ /**
438
+ * The resync body. Never call directly — `handleResync()` owns the in-flight handle.
439
+ *
440
+ * TWO FLAGS, ONE FACT — documented rather than consolidated here, deliberately. `resyncing` and
441
+ * `activeResync` both mean "a re-seed is in flight", and they can disagree: the boot path sets
442
+ * `resyncing` directly (so a resync cannot race startup) without ever creating an `activeResync`
443
+ * handle. In that window a call landing here would hit the guard below and resolve silently, which
444
+ * is the very shape round 10 fixed for the live path.
445
+ *
446
+ * It is NOT reachable today, and both reasons are load-bearing: `requestResync()` serialises behind
447
+ * `bootTask` before it can get here, and the server-frame path needs a socket, which does not exist
448
+ * until the boot opens one. Consolidating the two into a single handle is the right fix and belongs
449
+ * with the wider lifecycle rework — not in a release candidate at round eleven.
450
+ */
451
+ private runResync;
273
452
  /** Epoch ms of the last inbound frame (change, pong, or malformed) — null before the first frame.
274
453
  * Any inbound bytes prove the socket is alive; the catalyst daemon's stall classifier reads this to
275
454
  * tell a quiet feed from a half-open socket (the per-frame timestamp it previously lacked). */
@@ -284,8 +463,10 @@ export declare class LiveSyncClient {
284
463
  /** Any inbound frame: stamp liveness, cancel a pending pong deadline (it was answered), and postpone
285
464
  * the next ping so a busy stream never sends one. Runs synchronously in onmessage before parsing. */
286
465
  private onInboundFrame;
287
- /** (Re)arm the idle-ping timer. No-op when the watchdog is disabled/off or there is no live socket,
288
- * so it is safe to call on every frame. A setTimeout chain (not setInterval): each frame resets it. */
466
+ /** (Re)arm the idle-ping timer. No-op when the watchdog is off or there is no live socket, so it is
467
+ * safe to call on every frame. A setTimeout chain (not setInterval): each frame resets it. A
468
+ * DEGRADED watchdog still arms — at {@link DEGRADED_PROBE_MULTIPLIER}x the interval — so detection
469
+ * is never permanently off (CTC-281): every live socket always has a probe pending. */
289
470
  private armPing;
290
471
  /** The feed has been idle for a full interval: send one liveness ping and start the pong deadline. A
291
472
  * synchronous send throw means the socket is already dead — treat it as an unanswered probe now. */
@@ -295,9 +476,16 @@ export declare class LiveSyncClient {
295
476
  * is proven — re-arm and move on (detection latency grows; correctness holds). Otherwise: half-open. */
296
477
  private onPongDeadline;
297
478
  /** A ping went unanswered (deadline elapsed or the send threw). If this connection had already proven
298
- * pong capability it is a genuine liveness timeout; otherwise it counts toward the feature-detect
299
- * after PROBE_FAILURE_LIMIT never-ponged connections the watchdog disables itself for good (an old
300
- * server without auto-pong). Either way, force-reconnect through the existing backoff path. */
479
+ * pong capability it is a genuine liveness timeout. If pong capability was proven EARLIER in this
480
+ * client's lifetime (CTC-281), a never-ponged connection is the incident signature a half-open
481
+ * socket against a server we KNOW auto-pongs so it too is a liveness failure and must NEVER count
482
+ * toward the feature-detect (during the Jul 17-23 windows, 3 such sockets permanently disabled
483
+ * detection). Only while capability is UNPROVEN does the failure count toward the DEGRADE — after
484
+ * PROBE_FAILURE_LIMIT never-ponged connections the watchdog backs its probes off to
485
+ * DEGRADED_PROBE_MULTIPLIER x pingIntervalMs (an old server without auto-pong costs one bounded
486
+ * reconnect per degraded window; a mid-incident restart — per-process latch reset — still detects
487
+ * the next half-open within one degraded window, never restart-only; CTC-281). Every path
488
+ * force-reconnects through the existing backoff. */
301
489
  private onProbeUnanswered;
302
490
  /** Tear the socket down and reconnect through the normal backoff. closeSocket detaches handlers (so
303
491
  * onclose won't also fire) and clears the liveness timers, so we schedule the reopen ourselves. */
@@ -305,6 +493,8 @@ export declare class LiveSyncClient {
305
493
  private clearPingTimer;
306
494
  private clearPongDeadline;
307
495
  private clearLivenessTimers;
496
+ /** Clear the per-connection connect/open deadline + onerror→onclose fallback (CTC-281). */
497
+ private clearConnectTimers;
308
498
  }
309
499
  /** Parse a WS frame (string or ArrayBuffer) into a known server frame, or null for anything malformed. */
310
500
  export declare function parseFrame(data: unknown): ServerFrame | null;
@@ -1 +1 @@
1
- {"version":3,"file":"live-sync-client.d.ts","sourceRoot":"","sources":["../src/live-sync-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"live-sync-client.d.ts","sourceRoot":"","sources":["../src/live-sync-client.ts"],"names":[],"mappings":"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"}