@korajs/sync 0.6.1 → 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/LICENSE +21 -0
- package/dist/index.cjs +444 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +154 -7
- package/dist/index.d.ts +154 -7
- package/dist/index.js +423 -19
- package/dist/index.js.map +1 -1
- package/dist/internal.d.cts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/{transport-BrdBj7rH.d.cts → transport-CZLMdZ0k.d.cts} +70 -3
- package/dist/{transport-BrdBj7rH.d.ts → transport-CZLMdZ0k.d.ts} +70 -3
- package/package.json +4 -3
package/dist/internal.d.cts
CHANGED
|
@@ -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-
|
|
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
|
/**
|
package/dist/internal.d.ts
CHANGED
|
@@ -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-
|
|
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
|
/**
|
|
@@ -93,7 +93,7 @@ type SyncState = (typeof SYNC_STATES)[number];
|
|
|
93
93
|
/**
|
|
94
94
|
* Developer-facing sync status. Simplified view of the internal state.
|
|
95
95
|
*/
|
|
96
|
-
declare const SYNC_STATUSES: readonly ["connected", "syncing", "synced", "offline", "error", "schema-mismatch"];
|
|
96
|
+
declare const SYNC_STATUSES: readonly ["connected", "syncing", "synced", "offline", "clock-error", "error", "schema-mismatch"];
|
|
97
97
|
type SyncStatus = (typeof SYNC_STATUSES)[number];
|
|
98
98
|
/**
|
|
99
99
|
* Sync status information exposed to developers.
|
|
@@ -111,6 +111,8 @@ interface SyncStatusInfo {
|
|
|
111
111
|
lastSuccessfulPull: number | null;
|
|
112
112
|
/** Number of merge conflicts encountered during this session */
|
|
113
113
|
conflicts: number;
|
|
114
|
+
/** serverTime - localTime in ms measured at the last handshake, or null before first connect. Negative = this device's clock is fast. */
|
|
115
|
+
clockSkewMs: number | null;
|
|
114
116
|
}
|
|
115
117
|
/**
|
|
116
118
|
* Per-collection sync scope map. Maps collection names to field-value filters.
|
|
@@ -303,6 +305,14 @@ interface HandshakeResponseMessage {
|
|
|
303
305
|
selectedWireFormat?: WireFormat;
|
|
304
306
|
/** The server-accepted per-collection sync scope. Confirms what data will be synced. */
|
|
305
307
|
acceptedScope?: Record<string, Record<string, unknown>>;
|
|
308
|
+
/** Server wall-clock time (ms since epoch) at response creation. Lets clients measure their own clock skew. */
|
|
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;
|
|
306
316
|
}
|
|
307
317
|
/**
|
|
308
318
|
* Batch of operations sent during delta exchange or streaming.
|
|
@@ -383,10 +393,55 @@ interface YjsDocUpdateMessage {
|
|
|
383
393
|
/** Base64-encoded Yjs update binary */
|
|
384
394
|
update: string;
|
|
385
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
|
+
}
|
|
386
441
|
/**
|
|
387
442
|
* Union of all sync protocol messages.
|
|
388
443
|
*/
|
|
389
|
-
type SyncMessage = HandshakeMessage | HandshakeResponseMessage | OperationBatchMessage | AcknowledgmentMessage | ErrorMessage | AwarenessUpdateMessage | YjsDocUpdateMessage;
|
|
444
|
+
type SyncMessage = HandshakeMessage | HandshakeResponseMessage | OperationBatchMessage | AcknowledgmentMessage | ErrorMessage | AwarenessUpdateMessage | YjsDocUpdateMessage | BlobChunkRequestMessage | BlobChunkResponseMessage | BlobChunkPushMessage;
|
|
390
445
|
/**
|
|
391
446
|
* Check if an unknown value is a valid SyncMessage.
|
|
392
447
|
*/
|
|
@@ -419,6 +474,18 @@ declare function isAwarenessUpdateMessage(value: unknown): value is AwarenessUpd
|
|
|
419
474
|
* Check if a value is a YjsDocUpdateMessage.
|
|
420
475
|
*/
|
|
421
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;
|
|
422
489
|
|
|
423
490
|
/**
|
|
424
491
|
* Options for transport connection.
|
|
@@ -462,4 +529,4 @@ interface SyncTransport {
|
|
|
462
529
|
isConnected(): boolean;
|
|
463
530
|
}
|
|
464
531
|
|
|
465
|
-
export { type AcknowledgmentMessage as A,
|
|
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 };
|
|
@@ -93,7 +93,7 @@ type SyncState = (typeof SYNC_STATES)[number];
|
|
|
93
93
|
/**
|
|
94
94
|
* Developer-facing sync status. Simplified view of the internal state.
|
|
95
95
|
*/
|
|
96
|
-
declare const SYNC_STATUSES: readonly ["connected", "syncing", "synced", "offline", "error", "schema-mismatch"];
|
|
96
|
+
declare const SYNC_STATUSES: readonly ["connected", "syncing", "synced", "offline", "clock-error", "error", "schema-mismatch"];
|
|
97
97
|
type SyncStatus = (typeof SYNC_STATUSES)[number];
|
|
98
98
|
/**
|
|
99
99
|
* Sync status information exposed to developers.
|
|
@@ -111,6 +111,8 @@ interface SyncStatusInfo {
|
|
|
111
111
|
lastSuccessfulPull: number | null;
|
|
112
112
|
/** Number of merge conflicts encountered during this session */
|
|
113
113
|
conflicts: number;
|
|
114
|
+
/** serverTime - localTime in ms measured at the last handshake, or null before first connect. Negative = this device's clock is fast. */
|
|
115
|
+
clockSkewMs: number | null;
|
|
114
116
|
}
|
|
115
117
|
/**
|
|
116
118
|
* Per-collection sync scope map. Maps collection names to field-value filters.
|
|
@@ -303,6 +305,14 @@ interface HandshakeResponseMessage {
|
|
|
303
305
|
selectedWireFormat?: WireFormat;
|
|
304
306
|
/** The server-accepted per-collection sync scope. Confirms what data will be synced. */
|
|
305
307
|
acceptedScope?: Record<string, Record<string, unknown>>;
|
|
308
|
+
/** Server wall-clock time (ms since epoch) at response creation. Lets clients measure their own clock skew. */
|
|
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;
|
|
306
316
|
}
|
|
307
317
|
/**
|
|
308
318
|
* Batch of operations sent during delta exchange or streaming.
|
|
@@ -383,10 +393,55 @@ interface YjsDocUpdateMessage {
|
|
|
383
393
|
/** Base64-encoded Yjs update binary */
|
|
384
394
|
update: string;
|
|
385
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
|
+
}
|
|
386
441
|
/**
|
|
387
442
|
* Union of all sync protocol messages.
|
|
388
443
|
*/
|
|
389
|
-
type SyncMessage = HandshakeMessage | HandshakeResponseMessage | OperationBatchMessage | AcknowledgmentMessage | ErrorMessage | AwarenessUpdateMessage | YjsDocUpdateMessage;
|
|
444
|
+
type SyncMessage = HandshakeMessage | HandshakeResponseMessage | OperationBatchMessage | AcknowledgmentMessage | ErrorMessage | AwarenessUpdateMessage | YjsDocUpdateMessage | BlobChunkRequestMessage | BlobChunkResponseMessage | BlobChunkPushMessage;
|
|
390
445
|
/**
|
|
391
446
|
* Check if an unknown value is a valid SyncMessage.
|
|
392
447
|
*/
|
|
@@ -419,6 +474,18 @@ declare function isAwarenessUpdateMessage(value: unknown): value is AwarenessUpd
|
|
|
419
474
|
* Check if a value is a YjsDocUpdateMessage.
|
|
420
475
|
*/
|
|
421
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;
|
|
422
489
|
|
|
423
490
|
/**
|
|
424
491
|
* Options for transport connection.
|
|
@@ -462,4 +529,4 @@ interface SyncTransport {
|
|
|
462
529
|
isConnected(): boolean;
|
|
463
530
|
}
|
|
464
531
|
|
|
465
|
-
export { type AcknowledgmentMessage as A,
|
|
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": "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/
|
|
37
|
-
"@korajs/
|
|
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",
|