@korajs/sync 1.0.0-beta.5 → 1.0.0-beta.7
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 +64 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +64 -3
- package/dist/index.js.map +1 -1
- package/dist/internal.d.cts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/{transport-DXmZ8kyI.d.cts → transport-ByWfWBbB.d.cts} +7 -0
- package/dist/{transport-DXmZ8kyI.d.ts → transport-ByWfWBbB.d.ts} +7 -0
- package/package.json +3 -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, 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-
|
|
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-
|
|
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-ByWfWBbB.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-ByWfWBbB.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';
|
|
@@ -946,6 +946,7 @@ declare class SyncEngine {
|
|
|
946
946
|
private readonly outboundQueue;
|
|
947
947
|
private readonly rejectedStorage;
|
|
948
948
|
private readonly batchSize;
|
|
949
|
+
private readonly outboundAckTimeoutMs;
|
|
949
950
|
private readonly encryptor;
|
|
950
951
|
private readonly awarenessManager;
|
|
951
952
|
private readonly richtextDocChannel;
|
|
@@ -965,6 +966,9 @@ declare class SyncEngine {
|
|
|
965
966
|
private clockBlocked;
|
|
966
967
|
private clockSkewMs;
|
|
967
968
|
private blobStorageEnabled;
|
|
969
|
+
private outboundAckTimer;
|
|
970
|
+
private startPromise;
|
|
971
|
+
private stopPromise;
|
|
968
972
|
private deltaBatchesReceived;
|
|
969
973
|
private deltaReceiveComplete;
|
|
970
974
|
private deltaSendComplete;
|
|
@@ -1008,10 +1012,12 @@ declare class SyncEngine {
|
|
|
1008
1012
|
* Start the sync engine: connect → handshake → delta exchange → streaming.
|
|
1009
1013
|
*/
|
|
1010
1014
|
start(): Promise<void>;
|
|
1015
|
+
private startInternal;
|
|
1011
1016
|
/**
|
|
1012
1017
|
* Stop the sync engine. Disconnects the transport.
|
|
1013
1018
|
*/
|
|
1014
1019
|
stop(): Promise<void>;
|
|
1020
|
+
private stopInternal;
|
|
1015
1021
|
private ensureDisconnected;
|
|
1016
1022
|
/**
|
|
1017
1023
|
* Push a local operation to the outbound queue.
|
|
@@ -1236,6 +1242,9 @@ declare class SyncEngine {
|
|
|
1236
1242
|
*/
|
|
1237
1243
|
private reconcileOutboundFromOpLog;
|
|
1238
1244
|
private flushQueue;
|
|
1245
|
+
private startOutboundAckTimer;
|
|
1246
|
+
private clearOutboundAckTimer;
|
|
1247
|
+
private handleOutboundAckTimeout;
|
|
1239
1248
|
private handleAwarenessUpdate;
|
|
1240
1249
|
private handleTransportClose;
|
|
1241
1250
|
private handleTransportError;
|
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, 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-
|
|
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-
|
|
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-ByWfWBbB.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-ByWfWBbB.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';
|
|
@@ -946,6 +946,7 @@ declare class SyncEngine {
|
|
|
946
946
|
private readonly outboundQueue;
|
|
947
947
|
private readonly rejectedStorage;
|
|
948
948
|
private readonly batchSize;
|
|
949
|
+
private readonly outboundAckTimeoutMs;
|
|
949
950
|
private readonly encryptor;
|
|
950
951
|
private readonly awarenessManager;
|
|
951
952
|
private readonly richtextDocChannel;
|
|
@@ -965,6 +966,9 @@ declare class SyncEngine {
|
|
|
965
966
|
private clockBlocked;
|
|
966
967
|
private clockSkewMs;
|
|
967
968
|
private blobStorageEnabled;
|
|
969
|
+
private outboundAckTimer;
|
|
970
|
+
private startPromise;
|
|
971
|
+
private stopPromise;
|
|
968
972
|
private deltaBatchesReceived;
|
|
969
973
|
private deltaReceiveComplete;
|
|
970
974
|
private deltaSendComplete;
|
|
@@ -1008,10 +1012,12 @@ declare class SyncEngine {
|
|
|
1008
1012
|
* Start the sync engine: connect → handshake → delta exchange → streaming.
|
|
1009
1013
|
*/
|
|
1010
1014
|
start(): Promise<void>;
|
|
1015
|
+
private startInternal;
|
|
1011
1016
|
/**
|
|
1012
1017
|
* Stop the sync engine. Disconnects the transport.
|
|
1013
1018
|
*/
|
|
1014
1019
|
stop(): Promise<void>;
|
|
1020
|
+
private stopInternal;
|
|
1015
1021
|
private ensureDisconnected;
|
|
1016
1022
|
/**
|
|
1017
1023
|
* Push a local operation to the outbound queue.
|
|
@@ -1236,6 +1242,9 @@ declare class SyncEngine {
|
|
|
1236
1242
|
*/
|
|
1237
1243
|
private reconcileOutboundFromOpLog;
|
|
1238
1244
|
private flushQueue;
|
|
1245
|
+
private startOutboundAckTimer;
|
|
1246
|
+
private clearOutboundAckTimer;
|
|
1247
|
+
private handleOutboundAckTimeout;
|
|
1239
1248
|
private handleAwarenessUpdate;
|
|
1240
1249
|
private handleTransportClose;
|
|
1241
1250
|
private handleTransportError;
|
package/dist/index.js
CHANGED
|
@@ -2631,6 +2631,7 @@ var OutboundQueue = class {
|
|
|
2631
2631
|
// src/engine/sync-engine.ts
|
|
2632
2632
|
var DEFAULT_BATCH_SIZE = 100;
|
|
2633
2633
|
var DEFAULT_SCHEMA_VERSION = 1;
|
|
2634
|
+
var DEFAULT_OUTBOUND_ACK_TIMEOUT_MS = 3e4;
|
|
2634
2635
|
var VALID_TRANSITIONS = {
|
|
2635
2636
|
disconnected: ["connecting"],
|
|
2636
2637
|
connecting: ["handshaking", "error", "disconnected"],
|
|
@@ -2665,6 +2666,7 @@ var SyncEngine = class {
|
|
|
2665
2666
|
outboundQueue;
|
|
2666
2667
|
rejectedStorage;
|
|
2667
2668
|
batchSize;
|
|
2669
|
+
outboundAckTimeoutMs;
|
|
2668
2670
|
encryptor;
|
|
2669
2671
|
awarenessManager;
|
|
2670
2672
|
richtextDocChannel;
|
|
@@ -2684,6 +2686,9 @@ var SyncEngine = class {
|
|
|
2684
2686
|
clockBlocked = false;
|
|
2685
2687
|
clockSkewMs = null;
|
|
2686
2688
|
blobStorageEnabled = false;
|
|
2689
|
+
outboundAckTimer = null;
|
|
2690
|
+
startPromise = null;
|
|
2691
|
+
stopPromise = null;
|
|
2687
2692
|
// Track delta exchange state
|
|
2688
2693
|
deltaBatchesReceived = 0;
|
|
2689
2694
|
deltaReceiveComplete = false;
|
|
@@ -2730,6 +2735,7 @@ var SyncEngine = class {
|
|
|
2730
2735
|
this.serializer = options.serializer ?? new NegotiatedMessageSerializer("json");
|
|
2731
2736
|
this.emitter = options.emitter ?? null;
|
|
2732
2737
|
this.batchSize = options.config.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
2738
|
+
this.outboundAckTimeoutMs = options.config.outboundAckTimeoutMs ?? DEFAULT_OUTBOUND_ACK_TIMEOUT_MS;
|
|
2733
2739
|
this.encryptor = options.encryptor ?? null;
|
|
2734
2740
|
this.syncState = options.syncState ?? null;
|
|
2735
2741
|
this.activeScope = options.config.scopeMap;
|
|
@@ -2775,10 +2781,20 @@ var SyncEngine = class {
|
|
|
2775
2781
|
* Start the sync engine: connect → handshake → delta exchange → streaming.
|
|
2776
2782
|
*/
|
|
2777
2783
|
async start() {
|
|
2784
|
+
if (this.state === "streaming") return;
|
|
2785
|
+
if (this.startPromise) return this.startPromise;
|
|
2786
|
+
this.startPromise = this.startInternal().finally(() => {
|
|
2787
|
+
this.startPromise = null;
|
|
2788
|
+
});
|
|
2789
|
+
return this.startPromise;
|
|
2790
|
+
}
|
|
2791
|
+
async startInternal() {
|
|
2792
|
+
if (this.stopPromise) {
|
|
2793
|
+
await this.stopPromise;
|
|
2794
|
+
}
|
|
2795
|
+
if (this.state === "streaming") return;
|
|
2778
2796
|
if (this.state !== "disconnected") {
|
|
2779
|
-
|
|
2780
|
-
currentState: this.state
|
|
2781
|
-
});
|
|
2797
|
+
await this.stop();
|
|
2782
2798
|
}
|
|
2783
2799
|
await this.outboundQueue.initialize();
|
|
2784
2800
|
if (this.syncState) {
|
|
@@ -2811,7 +2827,12 @@ var SyncEngine = class {
|
|
|
2811
2827
|
this.transitionTo("connecting");
|
|
2812
2828
|
try {
|
|
2813
2829
|
const authToken = this.config.auth ? (await this.config.auth()).token : void 0;
|
|
2830
|
+
if (this.state !== "connecting") return;
|
|
2814
2831
|
await this.transport.connect(this.config.url, { authToken });
|
|
2832
|
+
if (this.state !== "connecting") {
|
|
2833
|
+
await this.transport.disconnect();
|
|
2834
|
+
return;
|
|
2835
|
+
}
|
|
2815
2836
|
this.transitionTo("handshaking");
|
|
2816
2837
|
const localVector = this.store.getVersionVector();
|
|
2817
2838
|
const activeQuerySubsets = this.getActiveQuerySubsets();
|
|
@@ -2841,7 +2862,15 @@ var SyncEngine = class {
|
|
|
2841
2862
|
* Stop the sync engine. Disconnects the transport.
|
|
2842
2863
|
*/
|
|
2843
2864
|
async stop() {
|
|
2865
|
+
if (this.stopPromise) return this.stopPromise;
|
|
2866
|
+
this.stopPromise = this.stopInternal().finally(() => {
|
|
2867
|
+
this.stopPromise = null;
|
|
2868
|
+
});
|
|
2869
|
+
return this.stopPromise;
|
|
2870
|
+
}
|
|
2871
|
+
async stopInternal() {
|
|
2844
2872
|
if (this.state === "disconnected") return;
|
|
2873
|
+
this.clearOutboundAckTimer();
|
|
2845
2874
|
this.awarenessManager.stopCleanupTimer();
|
|
2846
2875
|
if (this.currentBatch) {
|
|
2847
2876
|
this.outboundQueue.returnBatch(this.currentBatch.batchId);
|
|
@@ -3551,6 +3580,7 @@ var SyncEngine = class {
|
|
|
3551
3580
|
this.transport.send(ack);
|
|
3552
3581
|
}
|
|
3553
3582
|
handleAcknowledgment(msg) {
|
|
3583
|
+
this.clearOutboundAckTimer();
|
|
3554
3584
|
if (this.state === "syncing" && this.config.strictHandshake) {
|
|
3555
3585
|
this.pendingDeltaBatchAcks.delete(msg.acknowledgedMessageId);
|
|
3556
3586
|
this.markDeltaSendCompleteIfReady();
|
|
@@ -3570,6 +3600,7 @@ var SyncEngine = class {
|
|
|
3570
3600
|
}
|
|
3571
3601
|
}
|
|
3572
3602
|
handleError(msg) {
|
|
3603
|
+
this.clearOutboundAckTimer();
|
|
3573
3604
|
if (this.currentBatch) {
|
|
3574
3605
|
this.outboundQueue.returnBatch(this.currentBatch.batchId);
|
|
3575
3606
|
this.currentBatch = null;
|
|
@@ -3757,6 +3788,7 @@ var SyncEngine = class {
|
|
|
3757
3788
|
batchIndex: 0
|
|
3758
3789
|
};
|
|
3759
3790
|
this.transport.send(batchMsg);
|
|
3791
|
+
this.startOutboundAckTimer(batch.batchId);
|
|
3760
3792
|
this.emitter?.emit({
|
|
3761
3793
|
type: "sync:sent",
|
|
3762
3794
|
operations: batch.operations,
|
|
@@ -3782,6 +3814,7 @@ var SyncEngine = class {
|
|
|
3782
3814
|
batchIndex: 0
|
|
3783
3815
|
};
|
|
3784
3816
|
this.transport.send(batchMsg);
|
|
3817
|
+
this.startOutboundAckTimer(batch.batchId);
|
|
3785
3818
|
this.emitter?.emit({
|
|
3786
3819
|
type: "sync:sent",
|
|
3787
3820
|
operations: batch.operations,
|
|
@@ -3789,6 +3822,33 @@ var SyncEngine = class {
|
|
|
3789
3822
|
});
|
|
3790
3823
|
}
|
|
3791
3824
|
}
|
|
3825
|
+
startOutboundAckTimer(batchId) {
|
|
3826
|
+
this.clearOutboundAckTimer();
|
|
3827
|
+
if (this.outboundAckTimeoutMs <= 0) return;
|
|
3828
|
+
this.outboundAckTimer = setTimeout(() => {
|
|
3829
|
+
void this.handleOutboundAckTimeout(batchId);
|
|
3830
|
+
}, this.outboundAckTimeoutMs);
|
|
3831
|
+
}
|
|
3832
|
+
clearOutboundAckTimer() {
|
|
3833
|
+
if (!this.outboundAckTimer) return;
|
|
3834
|
+
clearTimeout(this.outboundAckTimer);
|
|
3835
|
+
this.outboundAckTimer = null;
|
|
3836
|
+
}
|
|
3837
|
+
async handleOutboundAckTimeout(batchId) {
|
|
3838
|
+
if (!this.currentBatch || this.currentBatch.batchId !== batchId) return;
|
|
3839
|
+
this.outboundQueue.returnBatch(batchId);
|
|
3840
|
+
this.currentBatch = null;
|
|
3841
|
+
this.clearOutboundAckTimer();
|
|
3842
|
+
await this.refreshPendingCount();
|
|
3843
|
+
if (this.state === "disconnected") return;
|
|
3844
|
+
const reason = `Timed out waiting for acknowledgment of outbound batch ${batchId}`;
|
|
3845
|
+
try {
|
|
3846
|
+
await this.transport.disconnect();
|
|
3847
|
+
} finally {
|
|
3848
|
+
this.ensureDisconnected();
|
|
3849
|
+
this.emitter?.emit({ type: "sync:disconnected", reason });
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3792
3852
|
handleAwarenessUpdate(msg) {
|
|
3793
3853
|
const awarenessMessage = {
|
|
3794
3854
|
type: "awareness",
|
|
@@ -3798,6 +3858,7 @@ var SyncEngine = class {
|
|
|
3798
3858
|
this.awarenessManager.handleRemoteMessage(awarenessMessage);
|
|
3799
3859
|
}
|
|
3800
3860
|
handleTransportClose(reason) {
|
|
3861
|
+
this.clearOutboundAckTimer();
|
|
3801
3862
|
if (this.currentBatch) {
|
|
3802
3863
|
this.outboundQueue.returnBatch(this.currentBatch.batchId);
|
|
3803
3864
|
this.currentBatch = null;
|