@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.
- package/dist/algorithms/client/applyCommittedChanges.d.ts +8 -2
- package/dist/algorithms/client/applyCommittedChanges.js +30 -38
- package/dist/algorithms/client/batching.d.ts +8 -2
- package/dist/algorithms/client/batching.js +38 -37
- package/dist/algorithms/client/breakChange.d.ts +8 -2
- package/dist/algorithms/client/breakChange.js +191 -240
- package/dist/algorithms/client/createStateFromSnapshot.d.ts +8 -2
- package/dist/algorithms/client/createStateFromSnapshot.js +7 -8
- package/dist/algorithms/client/getJSONByteSize.d.ts +3 -1
- package/dist/algorithms/client/getJSONByteSize.js +12 -11
- package/dist/algorithms/client/makeChange.d.ts +8 -2
- package/dist/algorithms/client/makeChange.js +28 -36
- package/dist/algorithms/server/commitChanges.d.ts +9 -3
- package/dist/algorithms/server/commitChanges.js +69 -78
- package/dist/algorithms/server/createVersion.d.ts +9 -3
- package/dist/algorithms/server/createVersion.js +21 -27
- package/dist/algorithms/server/getSnapshotAtRevision.d.ts +9 -3
- package/dist/algorithms/server/getSnapshotAtRevision.js +27 -28
- package/dist/algorithms/server/getStateAtRevision.d.ts +9 -3
- package/dist/algorithms/server/getStateAtRevision.js +13 -17
- package/dist/algorithms/server/handleOfflineSessionsAndBatches.d.ts +9 -3
- package/dist/algorithms/server/handleOfflineSessionsAndBatches.js +60 -77
- package/dist/algorithms/server/transformIncomingChanges.d.ts +8 -2
- package/dist/algorithms/server/transformIncomingChanges.js +27 -39
- package/dist/algorithms/shared/applyChanges.d.ts +8 -2
- package/dist/algorithms/shared/applyChanges.js +11 -16
- package/dist/algorithms/shared/rebaseChanges.d.ts +8 -2
- package/dist/algorithms/shared/rebaseChanges.js +30 -49
- package/dist/chunk-IZ2YBCUP.js +56 -0
- package/dist/client/InMemoryStore.d.ts +9 -3
- package/dist/client/InMemoryStore.js +92 -101
- package/dist/client/IndexedDBStore.d.ts +9 -3
- package/dist/client/IndexedDBStore.js +378 -491
- package/dist/client/Patches.d.ts +18 -13
- package/dist/client/Patches.js +152 -207
- package/dist/client/PatchesDoc.d.ts +14 -8
- package/dist/client/PatchesDoc.js +147 -154
- package/dist/client/PatchesHistoryClient.d.ts +12 -5
- package/dist/client/PatchesHistoryClient.js +110 -117
- package/dist/client/PatchesStore.d.ts +9 -3
- package/dist/client/PatchesStore.js +0 -1
- package/dist/client/index.d.ts +12 -6
- package/dist/client/index.js +5 -5
- package/dist/data/change.d.ts +9 -3
- package/dist/data/change.js +23 -15
- package/dist/data/version.d.ts +9 -3
- package/dist/data/version.js +11 -15
- package/dist/event-signal.d.ts +7 -6
- package/dist/event-signal.js +24 -39
- package/dist/index-CvQws3AB.d.ts +36 -0
- package/dist/index.d.ts +27 -5
- package/dist/index.js +10 -4
- package/dist/json-patch/JSONPatch.d.ts +9 -5
- package/dist/json-patch/JSONPatch.js +175 -183
- package/dist/json-patch/applyPatch.d.ts +5 -2
- package/dist/json-patch/applyPatch.js +27 -35
- package/dist/json-patch/composePatch.d.ts +5 -2
- package/dist/json-patch/composePatch.js +34 -34
- package/dist/json-patch/createJSONPatch.d.ts +7 -2
- package/dist/json-patch/createJSONPatch.js +11 -38
- package/dist/json-patch/index.d.ts +14 -6
- package/dist/json-patch/index.js +20 -9
- package/dist/json-patch/invertPatch.d.ts +5 -2
- package/dist/json-patch/invertPatch.js +31 -30
- package/dist/json-patch/ops/add.d.ts +5 -2
- package/dist/json-patch/ops/add.js +53 -51
- package/dist/json-patch/ops/bitmask.d.ts +8 -5
- package/dist/json-patch/ops/bitmask.js +41 -44
- package/dist/json-patch/ops/copy.d.ts +5 -2
- package/dist/json-patch/ops/copy.js +32 -33
- package/dist/json-patch/ops/increment.d.ts +5 -2
- package/dist/json-patch/ops/increment.js +21 -20
- package/dist/json-patch/ops/index.d.ts +10 -21
- package/dist/json-patch/ops/index.js +34 -24
- package/dist/json-patch/ops/move.d.ts +5 -2
- package/dist/json-patch/ops/move.js +132 -198
- package/dist/json-patch/ops/remove.d.ts +5 -2
- package/dist/json-patch/ops/remove.js +33 -30
- package/dist/json-patch/ops/replace.d.ts +5 -2
- package/dist/json-patch/ops/replace.js +45 -43
- package/dist/json-patch/ops/test.d.ts +5 -2
- package/dist/json-patch/ops/test.js +25 -21
- package/dist/json-patch/ops/text.d.ts +5 -2
- package/dist/json-patch/ops/text.js +54 -54
- package/dist/json-patch/pathProxy.d.ts +9 -3
- package/dist/json-patch/pathProxy.js +27 -48
- package/dist/json-patch/state.d.ts +5 -2
- package/dist/json-patch/state.js +11 -7
- package/dist/json-patch/transformPatch.d.ts +6 -2
- package/dist/json-patch/transformPatch.js +21 -24
- package/dist/json-patch/types.d.ts +9 -7
- package/dist/json-patch/types.js +0 -1
- package/dist/json-patch/utils/deepEqual.d.ts +3 -1
- package/dist/json-patch/utils/deepEqual.js +32 -28
- package/dist/json-patch/utils/exit.d.ts +5 -2
- package/dist/json-patch/utils/exit.js +7 -3
- package/dist/json-patch/utils/get.d.ts +5 -2
- package/dist/json-patch/utils/get.js +8 -4
- package/dist/json-patch/utils/getOpData.d.ts +5 -2
- package/dist/json-patch/utils/getOpData.js +12 -9
- package/dist/json-patch/utils/getType.d.ts +6 -3
- package/dist/json-patch/utils/getType.js +9 -4
- package/dist/json-patch/utils/index.d.ts +15 -14
- package/dist/json-patch/utils/index.js +14 -14
- package/dist/json-patch/utils/log.d.ts +4 -2
- package/dist/json-patch/utils/log.js +8 -3
- package/dist/json-patch/utils/ops.d.ts +8 -5
- package/dist/json-patch/utils/ops.js +83 -100
- package/dist/json-patch/utils/paths.d.ts +12 -9
- package/dist/json-patch/utils/paths.js +54 -51
- package/dist/json-patch/utils/pluck.d.ts +8 -5
- package/dist/json-patch/utils/pluck.js +32 -26
- package/dist/json-patch/utils/shallowCopy.d.ts +3 -1
- package/dist/json-patch/utils/shallowCopy.js +22 -18
- package/dist/json-patch/utils/softWrites.d.ts +6 -3
- package/dist/json-patch/utils/softWrites.js +17 -16
- package/dist/json-patch/utils/toArrayIndex.d.ts +3 -1
- package/dist/json-patch/utils/toArrayIndex.js +14 -10
- package/dist/json-patch/utils/toKeys.d.ts +3 -1
- package/dist/json-patch/utils/toKeys.js +15 -11
- package/dist/json-patch/utils/updateArrayIndexes.d.ts +5 -2
- package/dist/json-patch/utils/updateArrayIndexes.js +33 -37
- package/dist/json-patch/utils/updateArrayPath.d.ts +5 -2
- package/dist/json-patch/utils/updateArrayPath.js +29 -42
- package/dist/net/PatchesClient.d.ts +128 -0
- package/dist/net/PatchesClient.js +161 -0
- package/dist/net/PatchesSync.d.ts +19 -9
- package/dist/net/PatchesSync.js +291 -386
- package/dist/net/error.d.ts +3 -1
- package/dist/net/error.js +9 -6
- package/dist/net/http/FetchTransport.d.ts +21 -0
- package/dist/net/http/FetchTransport.js +34 -0
- package/dist/net/index.d.ts +26 -12
- package/dist/net/index.js +12 -10
- package/dist/net/protocol/JSONRPCClient.d.ts +11 -4
- package/dist/net/protocol/JSONRPCClient.js +95 -103
- package/dist/net/protocol/JSONRPCServer.d.ts +15 -8
- package/dist/net/protocol/JSONRPCServer.js +101 -123
- package/dist/net/protocol/types.d.ts +21 -15
- package/dist/net/protocol/types.js +0 -1
- package/dist/net/protocol/utils.d.ts +12 -0
- package/dist/net/protocol/utils.js +15 -0
- package/dist/net/types.d.ts +4 -2
- package/dist/net/types.js +0 -1
- package/dist/net/webrtc/WebRTCAwareness.d.ts +14 -4
- package/dist/net/webrtc/WebRTCAwareness.js +111 -120
- package/dist/net/webrtc/WebRTCTransport.d.ts +16 -8
- package/dist/net/webrtc/WebRTCTransport.js +149 -157
- package/dist/net/webrtc/index.d.ts +10 -2
- package/dist/net/webrtc/index.js +2 -2
- package/dist/net/websocket/AuthorizationProvider.d.ts +7 -5
- package/dist/net/websocket/AuthorizationProvider.js +12 -17
- package/dist/net/websocket/PatchesWebSocket.d.ts +14 -109
- package/dist/net/websocket/PatchesWebSocket.js +37 -184
- package/dist/net/websocket/RPCServer.d.ts +19 -10
- package/dist/net/websocket/RPCServer.js +190 -192
- package/dist/net/websocket/SignalingService.d.ts +12 -32
- package/dist/net/websocket/SignalingService.js +126 -133
- package/dist/net/websocket/WebSocketServer.d.ts +17 -4
- package/dist/net/websocket/WebSocketServer.js +64 -72
- package/dist/net/websocket/WebSocketTransport.d.ts +13 -5
- package/dist/net/websocket/WebSocketTransport.js +178 -207
- package/dist/net/websocket/onlineState.d.ts +6 -3
- package/dist/net/websocket/onlineState.js +25 -21
- package/dist/server/PatchesBranchManager.d.ts +12 -5
- package/dist/server/PatchesBranchManager.js +132 -142
- package/dist/server/PatchesHistoryManager.d.ts +11 -3
- package/dist/server/PatchesHistoryManager.js +81 -84
- package/dist/server/PatchesServer.d.ts +16 -10
- package/dist/server/PatchesServer.js +131 -137
- package/dist/server/index.d.ts +7 -2
- package/dist/server/index.js +9 -3
- package/dist/server/types.d.ts +9 -3
- package/dist/server/types.js +0 -1
- package/dist/types.d.ts +49 -19
- package/dist/types.js +1 -1
- package/dist/utils/concurrency.d.ts +7 -5
- package/dist/utils/concurrency.js +43 -53
- package/dist/utils/deferred.d.ts +4 -2
- package/dist/utils/deferred.js +25 -21
- package/package.json +5 -7
|
@@ -1,220 +1,191 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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:
|
|
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
|
-
|
|
9
|
-
|
|
10
|
+
declare const onlineState: OnlineState;
|
|
11
|
+
|
|
12
|
+
export { onlineState };
|
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "../../chunk-IZ2YBCUP.js";
|
|
2
|
+
import { signal } from "../../event-signal.js";
|
|
2
3
|
class OnlineState {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
25
|
+
const onlineState = new OnlineState();
|
|
26
|
+
export {
|
|
27
|
+
onlineState
|
|
28
|
+
};
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
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
|
-
|
|
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
|
-
|
|
53
|
+
declare function assertBranchMetadata(metadata?: EditableBranchMetadata): void;
|
|
54
|
+
|
|
55
|
+
export { PatchesBranchManager, assertBranchMetadata };
|