@loro-dev/streams-crdt 0.9.1 → 0.10.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 +41 -0
- 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-2eJsM9CJ.js → stream-id-AfFikxB2.js} +93 -4
- package/dist/stream-id-AfFikxB2.js.map +1 -0
- package/dist/{stream-id-JuJ1JqCX.d.ts → stream-id-BP6BR7jn.d.ts} +30 -2
- package/package.json +1 -1
- package/dist/stream-id-2eJsM9CJ.js.map +0 -1
package/README.md
CHANGED
|
@@ -189,6 +189,47 @@ const sub = joined.value;
|
|
|
189
189
|
checked out or detached, call `checkoutToLatest()` or `attach()` before passing
|
|
190
190
|
it to `StreamsCrdt`.
|
|
191
191
|
|
|
192
|
+
### Request shard origins
|
|
193
|
+
|
|
194
|
+
Browsers can still show head-of-line blocking symptoms when large
|
|
195
|
+
bootstrap/catch-up downloads and normal app requests contend on the same
|
|
196
|
+
connection. `shardUrls` lets the transport replace only the request origin for
|
|
197
|
+
selected operations while preserving the stream path and query:
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
const transport = new StreamsCrdt({
|
|
201
|
+
streamUrl,
|
|
202
|
+
auth: async () => "<gateway-jwt>",
|
|
203
|
+
adapter: createLoroDocAdapter(doc),
|
|
204
|
+
shardUrls: {
|
|
205
|
+
bootstrap: [
|
|
206
|
+
"https://control-a.streams-api-proxy.loro.dev",
|
|
207
|
+
"https://control-b.streams-api-proxy.loro.dev",
|
|
208
|
+
],
|
|
209
|
+
catchup: [
|
|
210
|
+
"https://control-a.streams-api-proxy.loro.dev",
|
|
211
|
+
"https://control-b.streams-api-proxy.loro.dev",
|
|
212
|
+
],
|
|
213
|
+
largePost: [
|
|
214
|
+
"https://write-a.streams-api-proxy.loro.dev",
|
|
215
|
+
"https://write-b.streams-api-proxy.loro.dev",
|
|
216
|
+
],
|
|
217
|
+
largePostMinBytes: 64 * 1024,
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Shard entries must be origin URLs with no path, query, or hash. Each transport
|
|
223
|
+
instance rotates through the configured origins per operation, with a randomized
|
|
224
|
+
starting point so multiple tabs are less likely to all begin on the same shard.
|
|
225
|
+
Bootstrap applies to `GET <stream>/bootstrap`; catch-up applies to non-SSE
|
|
226
|
+
offset reads, including long-poll fallback; SSE live reads stay on the original
|
|
227
|
+
`streamUrl`. `largePost` applies to non-empty append POST bodies at or above
|
|
228
|
+
`largePostMinBytes` bytes. The default threshold is `0`, so every non-empty
|
|
229
|
+
append POST can use `largePost` when that pool is configured. Verify actual
|
|
230
|
+
connection separation with browser NetLog: browsers may coalesce compatible
|
|
231
|
+
HTTP/2 or HTTP/3 origins when DNS, certificate, and transport settings allow it.
|
|
232
|
+
|
|
192
233
|
### Loro pending imports and cursor safety
|
|
193
234
|
|
|
194
235
|
Loro can accept an update whose dependencies are missing and keep it as a
|
package/dist/flock.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as IndexedDbRemoteCursorStore, A as PayloadProtectionReadPolicy, B as StreamsCrdtShardUrlsOptions, C as IsolatedCrdtAdapter, D as PayloadProtectionKey, E as PayloadProtectionEncryptionOptions, F as SnapshotTransformHook, G as TransportRoomStatus, H as TransportDeleteStreamSuccess, I as SnapshotUploadOptions, J as TransportSyncSuccess, K as TransportSnapshotUploadSuccess, L as StreamsAuthContext, M as PayloadProtectionWritePolicy, N as Result, O as PayloadProtectionKeyProvider, P as SnapshotCodec, Q as InMemoryRemoteCursorStore, R as StreamsAuthProvider, S as EphemeralStreamSubscription, T as JsonValue, U as TransportError, V as TransportCreateStreamSuccess, W as TransportJoinParams, X as BeforeRemoteCursorSaveContext, Y as WriteOnlyAppendResult, Z as BeforeRemoteCursorSaveHook, _ as E2eeScope, a as EphemeralStreamCrdt, b as EphemeralStreamCrdtOptions, c as CrdtApplyOutcome, d as CrdtUpdateBatch, et as IndexedDbRemoteCursorStoreOptions, f as E2eeEncryptionOptions, g as E2eeReadPolicy, h as E2eeOptions, i as PayloadProtectionError, it as createInitialRemoteCursor, j as PayloadProtectionScope, k as PayloadProtectionOptions, l as CrdtApplyReturn, m as E2eeKeyProvider, n as isValidBucketId, nt as RemoteCursorSaveSource, o as StreamsCrdt, p as E2eeKey, q as TransportSubscription, r as isValidRillId, rt as RemoteCursorStore, s as CrdtAdapter, t as createStreamUrl, tt as RemoteCursor, u as CrdtUnresolvedSpan, v as E2eeWritePolicy, w as JsonObject, x as EphemeralStreamJoinParams, y as EphemeralStreamAdaptor, z as StreamsCrdtOptions } from "./stream-id-BP6BR7jn.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, 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, 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-AfFikxB2.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, TransportCreateStreamSuccess, TransportDeleteStreamSuccess, TransportError, TransportJoinParams, TransportRoomStatus, TransportSnapshotUploadSuccess, TransportSubscription, TransportSyncSuccess, WriteOnlyAppendResult, createInitialRemoteCursor, createStreamUrl, isValidBucketId, isValidRillId };
|
|
1
|
+
import { $ as IndexedDbRemoteCursorStore, A as PayloadProtectionReadPolicy, B as StreamsCrdtShardUrlsOptions, C as IsolatedCrdtAdapter, D as PayloadProtectionKey, E as PayloadProtectionEncryptionOptions, F as SnapshotTransformHook, G as TransportRoomStatus, H as TransportDeleteStreamSuccess, I as SnapshotUploadOptions, J as TransportSyncSuccess, K as TransportSnapshotUploadSuccess, L as StreamsAuthContext, M as PayloadProtectionWritePolicy, N as Result, O as PayloadProtectionKeyProvider, P as SnapshotCodec, Q as InMemoryRemoteCursorStore, R as StreamsAuthProvider, S as EphemeralStreamSubscription, T as JsonValue, U as TransportError, V as TransportCreateStreamSuccess, W as TransportJoinParams, X as BeforeRemoteCursorSaveContext, Y as WriteOnlyAppendResult, Z as BeforeRemoteCursorSaveHook, _ as E2eeScope, a as EphemeralStreamCrdt, b as EphemeralStreamCrdtOptions, c as CrdtApplyOutcome, d as CrdtUpdateBatch, et as IndexedDbRemoteCursorStoreOptions, f as E2eeEncryptionOptions, g as E2eeReadPolicy, h as E2eeOptions, i as PayloadProtectionError, it as createInitialRemoteCursor, j as PayloadProtectionScope, k as PayloadProtectionOptions, l as CrdtApplyReturn, m as E2eeKeyProvider, n as isValidBucketId, nt as RemoteCursorSaveSource, o as StreamsCrdt, p as E2eeKey, q as TransportSubscription, r as isValidRillId, rt as RemoteCursorStore, s as CrdtAdapter, t as createStreamUrl, tt as RemoteCursor, u as CrdtUnresolvedSpan, v as E2eeWritePolicy, w as JsonObject, x as EphemeralStreamJoinParams, y as EphemeralStreamAdaptor, z as StreamsCrdtOptions } from "./stream-id-BP6BR7jn.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, 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-AfFikxB2.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 IndexedDbRemoteCursorStore, A as PayloadProtectionReadPolicy, B as StreamsCrdtShardUrlsOptions, C as IsolatedCrdtAdapter, D as PayloadProtectionKey, E as PayloadProtectionEncryptionOptions, F as SnapshotTransformHook, G as TransportRoomStatus, H as TransportDeleteStreamSuccess, I as SnapshotUploadOptions, J as TransportSyncSuccess, K as TransportSnapshotUploadSuccess, L as StreamsAuthContext, M as PayloadProtectionWritePolicy, N as Result, O as PayloadProtectionKeyProvider, P as SnapshotCodec, Q as InMemoryRemoteCursorStore, R as StreamsAuthProvider, S as EphemeralStreamSubscription, T as JsonValue, U as TransportError, V as TransportCreateStreamSuccess, W as TransportJoinParams, X as BeforeRemoteCursorSaveContext, Y as WriteOnlyAppendResult, Z as BeforeRemoteCursorSaveHook, _ as E2eeScope, a as EphemeralStreamCrdt, b as EphemeralStreamCrdtOptions, c as CrdtApplyOutcome, d as CrdtUpdateBatch, et as IndexedDbRemoteCursorStoreOptions, f as E2eeEncryptionOptions, g as E2eeReadPolicy, h as E2eeOptions, i as PayloadProtectionError, it as createInitialRemoteCursor, j as PayloadProtectionScope, k as PayloadProtectionOptions, l as CrdtApplyReturn, m as E2eeKeyProvider, n as isValidBucketId, nt as RemoteCursorSaveSource, o as StreamsCrdt, p as E2eeKey, q as TransportSubscription, r as isValidRillId, rt as RemoteCursorStore, s as CrdtAdapter, t as createStreamUrl, tt as RemoteCursor, u as CrdtUnresolvedSpan, v as E2eeWritePolicy, w as JsonObject, x as EphemeralStreamJoinParams, y as EphemeralStreamAdaptor, z as StreamsCrdtOptions } from "./stream-id-BP6BR7jn.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, 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, 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-AfFikxB2.js";
|
|
2
2
|
import { LoroDoc, VersionVector, decodeImportBlobMeta } from "loro-crdt";
|
|
3
3
|
//#region src/loro.ts
|
|
4
4
|
function batchImportUpdates(doc, updates) {
|
|
@@ -881,6 +881,56 @@ function resolveNextOffsetAfterConcurrentAdvance(requestOffset, currentOffset, r
|
|
|
881
881
|
}
|
|
882
882
|
//#endregion
|
|
883
883
|
//#region src/transport-client.ts
|
|
884
|
+
const bodySizeEncoder = new TextEncoder();
|
|
885
|
+
function normalizeShardOrigins(urls, label) {
|
|
886
|
+
if (urls == null) return;
|
|
887
|
+
const out = [];
|
|
888
|
+
for (const raw of urls) {
|
|
889
|
+
const trimmed = raw.trim();
|
|
890
|
+
if (trimmed.length === 0) continue;
|
|
891
|
+
const url = new URL(trimmed);
|
|
892
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error(`${label} shard URL must use http or https`);
|
|
893
|
+
if (url.pathname !== "/" || url.search !== "" || url.hash !== "") throw new Error(`${label} shard URL must be an origin URL`);
|
|
894
|
+
out.push(url.origin);
|
|
895
|
+
}
|
|
896
|
+
return out.length === 0 ? void 0 : out;
|
|
897
|
+
}
|
|
898
|
+
function normalizeShardUrlsOptions(options) {
|
|
899
|
+
if (options == null) return;
|
|
900
|
+
const largePostMinBytes = options.largePostMinBytes ?? 0;
|
|
901
|
+
if (!Number.isSafeInteger(largePostMinBytes) || largePostMinBytes < 0) throw new Error("shardUrls.largePostMinBytes must be a non-negative safe integer");
|
|
902
|
+
const normalized = {
|
|
903
|
+
bootstrap: normalizeShardOrigins(options.bootstrap, "shardUrls.bootstrap"),
|
|
904
|
+
catchup: normalizeShardOrigins(options.catchup, "shardUrls.catchup"),
|
|
905
|
+
largePost: normalizeShardOrigins(options.largePost, "shardUrls.largePost"),
|
|
906
|
+
largePostMinBytes
|
|
907
|
+
};
|
|
908
|
+
if (normalized.bootstrap == null && normalized.catchup == null && normalized.largePost == null) return;
|
|
909
|
+
return normalized;
|
|
910
|
+
}
|
|
911
|
+
function requestBodyByteLength(body) {
|
|
912
|
+
if (body == null) return 0;
|
|
913
|
+
if (typeof body === "string") return bodySizeEncoder.encode(body).byteLength;
|
|
914
|
+
if (body instanceof ArrayBuffer) return body.byteLength;
|
|
915
|
+
if (ArrayBuffer.isView(body)) return body.byteLength;
|
|
916
|
+
if (typeof Blob !== "undefined" && body instanceof Blob) return body.size;
|
|
917
|
+
if (typeof URLSearchParams !== "undefined" && body instanceof URLSearchParams) return bodySizeEncoder.encode(body.toString()).byteLength;
|
|
918
|
+
}
|
|
919
|
+
function createRandomShardStart(originCount) {
|
|
920
|
+
if (originCount <= 1) return 0;
|
|
921
|
+
try {
|
|
922
|
+
const crypto = globalThis.crypto;
|
|
923
|
+
if (crypto != null) {
|
|
924
|
+
const values = new Uint32Array(1);
|
|
925
|
+
crypto.getRandomValues(values);
|
|
926
|
+
return (values[0] ?? 0) % originCount;
|
|
927
|
+
}
|
|
928
|
+
} catch {}
|
|
929
|
+
return Math.floor(Math.random() * originCount);
|
|
930
|
+
}
|
|
931
|
+
function normalizedStreamPath(streamUrl) {
|
|
932
|
+
return streamUrl.pathname.endsWith("/") ? streamUrl.pathname.slice(0, -1) : streamUrl.pathname;
|
|
933
|
+
}
|
|
884
934
|
/**
|
|
885
935
|
* Low-level HTTP and SSE client for one stream.
|
|
886
936
|
*
|
|
@@ -894,24 +944,62 @@ var StreamsTransportClient = class {
|
|
|
894
944
|
fetchImpl;
|
|
895
945
|
authProvider;
|
|
896
946
|
reconnectConfig;
|
|
947
|
+
shardUrls;
|
|
948
|
+
shardCursorIndexes = {};
|
|
897
949
|
authRefreshInFlight;
|
|
898
950
|
constructor(options) {
|
|
899
951
|
this.streamUrl = options.streamUrl;
|
|
900
952
|
this.adapter = options.adapter;
|
|
953
|
+
this.fetchImpl = options.fetchImpl;
|
|
954
|
+
this.shardUrls = normalizeShardUrlsOptions(options.shardUrls);
|
|
901
955
|
this.client = new StreamsClient({
|
|
902
956
|
url: options.streamUrl,
|
|
903
957
|
auth: options.authProvider,
|
|
904
|
-
fetch:
|
|
958
|
+
fetch: this.fetchRouted.bind(this),
|
|
905
959
|
retry: { maxAttempts: 0 },
|
|
906
960
|
timeout: {
|
|
907
961
|
connectTimeoutMs: options.reconnectConfig.connectTimeoutMs,
|
|
908
962
|
pollTimeoutMs: options.reconnectConfig.pollTimeoutMs
|
|
909
963
|
}
|
|
910
964
|
});
|
|
911
|
-
this.fetchImpl = options.fetchImpl;
|
|
912
965
|
this.authProvider = options.authProvider;
|
|
913
966
|
this.reconnectConfig = options.reconnectConfig;
|
|
914
967
|
}
|
|
968
|
+
fetchRouted(input, init) {
|
|
969
|
+
return this.fetchImpl(this.routeRequestUrl(input, init), init);
|
|
970
|
+
}
|
|
971
|
+
routeRequestUrl(input, init) {
|
|
972
|
+
const shardUrls = this.shardUrls;
|
|
973
|
+
if (shardUrls == null) return input;
|
|
974
|
+
const operation = this.classifyShardOperation(input, init, shardUrls);
|
|
975
|
+
if (operation == null) return input;
|
|
976
|
+
const origins = operation === "bootstrap" ? shardUrls.bootstrap : operation === "catchup" ? shardUrls.catchup : shardUrls.largePost;
|
|
977
|
+
if (origins == null || origins.length === 0) return input;
|
|
978
|
+
const target = new URL(input);
|
|
979
|
+
const shardOrigin = new URL(this.nextShardOrigin(operation, origins));
|
|
980
|
+
target.protocol = shardOrigin.protocol;
|
|
981
|
+
target.host = shardOrigin.host;
|
|
982
|
+
target.username = "";
|
|
983
|
+
target.password = "";
|
|
984
|
+
return target.toString();
|
|
985
|
+
}
|
|
986
|
+
nextShardOrigin(operation, origins) {
|
|
987
|
+
const currentIndex = this.shardCursorIndexes[operation] ?? createRandomShardStart(origins.length);
|
|
988
|
+
this.shardCursorIndexes[operation] = (currentIndex + 1) % origins.length;
|
|
989
|
+
return origins[currentIndex % origins.length];
|
|
990
|
+
}
|
|
991
|
+
classifyShardOperation(input, init, shardUrls) {
|
|
992
|
+
const method = (init?.method ?? "GET").toUpperCase();
|
|
993
|
+
const requestUrl = new URL(input);
|
|
994
|
+
const streamUrl = new URL(this.streamUrl);
|
|
995
|
+
const streamPath = normalizedStreamPath(streamUrl);
|
|
996
|
+
if (method === "GET" && requestUrl.pathname === `${streamPath}/bootstrap`) return "bootstrap";
|
|
997
|
+
if (method === "GET" && requestUrl.pathname === streamUrl.pathname && requestUrl.searchParams.has("offset") && requestUrl.searchParams.get("live") !== "sse") return "catchup";
|
|
998
|
+
if (method !== "POST" || requestUrl.pathname !== streamUrl.pathname) return;
|
|
999
|
+
const bodyLength = requestBodyByteLength(init?.body);
|
|
1000
|
+
if (bodyLength == null || bodyLength === 0 || bodyLength < shardUrls.largePostMinBytes) return;
|
|
1001
|
+
return "large-post";
|
|
1002
|
+
}
|
|
915
1003
|
async createStreamRequest() {
|
|
916
1004
|
const adapterHeaders = this.adapter.getCreateStreamHeaders ? await this.adapter.getCreateStreamHeaders() : void 0;
|
|
917
1005
|
const result = await this.client.create({ headers: adapterHeaders });
|
|
@@ -2209,7 +2297,8 @@ var StreamsCrdt = class StreamsCrdt {
|
|
|
2209
2297
|
adapter: this.adapter,
|
|
2210
2298
|
authProvider,
|
|
2211
2299
|
fetchImpl,
|
|
2212
|
-
reconnectConfig: this.reconnectConfig
|
|
2300
|
+
reconnectConfig: this.reconnectConfig,
|
|
2301
|
+
shardUrls: options.shardUrls
|
|
2213
2302
|
});
|
|
2214
2303
|
this.cursorManager = this.createCursorManager(this.adapter, (cursor, source) => this.saveRemoteCursor(cursor, source));
|
|
2215
2304
|
this.volatileCursorManager = this.createCursorManager(this.adapter, async (cursor) => cursor);
|
|
@@ -3393,4 +3482,4 @@ function createStreamUrl(input) {
|
|
|
3393
3482
|
//#endregion
|
|
3394
3483
|
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 };
|
|
3395
3484
|
|
|
3396
|
-
//# sourceMappingURL=stream-id-
|
|
3485
|
+
//# sourceMappingURL=stream-id-AfFikxB2.js.map
|