@korajs/sync 1.0.0-beta.0 → 1.0.0-beta.2
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 +392 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +119 -3
- package/dist/index.d.ts +119 -3
- package/dist/index.js +369 -4
- package/dist/index.js.map +1 -1
- package/dist/internal.d.cts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/{transport-BMesMB6s.d.cts → transport-BGr-_eH8.d.cts} +138 -2
- package/dist/{transport-BMesMB6s.d.ts → transport-BGr-_eH8.d.ts} +138 -2
- package/package.json +4 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SyncScopeMap, D as DeltaCursor, a as SyncMessage, b as SerializedOperation, W as WireFormat, c as SyncTransport, T as TransportOptions, d as TransportMessageHandler, e as TransportCloseHandler, f as TransportErrorHandler, g as SyncEncryptionConfig, V as VersionedKey, Y as YjsDocUpdateMessage, Q as QueueStorage,
|
|
2
|
-
export { A as AcknowledgmentMessage,
|
|
1
|
+
import { S as SyncScopeMap, D as DeltaCursor, a as SyncMessage, b as SerializedOperation, W as WireFormat, c as SyncTransport, T as TransportOptions, d as TransportMessageHandler, e as TransportCloseHandler, f as TransportErrorHandler, B as BlobChunkRequestMessage, g as BlobChunkResponseMessage, h as BlobChunkPushMessage, i as SyncEncryptionConfig, V as VersionedKey, Y as YjsDocUpdateMessage, Q as QueueStorage, j as SyncState, k as SyncStatusInfo, l as SyncConfig, R as RejectedOperationStorage, m as SyncStatePersistence, n as SyncQuerySubset, o as RejectedOperation } from './transport-BGr-_eH8.cjs';
|
|
2
|
+
export { A as AcknowledgmentMessage, p as AwarenessStateWire, q as AwarenessUpdateMessage, E as EncryptedPayload, r as ErrorMessage, H as HandshakeMessage, s as HandshakeResponseMessage, I as InvalidScopeError, M as MemoryRejectedOperationStorage, O as OperationBatchMessage, t as OperationRejectedMessage, u as SYNC_STATES, v as SYNC_STATUSES, w as ScopeViolationError, x as SyncEncryptionAlgorithm, y as SyncScopeContext, z as SyncStatus, C as dedupeQuerySubsets, F as isAcknowledgmentMessage, G as isAwarenessUpdateMessage, J as isBlobChunkPushMessage, K as isBlobChunkRequestMessage, L as isBlobChunkResponseMessage, N as isErrorMessage, P as isHandshakeMessage, U as isHandshakeResponseMessage, X as isOperationBatchMessage, Z as isOperationRejectedMessage, _ as isSyncMessage, $ as isYjsDocUpdateMessage, a0 as operationMatchesQuerySubsets } from './transport-BGr-_eH8.cjs';
|
|
3
3
|
import * as _korajs_core from '@korajs/core';
|
|
4
4
|
import { Operation, VersionVector, ApplyResult, KoraEventEmitter, TimeSource, SyncError, ConnectionQuality } from '@korajs/core';
|
|
5
5
|
export { ApplyFailureReason, ApplyResult } from '@korajs/core';
|
|
@@ -470,6 +470,71 @@ declare class AwarenessManager {
|
|
|
470
470
|
private emitAwarenessEvent;
|
|
471
471
|
}
|
|
472
472
|
|
|
473
|
+
/**
|
|
474
|
+
* A blob-chunk message in decoded form (chunk bytes as a `Uint8Array` rather
|
|
475
|
+
* than the base64 wire string). This is the shape callers of the channel work
|
|
476
|
+
* with; the channel handles base64 encode/decode at the wire boundary.
|
|
477
|
+
*
|
|
478
|
+
* The shape mirrors `@korajs/store`'s `ChunkMessage` so an app-layer adapter can
|
|
479
|
+
* bridge the two with no field translation.
|
|
480
|
+
*/
|
|
481
|
+
type BlobChunkChannelMessage = {
|
|
482
|
+
type: 'blob-chunk-request';
|
|
483
|
+
requestId: string;
|
|
484
|
+
hash: string;
|
|
485
|
+
} | {
|
|
486
|
+
type: 'blob-chunk-response';
|
|
487
|
+
requestId: string;
|
|
488
|
+
bytes: Uint8Array | null;
|
|
489
|
+
} | {
|
|
490
|
+
type: 'blob-chunk-push';
|
|
491
|
+
hash: string;
|
|
492
|
+
bytes: Uint8Array;
|
|
493
|
+
};
|
|
494
|
+
/** Encode chunk bytes to a base64 string for the JSON wire. */
|
|
495
|
+
declare function encodeBlobChunkBytes(bytes: Uint8Array): string;
|
|
496
|
+
/** Decode base64 chunk bytes from the wire back to a `Uint8Array`. */
|
|
497
|
+
declare function decodeBlobChunkBytes(encoded: string): Uint8Array;
|
|
498
|
+
interface BlobChunkChannelOptions {
|
|
499
|
+
/**
|
|
500
|
+
* Called when a local blob-chunk message should go out on the wire. The
|
|
501
|
+
* caller (the sync engine) decides whether the connection is ready to send.
|
|
502
|
+
*/
|
|
503
|
+
onSend?: (message: BlobChunkRequestMessage | BlobChunkResponseMessage | BlobChunkPushMessage) => void;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Ephemeral side channel for out-of-band blob chunk transfer over the sync
|
|
507
|
+
* connection. Symmetric: a peer can both request chunks it needs and answer
|
|
508
|
+
* requests for chunks it holds. Never persisted in the operation log — durable
|
|
509
|
+
* state is the `BlobRef` inside a record's fields; this channel only moves the
|
|
510
|
+
* referenced bytes.
|
|
511
|
+
*
|
|
512
|
+
* The channel owns the base64 wire encoding so callers work purely in
|
|
513
|
+
* `Uint8Array`, and its {@link BlobChunkChannelMessage} shape mirrors
|
|
514
|
+
* `@korajs/store`'s `ChunkMessage` so the app layer can expose it as a
|
|
515
|
+
* `ChunkMessagePort` without translating fields.
|
|
516
|
+
*/
|
|
517
|
+
declare class BlobChunkChannel {
|
|
518
|
+
private readonly onSend;
|
|
519
|
+
private readonly handlers;
|
|
520
|
+
constructor(options?: BlobChunkChannelOptions);
|
|
521
|
+
/**
|
|
522
|
+
* Send a blob-chunk message to the peer. Response bytes are base64-encoded
|
|
523
|
+
* onto the wire here; callers pass a `Uint8Array`.
|
|
524
|
+
*/
|
|
525
|
+
send(message: BlobChunkChannelMessage): void;
|
|
526
|
+
/**
|
|
527
|
+
* Register a handler for inbound blob-chunk messages. Multiple handlers are
|
|
528
|
+
* allowed; each receives every delivered message.
|
|
529
|
+
*/
|
|
530
|
+
onMessage(handler: (message: BlobChunkChannelMessage) => void): () => void;
|
|
531
|
+
/**
|
|
532
|
+
* Deliver an inbound wire message to registered handlers, decoding response
|
|
533
|
+
* bytes from base64 back to a `Uint8Array` first.
|
|
534
|
+
*/
|
|
535
|
+
deliver(message: BlobChunkRequestMessage | BlobChunkResponseMessage | BlobChunkPushMessage): void;
|
|
536
|
+
}
|
|
537
|
+
|
|
473
538
|
/**
|
|
474
539
|
* Configuration for the SyncMetricsCollector.
|
|
475
540
|
*/
|
|
@@ -779,6 +844,14 @@ declare class OutboundQueue {
|
|
|
779
844
|
* Whether initialize() has been called.
|
|
780
845
|
*/
|
|
781
846
|
get isInitialized(): boolean;
|
|
847
|
+
/**
|
|
848
|
+
* Remove a single operation the server permanently rejected — from the queue,
|
|
849
|
+
* from any in-flight batch, and from durable storage — so a later batch ack or
|
|
850
|
+
* a reconnect `returnBatch` can never resend or resurrect it. Returns the
|
|
851
|
+
* removed operation so the caller can record it in a durable rejected store,
|
|
852
|
+
* or null if it was not present (already acknowledged and removed).
|
|
853
|
+
*/
|
|
854
|
+
reject(opId: string): Promise<Operation | null>;
|
|
782
855
|
/**
|
|
783
856
|
* Remove operations by id from queue and persistent storage.
|
|
784
857
|
* Used when ops were already sent during handshake delta exchange.
|
|
@@ -802,6 +875,11 @@ interface SyncEngineOptions {
|
|
|
802
875
|
emitter?: KoraEventEmitter;
|
|
803
876
|
/** Queue storage for persistent outbound queue. Defaults to in-memory. */
|
|
804
877
|
queueStorage?: QueueStorage;
|
|
878
|
+
/**
|
|
879
|
+
* Durable storage for operations the server rejected. Defaults to in-memory.
|
|
880
|
+
* Provide a store-backed implementation so rejections survive a page refresh.
|
|
881
|
+
*/
|
|
882
|
+
rejectedStorage?: RejectedOperationStorage;
|
|
805
883
|
/**
|
|
806
884
|
* Optional encryptor for end-to-end encryption.
|
|
807
885
|
* When provided, `data` and `previousData` fields of operations are encrypted
|
|
@@ -846,10 +924,12 @@ declare class SyncEngine {
|
|
|
846
924
|
private readonly serializer;
|
|
847
925
|
private readonly emitter;
|
|
848
926
|
private readonly outboundQueue;
|
|
927
|
+
private readonly rejectedStorage;
|
|
849
928
|
private readonly batchSize;
|
|
850
929
|
private readonly encryptor;
|
|
851
930
|
private readonly awarenessManager;
|
|
852
931
|
private readonly richtextDocChannel;
|
|
932
|
+
private readonly blobChunkChannel;
|
|
853
933
|
private readonly metricsCollector;
|
|
854
934
|
private readonly syncState;
|
|
855
935
|
private remoteVector;
|
|
@@ -864,6 +944,7 @@ declare class SyncEngine {
|
|
|
864
944
|
private schemaBlocked;
|
|
865
945
|
private clockBlocked;
|
|
866
946
|
private clockSkewMs;
|
|
947
|
+
private blobStorageEnabled;
|
|
867
948
|
private deltaBatchesReceived;
|
|
868
949
|
private deltaReceiveComplete;
|
|
869
950
|
private deltaSendComplete;
|
|
@@ -998,6 +1079,22 @@ declare class SyncEngine {
|
|
|
998
1079
|
* Optional side channel for incremental Yjs updates on large richtext fields.
|
|
999
1080
|
*/
|
|
1000
1081
|
getRichtextDocChannel(): RichtextDocChannel;
|
|
1082
|
+
/**
|
|
1083
|
+
* Side channel for out-of-band blob chunk transfer over the sync connection.
|
|
1084
|
+
* The app layer bridges this to a `ChunkMessagePort` to pull/serve blob bytes.
|
|
1085
|
+
*/
|
|
1086
|
+
getBlobChunkChannel(): BlobChunkChannel;
|
|
1087
|
+
/**
|
|
1088
|
+
* Whether the connected server persists blob bytes centrally (learned from the
|
|
1089
|
+
* handshake response). When true, the app uploads the bytes behind `blob`
|
|
1090
|
+
* fields so they stay available after the authoring device goes offline.
|
|
1091
|
+
*/
|
|
1092
|
+
isBlobStorageEnabled(): boolean;
|
|
1093
|
+
/**
|
|
1094
|
+
* Upload a blob chunk (or manifest) to the server for central persistence.
|
|
1095
|
+
* A no-op unless connected and the server advertised blob storage.
|
|
1096
|
+
*/
|
|
1097
|
+
uploadBlobChunk(hash: string, bytes: Uint8Array): void;
|
|
1001
1098
|
private messageChain;
|
|
1002
1099
|
private enqueueMessage;
|
|
1003
1100
|
private handleMessageAsync;
|
|
@@ -1024,6 +1121,25 @@ declare class SyncEngine {
|
|
|
1024
1121
|
private handleOperationBatch;
|
|
1025
1122
|
private handleAcknowledgment;
|
|
1026
1123
|
private handleError;
|
|
1124
|
+
/**
|
|
1125
|
+
* Handle a per-operation rejection: divert the op out of the pending outbound
|
|
1126
|
+
* queue (so it is never retried or resurrected on reconnect), record it in the
|
|
1127
|
+
* durable rejected store (so it is kept and explainable), and emit an event so
|
|
1128
|
+
* the app can reconcile. Unlike {@link handleError}, this is a normal per-op
|
|
1129
|
+
* signal, so the connection stays up.
|
|
1130
|
+
*/
|
|
1131
|
+
private handleOperationRejected;
|
|
1132
|
+
/**
|
|
1133
|
+
* Every operation the server rejected that has not yet been reconciled. The app
|
|
1134
|
+
* uses this (alongside the `sync:operation-rejected` event) to surface failed
|
|
1135
|
+
* submissions and decide whether to roll back or resubmit.
|
|
1136
|
+
*/
|
|
1137
|
+
getRejectedOperations(): Promise<RejectedOperation[]>;
|
|
1138
|
+
/**
|
|
1139
|
+
* Forget rejected operations by id once the app has reconciled them (rolled the
|
|
1140
|
+
* optimistic write back or resubmitted a corrected op).
|
|
1141
|
+
*/
|
|
1142
|
+
clearRejectedOperations(operationIds: string[]): Promise<void>;
|
|
1027
1143
|
private checkDeltaComplete;
|
|
1028
1144
|
/**
|
|
1029
1145
|
* Effective server vector: persisted last-ack merged with live handshake remote vector.
|
|
@@ -1292,4 +1408,4 @@ declare function getRemoteAwarenessStates(awareness: AwarenessManager): Awarenes
|
|
|
1292
1408
|
*/
|
|
1293
1409
|
declare function subscribeRemoteAwarenessStates(awareness: AwarenessManager, listener: (states: AwarenessState[]) => void): () => void;
|
|
1294
1410
|
|
|
1295
|
-
export { type AwarenessChange, type AwarenessCursor, AwarenessManager, type AwarenessMessage, type AwarenessState, type AwarenessUser, type ChaosConfig, ChaosTransport, ConnectionMonitor, type ConnectionMonitorConfig, type CursorInfo, DEFAULT_RICHTEXT_DOC_CHANNEL_THRESHOLD, DecryptionError, DeltaCursor, EncryptionError, HttpLongPollingTransport, type HttpLongPollingTransportOptions, JsonMessageSerializer, KeyDerivationError, type MessageSerializer, NegotiatedMessageSerializer, OFFLINE_SYNC_STATUS, type OutboundBatch, OutboundQueue, ProtobufMessageSerializer, QueueStorage, type ReconnectionConfig, ReconnectionManager, RichtextDocChannel, type RichtextDocChannelOptions, type RichtextDocListener, SCHEMA_MISMATCH_PREFIX, SerializedOperation, SyncConfig, type SyncDiagnostics, SyncEncryptionConfig, SyncEncryptor, SyncEngine, type SyncEngineOptions, SyncMessage, SyncQuerySubset, SyncScopeMap, SyncState, SyncStatePersistence, type SyncStatusController, type SyncStatusControllerOptions, SyncStatusInfo, type SyncStore, SyncTransport, TransportCloseHandler, TransportErrorHandler, TransportMessageHandler, TransportOptions, VersionedKey, type WebSocketConstructor, type WebSocketLike, WebSocketTransport, type WebSocketTransportOptions, WireFormat, YjsDocUpdateMessage, createDeltaCursorFromBatch, createSyncStatusController, decodeDeltaCursor, decodeYjsUpdate, deriveKey, deriveVersionedKey, encodeDeltaCursor, encodeYjsUpdate, filterOperationsByScope, generateSalt, getRemoteAwarenessStates, isClientSchemaVersionSupported, isEncryptedPayload, isSchemaMismatchReject, operationMatchesScope, richtextDocKey, sliceOperationsAfterCursor, subscribeRemoteAwarenessStates, versionVectorToWire, wireToVersionVector };
|
|
1411
|
+
export { type AwarenessChange, type AwarenessCursor, AwarenessManager, type AwarenessMessage, type AwarenessState, type AwarenessUser, BlobChunkChannel, type BlobChunkChannelMessage, type BlobChunkChannelOptions, BlobChunkPushMessage, BlobChunkRequestMessage, BlobChunkResponseMessage, type ChaosConfig, ChaosTransport, ConnectionMonitor, type ConnectionMonitorConfig, type CursorInfo, DEFAULT_RICHTEXT_DOC_CHANNEL_THRESHOLD, DecryptionError, DeltaCursor, EncryptionError, HttpLongPollingTransport, type HttpLongPollingTransportOptions, JsonMessageSerializer, KeyDerivationError, type MessageSerializer, NegotiatedMessageSerializer, OFFLINE_SYNC_STATUS, type OutboundBatch, OutboundQueue, ProtobufMessageSerializer, QueueStorage, type ReconnectionConfig, ReconnectionManager, RejectedOperation, RejectedOperationStorage, RichtextDocChannel, type RichtextDocChannelOptions, type RichtextDocListener, SCHEMA_MISMATCH_PREFIX, SerializedOperation, SyncConfig, type SyncDiagnostics, SyncEncryptionConfig, SyncEncryptor, SyncEngine, type SyncEngineOptions, SyncMessage, SyncQuerySubset, SyncScopeMap, SyncState, SyncStatePersistence, type SyncStatusController, type SyncStatusControllerOptions, SyncStatusInfo, type SyncStore, SyncTransport, TransportCloseHandler, TransportErrorHandler, TransportMessageHandler, TransportOptions, VersionedKey, type WebSocketConstructor, type WebSocketLike, WebSocketTransport, type WebSocketTransportOptions, WireFormat, YjsDocUpdateMessage, createDeltaCursorFromBatch, createSyncStatusController, decodeBlobChunkBytes, decodeDeltaCursor, decodeYjsUpdate, deriveKey, deriveVersionedKey, encodeBlobChunkBytes, encodeDeltaCursor, encodeYjsUpdate, filterOperationsByScope, generateSalt, getRemoteAwarenessStates, isClientSchemaVersionSupported, isEncryptedPayload, isSchemaMismatchReject, operationMatchesScope, richtextDocKey, sliceOperationsAfterCursor, subscribeRemoteAwarenessStates, versionVectorToWire, wireToVersionVector };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SyncScopeMap, D as DeltaCursor, a as SyncMessage, b as SerializedOperation, W as WireFormat, c as SyncTransport, T as TransportOptions, d as TransportMessageHandler, e as TransportCloseHandler, f as TransportErrorHandler, g as SyncEncryptionConfig, V as VersionedKey, Y as YjsDocUpdateMessage, Q as QueueStorage,
|
|
2
|
-
export { A as AcknowledgmentMessage,
|
|
1
|
+
import { S as SyncScopeMap, D as DeltaCursor, a as SyncMessage, b as SerializedOperation, W as WireFormat, c as SyncTransport, T as TransportOptions, d as TransportMessageHandler, e as TransportCloseHandler, f as TransportErrorHandler, B as BlobChunkRequestMessage, g as BlobChunkResponseMessage, h as BlobChunkPushMessage, i as SyncEncryptionConfig, V as VersionedKey, Y as YjsDocUpdateMessage, Q as QueueStorage, j as SyncState, k as SyncStatusInfo, l as SyncConfig, R as RejectedOperationStorage, m as SyncStatePersistence, n as SyncQuerySubset, o as RejectedOperation } from './transport-BGr-_eH8.js';
|
|
2
|
+
export { A as AcknowledgmentMessage, p as AwarenessStateWire, q as AwarenessUpdateMessage, E as EncryptedPayload, r as ErrorMessage, H as HandshakeMessage, s as HandshakeResponseMessage, I as InvalidScopeError, M as MemoryRejectedOperationStorage, O as OperationBatchMessage, t as OperationRejectedMessage, u as SYNC_STATES, v as SYNC_STATUSES, w as ScopeViolationError, x as SyncEncryptionAlgorithm, y as SyncScopeContext, z as SyncStatus, C as dedupeQuerySubsets, F as isAcknowledgmentMessage, G as isAwarenessUpdateMessage, J as isBlobChunkPushMessage, K as isBlobChunkRequestMessage, L as isBlobChunkResponseMessage, N as isErrorMessage, P as isHandshakeMessage, U as isHandshakeResponseMessage, X as isOperationBatchMessage, Z as isOperationRejectedMessage, _ as isSyncMessage, $ as isYjsDocUpdateMessage, a0 as operationMatchesQuerySubsets } from './transport-BGr-_eH8.js';
|
|
3
3
|
import * as _korajs_core from '@korajs/core';
|
|
4
4
|
import { Operation, VersionVector, ApplyResult, KoraEventEmitter, TimeSource, SyncError, ConnectionQuality } from '@korajs/core';
|
|
5
5
|
export { ApplyFailureReason, ApplyResult } from '@korajs/core';
|
|
@@ -470,6 +470,71 @@ declare class AwarenessManager {
|
|
|
470
470
|
private emitAwarenessEvent;
|
|
471
471
|
}
|
|
472
472
|
|
|
473
|
+
/**
|
|
474
|
+
* A blob-chunk message in decoded form (chunk bytes as a `Uint8Array` rather
|
|
475
|
+
* than the base64 wire string). This is the shape callers of the channel work
|
|
476
|
+
* with; the channel handles base64 encode/decode at the wire boundary.
|
|
477
|
+
*
|
|
478
|
+
* The shape mirrors `@korajs/store`'s `ChunkMessage` so an app-layer adapter can
|
|
479
|
+
* bridge the two with no field translation.
|
|
480
|
+
*/
|
|
481
|
+
type BlobChunkChannelMessage = {
|
|
482
|
+
type: 'blob-chunk-request';
|
|
483
|
+
requestId: string;
|
|
484
|
+
hash: string;
|
|
485
|
+
} | {
|
|
486
|
+
type: 'blob-chunk-response';
|
|
487
|
+
requestId: string;
|
|
488
|
+
bytes: Uint8Array | null;
|
|
489
|
+
} | {
|
|
490
|
+
type: 'blob-chunk-push';
|
|
491
|
+
hash: string;
|
|
492
|
+
bytes: Uint8Array;
|
|
493
|
+
};
|
|
494
|
+
/** Encode chunk bytes to a base64 string for the JSON wire. */
|
|
495
|
+
declare function encodeBlobChunkBytes(bytes: Uint8Array): string;
|
|
496
|
+
/** Decode base64 chunk bytes from the wire back to a `Uint8Array`. */
|
|
497
|
+
declare function decodeBlobChunkBytes(encoded: string): Uint8Array;
|
|
498
|
+
interface BlobChunkChannelOptions {
|
|
499
|
+
/**
|
|
500
|
+
* Called when a local blob-chunk message should go out on the wire. The
|
|
501
|
+
* caller (the sync engine) decides whether the connection is ready to send.
|
|
502
|
+
*/
|
|
503
|
+
onSend?: (message: BlobChunkRequestMessage | BlobChunkResponseMessage | BlobChunkPushMessage) => void;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Ephemeral side channel for out-of-band blob chunk transfer over the sync
|
|
507
|
+
* connection. Symmetric: a peer can both request chunks it needs and answer
|
|
508
|
+
* requests for chunks it holds. Never persisted in the operation log — durable
|
|
509
|
+
* state is the `BlobRef` inside a record's fields; this channel only moves the
|
|
510
|
+
* referenced bytes.
|
|
511
|
+
*
|
|
512
|
+
* The channel owns the base64 wire encoding so callers work purely in
|
|
513
|
+
* `Uint8Array`, and its {@link BlobChunkChannelMessage} shape mirrors
|
|
514
|
+
* `@korajs/store`'s `ChunkMessage` so the app layer can expose it as a
|
|
515
|
+
* `ChunkMessagePort` without translating fields.
|
|
516
|
+
*/
|
|
517
|
+
declare class BlobChunkChannel {
|
|
518
|
+
private readonly onSend;
|
|
519
|
+
private readonly handlers;
|
|
520
|
+
constructor(options?: BlobChunkChannelOptions);
|
|
521
|
+
/**
|
|
522
|
+
* Send a blob-chunk message to the peer. Response bytes are base64-encoded
|
|
523
|
+
* onto the wire here; callers pass a `Uint8Array`.
|
|
524
|
+
*/
|
|
525
|
+
send(message: BlobChunkChannelMessage): void;
|
|
526
|
+
/**
|
|
527
|
+
* Register a handler for inbound blob-chunk messages. Multiple handlers are
|
|
528
|
+
* allowed; each receives every delivered message.
|
|
529
|
+
*/
|
|
530
|
+
onMessage(handler: (message: BlobChunkChannelMessage) => void): () => void;
|
|
531
|
+
/**
|
|
532
|
+
* Deliver an inbound wire message to registered handlers, decoding response
|
|
533
|
+
* bytes from base64 back to a `Uint8Array` first.
|
|
534
|
+
*/
|
|
535
|
+
deliver(message: BlobChunkRequestMessage | BlobChunkResponseMessage | BlobChunkPushMessage): void;
|
|
536
|
+
}
|
|
537
|
+
|
|
473
538
|
/**
|
|
474
539
|
* Configuration for the SyncMetricsCollector.
|
|
475
540
|
*/
|
|
@@ -779,6 +844,14 @@ declare class OutboundQueue {
|
|
|
779
844
|
* Whether initialize() has been called.
|
|
780
845
|
*/
|
|
781
846
|
get isInitialized(): boolean;
|
|
847
|
+
/**
|
|
848
|
+
* Remove a single operation the server permanently rejected — from the queue,
|
|
849
|
+
* from any in-flight batch, and from durable storage — so a later batch ack or
|
|
850
|
+
* a reconnect `returnBatch` can never resend or resurrect it. Returns the
|
|
851
|
+
* removed operation so the caller can record it in a durable rejected store,
|
|
852
|
+
* or null if it was not present (already acknowledged and removed).
|
|
853
|
+
*/
|
|
854
|
+
reject(opId: string): Promise<Operation | null>;
|
|
782
855
|
/**
|
|
783
856
|
* Remove operations by id from queue and persistent storage.
|
|
784
857
|
* Used when ops were already sent during handshake delta exchange.
|
|
@@ -802,6 +875,11 @@ interface SyncEngineOptions {
|
|
|
802
875
|
emitter?: KoraEventEmitter;
|
|
803
876
|
/** Queue storage for persistent outbound queue. Defaults to in-memory. */
|
|
804
877
|
queueStorage?: QueueStorage;
|
|
878
|
+
/**
|
|
879
|
+
* Durable storage for operations the server rejected. Defaults to in-memory.
|
|
880
|
+
* Provide a store-backed implementation so rejections survive a page refresh.
|
|
881
|
+
*/
|
|
882
|
+
rejectedStorage?: RejectedOperationStorage;
|
|
805
883
|
/**
|
|
806
884
|
* Optional encryptor for end-to-end encryption.
|
|
807
885
|
* When provided, `data` and `previousData` fields of operations are encrypted
|
|
@@ -846,10 +924,12 @@ declare class SyncEngine {
|
|
|
846
924
|
private readonly serializer;
|
|
847
925
|
private readonly emitter;
|
|
848
926
|
private readonly outboundQueue;
|
|
927
|
+
private readonly rejectedStorage;
|
|
849
928
|
private readonly batchSize;
|
|
850
929
|
private readonly encryptor;
|
|
851
930
|
private readonly awarenessManager;
|
|
852
931
|
private readonly richtextDocChannel;
|
|
932
|
+
private readonly blobChunkChannel;
|
|
853
933
|
private readonly metricsCollector;
|
|
854
934
|
private readonly syncState;
|
|
855
935
|
private remoteVector;
|
|
@@ -864,6 +944,7 @@ declare class SyncEngine {
|
|
|
864
944
|
private schemaBlocked;
|
|
865
945
|
private clockBlocked;
|
|
866
946
|
private clockSkewMs;
|
|
947
|
+
private blobStorageEnabled;
|
|
867
948
|
private deltaBatchesReceived;
|
|
868
949
|
private deltaReceiveComplete;
|
|
869
950
|
private deltaSendComplete;
|
|
@@ -998,6 +1079,22 @@ declare class SyncEngine {
|
|
|
998
1079
|
* Optional side channel for incremental Yjs updates on large richtext fields.
|
|
999
1080
|
*/
|
|
1000
1081
|
getRichtextDocChannel(): RichtextDocChannel;
|
|
1082
|
+
/**
|
|
1083
|
+
* Side channel for out-of-band blob chunk transfer over the sync connection.
|
|
1084
|
+
* The app layer bridges this to a `ChunkMessagePort` to pull/serve blob bytes.
|
|
1085
|
+
*/
|
|
1086
|
+
getBlobChunkChannel(): BlobChunkChannel;
|
|
1087
|
+
/**
|
|
1088
|
+
* Whether the connected server persists blob bytes centrally (learned from the
|
|
1089
|
+
* handshake response). When true, the app uploads the bytes behind `blob`
|
|
1090
|
+
* fields so they stay available after the authoring device goes offline.
|
|
1091
|
+
*/
|
|
1092
|
+
isBlobStorageEnabled(): boolean;
|
|
1093
|
+
/**
|
|
1094
|
+
* Upload a blob chunk (or manifest) to the server for central persistence.
|
|
1095
|
+
* A no-op unless connected and the server advertised blob storage.
|
|
1096
|
+
*/
|
|
1097
|
+
uploadBlobChunk(hash: string, bytes: Uint8Array): void;
|
|
1001
1098
|
private messageChain;
|
|
1002
1099
|
private enqueueMessage;
|
|
1003
1100
|
private handleMessageAsync;
|
|
@@ -1024,6 +1121,25 @@ declare class SyncEngine {
|
|
|
1024
1121
|
private handleOperationBatch;
|
|
1025
1122
|
private handleAcknowledgment;
|
|
1026
1123
|
private handleError;
|
|
1124
|
+
/**
|
|
1125
|
+
* Handle a per-operation rejection: divert the op out of the pending outbound
|
|
1126
|
+
* queue (so it is never retried or resurrected on reconnect), record it in the
|
|
1127
|
+
* durable rejected store (so it is kept and explainable), and emit an event so
|
|
1128
|
+
* the app can reconcile. Unlike {@link handleError}, this is a normal per-op
|
|
1129
|
+
* signal, so the connection stays up.
|
|
1130
|
+
*/
|
|
1131
|
+
private handleOperationRejected;
|
|
1132
|
+
/**
|
|
1133
|
+
* Every operation the server rejected that has not yet been reconciled. The app
|
|
1134
|
+
* uses this (alongside the `sync:operation-rejected` event) to surface failed
|
|
1135
|
+
* submissions and decide whether to roll back or resubmit.
|
|
1136
|
+
*/
|
|
1137
|
+
getRejectedOperations(): Promise<RejectedOperation[]>;
|
|
1138
|
+
/**
|
|
1139
|
+
* Forget rejected operations by id once the app has reconciled them (rolled the
|
|
1140
|
+
* optimistic write back or resubmitted a corrected op).
|
|
1141
|
+
*/
|
|
1142
|
+
clearRejectedOperations(operationIds: string[]): Promise<void>;
|
|
1027
1143
|
private checkDeltaComplete;
|
|
1028
1144
|
/**
|
|
1029
1145
|
* Effective server vector: persisted last-ack merged with live handshake remote vector.
|
|
@@ -1292,4 +1408,4 @@ declare function getRemoteAwarenessStates(awareness: AwarenessManager): Awarenes
|
|
|
1292
1408
|
*/
|
|
1293
1409
|
declare function subscribeRemoteAwarenessStates(awareness: AwarenessManager, listener: (states: AwarenessState[]) => void): () => void;
|
|
1294
1410
|
|
|
1295
|
-
export { type AwarenessChange, type AwarenessCursor, AwarenessManager, type AwarenessMessage, type AwarenessState, type AwarenessUser, type ChaosConfig, ChaosTransport, ConnectionMonitor, type ConnectionMonitorConfig, type CursorInfo, DEFAULT_RICHTEXT_DOC_CHANNEL_THRESHOLD, DecryptionError, DeltaCursor, EncryptionError, HttpLongPollingTransport, type HttpLongPollingTransportOptions, JsonMessageSerializer, KeyDerivationError, type MessageSerializer, NegotiatedMessageSerializer, OFFLINE_SYNC_STATUS, type OutboundBatch, OutboundQueue, ProtobufMessageSerializer, QueueStorage, type ReconnectionConfig, ReconnectionManager, RichtextDocChannel, type RichtextDocChannelOptions, type RichtextDocListener, SCHEMA_MISMATCH_PREFIX, SerializedOperation, SyncConfig, type SyncDiagnostics, SyncEncryptionConfig, SyncEncryptor, SyncEngine, type SyncEngineOptions, SyncMessage, SyncQuerySubset, SyncScopeMap, SyncState, SyncStatePersistence, type SyncStatusController, type SyncStatusControllerOptions, SyncStatusInfo, type SyncStore, SyncTransport, TransportCloseHandler, TransportErrorHandler, TransportMessageHandler, TransportOptions, VersionedKey, type WebSocketConstructor, type WebSocketLike, WebSocketTransport, type WebSocketTransportOptions, WireFormat, YjsDocUpdateMessage, createDeltaCursorFromBatch, createSyncStatusController, decodeDeltaCursor, decodeYjsUpdate, deriveKey, deriveVersionedKey, encodeDeltaCursor, encodeYjsUpdate, filterOperationsByScope, generateSalt, getRemoteAwarenessStates, isClientSchemaVersionSupported, isEncryptedPayload, isSchemaMismatchReject, operationMatchesScope, richtextDocKey, sliceOperationsAfterCursor, subscribeRemoteAwarenessStates, versionVectorToWire, wireToVersionVector };
|
|
1411
|
+
export { type AwarenessChange, type AwarenessCursor, AwarenessManager, type AwarenessMessage, type AwarenessState, type AwarenessUser, BlobChunkChannel, type BlobChunkChannelMessage, type BlobChunkChannelOptions, BlobChunkPushMessage, BlobChunkRequestMessage, BlobChunkResponseMessage, type ChaosConfig, ChaosTransport, ConnectionMonitor, type ConnectionMonitorConfig, type CursorInfo, DEFAULT_RICHTEXT_DOC_CHANNEL_THRESHOLD, DecryptionError, DeltaCursor, EncryptionError, HttpLongPollingTransport, type HttpLongPollingTransportOptions, JsonMessageSerializer, KeyDerivationError, type MessageSerializer, NegotiatedMessageSerializer, OFFLINE_SYNC_STATUS, type OutboundBatch, OutboundQueue, ProtobufMessageSerializer, QueueStorage, type ReconnectionConfig, ReconnectionManager, RejectedOperation, RejectedOperationStorage, RichtextDocChannel, type RichtextDocChannelOptions, type RichtextDocListener, SCHEMA_MISMATCH_PREFIX, SerializedOperation, SyncConfig, type SyncDiagnostics, SyncEncryptionConfig, SyncEncryptor, SyncEngine, type SyncEngineOptions, SyncMessage, SyncQuerySubset, SyncScopeMap, SyncState, SyncStatePersistence, type SyncStatusController, type SyncStatusControllerOptions, SyncStatusInfo, type SyncStore, SyncTransport, TransportCloseHandler, TransportErrorHandler, TransportMessageHandler, TransportOptions, VersionedKey, type WebSocketConstructor, type WebSocketLike, WebSocketTransport, type WebSocketTransportOptions, WireFormat, YjsDocUpdateMessage, createDeltaCursorFromBatch, createSyncStatusController, decodeBlobChunkBytes, decodeDeltaCursor, decodeYjsUpdate, deriveKey, deriveVersionedKey, encodeBlobChunkBytes, encodeDeltaCursor, encodeYjsUpdate, filterOperationsByScope, generateSalt, getRemoteAwarenessStates, isClientSchemaVersionSupported, isEncryptedPayload, isSchemaMismatchReject, operationMatchesScope, richtextDocKey, sliceOperationsAfterCursor, subscribeRemoteAwarenessStates, versionVectorToWire, wireToVersionVector };
|