@electric-sql/client 1.3.0 → 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 +16 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.legacy-esm.js +16 -1
- package/dist/index.legacy-esm.js.map +1 -1
- package/dist/index.mjs +16 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +20 -1
- package/src/fetch.ts +16 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@electric-sql/client",
|
|
3
3
|
"description": "Postgres everywhere - your data, in sync, wherever you need it.",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.1",
|
|
5
5
|
"author": "ElectricSQL team and contributors.",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/electric-sql/electric/issues"
|
package/src/client.ts
CHANGED
|
@@ -982,7 +982,26 @@ export class ShapeStream<T extends Row<unknown> = Row>
|
|
|
982
982
|
const { headers, status } = response
|
|
983
983
|
const shapeHandle = headers.get(SHAPE_HANDLE_HEADER)
|
|
984
984
|
if (shapeHandle) {
|
|
985
|
-
this
|
|
985
|
+
// Don't accept a handle we know is expired - this can happen if a
|
|
986
|
+
// proxy serves a stale cached response despite the expired_handle
|
|
987
|
+
// cache buster parameter
|
|
988
|
+
const shapeKey = this.#currentFetchUrl
|
|
989
|
+
? canonicalShapeKey(this.#currentFetchUrl)
|
|
990
|
+
: null
|
|
991
|
+
const expiredHandle = shapeKey
|
|
992
|
+
? expiredShapesCache.getExpiredHandle(shapeKey)
|
|
993
|
+
: null
|
|
994
|
+
if (shapeHandle !== expiredHandle) {
|
|
995
|
+
this.#shapeHandle = shapeHandle
|
|
996
|
+
} else {
|
|
997
|
+
console.warn(
|
|
998
|
+
`[Electric] Received stale cached response with expired shape handle. ` +
|
|
999
|
+
`This should not happen and indicates a proxy/CDN caching misconfiguration. ` +
|
|
1000
|
+
`The response contained handle "${shapeHandle}" which was previously marked as expired. ` +
|
|
1001
|
+
`Check that your proxy includes all query parameters (especially 'handle' and 'offset') in its cache key. ` +
|
|
1002
|
+
`Ignoring the stale handle and continuing with handle "${this.#shapeHandle}".`
|
|
1003
|
+
)
|
|
1004
|
+
}
|
|
986
1005
|
}
|
|
987
1006
|
|
|
988
1007
|
const lastOffset = headers.get(CHUNK_LAST_OFFSET_HEADER)
|
package/src/fetch.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CHUNK_LAST_OFFSET_HEADER,
|
|
3
3
|
CHUNK_UP_TO_DATE_HEADER,
|
|
4
|
+
EXPIRED_HANDLE_QUERY_PARAM,
|
|
4
5
|
LIVE_QUERY_PARAM,
|
|
5
6
|
OFFSET_QUERY_PARAM,
|
|
6
7
|
SHAPE_HANDLE_HEADER,
|
|
@@ -436,6 +437,21 @@ function getNextChunkUrl(url: string, res: Response): string | void {
|
|
|
436
437
|
// potentially miss more recent data
|
|
437
438
|
if (nextUrl.searchParams.has(LIVE_QUERY_PARAM)) return
|
|
438
439
|
|
|
440
|
+
// don't prefetch if the response handle is the expired handle from the request
|
|
441
|
+
// this can happen when a proxy serves a stale cached response despite the
|
|
442
|
+
// expired_handle cache buster parameter
|
|
443
|
+
const expiredHandle = nextUrl.searchParams.get(EXPIRED_HANDLE_QUERY_PARAM)
|
|
444
|
+
if (expiredHandle && shapeHandle === expiredHandle) {
|
|
445
|
+
console.warn(
|
|
446
|
+
`[Electric] Received stale cached response with expired shape handle. ` +
|
|
447
|
+
`This should not happen and indicates a proxy/CDN caching misconfiguration. ` +
|
|
448
|
+
`The response contained handle "${shapeHandle}" which was previously marked as expired. ` +
|
|
449
|
+
`Check that your proxy includes all query parameters (especially 'handle' and 'offset') in its cache key. ` +
|
|
450
|
+
`Skipping prefetch to prevent infinite 409 loop.`
|
|
451
|
+
)
|
|
452
|
+
return
|
|
453
|
+
}
|
|
454
|
+
|
|
439
455
|
nextUrl.searchParams.set(SHAPE_HANDLE_QUERY_PARAM, shapeHandle)
|
|
440
456
|
nextUrl.searchParams.set(OFFSET_QUERY_PARAM, lastOffset)
|
|
441
457
|
nextUrl.searchParams.sort()
|