@korajs/sync 0.5.0 → 0.6.0

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.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
- 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, 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, SyncStatusInfo, type SyncStore, SyncTransport, TransportCloseHandler, TransportErrorHandler, TransportMessageHandler, TransportOptions, VersionedKey, type WebSocketConstructor, type WebSocketLike, WebSocketTransport, type WebSocketTransportOptions, WireFormat, YjsDocUpdateMessage, createDeltaCursorFromBatch, decodeDeltaCursor, decodeYjsUpdate, deriveKey, deriveVersionedKey, encodeDeltaCursor, encodeYjsUpdate, filterOperationsByScope, generateSalt, isClientSchemaVersionSupported, isEncryptedPayload, isSchemaMismatchReject, operationMatchesScope, richtextDocKey, sliceOperationsAfterCursor, versionVectorToWire, wireToVersionVector };
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
- 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, 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, SyncStatusInfo, type SyncStore, SyncTransport, TransportCloseHandler, TransportErrorHandler, TransportMessageHandler, TransportOptions, VersionedKey, type WebSocketConstructor, type WebSocketLike, WebSocketTransport, type WebSocketTransportOptions, WireFormat, YjsDocUpdateMessage, createDeltaCursorFromBatch, decodeDeltaCursor, decodeYjsUpdate, deriveKey, deriveVersionedKey, encodeDeltaCursor, encodeYjsUpdate, filterOperationsByScope, generateSalt, isClientSchemaVersionSupported, isEncryptedPayload, isSchemaMismatchReject, operationMatchesScope, richtextDocKey, sliceOperationsAfterCursor, versionVectorToWire, wireToVersionVector };
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
@@ -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
  };