@loro-dev/streams-crdt 0.10.0 → 0.11.1
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 +39 -5
- package/dist/flock.d.ts +2 -2
- package/dist/flock.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/loro.d.ts +2 -2
- package/dist/loro.js +1 -1
- package/dist/{stream-id-BP6BR7jn.d.ts → stream-id-DAAMJlvT.d.ts} +48 -3
- package/dist/{stream-id-AfFikxB2.js → stream-id-fOF9ZqCH.js} +64 -2
- package/dist/stream-id-fOF9ZqCH.js.map +1 -0
- package/package.json +2 -2
- package/dist/stream-id-AfFikxB2.js.map +0 -1
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Transport layer for synchronizing CRDT state over
|
|
|
19
19
|
| `createStream()` | Creates the stream on the server. Returns `{ created: true }` on first call, `{ created: false }` if it already exists. |
|
|
20
20
|
| `deleteStream()` | Deletes the stream. Closes any active `join()` first. |
|
|
21
21
|
| `sync()` | One-shot bootstrap/catch-up cycle. Syncs remote state into local CRDT and pushes any local changes to the server. Does **not** enter live mode. |
|
|
22
|
+
| `catchup()` | Pull-only remote catch-up. Applies remote stream updates to the local CRDT but does not intentionally append new local updates. If live reads from `join()` are already healthy, returns immediately unless `{ force: true }` is passed. |
|
|
22
23
|
| `join()` | Initial sync **plus** live subscription. Internally performs the same sync as `sync()`, then enters a persistent SSE/long-poll read loop and starts forwarding local writes. No need to call `sync()` before `join()`. |
|
|
23
24
|
| `close()` | Closes any active join and releases resources. If this instance was using `appendWriteOnly()`, that write-only path is also torn down and cannot be used again on the same instance. |
|
|
24
25
|
|
|
@@ -107,7 +108,8 @@ if (err.code === "server_error") {
|
|
|
107
108
|
|
|
108
109
|
#### Operation-level retries vs. live-mode retries
|
|
109
110
|
|
|
110
|
-
- `sync()`, `
|
|
111
|
+
- `sync()`, `catchup()`, `createStream()`, `deleteStream()`,
|
|
112
|
+
`appendWriteOnly()` return
|
|
111
113
|
after a **single** attempt. The application is responsible for retrying
|
|
112
114
|
`retryable` errors.
|
|
113
115
|
- After `join()` succeeds, the live read/write loops automatically reconnect
|
|
@@ -371,17 +373,47 @@ if (!joined.ok) throw joined.error;
|
|
|
371
373
|
const sub = joined.value;
|
|
372
374
|
```
|
|
373
375
|
|
|
374
|
-
## When to Use `sync()
|
|
376
|
+
## When to Use `catchup()`, `sync()`, and `join()`
|
|
375
377
|
|
|
376
|
-
Use **`
|
|
378
|
+
Use **`catchup()`** when you only want to pull remote updates into the local
|
|
379
|
+
CRDT:
|
|
377
380
|
|
|
378
381
|
```ts
|
|
379
|
-
//
|
|
382
|
+
// Pull remote changes without uploading local pending changes.
|
|
383
|
+
const caughtUp = await transport.catchup();
|
|
384
|
+
if (!caughtUp.ok) throw caughtUp.error;
|
|
385
|
+
// caughtUp.value.cursor contains the replay progress after the pull.
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
`catchup()` is safe to call while a room is live. When `join()` has a healthy
|
|
389
|
+
SSE/long-poll read loop, `catchup()` returns immediately because the live loop
|
|
390
|
+
is already catching up continuously. Pass `{ force: true }` to issue one
|
|
391
|
+
explicit non-SSE offset read anyway, for example after app foreground or device
|
|
392
|
+
wake:
|
|
393
|
+
|
|
394
|
+
```ts
|
|
395
|
+
await transport.catchup({ force: true });
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
If the live read side of the room is reconnecting, disconnected, or in error,
|
|
399
|
+
`catchup()` skips the live backoff path and tries one immediate non-SSE
|
|
400
|
+
catch-up read from the room's current cursor. A successful call updates the
|
|
401
|
+
local cursor and nudges the live loops to reconnect, but it does not by itself
|
|
402
|
+
guarantee that local pending writes have reached the server.
|
|
403
|
+
|
|
404
|
+
Use **`sync()`** when you need a one-shot bidirectional sync without entering
|
|
405
|
+
live mode:
|
|
406
|
+
|
|
407
|
+
```ts
|
|
408
|
+
// Offline-first: pull remote changes, upload local changes, then work offline.
|
|
380
409
|
const synced = await transport.sync();
|
|
381
410
|
if (!synced.ok) throw synced.error;
|
|
382
411
|
// synced.value.cursor contains the replay progress after sync.
|
|
383
412
|
```
|
|
384
413
|
|
|
414
|
+
Use `sync()` or `subscription.waitUntilSynced()` when the caller needs local
|
|
415
|
+
pending changes uploaded to the server.
|
|
416
|
+
|
|
385
417
|
Use **`join()`** for real-time collaboration. It does everything `sync()` does
|
|
386
418
|
and then keeps the connection alive for continuous bidirectional sync:
|
|
387
419
|
|
|
@@ -1021,7 +1053,9 @@ const transport = new StreamsCrdt({
|
|
|
1021
1053
|
- `TransportError` — discriminated error union
|
|
1022
1054
|
`apply_incomplete` is returned when remote data was read but the CRDT adapter
|
|
1023
1055
|
still has unresolved dependencies and the cursor cannot be saved.
|
|
1024
|
-
- `
|
|
1056
|
+
- `TransportCatchupParams` — `catchup()` options
|
|
1057
|
+
- `TransportCreateStreamSuccess`, `TransportDeleteStreamSuccess`,
|
|
1058
|
+
`TransportCatchupSuccess`, `TransportSyncSuccess` — result payloads
|
|
1025
1059
|
- `TransportJoinParams` — `join()` options
|
|
1026
1060
|
- `TransportSubscription` — active live subscription handle
|
|
1027
1061
|
- `TransportRoomStatus` — `"joined" | "reconnecting" | "disconnected" | "error"`
|
package/dist/flock.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
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";
|
|
2
2
|
import { ExportBundle, Flock, VersionVector, VersionVector as VersionVector$1 } from "@loro-dev/flock-wasm";
|
|
3
3
|
|
|
4
4
|
//#region src/flock.d.ts
|
|
@@ -7,5 +7,5 @@ import { ExportBundle, Flock, VersionVector, VersionVector as VersionVector$1 }
|
|
|
7
7
|
*/
|
|
8
8
|
declare function createFlockAdapter(flock: Flock): CrdtAdapter<VersionVector$1>;
|
|
9
9
|
//#endregion
|
|
10
|
-
export { BeforeRemoteCursorSaveContext, BeforeRemoteCursorSaveHook, CrdtAdapter, CrdtApplyOutcome, CrdtApplyReturn, CrdtUnresolvedSpan, CrdtUpdateBatch, E2eeEncryptionOptions, PayloadProtectionError as E2eeError, PayloadProtectionError, E2eeKey, E2eeKeyProvider, E2eeOptions, E2eeReadPolicy, E2eeScope, E2eeWritePolicy, EphemeralStreamAdaptor, EphemeralStreamCrdt, EphemeralStreamCrdtOptions, EphemeralStreamJoinParams, EphemeralStreamSubscription, type ExportBundle, 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, TransportCreateStreamSuccess, TransportDeleteStreamSuccess, TransportError, TransportJoinParams, TransportRoomStatus, TransportSnapshotUploadSuccess, TransportSubscription, TransportSyncSuccess, type VersionVector, WriteOnlyAppendResult, createFlockAdapter, createInitialRemoteCursor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
10
|
+
export { BeforeRemoteCursorSaveContext, BeforeRemoteCursorSaveHook, CrdtAdapter, CrdtApplyOutcome, CrdtApplyReturn, CrdtUnresolvedSpan, CrdtUpdateBatch, E2eeEncryptionOptions, PayloadProtectionError as E2eeError, PayloadProtectionError, E2eeKey, E2eeKeyProvider, E2eeOptions, E2eeReadPolicy, E2eeScope, E2eeWritePolicy, EphemeralStreamAdaptor, EphemeralStreamCrdt, EphemeralStreamCrdtOptions, EphemeralStreamJoinParams, EphemeralStreamSubscription, type ExportBundle, 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, type VersionVector, WriteOnlyAppendResult, createFlockAdapter, createInitialRemoteCursor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
11
11
|
//# sourceMappingURL=flock.d.ts.map
|
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-
|
|
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";
|
|
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
|
|
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, TransportCreateStreamSuccess, TransportDeleteStreamSuccess, TransportError, TransportJoinParams, TransportRoomStatus, TransportSnapshotUploadSuccess, TransportSubscription, TransportSyncSuccess, WriteOnlyAppendResult, createInitialRemoteCursor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
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";
|
|
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-
|
|
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";
|
|
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
|
|
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";
|
|
2
2
|
import { LoroDoc } from "loro-crdt";
|
|
3
3
|
|
|
4
4
|
//#region src/loro.d.ts
|
|
@@ -41,5 +41,5 @@ interface LoroEphemeralStoreLike {
|
|
|
41
41
|
declare function EphemeralStoreAdaptor(store: LoroEphemeralStoreLike): EphemeralStreamAdaptor;
|
|
42
42
|
declare const createLoroEphemeralStoreAdaptor: typeof EphemeralStoreAdaptor;
|
|
43
43
|
//#endregion
|
|
44
|
-
export { BeforeRemoteCursorSaveContext, BeforeRemoteCursorSaveHook, CrdtAdapter, CrdtApplyOutcome, CrdtApplyReturn, CrdtUnresolvedSpan, CrdtUpdateBatch, E2eeEncryptionOptions, PayloadProtectionError as E2eeError, PayloadProtectionError, E2eeKey, E2eeKeyProvider, E2eeOptions, E2eeReadPolicy, E2eeScope, E2eeWritePolicy, EphemeralStoreAdaptor, EphemeralStreamAdaptor, EphemeralStreamCrdt, EphemeralStreamCrdtOptions, EphemeralStreamJoinParams, EphemeralStreamSubscription, InMemoryRemoteCursorStore, IndexedDbRemoteCursorStore, IndexedDbRemoteCursorStoreOptions, IsolatedCrdtAdapter, JsonObject, JsonValue, LoroEphemeralStoreLike, PayloadProtectionEncryptionOptions, PayloadProtectionKey, PayloadProtectionKeyProvider, PayloadProtectionOptions, PayloadProtectionReadPolicy, PayloadProtectionScope, PayloadProtectionWritePolicy, RemoteCursor, RemoteCursorSaveSource, RemoteCursorStore, Result, SnapshotCodec, SnapshotTransformHook, SnapshotUploadOptions, StreamsAuthContext, StreamsAuthProvider, StreamsCrdt, StreamsCrdtOptions, StreamsCrdtShardUrlsOptions, TransportCreateStreamSuccess, TransportDeleteStreamSuccess, TransportError, TransportJoinParams, TransportRoomStatus, TransportSnapshotUploadSuccess, TransportSubscription, TransportSyncSuccess, WriteOnlyAppendResult, createInitialRemoteCursor, createLoroDocAdapter, createLoroEphemeralStoreAdaptor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
44
|
+
export { BeforeRemoteCursorSaveContext, BeforeRemoteCursorSaveHook, CrdtAdapter, CrdtApplyOutcome, CrdtApplyReturn, CrdtUnresolvedSpan, CrdtUpdateBatch, E2eeEncryptionOptions, PayloadProtectionError as E2eeError, PayloadProtectionError, E2eeKey, E2eeKeyProvider, E2eeOptions, E2eeReadPolicy, E2eeScope, E2eeWritePolicy, EphemeralStoreAdaptor, EphemeralStreamAdaptor, EphemeralStreamCrdt, EphemeralStreamCrdtOptions, EphemeralStreamJoinParams, EphemeralStreamSubscription, InMemoryRemoteCursorStore, IndexedDbRemoteCursorStore, IndexedDbRemoteCursorStoreOptions, IsolatedCrdtAdapter, JsonObject, JsonValue, LoroEphemeralStoreLike, 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, createLoroDocAdapter, createLoroEphemeralStoreAdaptor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
45
45
|
//# sourceMappingURL=loro.d.ts.map
|
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-
|
|
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";
|
|
2
2
|
import { LoroDoc, VersionVector, decodeImportBlobMeta } from "loro-crdt";
|
|
3
3
|
//#region src/loro.ts
|
|
4
4
|
function batchImportUpdates(doc, updates) {
|
|
@@ -356,6 +356,24 @@ interface TransportDeleteStreamSuccess {
|
|
|
356
356
|
interface TransportSyncSuccess<TVersion extends JsonObject = JsonObject> {
|
|
357
357
|
readonly cursor: RemoteCursor<TVersion>;
|
|
358
358
|
}
|
|
359
|
+
/**
|
|
360
|
+
* Optional parameters for a `catchup()` call.
|
|
361
|
+
*/
|
|
362
|
+
interface TransportCatchupParams {
|
|
363
|
+
/**
|
|
364
|
+
* When `false` or omitted, an active healthy live read loop is treated as
|
|
365
|
+
* already catching up and `catchup()` returns immediately with the current
|
|
366
|
+
* cursor. When `true`, the transport performs one non-SSE offset read even
|
|
367
|
+
* if live SSE/long-poll is currently healthy.
|
|
368
|
+
*/
|
|
369
|
+
readonly force?: boolean;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Result payload returned by `catchup()`.
|
|
373
|
+
*/
|
|
374
|
+
interface TransportCatchupSuccess<TVersion extends JsonObject = JsonObject> {
|
|
375
|
+
readonly cursor: RemoteCursor<TVersion>;
|
|
376
|
+
}
|
|
359
377
|
/**
|
|
360
378
|
* Result payload returned by the internal snapshot upload test hook.
|
|
361
379
|
*/
|
|
@@ -732,6 +750,21 @@ interface StreamsCrdtLike<TVersion extends JsonObject> {
|
|
|
732
750
|
createStream(): Promise<Result<TransportCreateStreamSuccess, TransportError>>;
|
|
733
751
|
deleteStream(): Promise<Result<TransportDeleteStreamSuccess, TransportError>>;
|
|
734
752
|
sync(): Promise<Result<TransportSyncSuccess<TVersion>, TransportError>>;
|
|
753
|
+
/**
|
|
754
|
+
* Pulls remote stream updates into the local CRDT without intentionally
|
|
755
|
+
* appending new local updates.
|
|
756
|
+
*
|
|
757
|
+
* If a healthy `join()` live read loop is active, this is a fast no-op by
|
|
758
|
+
* default because the loop is already catching up continuously. Pass
|
|
759
|
+
* `{ force: true }` to issue one explicit non-SSE offset read anyway.
|
|
760
|
+
*
|
|
761
|
+
* If the live read side of a join is reconnecting, disconnected, or in
|
|
762
|
+
* error, `catchup()` attempts one immediate non-SSE offset read from the
|
|
763
|
+
* room's current cursor and then nudges the live loops to reconnect. Use
|
|
764
|
+
* `sync()` or `subscription.waitUntilSynced()` when the caller also needs
|
|
765
|
+
* local pending changes uploaded to the server.
|
|
766
|
+
*/
|
|
767
|
+
catchup(params?: TransportCatchupParams): Promise<Result<TransportCatchupSuccess<TVersion>, TransportError>>;
|
|
735
768
|
/**
|
|
736
769
|
* Appends only locally observed batches without reading remote state first.
|
|
737
770
|
*
|
|
@@ -840,6 +873,16 @@ declare class StreamsCrdt<TVersion extends JsonObject> implements StreamsCrdtLik
|
|
|
840
873
|
* Runs one bootstrap/catch-up cycle without entering live mode.
|
|
841
874
|
*/
|
|
842
875
|
sync(): Promise<Result<TransportSyncSuccess<TVersion>, TransportError>>;
|
|
876
|
+
/**
|
|
877
|
+
* Pulls remote updates into the local CRDT without intentionally appending
|
|
878
|
+
* new local updates.
|
|
879
|
+
*
|
|
880
|
+
* Healthy live reads already catch up continuously, so an active `join()`
|
|
881
|
+
* returns immediately unless `force: true` is passed. Reconnecting or
|
|
882
|
+
* terminal live reads perform one immediate non-SSE offset read and then
|
|
883
|
+
* nudge the room to reconnect.
|
|
884
|
+
*/
|
|
885
|
+
catchup(params?: TransportCatchupParams): Promise<Result<TransportCatchupSuccess<TVersion>, TransportError>>;
|
|
843
886
|
/**
|
|
844
887
|
* Appends local CRDT updates without reading the stream first.
|
|
845
888
|
*
|
|
@@ -859,8 +902,10 @@ declare class StreamsCrdt<TVersion extends JsonObject> implements StreamsCrdtLik
|
|
|
859
902
|
private performInitialJoinSync;
|
|
860
903
|
private createInitialCursor;
|
|
861
904
|
private resolveInitialRemoteState;
|
|
905
|
+
private resolvePullOnlyRemoteState;
|
|
906
|
+
private catchupJoinState;
|
|
862
907
|
private bootstrapState;
|
|
863
|
-
private
|
|
908
|
+
private catchupFromCursor;
|
|
864
909
|
private catchupOrGone;
|
|
865
910
|
private recoverLiveIncompleteRemoteApply;
|
|
866
911
|
private appendLocalBatch;
|
|
@@ -1005,5 +1050,5 @@ declare function createStreamUrl(input: {
|
|
|
1005
1050
|
baseUrl?: string;
|
|
1006
1051
|
}): string;
|
|
1007
1052
|
//#endregion
|
|
1008
|
-
export {
|
|
1009
|
-
//# sourceMappingURL=stream-id-
|
|
1053
|
+
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
|
|
@@ -2495,6 +2495,34 @@ var StreamsCrdt = class StreamsCrdt {
|
|
|
2495
2495
|
}
|
|
2496
2496
|
}
|
|
2497
2497
|
/**
|
|
2498
|
+
* Pulls remote updates into the local CRDT without intentionally appending
|
|
2499
|
+
* new local updates.
|
|
2500
|
+
*
|
|
2501
|
+
* Healthy live reads already catch up continuously, so an active `join()`
|
|
2502
|
+
* returns immediately unless `force: true` is passed. Reconnecting or
|
|
2503
|
+
* terminal live reads perform one immediate non-SSE offset read and then
|
|
2504
|
+
* nudge the room to reconnect.
|
|
2505
|
+
*/
|
|
2506
|
+
async catchup(params = {}) {
|
|
2507
|
+
try {
|
|
2508
|
+
this.disableWriteOnlyMode("appendWriteOnly cannot be used after catchup() on the same transport");
|
|
2509
|
+
const state = this.joinState;
|
|
2510
|
+
if (state != null && !state.closed) return {
|
|
2511
|
+
ok: true,
|
|
2512
|
+
value: { cursor: await this.catchupJoinState(state, params) }
|
|
2513
|
+
};
|
|
2514
|
+
return {
|
|
2515
|
+
ok: true,
|
|
2516
|
+
value: { cursor: (await this.resolvePullOnlyRemoteState()).cursor }
|
|
2517
|
+
};
|
|
2518
|
+
} catch (error) {
|
|
2519
|
+
return {
|
|
2520
|
+
ok: false,
|
|
2521
|
+
error: toTransportError(error)
|
|
2522
|
+
};
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
/**
|
|
2498
2526
|
* Appends local CRDT updates without reading the stream first.
|
|
2499
2527
|
*
|
|
2500
2528
|
* Use this for write-only actors whose auth token may POST to the stream but
|
|
@@ -2747,6 +2775,40 @@ var StreamsCrdt = class StreamsCrdt {
|
|
|
2747
2775
|
return await this.bootstrapState(this.createInitialCursor());
|
|
2748
2776
|
}
|
|
2749
2777
|
}
|
|
2778
|
+
async resolvePullOnlyRemoteState() {
|
|
2779
|
+
const loaded = await this.remoteCursorStore.load(this.streamUrl);
|
|
2780
|
+
const cursor = loaded ?? this.createInitialCursor();
|
|
2781
|
+
try {
|
|
2782
|
+
if (loaded == null) return await this.bootstrapState(cursor);
|
|
2783
|
+
return await this.catchupFromCursor(cursor);
|
|
2784
|
+
} catch (error) {
|
|
2785
|
+
if (!isStreamNotFoundError(error) || !this.createStreamIfMissing) throw error;
|
|
2786
|
+
await this.ensureStreamExists();
|
|
2787
|
+
return await this.bootstrapState(this.createInitialCursor());
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
async catchupJoinState(state, params) {
|
|
2791
|
+
if (state.readSubStatus === "connecting") {
|
|
2792
|
+
await state.started;
|
|
2793
|
+
return state.cursor;
|
|
2794
|
+
}
|
|
2795
|
+
if (state.readSubStatus === "ok" && params.force !== true) return state.cursor;
|
|
2796
|
+
const cursor = await this.enqueueExclusive(async () => {
|
|
2797
|
+
if (state.closed) throw new Error("subscription closed");
|
|
2798
|
+
const caughtUp = await this.catchupFromCursor(state.cursor, void 0, state.streamCursor, (previousVersion, nextVersion) => {
|
|
2799
|
+
this.snapshotManager.observeRemoteVersion(state, previousVersion, nextVersion);
|
|
2800
|
+
});
|
|
2801
|
+
state.cursor = caughtUp.cursor;
|
|
2802
|
+
state.streamCursor = caughtUp.streamCursor;
|
|
2803
|
+
return state.cursor;
|
|
2804
|
+
});
|
|
2805
|
+
if (state.closed) return cursor;
|
|
2806
|
+
state.retryAttempt = 0;
|
|
2807
|
+
state.lastError = void 0;
|
|
2808
|
+
if (state.readSubStatus !== "ok" || state.writeSubStatus === "error") this.rejoin();
|
|
2809
|
+
else if (state.pendingLocal.length > 0) this.flushPendingLocal(state);
|
|
2810
|
+
return cursor;
|
|
2811
|
+
}
|
|
2750
2812
|
async bootstrapState(cursor, options = {}) {
|
|
2751
2813
|
const cursorManager = options.cursorManager ?? this.cursorManager;
|
|
2752
2814
|
const result = await this.client.bootstrap();
|
|
@@ -2766,7 +2828,7 @@ var StreamsCrdt = class StreamsCrdt {
|
|
|
2766
2828
|
streamCursor: bootstrapCursor
|
|
2767
2829
|
};
|
|
2768
2830
|
}
|
|
2769
|
-
async
|
|
2831
|
+
async catchupFromCursor(cursor, live, streamCursor, onRemoteVersionApplied) {
|
|
2770
2832
|
const result = await this.catchupOrGone(cursor, {
|
|
2771
2833
|
live,
|
|
2772
2834
|
streamCursor,
|
|
@@ -3482,4 +3544,4 @@ function createStreamUrl(input) {
|
|
|
3482
3544
|
//#endregion
|
|
3483
3545
|
export { InMemoryRemoteCursorStore as a, EphemeralStreamCrdt as c, StreamsCrdt as i, PayloadProtectionError as l, isValidBucketId as n, IndexedDbRemoteCursorStore as o, isValidRillId as r, createInitialRemoteCursor as s, createStreamUrl as t };
|
|
3484
3546
|
|
|
3485
|
-
//# sourceMappingURL=stream-id-
|
|
3547
|
+
//# sourceMappingURL=stream-id-fOF9ZqCH.js.map
|