@electric-sql/client 1.5.9 → 1.5.11
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/cjs/index.cjs +62 -9
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.browser.mjs +4 -4
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.legacy-esm.js +62 -9
- package/dist/index.legacy-esm.js.map +1 -1
- package/dist/index.mjs +62 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +39 -13
- package/src/shape-stream-state.ts +72 -35
package/dist/index.legacy-esm.js
CHANGED
|
@@ -1682,7 +1682,7 @@ var PausedState = class _PausedState extends ShapeStreamState {
|
|
|
1682
1682
|
constructor(previousState) {
|
|
1683
1683
|
super();
|
|
1684
1684
|
this.kind = `paused`;
|
|
1685
|
-
this.previousState = previousState;
|
|
1685
|
+
this.previousState = previousState instanceof _PausedState ? previousState.previousState : previousState;
|
|
1686
1686
|
}
|
|
1687
1687
|
get handle() {
|
|
1688
1688
|
return this.previousState.handle;
|
|
@@ -1722,7 +1722,20 @@ var PausedState = class _PausedState extends ShapeStreamState {
|
|
|
1722
1722
|
if (transition.action === `accepted`) {
|
|
1723
1723
|
return { action: `accepted`, state: new _PausedState(transition.state) };
|
|
1724
1724
|
}
|
|
1725
|
-
|
|
1725
|
+
if (transition.action === `ignored`) {
|
|
1726
|
+
return { action: `ignored`, state: this };
|
|
1727
|
+
}
|
|
1728
|
+
if (transition.action === `stale-retry`) {
|
|
1729
|
+
return {
|
|
1730
|
+
action: `stale-retry`,
|
|
1731
|
+
state: new _PausedState(transition.state),
|
|
1732
|
+
exceededMaxRetries: transition.exceededMaxRetries
|
|
1733
|
+
};
|
|
1734
|
+
}
|
|
1735
|
+
const _exhaustive = transition;
|
|
1736
|
+
throw new Error(
|
|
1737
|
+
`PausedState.handleResponseMetadata: unhandled transition action "${_exhaustive.action}"`
|
|
1738
|
+
);
|
|
1726
1739
|
}
|
|
1727
1740
|
withHandle(handle) {
|
|
1728
1741
|
return new _PausedState(this.previousState.withHandle(handle));
|
|
@@ -1741,7 +1754,7 @@ var ErrorState = class _ErrorState extends ShapeStreamState {
|
|
|
1741
1754
|
constructor(previousState, error) {
|
|
1742
1755
|
super();
|
|
1743
1756
|
this.kind = `error`;
|
|
1744
|
-
this.previousState = previousState;
|
|
1757
|
+
this.previousState = previousState instanceof _ErrorState ? previousState.previousState : previousState;
|
|
1745
1758
|
this.error = error;
|
|
1746
1759
|
}
|
|
1747
1760
|
get handle() {
|
|
@@ -1762,6 +1775,21 @@ var ErrorState = class _ErrorState extends ShapeStreamState {
|
|
|
1762
1775
|
get isUpToDate() {
|
|
1763
1776
|
return this.previousState.isUpToDate;
|
|
1764
1777
|
}
|
|
1778
|
+
get staleCacheBuster() {
|
|
1779
|
+
return this.previousState.staleCacheBuster;
|
|
1780
|
+
}
|
|
1781
|
+
get staleCacheRetryCount() {
|
|
1782
|
+
return this.previousState.staleCacheRetryCount;
|
|
1783
|
+
}
|
|
1784
|
+
get sseFallbackToLongPolling() {
|
|
1785
|
+
return this.previousState.sseFallbackToLongPolling;
|
|
1786
|
+
}
|
|
1787
|
+
get consecutiveShortSseConnections() {
|
|
1788
|
+
return this.previousState.consecutiveShortSseConnections;
|
|
1789
|
+
}
|
|
1790
|
+
get replayCursor() {
|
|
1791
|
+
return this.previousState.replayCursor;
|
|
1792
|
+
}
|
|
1765
1793
|
withHandle(handle) {
|
|
1766
1794
|
return new _ErrorState(this.previousState.withHandle(handle), this.error);
|
|
1767
1795
|
}
|
|
@@ -1875,6 +1903,9 @@ var RESERVED_PARAMS = /* @__PURE__ */ new Set([
|
|
|
1875
1903
|
CACHE_BUSTER_QUERY_PARAM
|
|
1876
1904
|
]);
|
|
1877
1905
|
var TROUBLESHOOTING_URL = `https://electric-sql.com/docs/guides/troubleshooting`;
|
|
1906
|
+
function createCacheBuster() {
|
|
1907
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
1908
|
+
}
|
|
1878
1909
|
async function resolveValue(value) {
|
|
1879
1910
|
if (typeof value === `function`) {
|
|
1880
1911
|
return value();
|
|
@@ -1915,7 +1946,7 @@ function canonicalShapeKey(url) {
|
|
|
1915
1946
|
cleanUrl.searchParams.sort();
|
|
1916
1947
|
return cleanUrl.toString();
|
|
1917
1948
|
}
|
|
1918
|
-
var _error, _fetchClient2, _sseFetchClient, _messageParser, _subscribers, _started, _syncState, _connected, _mode, _onError, _requestAbortController, _refreshCount, _snapshotCounter, _ShapeStream_instances, isRefreshing_get, _tickPromise, _tickPromiseResolver, _tickPromiseRejecter, _messageChain, _snapshotTracker, _pauseLock, _currentFetchUrl, _lastSseConnectionStartTime, _minSseConnectionDuration, _maxShortSseConnections, _sseBackoffBaseDelay, _sseBackoffMaxDelay, _unsubscribeFromVisibilityChanges, _unsubscribeFromWakeDetection, _maxStaleCacheRetries, _recentRequestEntries, _fastLoopWindowMs, _fastLoopThreshold, _fastLoopBackoffBaseMs, _fastLoopBackoffMaxMs, _fastLoopConsecutiveCount, _fastLoopMaxCount, start_fn, teardown_fn, requestShape_fn, checkFastLoop_fn, constructUrl_fn, createAbortListener_fn, onInitialResponse_fn, onMessages_fn, fetchShape_fn, requestShapeLongPoll_fn, requestShapeSSE_fn, nextTick_fn, publish_fn, sendErrorToSubscribers_fn, hasBrowserVisibilityAPI_fn, subscribeToVisibilityChanges_fn, subscribeToWakeDetection_fn, reset_fn, buildSubsetBody_fn;
|
|
1949
|
+
var _error, _fetchClient2, _sseFetchClient, _messageParser, _subscribers, _started, _syncState, _connected, _mode, _onError, _requestAbortController, _refreshCount, _snapshotCounter, _ShapeStream_instances, isRefreshing_get, _tickPromise, _tickPromiseResolver, _tickPromiseRejecter, _messageChain, _snapshotTracker, _pauseLock, _currentFetchUrl, _lastSseConnectionStartTime, _minSseConnectionDuration, _maxShortSseConnections, _sseBackoffBaseDelay, _sseBackoffMaxDelay, _unsubscribeFromVisibilityChanges, _unsubscribeFromWakeDetection, _maxStaleCacheRetries, _recentRequestEntries, _fastLoopWindowMs, _fastLoopThreshold, _fastLoopBackoffBaseMs, _fastLoopBackoffMaxMs, _fastLoopConsecutiveCount, _fastLoopMaxCount, _refetchCacheBuster, start_fn, teardown_fn, requestShape_fn, checkFastLoop_fn, constructUrl_fn, createAbortListener_fn, onInitialResponse_fn, onMessages_fn, fetchShape_fn, requestShapeLongPoll_fn, requestShapeSSE_fn, nextTick_fn, publish_fn, sendErrorToSubscribers_fn, hasBrowserVisibilityAPI_fn, subscribeToVisibilityChanges_fn, subscribeToWakeDetection_fn, reset_fn, buildSubsetBody_fn;
|
|
1919
1950
|
var ShapeStream = class {
|
|
1920
1951
|
constructor(options) {
|
|
1921
1952
|
__privateAdd(this, _ShapeStream_instances);
|
|
@@ -1962,6 +1993,7 @@ var ShapeStream = class {
|
|
|
1962
1993
|
__privateAdd(this, _fastLoopBackoffMaxMs, 5e3);
|
|
1963
1994
|
__privateAdd(this, _fastLoopConsecutiveCount, 0);
|
|
1964
1995
|
__privateAdd(this, _fastLoopMaxCount, 5);
|
|
1996
|
+
__privateAdd(this, _refetchCacheBuster);
|
|
1965
1997
|
var _a, _b, _c, _d;
|
|
1966
1998
|
this.options = __spreadValues({ subscribe: true }, options);
|
|
1967
1999
|
validateOptions(this.options);
|
|
@@ -2142,7 +2174,7 @@ var ShapeStream = class {
|
|
|
2142
2174
|
expiredHandle: null,
|
|
2143
2175
|
now: Date.now(),
|
|
2144
2176
|
maxStaleCacheRetries: __privateGet(this, _maxStaleCacheRetries),
|
|
2145
|
-
createCacheBuster
|
|
2177
|
+
createCacheBuster
|
|
2146
2178
|
});
|
|
2147
2179
|
if (transition.action === `accepted`) {
|
|
2148
2180
|
__privateSet(this, _syncState, transition.state);
|
|
@@ -2203,8 +2235,15 @@ var ShapeStream = class {
|
|
|
2203
2235
|
const shapeKey = canonicalShapeKey(fetchUrl);
|
|
2204
2236
|
expiredShapesCache.markExpired(shapeKey, usedHandle);
|
|
2205
2237
|
}
|
|
2206
|
-
const nextHandle = e.headers[SHAPE_HANDLE_HEADER]
|
|
2207
|
-
|
|
2238
|
+
const nextHandle = e.headers[SHAPE_HANDLE_HEADER];
|
|
2239
|
+
if (nextHandle) {
|
|
2240
|
+
__privateSet(this, _syncState, __privateGet(this, _syncState).withHandle(nextHandle));
|
|
2241
|
+
} else {
|
|
2242
|
+
console.warn(
|
|
2243
|
+
`[Electric] Received 409 response without a shape handle header. This likely indicates a proxy or CDN stripping required headers.`
|
|
2244
|
+
);
|
|
2245
|
+
__privateSet(this, _refetchCacheBuster, createCacheBuster());
|
|
2246
|
+
}
|
|
2208
2247
|
return this.fetchSnapshot(opts);
|
|
2209
2248
|
}
|
|
2210
2249
|
throw e;
|
|
@@ -2265,6 +2304,7 @@ _fastLoopBackoffBaseMs = new WeakMap();
|
|
|
2265
2304
|
_fastLoopBackoffMaxMs = new WeakMap();
|
|
2266
2305
|
_fastLoopConsecutiveCount = new WeakMap();
|
|
2267
2306
|
_fastLoopMaxCount = new WeakMap();
|
|
2307
|
+
_refetchCacheBuster = new WeakMap();
|
|
2268
2308
|
start_fn = async function() {
|
|
2269
2309
|
var _a, _b;
|
|
2270
2310
|
__privateSet(this, _started, true);
|
|
@@ -2369,7 +2409,13 @@ requestShape_fn = async function() {
|
|
|
2369
2409
|
const shapeKey = canonicalShapeKey(fetchUrl);
|
|
2370
2410
|
expiredShapesCache.markExpired(shapeKey, __privateGet(this, _syncState).handle);
|
|
2371
2411
|
}
|
|
2372
|
-
const newShapeHandle = e.headers[SHAPE_HANDLE_HEADER]
|
|
2412
|
+
const newShapeHandle = e.headers[SHAPE_HANDLE_HEADER];
|
|
2413
|
+
if (!newShapeHandle) {
|
|
2414
|
+
console.warn(
|
|
2415
|
+
`[Electric] Received 409 response without a shape handle header. This likely indicates a proxy or CDN stripping required headers.`
|
|
2416
|
+
);
|
|
2417
|
+
__privateSet(this, _refetchCacheBuster, createCacheBuster());
|
|
2418
|
+
}
|
|
2373
2419
|
__privateMethod(this, _ShapeStream_instances, reset_fn).call(this, newShapeHandle);
|
|
2374
2420
|
const messages409 = Array.isArray(e.json) ? e.json : e.json != null ? [e.json] : [];
|
|
2375
2421
|
await __privateMethod(this, _ShapeStream_instances, publish_fn).call(this, messages409);
|
|
@@ -2538,6 +2584,13 @@ constructUrl_fn = async function(url, resumingFromPause, subsetParams) {
|
|
|
2538
2584
|
if (expiredHandle) {
|
|
2539
2585
|
fetchUrl.searchParams.set(EXPIRED_HANDLE_QUERY_PARAM, expiredHandle);
|
|
2540
2586
|
}
|
|
2587
|
+
if (__privateGet(this, _refetchCacheBuster)) {
|
|
2588
|
+
fetchUrl.searchParams.set(
|
|
2589
|
+
CACHE_BUSTER_QUERY_PARAM,
|
|
2590
|
+
__privateGet(this, _refetchCacheBuster)
|
|
2591
|
+
);
|
|
2592
|
+
__privateSet(this, _refetchCacheBuster, void 0);
|
|
2593
|
+
}
|
|
2541
2594
|
fetchUrl.searchParams.sort();
|
|
2542
2595
|
return {
|
|
2543
2596
|
fetchUrl,
|
|
@@ -2574,7 +2627,7 @@ onInitialResponse_fn = async function(response) {
|
|
|
2574
2627
|
expiredHandle,
|
|
2575
2628
|
now: Date.now(),
|
|
2576
2629
|
maxStaleCacheRetries: __privateGet(this, _maxStaleCacheRetries),
|
|
2577
|
-
createCacheBuster
|
|
2630
|
+
createCacheBuster
|
|
2578
2631
|
});
|
|
2579
2632
|
__privateSet(this, _syncState, transition.state);
|
|
2580
2633
|
if (transition.action === `stale-retry`) {
|