@dabble/patches 0.4.4 → 0.4.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.
Files changed (181) hide show
  1. package/dist/algorithms/client/applyCommittedChanges.d.ts +8 -2
  2. package/dist/algorithms/client/applyCommittedChanges.js +30 -38
  3. package/dist/algorithms/client/batching.d.ts +8 -2
  4. package/dist/algorithms/client/batching.js +38 -37
  5. package/dist/algorithms/client/breakChange.d.ts +8 -2
  6. package/dist/algorithms/client/breakChange.js +191 -240
  7. package/dist/algorithms/client/createStateFromSnapshot.d.ts +8 -2
  8. package/dist/algorithms/client/createStateFromSnapshot.js +7 -8
  9. package/dist/algorithms/client/getJSONByteSize.d.ts +3 -1
  10. package/dist/algorithms/client/getJSONByteSize.js +12 -11
  11. package/dist/algorithms/client/makeChange.d.ts +8 -2
  12. package/dist/algorithms/client/makeChange.js +28 -36
  13. package/dist/algorithms/server/commitChanges.d.ts +9 -3
  14. package/dist/algorithms/server/commitChanges.js +69 -78
  15. package/dist/algorithms/server/createVersion.d.ts +9 -3
  16. package/dist/algorithms/server/createVersion.js +21 -27
  17. package/dist/algorithms/server/getSnapshotAtRevision.d.ts +9 -3
  18. package/dist/algorithms/server/getSnapshotAtRevision.js +27 -28
  19. package/dist/algorithms/server/getStateAtRevision.d.ts +9 -3
  20. package/dist/algorithms/server/getStateAtRevision.js +13 -17
  21. package/dist/algorithms/server/handleOfflineSessionsAndBatches.d.ts +9 -3
  22. package/dist/algorithms/server/handleOfflineSessionsAndBatches.js +60 -77
  23. package/dist/algorithms/server/transformIncomingChanges.d.ts +8 -2
  24. package/dist/algorithms/server/transformIncomingChanges.js +27 -39
  25. package/dist/algorithms/shared/applyChanges.d.ts +8 -2
  26. package/dist/algorithms/shared/applyChanges.js +11 -16
  27. package/dist/algorithms/shared/rebaseChanges.d.ts +8 -2
  28. package/dist/algorithms/shared/rebaseChanges.js +30 -49
  29. package/dist/chunk-IZ2YBCUP.js +56 -0
  30. package/dist/client/InMemoryStore.d.ts +9 -3
  31. package/dist/client/InMemoryStore.js +92 -101
  32. package/dist/client/IndexedDBStore.d.ts +9 -3
  33. package/dist/client/IndexedDBStore.js +378 -491
  34. package/dist/client/Patches.d.ts +18 -13
  35. package/dist/client/Patches.js +152 -207
  36. package/dist/client/PatchesDoc.d.ts +14 -8
  37. package/dist/client/PatchesDoc.js +147 -154
  38. package/dist/client/PatchesHistoryClient.d.ts +12 -5
  39. package/dist/client/PatchesHistoryClient.js +110 -117
  40. package/dist/client/PatchesStore.d.ts +9 -3
  41. package/dist/client/PatchesStore.js +0 -1
  42. package/dist/client/index.d.ts +12 -6
  43. package/dist/client/index.js +5 -5
  44. package/dist/data/change.d.ts +9 -3
  45. package/dist/data/change.js +23 -15
  46. package/dist/data/version.d.ts +9 -3
  47. package/dist/data/version.js +11 -15
  48. package/dist/event-signal.d.ts +7 -6
  49. package/dist/event-signal.js +24 -39
  50. package/dist/index-CvQws3AB.d.ts +36 -0
  51. package/dist/index.d.ts +27 -5
  52. package/dist/index.js +10 -4
  53. package/dist/json-patch/JSONPatch.d.ts +9 -5
  54. package/dist/json-patch/JSONPatch.js +175 -183
  55. package/dist/json-patch/applyPatch.d.ts +5 -2
  56. package/dist/json-patch/applyPatch.js +27 -35
  57. package/dist/json-patch/composePatch.d.ts +5 -2
  58. package/dist/json-patch/composePatch.js +34 -34
  59. package/dist/json-patch/createJSONPatch.d.ts +7 -2
  60. package/dist/json-patch/createJSONPatch.js +11 -38
  61. package/dist/json-patch/index.d.ts +14 -6
  62. package/dist/json-patch/index.js +20 -9
  63. package/dist/json-patch/invertPatch.d.ts +5 -2
  64. package/dist/json-patch/invertPatch.js +31 -30
  65. package/dist/json-patch/ops/add.d.ts +5 -2
  66. package/dist/json-patch/ops/add.js +53 -51
  67. package/dist/json-patch/ops/bitmask.d.ts +8 -5
  68. package/dist/json-patch/ops/bitmask.js +41 -44
  69. package/dist/json-patch/ops/copy.d.ts +5 -2
  70. package/dist/json-patch/ops/copy.js +32 -33
  71. package/dist/json-patch/ops/increment.d.ts +5 -2
  72. package/dist/json-patch/ops/increment.js +21 -20
  73. package/dist/json-patch/ops/index.d.ts +10 -21
  74. package/dist/json-patch/ops/index.js +34 -24
  75. package/dist/json-patch/ops/move.d.ts +5 -2
  76. package/dist/json-patch/ops/move.js +132 -198
  77. package/dist/json-patch/ops/remove.d.ts +5 -2
  78. package/dist/json-patch/ops/remove.js +33 -30
  79. package/dist/json-patch/ops/replace.d.ts +5 -2
  80. package/dist/json-patch/ops/replace.js +45 -43
  81. package/dist/json-patch/ops/test.d.ts +5 -2
  82. package/dist/json-patch/ops/test.js +25 -21
  83. package/dist/json-patch/ops/text.d.ts +5 -2
  84. package/dist/json-patch/ops/text.js +54 -54
  85. package/dist/json-patch/pathProxy.d.ts +9 -3
  86. package/dist/json-patch/pathProxy.js +27 -48
  87. package/dist/json-patch/state.d.ts +5 -2
  88. package/dist/json-patch/state.js +11 -7
  89. package/dist/json-patch/transformPatch.d.ts +6 -2
  90. package/dist/json-patch/transformPatch.js +21 -24
  91. package/dist/json-patch/types.d.ts +9 -7
  92. package/dist/json-patch/types.js +0 -1
  93. package/dist/json-patch/utils/deepEqual.d.ts +3 -1
  94. package/dist/json-patch/utils/deepEqual.js +32 -28
  95. package/dist/json-patch/utils/exit.d.ts +5 -2
  96. package/dist/json-patch/utils/exit.js +7 -3
  97. package/dist/json-patch/utils/get.d.ts +5 -2
  98. package/dist/json-patch/utils/get.js +8 -4
  99. package/dist/json-patch/utils/getOpData.d.ts +5 -2
  100. package/dist/json-patch/utils/getOpData.js +12 -9
  101. package/dist/json-patch/utils/getType.d.ts +6 -3
  102. package/dist/json-patch/utils/getType.js +9 -4
  103. package/dist/json-patch/utils/index.d.ts +15 -14
  104. package/dist/json-patch/utils/index.js +14 -14
  105. package/dist/json-patch/utils/log.d.ts +4 -2
  106. package/dist/json-patch/utils/log.js +8 -3
  107. package/dist/json-patch/utils/ops.d.ts +8 -5
  108. package/dist/json-patch/utils/ops.js +83 -100
  109. package/dist/json-patch/utils/paths.d.ts +12 -9
  110. package/dist/json-patch/utils/paths.js +54 -51
  111. package/dist/json-patch/utils/pluck.d.ts +8 -5
  112. package/dist/json-patch/utils/pluck.js +32 -26
  113. package/dist/json-patch/utils/shallowCopy.d.ts +3 -1
  114. package/dist/json-patch/utils/shallowCopy.js +22 -18
  115. package/dist/json-patch/utils/softWrites.d.ts +6 -3
  116. package/dist/json-patch/utils/softWrites.js +17 -16
  117. package/dist/json-patch/utils/toArrayIndex.d.ts +3 -1
  118. package/dist/json-patch/utils/toArrayIndex.js +14 -10
  119. package/dist/json-patch/utils/toKeys.d.ts +3 -1
  120. package/dist/json-patch/utils/toKeys.js +15 -11
  121. package/dist/json-patch/utils/updateArrayIndexes.d.ts +5 -2
  122. package/dist/json-patch/utils/updateArrayIndexes.js +33 -37
  123. package/dist/json-patch/utils/updateArrayPath.d.ts +5 -2
  124. package/dist/json-patch/utils/updateArrayPath.js +29 -42
  125. package/dist/net/PatchesClient.d.ts +128 -0
  126. package/dist/net/PatchesClient.js +161 -0
  127. package/dist/net/PatchesSync.d.ts +19 -9
  128. package/dist/net/PatchesSync.js +291 -386
  129. package/dist/net/error.d.ts +3 -1
  130. package/dist/net/error.js +9 -6
  131. package/dist/net/http/FetchTransport.d.ts +21 -0
  132. package/dist/net/http/FetchTransport.js +34 -0
  133. package/dist/net/index.d.ts +26 -12
  134. package/dist/net/index.js +12 -10
  135. package/dist/net/protocol/JSONRPCClient.d.ts +11 -4
  136. package/dist/net/protocol/JSONRPCClient.js +95 -103
  137. package/dist/net/protocol/JSONRPCServer.d.ts +15 -8
  138. package/dist/net/protocol/JSONRPCServer.js +101 -123
  139. package/dist/net/protocol/types.d.ts +21 -15
  140. package/dist/net/protocol/types.js +0 -1
  141. package/dist/net/protocol/utils.d.ts +12 -0
  142. package/dist/net/protocol/utils.js +15 -0
  143. package/dist/net/types.d.ts +4 -2
  144. package/dist/net/types.js +0 -1
  145. package/dist/net/webrtc/WebRTCAwareness.d.ts +14 -4
  146. package/dist/net/webrtc/WebRTCAwareness.js +111 -120
  147. package/dist/net/webrtc/WebRTCTransport.d.ts +16 -8
  148. package/dist/net/webrtc/WebRTCTransport.js +149 -157
  149. package/dist/net/webrtc/index.d.ts +10 -2
  150. package/dist/net/webrtc/index.js +2 -2
  151. package/dist/net/websocket/AuthorizationProvider.d.ts +7 -5
  152. package/dist/net/websocket/AuthorizationProvider.js +12 -17
  153. package/dist/net/websocket/PatchesWebSocket.d.ts +14 -109
  154. package/dist/net/websocket/PatchesWebSocket.js +37 -184
  155. package/dist/net/websocket/RPCServer.d.ts +19 -10
  156. package/dist/net/websocket/RPCServer.js +190 -192
  157. package/dist/net/websocket/SignalingService.d.ts +12 -32
  158. package/dist/net/websocket/SignalingService.js +126 -133
  159. package/dist/net/websocket/WebSocketServer.d.ts +17 -4
  160. package/dist/net/websocket/WebSocketServer.js +64 -72
  161. package/dist/net/websocket/WebSocketTransport.d.ts +13 -5
  162. package/dist/net/websocket/WebSocketTransport.js +178 -207
  163. package/dist/net/websocket/onlineState.d.ts +6 -3
  164. package/dist/net/websocket/onlineState.js +25 -21
  165. package/dist/server/PatchesBranchManager.d.ts +12 -5
  166. package/dist/server/PatchesBranchManager.js +132 -142
  167. package/dist/server/PatchesHistoryManager.d.ts +11 -3
  168. package/dist/server/PatchesHistoryManager.js +81 -84
  169. package/dist/server/PatchesServer.d.ts +16 -10
  170. package/dist/server/PatchesServer.js +131 -137
  171. package/dist/server/index.d.ts +7 -2
  172. package/dist/server/index.js +9 -3
  173. package/dist/server/types.d.ts +9 -3
  174. package/dist/server/types.js +0 -1
  175. package/dist/types.d.ts +49 -19
  176. package/dist/types.js +1 -1
  177. package/dist/utils/concurrency.d.ts +7 -5
  178. package/dist/utils/concurrency.js +43 -53
  179. package/dist/utils/deferred.d.ts +4 -2
  180. package/dist/utils/deferred.js +25 -21
  181. package/package.json +5 -7
@@ -1,220 +1,191 @@
1
- import { signal } from '../../event-signal.js';
2
- import { deferred } from '../../utils/deferred.js';
3
- import { onlineState } from './onlineState.js';
4
- /**
5
- * WebSocket-based transport implementation that provides communication over the WebSocket protocol.
6
- * Includes automatic reconnection with exponential backoff.
7
- */
8
- export class WebSocketTransport {
9
- url;
10
- wsOptions;
11
- _state = 'disconnected';
12
- ws = null;
13
- reconnectTimer = null;
14
- backoff = 1000;
15
- connecting = false;
16
- connectionDeferred = null;
17
- onlineUnsubscriber = null;
18
- /** Flag representing the *intent* to be connected. It is set by `connect()` and cleared by `disconnect()`. */
19
- shouldBeConnected = false;
20
- /**
21
- * Signal that emits when the connection state changes.
22
- * Subscribers will receive the new connection state as an argument.
23
- */
24
- onStateChange = signal();
25
- /**
26
- * Signal that emits when a message is received from the transport.
27
- * Subscribers will receive the message data as a string.
28
- */
29
- onMessage = signal();
30
- /**
31
- * Creates a new WebSocket transport instance.
32
- * @param url - The WebSocket server URL to connect to
33
- * @param wsOptions - Optional configuration for the WebSocket connection
34
- */
35
- constructor(url, wsOptions) {
36
- this.url = url;
37
- this.wsOptions = wsOptions;
1
+ import "../../chunk-IZ2YBCUP.js";
2
+ import { signal } from "../../event-signal.js";
3
+ import { deferred } from "../../utils/deferred.js";
4
+ import { onlineState } from "./onlineState.js";
5
+ class WebSocketTransport {
6
+ /**
7
+ * Creates a new WebSocket transport instance.
8
+ * @param url - The WebSocket server URL to connect to
9
+ * @param wsOptions - Optional configuration for the WebSocket connection
10
+ */
11
+ constructor(url, wsOptions) {
12
+ this.url = url;
13
+ this.wsOptions = wsOptions;
14
+ }
15
+ _state = "disconnected";
16
+ ws = null;
17
+ reconnectTimer = null;
18
+ backoff = 1e3;
19
+ connecting = false;
20
+ connectionDeferred = null;
21
+ onlineUnsubscriber = null;
22
+ /** Flag representing the *intent* to be connected. It is set by `connect()` and cleared by `disconnect()`. */
23
+ shouldBeConnected = false;
24
+ /**
25
+ * Signal that emits when the connection state changes.
26
+ * Subscribers will receive the new connection state as an argument.
27
+ */
28
+ onStateChange = signal();
29
+ /**
30
+ * Signal that emits when a message is received from the transport.
31
+ * Subscribers will receive the message data as a string.
32
+ */
33
+ onMessage = signal();
34
+ /**
35
+ * Gets the current connection state of the transport.
36
+ * @returns The current connection state ('connecting', 'connected', 'disconnected', or 'error')
37
+ */
38
+ get state() {
39
+ return this._state;
40
+ }
41
+ /**
42
+ * Sets the connection state and emits a state change event.
43
+ * This method is protected and should only be called by subclasses.
44
+ * @param state - The new connection state
45
+ */
46
+ set state(state) {
47
+ if (state === this._state) return;
48
+ this._state = state;
49
+ this.onStateChange.emit(state);
50
+ }
51
+ /**
52
+ * Establishes a connection to the WebSocket server.
53
+ * If a connection is already open or in progress, this method returns immediately.
54
+ * On connection failure, an automatic reconnection attempt will be scheduled.
55
+ * @returns A promise that resolves when the connection is established or rejects on error
56
+ */
57
+ async connect() {
58
+ this.shouldBeConnected = true;
59
+ this._ensureOnlineOfflineListeners();
60
+ if (onlineState.isOffline) {
61
+ if (!this.connectionDeferred) {
62
+ this.connectionDeferred = deferred();
63
+ }
64
+ return this.connectionDeferred.promise;
38
65
  }
39
- /**
40
- * Gets the current connection state of the transport.
41
- * @returns The current connection state ('connecting', 'connected', 'disconnected', or 'error')
42
- */
43
- get state() {
44
- return this._state;
66
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
67
+ return Promise.resolve();
45
68
  }
46
- /**
47
- * Sets the connection state and emits a state change event.
48
- * This method is protected and should only be called by subclasses.
49
- * @param state - The new connection state
50
- */
51
- set state(state) {
52
- if (state === this._state)
53
- return;
54
- this._state = state;
55
- this.onStateChange.emit(state);
69
+ if (this.connecting && this.connectionDeferred) {
70
+ return this.connectionDeferred.promise;
56
71
  }
57
- /**
58
- * Establishes a connection to the WebSocket server.
59
- * If a connection is already open or in progress, this method returns immediately.
60
- * On connection failure, an automatic reconnection attempt will be scheduled.
61
- * @returns A promise that resolves when the connection is established or rejects on error
62
- */
63
- async connect() {
64
- // Record the caller's intent.
65
- this.shouldBeConnected = true;
66
- // Make sure we react to browser connectivity changes
67
- this._ensureOnlineOfflineListeners();
68
- // If the browser is known to be offline, defer the actual connection until
69
- // it comes back online. We still return a promise that resolves once the
70
- // connection is eventually established, so callers can `await` safely.
71
- if (onlineState.isOffline) {
72
- if (!this.connectionDeferred) {
73
- this.connectionDeferred = deferred();
74
- }
75
- return this.connectionDeferred.promise;
76
- }
77
- // Return existing connection if already connected
78
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
79
- return Promise.resolve();
80
- }
81
- // Return pending connection promise if already connecting
82
- if (this.connecting && this.connectionDeferred) {
83
- return this.connectionDeferred.promise;
84
- }
85
- this.connecting = true;
86
- this.state = 'connecting';
87
- // Create a new connection promise
88
- this.connectionDeferred = deferred();
89
- const { resolve, reject } = this.connectionDeferred;
90
- try {
91
- // Pass protocol option if available (standard 2nd arg)
92
- // Other options like headers are not standard and require specific server/client handling
93
- // or a different WebSocket client library.
94
- this.ws = new WebSocket(this.url, this.wsOptions?.protocol);
95
- this.ws.onopen = () => {
96
- this.backoff = 1000; // Reset backoff on successful connection
97
- this.state = 'connected';
98
- this.connecting = false;
99
- resolve();
100
- };
101
- this.ws.onclose = () => {
102
- this.state = 'disconnected';
103
- // If we were in the process of connecting, reject the promise
104
- if (this.connecting) {
105
- reject(new Error('Connection closed'));
106
- this.connecting = false;
107
- }
108
- // Schedule reconnect regardless of whether it was a clean close
109
- // as WebSockets don't always emit error events before closing
110
- this._scheduleReconnect();
111
- };
112
- this.ws.onerror = error => {
113
- this.state = 'error';
114
- // If we're in the connection phase, reject the promise
115
- if (this.connecting) {
116
- this.connecting = false;
117
- reject(error);
118
- }
119
- else {
120
- // If error happens after established connection,
121
- // schedule a reconnect. The socket will likely close
122
- // right after this, but we schedule it anyway to be sure.
123
- this._scheduleReconnect();
124
- }
125
- // Log the error for debugging
126
- console.error('WebSocket error:', error);
127
- };
128
- this.ws.onmessage = event => {
129
- this.onMessage.emit(event.data);
130
- };
72
+ this.connecting = true;
73
+ this.state = "connecting";
74
+ this.connectionDeferred = deferred();
75
+ const { resolve, reject } = this.connectionDeferred;
76
+ try {
77
+ this.ws = new WebSocket(this.url, this.wsOptions?.protocol);
78
+ this.ws.onopen = () => {
79
+ this.backoff = 1e3;
80
+ this.state = "connected";
81
+ this.connecting = false;
82
+ resolve();
83
+ };
84
+ this.ws.onclose = () => {
85
+ this.state = "disconnected";
86
+ if (this.connecting) {
87
+ reject(new Error("Connection closed"));
88
+ this.connecting = false;
131
89
  }
132
- catch (error) {
133
- this.state = 'error';
134
- this.connecting = false;
135
- reject(error);
136
- this._scheduleReconnect();
90
+ this._scheduleReconnect();
91
+ };
92
+ this.ws.onerror = (error) => {
93
+ this.state = "error";
94
+ if (this.connecting) {
95
+ this.connecting = false;
96
+ reject(error);
97
+ } else {
98
+ this._scheduleReconnect();
137
99
  }
138
- return this.connectionDeferred.promise;
100
+ console.error("WebSocket error:", error);
101
+ };
102
+ this.ws.onmessage = (event) => {
103
+ this.onMessage.emit(event.data);
104
+ };
105
+ } catch (error) {
106
+ this.state = "error";
107
+ this.connecting = false;
108
+ reject(error);
109
+ this._scheduleReconnect();
139
110
  }
140
- /**
141
- * Terminates the WebSocket connection and cancels any pending reconnection attempts.
142
- */
143
- disconnect() {
144
- // Clearing the intent stops automatic reconnection attempts.
145
- this.shouldBeConnected = false;
146
- // Remove listener now that we no longer intend to stay connected.
147
- this._removeOnlineOfflineListeners();
148
- if (this.reconnectTimer) {
149
- clearTimeout(this.reconnectTimer);
150
- this.reconnectTimer = null;
151
- }
152
- this.connecting = false;
153
- if (this.ws) {
154
- // Only attempt to close if not already closed
155
- if (this.ws.readyState !== WebSocket.CLOSED && this.ws.readyState !== WebSocket.CLOSING) {
156
- this.ws.close();
157
- }
158
- this.ws = null;
159
- }
160
- this.state = 'disconnected';
111
+ return this.connectionDeferred.promise;
112
+ }
113
+ /**
114
+ * Terminates the WebSocket connection and cancels any pending reconnection attempts.
115
+ */
116
+ disconnect() {
117
+ this.shouldBeConnected = false;
118
+ this._removeOnlineOfflineListeners();
119
+ if (this.reconnectTimer) {
120
+ clearTimeout(this.reconnectTimer);
121
+ this.reconnectTimer = null;
161
122
  }
162
- /**
163
- * Sends data through the WebSocket connection.
164
- * @param data - The string data to send
165
- * @throws {Error} If the WebSocket is not connected
166
- */
167
- send(data) {
168
- if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
169
- throw new Error('WebSocket is not connected');
170
- }
171
- this.ws.send(data);
123
+ this.connecting = false;
124
+ if (this.ws) {
125
+ if (this.ws.readyState !== WebSocket.CLOSED && this.ws.readyState !== WebSocket.CLOSING) {
126
+ this.ws.close();
127
+ }
128
+ this.ws = null;
172
129
  }
173
- /**
174
- * Schedules a reconnection attempt using exponential backoff.
175
- * The backoff time increases with each failed attempt, up to a maximum of 30 seconds.
176
- * @private
177
- */
178
- _scheduleReconnect() {
179
- // Only schedule a reconnect if the caller still wants to be connected.
180
- if (!this.shouldBeConnected || onlineState.isOffline) {
181
- return;
182
- }
183
- if (this.reconnectTimer) {
184
- return;
185
- }
186
- this.reconnectTimer = setTimeout(() => {
187
- this.reconnectTimer = null;
188
- this.connect().catch(err => {
189
- console.error('WebSocket reconnect failed:', err);
190
- });
191
- }, this.backoff);
192
- this.backoff = Math.min(this.backoff * 1.5, 30000);
130
+ this.state = "disconnected";
131
+ }
132
+ /**
133
+ * Sends data through the WebSocket connection.
134
+ * @param data - The string data to send
135
+ * @throws {Error} If the WebSocket is not connected
136
+ */
137
+ send(data) {
138
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
139
+ throw new Error("WebSocket is not connected");
193
140
  }
194
- /**
195
- * Internal helper that adds (once) listeners for the browser's online/offline
196
- * events so we can automatically attempt to connect when the network comes
197
- * back and forcibly close when it goes away.
198
- */
199
- _ensureOnlineOfflineListeners() {
200
- if (!this.onlineUnsubscriber) {
201
- this.onlineUnsubscriber = onlineState.onOnlineChange(isOnline => {
202
- if (isOnline && this.shouldBeConnected && !this.connecting && this.state !== 'connected') {
203
- const { resolve, reject } = this.connectionDeferred;
204
- this.connectionDeferred = null;
205
- this.connect().then(resolve, reject);
206
- }
207
- else if (!isOnline && this.ws) {
208
- this.ws.close();
209
- }
210
- });
211
- }
141
+ this.ws.send(data);
142
+ }
143
+ /**
144
+ * Schedules a reconnection attempt using exponential backoff.
145
+ * The backoff time increases with each failed attempt, up to a maximum of 30 seconds.
146
+ * @private
147
+ */
148
+ _scheduleReconnect() {
149
+ if (!this.shouldBeConnected || onlineState.isOffline) {
150
+ return;
151
+ }
152
+ if (this.reconnectTimer) {
153
+ return;
212
154
  }
213
- /** Removes previously registered online/offline listeners (if any) */
214
- _removeOnlineOfflineListeners() {
215
- if (this.onlineUnsubscriber) {
216
- this.onlineUnsubscriber();
217
- this.onlineUnsubscriber = null;
155
+ this.reconnectTimer = setTimeout(() => {
156
+ this.reconnectTimer = null;
157
+ this.connect().catch((err) => {
158
+ console.error("WebSocket reconnect failed:", err);
159
+ });
160
+ }, this.backoff);
161
+ this.backoff = Math.min(this.backoff * 1.5, 3e4);
162
+ }
163
+ /**
164
+ * Internal helper that adds (once) listeners for the browser's online/offline
165
+ * events so we can automatically attempt to connect when the network comes
166
+ * back and forcibly close when it goes away.
167
+ */
168
+ _ensureOnlineOfflineListeners() {
169
+ if (!this.onlineUnsubscriber) {
170
+ this.onlineUnsubscriber = onlineState.onOnlineChange((isOnline) => {
171
+ if (isOnline && this.shouldBeConnected && !this.connecting && this.state !== "connected") {
172
+ const { resolve, reject } = this.connectionDeferred;
173
+ this.connectionDeferred = null;
174
+ this.connect().then(resolve, reject);
175
+ } else if (!isOnline && this.ws) {
176
+ this.ws.close();
218
177
  }
178
+ });
179
+ }
180
+ }
181
+ /** Removes previously registered online/offline listeners (if any) */
182
+ _removeOnlineOfflineListeners() {
183
+ if (this.onlineUnsubscriber) {
184
+ this.onlineUnsubscriber();
185
+ this.onlineUnsubscriber = null;
219
186
  }
187
+ }
220
188
  }
189
+ export {
190
+ WebSocketTransport
191
+ };
@@ -1,9 +1,12 @@
1
+ import { Signal } from '../../event-signal.js';
2
+
1
3
  declare class OnlineState {
2
- onOnlineChange: import("../../event-signal.js").Signal<(isOnline: boolean) => void>;
4
+ onOnlineChange: Signal<(isOnline: boolean) => void>;
3
5
  protected _isOnline: boolean;
4
6
  constructor();
5
7
  get isOnline(): boolean;
6
8
  get isOffline(): boolean;
7
9
  }
8
- export declare const onlineState: OnlineState;
9
- export {};
10
+ declare const onlineState: OnlineState;
11
+
12
+ export { onlineState };
@@ -1,24 +1,28 @@
1
- import { signal } from '../../event-signal.js';
1
+ import "../../chunk-IZ2YBCUP.js";
2
+ import { signal } from "../../event-signal.js";
2
3
  class OnlineState {
3
- onOnlineChange = signal();
4
- _isOnline = typeof navigator !== 'undefined' && navigator.onLine;
5
- constructor() {
6
- if (typeof addEventListener === 'function') {
7
- addEventListener('online', () => {
8
- this._isOnline = true;
9
- this.onOnlineChange.emit(true);
10
- });
11
- addEventListener('offline', () => {
12
- this._isOnline = false;
13
- this.onOnlineChange.emit(false);
14
- });
15
- }
16
- }
17
- get isOnline() {
18
- return this._isOnline;
19
- }
20
- get isOffline() {
21
- return !this._isOnline;
4
+ onOnlineChange = signal();
5
+ _isOnline = typeof navigator !== "undefined" && navigator.onLine;
6
+ constructor() {
7
+ if (typeof addEventListener === "function") {
8
+ addEventListener("online", () => {
9
+ this._isOnline = true;
10
+ this.onOnlineChange.emit(true);
11
+ });
12
+ addEventListener("offline", () => {
13
+ this._isOnline = false;
14
+ this.onOnlineChange.emit(false);
15
+ });
22
16
  }
17
+ }
18
+ get isOnline() {
19
+ return this._isOnline;
20
+ }
21
+ get isOffline() {
22
+ return !this._isOnline;
23
+ }
23
24
  }
24
- export const onlineState = new OnlineState();
25
+ const onlineState = new OnlineState();
26
+ export {
27
+ onlineState
28
+ };
@@ -1,12 +1,17 @@
1
- import type { Branch, BranchStatus, Change, EditableBranchMetadata } from '../types.js';
2
- import type { PatchesServer } from './PatchesServer.js';
3
- import type { BranchingStoreBackend } from './types.js';
1
+ import { Branch, EditableBranchMetadata, BranchStatus, Change } from '../types.js';
2
+ import { PatchesServer } from './PatchesServer.js';
3
+ import { BranchingStoreBackend } from './types.js';
4
+ import '../json-patch/JSONPatch.js';
5
+ import '@dabble/delta';
6
+ import '../json-patch/types.js';
7
+ import '../event-signal.js';
8
+
4
9
  /**
5
10
  * Helps manage branches for a document. A branch is a document that is branched from another document. Its first
6
11
  * version will be the point-in-time of the original document at the time of the branch. Branches allow for parallel
7
12
  * development of a document with the ability to merge changes back into the original document later.
8
13
  */
9
- export declare class PatchesBranchManager {
14
+ declare class PatchesBranchManager {
10
15
  private readonly store;
11
16
  private readonly patchesServer;
12
17
  constructor(store: BranchingStoreBackend, patchesServer: PatchesServer);
@@ -45,4 +50,6 @@ export declare class PatchesBranchManager {
45
50
  */
46
51
  mergeBranch(branchId: string): Promise<Change[]>;
47
52
  }
48
- export declare function assertBranchMetadata(metadata?: EditableBranchMetadata): void;
53
+ declare function assertBranchMetadata(metadata?: EditableBranchMetadata): void;
54
+
55
+ export { PatchesBranchManager, assertBranchMetadata };