@electric-sql/client 1.2.2 → 1.3.1
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 +533 -575
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +10 -8
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.d.ts +10 -8
- package/dist/index.legacy-esm.js +33 -9
- package/dist/index.legacy-esm.js.map +1 -1
- package/dist/index.mjs +533 -575
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +29 -10
- package/src/fetch.ts +30 -3
- package/src/helpers.ts +2 -4
- package/src/types.ts +9 -0
package/dist/index.d.ts
CHANGED
|
@@ -45,13 +45,22 @@ type MoveOutPattern = {
|
|
|
45
45
|
pos: number;
|
|
46
46
|
value: string;
|
|
47
47
|
};
|
|
48
|
+
type SubsetParams = {
|
|
49
|
+
where?: string;
|
|
50
|
+
params?: Record<string, string>;
|
|
51
|
+
limit?: number;
|
|
52
|
+
offset?: number;
|
|
53
|
+
orderBy?: string;
|
|
54
|
+
};
|
|
48
55
|
type ControlMessage = {
|
|
49
56
|
headers: (Header & {
|
|
50
57
|
control: `up-to-date` | `must-refetch`;
|
|
51
58
|
global_last_seen_lsn?: string;
|
|
52
59
|
}) | (Header & {
|
|
53
60
|
control: `snapshot-end`;
|
|
54
|
-
} & PostgresSnapshot)
|
|
61
|
+
} & PostgresSnapshot) | (Header & {
|
|
62
|
+
control: `subset-end`;
|
|
63
|
+
} & SubsetParams);
|
|
55
64
|
};
|
|
56
65
|
type EventMessage = {
|
|
57
66
|
headers: Header & {
|
|
@@ -377,13 +386,6 @@ type ExternalParamsRecord<T extends Row<unknown> = Row> = {
|
|
|
377
386
|
} & Partial<PostgresParams<T>> & {
|
|
378
387
|
[K in ReservedParamKeys]?: never;
|
|
379
388
|
};
|
|
380
|
-
type SubsetParams = {
|
|
381
|
-
where?: string;
|
|
382
|
-
params?: Record<string, string>;
|
|
383
|
-
limit?: number;
|
|
384
|
-
offset?: number;
|
|
385
|
-
orderBy?: string;
|
|
386
|
-
};
|
|
387
389
|
type ReservedParamKeys = typeof LIVE_CACHE_BUSTER_QUERY_PARAM | typeof SHAPE_HANDLE_QUERY_PARAM | typeof LIVE_QUERY_PARAM | typeof OFFSET_QUERY_PARAM | `subset__${string}`;
|
|
388
390
|
/**
|
|
389
391
|
* External headers type - what users provide.
|
package/dist/index.legacy-esm.js
CHANGED
|
@@ -429,11 +429,9 @@ function isUpToDateMessage(message) {
|
|
|
429
429
|
return isControlMessage(message) && message.headers.control === `up-to-date`;
|
|
430
430
|
}
|
|
431
431
|
function getOffset(message) {
|
|
432
|
+
if (message.headers.control != `up-to-date`) return;
|
|
432
433
|
const lsn = message.headers.global_last_seen_lsn;
|
|
433
|
-
|
|
434
|
-
return;
|
|
435
|
-
}
|
|
436
|
-
return `${lsn}_0`;
|
|
434
|
+
return lsn ? `${lsn}_0` : void 0;
|
|
437
435
|
}
|
|
438
436
|
function isVisibleInSnapshot(txid, snapshot) {
|
|
439
437
|
const xid = BigInt(txid);
|
|
@@ -603,6 +601,7 @@ function createFetchWithChunkBuffer(fetchClient, prefetchOptions = ChunkPrefetch
|
|
|
603
601
|
return prefetchedRequest;
|
|
604
602
|
}
|
|
605
603
|
prefetchQueue == null ? void 0 : prefetchQueue.abort();
|
|
604
|
+
prefetchQueue = void 0;
|
|
606
605
|
const response = await fetchClient(...args);
|
|
607
606
|
const nextUrl = getNextChunkUrl(url, response);
|
|
608
607
|
if (nextUrl) {
|
|
@@ -675,12 +674,17 @@ var PrefetchQueue = class {
|
|
|
675
674
|
}
|
|
676
675
|
abort() {
|
|
677
676
|
__privateGet(this, _prefetchQueue).forEach(([_, aborter]) => aborter.abort());
|
|
677
|
+
__privateGet(this, _prefetchQueue).clear();
|
|
678
678
|
}
|
|
679
679
|
consume(...args) {
|
|
680
|
-
var _a;
|
|
681
680
|
const url = args[0].toString();
|
|
682
|
-
const
|
|
683
|
-
if (!
|
|
681
|
+
const entry = __privateGet(this, _prefetchQueue).get(url);
|
|
682
|
+
if (!entry || url !== __privateGet(this, _queueHeadUrl)) return;
|
|
683
|
+
const [request, aborter] = entry;
|
|
684
|
+
if (aborter.signal.aborted) {
|
|
685
|
+
__privateGet(this, _prefetchQueue).delete(url);
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
684
688
|
__privateGet(this, _prefetchQueue).delete(url);
|
|
685
689
|
request.then((response) => {
|
|
686
690
|
const nextUrl = getNextChunkUrl(url, response);
|
|
@@ -729,6 +733,13 @@ function getNextChunkUrl(url, res) {
|
|
|
729
733
|
if (!shapeHandle || !lastOffset || isUpToDate) return;
|
|
730
734
|
const nextUrl = new URL(url);
|
|
731
735
|
if (nextUrl.searchParams.has(LIVE_QUERY_PARAM)) return;
|
|
736
|
+
const expiredHandle = nextUrl.searchParams.get(EXPIRED_HANDLE_QUERY_PARAM);
|
|
737
|
+
if (expiredHandle && shapeHandle === expiredHandle) {
|
|
738
|
+
console.warn(
|
|
739
|
+
`[Electric] Received stale cached response with expired shape handle. This should not happen and indicates a proxy/CDN caching misconfiguration. The response contained handle "${shapeHandle}" which was previously marked as expired. Check that your proxy includes all query parameters (especially 'handle' and 'offset') in its cache key. Skipping prefetch to prevent infinite 409 loop.`
|
|
740
|
+
);
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
732
743
|
nextUrl.searchParams.set(SHAPE_HANDLE_QUERY_PARAM, shapeHandle);
|
|
733
744
|
nextUrl.searchParams.set(OFFSET_QUERY_PARAM, lastOffset);
|
|
734
745
|
nextUrl.searchParams.sort();
|
|
@@ -1231,7 +1242,8 @@ var ShapeStream = class {
|
|
|
1231
1242
|
}
|
|
1232
1243
|
const { metadata, data } = await this.fetchSnapshot(opts);
|
|
1233
1244
|
const dataWithEndBoundary = data.concat([
|
|
1234
|
-
{ headers: __spreadValues({ control: `snapshot-end` }, metadata) }
|
|
1245
|
+
{ headers: __spreadValues({ control: `snapshot-end` }, metadata) },
|
|
1246
|
+
{ headers: __spreadValues({ control: `subset-end` }, opts) }
|
|
1235
1247
|
]);
|
|
1236
1248
|
__privateGet(this, _snapshotTracker).addSnapshot(
|
|
1237
1249
|
metadata,
|
|
@@ -1536,7 +1548,15 @@ onInitialResponse_fn = async function(response) {
|
|
|
1536
1548
|
const { headers, status } = response;
|
|
1537
1549
|
const shapeHandle = headers.get(SHAPE_HANDLE_HEADER);
|
|
1538
1550
|
if (shapeHandle) {
|
|
1539
|
-
|
|
1551
|
+
const shapeKey = __privateGet(this, _currentFetchUrl) ? canonicalShapeKey(__privateGet(this, _currentFetchUrl)) : null;
|
|
1552
|
+
const expiredHandle = shapeKey ? expiredShapesCache.getExpiredHandle(shapeKey) : null;
|
|
1553
|
+
if (shapeHandle !== expiredHandle) {
|
|
1554
|
+
__privateSet(this, _shapeHandle, shapeHandle);
|
|
1555
|
+
} else {
|
|
1556
|
+
console.warn(
|
|
1557
|
+
`[Electric] Received stale cached response with expired shape handle. This should not happen and indicates a proxy/CDN caching misconfiguration. The response contained handle "${shapeHandle}" which was previously marked as expired. Check that your proxy includes all query parameters (especially 'handle' and 'offset') in its cache key. Ignoring the stale handle and continuing with handle "${__privateGet(this, _shapeHandle)}".`
|
|
1558
|
+
);
|
|
1559
|
+
}
|
|
1540
1560
|
}
|
|
1541
1561
|
const lastOffset = headers.get(CHUNK_LAST_OFFSET_HEADER);
|
|
1542
1562
|
if (lastOffset) {
|
|
@@ -1691,7 +1711,11 @@ pause_fn = function() {
|
|
|
1691
1711
|
}
|
|
1692
1712
|
};
|
|
1693
1713
|
resume_fn = function() {
|
|
1714
|
+
var _a;
|
|
1694
1715
|
if (__privateGet(this, _started) && (__privateGet(this, _state) === `paused` || __privateGet(this, _state) === `pause-requested`)) {
|
|
1716
|
+
if ((_a = this.options.signal) == null ? void 0 : _a.aborted) {
|
|
1717
|
+
return;
|
|
1718
|
+
}
|
|
1695
1719
|
if (__privateGet(this, _state) === `pause-requested`) {
|
|
1696
1720
|
__privateSet(this, _state, `active`);
|
|
1697
1721
|
}
|