@loro-dev/streams-crdt 0.11.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -54,6 +54,7 @@ if (!result.ok) {
54
54
  break;
55
55
  case "network_error":
56
56
  case "timeout":
57
+ case "initial_sync_timeout":
57
58
  // Transient — safe to retry.
58
59
  break;
59
60
  case "protocol_error":
@@ -101,6 +102,7 @@ if (err.code === "server_error") {
101
102
  | `gone` | 410 | yes | yes | — |
102
103
  | `server_error` | 5xx | yes | yes | `requestId?`, `retryAfterMs?` |
103
104
  | `timeout` | — | yes | — | `phase: "connect" \| "poll"` |
105
+ | `initial_sync_timeout` | — | yes | — | `operation`, `timeoutMs`, `elapsedMs` |
104
106
  | `network_error` | — | yes | — | — |
105
107
  | `auth_provider_error` | — | yes | — | `cause?` (original thrown value) |
106
108
  | `internal_error` | — | yes | — | — |
@@ -120,6 +122,33 @@ if (err.code === "server_error") {
120
122
  call `transport.rejoin()` after fixing the cause (e.g., refreshing the auth
121
123
  token) to reset retry state and reconnect.
122
124
 
125
+ #### Initial sync deadlines
126
+
127
+ Initial bootstrap/catch-up work is allowed to run longer than ordinary request
128
+ connect and poll deadlines. The transport uses `reconnectConfig` for this:
129
+
130
+ ```ts
131
+ const transport = new StreamsCrdt({
132
+ streamUrl,
133
+ adapter,
134
+ auth,
135
+ reconnectConfig: {
136
+ // Logs a debug diagnostic when initial sync is still pending; does not abort.
137
+ initialSyncSlowAfterMs: 30_000,
138
+ // Aborts initial bootstrap/catch-up with `initial_sync_timeout`.
139
+ initialSyncHardTimeoutMs: 120_000,
140
+ },
141
+ });
142
+ ```
143
+
144
+ `join()`, `sync()`, pull-only `catchup()`, and 410 bootstrap recovery all use
145
+ the initial-sync deadline path when they need to bootstrap or catch up from a
146
+ stored cursor. In `StreamsCrdt` constructor options, set
147
+ `initialSyncHardTimeoutMs` to `0` or `Infinity` to disable the hard cap. Because
148
+ constructor `reconnectConfig` is merged over defaults, omitting the field keeps
149
+ the default hard cap. Set `initialSyncSlowAfterMs` the same way to disable the
150
+ slow diagnostic.
151
+
123
152
  > **Why `Result` instead of `throw`?** Transport failures (network errors,
124
153
  > auth expiry, missing streams) are expected at runtime, not exceptional.
125
154
  > Wrapping them in `Result` makes the error path explicit in the type system
@@ -141,8 +170,8 @@ Only adjust if any of these apply:
141
170
  `stream_not_found` now requires `status: 404` + `message`; `gone` now
142
171
  requires `status: 410`. TypeScript will flag these.
143
172
  - **You exhaustively switch on `code` with a `: never` default.** Add a case
144
- for `auth_provider_error` (and optionally `server_error` if you handled
145
- 5xx via `unknown`/`internal_error` before).
173
+ for `auth_provider_error` and `initial_sync_timeout` (and optionally
174
+ `server_error` if you handled 5xx via `unknown`/`internal_error` before).
146
175
  - **You used `"message" in error` to defensively narrow.** All variants now
147
176
  carry `message`; the guard is no longer needed.
148
177
 
@@ -164,6 +193,8 @@ const transport = new StreamsCrdt({
164
193
  }),
165
194
  auth: async () => "<gateway-jwt>",
166
195
  adapter: createLoroDocAdapter(doc),
196
+ // Optional TTL applied when the stream is created.
197
+ streamTtlSeconds: 60 * 60 * 24 * 30,
167
198
  // Enable automatic snapshot upload so new readers bootstrap faster.
168
199
  snapshotUpload: { canUpload: async () => true },
169
200
  });
@@ -205,16 +236,20 @@ const transport = new StreamsCrdt({
205
236
  adapter: createLoroDocAdapter(doc),
206
237
  shardUrls: {
207
238
  bootstrap: [
208
- "https://control-a.streams-api-proxy.loro.dev",
209
- "https://control-b.streams-api-proxy.loro.dev",
239
+ "https://control-a.api.streams-api-x.loro.dev",
240
+ "https://control-b.api.streams-api-x.loro.dev",
210
241
  ],
211
242
  catchup: [
212
- "https://control-a.streams-api-proxy.loro.dev",
213
- "https://control-b.streams-api-proxy.loro.dev",
243
+ "https://control-a.api.streams-api-x.loro.dev",
244
+ "https://control-b.api.streams-api-x.loro.dev",
214
245
  ],
215
246
  largePost: [
216
- "https://write-a.streams-api-proxy.loro.dev",
217
- "https://write-b.streams-api-proxy.loro.dev",
247
+ "https://write-a.api.streams-api-x.loro.dev",
248
+ "https://write-b.api.streams-api-x.loro.dev",
249
+ ],
250
+ other: [
251
+ "https://live-a.api.streams-api-x.loro.dev",
252
+ "https://live-b.api.streams-api-x.loro.dev",
218
253
  ],
219
254
  largePostMinBytes: 64 * 1024,
220
255
  },
@@ -225,12 +260,14 @@ Shard entries must be origin URLs with no path, query, or hash. Each transport
225
260
  instance rotates through the configured origins per operation, with a randomized
226
261
  starting point so multiple tabs are less likely to all begin on the same shard.
227
262
  Bootstrap applies to `GET <stream>/bootstrap`; catch-up applies to non-SSE
228
- offset reads, including long-poll fallback; SSE live reads stay on the original
229
- `streamUrl`. `largePost` applies to non-empty append POST bodies at or above
230
- `largePostMinBytes` bytes. The default threshold is `0`, so every non-empty
231
- append POST can use `largePost` when that pool is configured. Verify actual
232
- connection separation with browser NetLog: browsers may coalesce compatible
233
- HTTP/2 or HTTP/3 origins when DNS, certificate, and transport settings allow it.
263
+ offset reads, including long-poll fallback. `largePost` applies to non-empty
264
+ append POST bodies at or above `largePostMinBytes` bytes. `other` applies when
265
+ no operation-specific pool routes the request, covering live SSE, create/delete,
266
+ head, snapshot upload, and append POSTs not routed by `largePost`. The default
267
+ threshold is `0`, so every non-empty append POST can use `largePost` when that
268
+ pool is configured. Verify actual connection separation with browser NetLog:
269
+ browsers may coalesce compatible HTTP/2 or HTTP/3 origins when DNS, certificate,
270
+ and transport settings allow it.
234
271
 
235
272
  ### Loro pending imports and cursor safety
236
273
 
@@ -1050,6 +1087,7 @@ const transport = new StreamsCrdt({
1050
1087
  result types used to report incomplete imports such as Loro pending updates
1051
1088
  - `Result` — Rust-style `Ok | Err` result
1052
1089
  - `StreamsAuthProvider` — auth callback type
1090
+ - `StreamsCrdtShardUrlsOptions` — optional origin pools for request routing
1053
1091
  - `TransportError` — discriminated error union
1054
1092
  `apply_incomplete` is returned when remote data was read but the CRDT adapter
1055
1093
  still has unresolved dependencies and the cursor cannot be saved.
@@ -1105,6 +1143,9 @@ const transport = new StreamsCrdt({
1105
1143
  ## Notes
1106
1144
 
1107
1145
  - `createStreamIfMissing` defaults to `false` and only affects the initial sync/join bootstrap
1146
+ - `streamTtlSeconds` is a non-negative safe integer in seconds. It is sent only
1147
+ when the transport creates the stream, either through `createStream()` or
1148
+ automatic creation with `createStreamIfMissing`.
1108
1149
  - `deleteStream()` returns `{ deleted: false }` when the target stream is already missing
1109
1150
  - `sync()` and `join()` return `Result` objects instead of implicitly creating missing streams
1110
1151
  - `join()` resolves only after the initial replay has succeeded; without a stored remote cursor it bootstraps once, then prefers ordinary live SSE and falls back sticky to long-poll
package/dist/flock.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as BeforeRemoteCursorSaveHook, A as PayloadProtectionReadPolicy, B as StreamsCrdtShardUrlsOptions, C as IsolatedCrdtAdapter, D as PayloadProtectionKey, E as PayloadProtectionEncryptionOptions, F as SnapshotTransformHook, G as TransportError, H as TransportCatchupSuccess, I as SnapshotUploadOptions, J as TransportSnapshotUploadSuccess, K as TransportJoinParams, L as StreamsAuthContext, M as PayloadProtectionWritePolicy, N as Result, O as PayloadProtectionKeyProvider, P as SnapshotCodec, Q as BeforeRemoteCursorSaveContext, R as StreamsAuthProvider, S as EphemeralStreamSubscription, T as JsonValue, U as TransportCreateStreamSuccess, V as TransportCatchupParams, W as TransportDeleteStreamSuccess, X as TransportSyncSuccess, Y as TransportSubscription, Z as WriteOnlyAppendResult, _ as E2eeScope, a as EphemeralStreamCrdt, at as RemoteCursorStore, b as EphemeralStreamCrdtOptions, c as CrdtApplyOutcome, d as CrdtUpdateBatch, et as InMemoryRemoteCursorStore, f as E2eeEncryptionOptions, g as E2eeReadPolicy, h as E2eeOptions, i as PayloadProtectionError, it as RemoteCursorSaveSource, j as PayloadProtectionScope, k as PayloadProtectionOptions, l as CrdtApplyReturn, m as E2eeKeyProvider, n as isValidBucketId, nt as IndexedDbRemoteCursorStoreOptions, o as StreamsCrdt, ot as createInitialRemoteCursor, p as E2eeKey, q as TransportRoomStatus, r as isValidRillId, rt as RemoteCursor, s as CrdtAdapter, t as createStreamUrl, tt as IndexedDbRemoteCursorStore, u as CrdtUnresolvedSpan, v as E2eeWritePolicy, w as JsonObject, x as EphemeralStreamJoinParams, y as EphemeralStreamAdaptor, z as StreamsCrdtOptions } from "./stream-id-DAAMJlvT.js";
1
+ import { $ as BeforeRemoteCursorSaveHook, A as PayloadProtectionReadPolicy, B as StreamsCrdtShardUrlsOptions, C as IsolatedCrdtAdapter, D as PayloadProtectionKey, E as PayloadProtectionEncryptionOptions, F as SnapshotTransformHook, G as TransportError, H as TransportCatchupSuccess, I as SnapshotUploadOptions, J as TransportSnapshotUploadSuccess, K as TransportJoinParams, L as StreamsAuthContext, M as PayloadProtectionWritePolicy, N as Result, O as PayloadProtectionKeyProvider, P as SnapshotCodec, Q as BeforeRemoteCursorSaveContext, R as StreamsAuthProvider, S as EphemeralStreamSubscription, T as JsonValue, U as TransportCreateStreamSuccess, V as TransportCatchupParams, W as TransportDeleteStreamSuccess, X as TransportSyncSuccess, Y as TransportSubscription, Z as WriteOnlyAppendResult, _ as E2eeScope, a as EphemeralStreamCrdt, at as RemoteCursorStore, b as EphemeralStreamCrdtOptions, c as CrdtApplyOutcome, d as CrdtUpdateBatch, et as InMemoryRemoteCursorStore, f as E2eeEncryptionOptions, g as E2eeReadPolicy, h as E2eeOptions, i as PayloadProtectionError, it as RemoteCursorSaveSource, j as PayloadProtectionScope, k as PayloadProtectionOptions, l as CrdtApplyReturn, m as E2eeKeyProvider, n as isValidBucketId, nt as IndexedDbRemoteCursorStoreOptions, o as StreamsCrdt, ot as createInitialRemoteCursor, p as E2eeKey, q as TransportRoomStatus, r as isValidRillId, rt as RemoteCursor, s as CrdtAdapter, t as createStreamUrl, tt as IndexedDbRemoteCursorStore, u as CrdtUnresolvedSpan, v as E2eeWritePolicy, w as JsonObject, x as EphemeralStreamJoinParams, y as EphemeralStreamAdaptor, z as StreamsCrdtOptions } from "./stream-id-DJYQlTE2.js";
2
2
  import { ExportBundle, Flock, VersionVector, VersionVector as VersionVector$1 } from "@loro-dev/flock-wasm";
3
3
 
4
4
  //#region src/flock.d.ts
package/dist/flock.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as InMemoryRemoteCursorStore, c as EphemeralStreamCrdt, i as StreamsCrdt, l as PayloadProtectionError, n as isValidBucketId, o as IndexedDbRemoteCursorStore, r as isValidRillId, s as createInitialRemoteCursor, t as createStreamUrl } from "./stream-id-fOF9ZqCH.js";
1
+ import { a as InMemoryRemoteCursorStore, c as EphemeralStreamCrdt, i as StreamsCrdt, l as PayloadProtectionError, n as isValidBucketId, o as IndexedDbRemoteCursorStore, r as isValidRillId, s as createInitialRemoteCursor, t as createStreamUrl } from "./stream-id-DVVP3k7V.js";
2
2
  import { Flock } from "@loro-dev/flock-wasm";
3
3
  //#region src/flock.ts
4
4
  function isAfter(entry, current) {
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as BeforeRemoteCursorSaveHook, A as PayloadProtectionReadPolicy, B as StreamsCrdtShardUrlsOptions, C as IsolatedCrdtAdapter, D as PayloadProtectionKey, E as PayloadProtectionEncryptionOptions, F as SnapshotTransformHook, G as TransportError, H as TransportCatchupSuccess, I as SnapshotUploadOptions, J as TransportSnapshotUploadSuccess, K as TransportJoinParams, L as StreamsAuthContext, M as PayloadProtectionWritePolicy, N as Result, O as PayloadProtectionKeyProvider, P as SnapshotCodec, Q as BeforeRemoteCursorSaveContext, R as StreamsAuthProvider, S as EphemeralStreamSubscription, T as JsonValue, U as TransportCreateStreamSuccess, V as TransportCatchupParams, W as TransportDeleteStreamSuccess, X as TransportSyncSuccess, Y as TransportSubscription, Z as WriteOnlyAppendResult, _ as E2eeScope, a as EphemeralStreamCrdt, at as RemoteCursorStore, b as EphemeralStreamCrdtOptions, c as CrdtApplyOutcome, d as CrdtUpdateBatch, et as InMemoryRemoteCursorStore, f as E2eeEncryptionOptions, g as E2eeReadPolicy, h as E2eeOptions, i as PayloadProtectionError, it as RemoteCursorSaveSource, j as PayloadProtectionScope, k as PayloadProtectionOptions, l as CrdtApplyReturn, m as E2eeKeyProvider, n as isValidBucketId, nt as IndexedDbRemoteCursorStoreOptions, o as StreamsCrdt, ot as createInitialRemoteCursor, p as E2eeKey, q as TransportRoomStatus, r as isValidRillId, rt as RemoteCursor, s as CrdtAdapter, t as createStreamUrl, tt as IndexedDbRemoteCursorStore, u as CrdtUnresolvedSpan, v as E2eeWritePolicy, w as JsonObject, x as EphemeralStreamJoinParams, y as EphemeralStreamAdaptor, z as StreamsCrdtOptions } from "./stream-id-DAAMJlvT.js";
1
+ import { $ as BeforeRemoteCursorSaveHook, A as PayloadProtectionReadPolicy, B as StreamsCrdtShardUrlsOptions, C as IsolatedCrdtAdapter, D as PayloadProtectionKey, E as PayloadProtectionEncryptionOptions, F as SnapshotTransformHook, G as TransportError, H as TransportCatchupSuccess, I as SnapshotUploadOptions, J as TransportSnapshotUploadSuccess, K as TransportJoinParams, L as StreamsAuthContext, M as PayloadProtectionWritePolicy, N as Result, O as PayloadProtectionKeyProvider, P as SnapshotCodec, Q as BeforeRemoteCursorSaveContext, R as StreamsAuthProvider, S as EphemeralStreamSubscription, T as JsonValue, U as TransportCreateStreamSuccess, V as TransportCatchupParams, W as TransportDeleteStreamSuccess, X as TransportSyncSuccess, Y as TransportSubscription, Z as WriteOnlyAppendResult, _ as E2eeScope, a as EphemeralStreamCrdt, at as RemoteCursorStore, b as EphemeralStreamCrdtOptions, c as CrdtApplyOutcome, d as CrdtUpdateBatch, et as InMemoryRemoteCursorStore, f as E2eeEncryptionOptions, g as E2eeReadPolicy, h as E2eeOptions, i as PayloadProtectionError, it as RemoteCursorSaveSource, j as PayloadProtectionScope, k as PayloadProtectionOptions, l as CrdtApplyReturn, m as E2eeKeyProvider, n as isValidBucketId, nt as IndexedDbRemoteCursorStoreOptions, o as StreamsCrdt, ot as createInitialRemoteCursor, p as E2eeKey, q as TransportRoomStatus, r as isValidRillId, rt as RemoteCursor, s as CrdtAdapter, t as createStreamUrl, tt as IndexedDbRemoteCursorStore, u as CrdtUnresolvedSpan, v as E2eeWritePolicy, w as JsonObject, x as EphemeralStreamJoinParams, y as EphemeralStreamAdaptor, z as StreamsCrdtOptions } from "./stream-id-DJYQlTE2.js";
2
2
  export { BeforeRemoteCursorSaveContext, BeforeRemoteCursorSaveHook, CrdtAdapter, CrdtApplyOutcome, CrdtApplyReturn, CrdtUnresolvedSpan, CrdtUpdateBatch, E2eeEncryptionOptions, PayloadProtectionError as E2eeError, PayloadProtectionError, E2eeKey, E2eeKeyProvider, E2eeOptions, E2eeReadPolicy, E2eeScope, E2eeWritePolicy, EphemeralStreamAdaptor, EphemeralStreamCrdt, EphemeralStreamCrdtOptions, EphemeralStreamJoinParams, EphemeralStreamSubscription, InMemoryRemoteCursorStore, IndexedDbRemoteCursorStore, IndexedDbRemoteCursorStoreOptions, IsolatedCrdtAdapter, JsonObject, JsonValue, PayloadProtectionEncryptionOptions, PayloadProtectionKey, PayloadProtectionKeyProvider, PayloadProtectionOptions, PayloadProtectionReadPolicy, PayloadProtectionScope, PayloadProtectionWritePolicy, RemoteCursor, RemoteCursorSaveSource, RemoteCursorStore, Result, SnapshotCodec, SnapshotTransformHook, SnapshotUploadOptions, StreamsAuthContext, StreamsAuthProvider, StreamsCrdt, StreamsCrdtOptions, StreamsCrdtShardUrlsOptions, TransportCatchupParams, TransportCatchupSuccess, TransportCreateStreamSuccess, TransportDeleteStreamSuccess, TransportError, TransportJoinParams, TransportRoomStatus, TransportSnapshotUploadSuccess, TransportSubscription, TransportSyncSuccess, WriteOnlyAppendResult, createInitialRemoteCursor, createStreamUrl, isValidBucketId, isValidRillId };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as InMemoryRemoteCursorStore, c as EphemeralStreamCrdt, i as StreamsCrdt, l as PayloadProtectionError, n as isValidBucketId, o as IndexedDbRemoteCursorStore, r as isValidRillId, s as createInitialRemoteCursor, t as createStreamUrl } from "./stream-id-fOF9ZqCH.js";
1
+ import { a as InMemoryRemoteCursorStore, c as EphemeralStreamCrdt, i as StreamsCrdt, l as PayloadProtectionError, n as isValidBucketId, o as IndexedDbRemoteCursorStore, r as isValidRillId, s as createInitialRemoteCursor, t as createStreamUrl } from "./stream-id-DVVP3k7V.js";
2
2
  export { PayloadProtectionError as E2eeError, PayloadProtectionError, EphemeralStreamCrdt, InMemoryRemoteCursorStore, IndexedDbRemoteCursorStore, StreamsCrdt, createInitialRemoteCursor, createStreamUrl, isValidBucketId, isValidRillId };
package/dist/loro.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as BeforeRemoteCursorSaveHook, A as PayloadProtectionReadPolicy, B as StreamsCrdtShardUrlsOptions, C as IsolatedCrdtAdapter, D as PayloadProtectionKey, E as PayloadProtectionEncryptionOptions, F as SnapshotTransformHook, G as TransportError, H as TransportCatchupSuccess, I as SnapshotUploadOptions, J as TransportSnapshotUploadSuccess, K as TransportJoinParams, L as StreamsAuthContext, M as PayloadProtectionWritePolicy, N as Result, O as PayloadProtectionKeyProvider, P as SnapshotCodec, Q as BeforeRemoteCursorSaveContext, R as StreamsAuthProvider, S as EphemeralStreamSubscription, T as JsonValue, U as TransportCreateStreamSuccess, V as TransportCatchupParams, W as TransportDeleteStreamSuccess, X as TransportSyncSuccess, Y as TransportSubscription, Z as WriteOnlyAppendResult, _ as E2eeScope, a as EphemeralStreamCrdt, at as RemoteCursorStore, b as EphemeralStreamCrdtOptions, c as CrdtApplyOutcome, d as CrdtUpdateBatch, et as InMemoryRemoteCursorStore, f as E2eeEncryptionOptions, g as E2eeReadPolicy, h as E2eeOptions, i as PayloadProtectionError, it as RemoteCursorSaveSource, j as PayloadProtectionScope, k as PayloadProtectionOptions, l as CrdtApplyReturn, m as E2eeKeyProvider, n as isValidBucketId, nt as IndexedDbRemoteCursorStoreOptions, o as StreamsCrdt, ot as createInitialRemoteCursor, p as E2eeKey, q as TransportRoomStatus, r as isValidRillId, rt as RemoteCursor, s as CrdtAdapter, t as createStreamUrl, tt as IndexedDbRemoteCursorStore, u as CrdtUnresolvedSpan, v as E2eeWritePolicy, w as JsonObject, x as EphemeralStreamJoinParams, y as EphemeralStreamAdaptor, z as StreamsCrdtOptions } from "./stream-id-DAAMJlvT.js";
1
+ import { $ as BeforeRemoteCursorSaveHook, A as PayloadProtectionReadPolicy, B as StreamsCrdtShardUrlsOptions, C as IsolatedCrdtAdapter, D as PayloadProtectionKey, E as PayloadProtectionEncryptionOptions, F as SnapshotTransformHook, G as TransportError, H as TransportCatchupSuccess, I as SnapshotUploadOptions, J as TransportSnapshotUploadSuccess, K as TransportJoinParams, L as StreamsAuthContext, M as PayloadProtectionWritePolicy, N as Result, O as PayloadProtectionKeyProvider, P as SnapshotCodec, Q as BeforeRemoteCursorSaveContext, R as StreamsAuthProvider, S as EphemeralStreamSubscription, T as JsonValue, U as TransportCreateStreamSuccess, V as TransportCatchupParams, W as TransportDeleteStreamSuccess, X as TransportSyncSuccess, Y as TransportSubscription, Z as WriteOnlyAppendResult, _ as E2eeScope, a as EphemeralStreamCrdt, at as RemoteCursorStore, b as EphemeralStreamCrdtOptions, c as CrdtApplyOutcome, d as CrdtUpdateBatch, et as InMemoryRemoteCursorStore, f as E2eeEncryptionOptions, g as E2eeReadPolicy, h as E2eeOptions, i as PayloadProtectionError, it as RemoteCursorSaveSource, j as PayloadProtectionScope, k as PayloadProtectionOptions, l as CrdtApplyReturn, m as E2eeKeyProvider, n as isValidBucketId, nt as IndexedDbRemoteCursorStoreOptions, o as StreamsCrdt, ot as createInitialRemoteCursor, p as E2eeKey, q as TransportRoomStatus, r as isValidRillId, rt as RemoteCursor, s as CrdtAdapter, t as createStreamUrl, tt as IndexedDbRemoteCursorStore, u as CrdtUnresolvedSpan, v as E2eeWritePolicy, w as JsonObject, x as EphemeralStreamJoinParams, y as EphemeralStreamAdaptor, z as StreamsCrdtOptions } from "./stream-id-DJYQlTE2.js";
2
2
  import { LoroDoc } from "loro-crdt";
3
3
 
4
4
  //#region src/loro.d.ts
package/dist/loro.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as InMemoryRemoteCursorStore, c as EphemeralStreamCrdt, i as StreamsCrdt, l as PayloadProtectionError, n as isValidBucketId, o as IndexedDbRemoteCursorStore, r as isValidRillId, s as createInitialRemoteCursor, t as createStreamUrl } from "./stream-id-fOF9ZqCH.js";
1
+ import { a as InMemoryRemoteCursorStore, c as EphemeralStreamCrdt, i as StreamsCrdt, l as PayloadProtectionError, n as isValidBucketId, o as IndexedDbRemoteCursorStore, r as isValidRillId, s as createInitialRemoteCursor, t as createStreamUrl } from "./stream-id-DVVP3k7V.js";
2
2
  import { LoroDoc, VersionVector, decodeImportBlobMeta } from "loro-crdt";
3
3
  //#region src/loro.ts
4
4
  function batchImportUpdates(doc, updates) {
@@ -104,10 +104,29 @@ declare function createInitialRemoteCursor<TVersion extends JsonObject = JsonObj
104
104
  * Retry and timeout settings used by `StreamsCrdt`.
105
105
  */
106
106
  interface ReconnectConfig {
107
+ /** Retry delay schedule in milliseconds, indexed by retry attempt and clamped at the last entry. */
107
108
  readonly delays: readonly number[];
109
+ /** Fractional +/- jitter applied to scheduled retry delays. */
108
110
  readonly jitterFraction: number;
111
+ /** Maximum retry attempts for background live loops. Use `Infinity` to retry forever. */
109
112
  readonly maxAttempts: number;
113
+ /** Connect deadline for ordinary transport requests. */
110
114
  readonly connectTimeoutMs: number;
115
+ /**
116
+ * Soft diagnostic threshold for initial bootstrap/catch-up.
117
+ *
118
+ * Crossing this threshold does not abort or reject the in-flight request.
119
+ * Set to 0 or `Infinity` to disable it.
120
+ */
121
+ readonly initialSyncSlowAfterMs?: number;
122
+ /**
123
+ * Hard cap for initial bootstrap/catch-up before aborting with
124
+ * `initial_sync_timeout`.
125
+ *
126
+ * Set to 0 or `Infinity` to disable it.
127
+ */
128
+ readonly initialSyncHardTimeoutMs?: number;
129
+ /** Poll deadline for ordinary long-poll/read requests. */
111
130
  readonly pollTimeoutMs: number;
112
131
  /** SSE inactivity timeout. Aborts and reconnects if no event arrives within this period. */
113
132
  readonly liveInactivityTimeoutMs?: number;
@@ -186,6 +205,7 @@ type TransportRoomStatus = "joined" | "reconnecting" | "disconnected" | "error";
186
205
  * - `protocol_error` — 400/405/409 or malformed response; treat as a bug.
187
206
  * - `network_error` — fetch-level failure (DNS, connection refused). Retry.
188
207
  * - `timeout` — connect or poll deadline exceeded. Retry.
208
+ * - `initial_sync_timeout` — initial bootstrap/catch-up exceeded its hard cap.
189
209
  * - `gone` — 410; persisted cursor is no longer valid. Bootstrap from scratch.
190
210
  * - `apply_incomplete` — a CRDT adapter could not fully apply remote data.
191
211
  * - `server_error` — 5xx; transient backend failure, retry with backoff.
@@ -272,6 +292,18 @@ type TransportError =
272
292
  readonly phase: "connect" | "poll";
273
293
  readonly message: string;
274
294
  }
295
+ /**
296
+ * Initial bootstrap/catch-up exceeded its hard timeout. The request was allowed
297
+ * past the slow diagnostic threshold first; this only fires at the hard cap.
298
+ */
299
+ | {
300
+ readonly code: "initial_sync_timeout";
301
+ readonly retryable: true;
302
+ readonly operation: string;
303
+ readonly timeoutMs: number;
304
+ readonly elapsedMs: number;
305
+ readonly message: string;
306
+ }
275
307
  /**
276
308
  * The server indicated the persisted cursor is no longer valid (410). The
277
309
  * runtime will bootstrap from scratch on the next `join()`/`sync()` —
@@ -418,19 +450,32 @@ interface StreamsCrdtShardUrlsOptions {
418
450
  * Origin URLs used for `GET <stream>/bootstrap`.
419
451
  *
420
452
  * Each entry should be an origin URL such as
421
- * `https://control-a.streams-api-proxy.loro.dev`. The transport keeps the
453
+ * `https://control-a.api.streams-api-x.loro.dev`. The transport keeps the
422
454
  * stream path and query from `streamUrl` and only replaces the request origin.
455
+ * If omitted, `other` is used as the fallback pool for bootstrap requests.
423
456
  */
424
457
  readonly bootstrap?: readonly string[];
425
458
  /**
426
459
  * Origin URLs used for non-SSE catch-up reads:
427
460
  * `GET <stream>?offset=...` and long-poll fallback reads.
461
+ *
462
+ * If omitted, `other` is used as the fallback pool for catch-up requests.
428
463
  */
429
464
  readonly catchup?: readonly string[];
430
465
  /**
431
466
  * Origin URLs used for large `POST <stream>` append requests.
467
+ *
468
+ * If omitted, `other` is used as the fallback pool for large append requests.
432
469
  */
433
470
  readonly largePost?: readonly string[];
471
+ /**
472
+ * Origin URLs used when no operation-specific shard pool routes the request.
473
+ *
474
+ * This covers live SSE reads, create/delete/head requests, snapshot uploads,
475
+ * append POSTs not routed by `largePost`, and any future request shape not
476
+ * listed above.
477
+ */
478
+ readonly other?: readonly string[];
434
479
  /**
435
480
  * Minimum request body size before `largePost` routing applies.
436
481
  *
@@ -670,6 +715,8 @@ interface EphemeralStreamCrdtOptions {
670
715
  readonly auth?: StreamsAuthProvider;
671
716
  /** Optional fetch implementation for tests, workers, or custom runtimes. */
672
717
  readonly fetch?: (input: string, init?: RequestInit) => Promise<Response>;
718
+ /** Optional origin pools for routing ephemeral POST/SSE requests. */
719
+ readonly shardUrls?: StreamsCrdtShardUrlsOptions;
673
720
  /** Reconnect policy for the SSE read loop and local POST retry loop. */
674
721
  readonly reconnectConfig?: Partial<ReconnectConfig>;
675
722
  /** Enables diagnostic console logging for terminal read/write failures. */
@@ -690,6 +737,15 @@ interface StreamsCrdtOptions<TVersion extends JsonObject> {
690
737
  * Defaults to false so missing streams are surfaced explicitly.
691
738
  */
692
739
  readonly createStreamIfMissing?: boolean;
740
+ /**
741
+ * Optional stream time-to-live in seconds used when creating the stream.
742
+ *
743
+ * Applies to both explicit `createStream()` calls and automatic stream
744
+ * creation through `createStreamIfMissing`. The value must be a non-negative
745
+ * safe integer. Updating this option on an existing stream has no effect
746
+ * until the transport creates that stream again.
747
+ */
748
+ readonly streamTtlSeconds?: number;
693
749
  /**
694
750
  * Auth token source.
695
751
  *
@@ -741,8 +797,16 @@ interface StreamsCrdtOptions<TVersion extends JsonObject> {
741
797
  */
742
798
  readonly payloadProtection?: PayloadProtectionOptions;
743
799
  readonly snapshotUpload?: SnapshotUploadOptions;
744
- /** Optional origin pools for routing bootstrap/catch-up and large append requests. */
800
+ /** Optional origin pools for routing transport requests. */
745
801
  readonly shardUrls?: StreamsCrdtShardUrlsOptions;
802
+ /**
803
+ * Partial override for retry, ordinary request timeout, live SSE inactivity,
804
+ * and initial bootstrap/catch-up deadline behavior.
805
+ *
806
+ * The runtime merges this with its defaults. `initialSyncSlowAfterMs` is only
807
+ * a diagnostic threshold; it does not abort the request. `initialSyncHardTimeoutMs`
808
+ * aborts initial bootstrap/catch-up and returns `initial_sync_timeout`.
809
+ */
746
810
  readonly reconnectConfig?: Partial<ReconnectConfig>;
747
811
  readonly debug?: boolean;
748
812
  }
@@ -897,6 +961,7 @@ declare class StreamsCrdt<TVersion extends JsonObject> implements StreamsCrdtLik
897
961
  join(params?: TransportJoinParams): Promise<Result<TransportSubscription, TransportError>>;
898
962
  private createSubscription;
899
963
  private disposeJoinState;
964
+ private runInitialSyncWithDeadline;
900
965
  private startJoin;
901
966
  private syncOnce;
902
967
  private performInitialJoinSync;
@@ -1051,4 +1116,4 @@ declare function createStreamUrl(input: {
1051
1116
  }): string;
1052
1117
  //#endregion
1053
1118
  export { BeforeRemoteCursorSaveHook as $, PayloadProtectionReadPolicy as A, StreamsCrdtShardUrlsOptions as B, IsolatedCrdtAdapter as C, PayloadProtectionKey as D, PayloadProtectionEncryptionOptions as E, SnapshotTransformHook as F, TransportError as G, TransportCatchupSuccess as H, SnapshotUploadOptions as I, TransportSnapshotUploadSuccess as J, TransportJoinParams as K, StreamsAuthContext as L, PayloadProtectionWritePolicy as M, Result as N, PayloadProtectionKeyProvider as O, SnapshotCodec as P, BeforeRemoteCursorSaveContext as Q, StreamsAuthProvider as R, EphemeralStreamSubscription as S, JsonValue as T, TransportCreateStreamSuccess as U, TransportCatchupParams as V, TransportDeleteStreamSuccess as W, TransportSyncSuccess as X, TransportSubscription as Y, WriteOnlyAppendResult as Z, E2eeScope as _, EphemeralStreamCrdt as a, RemoteCursorStore as at, EphemeralStreamCrdtOptions as b, CrdtApplyOutcome as c, CrdtUpdateBatch as d, InMemoryRemoteCursorStore as et, E2eeEncryptionOptions as f, E2eeReadPolicy as g, E2eeOptions as h, PayloadProtectionError as i, RemoteCursorSaveSource as it, PayloadProtectionScope as j, PayloadProtectionOptions as k, CrdtApplyReturn as l, E2eeKeyProvider as m, isValidBucketId as n, IndexedDbRemoteCursorStoreOptions as nt, StreamsCrdt as o, createInitialRemoteCursor as ot, E2eeKey as p, TransportRoomStatus as q, isValidRillId as r, RemoteCursor as rt, CrdtAdapter as s, createStreamUrl as t, IndexedDbRemoteCursorStore as tt, CrdtUnresolvedSpan as u, E2eeWritePolicy as v, JsonObject as w, EphemeralStreamJoinParams as x, EphemeralStreamAdaptor as y, StreamsCrdtOptions as z };
1054
- //# sourceMappingURL=stream-id-DAAMJlvT.d.ts.map
1119
+ //# sourceMappingURL=stream-id-DJYQlTE2.d.ts.map