@korajs/sync 1.0.0-beta.0 → 1.0.0-beta.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/dist/index.cjs CHANGED
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  AwarenessManager: () => AwarenessManager,
34
+ BlobChunkChannel: () => BlobChunkChannel,
34
35
  ChaosTransport: () => ChaosTransport,
35
36
  ConnectionMonitor: () => ConnectionMonitor,
36
37
  DEFAULT_RICHTEXT_DOC_CHANNEL_THRESHOLD: () => DEFAULT_RICHTEXT_DOC_CHANNEL_THRESHOLD,
@@ -55,11 +56,13 @@ __export(index_exports, {
55
56
  WebSocketTransport: () => WebSocketTransport,
56
57
  createDeltaCursorFromBatch: () => createDeltaCursorFromBatch,
57
58
  createSyncStatusController: () => createSyncStatusController,
59
+ decodeBlobChunkBytes: () => decodeBlobChunkBytes,
58
60
  decodeDeltaCursor: () => decodeDeltaCursor,
59
61
  decodeYjsUpdate: () => decodeYjsUpdate,
60
62
  dedupeQuerySubsets: () => dedupeQuerySubsets,
61
63
  deriveKey: () => deriveKey,
62
64
  deriveVersionedKey: () => deriveVersionedKey,
65
+ encodeBlobChunkBytes: () => encodeBlobChunkBytes,
63
66
  encodeDeltaCursor: () => encodeDeltaCursor,
64
67
  encodeYjsUpdate: () => encodeYjsUpdate,
65
68
  filterOperationsByScope: () => filterOperationsByScope,
@@ -67,6 +70,9 @@ __export(index_exports, {
67
70
  getRemoteAwarenessStates: () => getRemoteAwarenessStates,
68
71
  isAcknowledgmentMessage: () => isAcknowledgmentMessage,
69
72
  isAwarenessUpdateMessage: () => isAwarenessUpdateMessage,
73
+ isBlobChunkPushMessage: () => isBlobChunkPushMessage,
74
+ isBlobChunkRequestMessage: () => isBlobChunkRequestMessage,
75
+ isBlobChunkResponseMessage: () => isBlobChunkResponseMessage,
70
76
  isClientSchemaVersionSupported: () => isClientSchemaVersionSupported,
71
77
  isEncryptedPayload: () => isEncryptedPayload,
72
78
  isErrorMessage: () => isErrorMessage,
@@ -306,6 +312,12 @@ function isSyncMessage(value) {
306
312
  return isAwarenessUpdateMessage(value);
307
313
  case "yjs-doc-update":
308
314
  return isYjsDocUpdateMessage(value);
315
+ case "blob-chunk-request":
316
+ return isBlobChunkRequestMessage(value);
317
+ case "blob-chunk-response":
318
+ return isBlobChunkResponseMessage(value);
319
+ case "blob-chunk-push":
320
+ return isBlobChunkPushMessage(value);
309
321
  default:
310
322
  return false;
311
323
  }
@@ -345,6 +357,21 @@ function isYjsDocUpdateMessage(value) {
345
357
  const msg = value;
346
358
  return msg.type === "yjs-doc-update" && typeof msg.messageId === "string" && typeof msg.collection === "string" && typeof msg.recordId === "string" && typeof msg.field === "string" && typeof msg.update === "string";
347
359
  }
360
+ function isBlobChunkRequestMessage(value) {
361
+ if (typeof value !== "object" || value === null) return false;
362
+ const msg = value;
363
+ return msg.type === "blob-chunk-request" && typeof msg.messageId === "string" && typeof msg.requestId === "string" && typeof msg.hash === "string";
364
+ }
365
+ function isBlobChunkResponseMessage(value) {
366
+ if (typeof value !== "object" || value === null) return false;
367
+ const msg = value;
368
+ return msg.type === "blob-chunk-response" && typeof msg.messageId === "string" && typeof msg.requestId === "string" && (typeof msg.bytes === "string" || msg.bytes === null);
369
+ }
370
+ function isBlobChunkPushMessage(value) {
371
+ if (typeof value !== "object" || value === null) return false;
372
+ const msg = value;
373
+ return msg.type === "blob-chunk-push" && typeof msg.messageId === "string" && typeof msg.hash === "string" && typeof msg.bytes === "string";
374
+ }
348
375
 
349
376
  // src/protocol/serializer.ts
350
377
  var import_core2 = require("@korajs/core");
@@ -585,7 +612,8 @@ function toProtoEnvelope(message) {
585
612
  accepted: message.accepted,
586
613
  rejectReason: message.rejectReason,
587
614
  selectedWireFormat: message.selectedWireFormat,
588
- serverTime: message.serverTime
615
+ serverTime: message.serverTime,
616
+ blobStorageEnabled: message.blobStorageEnabled
589
617
  };
590
618
  case "operation-batch":
591
619
  return {
@@ -616,6 +644,28 @@ function toProtoEnvelope(message) {
616
644
  type: message.type,
617
645
  messageId: message.messageId
618
646
  };
647
+ case "blob-chunk-request":
648
+ return {
649
+ type: message.type,
650
+ messageId: message.messageId,
651
+ requestId: message.requestId,
652
+ hash: message.hash
653
+ };
654
+ case "blob-chunk-response":
655
+ return {
656
+ type: message.type,
657
+ messageId: message.messageId,
658
+ requestId: message.requestId,
659
+ hasBytes: message.bytes !== null,
660
+ ...message.bytes !== null ? { chunkBytes: message.bytes } : {}
661
+ };
662
+ case "blob-chunk-push":
663
+ return {
664
+ type: message.type,
665
+ messageId: message.messageId,
666
+ hash: message.hash,
667
+ chunkBytes: message.bytes
668
+ };
619
669
  }
620
670
  }
621
671
  function fromProtoEnvelope(envelope) {
@@ -648,7 +698,8 @@ function fromProtoEnvelope(envelope) {
648
698
  selectedWireFormat: envelope.selectedWireFormat === "json" || envelope.selectedWireFormat === "protobuf" ? envelope.selectedWireFormat : void 0,
649
699
  // Preserve the server's wall-clock time so clock-skew detection and
650
700
  // automatic timestamp rebase work over the protobuf wire, not just JSON.
651
- ...envelope.serverTime !== void 0 ? { serverTime: envelope.serverTime } : {}
701
+ ...envelope.serverTime !== void 0 ? { serverTime: envelope.serverTime } : {},
702
+ ...envelope.blobStorageEnabled !== void 0 ? { blobStorageEnabled: envelope.blobStorageEnabled } : {}
652
703
  };
653
704
  case "operation-batch":
654
705
  return {
@@ -673,6 +724,27 @@ function fromProtoEnvelope(envelope) {
673
724
  message: envelope.errorMessage ?? "Unknown error",
674
725
  retriable: envelope.retriable ?? false
675
726
  };
727
+ case "blob-chunk-request":
728
+ return {
729
+ type: "blob-chunk-request",
730
+ messageId: envelope.messageId,
731
+ requestId: envelope.requestId ?? "",
732
+ hash: envelope.hash ?? ""
733
+ };
734
+ case "blob-chunk-response":
735
+ return {
736
+ type: "blob-chunk-response",
737
+ messageId: envelope.messageId,
738
+ requestId: envelope.requestId ?? "",
739
+ bytes: envelope.hasBytes ? envelope.chunkBytes ?? "" : null
740
+ };
741
+ case "blob-chunk-push":
742
+ return {
743
+ type: "blob-chunk-push",
744
+ messageId: envelope.messageId,
745
+ hash: envelope.hash ?? "",
746
+ bytes: envelope.chunkBytes ?? ""
747
+ };
676
748
  default:
677
749
  throw new import_core2.SyncError("Failed to decode sync message: unknown protobuf type", {
678
750
  type: envelope.type
@@ -818,6 +890,14 @@ function encodeEnvelope(envelope) {
818
890
  }
819
891
  if (envelope.retriable !== void 0) writer.uint32(144).bool(envelope.retriable);
820
892
  if (envelope.serverTime !== void 0) writer.uint32(152).int64(envelope.serverTime);
893
+ if (envelope.requestId && envelope.requestId.length > 0)
894
+ writer.uint32(162).string(envelope.requestId);
895
+ if (envelope.hash && envelope.hash.length > 0) writer.uint32(170).string(envelope.hash);
896
+ if (envelope.chunkBytes && envelope.chunkBytes.length > 0)
897
+ writer.uint32(178).string(envelope.chunkBytes);
898
+ if (envelope.hasBytes !== void 0) writer.uint32(184).bool(envelope.hasBytes);
899
+ if (envelope.blobStorageEnabled !== void 0)
900
+ writer.uint32(200).bool(envelope.blobStorageEnabled);
821
901
  return writer.finish();
822
902
  }
823
903
  function decodeEnvelope(bytes) {
@@ -889,6 +969,21 @@ function decodeEnvelope(bytes) {
889
969
  case 19:
890
970
  envelope.serverTime = longToNumber(reader.int64());
891
971
  break;
972
+ case 20:
973
+ envelope.requestId = reader.string();
974
+ break;
975
+ case 21:
976
+ envelope.hash = reader.string();
977
+ break;
978
+ case 22:
979
+ envelope.chunkBytes = reader.string();
980
+ break;
981
+ case 23:
982
+ envelope.hasBytes = reader.bool();
983
+ break;
984
+ case 25:
985
+ envelope.blobStorageEnabled = reader.bool();
986
+ break;
892
987
  default:
893
988
  reader.skipType(tag & 7);
894
989
  }
@@ -1480,7 +1575,7 @@ var ChaosTransport = class {
1480
1575
  };
1481
1576
 
1482
1577
  // src/engine/sync-engine.ts
1483
- var import_core6 = require("@korajs/core");
1578
+ var import_core7 = require("@korajs/core");
1484
1579
  var import_internal2 = require("@korajs/core/internal");
1485
1580
 
1486
1581
  // src/awareness/awareness-manager.ts
@@ -1689,6 +1784,95 @@ var AwarenessManager = class {
1689
1784
  }
1690
1785
  };
1691
1786
 
1787
+ // src/blob/blob-chunk-channel.ts
1788
+ var import_core5 = require("@korajs/core");
1789
+ function encodeBlobChunkBytes(bytes) {
1790
+ let binary = "";
1791
+ for (let i = 0; i < bytes.length; i++) {
1792
+ binary += String.fromCharCode(bytes[i]);
1793
+ }
1794
+ return btoa(binary);
1795
+ }
1796
+ function decodeBlobChunkBytes(encoded) {
1797
+ const binary = atob(encoded);
1798
+ const out = new Uint8Array(binary.length);
1799
+ for (let i = 0; i < binary.length; i++) {
1800
+ out[i] = binary.charCodeAt(i);
1801
+ }
1802
+ return out;
1803
+ }
1804
+ var BlobChunkChannel = class {
1805
+ onSend;
1806
+ handlers = /* @__PURE__ */ new Set();
1807
+ constructor(options) {
1808
+ this.onSend = options?.onSend ?? null;
1809
+ }
1810
+ /**
1811
+ * Send a blob-chunk message to the peer. Response bytes are base64-encoded
1812
+ * onto the wire here; callers pass a `Uint8Array`.
1813
+ */
1814
+ send(message) {
1815
+ if (!this.onSend) {
1816
+ return;
1817
+ }
1818
+ if (message.type === "blob-chunk-request") {
1819
+ this.onSend({
1820
+ type: "blob-chunk-request",
1821
+ messageId: (0, import_core5.generateUUIDv7)(),
1822
+ requestId: message.requestId,
1823
+ hash: message.hash
1824
+ });
1825
+ return;
1826
+ }
1827
+ if (message.type === "blob-chunk-push") {
1828
+ this.onSend({
1829
+ type: "blob-chunk-push",
1830
+ messageId: (0, import_core5.generateUUIDv7)(),
1831
+ hash: message.hash,
1832
+ bytes: encodeBlobChunkBytes(message.bytes)
1833
+ });
1834
+ return;
1835
+ }
1836
+ this.onSend({
1837
+ type: "blob-chunk-response",
1838
+ messageId: (0, import_core5.generateUUIDv7)(),
1839
+ requestId: message.requestId,
1840
+ bytes: message.bytes === null ? null : encodeBlobChunkBytes(message.bytes)
1841
+ });
1842
+ }
1843
+ /**
1844
+ * Register a handler for inbound blob-chunk messages. Multiple handlers are
1845
+ * allowed; each receives every delivered message.
1846
+ */
1847
+ onMessage(handler) {
1848
+ this.handlers.add(handler);
1849
+ return () => {
1850
+ this.handlers.delete(handler);
1851
+ };
1852
+ }
1853
+ /**
1854
+ * Deliver an inbound wire message to registered handlers, decoding response
1855
+ * bytes from base64 back to a `Uint8Array` first.
1856
+ */
1857
+ deliver(message) {
1858
+ if (this.handlers.size === 0) {
1859
+ return;
1860
+ }
1861
+ const decoded = message.type === "blob-chunk-request" ? { type: "blob-chunk-request", requestId: message.requestId, hash: message.hash } : message.type === "blob-chunk-push" ? {
1862
+ type: "blob-chunk-push",
1863
+ hash: message.hash,
1864
+ bytes: decodeBlobChunkBytes(message.bytes)
1865
+ } : {
1866
+ type: "blob-chunk-response",
1867
+ requestId: message.requestId,
1868
+ bytes: message.bytes === null ? null : decodeBlobChunkBytes(message.bytes)
1869
+ };
1870
+ for (const handler of this.handlers) {
1871
+ handler(decoded);
1872
+ }
1873
+ }
1874
+ };
1875
+
1692
1876
  // src/diagnostics/bandwidth-estimator.ts
1693
1877
  var BandwidthEstimator = class {
1694
1878
  maxSamples;
@@ -2132,7 +2316,7 @@ var SyncMetricsCollector = class {
2132
2316
  };
2133
2317
 
2134
2318
  // src/richtext/richtext-doc-channel.ts
2135
- var import_core5 = require("@korajs/core");
2319
+ var import_core6 = require("@korajs/core");
2136
2320
 
2137
2321
  // src/richtext/doc-channel-wire.ts
2138
2322
  function encodeYjsUpdate(update) {
@@ -2211,7 +2395,7 @@ var RichtextDocChannel = class {
2211
2395
  }
2212
2396
  this.onSend({
2213
2397
  type: "yjs-doc-update",
2214
- messageId: (0, import_core5.generateUUIDv7)(),
2398
+ messageId: (0, import_core6.generateUUIDv7)(),
2215
2399
  collection,
2216
2400
  recordId,
2217
2401
  field,
@@ -2443,6 +2627,7 @@ var SyncEngine = class {
2443
2627
  encryptor;
2444
2628
  awarenessManager;
2445
2629
  richtextDocChannel;
2630
+ blobChunkChannel;
2446
2631
  metricsCollector;
2447
2632
  syncState;
2448
2633
  remoteVector = /* @__PURE__ */ new Map();
@@ -2457,6 +2642,7 @@ var SyncEngine = class {
2457
2642
  schemaBlocked = false;
2458
2643
  clockBlocked = false;
2459
2644
  clockSkewMs = null;
2645
+ blobStorageEnabled = false;
2460
2646
  // Track delta exchange state
2461
2647
  deltaBatchesReceived = 0;
2462
2648
  deltaReceiveComplete = false;
@@ -2505,6 +2691,14 @@ var SyncEngine = class {
2505
2691
  this.transport.send(message);
2506
2692
  }
2507
2693
  });
2694
+ this.blobChunkChannel = new BlobChunkChannel({
2695
+ onSend: (message) => {
2696
+ if (this.state !== "streaming") {
2697
+ return;
2698
+ }
2699
+ this.transport.send(message);
2700
+ }
2701
+ });
2508
2702
  this.awarenessManager.onSend((message) => {
2509
2703
  if (this.state !== "streaming") return;
2510
2704
  const wireMessage = {
@@ -2521,7 +2715,7 @@ var SyncEngine = class {
2521
2715
  */
2522
2716
  async start() {
2523
2717
  if (this.state !== "disconnected") {
2524
- throw new import_core6.SyncError("Cannot start sync engine: not in disconnected state", {
2718
+ throw new import_core7.SyncError("Cannot start sync engine: not in disconnected state", {
2525
2719
  currentState: this.state
2526
2720
  });
2527
2721
  }
@@ -2538,7 +2732,7 @@ var SyncEngine = class {
2538
2732
  this.transport.onClose((reason) => this.handleTransportClose(reason));
2539
2733
  this.transport.onError((err) => this.handleTransportError(err));
2540
2734
  if (this.schemaBlocked) {
2541
- throw new import_core6.SyncError(
2735
+ throw new import_core7.SyncError(
2542
2736
  "Sync is blocked due to schema version mismatch. Upgrade the app schema or align sync.schemaVersion with the server.",
2543
2737
  { code: "SCHEMA_MISMATCH_BLOCKED" }
2544
2738
  );
@@ -2708,7 +2902,7 @@ var SyncEngine = class {
2708
2902
  return this.getStatus().pendingOperations;
2709
2903
  }
2710
2904
  emitApplyFailure(op, result, overrides) {
2711
- const reason = (0, import_core6.defaultApplyFailureReason)(result, overrides);
2905
+ const reason = (0, import_core7.defaultApplyFailureReason)(result, overrides);
2712
2906
  this.emitter?.emit({
2713
2907
  type: "sync:apply-failed",
2714
2908
  operationId: op.id,
@@ -2818,6 +3012,31 @@ var SyncEngine = class {
2818
3012
  getRichtextDocChannel() {
2819
3013
  return this.richtextDocChannel;
2820
3014
  }
3015
+ /**
3016
+ * Side channel for out-of-band blob chunk transfer over the sync connection.
3017
+ * The app layer bridges this to a `ChunkMessagePort` to pull/serve blob bytes.
3018
+ */
3019
+ getBlobChunkChannel() {
3020
+ return this.blobChunkChannel;
3021
+ }
3022
+ /**
3023
+ * Whether the connected server persists blob bytes centrally (learned from the
3024
+ * handshake response). When true, the app uploads the bytes behind `blob`
3025
+ * fields so they stay available after the authoring device goes offline.
3026
+ */
3027
+ isBlobStorageEnabled() {
3028
+ return this.blobStorageEnabled;
3029
+ }
3030
+ /**
3031
+ * Upload a blob chunk (or manifest) to the server for central persistence.
3032
+ * A no-op unless connected and the server advertised blob storage.
3033
+ */
3034
+ uploadBlobChunk(hash, bytes) {
3035
+ if (this.state !== "streaming" || !this.blobStorageEnabled) {
3036
+ return;
3037
+ }
3038
+ this.blobChunkChannel.send({ type: "blob-chunk-push", hash, bytes });
3039
+ }
2821
3040
  // --- Private methods ---
2822
3041
  messageChain = Promise.resolve();
2823
3042
  enqueueMessage(message) {
@@ -2843,6 +3062,11 @@ var SyncEngine = class {
2843
3062
  case "yjs-doc-update":
2844
3063
  this.richtextDocChannel.deliver(message);
2845
3064
  break;
3065
+ case "blob-chunk-request":
3066
+ case "blob-chunk-response":
3067
+ case "blob-chunk-push":
3068
+ this.blobChunkChannel.deliver(message);
3069
+ break;
2846
3070
  }
2847
3071
  }
2848
3072
  handleMessageFailure(error) {
@@ -2875,6 +3099,7 @@ var SyncEngine = class {
2875
3099
  }
2876
3100
  async handleHandshakeResponse(msg) {
2877
3101
  if (this.state !== "handshaking") return;
3102
+ this.blobStorageEnabled = msg.blobStorageEnabled === true;
2878
3103
  if (typeof msg.serverTime === "number") {
2879
3104
  this.evaluateClockSkew(msg.serverTime);
2880
3105
  if (this.clockBlocked) {
@@ -3059,7 +3284,7 @@ var SyncEngine = class {
3059
3284
  const targetSchemaVersion = this.config.schemaVersion ?? DEFAULT_SCHEMA_VERSION;
3060
3285
  const transforms = this.config.operationTransforms ?? [];
3061
3286
  for (const op of inScopeOps) {
3062
- const transformed = transforms.length > 0 ? (0, import_core6.applyOperationTransforms)(op, targetSchemaVersion, transforms) : op;
3287
+ const transformed = transforms.length > 0 ? (0, import_core7.applyOperationTransforms)(op, targetSchemaVersion, transforms) : op;
3063
3288
  if (transformed === null) {
3064
3289
  continue;
3065
3290
  }
@@ -3069,20 +3294,20 @@ var SyncEngine = class {
3069
3294
  this.emitApplyFailure(transformed, result);
3070
3295
  }
3071
3296
  } catch (error) {
3072
- if (error instanceof import_core6.ClockDriftError) {
3297
+ if (error instanceof import_core7.ClockDriftError) {
3073
3298
  this.emitApplyFailure(transformed, "rejected", {
3074
- code: import_core6.APPLY_FAILURE_CODES.CLOCK_DRIFT,
3299
+ code: import_core7.APPLY_FAILURE_CODES.CLOCK_DRIFT,
3075
3300
  message: error.message,
3076
3301
  retriable: false
3077
3302
  });
3078
3303
  continue;
3079
3304
  }
3080
3305
  const message = error instanceof Error ? error.message : "Apply failed";
3081
- const code = error instanceof import_core6.SyncError ? error.code : error instanceof import_core6.KoraError ? error.code : error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : import_core6.APPLY_FAILURE_CODES.APPLY_FAILED;
3306
+ const code = error instanceof import_core7.SyncError ? error.code : error instanceof import_core7.KoraError ? error.code : error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : import_core7.APPLY_FAILURE_CODES.APPLY_FAILED;
3082
3307
  this.emitApplyFailure(transformed, "rejected", {
3083
3308
  code,
3084
3309
  message,
3085
- retriable: code !== import_core6.APPLY_FAILURE_CODES.REFERENTIAL_INTEGRITY
3310
+ retriable: code !== import_core7.APPLY_FAILURE_CODES.REFERENTIAL_INTEGRITY
3086
3311
  });
3087
3312
  }
3088
3313
  }
@@ -3352,7 +3577,7 @@ var SyncEngine = class {
3352
3577
  transitionTo(newState) {
3353
3578
  const validTargets = VALID_TRANSITIONS[this.state];
3354
3579
  if (!validTargets.includes(newState)) {
3355
- throw new import_core6.SyncError(`Invalid sync state transition: ${this.state} \u2192 ${newState}`, {
3580
+ throw new import_core7.SyncError(`Invalid sync state transition: ${this.state} \u2192 ${newState}`, {
3356
3581
  from: this.state,
3357
3582
  to: newState
3358
3583
  });
@@ -3634,11 +3859,11 @@ var ReconnectionManager = class {
3634
3859
  };
3635
3860
 
3636
3861
  // src/encryption/sync-encryptor.ts
3637
- var import_core8 = require("@korajs/core");
3862
+ var import_core9 = require("@korajs/core");
3638
3863
 
3639
3864
  // src/encryption/key-derivation.ts
3640
- var import_core7 = require("@korajs/core");
3641
- var KeyDerivationError = class extends import_core7.SyncError {
3865
+ var import_core8 = require("@korajs/core");
3866
+ var KeyDerivationError = class extends import_core8.SyncError {
3642
3867
  constructor(message, context) {
3643
3868
  super(message, { ...context, errorType: "KEY_DERIVATION_ERROR" });
3644
3869
  this.name = "KeyDerivationError";
@@ -3720,13 +3945,13 @@ async function deriveVersionedKey(passphrase, version, salt, iterations = DEFAUL
3720
3945
  }
3721
3946
 
3722
3947
  // src/encryption/sync-encryptor.ts
3723
- var EncryptionError = class extends import_core8.SyncError {
3948
+ var EncryptionError = class extends import_core9.SyncError {
3724
3949
  constructor(message, context) {
3725
3950
  super(message, { ...context, errorType: "ENCRYPTION_ERROR" });
3726
3951
  this.name = "EncryptionError";
3727
3952
  }
3728
3953
  };
3729
- var DecryptionError = class extends import_core8.SyncError {
3954
+ var DecryptionError = class extends import_core9.SyncError {
3730
3955
  constructor(message, context) {
3731
3956
  super(message, { ...context, errorType: "DECRYPTION_ERROR" });
3732
3957
  this.name = "DecryptionError";
@@ -4223,6 +4448,7 @@ function subscribeRemoteAwarenessStates(awareness, listener) {
4223
4448
  // Annotate the CommonJS export names for ESM import in node:
4224
4449
  0 && (module.exports = {
4225
4450
  AwarenessManager,
4451
+ BlobChunkChannel,
4226
4452
  ChaosTransport,
4227
4453
  ConnectionMonitor,
4228
4454
  DEFAULT_RICHTEXT_DOC_CHANNEL_THRESHOLD,
@@ -4247,11 +4473,13 @@ function subscribeRemoteAwarenessStates(awareness, listener) {
4247
4473
  WebSocketTransport,
4248
4474
  createDeltaCursorFromBatch,
4249
4475
  createSyncStatusController,
4476
+ decodeBlobChunkBytes,
4250
4477
  decodeDeltaCursor,
4251
4478
  decodeYjsUpdate,
4252
4479
  dedupeQuerySubsets,
4253
4480
  deriveKey,
4254
4481
  deriveVersionedKey,
4482
+ encodeBlobChunkBytes,
4255
4483
  encodeDeltaCursor,
4256
4484
  encodeYjsUpdate,
4257
4485
  filterOperationsByScope,
@@ -4259,6 +4487,9 @@ function subscribeRemoteAwarenessStates(awareness, listener) {
4259
4487
  getRemoteAwarenessStates,
4260
4488
  isAcknowledgmentMessage,
4261
4489
  isAwarenessUpdateMessage,
4490
+ isBlobChunkPushMessage,
4491
+ isBlobChunkRequestMessage,
4492
+ isBlobChunkResponseMessage,
4262
4493
  isClientSchemaVersionSupported,
4263
4494
  isEncryptedPayload,
4264
4495
  isErrorMessage,