@korajs/sync 1.0.0-beta.5 → 1.0.0-beta.6
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.cjs
CHANGED
|
@@ -2735,6 +2735,7 @@ var OutboundQueue = class {
|
|
|
2735
2735
|
// src/engine/sync-engine.ts
|
|
2736
2736
|
var DEFAULT_BATCH_SIZE = 100;
|
|
2737
2737
|
var DEFAULT_SCHEMA_VERSION = 1;
|
|
2738
|
+
var DEFAULT_OUTBOUND_ACK_TIMEOUT_MS = 3e4;
|
|
2738
2739
|
var VALID_TRANSITIONS = {
|
|
2739
2740
|
disconnected: ["connecting"],
|
|
2740
2741
|
connecting: ["handshaking", "error", "disconnected"],
|
|
@@ -2769,6 +2770,7 @@ var SyncEngine = class {
|
|
|
2769
2770
|
outboundQueue;
|
|
2770
2771
|
rejectedStorage;
|
|
2771
2772
|
batchSize;
|
|
2773
|
+
outboundAckTimeoutMs;
|
|
2772
2774
|
encryptor;
|
|
2773
2775
|
awarenessManager;
|
|
2774
2776
|
richtextDocChannel;
|
|
@@ -2788,6 +2790,9 @@ var SyncEngine = class {
|
|
|
2788
2790
|
clockBlocked = false;
|
|
2789
2791
|
clockSkewMs = null;
|
|
2790
2792
|
blobStorageEnabled = false;
|
|
2793
|
+
outboundAckTimer = null;
|
|
2794
|
+
startPromise = null;
|
|
2795
|
+
stopPromise = null;
|
|
2791
2796
|
// Track delta exchange state
|
|
2792
2797
|
deltaBatchesReceived = 0;
|
|
2793
2798
|
deltaReceiveComplete = false;
|
|
@@ -2834,6 +2839,7 @@ var SyncEngine = class {
|
|
|
2834
2839
|
this.serializer = options.serializer ?? new NegotiatedMessageSerializer("json");
|
|
2835
2840
|
this.emitter = options.emitter ?? null;
|
|
2836
2841
|
this.batchSize = options.config.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
2842
|
+
this.outboundAckTimeoutMs = options.config.outboundAckTimeoutMs ?? DEFAULT_OUTBOUND_ACK_TIMEOUT_MS;
|
|
2837
2843
|
this.encryptor = options.encryptor ?? null;
|
|
2838
2844
|
this.syncState = options.syncState ?? null;
|
|
2839
2845
|
this.activeScope = options.config.scopeMap;
|
|
@@ -2879,10 +2885,20 @@ var SyncEngine = class {
|
|
|
2879
2885
|
* Start the sync engine: connect → handshake → delta exchange → streaming.
|
|
2880
2886
|
*/
|
|
2881
2887
|
async start() {
|
|
2888
|
+
if (this.state === "streaming") return;
|
|
2889
|
+
if (this.startPromise) return this.startPromise;
|
|
2890
|
+
this.startPromise = this.startInternal().finally(() => {
|
|
2891
|
+
this.startPromise = null;
|
|
2892
|
+
});
|
|
2893
|
+
return this.startPromise;
|
|
2894
|
+
}
|
|
2895
|
+
async startInternal() {
|
|
2896
|
+
if (this.stopPromise) {
|
|
2897
|
+
await this.stopPromise;
|
|
2898
|
+
}
|
|
2899
|
+
if (this.state === "streaming") return;
|
|
2882
2900
|
if (this.state !== "disconnected") {
|
|
2883
|
-
|
|
2884
|
-
currentState: this.state
|
|
2885
|
-
});
|
|
2901
|
+
await this.stop();
|
|
2886
2902
|
}
|
|
2887
2903
|
await this.outboundQueue.initialize();
|
|
2888
2904
|
if (this.syncState) {
|
|
@@ -2915,7 +2931,12 @@ var SyncEngine = class {
|
|
|
2915
2931
|
this.transitionTo("connecting");
|
|
2916
2932
|
try {
|
|
2917
2933
|
const authToken = this.config.auth ? (await this.config.auth()).token : void 0;
|
|
2934
|
+
if (this.state !== "connecting") return;
|
|
2918
2935
|
await this.transport.connect(this.config.url, { authToken });
|
|
2936
|
+
if (this.state !== "connecting") {
|
|
2937
|
+
await this.transport.disconnect();
|
|
2938
|
+
return;
|
|
2939
|
+
}
|
|
2919
2940
|
this.transitionTo("handshaking");
|
|
2920
2941
|
const localVector = this.store.getVersionVector();
|
|
2921
2942
|
const activeQuerySubsets = this.getActiveQuerySubsets();
|
|
@@ -2945,7 +2966,15 @@ var SyncEngine = class {
|
|
|
2945
2966
|
* Stop the sync engine. Disconnects the transport.
|
|
2946
2967
|
*/
|
|
2947
2968
|
async stop() {
|
|
2969
|
+
if (this.stopPromise) return this.stopPromise;
|
|
2970
|
+
this.stopPromise = this.stopInternal().finally(() => {
|
|
2971
|
+
this.stopPromise = null;
|
|
2972
|
+
});
|
|
2973
|
+
return this.stopPromise;
|
|
2974
|
+
}
|
|
2975
|
+
async stopInternal() {
|
|
2948
2976
|
if (this.state === "disconnected") return;
|
|
2977
|
+
this.clearOutboundAckTimer();
|
|
2949
2978
|
this.awarenessManager.stopCleanupTimer();
|
|
2950
2979
|
if (this.currentBatch) {
|
|
2951
2980
|
this.outboundQueue.returnBatch(this.currentBatch.batchId);
|
|
@@ -3655,6 +3684,7 @@ var SyncEngine = class {
|
|
|
3655
3684
|
this.transport.send(ack);
|
|
3656
3685
|
}
|
|
3657
3686
|
handleAcknowledgment(msg) {
|
|
3687
|
+
this.clearOutboundAckTimer();
|
|
3658
3688
|
if (this.state === "syncing" && this.config.strictHandshake) {
|
|
3659
3689
|
this.pendingDeltaBatchAcks.delete(msg.acknowledgedMessageId);
|
|
3660
3690
|
this.markDeltaSendCompleteIfReady();
|
|
@@ -3674,6 +3704,7 @@ var SyncEngine = class {
|
|
|
3674
3704
|
}
|
|
3675
3705
|
}
|
|
3676
3706
|
handleError(msg) {
|
|
3707
|
+
this.clearOutboundAckTimer();
|
|
3677
3708
|
if (this.currentBatch) {
|
|
3678
3709
|
this.outboundQueue.returnBatch(this.currentBatch.batchId);
|
|
3679
3710
|
this.currentBatch = null;
|
|
@@ -3861,6 +3892,7 @@ var SyncEngine = class {
|
|
|
3861
3892
|
batchIndex: 0
|
|
3862
3893
|
};
|
|
3863
3894
|
this.transport.send(batchMsg);
|
|
3895
|
+
this.startOutboundAckTimer(batch.batchId);
|
|
3864
3896
|
this.emitter?.emit({
|
|
3865
3897
|
type: "sync:sent",
|
|
3866
3898
|
operations: batch.operations,
|
|
@@ -3886,6 +3918,7 @@ var SyncEngine = class {
|
|
|
3886
3918
|
batchIndex: 0
|
|
3887
3919
|
};
|
|
3888
3920
|
this.transport.send(batchMsg);
|
|
3921
|
+
this.startOutboundAckTimer(batch.batchId);
|
|
3889
3922
|
this.emitter?.emit({
|
|
3890
3923
|
type: "sync:sent",
|
|
3891
3924
|
operations: batch.operations,
|
|
@@ -3893,6 +3926,33 @@ var SyncEngine = class {
|
|
|
3893
3926
|
});
|
|
3894
3927
|
}
|
|
3895
3928
|
}
|
|
3929
|
+
startOutboundAckTimer(batchId) {
|
|
3930
|
+
this.clearOutboundAckTimer();
|
|
3931
|
+
if (this.outboundAckTimeoutMs <= 0) return;
|
|
3932
|
+
this.outboundAckTimer = setTimeout(() => {
|
|
3933
|
+
void this.handleOutboundAckTimeout(batchId);
|
|
3934
|
+
}, this.outboundAckTimeoutMs);
|
|
3935
|
+
}
|
|
3936
|
+
clearOutboundAckTimer() {
|
|
3937
|
+
if (!this.outboundAckTimer) return;
|
|
3938
|
+
clearTimeout(this.outboundAckTimer);
|
|
3939
|
+
this.outboundAckTimer = null;
|
|
3940
|
+
}
|
|
3941
|
+
async handleOutboundAckTimeout(batchId) {
|
|
3942
|
+
if (!this.currentBatch || this.currentBatch.batchId !== batchId) return;
|
|
3943
|
+
this.outboundQueue.returnBatch(batchId);
|
|
3944
|
+
this.currentBatch = null;
|
|
3945
|
+
this.clearOutboundAckTimer();
|
|
3946
|
+
await this.refreshPendingCount();
|
|
3947
|
+
if (this.state === "disconnected") return;
|
|
3948
|
+
const reason = `Timed out waiting for acknowledgment of outbound batch ${batchId}`;
|
|
3949
|
+
try {
|
|
3950
|
+
await this.transport.disconnect();
|
|
3951
|
+
} finally {
|
|
3952
|
+
this.ensureDisconnected();
|
|
3953
|
+
this.emitter?.emit({ type: "sync:disconnected", reason });
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3896
3956
|
handleAwarenessUpdate(msg) {
|
|
3897
3957
|
const awarenessMessage = {
|
|
3898
3958
|
type: "awareness",
|
|
@@ -3902,6 +3962,7 @@ var SyncEngine = class {
|
|
|
3902
3962
|
this.awarenessManager.handleRemoteMessage(awarenessMessage);
|
|
3903
3963
|
}
|
|
3904
3964
|
handleTransportClose(reason) {
|
|
3965
|
+
this.clearOutboundAckTimer();
|
|
3905
3966
|
if (this.currentBatch) {
|
|
3906
3967
|
this.outboundQueue.returnBatch(this.currentBatch.batchId);
|
|
3907
3968
|
this.currentBatch = null;
|