@loro-dev/streams-crdt 0.7.1 → 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.
- package/README.md +37 -0
- package/dist/flock.d.ts +2 -2
- package/dist/flock.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/loro.d.ts +27 -2
- package/dist/loro.js +24 -2
- package/dist/loro.js.map +1 -1
- package/dist/{stream-id-CS7SzuLW.d.ts → stream-id-BXJvwX_O.d.ts} +117 -2
- package/dist/{stream-id-D0qcbI5c.js → stream-id-CF1egQDz.js} +1034 -400
- package/dist/stream-id-CF1egQDz.js.map +1 -0
- package/package.json +4 -2
- package/dist/stream-id-D0qcbI5c.js.map +0 -1
package/README.md
CHANGED
|
@@ -118,6 +118,43 @@ const sub = joined.value;
|
|
|
118
118
|
checked out or detached, call `checkoutToLatest()` or `attach()` before passing
|
|
119
119
|
it to `StreamsCrdt`.
|
|
120
120
|
|
|
121
|
+
## Quick Start (Loro EphemeralStore)
|
|
122
|
+
|
|
123
|
+
Use a separate `EphemeralStreamCrdt` for presence-like Loro `EphemeralStore`
|
|
124
|
+
data. It bootstraps through the first SSE event, posts local ephemeral updates,
|
|
125
|
+
and periodically re-announces `store.encodeAll()` so reconnecting peers can
|
|
126
|
+
recover the current live state without replaying old presence history.
|
|
127
|
+
|
|
128
|
+
Ephemeral live delivery is latest-state oriented. The server may keep only a
|
|
129
|
+
tiny live fanout queue for current SSE subscribers and may disconnect slow
|
|
130
|
+
subscribers instead of buffering every intermediate cursor or presence update.
|
|
131
|
+
The client reconnects and receives a fresh bootstrap, so the local store
|
|
132
|
+
converges to current state without requiring offset replay.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { EphemeralStore } from "loro-crdt";
|
|
136
|
+
import {
|
|
137
|
+
EphemeralStreamCrdt,
|
|
138
|
+
EphemeralStoreAdaptor,
|
|
139
|
+
createStreamUrl,
|
|
140
|
+
} from "@loro-dev/streams-crdt/loro";
|
|
141
|
+
|
|
142
|
+
const store = new EphemeralStore();
|
|
143
|
+
const docStreamUrl = createStreamUrl({
|
|
144
|
+
bucketId: "my-bucket",
|
|
145
|
+
streamId: "doc-1",
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const presence = new EphemeralStreamCrdt({
|
|
149
|
+
streamUrl: `${docStreamUrl}?ephemeral=presence`,
|
|
150
|
+
auth: async () => "<gateway-jwt>",
|
|
151
|
+
adaptor: EphemeralStoreAdaptor(store),
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const joinedPresence = await presence.join();
|
|
155
|
+
if (!joinedPresence.ok) throw joinedPresence.error;
|
|
156
|
+
```
|
|
157
|
+
|
|
121
158
|
## Quick Start (Flock)
|
|
122
159
|
|
|
123
160
|
```ts
|
package/dist/flock.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { $ as RemoteCursorStore, A as Result, B as TransportJoinParams, C as PayloadProtectionEncryptionOptions, D as PayloadProtectionReadPolicy, E as PayloadProtectionOptions, F as StreamsAuthProvider, G as WriteOnlyAppendResult, H as TransportSnapshotUploadSuccess, I as StreamsCrdtOptions, J as InMemoryRemoteCursorStore, K as BeforeRemoteCursorSaveContext, L as TransportCreateStreamSuccess, M as SnapshotTransformHook, N as SnapshotUploadOptions, O as PayloadProtectionScope, P as StreamsAuthContext, Q as RemoteCursorSaveSource, R as TransportDeleteStreamSuccess, S as JsonValue, T as PayloadProtectionKeyProvider, U as TransportSubscription, V as TransportRoomStatus, W as TransportSyncSuccess, X as IndexedDbRemoteCursorStoreOptions, Y as IndexedDbRemoteCursorStore, Z as RemoteCursor, _ as EphemeralStreamCrdtOptions, a as EphemeralStreamCrdt, b as IsolatedCrdtAdapter, c as CrdtUpdateBatch, d as E2eeKeyProvider, et as createInitialRemoteCursor, f as E2eeOptions, g as EphemeralStreamAdaptor, h as E2eeWritePolicy, i as PayloadProtectionError, j as SnapshotCodec, k as PayloadProtectionWritePolicy, l as E2eeEncryptionOptions, m as E2eeScope, n as isValidBucketId, o as StreamsCrdt, p as E2eeReadPolicy, q as BeforeRemoteCursorSaveHook, r as isValidRillId, s as CrdtAdapter, t as createStreamUrl, u as E2eeKey, v as EphemeralStreamJoinParams, w as PayloadProtectionKey, x as JsonObject, y as EphemeralStreamSubscription, z as TransportError } from "./stream-id-BXJvwX_O.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, CrdtUpdateBatch, E2eeEncryptionOptions, PayloadProtectionError as E2eeError, PayloadProtectionError, E2eeKey, E2eeKeyProvider, E2eeOptions, E2eeReadPolicy, E2eeScope, E2eeWritePolicy, 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, TransportCreateStreamSuccess, TransportDeleteStreamSuccess, TransportError, TransportJoinParams, TransportRoomStatus, TransportSnapshotUploadSuccess, TransportSubscription, TransportSyncSuccess, type VersionVector, WriteOnlyAppendResult, createFlockAdapter, createInitialRemoteCursor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
10
|
+
export { BeforeRemoteCursorSaveContext, BeforeRemoteCursorSaveHook, CrdtAdapter, 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, 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
|
|
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-CF1egQDz.js";
|
|
2
2
|
import { Flock } from "@loro-dev/flock-wasm";
|
|
3
3
|
//#region src/flock.ts
|
|
4
4
|
function isAfter(entry, current) {
|
|
@@ -149,6 +149,6 @@ function createFlockAdapter(flock) {
|
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
151
|
//#endregion
|
|
152
|
-
export { PayloadProtectionError as E2eeError, PayloadProtectionError, InMemoryRemoteCursorStore, IndexedDbRemoteCursorStore, StreamsCrdt, createFlockAdapter, createInitialRemoteCursor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
152
|
+
export { PayloadProtectionError as E2eeError, PayloadProtectionError, EphemeralStreamCrdt, InMemoryRemoteCursorStore, IndexedDbRemoteCursorStore, StreamsCrdt, createFlockAdapter, createInitialRemoteCursor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
153
153
|
|
|
154
154
|
//# sourceMappingURL=flock.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { BeforeRemoteCursorSaveContext, BeforeRemoteCursorSaveHook, CrdtAdapter, CrdtUpdateBatch, E2eeEncryptionOptions, PayloadProtectionError as E2eeError, PayloadProtectionError, E2eeKey, E2eeKeyProvider, E2eeOptions, E2eeReadPolicy, E2eeScope, E2eeWritePolicy, InMemoryRemoteCursorStore, IndexedDbRemoteCursorStore, IndexedDbRemoteCursorStoreOptions, IsolatedCrdtAdapter, JsonObject, JsonValue, PayloadProtectionEncryptionOptions, PayloadProtectionKey, PayloadProtectionKeyProvider, PayloadProtectionOptions, PayloadProtectionReadPolicy, PayloadProtectionScope, PayloadProtectionWritePolicy, RemoteCursor, RemoteCursorSaveSource, RemoteCursorStore, Result, SnapshotCodec, SnapshotTransformHook, SnapshotUploadOptions, StreamsAuthContext, StreamsAuthProvider, StreamsCrdt, StreamsCrdtOptions, TransportCreateStreamSuccess, TransportDeleteStreamSuccess, TransportError, TransportJoinParams, TransportRoomStatus, TransportSnapshotUploadSuccess, TransportSubscription, TransportSyncSuccess, WriteOnlyAppendResult, createInitialRemoteCursor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
1
|
+
import { $ as RemoteCursorStore, A as Result, B as TransportJoinParams, C as PayloadProtectionEncryptionOptions, D as PayloadProtectionReadPolicy, E as PayloadProtectionOptions, F as StreamsAuthProvider, G as WriteOnlyAppendResult, H as TransportSnapshotUploadSuccess, I as StreamsCrdtOptions, J as InMemoryRemoteCursorStore, K as BeforeRemoteCursorSaveContext, L as TransportCreateStreamSuccess, M as SnapshotTransformHook, N as SnapshotUploadOptions, O as PayloadProtectionScope, P as StreamsAuthContext, Q as RemoteCursorSaveSource, R as TransportDeleteStreamSuccess, S as JsonValue, T as PayloadProtectionKeyProvider, U as TransportSubscription, V as TransportRoomStatus, W as TransportSyncSuccess, X as IndexedDbRemoteCursorStoreOptions, Y as IndexedDbRemoteCursorStore, Z as RemoteCursor, _ as EphemeralStreamCrdtOptions, a as EphemeralStreamCrdt, b as IsolatedCrdtAdapter, c as CrdtUpdateBatch, d as E2eeKeyProvider, et as createInitialRemoteCursor, f as E2eeOptions, g as EphemeralStreamAdaptor, h as E2eeWritePolicy, i as PayloadProtectionError, j as SnapshotCodec, k as PayloadProtectionWritePolicy, l as E2eeEncryptionOptions, m as E2eeScope, n as isValidBucketId, o as StreamsCrdt, p as E2eeReadPolicy, q as BeforeRemoteCursorSaveHook, r as isValidRillId, s as CrdtAdapter, t as createStreamUrl, u as E2eeKey, v as EphemeralStreamJoinParams, w as PayloadProtectionKey, x as JsonObject, y as EphemeralStreamSubscription, z as TransportError } from "./stream-id-BXJvwX_O.js";
|
|
2
|
+
export { BeforeRemoteCursorSaveContext, BeforeRemoteCursorSaveHook, CrdtAdapter, 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, 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
|
|
2
|
-
export { PayloadProtectionError as E2eeError, PayloadProtectionError, InMemoryRemoteCursorStore, IndexedDbRemoteCursorStore, StreamsCrdt, createInitialRemoteCursor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
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-CF1egQDz.js";
|
|
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 { A as
|
|
1
|
+
import { $ as RemoteCursorStore, A as Result, B as TransportJoinParams, C as PayloadProtectionEncryptionOptions, D as PayloadProtectionReadPolicy, E as PayloadProtectionOptions, F as StreamsAuthProvider, G as WriteOnlyAppendResult, H as TransportSnapshotUploadSuccess, I as StreamsCrdtOptions, J as InMemoryRemoteCursorStore, K as BeforeRemoteCursorSaveContext, L as TransportCreateStreamSuccess, M as SnapshotTransformHook, N as SnapshotUploadOptions, O as PayloadProtectionScope, P as StreamsAuthContext, Q as RemoteCursorSaveSource, R as TransportDeleteStreamSuccess, S as JsonValue, T as PayloadProtectionKeyProvider, U as TransportSubscription, V as TransportRoomStatus, W as TransportSyncSuccess, X as IndexedDbRemoteCursorStoreOptions, Y as IndexedDbRemoteCursorStore, Z as RemoteCursor, _ as EphemeralStreamCrdtOptions, a as EphemeralStreamCrdt, b as IsolatedCrdtAdapter, c as CrdtUpdateBatch, d as E2eeKeyProvider, et as createInitialRemoteCursor, f as E2eeOptions, g as EphemeralStreamAdaptor, h as E2eeWritePolicy, i as PayloadProtectionError, j as SnapshotCodec, k as PayloadProtectionWritePolicy, l as E2eeEncryptionOptions, m as E2eeScope, n as isValidBucketId, o as StreamsCrdt, p as E2eeReadPolicy, q as BeforeRemoteCursorSaveHook, r as isValidRillId, s as CrdtAdapter, t as createStreamUrl, u as E2eeKey, v as EphemeralStreamJoinParams, w as PayloadProtectionKey, x as JsonObject, y as EphemeralStreamSubscription, z as TransportError } from "./stream-id-BXJvwX_O.js";
|
|
2
2
|
import { LoroDoc } from "loro-crdt";
|
|
3
3
|
|
|
4
4
|
//#region src/loro.d.ts
|
|
@@ -17,6 +17,31 @@ import { LoroDoc } from "loro-crdt";
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
declare function createLoroDocAdapter(doc: LoroDoc): CrdtAdapter<JsonObject>;
|
|
20
|
+
/**
|
|
21
|
+
* Structural subset of Loro's `EphemeralStore`.
|
|
22
|
+
*/
|
|
23
|
+
interface LoroEphemeralStoreLike {
|
|
24
|
+
/** Encodes the current non-expired store state for bootstrap/lease publish. */
|
|
25
|
+
encodeAll(): Uint8Array;
|
|
26
|
+
/** Applies one opaque Loro ephemeral update. */
|
|
27
|
+
apply(update: Uint8Array): void;
|
|
28
|
+
/** Subscribes to locally produced ephemeral updates. */
|
|
29
|
+
subscribeLocalUpdates(listener: (update: Uint8Array) => void): () => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Creates an ephemeral stream adaptor for a Loro `EphemeralStore`.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const room = new EphemeralStreamCrdt({
|
|
37
|
+
* streamUrl,
|
|
38
|
+
* auth,
|
|
39
|
+
* adaptor: EphemeralStoreAdaptor(store),
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare function EphemeralStoreAdaptor(store: LoroEphemeralStoreLike): EphemeralStreamAdaptor;
|
|
44
|
+
declare const createLoroEphemeralStoreAdaptor: typeof EphemeralStoreAdaptor;
|
|
20
45
|
//#endregion
|
|
21
|
-
export { BeforeRemoteCursorSaveContext, BeforeRemoteCursorSaveHook, CrdtAdapter, CrdtUpdateBatch, E2eeEncryptionOptions, PayloadProtectionError as E2eeError, PayloadProtectionError, E2eeKey, E2eeKeyProvider, E2eeOptions, E2eeReadPolicy, E2eeScope, E2eeWritePolicy, InMemoryRemoteCursorStore, IndexedDbRemoteCursorStore, IndexedDbRemoteCursorStoreOptions, IsolatedCrdtAdapter, JsonObject, JsonValue, PayloadProtectionEncryptionOptions, PayloadProtectionKey, PayloadProtectionKeyProvider, PayloadProtectionOptions, PayloadProtectionReadPolicy, PayloadProtectionScope, PayloadProtectionWritePolicy, RemoteCursor, RemoteCursorSaveSource, RemoteCursorStore, Result, SnapshotCodec, SnapshotTransformHook, SnapshotUploadOptions, StreamsAuthContext, StreamsAuthProvider, StreamsCrdt, StreamsCrdtOptions, TransportCreateStreamSuccess, TransportDeleteStreamSuccess, TransportError, TransportJoinParams, TransportRoomStatus, TransportSnapshotUploadSuccess, TransportSubscription, TransportSyncSuccess, WriteOnlyAppendResult, createInitialRemoteCursor, createLoroDocAdapter, createStreamUrl, isValidBucketId, isValidRillId };
|
|
46
|
+
export { BeforeRemoteCursorSaveContext, BeforeRemoteCursorSaveHook, CrdtAdapter, 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, TransportCreateStreamSuccess, TransportDeleteStreamSuccess, TransportError, TransportJoinParams, TransportRoomStatus, TransportSnapshotUploadSuccess, TransportSubscription, TransportSyncSuccess, WriteOnlyAppendResult, createInitialRemoteCursor, createLoroDocAdapter, createLoroEphemeralStoreAdaptor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
22
47
|
//# sourceMappingURL=loro.d.ts.map
|
package/dist/loro.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
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-CF1egQDz.js";
|
|
2
2
|
import { LoroDoc, VersionVector, decodeImportBlobMeta } from "loro-crdt";
|
|
3
3
|
//#region src/loro.ts
|
|
4
4
|
function batchImportUpdates(doc, updates) {
|
|
@@ -125,7 +125,29 @@ function createLoroDocAdapter(doc) {
|
|
|
125
125
|
}
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Creates an ephemeral stream adaptor for a Loro `EphemeralStore`.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* const room = new EphemeralStreamCrdt({
|
|
134
|
+
* streamUrl,
|
|
135
|
+
* auth,
|
|
136
|
+
* adaptor: EphemeralStoreAdaptor(store),
|
|
137
|
+
* });
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
function EphemeralStoreAdaptor(store) {
|
|
141
|
+
return {
|
|
142
|
+
encodeAll: () => store.encodeAll(),
|
|
143
|
+
applyRemoteUpdates: (updates) => {
|
|
144
|
+
for (const update of updates) store.apply(update);
|
|
145
|
+
},
|
|
146
|
+
subscribeLocalUpdates: (listener) => store.subscribeLocalUpdates(listener)
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const createLoroEphemeralStoreAdaptor = EphemeralStoreAdaptor;
|
|
128
150
|
//#endregion
|
|
129
|
-
export { PayloadProtectionError as E2eeError, PayloadProtectionError, InMemoryRemoteCursorStore, IndexedDbRemoteCursorStore, StreamsCrdt, createInitialRemoteCursor, createLoroDocAdapter, createStreamUrl, isValidBucketId, isValidRillId };
|
|
151
|
+
export { PayloadProtectionError as E2eeError, PayloadProtectionError, EphemeralStoreAdaptor, EphemeralStreamCrdt, InMemoryRemoteCursorStore, IndexedDbRemoteCursorStore, StreamsCrdt, createInitialRemoteCursor, createLoroDocAdapter, createLoroEphemeralStoreAdaptor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
130
152
|
|
|
131
153
|
//# sourceMappingURL=loro.js.map
|
package/dist/loro.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loro.js","names":[],"sources":["../src/loro.ts"],"sourcesContent":["import {\n decodeImportBlobMeta,\n LoroDoc,\n VersionVector,\n} from \"loro-crdt\";\n\nimport type { CrdtAdapter, JsonObject } from \"./types\";\n\nexport { StreamsCrdt } from \"./transport-runtime\";\nexport * from \"./shared\";\n\nfunction batchImportUpdates(doc: LoroDoc, updates: Uint8Array[]): void {\n if (\"batchImport\" in doc && typeof doc.batchImport === \"function\") {\n doc.batchImport(updates);\n } else {\n doc.importBatch(updates);\n }\n}\n\ntype PeerId = `${number}`;\ntype DocVersionRecord = Record<PeerId, number>;\n\nfunction toDocVersionRecord(version: VersionVector): DocVersionRecord {\n const out = {} as DocVersionRecord;\n for (const [peer, counter] of version.toJSON()) {\n out[peer as PeerId] = counter;\n }\n return out;\n}\n\nfunction toDocVersionMap(version: JsonObject): Map<PeerId, number> {\n const out = new Map<PeerId, number>();\n for (const [peer, counter] of Object.entries(version)) {\n if (typeof counter === \"number\" && Number.isFinite(counter)) {\n out.set(peer as PeerId, counter);\n }\n }\n return out;\n}\n\nfunction mergeDocVersions(\n base: DocVersionRecord,\n incoming: DocVersionRecord,\n): DocVersionRecord {\n const merged = new Map<PeerId, number>();\n for (const [peer, counter] of Object.entries(base)) {\n merged.set(peer as PeerId, counter);\n }\n for (const [peer, counter] of Object.entries(incoming)) {\n const peerId = peer as PeerId;\n merged.set(peerId, Math.max(merged.get(peerId) ?? 0, counter));\n }\n return toDocVersionRecord(VersionVector.parseJSON(merged));\n}\n\nfunction hasUpdatesSince(\n fromVersion: DocVersionRecord,\n currentVersion: DocVersionRecord,\n): boolean {\n for (const [peer, counter] of Object.entries(currentVersion)) {\n if (counter > (fromVersion[peer as PeerId] ?? 0)) {\n return true;\n }\n }\n return false;\n}\n\nfunction extractVersionFromUpdate(update: Uint8Array): DocVersionRecord | null {\n try {\n const meta = decodeImportBlobMeta(update, false);\n return toDocVersionRecord(meta.partialEndVersionVector);\n } catch {\n return null;\n }\n}\n\nfunction assertDocAttached(doc: LoroDoc): void {\n if (!doc.isDetached()) {\n return;\n }\n throw new Error(\n \"LoroDoc must be attached before using streams-crdt; \" +\n \"call checkoutToLatest() or attach() first\",\n );\n}\n\n/**\n * Creates a `CrdtAdapter` for one `LoroDoc`.\n *\n * The `LoroDoc` must be attached (not detached or checked out to a historical\n * version). If the document is detached, call `doc.checkoutToLatest()` or\n * `doc.attach()` before passing it here.\n *\n * @example\n * ```ts\n * const doc = new LoroDoc();\n * const adapter = createLoroDocAdapter(doc);\n * const transport = new StreamsCrdt({ streamUrl, adapter, auth });\n * ```\n */\nexport function createLoroDocAdapter(\n doc: LoroDoc,\n): CrdtAdapter<JsonObject> {\n return {\n emptyVersion: () => ({}),\n mergeVersions: (base, incoming) =>\n mergeDocVersions(base as DocVersionRecord, incoming as DocVersionRecord),\n exportSnapshot: () => {\n assertDocAttached(doc);\n return doc.export({ mode: \"snapshot\" });\n },\n applySnapshot: (snapshot) => {\n assertDocAttached(doc);\n doc.import(snapshot);\n return toDocVersionRecord(doc.version());\n },\n exportUpdates: (fromVersion) => {\n assertDocAttached(doc);\n const currentVersion = toDocVersionRecord(doc.version());\n if (\n !hasUpdatesSince(\n fromVersion as DocVersionRecord,\n currentVersion,\n )\n ) {\n return undefined;\n }\n const updates = [\n doc.export({\n mode: \"update\",\n from: VersionVector.parseJSON(toDocVersionMap(fromVersion)),\n }),\n ].filter((update) => update.byteLength > 0);\n if (updates.length === 0) {\n return undefined;\n }\n let version: DocVersionRecord = {};\n for (const update of updates) {\n const next = extractVersionFromUpdate(update);\n if (next != null) {\n version = mergeDocVersions(version, next);\n }\n }\n return {\n updates,\n version,\n };\n },\n applyRemoteUpdates: (updates, remoterVersion) => {\n assertDocAttached(doc);\n if (updates.length > 0) {\n batchImportUpdates(doc, updates);\n }\n let version = remoterVersion as DocVersionRecord;\n for (const update of updates) {\n const next = extractVersionFromUpdate(update);\n if (next != null) {\n version = mergeDocVersions(version, next);\n }\n }\n return version;\n },\n createIsolatedAdapter: () => {\n let isolatedDoc = new LoroDoc();\n return {\n applySnapshot: (snapshot) => {\n isolatedDoc = new LoroDoc();\n if (snapshot.byteLength > 0) {\n isolatedDoc.import(snapshot);\n }\n return toDocVersionRecord(isolatedDoc.version());\n },\n applyRemoteUpdates: (updates, remoterVersion) => {\n if (updates.length > 0) {\n batchImportUpdates(isolatedDoc, updates);\n }\n let version = remoterVersion as DocVersionRecord;\n for (const update of updates) {\n const next = extractVersionFromUpdate(update);\n if (next != null) {\n version = mergeDocVersions(version, next);\n }\n }\n return version;\n },\n };\n },\n subscribeLocalUpdates: (listener) => {\n assertDocAttached(doc);\n return doc.subscribeLocalUpdates((update) => {\n const version = extractVersionFromUpdate(update) ?? {};\n listener({ updates: [update], version });\n });\n },\n };\n}\n"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"loro.js","names":[],"sources":["../src/loro.ts"],"sourcesContent":["import {\n decodeImportBlobMeta,\n LoroDoc,\n VersionVector,\n} from \"loro-crdt\";\n\nimport type { CrdtAdapter, JsonObject } from \"./types\";\nimport type { EphemeralStreamAdaptor } from \"./types\";\n\nexport { EphemeralStreamCrdt } from \"./ephemeral-runtime\";\nexport { StreamsCrdt } from \"./transport-runtime\";\nexport * from \"./shared\";\n\nfunction batchImportUpdates(doc: LoroDoc, updates: Uint8Array[]): void {\n if (\"batchImport\" in doc && typeof doc.batchImport === \"function\") {\n doc.batchImport(updates);\n } else {\n doc.importBatch(updates);\n }\n}\n\ntype PeerId = `${number}`;\ntype DocVersionRecord = Record<PeerId, number>;\n\nfunction toDocVersionRecord(version: VersionVector): DocVersionRecord {\n const out = {} as DocVersionRecord;\n for (const [peer, counter] of version.toJSON()) {\n out[peer as PeerId] = counter;\n }\n return out;\n}\n\nfunction toDocVersionMap(version: JsonObject): Map<PeerId, number> {\n const out = new Map<PeerId, number>();\n for (const [peer, counter] of Object.entries(version)) {\n if (typeof counter === \"number\" && Number.isFinite(counter)) {\n out.set(peer as PeerId, counter);\n }\n }\n return out;\n}\n\nfunction mergeDocVersions(\n base: DocVersionRecord,\n incoming: DocVersionRecord,\n): DocVersionRecord {\n const merged = new Map<PeerId, number>();\n for (const [peer, counter] of Object.entries(base)) {\n merged.set(peer as PeerId, counter);\n }\n for (const [peer, counter] of Object.entries(incoming)) {\n const peerId = peer as PeerId;\n merged.set(peerId, Math.max(merged.get(peerId) ?? 0, counter));\n }\n return toDocVersionRecord(VersionVector.parseJSON(merged));\n}\n\nfunction hasUpdatesSince(\n fromVersion: DocVersionRecord,\n currentVersion: DocVersionRecord,\n): boolean {\n for (const [peer, counter] of Object.entries(currentVersion)) {\n if (counter > (fromVersion[peer as PeerId] ?? 0)) {\n return true;\n }\n }\n return false;\n}\n\nfunction extractVersionFromUpdate(update: Uint8Array): DocVersionRecord | null {\n try {\n const meta = decodeImportBlobMeta(update, false);\n return toDocVersionRecord(meta.partialEndVersionVector);\n } catch {\n return null;\n }\n}\n\nfunction assertDocAttached(doc: LoroDoc): void {\n if (!doc.isDetached()) {\n return;\n }\n throw new Error(\n \"LoroDoc must be attached before using streams-crdt; \" +\n \"call checkoutToLatest() or attach() first\",\n );\n}\n\n/**\n * Creates a `CrdtAdapter` for one `LoroDoc`.\n *\n * The `LoroDoc` must be attached (not detached or checked out to a historical\n * version). If the document is detached, call `doc.checkoutToLatest()` or\n * `doc.attach()` before passing it here.\n *\n * @example\n * ```ts\n * const doc = new LoroDoc();\n * const adapter = createLoroDocAdapter(doc);\n * const transport = new StreamsCrdt({ streamUrl, adapter, auth });\n * ```\n */\nexport function createLoroDocAdapter(\n doc: LoroDoc,\n): CrdtAdapter<JsonObject> {\n return {\n emptyVersion: () => ({}),\n mergeVersions: (base, incoming) =>\n mergeDocVersions(base as DocVersionRecord, incoming as DocVersionRecord),\n exportSnapshot: () => {\n assertDocAttached(doc);\n return doc.export({ mode: \"snapshot\" });\n },\n applySnapshot: (snapshot) => {\n assertDocAttached(doc);\n doc.import(snapshot);\n return toDocVersionRecord(doc.version());\n },\n exportUpdates: (fromVersion) => {\n assertDocAttached(doc);\n const currentVersion = toDocVersionRecord(doc.version());\n if (\n !hasUpdatesSince(\n fromVersion as DocVersionRecord,\n currentVersion,\n )\n ) {\n return undefined;\n }\n const updates = [\n doc.export({\n mode: \"update\",\n from: VersionVector.parseJSON(toDocVersionMap(fromVersion)),\n }),\n ].filter((update) => update.byteLength > 0);\n if (updates.length === 0) {\n return undefined;\n }\n let version: DocVersionRecord = {};\n for (const update of updates) {\n const next = extractVersionFromUpdate(update);\n if (next != null) {\n version = mergeDocVersions(version, next);\n }\n }\n return {\n updates,\n version,\n };\n },\n applyRemoteUpdates: (updates, remoterVersion) => {\n assertDocAttached(doc);\n if (updates.length > 0) {\n batchImportUpdates(doc, updates);\n }\n let version = remoterVersion as DocVersionRecord;\n for (const update of updates) {\n const next = extractVersionFromUpdate(update);\n if (next != null) {\n version = mergeDocVersions(version, next);\n }\n }\n return version;\n },\n createIsolatedAdapter: () => {\n let isolatedDoc = new LoroDoc();\n return {\n applySnapshot: (snapshot) => {\n isolatedDoc = new LoroDoc();\n if (snapshot.byteLength > 0) {\n isolatedDoc.import(snapshot);\n }\n return toDocVersionRecord(isolatedDoc.version());\n },\n applyRemoteUpdates: (updates, remoterVersion) => {\n if (updates.length > 0) {\n batchImportUpdates(isolatedDoc, updates);\n }\n let version = remoterVersion as DocVersionRecord;\n for (const update of updates) {\n const next = extractVersionFromUpdate(update);\n if (next != null) {\n version = mergeDocVersions(version, next);\n }\n }\n return version;\n },\n };\n },\n subscribeLocalUpdates: (listener) => {\n assertDocAttached(doc);\n return doc.subscribeLocalUpdates((update) => {\n const version = extractVersionFromUpdate(update) ?? {};\n listener({ updates: [update], version });\n });\n },\n };\n}\n\n/**\n * Structural subset of Loro's `EphemeralStore`.\n */\nexport interface LoroEphemeralStoreLike {\n /** Encodes the current non-expired store state for bootstrap/lease publish. */\n encodeAll(): Uint8Array;\n /** Applies one opaque Loro ephemeral update. */\n apply(update: Uint8Array): void;\n /** Subscribes to locally produced ephemeral updates. */\n subscribeLocalUpdates(listener: (update: Uint8Array) => void): () => void;\n}\n\n/**\n * Creates an ephemeral stream adaptor for a Loro `EphemeralStore`.\n *\n * @example\n * ```ts\n * const room = new EphemeralStreamCrdt({\n * streamUrl,\n * auth,\n * adaptor: EphemeralStoreAdaptor(store),\n * });\n * ```\n */\nexport function EphemeralStoreAdaptor(\n store: LoroEphemeralStoreLike,\n): EphemeralStreamAdaptor {\n return {\n encodeAll: () => store.encodeAll(),\n applyRemoteUpdates: (updates) => {\n for (const update of updates) {\n store.apply(update);\n }\n },\n subscribeLocalUpdates: (listener) =>\n store.subscribeLocalUpdates(listener),\n };\n}\n\nexport const createLoroEphemeralStoreAdaptor = EphemeralStoreAdaptor;\n"],"mappings":"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"}
|
|
@@ -392,6 +392,27 @@ interface TransportSubscription {
|
|
|
392
392
|
*/
|
|
393
393
|
readonly waitUntilSynced: () => Promise<void>;
|
|
394
394
|
}
|
|
395
|
+
/**
|
|
396
|
+
* Adapter contract for CRDT-like ephemeral stores.
|
|
397
|
+
*
|
|
398
|
+
* Ephemeral transports bootstrap through the first SSE event, then continue
|
|
399
|
+
* with live deltas only. They do not expose checkpoints, snapshots, or
|
|
400
|
+
* replayable offset history. `encodeAll()` is sent on join/reconnect/heartbeat
|
|
401
|
+
* so peers can converge on the caller's current presence state.
|
|
402
|
+
*/
|
|
403
|
+
interface EphemeralStreamAdaptor {
|
|
404
|
+
/** Encodes all currently live local ephemeral state. */
|
|
405
|
+
encodeAll(): MaybePromise<Uint8Array | null | undefined>;
|
|
406
|
+
/** Applies updates received from the remote ephemeral stream. */
|
|
407
|
+
applyRemoteUpdates(updates: readonly Uint8Array[]): MaybePromise<void>;
|
|
408
|
+
/** Subscribes to local ephemeral updates. Returns an unsubscribe function. */
|
|
409
|
+
subscribeLocalUpdates(listener: (update: Uint8Array) => void): () => void;
|
|
410
|
+
}
|
|
411
|
+
interface EphemeralStreamJoinParams {
|
|
412
|
+
/** Called when the live ephemeral subscription status changes. */
|
|
413
|
+
readonly onStatusChange?: (status: "connecting" | TransportRoomStatus) => void;
|
|
414
|
+
}
|
|
415
|
+
interface EphemeralStreamSubscription extends TransportSubscription {}
|
|
395
416
|
/**
|
|
396
417
|
* Local CRDT updates ready to append to Durable Streams.
|
|
397
418
|
*/
|
|
@@ -462,6 +483,34 @@ interface CrdtAdapter<TVersion extends JsonObject> {
|
|
|
462
483
|
/** Optional headers to include when creating the stream (e.g. retention config). */
|
|
463
484
|
getCreateStreamHeaders?(): MaybePromise<Record<string, string>>;
|
|
464
485
|
}
|
|
486
|
+
interface EphemeralStreamCrdtOptions {
|
|
487
|
+
/**
|
|
488
|
+
* Full ephemeral stream URL.
|
|
489
|
+
*
|
|
490
|
+
* The URL must include the channel query, usually
|
|
491
|
+
* `?ephemeral=presence` or the compatibility alias `?awareness=presence`.
|
|
492
|
+
*/
|
|
493
|
+
readonly streamUrl: string;
|
|
494
|
+
/**
|
|
495
|
+
* Ephemeral store adaptor.
|
|
496
|
+
*
|
|
497
|
+
* The public spelling intentionally matches Loro's "adaptor" examples.
|
|
498
|
+
*/
|
|
499
|
+
readonly adaptor: EphemeralStreamAdaptor;
|
|
500
|
+
/** Auth token source used for ephemeral POST and SSE requests. */
|
|
501
|
+
readonly auth?: StreamsAuthProvider;
|
|
502
|
+
/** Optional fetch implementation for tests, workers, or custom runtimes. */
|
|
503
|
+
readonly fetch?: (input: string, init?: RequestInit) => Promise<Response>;
|
|
504
|
+
/** Reconnect policy for the SSE read loop and local POST retry loop. */
|
|
505
|
+
readonly reconnectConfig?: Partial<ReconnectConfig>;
|
|
506
|
+
/**
|
|
507
|
+
* Interval for resending `adaptor.encodeAll()`. Set to `false` to disable.
|
|
508
|
+
* Defaults to 15 seconds, matching presence-style leases.
|
|
509
|
+
*/
|
|
510
|
+
readonly heartbeatMs?: number | false;
|
|
511
|
+
/** Enables diagnostic console logging for terminal read/write failures. */
|
|
512
|
+
readonly debug?: boolean;
|
|
513
|
+
}
|
|
465
514
|
/**
|
|
466
515
|
* Construction options for one `StreamsCrdt` instance.
|
|
467
516
|
*
|
|
@@ -585,6 +634,8 @@ declare class StreamsCrdt<TVersion extends JsonObject> implements StreamsCrdtLik
|
|
|
585
634
|
private readonly producerId;
|
|
586
635
|
private producerEpoch;
|
|
587
636
|
private nextProducerSeq;
|
|
637
|
+
private frozenLocalAppend?;
|
|
638
|
+
private committedPendingCount?;
|
|
588
639
|
private readonly pendingWriteOnly;
|
|
589
640
|
private writeOnlyCursor;
|
|
590
641
|
private unsubscribeWriteOnlyLocal?;
|
|
@@ -663,6 +714,15 @@ declare class StreamsCrdt<TVersion extends JsonObject> implements StreamsCrdtLik
|
|
|
663
714
|
private catchup;
|
|
664
715
|
private catchupOrGone;
|
|
665
716
|
private appendLocalBatch;
|
|
717
|
+
private appendLocalBatchDurably;
|
|
718
|
+
private appendLocalBatchRemote;
|
|
719
|
+
private getOrCreateFrozenLocalAppend;
|
|
720
|
+
private appendFrozenLocalBatchRemote;
|
|
721
|
+
private finalizeDirectLocalAppendIfNeeded;
|
|
722
|
+
private createCurrentProducerSession;
|
|
723
|
+
private commitProducerAck;
|
|
724
|
+
private abandonFrozenLocalAppend;
|
|
725
|
+
private consumeCommittedPendingCount;
|
|
666
726
|
/**
|
|
667
727
|
* Ensures the target stream exists, creating it if necessary.
|
|
668
728
|
* Tolerates 409 Conflict (stream already created concurrently).
|
|
@@ -712,6 +772,61 @@ declare class StreamsCrdt<TVersion extends JsonObject> implements StreamsCrdtLik
|
|
|
712
772
|
private logError;
|
|
713
773
|
}
|
|
714
774
|
//#endregion
|
|
775
|
+
//#region src/ephemeral-runtime.d.ts
|
|
776
|
+
/**
|
|
777
|
+
* Realtime transport for one ephemeral CRDT stream.
|
|
778
|
+
*
|
|
779
|
+
* This is intentionally separate from `StreamsCrdt`: it bootstraps through
|
|
780
|
+
* the first SSE event, then tails live deltas, and never stores a replay
|
|
781
|
+
* offset, snapshot checkpoint, or remote cursor.
|
|
782
|
+
*/
|
|
783
|
+
declare class EphemeralStreamCrdt {
|
|
784
|
+
/** Full ephemeral stream URL, including `?ephemeral=` or `?awareness=`. */
|
|
785
|
+
readonly streamUrl: string;
|
|
786
|
+
/** Store-specific adapter used to encode local state and apply remote bytes. */
|
|
787
|
+
readonly adaptor: EphemeralStreamAdaptor;
|
|
788
|
+
/** Low-level HTTP/SSE transport. It is reused only for auth, fetch, and parsing helpers. */
|
|
789
|
+
private readonly client;
|
|
790
|
+
/** Retry policy shared by the read loop and local write queue. */
|
|
791
|
+
private readonly reconnectConfig;
|
|
792
|
+
/** Period for republishing full local ephemeral state, or `false` to disable it. */
|
|
793
|
+
private readonly heartbeatMs;
|
|
794
|
+
/** Enables diagnostic console errors for failed read/write loops. */
|
|
795
|
+
private readonly debug;
|
|
796
|
+
/** Current shared subscription state, if the stream is joined. */
|
|
797
|
+
private joinState?;
|
|
798
|
+
constructor(options: EphemeralStreamCrdtOptions);
|
|
799
|
+
join(params?: EphemeralStreamJoinParams): Promise<{
|
|
800
|
+
readonly ok: true;
|
|
801
|
+
readonly value: EphemeralStreamSubscription;
|
|
802
|
+
} | {
|
|
803
|
+
readonly ok: false;
|
|
804
|
+
readonly error: TransportError;
|
|
805
|
+
}>;
|
|
806
|
+
rejoin(): void;
|
|
807
|
+
close(): Promise<void>;
|
|
808
|
+
private createJoinState;
|
|
809
|
+
private startJoin;
|
|
810
|
+
private waitForFirstOpen;
|
|
811
|
+
private createSubscription;
|
|
812
|
+
private onStatusChange;
|
|
813
|
+
private disposeJoinState;
|
|
814
|
+
private resolveFirstOpen;
|
|
815
|
+
private rejectFirstOpen;
|
|
816
|
+
private runReadLoop;
|
|
817
|
+
private startHeartbeat;
|
|
818
|
+
private enqueueFullState;
|
|
819
|
+
private enqueueLocal;
|
|
820
|
+
private flushPendingLocal;
|
|
821
|
+
private notifySyncWaiters;
|
|
822
|
+
private rejectSyncWaiters;
|
|
823
|
+
private setReadStatus;
|
|
824
|
+
private setWriteStatus;
|
|
825
|
+
private recomputeStatus;
|
|
826
|
+
private computeStatus;
|
|
827
|
+
private logError;
|
|
828
|
+
}
|
|
829
|
+
//#endregion
|
|
715
830
|
//#region src/payload-protection.d.ts
|
|
716
831
|
type PayloadProtectionFailureReason = "plaintext_forbidden" | "missing_read_key" | "decrypt_failed" | "invalid_envelope" | "wrong_payload_kind" | "encrypt_failed";
|
|
717
832
|
declare class PayloadProtectionError extends Error {
|
|
@@ -741,5 +856,5 @@ declare function createStreamUrl(input: {
|
|
|
741
856
|
baseUrl?: string;
|
|
742
857
|
}): string;
|
|
743
858
|
//#endregion
|
|
744
|
-
export {
|
|
745
|
-
//# sourceMappingURL=stream-id-
|
|
859
|
+
export { RemoteCursorStore as $, Result as A, TransportJoinParams as B, PayloadProtectionEncryptionOptions as C, PayloadProtectionReadPolicy as D, PayloadProtectionOptions as E, StreamsAuthProvider as F, WriteOnlyAppendResult as G, TransportSnapshotUploadSuccess as H, StreamsCrdtOptions as I, InMemoryRemoteCursorStore as J, BeforeRemoteCursorSaveContext as K, TransportCreateStreamSuccess as L, SnapshotTransformHook as M, SnapshotUploadOptions as N, PayloadProtectionScope as O, StreamsAuthContext as P, RemoteCursorSaveSource as Q, TransportDeleteStreamSuccess as R, JsonValue as S, PayloadProtectionKeyProvider as T, TransportSubscription as U, TransportRoomStatus as V, TransportSyncSuccess as W, IndexedDbRemoteCursorStoreOptions as X, IndexedDbRemoteCursorStore as Y, RemoteCursor as Z, EphemeralStreamCrdtOptions as _, EphemeralStreamCrdt as a, IsolatedCrdtAdapter as b, CrdtUpdateBatch as c, E2eeKeyProvider as d, createInitialRemoteCursor as et, E2eeOptions as f, EphemeralStreamAdaptor as g, E2eeWritePolicy as h, PayloadProtectionError as i, SnapshotCodec as j, PayloadProtectionWritePolicy as k, E2eeEncryptionOptions as l, E2eeScope as m, isValidBucketId as n, StreamsCrdt as o, E2eeReadPolicy as p, BeforeRemoteCursorSaveHook as q, isValidRillId as r, CrdtAdapter as s, createStreamUrl as t, E2eeKey as u, EphemeralStreamJoinParams as v, PayloadProtectionKey as w, JsonObject as x, EphemeralStreamSubscription as y, TransportError as z };
|
|
860
|
+
//# sourceMappingURL=stream-id-BXJvwX_O.d.ts.map
|