@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.
@@ -1,4 +1,4 @@
1
- import { c as SyncTransport, T as TransportOptions, a as SyncMessage, d as TransportMessageHandler, e as TransportCloseHandler, f as TransportErrorHandler, Q as QueueStorage } from './transport-BMesMB6s.cjs';
1
+ import { c as SyncTransport, T as TransportOptions, a as SyncMessage, d as TransportMessageHandler, e as TransportCloseHandler, f as TransportErrorHandler, Q as QueueStorage } from './transport-CZLMdZ0k.cjs';
2
2
  import { Operation } from '@korajs/core';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { c as SyncTransport, T as TransportOptions, a as SyncMessage, d as TransportMessageHandler, e as TransportCloseHandler, f as TransportErrorHandler, Q as QueueStorage } from './transport-BMesMB6s.js';
1
+ import { c as SyncTransport, T as TransportOptions, a as SyncMessage, d as TransportMessageHandler, e as TransportCloseHandler, f as TransportErrorHandler, Q as QueueStorage } from './transport-CZLMdZ0k.js';
2
2
  import { Operation } from '@korajs/core';
3
3
 
4
4
  /**
@@ -307,6 +307,12 @@ interface HandshakeResponseMessage {
307
307
  acceptedScope?: Record<string, Record<string, unknown>>;
308
308
  /** Server wall-clock time (ms since epoch) at response creation. Lets clients measure their own clock skew. */
309
309
  serverTime?: number;
310
+ /**
311
+ * Whether the server persists blob bytes centrally. When true, a client
312
+ * automatically uploads the bytes behind its `blob` fields so they remain
313
+ * available to other devices even after the authoring device goes offline.
314
+ */
315
+ blobStorageEnabled?: boolean;
310
316
  }
311
317
  /**
312
318
  * Batch of operations sent during delta exchange or streaming.
@@ -387,10 +393,55 @@ interface YjsDocUpdateMessage {
387
393
  /** Base64-encoded Yjs update binary */
388
394
  update: string;
389
395
  }
396
+ /**
397
+ * Request for a single blob chunk by content hash. Ephemeral side channel for
398
+ * out-of-band blob transfer over the sync connection; never persisted in the
399
+ * operation log (durable state is the BlobRef inside a record's fields).
400
+ *
401
+ * Possession of a chunk hash is itself the capability to request it: hashes are
402
+ * only learned from BlobRefs inside records the peer already received through
403
+ * its (scope-filtered) sync, and SHA-256 preimage resistance makes guessing a
404
+ * hash infeasible. The server therefore relays chunk requests among peers
405
+ * without a separate ACL.
406
+ */
407
+ interface BlobChunkRequestMessage {
408
+ type: 'blob-chunk-request';
409
+ messageId: string;
410
+ /** Correlates the response to this request. */
411
+ requestId: string;
412
+ /** SHA-256 hash of the requested chunk. */
413
+ hash: string;
414
+ }
415
+ /**
416
+ * Response to a {@link BlobChunkRequestMessage}. Carries the chunk bytes, or
417
+ * null when the responder does not hold that hash.
418
+ */
419
+ interface BlobChunkResponseMessage {
420
+ type: 'blob-chunk-response';
421
+ messageId: string;
422
+ /** Echoes the request's `requestId` for correlation. */
423
+ requestId: string;
424
+ /** Base64-encoded chunk bytes, or null when the responder does not hold the hash. */
425
+ bytes: string | null;
426
+ }
427
+ /**
428
+ * Unsolicited upload of a blob chunk (or a blob manifest) from a client to the
429
+ * server, so the server can persist it centrally and serve it to other devices
430
+ * even after the authoring device disconnects. Content-addressed: the receiver
431
+ * verifies the bytes hash to `hash`.
432
+ */
433
+ interface BlobChunkPushMessage {
434
+ type: 'blob-chunk-push';
435
+ messageId: string;
436
+ /** SHA-256 hash of the pushed bytes (a chunk hash or a manifest hash). */
437
+ hash: string;
438
+ /** Base64-encoded bytes. */
439
+ bytes: string;
440
+ }
390
441
  /**
391
442
  * Union of all sync protocol messages.
392
443
  */
393
- type SyncMessage = HandshakeMessage | HandshakeResponseMessage | OperationBatchMessage | AcknowledgmentMessage | ErrorMessage | AwarenessUpdateMessage | YjsDocUpdateMessage;
444
+ type SyncMessage = HandshakeMessage | HandshakeResponseMessage | OperationBatchMessage | AcknowledgmentMessage | ErrorMessage | AwarenessUpdateMessage | YjsDocUpdateMessage | BlobChunkRequestMessage | BlobChunkResponseMessage | BlobChunkPushMessage;
394
445
  /**
395
446
  * Check if an unknown value is a valid SyncMessage.
396
447
  */
@@ -423,6 +474,18 @@ declare function isAwarenessUpdateMessage(value: unknown): value is AwarenessUpd
423
474
  * Check if a value is a YjsDocUpdateMessage.
424
475
  */
425
476
  declare function isYjsDocUpdateMessage(value: unknown): value is YjsDocUpdateMessage;
477
+ /**
478
+ * Check if a value is a BlobChunkRequestMessage.
479
+ */
480
+ declare function isBlobChunkRequestMessage(value: unknown): value is BlobChunkRequestMessage;
481
+ /**
482
+ * Check if a value is a BlobChunkResponseMessage.
483
+ */
484
+ declare function isBlobChunkResponseMessage(value: unknown): value is BlobChunkResponseMessage;
485
+ /**
486
+ * Check if a value is a BlobChunkPushMessage.
487
+ */
488
+ declare function isBlobChunkPushMessage(value: unknown): value is BlobChunkPushMessage;
426
489
 
427
490
  /**
428
491
  * Options for transport connection.
@@ -466,4 +529,4 @@ interface SyncTransport {
466
529
  isConnected(): boolean;
467
530
  }
468
531
 
469
- export { type AcknowledgmentMessage as A, isHandshakeMessage as B, isHandshakeResponseMessage as C, type DeltaCursor as D, type EncryptedPayload as E, isOperationBatchMessage as F, isSyncMessage as G, type HandshakeMessage as H, InvalidScopeError as I, isYjsDocUpdateMessage as J, operationMatchesQuerySubsets as K, type OperationBatchMessage as O, type QueueStorage as Q, type SyncScopeMap as S, type TransportOptions as T, type VersionedKey as V, type WireFormat as W, type YjsDocUpdateMessage as Y, type SyncMessage as a, type SerializedOperation as b, type SyncTransport as c, type TransportMessageHandler as d, type TransportCloseHandler as e, type TransportErrorHandler as f, type SyncEncryptionConfig as g, type SyncState as h, type SyncStatusInfo as i, type SyncConfig as j, type SyncStatePersistence as k, type SyncQuerySubset as l, type AwarenessStateWire as m, type AwarenessUpdateMessage as n, type ErrorMessage as o, type HandshakeResponseMessage as p, SYNC_STATES as q, SYNC_STATUSES as r, ScopeViolationError as s, type SyncEncryptionAlgorithm as t, type SyncScopeContext as u, type SyncStatus as v, dedupeQuerySubsets as w, isAcknowledgmentMessage as x, isAwarenessUpdateMessage as y, isErrorMessage as z };
532
+ export { type AcknowledgmentMessage as A, type BlobChunkRequestMessage as B, isAwarenessUpdateMessage as C, type DeltaCursor as D, type EncryptedPayload as E, isBlobChunkPushMessage as F, isBlobChunkRequestMessage as G, type HandshakeMessage as H, InvalidScopeError as I, isBlobChunkResponseMessage as J, isErrorMessage as K, isHandshakeMessage as L, isHandshakeResponseMessage as M, isOperationBatchMessage as N, type OperationBatchMessage as O, isSyncMessage as P, type QueueStorage as Q, isYjsDocUpdateMessage as R, type SyncScopeMap as S, type TransportOptions as T, operationMatchesQuerySubsets as U, type VersionedKey as V, type WireFormat as W, type YjsDocUpdateMessage as Y, type SyncMessage as a, type SerializedOperation as b, type SyncTransport as c, type TransportMessageHandler as d, type TransportCloseHandler as e, type TransportErrorHandler as f, type BlobChunkResponseMessage as g, type BlobChunkPushMessage as h, type SyncEncryptionConfig as i, type SyncState as j, type SyncStatusInfo as k, type SyncConfig as l, type SyncStatePersistence as m, type SyncQuerySubset as n, type AwarenessStateWire as o, type AwarenessUpdateMessage as p, type ErrorMessage as q, type HandshakeResponseMessage as r, SYNC_STATES as s, SYNC_STATUSES as t, ScopeViolationError as u, type SyncEncryptionAlgorithm as v, type SyncScopeContext as w, type SyncStatus as x, dedupeQuerySubsets as y, isAcknowledgmentMessage as z };
@@ -307,6 +307,12 @@ interface HandshakeResponseMessage {
307
307
  acceptedScope?: Record<string, Record<string, unknown>>;
308
308
  /** Server wall-clock time (ms since epoch) at response creation. Lets clients measure their own clock skew. */
309
309
  serverTime?: number;
310
+ /**
311
+ * Whether the server persists blob bytes centrally. When true, a client
312
+ * automatically uploads the bytes behind its `blob` fields so they remain
313
+ * available to other devices even after the authoring device goes offline.
314
+ */
315
+ blobStorageEnabled?: boolean;
310
316
  }
311
317
  /**
312
318
  * Batch of operations sent during delta exchange or streaming.
@@ -387,10 +393,55 @@ interface YjsDocUpdateMessage {
387
393
  /** Base64-encoded Yjs update binary */
388
394
  update: string;
389
395
  }
396
+ /**
397
+ * Request for a single blob chunk by content hash. Ephemeral side channel for
398
+ * out-of-band blob transfer over the sync connection; never persisted in the
399
+ * operation log (durable state is the BlobRef inside a record's fields).
400
+ *
401
+ * Possession of a chunk hash is itself the capability to request it: hashes are
402
+ * only learned from BlobRefs inside records the peer already received through
403
+ * its (scope-filtered) sync, and SHA-256 preimage resistance makes guessing a
404
+ * hash infeasible. The server therefore relays chunk requests among peers
405
+ * without a separate ACL.
406
+ */
407
+ interface BlobChunkRequestMessage {
408
+ type: 'blob-chunk-request';
409
+ messageId: string;
410
+ /** Correlates the response to this request. */
411
+ requestId: string;
412
+ /** SHA-256 hash of the requested chunk. */
413
+ hash: string;
414
+ }
415
+ /**
416
+ * Response to a {@link BlobChunkRequestMessage}. Carries the chunk bytes, or
417
+ * null when the responder does not hold that hash.
418
+ */
419
+ interface BlobChunkResponseMessage {
420
+ type: 'blob-chunk-response';
421
+ messageId: string;
422
+ /** Echoes the request's `requestId` for correlation. */
423
+ requestId: string;
424
+ /** Base64-encoded chunk bytes, or null when the responder does not hold the hash. */
425
+ bytes: string | null;
426
+ }
427
+ /**
428
+ * Unsolicited upload of a blob chunk (or a blob manifest) from a client to the
429
+ * server, so the server can persist it centrally and serve it to other devices
430
+ * even after the authoring device disconnects. Content-addressed: the receiver
431
+ * verifies the bytes hash to `hash`.
432
+ */
433
+ interface BlobChunkPushMessage {
434
+ type: 'blob-chunk-push';
435
+ messageId: string;
436
+ /** SHA-256 hash of the pushed bytes (a chunk hash or a manifest hash). */
437
+ hash: string;
438
+ /** Base64-encoded bytes. */
439
+ bytes: string;
440
+ }
390
441
  /**
391
442
  * Union of all sync protocol messages.
392
443
  */
393
- type SyncMessage = HandshakeMessage | HandshakeResponseMessage | OperationBatchMessage | AcknowledgmentMessage | ErrorMessage | AwarenessUpdateMessage | YjsDocUpdateMessage;
444
+ type SyncMessage = HandshakeMessage | HandshakeResponseMessage | OperationBatchMessage | AcknowledgmentMessage | ErrorMessage | AwarenessUpdateMessage | YjsDocUpdateMessage | BlobChunkRequestMessage | BlobChunkResponseMessage | BlobChunkPushMessage;
394
445
  /**
395
446
  * Check if an unknown value is a valid SyncMessage.
396
447
  */
@@ -423,6 +474,18 @@ declare function isAwarenessUpdateMessage(value: unknown): value is AwarenessUpd
423
474
  * Check if a value is a YjsDocUpdateMessage.
424
475
  */
425
476
  declare function isYjsDocUpdateMessage(value: unknown): value is YjsDocUpdateMessage;
477
+ /**
478
+ * Check if a value is a BlobChunkRequestMessage.
479
+ */
480
+ declare function isBlobChunkRequestMessage(value: unknown): value is BlobChunkRequestMessage;
481
+ /**
482
+ * Check if a value is a BlobChunkResponseMessage.
483
+ */
484
+ declare function isBlobChunkResponseMessage(value: unknown): value is BlobChunkResponseMessage;
485
+ /**
486
+ * Check if a value is a BlobChunkPushMessage.
487
+ */
488
+ declare function isBlobChunkPushMessage(value: unknown): value is BlobChunkPushMessage;
426
489
 
427
490
  /**
428
491
  * Options for transport connection.
@@ -466,4 +529,4 @@ interface SyncTransport {
466
529
  isConnected(): boolean;
467
530
  }
468
531
 
469
- export { type AcknowledgmentMessage as A, isHandshakeMessage as B, isHandshakeResponseMessage as C, type DeltaCursor as D, type EncryptedPayload as E, isOperationBatchMessage as F, isSyncMessage as G, type HandshakeMessage as H, InvalidScopeError as I, isYjsDocUpdateMessage as J, operationMatchesQuerySubsets as K, type OperationBatchMessage as O, type QueueStorage as Q, type SyncScopeMap as S, type TransportOptions as T, type VersionedKey as V, type WireFormat as W, type YjsDocUpdateMessage as Y, type SyncMessage as a, type SerializedOperation as b, type SyncTransport as c, type TransportMessageHandler as d, type TransportCloseHandler as e, type TransportErrorHandler as f, type SyncEncryptionConfig as g, type SyncState as h, type SyncStatusInfo as i, type SyncConfig as j, type SyncStatePersistence as k, type SyncQuerySubset as l, type AwarenessStateWire as m, type AwarenessUpdateMessage as n, type ErrorMessage as o, type HandshakeResponseMessage as p, SYNC_STATES as q, SYNC_STATUSES as r, ScopeViolationError as s, type SyncEncryptionAlgorithm as t, type SyncScopeContext as u, type SyncStatus as v, dedupeQuerySubsets as w, isAcknowledgmentMessage as x, isAwarenessUpdateMessage as y, isErrorMessage as z };
532
+ export { type AcknowledgmentMessage as A, type BlobChunkRequestMessage as B, isAwarenessUpdateMessage as C, type DeltaCursor as D, type EncryptedPayload as E, isBlobChunkPushMessage as F, isBlobChunkRequestMessage as G, type HandshakeMessage as H, InvalidScopeError as I, isBlobChunkResponseMessage as J, isErrorMessage as K, isHandshakeMessage as L, isHandshakeResponseMessage as M, isOperationBatchMessage as N, type OperationBatchMessage as O, isSyncMessage as P, type QueueStorage as Q, isYjsDocUpdateMessage as R, type SyncScopeMap as S, type TransportOptions as T, operationMatchesQuerySubsets as U, type VersionedKey as V, type WireFormat as W, type YjsDocUpdateMessage as Y, type SyncMessage as a, type SerializedOperation as b, type SyncTransport as c, type TransportMessageHandler as d, type TransportCloseHandler as e, type TransportErrorHandler as f, type BlobChunkResponseMessage as g, type BlobChunkPushMessage as h, type SyncEncryptionConfig as i, type SyncState as j, type SyncStatusInfo as k, type SyncConfig as l, type SyncStatePersistence as m, type SyncQuerySubset as n, type AwarenessStateWire as o, type AwarenessUpdateMessage as p, type ErrorMessage as q, type HandshakeResponseMessage as r, SYNC_STATES as s, SYNC_STATUSES as t, ScopeViolationError as u, type SyncEncryptionAlgorithm as v, type SyncScopeContext as w, type SyncStatus as x, dedupeQuerySubsets as y, isAcknowledgmentMessage as z };
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@korajs/sync",
3
- "version": "1.0.0-beta.0",
3
+ "version": "1.0.0-beta.1",
4
4
  "description": "Sync protocol and transports for Kora.js with delta sync, causal ordering, and automatic reconnection",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
8
8
  "types": "./dist/index.d.ts",
9
9
  "exports": {
10
+ "./package.json": "./package.json",
10
11
  ".": {
11
12
  "import": {
12
13
  "types": "./dist/index.d.ts",
@@ -33,8 +34,8 @@
33
34
  ],
34
35
  "dependencies": {
35
36
  "protobufjs": "^8.0.1",
36
- "@korajs/merge": "1.0.0-beta.0",
37
- "@korajs/core": "1.0.0-beta.0"
37
+ "@korajs/core": "1.0.0-beta.1",
38
+ "@korajs/merge": "1.0.0-beta.1"
38
39
  },
39
40
  "devDependencies": {
40
41
  "@fast-check/vitest": "0.2.0",