@dabble/patches 0.5.7 → 0.5.9

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.
@@ -48,7 +48,7 @@ declare class Patches {
48
48
  trackDocs(docIds: string[]): Promise<void>;
49
49
  /**
50
50
  * Untracks the given document IDs, removing them from the set of tracked documents and notifying listeners.
51
- * Untracked docs will no longer be kept in sync with the server, even if not open locally.
51
+ * Untracked docs will no longer be kept in sync with the server.
52
52
  * Closes any open docs and removes them from the store.
53
53
  * @param docIds - Array of document IDs to untrack.
54
54
  */
@@ -48,7 +48,7 @@ class Patches {
48
48
  }
49
49
  /**
50
50
  * Untracks the given document IDs, removing them from the set of tracked documents and notifying listeners.
51
- * Untracked docs will no longer be kept in sync with the server, even if not open locally.
51
+ * Untracked docs will no longer be kept in sync with the server.
52
52
  * Closes any open docs and removes them from the store.
53
53
  * @param docIds - Array of document IDs to untrack.
54
54
  */
@@ -1,17 +1,18 @@
1
- import { JSONRPCClient } from './protocol/JSONRPCClient.js';
2
1
  import { Signal } from '../event-signal.js';
3
- import { SizeCalculator } from '../algorithms/shared/changeBatching.js';
4
- import { Patches } from '../client/Patches.js';
5
- import { PatchesStore } from '../client/PatchesStore.js';
6
- import { SyncingState, Change } from '../types.js';
7
2
  import { ConnectionState } from './protocol/types.js';
3
+ import { SyncingState, Change } from '../types.js';
4
+ import { JSONRPCClient } from './protocol/JSONRPCClient.js';
8
5
  import { PatchesWebSocket } from './websocket/PatchesWebSocket.js';
9
6
  import { WebSocketOptions } from './websocket/WebSocketTransport.js';
7
+ import { SizeCalculator } from '../algorithms/shared/changeBatching.js';
8
+ import { Patches } from '../client/Patches.js';
9
+ import { PatchesStore } from '../client/PatchesStore.js';
10
10
  import '../json-patch/JSONPatch.js';
11
11
  import '@dabble/delta';
12
12
  import '../json-patch/types.js';
13
- import '../client/PatchesDoc.js';
14
13
  import './PatchesClient.js';
14
+ import '../utils/deferred.js';
15
+ import '../client/PatchesDoc.js';
15
16
 
16
17
  interface PatchesSyncState {
17
18
  online: boolean;
@@ -53,6 +54,14 @@ declare class PatchesSync {
53
54
  docId?: string;
54
55
  }) => void>;
55
56
  constructor(patches: Patches, url: string, options?: PatchesSyncOptions | undefined);
57
+ /**
58
+ * Gets the URL of the WebSocket connection.
59
+ */
60
+ get url(): string;
61
+ /**
62
+ * Sets the URL of the WebSocket connection.
63
+ */
64
+ set url(url: string);
56
65
  /**
57
66
  * Gets the current sync state.
58
67
  */
@@ -109,6 +118,7 @@ declare class PatchesSync {
109
118
  protected _handleConnectionChange(connectionState: ConnectionState): void;
110
119
  protected _handleDocsTracked(docIds: string[]): Promise<void>;
111
120
  protected _handleDocsUntracked(docIds: string[]): Promise<void>;
121
+ protected _handleDocChange(docId: string, _changes: Change[]): Promise<void>;
112
122
  }
113
123
 
114
124
  export { PatchesSync, type PatchesSyncOptions, type PatchesSyncState };
@@ -49,6 +49,23 @@ class PatchesSync {
49
49
  patches.onTrackDocs(this._handleDocsTracked.bind(this));
50
50
  patches.onUntrackDocs(this._handleDocsUntracked.bind(this));
51
51
  patches.onDeleteDoc(this._handleDocDeleted.bind(this));
52
+ patches.onChange(this._handleDocChange.bind(this));
53
+ }
54
+ /**
55
+ * Gets the URL of the WebSocket connection.
56
+ */
57
+ get url() {
58
+ return this.ws.transport.url;
59
+ }
60
+ /**
61
+ * Sets the URL of the WebSocket connection.
62
+ */
63
+ set url(url) {
64
+ this.ws.transport.url = url;
65
+ if (this.state.connected) {
66
+ this.ws.disconnect();
67
+ this.ws.connect();
68
+ }
52
69
  }
53
70
  /**
54
71
  * Gets the current sync state.
@@ -306,6 +323,11 @@ class PatchesSync {
306
323
  }
307
324
  }
308
325
  }
326
+ async _handleDocChange(docId, _changes) {
327
+ if (!this.state.connected) return;
328
+ if (!this.trackedDocs.has(docId)) return;
329
+ await this.flushDoc(docId);
330
+ }
309
331
  }
310
332
  _init = __decoratorStart(null);
311
333
  __decorateElement(_init, 1, "syncDoc", _syncDoc_dec, PatchesSync);
@@ -26,5 +26,6 @@ import '../compression/index.js';
26
26
  import '../algorithms/shared/lz.js';
27
27
  import '../json-patch/types.js';
28
28
  import '../server/PatchesHistoryManager.js';
29
+ import '../utils/deferred.js';
29
30
  import '../json-patch/JSONPatch.js';
30
31
  import '@dabble/delta';
@@ -7,6 +7,7 @@ import '@dabble/delta';
7
7
  import '../../json-patch/types.js';
8
8
  import 'simple-peer';
9
9
  import '../websocket/WebSocketTransport.js';
10
+ import '../../utils/deferred.js';
10
11
 
11
12
  /**
12
13
  * Base type for awareness states, representing arbitrary structured data
@@ -6,6 +6,7 @@ import '../../types.js';
6
6
  import '../../json-patch/JSONPatch.js';
7
7
  import '@dabble/delta';
8
8
  import '../../json-patch/types.js';
9
+ import '../../utils/deferred.js';
9
10
 
10
11
  /**
11
12
  * WebRTC-based transport implementation that enables direct peer-to-peer communication.
@@ -8,3 +8,4 @@ import '@dabble/delta';
8
8
  import '../../json-patch/types.js';
9
9
  import 'simple-peer';
10
10
  import '../websocket/WebSocketTransport.js';
11
+ import '../../utils/deferred.js';
@@ -7,6 +7,7 @@ import '../../json-patch/JSONPatch.js';
7
7
  import '@dabble/delta';
8
8
  import '../../json-patch/types.js';
9
9
  import '../protocol/JSONRPCClient.js';
10
+ import '../../utils/deferred.js';
10
11
 
11
12
  /**
12
13
  * High-level client for the Patches real-time collaboration service.
@@ -1,4 +1,5 @@
1
- import { Signal } from '../../event-signal.js';
1
+ import { Unsubscriber, Signal } from '../../event-signal.js';
2
+ import { Deferred } from '../../utils/deferred.js';
2
3
  import { ClientTransport, ConnectionState } from '../protocol/types.js';
3
4
  import '../../types.js';
4
5
  import '../../json-patch/JSONPatch.js';
@@ -14,17 +15,17 @@ interface WebSocketOptions {
14
15
  * Includes automatic reconnection with exponential backoff.
15
16
  */
16
17
  declare class WebSocketTransport implements ClientTransport {
17
- private url;
18
- private wsOptions?;
19
- private _state;
20
- private ws;
21
- private reconnectTimer;
22
- private backoff;
23
- private connecting;
24
- private connectionDeferred;
25
- private onlineUnsubscriber;
18
+ url: string;
19
+ wsOptions?: WebSocketOptions | undefined;
20
+ protected _state: ConnectionState;
21
+ protected ws: WebSocket | null;
22
+ protected reconnectTimer: any;
23
+ protected backoff: number;
24
+ protected connecting: boolean;
25
+ protected connectionDeferred: Deferred | null;
26
+ protected onlineUnsubscriber: Unsubscriber | null;
26
27
  /** Flag representing the *intent* to be connected. It is set by `connect()` and cleared by `disconnect()`. */
27
- private shouldBeConnected;
28
+ protected shouldBeConnected: boolean;
28
29
  /**
29
30
  * Signal that emits when the connection state changes.
30
31
  * Subscribers will receive the new connection state as an argument.
@@ -72,17 +73,17 @@ declare class WebSocketTransport implements ClientTransport {
72
73
  /**
73
74
  * Schedules a reconnection attempt using exponential backoff.
74
75
  * The backoff time increases with each failed attempt, up to a maximum of 30 seconds.
75
- * @private
76
+ * @protected
76
77
  */
77
- private _scheduleReconnect;
78
+ protected _scheduleReconnect(): void;
78
79
  /**
79
80
  * Internal helper that adds (once) listeners for the browser's online/offline
80
81
  * events so we can automatically attempt to connect when the network comes
81
82
  * back and forcibly close when it goes away.
82
83
  */
83
- private _ensureOnlineOfflineListeners;
84
+ protected _ensureOnlineOfflineListeners(): void;
84
85
  /** Removes previously registered online/offline listeners (if any) */
85
- private _removeOnlineOfflineListeners;
86
+ protected _removeOnlineOfflineListeners(): void;
86
87
  }
87
88
 
88
89
  export { type WebSocketOptions, WebSocketTransport };
@@ -143,7 +143,7 @@ class WebSocketTransport {
143
143
  /**
144
144
  * Schedules a reconnection attempt using exponential backoff.
145
145
  * The backoff time increases with each failed attempt, up to a maximum of 30 seconds.
146
- * @private
146
+ * @protected
147
147
  */
148
148
  _scheduleReconnect() {
149
149
  if (!this.shouldBeConnected || onlineState.isOffline) {
@@ -9,11 +9,12 @@ import '../json-patch/types.js';
9
9
  import '../client/PatchesDoc.js';
10
10
  import '../algorithms/shared/changeBatching.js';
11
11
  import '../client/PatchesStore.js';
12
- import '../net/protocol/JSONRPCClient.js';
13
12
  import '../net/protocol/types.js';
13
+ import '../net/protocol/JSONRPCClient.js';
14
14
  import '../net/websocket/PatchesWebSocket.js';
15
15
  import '../net/PatchesClient.js';
16
16
  import '../net/websocket/WebSocketTransport.js';
17
+ import '../utils/deferred.js';
17
18
 
18
19
  /**
19
20
  * Context value containing Patches and optional PatchesSync instances.
@@ -58,7 +58,7 @@ class DocManager {
58
58
  }
59
59
  if (currentCount === 1) {
60
60
  this.refCounts.delete(docId);
61
- await patches.closeDoc(docId);
61
+ await patches.closeDoc(docId, { untrack: true });
62
62
  } else {
63
63
  this.refCounts.set(docId, currentCount - 1);
64
64
  }
@@ -12,8 +12,9 @@ import '../client/PatchesDoc.js';
12
12
  import '../algorithms/shared/changeBatching.js';
13
13
  import '../client/PatchesStore.js';
14
14
  import '../net/PatchesSync.js';
15
- import '../net/protocol/JSONRPCClient.js';
16
15
  import '../net/protocol/types.js';
16
+ import '../net/protocol/JSONRPCClient.js';
17
17
  import '../net/websocket/PatchesWebSocket.js';
18
18
  import '../net/PatchesClient.js';
19
19
  import '../net/websocket/WebSocketTransport.js';
20
+ import '../utils/deferred.js';
@@ -58,7 +58,7 @@ class DocManager {
58
58
  }
59
59
  if (currentCount === 1) {
60
60
  this.refCounts.delete(docId);
61
- await patches.closeDoc(docId);
61
+ await patches.closeDoc(docId, { untrack: true });
62
62
  } else {
63
63
  this.refCounts.set(docId, currentCount - 1);
64
64
  }
@@ -12,8 +12,9 @@ import '../client/PatchesDoc.js';
12
12
  import '../algorithms/shared/changeBatching.js';
13
13
  import '../client/PatchesStore.js';
14
14
  import '../net/PatchesSync.js';
15
- import '../net/protocol/JSONRPCClient.js';
16
15
  import '../net/protocol/types.js';
16
+ import '../net/protocol/JSONRPCClient.js';
17
17
  import '../net/websocket/PatchesWebSocket.js';
18
18
  import '../net/PatchesClient.js';
19
19
  import '../net/websocket/WebSocketTransport.js';
20
+ import '../utils/deferred.js';
@@ -9,11 +9,12 @@ import '../json-patch/types.js';
9
9
  import '../client/PatchesDoc.js';
10
10
  import '../algorithms/shared/changeBatching.js';
11
11
  import '../client/PatchesStore.js';
12
- import '../net/protocol/JSONRPCClient.js';
13
12
  import '../net/protocol/types.js';
13
+ import '../net/protocol/JSONRPCClient.js';
14
14
  import '../net/websocket/PatchesWebSocket.js';
15
15
  import '../net/PatchesClient.js';
16
16
  import '../net/websocket/WebSocketTransport.js';
17
+ import '../utils/deferred.js';
17
18
 
18
19
  /**
19
20
  * Injection key for Patches instance.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dabble/patches",
3
- "version": "0.5.7",
3
+ "version": "0.5.9",
4
4
  "description": "Immutable JSON Patch implementation based on RFC 6902 supporting operational transformation and last-writer-wins",
5
5
  "author": "Jacob Wright <jacwright@gmail.com>",
6
6
  "bugs": {
@@ -108,4 +108,4 @@
108
108
  "optional": true
109
109
  }
110
110
  }
111
- }
111
+ }