@rebasepro/client 0.9.1-canary.e2fc7b6 → 0.9.1-canary.e3f810f
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.es.js +192 -59
- package/dist/index.es.js.map +1 -1
- package/dist/websocket.d.ts +43 -0
- package/package.json +4 -4
- package/src/websocket.ts +296 -59
package/dist/index.es.js
CHANGED
|
@@ -1397,9 +1397,11 @@ var ClientStorageSourceRegistry = class ClientStorageSourceRegistry {
|
|
|
1397
1397
|
function extractMessageError(message) {
|
|
1398
1398
|
const payload = message.payload;
|
|
1399
1399
|
const errPayload = payload?.error;
|
|
1400
|
+
const errorMessage = typeof errPayload === "object" ? errPayload.message : payload?.message || (typeof errPayload === "string" ? errPayload : void 0) || message.error || "Unknown error";
|
|
1401
|
+
const errorCode = typeof errPayload === "object" ? errPayload.code : payload?.code;
|
|
1400
1402
|
return {
|
|
1401
|
-
errorMessage: typeof
|
|
1402
|
-
errorCode
|
|
1403
|
+
errorMessage: typeof errorMessage === "string" ? errorMessage : errorMessage == null ? "Unknown error" : JSON.stringify(errorMessage),
|
|
1404
|
+
errorCode
|
|
1403
1405
|
};
|
|
1404
1406
|
}
|
|
1405
1407
|
/**
|
|
@@ -1435,6 +1437,7 @@ var RebaseWebSocketClient = class {
|
|
|
1435
1437
|
isConnected = false;
|
|
1436
1438
|
messageQueue = [];
|
|
1437
1439
|
requestTimeoutMs = 3e4;
|
|
1440
|
+
subscriptionTimeoutMs = 3e4;
|
|
1438
1441
|
reconnectTimeout = null;
|
|
1439
1442
|
isAuthenticated = false;
|
|
1440
1443
|
authPromise = null;
|
|
@@ -1540,6 +1543,7 @@ var RebaseWebSocketClient = class {
|
|
|
1540
1543
|
this.emit(wasReconnect ? "reconnect" : "connect");
|
|
1541
1544
|
this.processMessageQueue();
|
|
1542
1545
|
if (wasReconnect) this.resubscribeAll();
|
|
1546
|
+
this.armPendingSubscribeWatchdogs();
|
|
1543
1547
|
};
|
|
1544
1548
|
this.ws.onmessage = (event) => {
|
|
1545
1549
|
try {
|
|
@@ -1554,6 +1558,7 @@ var RebaseWebSocketClient = class {
|
|
|
1554
1558
|
this.isConnected = false;
|
|
1555
1559
|
this.isAuthenticated = false;
|
|
1556
1560
|
this.authPromise = null;
|
|
1561
|
+
this.suspendSubscribeWatchdogs();
|
|
1557
1562
|
this.emit("disconnect");
|
|
1558
1563
|
for (const [reqId, request] of this.pendingRequests.entries()) {
|
|
1559
1564
|
if (reqId.startsWith("auth_")) request.reject(/* @__PURE__ */ new Error("Connection closed during authentication"));
|
|
@@ -1585,6 +1590,7 @@ var RebaseWebSocketClient = class {
|
|
|
1585
1590
|
attemptReconnect() {
|
|
1586
1591
|
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
1587
1592
|
console.error("Max reconnection attempts reached");
|
|
1593
|
+
this.failAllPendingSubscriptions(new RebaseApiError$1("Connection lost", { code: "CONNECTION_LOST" }));
|
|
1588
1594
|
return;
|
|
1589
1595
|
}
|
|
1590
1596
|
this.reconnectAttempts++;
|
|
@@ -1639,29 +1645,18 @@ var RebaseWebSocketClient = class {
|
|
|
1639
1645
|
subscription.backendSubscriptionId = newBackendId;
|
|
1640
1646
|
backendKeyMap.delete(oldBackendId);
|
|
1641
1647
|
backendKeyMap.set(newBackendId, subscriptionKey);
|
|
1642
|
-
this.
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
...subscription.props,
|
|
1646
|
-
subscriptionId: newBackendId
|
|
1647
|
-
}
|
|
1648
|
-
}).catch((error) => {
|
|
1649
|
-
console.error(`[WS] Failed to re-subscribe ${idPrefix} after auth refresh:`, subscriptionKey, error);
|
|
1650
|
-
subscription.callbacks.forEach((callback) => {
|
|
1651
|
-
if (callback.onError) callback.onError(error);
|
|
1652
|
-
});
|
|
1653
|
-
});
|
|
1654
|
-
} else {
|
|
1655
|
-
const { errorMessage, errorCode } = extractMessageError(message);
|
|
1656
|
-
const error = new RebaseApiError$1(errorMessage, { code: errorCode });
|
|
1657
|
-
subscription.callbacks.forEach((callback) => {
|
|
1658
|
-
if (callback.onError) callback.onError(error);
|
|
1659
|
-
});
|
|
1648
|
+
if (messageType === "subscribe_collection") this.sendCollectionSubscribe(subscriptionKey);
|
|
1649
|
+
else this.sendEntitySubscribe(subscriptionKey);
|
|
1650
|
+
return;
|
|
1660
1651
|
}
|
|
1652
|
+
const { errorMessage, errorCode } = extractMessageError(message);
|
|
1653
|
+
const error = new RebaseApiError$1(errorMessage, { code: errorCode });
|
|
1654
|
+
if (messageType === "subscribe_collection") this.failCollectionSubscription(subscriptionKey, error);
|
|
1655
|
+
else this.failEntitySubscription(subscriptionKey, error);
|
|
1661
1656
|
}).catch((err) => {
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1657
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1658
|
+
if (messageType === "subscribe_collection") this.failCollectionSubscription(subscriptionKey, error);
|
|
1659
|
+
else this.failEntitySubscription(subscriptionKey, error);
|
|
1665
1660
|
});
|
|
1666
1661
|
}
|
|
1667
1662
|
handleWebSocketMessage(message) {
|
|
@@ -1702,6 +1697,9 @@ var RebaseWebSocketClient = class {
|
|
|
1702
1697
|
collectionSub.latestData = rows;
|
|
1703
1698
|
collectionSub.lastUpdated = Date.now();
|
|
1704
1699
|
collectionSub.isInitialDataReceived = true;
|
|
1700
|
+
if (collectionSub.subscribeTimeout) clearTimeout(collectionSub.subscribeTimeout);
|
|
1701
|
+
collectionSub.subscribeTimeout = void 0;
|
|
1702
|
+
collectionSub.subscribeInFlight = false;
|
|
1705
1703
|
collectionSub.callbacks.forEach((callback) => {
|
|
1706
1704
|
try {
|
|
1707
1705
|
callback.onUpdate(rows);
|
|
@@ -1757,6 +1755,9 @@ var RebaseWebSocketClient = class {
|
|
|
1757
1755
|
entitySub.latestData = row;
|
|
1758
1756
|
entitySub.lastUpdated = Date.now();
|
|
1759
1757
|
entitySub.isInitialDataReceived = true;
|
|
1758
|
+
if (entitySub.subscribeTimeout) clearTimeout(entitySub.subscribeTimeout);
|
|
1759
|
+
entitySub.subscribeTimeout = void 0;
|
|
1760
|
+
entitySub.subscribeInFlight = false;
|
|
1760
1761
|
entitySub.callbacks.forEach((callback) => {
|
|
1761
1762
|
try {
|
|
1762
1763
|
callback.onUpdate(row);
|
|
@@ -1778,6 +1779,9 @@ var RebaseWebSocketClient = class {
|
|
|
1778
1779
|
this.resubscribeAfterAuthRefresh(message, collectionSub, collectionKey, "collection", this.backendToCollectionKey, "subscribe_collection");
|
|
1779
1780
|
return;
|
|
1780
1781
|
}
|
|
1782
|
+
if (collectionSub.subscribeTimeout) clearTimeout(collectionSub.subscribeTimeout);
|
|
1783
|
+
collectionSub.subscribeTimeout = void 0;
|
|
1784
|
+
collectionSub.subscribeInFlight = false;
|
|
1781
1785
|
const { errorMessage, errorCode } = extractMessageError(message);
|
|
1782
1786
|
const error = new RebaseApiError$1(errorMessage, { code: errorCode });
|
|
1783
1787
|
collectionSub.callbacks.forEach((callback) => {
|
|
@@ -1794,6 +1798,9 @@ var RebaseWebSocketClient = class {
|
|
|
1794
1798
|
this.resubscribeAfterAuthRefresh(message, entitySub, entityKey, "row", this.backendToEntityKey, "subscribe_one");
|
|
1795
1799
|
return;
|
|
1796
1800
|
}
|
|
1801
|
+
if (entitySub.subscribeTimeout) clearTimeout(entitySub.subscribeTimeout);
|
|
1802
|
+
entitySub.subscribeTimeout = void 0;
|
|
1803
|
+
entitySub.subscribeInFlight = false;
|
|
1797
1804
|
const { errorMessage, errorCode } = extractMessageError(message);
|
|
1798
1805
|
const error = new RebaseApiError$1(errorMessage, { code: errorCode });
|
|
1799
1806
|
entitySub.callbacks.forEach((callback) => {
|
|
@@ -2142,9 +2149,12 @@ var RebaseWebSocketClient = class {
|
|
|
2142
2149
|
console.error("Error in collection subscription callback:", error);
|
|
2143
2150
|
if (onError) onError(error instanceof Error ? error : new Error(String(error)));
|
|
2144
2151
|
}
|
|
2152
|
+
else if (!existingSubscription.subscribeInFlight) this.sendCollectionSubscribe(subscriptionKey);
|
|
2145
2153
|
return () => {
|
|
2146
2154
|
callbackMap.delete(callbackId);
|
|
2147
2155
|
if (callbackMap.size === 0) {
|
|
2156
|
+
if (this.collectionSubscriptions.get(subscriptionKey) !== existingSubscription) return;
|
|
2157
|
+
if (existingSubscription.subscribeTimeout) clearTimeout(existingSubscription.subscribeTimeout);
|
|
2148
2158
|
this.collectionSubscriptions.delete(subscriptionKey);
|
|
2149
2159
|
this.backendToCollectionKey.delete(existingSubscription.backendSubscriptionId);
|
|
2150
2160
|
if (this.isConnected && this.ws) this.sendMessage({
|
|
@@ -2166,21 +2176,14 @@ var RebaseWebSocketClient = class {
|
|
|
2166
2176
|
props
|
|
2167
2177
|
});
|
|
2168
2178
|
this.backendToCollectionKey.set(backendSubscriptionId, subscriptionKey);
|
|
2169
|
-
this.
|
|
2170
|
-
type: "subscribe_collection",
|
|
2171
|
-
payload: {
|
|
2172
|
-
...props,
|
|
2173
|
-
subscriptionId: backendSubscriptionId
|
|
2174
|
-
}
|
|
2175
|
-
}).catch((error) => {
|
|
2176
|
-
if (onError) onError(error);
|
|
2177
|
-
});
|
|
2179
|
+
this.sendCollectionSubscribe(subscriptionKey);
|
|
2178
2180
|
return () => {
|
|
2179
2181
|
const subscription = this.collectionSubscriptions.get(subscriptionKey);
|
|
2180
2182
|
if (subscription) {
|
|
2181
2183
|
const callbacks = subscription.callbacks;
|
|
2182
2184
|
callbacks.delete(callbackId);
|
|
2183
2185
|
if (callbacks.size === 0) {
|
|
2186
|
+
if (subscription.subscribeTimeout) clearTimeout(subscription.subscribeTimeout);
|
|
2184
2187
|
this.collectionSubscriptions.delete(subscriptionKey);
|
|
2185
2188
|
this.backendToCollectionKey.delete(subscription.backendSubscriptionId);
|
|
2186
2189
|
if (this.isConnected && this.ws) this.sendMessage({
|
|
@@ -2207,9 +2210,12 @@ var RebaseWebSocketClient = class {
|
|
|
2207
2210
|
console.error("Error in row subscription callback:", error);
|
|
2208
2211
|
if (onError) onError(error instanceof Error ? error : new Error(String(error)));
|
|
2209
2212
|
}
|
|
2213
|
+
else if (!existingSubscription.subscribeInFlight) this.sendEntitySubscribe(subscriptionKey);
|
|
2210
2214
|
return () => {
|
|
2211
2215
|
callbackMap.delete(callbackId);
|
|
2212
2216
|
if (callbackMap.size === 0) {
|
|
2217
|
+
if (this.singleSubscriptions.get(subscriptionKey) !== existingSubscription) return;
|
|
2218
|
+
if (existingSubscription.subscribeTimeout) clearTimeout(existingSubscription.subscribeTimeout);
|
|
2213
2219
|
this.singleSubscriptions.delete(subscriptionKey);
|
|
2214
2220
|
this.backendToEntityKey.delete(existingSubscription.backendSubscriptionId);
|
|
2215
2221
|
if (this.isConnected && this.ws) this.sendMessage({
|
|
@@ -2231,15 +2237,7 @@ var RebaseWebSocketClient = class {
|
|
|
2231
2237
|
props
|
|
2232
2238
|
});
|
|
2233
2239
|
this.backendToEntityKey.set(backendSubscriptionId, subscriptionKey);
|
|
2234
|
-
this.
|
|
2235
|
-
type: "subscribe_one",
|
|
2236
|
-
payload: {
|
|
2237
|
-
...props,
|
|
2238
|
-
subscriptionId: backendSubscriptionId
|
|
2239
|
-
}
|
|
2240
|
-
}).catch((error) => {
|
|
2241
|
-
if (onError) onError(error);
|
|
2242
|
-
});
|
|
2240
|
+
this.sendEntitySubscribe(subscriptionKey);
|
|
2243
2241
|
return () => {
|
|
2244
2242
|
const subscription = this.singleSubscriptions.get(subscriptionKey);
|
|
2245
2243
|
if (subscription) {
|
|
@@ -2257,6 +2255,157 @@ var RebaseWebSocketClient = class {
|
|
|
2257
2255
|
};
|
|
2258
2256
|
}
|
|
2259
2257
|
/**
|
|
2258
|
+
* Send a `subscribe_collection` for an already-registered subscription and
|
|
2259
|
+
* arm its watchdog.
|
|
2260
|
+
*
|
|
2261
|
+
* Every path that registers a collection subscription goes through here, so
|
|
2262
|
+
* that a subscribe which never lands — a rejected send, or a server that
|
|
2263
|
+
* never answers — always ends up in `failCollectionSubscription` rather than
|
|
2264
|
+
* leaving the entry parked with `isInitialDataReceived === false` forever.
|
|
2265
|
+
*/
|
|
2266
|
+
sendCollectionSubscribe(subscriptionKey) {
|
|
2267
|
+
const subscription = this.collectionSubscriptions.get(subscriptionKey);
|
|
2268
|
+
if (!subscription) return;
|
|
2269
|
+
const backendSubscriptionId = subscription.backendSubscriptionId;
|
|
2270
|
+
subscription.subscribeInFlight = true;
|
|
2271
|
+
if (subscription.subscribeTimeout) clearTimeout(subscription.subscribeTimeout);
|
|
2272
|
+
subscription.subscribeTimeout = void 0;
|
|
2273
|
+
if (this.isConnected) this.sendCollectionSubscribeWatchdog(subscriptionKey);
|
|
2274
|
+
this.sendMessage({
|
|
2275
|
+
type: "subscribe_collection",
|
|
2276
|
+
payload: {
|
|
2277
|
+
...subscription.props,
|
|
2278
|
+
subscriptionId: backendSubscriptionId
|
|
2279
|
+
}
|
|
2280
|
+
}).catch((error) => {
|
|
2281
|
+
const current = this.collectionSubscriptions.get(subscriptionKey);
|
|
2282
|
+
if (!current || current.backendSubscriptionId !== backendSubscriptionId) return;
|
|
2283
|
+
this.failCollectionSubscription(subscriptionKey, error instanceof Error ? error : new Error(String(error)));
|
|
2284
|
+
});
|
|
2285
|
+
}
|
|
2286
|
+
/** The `listenOne` counterpart of {@link sendCollectionSubscribe}. */
|
|
2287
|
+
sendEntitySubscribe(subscriptionKey) {
|
|
2288
|
+
const subscription = this.singleSubscriptions.get(subscriptionKey);
|
|
2289
|
+
if (!subscription) return;
|
|
2290
|
+
const backendSubscriptionId = subscription.backendSubscriptionId;
|
|
2291
|
+
subscription.subscribeInFlight = true;
|
|
2292
|
+
if (subscription.subscribeTimeout) clearTimeout(subscription.subscribeTimeout);
|
|
2293
|
+
subscription.subscribeTimeout = void 0;
|
|
2294
|
+
if (this.isConnected) this.sendEntitySubscribeWatchdog(subscriptionKey);
|
|
2295
|
+
this.sendMessage({
|
|
2296
|
+
type: "subscribe_one",
|
|
2297
|
+
payload: {
|
|
2298
|
+
...subscription.props,
|
|
2299
|
+
subscriptionId: backendSubscriptionId
|
|
2300
|
+
}
|
|
2301
|
+
}).catch((error) => {
|
|
2302
|
+
const current = this.singleSubscriptions.get(subscriptionKey);
|
|
2303
|
+
if (!current || current.backendSubscriptionId !== backendSubscriptionId) return;
|
|
2304
|
+
this.failEntitySubscription(subscriptionKey, error instanceof Error ? error : new Error(String(error)));
|
|
2305
|
+
});
|
|
2306
|
+
}
|
|
2307
|
+
/**
|
|
2308
|
+
* Report a subscribe failure to every listener and drop the registration.
|
|
2309
|
+
*
|
|
2310
|
+
* Dropping it is the point: the callbacks stay live (their components are
|
|
2311
|
+
* still mounted and have been told), but the next `listenCollection` for
|
|
2312
|
+
* these params finds no entry and issues a fresh subscribe instead of
|
|
2313
|
+
* silently attaching to a dead one.
|
|
2314
|
+
*/
|
|
2315
|
+
failCollectionSubscription(subscriptionKey, error) {
|
|
2316
|
+
const subscription = this.collectionSubscriptions.get(subscriptionKey);
|
|
2317
|
+
if (!subscription) return;
|
|
2318
|
+
if (subscription.subscribeTimeout) clearTimeout(subscription.subscribeTimeout);
|
|
2319
|
+
subscription.subscribeInFlight = false;
|
|
2320
|
+
this.collectionSubscriptions.delete(subscriptionKey);
|
|
2321
|
+
this.backendToCollectionKey.delete(subscription.backendSubscriptionId);
|
|
2322
|
+
subscription.callbacks.forEach((callback) => {
|
|
2323
|
+
if (callback.onError) try {
|
|
2324
|
+
callback.onError(error);
|
|
2325
|
+
} catch (callbackError) {
|
|
2326
|
+
console.error("Error in collection subscription error callback:", callbackError);
|
|
2327
|
+
}
|
|
2328
|
+
});
|
|
2329
|
+
}
|
|
2330
|
+
/** The `listenOne` counterpart of {@link failCollectionSubscription}. */
|
|
2331
|
+
failEntitySubscription(subscriptionKey, error) {
|
|
2332
|
+
const subscription = this.singleSubscriptions.get(subscriptionKey);
|
|
2333
|
+
if (!subscription) return;
|
|
2334
|
+
if (subscription.subscribeTimeout) clearTimeout(subscription.subscribeTimeout);
|
|
2335
|
+
subscription.subscribeInFlight = false;
|
|
2336
|
+
this.singleSubscriptions.delete(subscriptionKey);
|
|
2337
|
+
this.backendToEntityKey.delete(subscription.backendSubscriptionId);
|
|
2338
|
+
subscription.callbacks.forEach((callback) => {
|
|
2339
|
+
if (callback.onError) try {
|
|
2340
|
+
callback.onError(error);
|
|
2341
|
+
} catch (callbackError) {
|
|
2342
|
+
console.error("Error in row subscription error callback:", callbackError);
|
|
2343
|
+
}
|
|
2344
|
+
});
|
|
2345
|
+
}
|
|
2346
|
+
/**
|
|
2347
|
+
* Stop the watchdogs without failing anything — used when the socket drops,
|
|
2348
|
+
* since the reconnect path re-subscribes everything anyway and a watchdog
|
|
2349
|
+
* firing mid-reconnect would tear down healthy subscriptions.
|
|
2350
|
+
*/
|
|
2351
|
+
suspendSubscribeWatchdogs() {
|
|
2352
|
+
for (const sub of this.collectionSubscriptions.values()) {
|
|
2353
|
+
if (sub.subscribeTimeout) clearTimeout(sub.subscribeTimeout);
|
|
2354
|
+
sub.subscribeTimeout = void 0;
|
|
2355
|
+
sub.subscribeInFlight = false;
|
|
2356
|
+
}
|
|
2357
|
+
for (const sub of this.singleSubscriptions.values()) {
|
|
2358
|
+
if (sub.subscribeTimeout) clearTimeout(sub.subscribeTimeout);
|
|
2359
|
+
sub.subscribeTimeout = void 0;
|
|
2360
|
+
sub.subscribeInFlight = false;
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
/**
|
|
2364
|
+
* Arm watchdogs for subscribes that were requested while offline and have
|
|
2365
|
+
* just been flushed to the socket. Their timers were deliberately not set at
|
|
2366
|
+
* request time, so without this they would have no timeout at all.
|
|
2367
|
+
*/
|
|
2368
|
+
armPendingSubscribeWatchdogs() {
|
|
2369
|
+
for (const [key, sub] of this.collectionSubscriptions.entries()) if (sub.subscribeInFlight && !sub.subscribeTimeout) this.sendCollectionSubscribeWatchdog(key);
|
|
2370
|
+
for (const [key, sub] of this.singleSubscriptions.entries()) if (sub.subscribeInFlight && !sub.subscribeTimeout) this.sendEntitySubscribeWatchdog(key);
|
|
2371
|
+
}
|
|
2372
|
+
sendCollectionSubscribeWatchdog(subscriptionKey) {
|
|
2373
|
+
const subscription = this.collectionSubscriptions.get(subscriptionKey);
|
|
2374
|
+
if (!subscription) return;
|
|
2375
|
+
const backendSubscriptionId = subscription.backendSubscriptionId;
|
|
2376
|
+
subscription.subscribeTimeout = setTimeout(() => {
|
|
2377
|
+
const current = this.collectionSubscriptions.get(subscriptionKey);
|
|
2378
|
+
if (!current || current.backendSubscriptionId !== backendSubscriptionId) return;
|
|
2379
|
+
if (!current.subscribeInFlight) return;
|
|
2380
|
+
this.failCollectionSubscription(subscriptionKey, new RebaseApiError$1("Subscription timed out", { code: "SUBSCRIPTION_TIMEOUT" }));
|
|
2381
|
+
}, this.subscriptionTimeoutMs);
|
|
2382
|
+
}
|
|
2383
|
+
sendEntitySubscribeWatchdog(subscriptionKey) {
|
|
2384
|
+
const subscription = this.singleSubscriptions.get(subscriptionKey);
|
|
2385
|
+
if (!subscription) return;
|
|
2386
|
+
const backendSubscriptionId = subscription.backendSubscriptionId;
|
|
2387
|
+
subscription.subscribeTimeout = setTimeout(() => {
|
|
2388
|
+
const current = this.singleSubscriptions.get(subscriptionKey);
|
|
2389
|
+
if (!current || current.backendSubscriptionId !== backendSubscriptionId) return;
|
|
2390
|
+
if (!current.subscribeInFlight) return;
|
|
2391
|
+
this.failEntitySubscription(subscriptionKey, new RebaseApiError$1("Subscription timed out", { code: "SUBSCRIPTION_TIMEOUT" }));
|
|
2392
|
+
}, this.subscriptionTimeoutMs);
|
|
2393
|
+
}
|
|
2394
|
+
/**
|
|
2395
|
+
* Fail every subscription that never received data. Called when reconnection
|
|
2396
|
+
* is given up on, so views surface an error instead of spinning forever.
|
|
2397
|
+
*/
|
|
2398
|
+
failAllPendingSubscriptions(error) {
|
|
2399
|
+
for (const key of [...this.collectionSubscriptions.keys()]) {
|
|
2400
|
+
const sub = this.collectionSubscriptions.get(key);
|
|
2401
|
+
if (sub && !sub.isInitialDataReceived) this.failCollectionSubscription(key, error);
|
|
2402
|
+
}
|
|
2403
|
+
for (const key of [...this.singleSubscriptions.keys()]) {
|
|
2404
|
+
const sub = this.singleSubscriptions.get(key);
|
|
2405
|
+
if (sub && !sub.isInitialDataReceived) this.failEntitySubscription(key, error);
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
/**
|
|
2260
2409
|
* Re-send all active subscriptions to the backend after a reconnect.
|
|
2261
2410
|
* The server wipes subscription state when a client disconnects, so
|
|
2262
2411
|
* we need to re-register everything to resume receiving updates.
|
|
@@ -2269,15 +2418,7 @@ var RebaseWebSocketClient = class {
|
|
|
2269
2418
|
sub.backendSubscriptionId = newBackendId;
|
|
2270
2419
|
this.backendToCollectionKey.delete(oldBackendId);
|
|
2271
2420
|
this.backendToCollectionKey.set(newBackendId, key);
|
|
2272
|
-
this.
|
|
2273
|
-
type: "subscribe_collection",
|
|
2274
|
-
payload: {
|
|
2275
|
-
...sub.props,
|
|
2276
|
-
subscriptionId: newBackendId
|
|
2277
|
-
}
|
|
2278
|
-
}).catch((error) => {
|
|
2279
|
-
console.error("[WS] Failed to re-subscribe collection:", key, error);
|
|
2280
|
-
});
|
|
2421
|
+
this.sendCollectionSubscribe(key);
|
|
2281
2422
|
}
|
|
2282
2423
|
for (const [key, sub] of this.singleSubscriptions.entries()) {
|
|
2283
2424
|
const oldBackendId = sub.backendSubscriptionId;
|
|
@@ -2285,15 +2426,7 @@ var RebaseWebSocketClient = class {
|
|
|
2285
2426
|
sub.backendSubscriptionId = newBackendId;
|
|
2286
2427
|
this.backendToEntityKey.delete(oldBackendId);
|
|
2287
2428
|
this.backendToEntityKey.set(newBackendId, key);
|
|
2288
|
-
this.
|
|
2289
|
-
type: "subscribe_one",
|
|
2290
|
-
payload: {
|
|
2291
|
-
...sub.props,
|
|
2292
|
-
subscriptionId: newBackendId
|
|
2293
|
-
}
|
|
2294
|
-
}).catch((error) => {
|
|
2295
|
-
console.error("[WS] Failed to re-subscribe row:", key, error);
|
|
2296
|
-
});
|
|
2429
|
+
this.sendEntitySubscribe(key);
|
|
2297
2430
|
}
|
|
2298
2431
|
}
|
|
2299
2432
|
createCollectionSubscriptionKey(props) {
|