@korajs/sync 0.5.0 → 0.6.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/dist/index.cjs +161 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.js +157 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -1195,4 +1195,37 @@ declare function deriveKey(passphrase: string, salt?: Uint8Array): Promise<{
|
|
|
1195
1195
|
*/
|
|
1196
1196
|
declare function deriveVersionedKey(passphrase: string, version: number, salt?: Uint8Array): Promise<VersionedKey>;
|
|
1197
1197
|
|
|
1198
|
-
|
|
1198
|
+
/** Default status when sync is not configured or the engine is unavailable. */
|
|
1199
|
+
declare const OFFLINE_SYNC_STATUS: SyncStatusInfo;
|
|
1200
|
+
interface SyncStatusControllerOptions {
|
|
1201
|
+
syncEngine?: {
|
|
1202
|
+
getStatus(): SyncStatusInfo;
|
|
1203
|
+
} | null;
|
|
1204
|
+
getSyncEngine?: () => {
|
|
1205
|
+
getStatus(): SyncStatusInfo;
|
|
1206
|
+
} | null;
|
|
1207
|
+
subscribeSyncStatus: ((listener: (status: SyncStatusInfo) => void) => () => void) | null;
|
|
1208
|
+
events: KoraEventEmitter | null;
|
|
1209
|
+
}
|
|
1210
|
+
interface SyncStatusController {
|
|
1211
|
+
getSnapshot(): SyncStatusInfo;
|
|
1212
|
+
subscribe(listener: () => void): () => void;
|
|
1213
|
+
refresh(): void;
|
|
1214
|
+
destroy(): void;
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* Framework-agnostic sync status subscription with live reads when no bridge exists.
|
|
1218
|
+
*/
|
|
1219
|
+
declare function createSyncStatusController(options: SyncStatusControllerOptions): SyncStatusController;
|
|
1220
|
+
|
|
1221
|
+
/**
|
|
1222
|
+
* Returns remote collaborators' awareness states (excludes the local client).
|
|
1223
|
+
*/
|
|
1224
|
+
declare function getRemoteAwarenessStates(awareness: AwarenessManager): AwarenessState[];
|
|
1225
|
+
/**
|
|
1226
|
+
* Subscribes to awareness changes and invokes `listener` only when the remote
|
|
1227
|
+
* collaborator set changes.
|
|
1228
|
+
*/
|
|
1229
|
+
declare function subscribeRemoteAwarenessStates(awareness: AwarenessManager, listener: (states: AwarenessState[]) => void): () => void;
|
|
1230
|
+
|
|
1231
|
+
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1195,4 +1195,37 @@ declare function deriveKey(passphrase: string, salt?: Uint8Array): Promise<{
|
|
|
1195
1195
|
*/
|
|
1196
1196
|
declare function deriveVersionedKey(passphrase: string, version: number, salt?: Uint8Array): Promise<VersionedKey>;
|
|
1197
1197
|
|
|
1198
|
-
|
|
1198
|
+
/** Default status when sync is not configured or the engine is unavailable. */
|
|
1199
|
+
declare const OFFLINE_SYNC_STATUS: SyncStatusInfo;
|
|
1200
|
+
interface SyncStatusControllerOptions {
|
|
1201
|
+
syncEngine?: {
|
|
1202
|
+
getStatus(): SyncStatusInfo;
|
|
1203
|
+
} | null;
|
|
1204
|
+
getSyncEngine?: () => {
|
|
1205
|
+
getStatus(): SyncStatusInfo;
|
|
1206
|
+
} | null;
|
|
1207
|
+
subscribeSyncStatus: ((listener: (status: SyncStatusInfo) => void) => () => void) | null;
|
|
1208
|
+
events: KoraEventEmitter | null;
|
|
1209
|
+
}
|
|
1210
|
+
interface SyncStatusController {
|
|
1211
|
+
getSnapshot(): SyncStatusInfo;
|
|
1212
|
+
subscribe(listener: () => void): () => void;
|
|
1213
|
+
refresh(): void;
|
|
1214
|
+
destroy(): void;
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* Framework-agnostic sync status subscription with live reads when no bridge exists.
|
|
1218
|
+
*/
|
|
1219
|
+
declare function createSyncStatusController(options: SyncStatusControllerOptions): SyncStatusController;
|
|
1220
|
+
|
|
1221
|
+
/**
|
|
1222
|
+
* Returns remote collaborators' awareness states (excludes the local client).
|
|
1223
|
+
*/
|
|
1224
|
+
declare function getRemoteAwarenessStates(awareness: AwarenessManager): AwarenessState[];
|
|
1225
|
+
/**
|
|
1226
|
+
* Subscribes to awareness changes and invokes `listener` only when the remote
|
|
1227
|
+
* collaborator set changes.
|
|
1228
|
+
*/
|
|
1229
|
+
declare function subscribeRemoteAwarenessStates(awareness: AwarenessManager, listener: (states: AwarenessState[]) => void): () => void;
|
|
1230
|
+
|
|
1231
|
+
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 };
|
package/dist/index.js
CHANGED
|
@@ -263,7 +263,7 @@ function isYjsDocUpdateMessage(value) {
|
|
|
263
263
|
|
|
264
264
|
// src/protocol/serializer.ts
|
|
265
265
|
import { SyncError } from "@korajs/core";
|
|
266
|
-
import protobuf from "protobufjs/minimal";
|
|
266
|
+
import protobuf from "protobufjs/minimal.js";
|
|
267
267
|
var { Reader, Writer } = protobuf;
|
|
268
268
|
function versionVectorToWire(vector) {
|
|
269
269
|
const wire = {};
|
|
@@ -3793,6 +3793,158 @@ function fromBase642(str) {
|
|
|
3793
3793
|
}
|
|
3794
3794
|
return bytes;
|
|
3795
3795
|
}
|
|
3796
|
+
|
|
3797
|
+
// src/reactivity/sync-status-controller.ts
|
|
3798
|
+
var OFFLINE_SYNC_STATUS = Object.freeze({
|
|
3799
|
+
status: "offline",
|
|
3800
|
+
pendingOperations: 0,
|
|
3801
|
+
lastSyncedAt: null,
|
|
3802
|
+
lastSuccessfulPush: null,
|
|
3803
|
+
lastSuccessfulPull: null,
|
|
3804
|
+
conflicts: 0
|
|
3805
|
+
});
|
|
3806
|
+
var SYNC_STATUS_EVENT_TYPES = [
|
|
3807
|
+
"sync:connected",
|
|
3808
|
+
"sync:disconnected",
|
|
3809
|
+
"sync:schema-mismatch",
|
|
3810
|
+
"sync:auth-failed",
|
|
3811
|
+
"sync:sent",
|
|
3812
|
+
"sync:received",
|
|
3813
|
+
"sync:acknowledged",
|
|
3814
|
+
"sync:apply-failed",
|
|
3815
|
+
"sync:diagnostics",
|
|
3816
|
+
"sync:initial-sync-progress"
|
|
3817
|
+
];
|
|
3818
|
+
function createSyncStatusController(options) {
|
|
3819
|
+
const useLiveSnapshot = options.subscribeSyncStatus === null && options.events === null;
|
|
3820
|
+
let snapshot = OFFLINE_SYNC_STATUS;
|
|
3821
|
+
let serialized = JSON.stringify(OFFLINE_SYNC_STATUS);
|
|
3822
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
3823
|
+
let cleanup = null;
|
|
3824
|
+
const resolveEngine = () => {
|
|
3825
|
+
return options.getSyncEngine?.() ?? options.syncEngine ?? null;
|
|
3826
|
+
};
|
|
3827
|
+
const notify = () => {
|
|
3828
|
+
for (const listener of listeners) {
|
|
3829
|
+
listener();
|
|
3830
|
+
}
|
|
3831
|
+
};
|
|
3832
|
+
const setSnapshot = (next) => {
|
|
3833
|
+
const nextSerialized = JSON.stringify(next);
|
|
3834
|
+
if (nextSerialized === serialized) {
|
|
3835
|
+
return;
|
|
3836
|
+
}
|
|
3837
|
+
serialized = nextSerialized;
|
|
3838
|
+
snapshot = next;
|
|
3839
|
+
notify();
|
|
3840
|
+
};
|
|
3841
|
+
const refresh = () => {
|
|
3842
|
+
const engine = resolveEngine();
|
|
3843
|
+
const next = engine ? engine.getStatus() : OFFLINE_SYNC_STATUS;
|
|
3844
|
+
setSnapshot(next);
|
|
3845
|
+
};
|
|
3846
|
+
const attach = () => {
|
|
3847
|
+
cleanup?.();
|
|
3848
|
+
if (options.subscribeSyncStatus) {
|
|
3849
|
+
cleanup = options.subscribeSyncStatus(setSnapshot);
|
|
3850
|
+
return;
|
|
3851
|
+
}
|
|
3852
|
+
if (!resolveEngine()) {
|
|
3853
|
+
setSnapshot(OFFLINE_SYNC_STATUS);
|
|
3854
|
+
cleanup = () => {
|
|
3855
|
+
};
|
|
3856
|
+
return;
|
|
3857
|
+
}
|
|
3858
|
+
if (options.events) {
|
|
3859
|
+
const unsubs = SYNC_STATUS_EVENT_TYPES.map((type) => options.events?.on(type, refresh));
|
|
3860
|
+
refresh();
|
|
3861
|
+
cleanup = () => {
|
|
3862
|
+
for (const unsub of unsubs) {
|
|
3863
|
+
unsub?.();
|
|
3864
|
+
}
|
|
3865
|
+
};
|
|
3866
|
+
return;
|
|
3867
|
+
}
|
|
3868
|
+
refresh();
|
|
3869
|
+
cleanup = () => {
|
|
3870
|
+
};
|
|
3871
|
+
};
|
|
3872
|
+
attach();
|
|
3873
|
+
return {
|
|
3874
|
+
getSnapshot() {
|
|
3875
|
+
if (useLiveSnapshot) {
|
|
3876
|
+
const engine = resolveEngine();
|
|
3877
|
+
return engine ? engine.getStatus() : OFFLINE_SYNC_STATUS;
|
|
3878
|
+
}
|
|
3879
|
+
return snapshot;
|
|
3880
|
+
},
|
|
3881
|
+
subscribe(listener) {
|
|
3882
|
+
listeners.add(listener);
|
|
3883
|
+
listener();
|
|
3884
|
+
return () => {
|
|
3885
|
+
listeners.delete(listener);
|
|
3886
|
+
};
|
|
3887
|
+
},
|
|
3888
|
+
refresh,
|
|
3889
|
+
destroy() {
|
|
3890
|
+
cleanup?.();
|
|
3891
|
+
cleanup = null;
|
|
3892
|
+
listeners.clear();
|
|
3893
|
+
}
|
|
3894
|
+
};
|
|
3895
|
+
}
|
|
3896
|
+
|
|
3897
|
+
// src/reactivity/collaborators-snapshot.ts
|
|
3898
|
+
var EMPTY_COLLABORATORS = [];
|
|
3899
|
+
function awarenessStatesEqual(left, right) {
|
|
3900
|
+
if (left.length !== right.length) {
|
|
3901
|
+
return false;
|
|
3902
|
+
}
|
|
3903
|
+
for (let index = 0; index < left.length; index++) {
|
|
3904
|
+
const a = left[index];
|
|
3905
|
+
const b = right[index];
|
|
3906
|
+
if (!a || !b) {
|
|
3907
|
+
return false;
|
|
3908
|
+
}
|
|
3909
|
+
if (a.user.name !== b.user.name || a.user.color !== b.user.color) {
|
|
3910
|
+
return false;
|
|
3911
|
+
}
|
|
3912
|
+
const aCursor = a.cursor;
|
|
3913
|
+
const bCursor = b.cursor;
|
|
3914
|
+
if (aCursor === void 0 && bCursor === void 0) {
|
|
3915
|
+
continue;
|
|
3916
|
+
}
|
|
3917
|
+
if (!aCursor || !bCursor) {
|
|
3918
|
+
return false;
|
|
3919
|
+
}
|
|
3920
|
+
if (aCursor.collection !== bCursor.collection || aCursor.recordId !== bCursor.recordId || aCursor.field !== bCursor.field || aCursor.anchor !== bCursor.anchor || aCursor.head !== bCursor.head) {
|
|
3921
|
+
return false;
|
|
3922
|
+
}
|
|
3923
|
+
}
|
|
3924
|
+
return true;
|
|
3925
|
+
}
|
|
3926
|
+
function getRemoteAwarenessStates(awareness) {
|
|
3927
|
+
const localClientId = awareness.clientId;
|
|
3928
|
+
const remoteStates = [];
|
|
3929
|
+
for (const [clientId, state] of awareness.getStates()) {
|
|
3930
|
+
if (clientId === localClientId) continue;
|
|
3931
|
+
remoteStates.push(state);
|
|
3932
|
+
}
|
|
3933
|
+
return remoteStates;
|
|
3934
|
+
}
|
|
3935
|
+
function subscribeRemoteAwarenessStates(awareness, listener) {
|
|
3936
|
+
let snapshot = EMPTY_COLLABORATORS;
|
|
3937
|
+
const emitIfChanged = () => {
|
|
3938
|
+
const next = getRemoteAwarenessStates(awareness);
|
|
3939
|
+
if (awarenessStatesEqual(snapshot, next)) {
|
|
3940
|
+
return;
|
|
3941
|
+
}
|
|
3942
|
+
snapshot = next;
|
|
3943
|
+
listener(snapshot);
|
|
3944
|
+
};
|
|
3945
|
+
emitIfChanged();
|
|
3946
|
+
return awareness.on("change", emitIfChanged);
|
|
3947
|
+
}
|
|
3796
3948
|
export {
|
|
3797
3949
|
AwarenessManager,
|
|
3798
3950
|
ChaosTransport,
|
|
@@ -3805,6 +3957,7 @@ export {
|
|
|
3805
3957
|
JsonMessageSerializer,
|
|
3806
3958
|
KeyDerivationError,
|
|
3807
3959
|
NegotiatedMessageSerializer,
|
|
3960
|
+
OFFLINE_SYNC_STATUS,
|
|
3808
3961
|
OutboundQueue,
|
|
3809
3962
|
ProtobufMessageSerializer,
|
|
3810
3963
|
ReconnectionManager,
|
|
@@ -3817,6 +3970,7 @@ export {
|
|
|
3817
3970
|
SyncEngine,
|
|
3818
3971
|
WebSocketTransport,
|
|
3819
3972
|
createDeltaCursorFromBatch,
|
|
3973
|
+
createSyncStatusController,
|
|
3820
3974
|
decodeDeltaCursor,
|
|
3821
3975
|
decodeYjsUpdate,
|
|
3822
3976
|
dedupeQuerySubsets,
|
|
@@ -3826,6 +3980,7 @@ export {
|
|
|
3826
3980
|
encodeYjsUpdate,
|
|
3827
3981
|
filterOperationsByScope,
|
|
3828
3982
|
generateSalt,
|
|
3983
|
+
getRemoteAwarenessStates,
|
|
3829
3984
|
isAcknowledgmentMessage,
|
|
3830
3985
|
isAwarenessUpdateMessage,
|
|
3831
3986
|
isClientSchemaVersionSupported,
|
|
@@ -3841,6 +3996,7 @@ export {
|
|
|
3841
3996
|
operationMatchesScope,
|
|
3842
3997
|
richtextDocKey,
|
|
3843
3998
|
sliceOperationsAfterCursor,
|
|
3999
|
+
subscribeRemoteAwarenessStates,
|
|
3844
4000
|
versionVectorToWire,
|
|
3845
4001
|
wireToVersionVector
|
|
3846
4002
|
};
|