@electric-sql/client 1.3.1 → 1.4.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 +166 -11
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +67 -2
- package/dist/index.browser.mjs +3 -3
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.d.ts +67 -2
- package/dist/index.legacy-esm.js +164 -11
- package/dist/index.legacy-esm.js.map +1 -1
- package/dist/index.mjs +164 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +109 -3
- package/src/constants.ts +6 -0
- package/src/error.ts +7 -0
- package/src/expression-compiler.ts +132 -0
- package/src/index.ts +1 -0
- package/src/types.ts +28 -0
package/dist/cjs/index.d.cts
CHANGED
|
@@ -45,12 +45,45 @@ type MoveOutPattern = {
|
|
|
45
45
|
pos: number;
|
|
46
46
|
value: string;
|
|
47
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Serialized expression types for structured subset queries.
|
|
50
|
+
* These allow Electric to properly apply columnMapper transformations
|
|
51
|
+
* before generating the final SQL.
|
|
52
|
+
*/
|
|
53
|
+
type SerializedExpression = {
|
|
54
|
+
type: `ref`;
|
|
55
|
+
column: string;
|
|
56
|
+
} | {
|
|
57
|
+
type: `val`;
|
|
58
|
+
paramIndex: number;
|
|
59
|
+
} | {
|
|
60
|
+
type: `func`;
|
|
61
|
+
name: string;
|
|
62
|
+
args: SerializedExpression[];
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Serialized ORDER BY clause for structured subset queries.
|
|
66
|
+
*/
|
|
67
|
+
type SerializedOrderByClause = {
|
|
68
|
+
column: string;
|
|
69
|
+
direction?: `asc` | `desc`;
|
|
70
|
+
nulls?: `first` | `last`;
|
|
71
|
+
};
|
|
48
72
|
type SubsetParams = {
|
|
73
|
+
/** Legacy string format WHERE clause */
|
|
49
74
|
where?: string;
|
|
75
|
+
/** Positional parameter values for WHERE clause */
|
|
50
76
|
params?: Record<string, string>;
|
|
77
|
+
/** Maximum number of rows to return */
|
|
51
78
|
limit?: number;
|
|
79
|
+
/** Number of rows to skip */
|
|
52
80
|
offset?: number;
|
|
81
|
+
/** Legacy string format ORDER BY clause */
|
|
53
82
|
orderBy?: string;
|
|
83
|
+
/** Structured WHERE expression (preferred when available) */
|
|
84
|
+
whereExpr?: SerializedExpression;
|
|
85
|
+
/** Structured ORDER BY clauses (preferred when available) */
|
|
86
|
+
orderByExpr?: SerializedOrderByClause[];
|
|
54
87
|
};
|
|
55
88
|
type ControlMessage = {
|
|
56
89
|
headers: (Header & {
|
|
@@ -333,6 +366,7 @@ declare const LIVE_CACHE_BUSTER_QUERY_PARAM = "cursor";
|
|
|
333
366
|
declare const SHAPE_HANDLE_QUERY_PARAM = "handle";
|
|
334
367
|
declare const LIVE_QUERY_PARAM = "live";
|
|
335
368
|
declare const OFFSET_QUERY_PARAM = "offset";
|
|
369
|
+
declare const CACHE_BUSTER_QUERY_PARAM = "cache-buster";
|
|
336
370
|
declare const ELECTRIC_PROTOCOL_QUERY_PARAMS: Array<string>;
|
|
337
371
|
|
|
338
372
|
type Replica = `full` | `default`;
|
|
@@ -386,7 +420,7 @@ type ExternalParamsRecord<T extends Row<unknown> = Row> = {
|
|
|
386
420
|
} & Partial<PostgresParams<T>> & {
|
|
387
421
|
[K in ReservedParamKeys]?: never;
|
|
388
422
|
};
|
|
389
|
-
type ReservedParamKeys = typeof LIVE_CACHE_BUSTER_QUERY_PARAM | typeof SHAPE_HANDLE_QUERY_PARAM | typeof LIVE_QUERY_PARAM | typeof OFFSET_QUERY_PARAM | `subset__${string}`;
|
|
423
|
+
type ReservedParamKeys = typeof LIVE_CACHE_BUSTER_QUERY_PARAM | typeof SHAPE_HANDLE_QUERY_PARAM | typeof LIVE_QUERY_PARAM | typeof OFFSET_QUERY_PARAM | typeof CACHE_BUSTER_QUERY_PARAM | `subset__${string}`;
|
|
390
424
|
/**
|
|
391
425
|
* External headers type - what users provide.
|
|
392
426
|
* Allows string or function values for any header.
|
|
@@ -841,4 +875,35 @@ declare function isControlMessage<T extends Row<unknown> = Row>(message: Message
|
|
|
841
875
|
*/
|
|
842
876
|
declare function isVisibleInSnapshot(txid: number | bigint | `${bigint}`, snapshot: PostgresSnapshot | NormalizedPgSnapshot): boolean;
|
|
843
877
|
|
|
844
|
-
|
|
878
|
+
/**
|
|
879
|
+
* Compiles a serialized expression into a SQL string.
|
|
880
|
+
* Applies columnMapper transformations to column references.
|
|
881
|
+
*
|
|
882
|
+
* @param expr - The serialized expression to compile
|
|
883
|
+
* @param columnMapper - Optional function to transform column names (e.g., camelCase to snake_case)
|
|
884
|
+
* @returns The compiled SQL string
|
|
885
|
+
*
|
|
886
|
+
* @example
|
|
887
|
+
* ```typescript
|
|
888
|
+
* const expr = { type: 'ref', column: 'userId' }
|
|
889
|
+
* compileExpression(expr, camelToSnake) // '"user_id"'
|
|
890
|
+
* ```
|
|
891
|
+
*/
|
|
892
|
+
declare function compileExpression(expr: SerializedExpression, columnMapper?: (col: string) => string): string;
|
|
893
|
+
/**
|
|
894
|
+
* Compiles serialized ORDER BY clauses into a SQL string.
|
|
895
|
+
* Applies columnMapper transformations to column references.
|
|
896
|
+
*
|
|
897
|
+
* @param clauses - The serialized ORDER BY clauses to compile
|
|
898
|
+
* @param columnMapper - Optional function to transform column names
|
|
899
|
+
* @returns The compiled SQL ORDER BY string
|
|
900
|
+
*
|
|
901
|
+
* @example
|
|
902
|
+
* ```typescript
|
|
903
|
+
* const clauses = [{ column: 'createdAt', direction: 'desc', nulls: 'first' }]
|
|
904
|
+
* compileOrderBy(clauses, camelToSnake) // '"created_at" DESC NULLS FIRST'
|
|
905
|
+
* ```
|
|
906
|
+
*/
|
|
907
|
+
declare function compileOrderBy(clauses: SerializedOrderByClause[], columnMapper?: (col: string) => string): string;
|
|
908
|
+
|
|
909
|
+
export { BackoffDefaults, type BackoffOptions, type BitColumn, type BpcharColumn, type ChangeMessage, type ColumnInfo, type ColumnMapper, type CommonColumnProps, type ControlMessage, ELECTRIC_PROTOCOL_QUERY_PARAMS, type EventMessage, type ExternalHeadersRecord, type ExternalParamsRecord, FetchError, type GetExtensions, type IntervalColumn, type IntervalColumnWithPrecision, type LogMode, type MaybePromise, type Message, type MoveOutPattern, type MoveTag, type NormalizedPgSnapshot, type NumericColumn, type Offset, type Operation, type PostgresParams, type PostgresSnapshot, type RegularColumn, type Row, type Schema, type SerializedExpression, type SerializedOrderByClause, Shape, type ShapeChangedCallback, type ShapeData, ShapeStream, type ShapeStreamInterface, type ShapeStreamOptions, type SnapshotMetadata, type SubsetParams, type TimeColumn, type TypedMessages, type Value, type VarcharColumn, camelToSnake, compileExpression, compileOrderBy, createColumnMapper, isChangeMessage, isControlMessage, isVisibleInSnapshot, resolveValue, snakeCamelMapper, snakeToCamel };
|
package/dist/index.browser.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
`;t.forEach(
|
|
1
|
+
var Ts=Object.defineProperty,ws=Object.defineProperties;var Ps=Object.getOwnPropertyDescriptors;var Ve=Object.getOwnPropertySymbols;var Vt=Object.prototype.hasOwnProperty,Wt=Object.prototype.propertyIsEnumerable;var Qt=r=>{throw TypeError(r)};var Yt=(r,e,t)=>e in r?Ts(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,E=(r,e)=>{for(var t in e||(e={}))Vt.call(e,t)&&Yt(r,t,e[t]);if(Ve)for(var t of Ve(e))Wt.call(e,t)&&Yt(r,t,e[t]);return r},ce=(r,e)=>ws(r,Ps(e));var Kt=(r,e)=>{var t={};for(var s in r)Vt.call(r,s)&&e.indexOf(s)<0&&(t[s]=r[s]);if(r!=null&&Ve)for(var s of Ve(r))e.indexOf(s)<0&&Wt.call(r,s)&&(t[s]=r[s]);return t};var pt=(r,e,t)=>e.has(r)||Qt("Cannot "+t);var n=(r,e,t)=>(pt(r,e,"read from private field"),t?t.call(r):e.get(r)),d=(r,e,t)=>e.has(r)?Qt("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),c=(r,e,t,s)=>(pt(r,e,"write to private field"),s?s.call(r,t):e.set(r,t),t),p=(r,e,t)=>(pt(r,e,"access private method"),t);var ve=(r,e,t,s)=>({set _(i){c(r,e,i,t)},get _(){return n(r,e,s)}});var x=class r extends Error{constructor(t,s,i,o,a,h){super(h||`HTTP Error ${t} at ${a}: ${s!=null?s:JSON.stringify(i)}`);this.url=a;this.name="FetchError",this.status=t,this.text=s,this.json=i,this.headers=o}static async fromResponse(t,s){let i=t.status,o=Object.fromEntries([...t.headers.entries()]),a,h,u=t.headers.get("content-type");return t.bodyUsed||(u&&u.includes("application/json")?h=await t.json():a=await t.text()),new r(i,a,h,o,s)}},D=class extends Error{constructor(){super("Fetch with backoff aborted"),this.name="FetchBackoffAbortError"}};var We=class extends Error{constructor(){super("Invalid shape options: missing required url parameter"),this.name="MissingShapeUrlError"}},Qe=class extends Error{constructor(){super("Invalid signal option. It must be an instance of AbortSignal."),this.name="InvalidSignalError"}},Ke=class extends Error{constructor(){super("shapeHandle is required if this isn't an initial fetch (i.e. offset > -1)"),this.name="MissingShapeHandleError"}},ze=class extends Error{constructor(e){super(`Cannot use reserved Electric parameter names in custom params: ${e.join(", ")}`),this.name="ReservedParamError"}},Ge=class extends Error{constructor(e){super(`Column "${e!=null?e:"unknown"}" does not allow NULL values`),this.name="ParserNullValueError"}};var se=class extends Error{constructor(e,t){let s=`The response for the shape request to ${e} didn't include the following required headers:
|
|
2
|
+
`;t.forEach(i=>{s+=`- ${i}
|
|
3
3
|
`}),s+=`
|
|
4
4
|
This is often due to a proxy not setting CORS correctly so that all Electric headers can be read by the client.`,s+=`
|
|
5
|
-
For more information visit the troubleshooting guide: /docs/guides/troubleshooting/missing-headers`,super(s)}};var Ye=r=>Number(r),ys=r=>r==="true"||r==="t",Rs=r=>BigInt(r),Ft=r=>JSON.parse(r),bs=r=>r,As={int2:Ye,int4:Ye,int8:Rs,bool:ys,float4:Ye,float8:Ye,json:Ft,jsonb:Ft};function xs(r,e){let t=0,s=null,a="",o=!1,i=0,h;function u(l,g,R){let A=l.slice(g,R);return A=A==="NULL"?null:A,e?e(A):A}function m(l){let g=[];for(;t<l.length;t++){if(s=l[t],o)s==="\\"?a+=l[++t]:s==='"'?(g.push(e?e(a):a),a="",o=l[t+1]==='"',i=t+2):a+=s;else if(s==='"')o=!0;else if(s==="{")i=++t,g.push(m(l));else if(s==="}"){o=!1,i<t&&g.push(u(l,i,t)),i=t+1;break}else s===","&&h!=="}"&&h!=='"'&&(g.push(u(l,i,t)),i=t+1);h=s}return i<t&&g.push(g.push(u(l,i,t+1))),g}return m(r)[0]}var We=class{constructor(e,t){this.parser=S(S({},As),e),this.transformer=t}parse(e,t){return JSON.parse(e,(s,a)=>(s==="value"||s==="old_value")&&typeof a=="object"&&a!==null?this.transformMessageValue(a,t):a)}parseSnapshotData(e,t){return e.map(s=>{let a=s;return a.value&&typeof a.value=="object"&&a.value!==null&&(a.value=this.transformMessageValue(a.value,t)),a.old_value&&typeof a.old_value=="object"&&a.old_value!==null&&(a.old_value=this.transformMessageValue(a.old_value,t)),a})}transformMessageValue(e,t){let s=e;return Object.keys(s).forEach(a=>{s[a]=this.parseRow(a,s[a],t)}),this.transformer?this.transformer(s):s}parseRow(e,t,s){var g;let a=s[e];if(!a)return t;let l=a,{type:o,dims:i}=l,h=Nt(l,["type","dims"]),u=(g=this.parser[o])!=null?g:bs,m=Bt(u,a,e);return i&&i>0?Bt((A,E)=>xs(A,m),a,e)(t):m(t,h)}};function Bt(r,e,t){var a;let s=!((a=e.not_null)!=null&&a);return o=>{if(o===null){if(!s)throw new Ve(t!=null?t:"unknown");return null}return r(o,e)}}function qt(r){return`"${r.replace(/"/g,'""')}"`}function ot(r){var h,u,m,l;let e=(u=(h=r.match(/^_+/))==null?void 0:h[0])!=null?u:"",t=r.slice(e.length),s=(l=(m=t.match(/_+$/))==null?void 0:m[0])!=null?l:"",i=(s?t.slice(0,t.length-s.length):t).toLowerCase().replace(/_+([a-z])/g,(g,R)=>R.toUpperCase());return e+i+s}function jt(r){return r.replace(/([a-z])([A-Z])/g,"$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").toLowerCase()}function Vt(r){let e={};for(let[t,s]of Object.entries(r))e[s]=t;return{decode:t=>{var s;return(s=r[t])!=null?s:t},encode:t=>{var s;return(s=e[t])!=null?s:t}}}function Ke(r,e){if(!r||!e)return r!=null?r:"";let t=new Set(["SELECT","FROM","WHERE","AND","OR","NOT","IN","IS","NULL","NULLS","FIRST","LAST","TRUE","FALSE","LIKE","ILIKE","BETWEEN","ASC","DESC","LIMIT","OFFSET","ORDER","BY","GROUP","HAVING","DISTINCT","AS","ON","JOIN","LEFT","RIGHT","INNER","OUTER","CROSS","CASE","WHEN","THEN","ELSE","END","CAST","LOWER","UPPER","COALESCE","NULLIF"]),s=[],a=0;for(;a<r.length;){let h=r[a];if(h==="'"||h==='"'){let u=a,m=h;for(a++;a<r.length;)if(r[a]===m)if(r[a+1]===m)a+=2;else{a++;break}else a++;s.push({start:u,end:a})}else a++}let o=h=>s.some(u=>h>=u.start&&h<u.end),i=new RegExp("(?<![a-zA-Z0-9_])([a-zA-Z_][a-zA-Z0-9_]*)(?![a-zA-Z0-9_])","g");return r.replace(i,(h,u,m)=>o(m)||t.has(h.toUpperCase())||h.startsWith("$")?h:e(h))}function _s(r){if(r){let e={};for(let t of Object.keys(r))e[t]=ot(t);return Vt(e)}return{decode:e=>ot(e),encode:e=>jt(e)}}function ae(r){return"key"in r}function Qe(r){return!ae(r)}function ct(r){return Qe(r)&&r.headers.control==="up-to-date"}function Yt(r){if(r.headers.control!="up-to-date")return;let e=r.headers.global_last_seen_lsn;return e?`${e}_0`:void 0}function ht(r,e){let t=BigInt(r),s=BigInt(e.xmin),a=BigInt(e.xmax),o=e.xip_list.map(BigInt);return t<s||t<a&&!o.includes(t)}var Wt="electric-cursor",ye="electric-handle",$e="electric-offset",lt="electric-schema",Kt="electric-up-to-date",ut="columns",Ge="cursor",Re="expired_handle",ie="handle",L="live",oe="offset",Qt="table",$t="where",Gt="replica",zt="params",Jt="experimental_live_sse",dt="live_sse",ft="force-disconnect-and-refresh",pt="pause-stream",mt="log",be="subset__where",Ae="subset__limit",xe="subset__offset",_e="subset__order_by",Pe="subset__params",gt=[L,dt,ie,oe,Ge,Re,mt,be,Ae,xe,_e,Pe];var Ps=[429],Je={initialDelay:100,maxDelay:6e4,multiplier:1.3,maxRetries:1/0};function Ts(r){if(!r)return 0;let e=Number(r);if(Number.isFinite(e)&&e>0)return e*1e3;let t=Date.parse(r);if(!isNaN(t)){let s=t-Date.now();return Math.max(0,Math.min(s,36e5))}return 0}function Zt(r,e=Je){let{initialDelay:t,maxDelay:s,multiplier:a,debug:o=!1,onFailedAttempt:i,maxRetries:h=1/0}=e;return async(...u)=>{var A;let m=u[0],l=u[1],g=t,R=0;for(;;)try{let E=await r(...u);if(E.ok)return E;throw await x.fromResponse(E,m.toString())}catch(E){if(i==null||i(),(A=l==null?void 0:l.signal)!=null&&A.aborted)throw new O;if(E instanceof x&&!Ps.includes(E.status)&&E.status>=400&&E.status<500)throw E;{if(R++,R>h)throw o&&console.log(`Max retries reached (${R}/${h}), giving up`),E;let _=E instanceof x&&E.headers?Ts(E.headers["retry-after"]):0,J=Math.random()*g,He=Math.min(J,s),Ot=Math.max(_,He);if(o){let at=_>0?"server+client":"client";console.log(`Retry attempt #${R} after ${Ot}ms (${at}, serverMin=${_}ms, clientBackoff=${He}ms)`)}await new Promise(at=>setTimeout(at,Ot)),g=Math.min(g*a,s)}}}}var ws=[201,204,205];function Xt(r){return async(...e)=>{var a,o;let t=e[0],s=await r(...e);try{if(s.status<200||ws.includes(s.status))return s;let i=await s.text();return new Response(i,s)}catch(i){throw(o=(a=e[1])==null?void 0:a.signal)!=null&&o.aborted?new O:new x(s.status,void 0,void 0,Object.fromEntries([...s.headers.entries()]),t.toString(),i instanceof Error?i.message:typeof i=="string"?i:"failed to read body")}}}var Ms={maxChunksToPrefetch:2};function es(r,e=Ms){let{maxChunksToPrefetch:t}=e,s;return async(...o)=>{let i=o[0].toString(),h=s==null?void 0:s.consume(...o);if(h)return h;s==null||s.abort(),s=void 0;let u=await r(...o),m=St(i,u);return m&&(s=new Et({fetchClient:r,maxPrefetchedRequests:t,url:m,requestInit:o[1]})),u}}var vs=["electric-offset","electric-handle"],Cs=["electric-cursor"],ks=["electric-schema"];function ts(r){return async(...e)=>{let t=await r(...e);if(t.ok){let s=t.headers,a=[],o=l=>a.push(...l.filter(g=>!s.has(g))),h=e[0].toString(),u=new URL(h);if([be,Pe,Ae,xe,_e].some(l=>u.searchParams.has(l)))return t;if(o(vs),u.searchParams.get(L)==="true"&&o(Cs),(!u.searchParams.has(L)||u.searchParams.get(L)==="false")&&o(ks),a.length>0)throw new ne(h,a)}return t}}var Te,we,M,Z,D,ce,ze,Et=class{constructor(e){d(this,ce);d(this,Te);d(this,we);d(this,M,new Map);d(this,Z);d(this,D);var t;c(this,Te,(t=e.fetchClient)!=null?t:(...s)=>fetch(...s)),c(this,we,e.maxPrefetchedRequests),c(this,Z,e.url.toString()),c(this,D,n(this,Z)),p(this,ce,ze).call(this,e.url,e.requestInit)}abort(){n(this,M).forEach(([e,t])=>t.abort()),n(this,M).clear()}consume(...e){let t=e[0].toString(),s=n(this,M).get(t);if(!s||t!==n(this,Z))return;let[a,o]=s;if(o.signal.aborted){n(this,M).delete(t);return}return n(this,M).delete(t),a.then(i=>{let h=St(t,i);c(this,Z,h),n(this,D)&&!n(this,M).has(n(this,D))&&p(this,ce,ze).call(this,n(this,D),e[1])}).catch(()=>{}),a}};Te=new WeakMap,we=new WeakMap,M=new WeakMap,Z=new WeakMap,D=new WeakMap,ce=new WeakSet,ze=function(...e){var a,o;let t=e[0].toString();if(n(this,M).size>=n(this,we))return;let s=new AbortController;try{let{signal:i,cleanup:h}=Us(s,(a=e[1])==null?void 0:a.signal),u=n(this,Te).call(this,t,re(S({},(o=e[1])!=null?o:{}),{signal:i}));n(this,M).set(t,[u,s]),u.then(m=>{if(!m.ok||s.signal.aborted)return;let l=St(t,m);if(!l||l===t){c(this,D,void 0);return}return c(this,D,l),p(this,ce,ze).call(this,l,e[1])}).catch(()=>{}).finally(h)}catch(i){}};function St(r,e){let t=e.headers.get(ye),s=e.headers.get($e),a=e.headers.has(Kt);if(!t||!s||a)return;let o=new URL(r);if(o.searchParams.has(L))return;let i=o.searchParams.get(Re);if(i&&t===i){console.warn(`[Electric] Received stale cached response with expired shape handle. This should not happen and indicates a proxy/CDN caching misconfiguration. The response contained handle "${t}" 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.`);return}return o.searchParams.set(ie,t),o.searchParams.set(oe,s),o.searchParams.sort(),o.toString()}function Us(r,e){let t=Os;if(e)if(e.aborted)r.abort();else{let s=()=>r.abort();e.addEventListener("abort",s,{once:!0,signal:r.signal}),t=()=>e.removeEventListener("abort",s)}return{signal:r.signal,cleanup:t}}function Os(){}import{fetchEventSource as Ls}from"@microsoft/fetch-event-source";var yt=class{constructor(){this.data={};this.max=250;this.storageKey="electric_expired_shapes";this.load()}getExpiredHandle(e){let t=this.data[e];return t?(t.lastUsed=Date.now(),this.save(),t.expiredHandle):null}markExpired(e,t){this.data[e]={expiredHandle:t,lastUsed:Date.now()};let s=Object.keys(this.data);if(s.length>this.max){let a=s.reduce((o,i)=>this.data[i].lastUsed<this.data[o].lastUsed?i:o);delete this.data[a]}this.save()}save(){if(typeof localStorage!="undefined")try{localStorage.setItem(this.storageKey,JSON.stringify(this.data))}catch(e){}}load(){if(typeof localStorage!="undefined")try{let e=localStorage.getItem(this.storageKey);e&&(this.data=JSON.parse(e))}catch(e){this.data={}}}clear(){this.data={},this.save()}},Ze=new yt;var Rt=class{constructor(){this.data={};this.storageKey="electric_up_to_date_tracker";this.cacheTTL=6e4;this.maxEntries=250;this.writeThrottleMs=6e4;this.lastWriteTime=0;this.load(),this.cleanup()}recordUpToDate(e,t){this.data[e]={timestamp:Date.now(),cursor:t};let s=Object.keys(this.data);if(s.length>this.maxEntries){let a=s.reduce((o,i)=>this.data[i].timestamp<this.data[o].timestamp?i:o);delete this.data[a]}this.scheduleSave()}scheduleSave(){let e=Date.now(),t=e-this.lastWriteTime;if(t>=this.writeThrottleMs)this.lastWriteTime=e,this.save();else if(!this.pendingSaveTimer){let s=this.writeThrottleMs-t;this.pendingSaveTimer=setTimeout(()=>{this.lastWriteTime=Date.now(),this.pendingSaveTimer=void 0,this.save()},s)}}shouldEnterReplayMode(e){let t=this.data[e];return!t||Date.now()-t.timestamp>=this.cacheTTL?null:t.cursor}cleanup(){let e=Date.now(),t=Object.keys(this.data),s=!1;for(let a of t)e-this.data[a].timestamp>this.cacheTTL&&(delete this.data[a],s=!0);s&&this.save()}save(){if(typeof localStorage!="undefined")try{localStorage.setItem(this.storageKey,JSON.stringify(this.data))}catch(e){}}load(){if(typeof localStorage!="undefined")try{let e=localStorage.getItem(this.storageKey);e&&(this.data=JSON.parse(e))}catch(e){this.data={}}}clear(){this.data={},this.pendingSaveTimer&&(clearTimeout(this.pendingSaveTimer),this.pendingSaveTimer=void 0),this.save()}},bt=new Rt;var Xe=class{constructor(){this.activeSnapshots=new Map;this.xmaxSnapshots=new Map;this.snapshotsByDatabaseLsn=new Map}addSnapshot(e,t){var o,i,h,u;this.activeSnapshots.set(e.snapshot_mark,{xmin:BigInt(e.xmin),xmax:BigInt(e.xmax),xip_list:e.xip_list.map(BigInt),keys:t});let s=(i=(o=this.xmaxSnapshots.get(BigInt(e.xmax)))==null?void 0:o.add(e.snapshot_mark))!=null?i:new Set([e.snapshot_mark]);this.xmaxSnapshots.set(BigInt(e.xmax),s);let a=(u=(h=this.snapshotsByDatabaseLsn.get(BigInt(e.database_lsn)))==null?void 0:h.add(e.snapshot_mark))!=null?u:new Set([e.snapshot_mark]);this.snapshotsByDatabaseLsn.set(BigInt(e.database_lsn),a)}removeSnapshot(e){this.activeSnapshots.delete(e)}shouldRejectMessage(e){let t=e.headers.txids||[];if(t.length===0)return!1;let s=Math.max(...t);for(let[a,o]of this.xmaxSnapshots.entries())if(s>=a)for(let i of o)this.removeSnapshot(i);return[...this.activeSnapshots.values()].some(a=>a.keys.has(e.key)&&ht(s,a))}lastSeenUpdate(e){for(let[t,s]of this.snapshotsByDatabaseLsn.entries())if(t<=e)for(let a of s)this.removeSnapshot(a)}};var Ds=new Set([Ge,ie,L,oe]);async function Ct(r){return typeof r=="function"?r():r}async function Hs(r){let e=Object.entries(r),t=await Promise.all(e.map(async([s,a])=>{if(a===void 0)return[s,void 0];let o=await Ct(a);return[s,Array.isArray(o)?o.join(","):o]}));return Object.fromEntries(t.filter(([s,a])=>a!==void 0))}async function Is(r){if(!r)return{};let e=Object.entries(r),t=await Promise.all(e.map(async([s,a])=>[s,await Ct(a)]));return Object.fromEntries(t)}function Me(r){let e=new URL(r.origin+r.pathname);for(let[t,s]of r.searchParams)gt.includes(t)||e.searchParams.set(t,s);return e.searchParams.sort(),e.toString()}var he,le,ue,X,q,U,b,H,I,j,w,ee,C,P,V,N,de,k,te,F,fe,Y,pe,ke,W,B,me,se,K,Ue,Oe,Q,tt,ge,st,rt,Le,f,xt,ve,Ce,_t,rs,Pt,et,ns,as,is,Tt,wt,os,cs,Mt,vt,hs,ls,At=class{constructor(e){d(this,f);d(this,he,null);d(this,le);d(this,ue);d(this,X);d(this,q,new Map);d(this,U,!1);d(this,b,"active");d(this,H);d(this,I);d(this,j);d(this,w,!1);d(this,ee,!0);d(this,C,!1);d(this,P);d(this,V);d(this,N);d(this,de);d(this,k);d(this,te,!1);d(this,F);d(this,fe);d(this,Y);d(this,pe,Promise.resolve([]));d(this,ke,new Xe);d(this,W,0);d(this,B);d(this,me);d(this,se);d(this,K);d(this,Ue);d(this,Oe,1e3);d(this,Q,0);d(this,tt,3);d(this,ge,!1);d(this,st,100);d(this,rt,5e3);d(this,Le);var i,h,u,m;this.options=S({subscribe:!0},e),Ns(this.options),c(this,H,(i=this.options.offset)!=null?i:"-1"),c(this,I,""),c(this,P,this.options.handle);let t;if(e.columnMapper){let l=g=>{let R={};for(let[A,E]of Object.entries(g)){let _=e.columnMapper.decode(A);R[_]=E}return R};t=e.transformer?g=>e.transformer(l(g)):l}else t=e.transformer;c(this,X,new We(e.parser,t)),c(this,de,this.options.onError),c(this,V,(h=this.options.log)!=null?h:"full");let s=(u=e.fetchClient)!=null?u:(...l)=>fetch(...l),a=re(S({},(m=e.backoffOptions)!=null?m:Je),{onFailedAttempt:()=>{var l,g;c(this,C,!1),(g=(l=e.backoffOptions)==null?void 0:l.onFailedAttempt)==null||g.call(l)}}),o=Zt(s,a);c(this,ue,ts(es(o))),c(this,le,Xt(n(this,ue))),p(this,f,hs).call(this)}get shapeHandle(){return n(this,P)}get error(){return n(this,he)}get isUpToDate(){return n(this,w)}get lastOffset(){return n(this,H)}get mode(){return n(this,V)}subscribe(e,t=()=>{}){let s=Math.random();return n(this,q).set(s,[e,t]),n(this,U)||p(this,f,ve).call(this),()=>{n(this,q).delete(s)}}unsubscribeAll(){var e;n(this,q).clear(),(e=n(this,Le))==null||e.call(this)}lastSyncedAt(){return n(this,j)}lastSynced(){return n(this,j)===void 0?1/0:Date.now()-n(this,j)}isConnected(){return n(this,C)}isLoading(){return!n(this,w)}hasStarted(){return n(this,U)}isPaused(){return n(this,b)==="paused"}async forceDisconnectAndRefresh(){var e,t;c(this,te,!0),n(this,w)&&!((e=n(this,k))!=null&&e.signal.aborted)&&((t=n(this,k))==null||t.abort(ft)),await p(this,f,os).call(this),c(this,te,!1)}async requestSnapshot(e){if(n(this,V)==="full")throw new Error(`Snapshot requests are not supported in ${n(this,V)} mode, as the consumer is guaranteed to observe all data`);n(this,U)||await p(this,f,ve).call(this),await p(this,f,cs).call(this),Ne(this,W)._++;try{n(this,W)===1&&p(this,f,Tt).call(this);let{metadata:t,data:s}=await this.fetchSnapshot(e),a=s.concat([{headers:S({control:"snapshot-end"},t)},{headers:S({control:"subset-end"},e)}]);return n(this,ke).addSnapshot(t,new Set(s.map(o=>o.key))),p(this,f,et).call(this,a,!1),{metadata:t,data:s}}finally{Ne(this,W)._--,n(this,W)===0&&p(this,f,wt).call(this)}}async fetchSnapshot(e){var m;let{fetchUrl:t,requestHeaders:s}=await p(this,f,_t).call(this,this.options.url,!0,e),a=await n(this,le).call(this,t.toString(),{headers:s});if(!a.ok)throw new x(a.status,void 0,void 0,Object.fromEntries([...a.headers.entries()]),t.toString());let o=(m=n(this,N))!=null?m:ss(a.headers,{required:!0,url:t.toString()}),{metadata:i,data:h}=await a.json(),u=n(this,X).parseSnapshotData(h,o);return{metadata:i,data:u}}};he=new WeakMap,le=new WeakMap,ue=new WeakMap,X=new WeakMap,q=new WeakMap,U=new WeakMap,b=new WeakMap,H=new WeakMap,I=new WeakMap,j=new WeakMap,w=new WeakMap,ee=new WeakMap,C=new WeakMap,P=new WeakMap,V=new WeakMap,N=new WeakMap,de=new WeakMap,k=new WeakMap,te=new WeakMap,F=new WeakMap,fe=new WeakMap,Y=new WeakMap,pe=new WeakMap,ke=new WeakMap,W=new WeakMap,B=new WeakMap,me=new WeakMap,se=new WeakMap,K=new WeakMap,Ue=new WeakMap,Oe=new WeakMap,Q=new WeakMap,tt=new WeakMap,ge=new WeakMap,st=new WeakMap,rt=new WeakMap,Le=new WeakMap,f=new WeakSet,xt=function(){return n(this,se)!==void 0},ve=async function(){var e,t,s,a,o;c(this,U,!0);try{await p(this,f,Ce).call(this)}catch(i){if(c(this,he,i),n(this,de)){let h=await n(this,de).call(this,i);if(h&&typeof h=="object"){h.params&&(this.options.params=S(S({},(e=this.options.params)!=null?e:{}),h.params)),h.headers&&(this.options.headers=S(S({},(t=this.options.headers)!=null?t:{}),h.headers)),c(this,he,null),c(this,U,!1),await p(this,f,ve).call(this);return}i instanceof Error&&p(this,f,vt).call(this,i),c(this,C,!1),(s=n(this,Y))==null||s.call(this);return}throw i instanceof Error&&p(this,f,vt).call(this,i),c(this,C,!1),(a=n(this,Y))==null||a.call(this),i}c(this,C,!1),(o=n(this,Y))==null||o.call(this)},Ce=async function(){var u,m;if(n(this,b)==="pause-requested"){c(this,b,"paused");return}if(!this.options.subscribe&&((u=this.options.signal)!=null&&u.aborted||n(this,w)))return;let e=n(this,b)==="paused";c(this,b,"active");let{url:t,signal:s}=this.options,{fetchUrl:a,requestHeaders:o}=await p(this,f,_t).call(this,t,e),i=await p(this,f,rs).call(this,s),h=n(this,k);try{await p(this,f,ns).call(this,{fetchUrl:a,requestAbortController:h,headers:o,resumingFromPause:e})}catch(l){if((l instanceof x||l instanceof O)&&h.signal.aborted&&h.signal.reason===ft)return p(this,f,Ce).call(this);if(l instanceof O){let g=n(this,b);h.signal.aborted&&h.signal.reason===pt&&g==="pause-requested"&&c(this,b,"paused");return}if(!(l instanceof x))throw l;if(l.status==409){if(n(this,P)){let R=Me(a);Ze.markExpired(R,n(this,P))}let g=l.headers[ye]||`${n(this,P)}-next`;return p(this,f,ls).call(this,g),await p(this,f,Mt).call(this,Array.isArray(l.json)?l.json:[l.json]),p(this,f,Ce).call(this)}else throw l}finally{i&&s&&s.removeEventListener("abort",i),c(this,k,void 0)}return(m=n(this,fe))==null||m.call(this),p(this,f,Ce).call(this)},_t=async function(e,t,s){var l,g,R,A;let[a,o]=await Promise.all([Is(this.options.headers),this.options.params?Hs(Fs(this.options.params)):void 0]);o&&us(o);let i=new URL(e);if(o){if(o.table&&v(i,Qt,o.table),o.where&&typeof o.where=="string"){let _=Ke(o.where,(l=this.options.columnMapper)==null?void 0:l.encode);v(i,$t,_)}if(o.columns){let _=await Ct((g=this.options.params)==null?void 0:g.columns);if(Array.isArray(_)){let J=_.map(String);this.options.columnMapper&&(J=J.map(this.options.columnMapper.encode));let He=J.map(qt).join(",");v(i,ut,He)}else v(i,ut,o.columns)}o.replica&&v(i,Gt,o.replica),o.params&&v(i,zt,o.params);let E=S({},o);delete E.table,delete E.where,delete E.columns,delete E.replica,delete E.params;for(let[_,J]of Object.entries(E))v(i,_,J)}if(s){if(s.where&&typeof s.where=="string"){let E=Ke(s.where,(R=this.options.columnMapper)==null?void 0:R.encode);v(i,be,E)}if(s.params&&i.searchParams.set(Pe,JSON.stringify(s.params)),s.limit&&v(i,Ae,s.limit),s.offset&&v(i,xe,s.offset),s.orderBy&&typeof s.orderBy=="string"){let E=Ke(s.orderBy,(A=this.options.columnMapper)==null?void 0:A.encode);v(i,_e,E)}}i.searchParams.set(oe,n(this,H)),i.searchParams.set(mt,n(this,V));let h=s!==void 0;n(this,w)&&!h&&(!n(this,te)&&!t&&i.searchParams.set(L,"true"),i.searchParams.set(Ge,n(this,I))),n(this,P)&&i.searchParams.set(ie,n(this,P));let u=Me(i),m=Ze.getExpiredHandle(u);return m&&i.searchParams.set(Re,m),i.searchParams.sort(),{fetchUrl:i,requestHeaders:a}},rs=async function(e){var t;if(c(this,k,new AbortController),e){let s=()=>{var a;(a=n(this,k))==null||a.abort(e.reason)};return e.addEventListener("abort",s,{once:!0}),e.aborted&&((t=n(this,k))==null||t.abort(e.reason)),s}},Pt=async function(e){var h;let{headers:t,status:s}=e,a=t.get(ye);if(a){let u=n(this,K)?Me(n(this,K)):null,m=u?Ze.getExpiredHandle(u):null;a!==m?c(this,P,a):console.warn(`[Electric] Received stale cached response with expired shape handle. This should not happen and indicates a proxy/CDN caching misconfiguration. The response contained handle "${a}" 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 "${n(this,P)}".`)}let o=t.get($e);o&&c(this,H,o);let i=t.get(Wt);i&&c(this,I,i),c(this,N,(h=n(this,N))!=null?h:ss(t)),s===204&&c(this,j,Date.now())},et=async function(e,t=!1){var s;if(e.length>0){c(this,ee,!0);let a=e[e.length-1];if(ct(a)){if(t){let i=Yt(a);i&&c(this,H,i)}if(c(this,j,Date.now()),c(this,w,!0),c(this,ee,!1),(s=n(this,me))==null||s.call(this),n(this,f,xt)&&!t&&n(this,I)===n(this,se))return;if(c(this,se,void 0),n(this,K)){let i=Me(n(this,K));bt.recordUpToDate(i,n(this,I))}}let o=e.filter(i=>ae(i)?!n(this,ke).shouldRejectMessage(i):!0);await p(this,f,Mt).call(this,o)}},ns=async function(e){var s;if(c(this,K,e.fetchUrl),!n(this,w)&&!n(this,f,xt)){let a=Me(e.fetchUrl),o=bt.shouldEnterReplayMode(a);o&&c(this,se,o)}let t=(s=this.options.liveSse)!=null?s:this.options.experimentalLiveSse;return n(this,w)&&t&&!n(this,te)&&!e.resumingFromPause&&!n(this,ge)?(e.fetchUrl.searchParams.set(Jt,"true"),e.fetchUrl.searchParams.set(dt,"true"),p(this,f,is).call(this,e)):p(this,f,as).call(this,e)},as=async function(e){let{fetchUrl:t,requestAbortController:s,headers:a}=e,o=await n(this,le).call(this,t.toString(),{signal:s.signal,headers:a});c(this,C,!0),await p(this,f,Pt).call(this,o);let i=n(this,N),u=await o.text()||"[]",m=n(this,X).parse(u,i);await p(this,f,et).call(this,m)},is=async function(e){let{fetchUrl:t,requestAbortController:s,headers:a}=e,o=n(this,ue);c(this,Ue,Date.now());let i=re(S({},a),{Accept:"text/event-stream"});try{let h=[];await Ls(t.toString(),{headers:i,fetch:o,onopen:async u=>{c(this,C,!0),await p(this,f,Pt).call(this,u)},onmessage:u=>{if(u.data){let m=n(this,N),l=n(this,X).parse(u.data,m);h.push(l),ct(l)&&(p(this,f,et).call(this,h,!0),h=[])}},onerror:u=>{throw u},signal:s.signal})}catch(h){throw s.signal.aborted?new O:h}finally{let h=Date.now()-n(this,Ue),u=s.signal.aborted;if(h<n(this,Oe)&&!u)if(Ne(this,Q)._++,n(this,Q)>=n(this,tt))c(this,ge,!0),console.warn("[Electric] SSE connections are closing immediately (possibly due to proxy buffering or misconfiguration). Falling back to long polling. Your proxy must support streaming SSE responses (not buffer the complete response). Configuration: Nginx add 'X-Accel-Buffering: no', Caddy add 'flush_interval -1' to reverse_proxy. Note: Do NOT disable caching entirely - Electric uses cache headers to enable request collapsing for efficiency.");else{let m=Math.min(n(this,rt),n(this,st)*Math.pow(2,n(this,Q))),l=Math.floor(Math.random()*m);await new Promise(g=>setTimeout(g,l))}else h>=n(this,Oe)&&c(this,Q,0)}},Tt=function(){var e;n(this,U)&&n(this,b)==="active"&&(c(this,b,"pause-requested"),(e=n(this,k))==null||e.abort(pt))},wt=function(){var e;if(n(this,U)&&(n(this,b)==="paused"||n(this,b)==="pause-requested")){if((e=this.options.signal)!=null&&e.aborted)return;n(this,b)==="pause-requested"&&c(this,b,"active"),p(this,f,ve).call(this)}},os=async function(){return n(this,F)?n(this,F):(c(this,F,new Promise((e,t)=>{c(this,fe,e),c(this,Y,t)})),n(this,F).finally(()=>{c(this,F,void 0),c(this,fe,void 0),c(this,Y,void 0)}),n(this,F))},cs=async function(){if(n(this,ee))return n(this,B)?n(this,B):(c(this,B,new Promise(e=>{c(this,me,e)})),n(this,B).finally(()=>{c(this,B,void 0),c(this,me,void 0)}),n(this,B))},Mt=async function(e){return c(this,pe,n(this,pe).then(()=>Promise.all(Array.from(n(this,q).values()).map(async([t,s])=>{try{await t(e)}catch(a){queueMicrotask(()=>{throw a})}})))),n(this,pe)},vt=function(e){n(this,q).forEach(([t,s])=>{s==null||s(e)})},hs=function(){if(typeof document=="object"&&typeof document.hidden=="boolean"&&typeof document.addEventListener=="function"){let e=()=>{document.hidden?p(this,f,Tt).call(this):p(this,f,wt).call(this)};document.addEventListener("visibilitychange",e),c(this,Le,()=>{document.removeEventListener("visibilitychange",e)})}},ls=function(e){c(this,H,"-1"),c(this,I,""),c(this,P,e),c(this,w,!1),c(this,ee,!0),c(this,C,!1),c(this,N,void 0),c(this,W,0),c(this,Q,0),c(this,ge,!1)},At.Replica={FULL:"full",DEFAULT:"default"};function ss(r,e){let t=r.get(lt);if(!t){if(e!=null&&e.required&&(e!=null&&e.url))throw new ne(e.url,[lt]);return{}}return JSON.parse(t)}function us(r){if(!r)return;let e=Object.keys(r).filter(t=>Ds.has(t));if(e.length>0)throw new je(e)}function Ns(r){if(!r.url)throw new Fe;if(r.signal&&!(r.signal instanceof AbortSignal))throw new Be;if(r.offset!==void 0&&r.offset!=="-1"&&r.offset!=="now"&&!r.handle)throw new qe;us(r.params)}function v(r,e,t){if(!(t===void 0||t==null))if(typeof t=="string")r.searchParams.set(e,t);else if(typeof t=="object")for(let[s,a]of Object.entries(t))r.searchParams.set(`${e}[${s}]`,a);else r.searchParams.set(e,t.toString())}function Fs(r){return Array.isArray(r.params)?re(S({},r),{params:Object.fromEntries(r.params.map((e,t)=>[t+1,e]))}):r}var T,$,G,De,Ee,Se,z,y,fs,ps,kt,nt,ms,Ut,ds=class{constructor(e){d(this,y);d(this,T,new Map);d(this,$,new Map);d(this,G,new Set);d(this,De,new Set);d(this,Ee,!1);d(this,Se,"syncing");d(this,z,!1);this.stream=e,this.stream.subscribe(p(this,y,fs).bind(this),p(this,y,ms).bind(this))}get isUpToDate(){return n(this,Se)==="up-to-date"}get lastOffset(){return this.stream.lastOffset}get handle(){return this.stream.shapeHandle}get rows(){return this.value.then(e=>Array.from(e.values()))}get currentRows(){return Array.from(this.currentValue.values())}get value(){return new Promise((e,t)=>{if(this.stream.isUpToDate)e(this.currentValue);else{let s=this.subscribe(({value:a})=>{s(),n(this,z)&&t(n(this,z)),e(a)})}})}get currentValue(){return n(this,T)}get error(){return n(this,z)}lastSyncedAt(){return this.stream.lastSyncedAt()}lastSynced(){return this.stream.lastSynced()}isLoading(){return this.stream.isLoading()}isConnected(){return this.stream.isConnected()}get mode(){return this.stream.mode}async requestSnapshot(e){let t=JSON.stringify(e);n(this,De).add(t),await p(this,y,kt).call(this),await this.stream.requestSnapshot(e)}subscribe(e){let t=Math.random();return n(this,$).set(t,e),()=>{n(this,$).delete(t)}}unsubscribeAll(){n(this,$).clear()}get numSubscribers(){return n(this,$).size}};T=new WeakMap,$=new WeakMap,G=new WeakMap,De=new WeakMap,Ee=new WeakMap,Se=new WeakMap,z=new WeakMap,y=new WeakSet,fs=function(e){let t=!1;e.forEach(s=>{if(ae(s))if(t=p(this,y,nt).call(this,"syncing"),this.mode==="full")switch(s.headers.operation){case"insert":n(this,T).set(s.key,s.value);break;case"update":n(this,T).set(s.key,S(S({},n(this,T).get(s.key)),s.value));break;case"delete":n(this,T).delete(s.key);break}else switch(s.headers.operation){case"insert":n(this,G).add(s.key),n(this,T).set(s.key,s.value);break;case"update":n(this,G).has(s.key)&&n(this,T).set(s.key,S(S({},n(this,T).get(s.key)),s.value));break;case"delete":n(this,G).has(s.key)&&(n(this,T).delete(s.key),n(this,G).delete(s.key));break}if(Qe(s))switch(s.headers.control){case"up-to-date":t=p(this,y,nt).call(this,"up-to-date"),n(this,Ee)&&(c(this,Ee,!1),p(this,y,ps).call(this));break;case"must-refetch":n(this,T).clear(),n(this,G).clear(),c(this,z,!1),t=p(this,y,nt).call(this,"syncing"),c(this,Ee,!0);break}}),t&&p(this,y,Ut).call(this)},ps=async function(){await p(this,y,kt).call(this),await Promise.all(Array.from(n(this,De)).map(async e=>{try{let t=JSON.parse(e);await this.stream.requestSnapshot(t)}catch(t){}}))},kt=async function(){this.stream.isUpToDate||await new Promise(e=>{let t=()=>{this.stream.isUpToDate&&(clearInterval(s),a(),e())},s=setInterval(t,10),a=this.stream.subscribe(()=>t(),()=>t());t()})},nt=function(e){let t=n(this,Se)!==e;return c(this,Se,e),t&&e==="up-to-date"},ms=function(e){e instanceof x&&(c(this,z,e),p(this,y,Ut).call(this))},Ut=function(){n(this,$).forEach(e=>{e({value:this.currentValue,rows:this.currentRows})})};export{Je as BackoffDefaults,gt as ELECTRIC_PROTOCOL_QUERY_PARAMS,x as FetchError,ds as Shape,At as ShapeStream,jt as camelToSnake,Vt as createColumnMapper,ae as isChangeMessage,Qe as isControlMessage,ht as isVisibleInSnapshot,Ct as resolveValue,_s as snakeCamelMapper,ot as snakeToCamel};
|
|
5
|
+
For more information visit the troubleshooting guide: /docs/guides/troubleshooting/missing-headers`,super(s)}},Me=class extends Error{constructor(e){super(e),this.name="StaleCacheError"}};var Je=r=>Number(r),vs=r=>r==="true"||r==="t",Ms=r=>BigInt(r),zt=r=>JSON.parse(r),Cs=r=>r,ks={int2:Je,int4:Je,int8:Ms,bool:vs,float4:Je,float8:Je,json:zt,jsonb:zt};function Us(r,e){let t=0,s=null,i="",o=!1,a=0,h;function u(l,g,S){let _=l.slice(g,S);return _=_==="NULL"?null:_,e?e(_):_}function m(l){let g=[];for(;t<l.length;t++){if(s=l[t],o)s==="\\"?i+=l[++t]:s==='"'?(g.push(e?e(i):i),i="",o=l[t+1]==='"',a=t+2):i+=s;else if(s==='"')o=!0;else if(s==="{")a=++t,g.push(m(l));else if(s==="}"){o=!1,a<t&&g.push(u(l,a,t)),a=t+1;break}else s===","&&h!=="}"&&h!=='"'&&(g.push(u(l,a,t)),a=t+1);h=s}return a<t&&g.push(g.push(u(l,a,t+1))),g}return m(r)[0]}var Xe=class{constructor(e,t){this.parser=E(E({},ks),e),this.transformer=t}parse(e,t){return JSON.parse(e,(s,i)=>(s==="value"||s==="old_value")&&typeof i=="object"&&i!==null?this.transformMessageValue(i,t):i)}parseSnapshotData(e,t){return e.map(s=>{let i=s;return i.value&&typeof i.value=="object"&&i.value!==null&&(i.value=this.transformMessageValue(i.value,t)),i.old_value&&typeof i.old_value=="object"&&i.old_value!==null&&(i.old_value=this.transformMessageValue(i.old_value,t)),i})}transformMessageValue(e,t){let s=e;return Object.keys(s).forEach(i=>{s[i]=this.parseRow(i,s[i],t)}),this.transformer?this.transformer(s):s}parseRow(e,t,s){var g;let i=s[e];if(!i)return t;let l=i,{type:o,dims:a}=l,h=Kt(l,["type","dims"]),u=(g=this.parser[o])!=null?g:Cs,m=Gt(u,i,e);return a&&a>0?Gt((_,y)=>Us(_,m),i,e)(t):m(t,h)}};function Gt(r,e,t){var i;let s=!((i=e.not_null)!=null&&i);return o=>{if(o===null){if(!s)throw new Ge(t!=null?t:"unknown");return null}return r(o,e)}}function Ce(r){return`"${r.replace(/"/g,'""')}"`}function mt(r){var h,u,m,l;let e=(u=(h=r.match(/^_+/))==null?void 0:h[0])!=null?u:"",t=r.slice(e.length),s=(l=(m=t.match(/_+$/))==null?void 0:m[0])!=null?l:"",a=(s?t.slice(0,t.length-s.length):t).toLowerCase().replace(/_+([a-z])/g,(g,S)=>S.toUpperCase());return e+a+s}function Jt(r){return r.replace(/([a-z])([A-Z])/g,"$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").toLowerCase()}function Xt(r){let e={};for(let[t,s]of Object.entries(r))e[s]=t;return{decode:t=>{var s;return(s=r[t])!=null?s:t},encode:t=>{var s;return(s=e[t])!=null?s:t}}}function Ze(r,e){if(!r||!e)return r!=null?r:"";let t=new Set(["SELECT","FROM","WHERE","AND","OR","NOT","IN","IS","NULL","NULLS","FIRST","LAST","TRUE","FALSE","LIKE","ILIKE","BETWEEN","ASC","DESC","LIMIT","OFFSET","ORDER","BY","GROUP","HAVING","DISTINCT","AS","ON","JOIN","LEFT","RIGHT","INNER","OUTER","CROSS","CASE","WHEN","THEN","ELSE","END","CAST","LOWER","UPPER","COALESCE","NULLIF"]),s=[],i=0;for(;i<r.length;){let h=r[i];if(h==="'"||h==='"'){let u=i,m=h;for(i++;i<r.length;)if(r[i]===m)if(r[i+1]===m)i+=2;else{i++;break}else i++;s.push({start:u,end:i})}else i++}let o=h=>s.some(u=>h>=u.start&&h<u.end),a=new RegExp("(?<![a-zA-Z0-9_])([a-zA-Z_][a-zA-Z0-9_]*)(?![a-zA-Z0-9_])","g");return r.replace(a,(h,u,m)=>o(m)||t.has(h.toUpperCase())||h.startsWith("$")?h:e(h))}function Os(r){if(r){let e={};for(let t of Object.keys(r))e[t]=mt(t);return Xt(e)}return{decode:e=>mt(e),encode:e=>Jt(e)}}function he(r){return"key"in r}function et(r){return!he(r)}function gt(r){return et(r)&&r.headers.control==="up-to-date"}function Zt(r){if(r.headers.control!="up-to-date")return;let e=r.headers.global_last_seen_lsn;return e?`${e}_0`:void 0}function Et(r,e){let t=BigInt(r),s=BigInt(e.xmin),i=BigInt(e.xmax),o=e.xip_list.map(BigInt);return t<s||t<i&&!o.includes(t)}var es="electric-cursor",ke="electric-handle",tt="electric-offset",St="electric-schema",ts="electric-up-to-date",yt="columns",st="cursor",Ue="expired_handle",le="handle",H="live",ue="offset",ss="table",rs="where",ns="replica",is="params",as="experimental_live_sse",Rt="live_sse",bt="force-disconnect-and-refresh",At="pause-stream",_t="log",de="subset__where",Oe="subset__limit",Le="subset__offset",fe="subset__order_by",De="subset__params",xt="subset__where_expr",Tt="subset__order_by_expr",rt="cache-buster",wt=[H,Rt,le,ue,st,Ue,_t,de,Oe,Le,fe,De,xt,Tt,rt];var Ls=[429],it={initialDelay:100,maxDelay:6e4,multiplier:1.3,maxRetries:1/0};function Ds(r){if(!r)return 0;let e=Number(r);if(Number.isFinite(e)&&e>0)return e*1e3;let t=Date.parse(r);if(!isNaN(t)){let s=t-Date.now();return Math.max(0,Math.min(s,36e5))}return 0}function os(r,e=it){let{initialDelay:t,maxDelay:s,multiplier:i,debug:o=!1,onFailedAttempt:a,maxRetries:h=1/0}=e;return async(...u)=>{var _;let m=u[0],l=u[1],g=t,S=0;for(;;)try{let y=await r(...u);if(y.ok)return y;throw await x.fromResponse(y,m.toString())}catch(y){if(a==null||a(),(_=l==null?void 0:l.signal)!=null&&_.aborted)throw new D;if(y instanceof x&&!Ls.includes(y.status)&&y.status>=400&&y.status<500)throw y;{if(S++,S>h)throw o&&console.log(`Max retries reached (${S}/${h}), giving up`),y;let O=y instanceof x&&y.headers?Ds(y.headers["retry-after"]):0,b=Math.random()*g,L=Math.min(b,s),V=Math.max(O,L);if(o){let Pe=O>0?"server+client":"client";console.log(`Retry attempt #${S} after ${V}ms (${Pe}, serverMin=${O}ms, clientBackoff=${L}ms)`)}await new Promise(Pe=>setTimeout(Pe,V)),g=Math.min(g*i,s)}}}}var Hs=[201,204,205];function cs(r){return async(...e)=>{var i,o;let t=e[0],s=await r(...e);try{if(s.status<200||Hs.includes(s.status))return s;let a=await s.text();return new Response(a,s)}catch(a){throw(o=(i=e[1])==null?void 0:i.signal)!=null&&o.aborted?new D:new x(s.status,void 0,void 0,Object.fromEntries([...s.headers.entries()]),t.toString(),a instanceof Error?a.message:typeof a=="string"?a:"failed to read body")}}}var Is={maxChunksToPrefetch:2};function hs(r,e=Is){let{maxChunksToPrefetch:t}=e,s;return async(...o)=>{let a=o[0].toString(),h=s==null?void 0:s.consume(...o);if(h)return h;s==null||s.abort(),s=void 0;let u=await r(...o),m=vt(a,u);return m&&(s=new Pt({fetchClient:r,maxPrefetchedRequests:t,url:m,requestInit:o[1]})),u}}var Ns=["electric-offset","electric-handle"],Bs=["electric-cursor"],Fs=["electric-schema"];function ls(r){return async(...e)=>{let t=await r(...e);if(t.ok){let s=t.headers,i=[],o=l=>i.push(...l.filter(g=>!s.has(g))),h=e[0].toString(),u=new URL(h);if([de,De,Oe,Le,fe].some(l=>u.searchParams.has(l)))return t;if(o(Ns),u.searchParams.get(H)==="true"&&o(Bs),(!u.searchParams.has(H)||u.searchParams.get(H)==="false")&&o(Fs),i.length>0)throw new se(h,i)}return t}}var He,Ie,M,re,I,pe,nt,Pt=class{constructor(e){d(this,pe);d(this,He);d(this,Ie);d(this,M,new Map);d(this,re);d(this,I);var t;c(this,He,(t=e.fetchClient)!=null?t:(...s)=>fetch(...s)),c(this,Ie,e.maxPrefetchedRequests),c(this,re,e.url.toString()),c(this,I,n(this,re)),p(this,pe,nt).call(this,e.url,e.requestInit)}abort(){n(this,M).forEach(([e,t])=>t.abort()),n(this,M).clear()}consume(...e){let t=e[0].toString(),s=n(this,M).get(t);if(!s||t!==n(this,re))return;let[i,o]=s;if(o.signal.aborted){n(this,M).delete(t);return}return n(this,M).delete(t),i.then(a=>{let h=vt(t,a);c(this,re,h),n(this,I)&&!n(this,M).has(n(this,I))&&p(this,pe,nt).call(this,n(this,I),e[1])}).catch(()=>{}),i}};He=new WeakMap,Ie=new WeakMap,M=new WeakMap,re=new WeakMap,I=new WeakMap,pe=new WeakSet,nt=function(...e){var i,o;let t=e[0].toString();if(n(this,M).size>=n(this,Ie))return;let s=new AbortController;try{let{signal:a,cleanup:h}=qs(s,(i=e[1])==null?void 0:i.signal),u=n(this,He).call(this,t,ce(E({},(o=e[1])!=null?o:{}),{signal:a}));n(this,M).set(t,[u,s]),u.then(m=>{if(!m.ok||s.signal.aborted)return;let l=vt(t,m);if(!l||l===t){c(this,I,void 0);return}return c(this,I,l),p(this,pe,nt).call(this,l,e[1])}).catch(()=>{}).finally(h)}catch(a){}};function vt(r,e){let t=e.headers.get(ke),s=e.headers.get(tt),i=e.headers.has(ts);if(!t||!s||i)return;let o=new URL(r);if(o.searchParams.has(H))return;let a=o.searchParams.get(Ue);if(a&&t===a){console.warn(`[Electric] Received stale cached response with expired shape handle. This should not happen and indicates a proxy/CDN caching misconfiguration. The response contained handle "${t}" 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.`);return}return o.searchParams.set(le,t),o.searchParams.set(ue,s),o.searchParams.sort(),o.toString()}function qs(r,e){let t=$s;if(e)if(e.aborted)r.abort();else{let s=()=>r.abort();e.addEventListener("abort",s,{once:!0,signal:r.signal}),t=()=>e.removeEventListener("abort",s)}return{signal:r.signal,cleanup:t}}function $s(){}function at(r,e){switch(r.type){case"ref":{let t=e?e(r.column):r.column;return Ce(t)}case"val":return`$${r.paramIndex}`;case"func":return js(r,e);default:{let t=r;throw new Error(`Unknown expression type: ${JSON.stringify(t)}`)}}}function js(r,e){let t=r.args.map(s=>at(s,e));switch(r.name){case"eq":return`${t[0]} = ${t[1]}`;case"gt":return`${t[0]} > ${t[1]}`;case"gte":return`${t[0]} >= ${t[1]}`;case"lt":return`${t[0]} < ${t[1]}`;case"lte":return`${t[0]} <= ${t[1]}`;case"and":return t.map(s=>`(${s})`).join(" AND ");case"or":return t.map(s=>`(${s})`).join(" OR ");case"not":return`NOT (${t[0]})`;case"in":return`${t[0]} = ANY(${t[1]})`;case"like":return`${t[0]} LIKE ${t[1]}`;case"ilike":return`${t[0]} ILIKE ${t[1]}`;case"isNull":case"isUndefined":return`${t[0]} IS NULL`;case"upper":return`UPPER(${t[0]})`;case"lower":return`LOWER(${t[0]})`;case"length":return`LENGTH(${t[0]})`;case"concat":return`CONCAT(${t.join(", ")})`;case"coalesce":return`COALESCE(${t.join(", ")})`;default:throw new Error(`Unknown function: ${r.name}`)}}function Mt(r,e){return r.map(t=>{let s=e?e(t.column):t.column,i=Ce(s);return t.direction==="desc"&&(i+=" DESC"),t.nulls==="first"&&(i+=" NULLS FIRST"),t.nulls==="last"&&(i+=" NULLS LAST"),i}).join(", ")}import{fetchEventSource as Ys}from"@microsoft/fetch-event-source";var Ct=class{constructor(){this.data={};this.max=250;this.storageKey="electric_expired_shapes";this.load()}getExpiredHandle(e){let t=this.data[e];return t?(t.lastUsed=Date.now(),this.save(),t.expiredHandle):null}markExpired(e,t){this.data[e]={expiredHandle:t,lastUsed:Date.now()};let s=Object.keys(this.data);if(s.length>this.max){let i=s.reduce((o,a)=>this.data[a].lastUsed<this.data[o].lastUsed?a:o);delete this.data[i]}this.save()}save(){if(typeof localStorage!="undefined")try{localStorage.setItem(this.storageKey,JSON.stringify(this.data))}catch(e){}}load(){if(typeof localStorage!="undefined")try{let e=localStorage.getItem(this.storageKey);e&&(this.data=JSON.parse(e))}catch(e){this.data={}}}clear(){this.data={},this.save()}},ot=new Ct;var kt=class{constructor(){this.data={};this.storageKey="electric_up_to_date_tracker";this.cacheTTL=6e4;this.maxEntries=250;this.writeThrottleMs=6e4;this.lastWriteTime=0;this.load(),this.cleanup()}recordUpToDate(e,t){this.data[e]={timestamp:Date.now(),cursor:t};let s=Object.keys(this.data);if(s.length>this.maxEntries){let i=s.reduce((o,a)=>this.data[a].timestamp<this.data[o].timestamp?a:o);delete this.data[i]}this.scheduleSave()}scheduleSave(){let e=Date.now(),t=e-this.lastWriteTime;if(t>=this.writeThrottleMs)this.lastWriteTime=e,this.save();else if(!this.pendingSaveTimer){let s=this.writeThrottleMs-t;this.pendingSaveTimer=setTimeout(()=>{this.lastWriteTime=Date.now(),this.pendingSaveTimer=void 0,this.save()},s)}}shouldEnterReplayMode(e){let t=this.data[e];return!t||Date.now()-t.timestamp>=this.cacheTTL?null:t.cursor}cleanup(){let e=Date.now(),t=Object.keys(this.data),s=!1;for(let i of t)e-this.data[i].timestamp>this.cacheTTL&&(delete this.data[i],s=!0);s&&this.save()}save(){if(typeof localStorage!="undefined")try{localStorage.setItem(this.storageKey,JSON.stringify(this.data))}catch(e){}}load(){if(typeof localStorage!="undefined")try{let e=localStorage.getItem(this.storageKey);e&&(this.data=JSON.parse(e))}catch(e){this.data={}}}clear(){this.data={},this.pendingSaveTimer&&(clearTimeout(this.pendingSaveTimer),this.pendingSaveTimer=void 0),this.save()}},Ut=new kt;var ct=class{constructor(){this.activeSnapshots=new Map;this.xmaxSnapshots=new Map;this.snapshotsByDatabaseLsn=new Map}addSnapshot(e,t){var o,a,h,u;this.activeSnapshots.set(e.snapshot_mark,{xmin:BigInt(e.xmin),xmax:BigInt(e.xmax),xip_list:e.xip_list.map(BigInt),keys:t});let s=(a=(o=this.xmaxSnapshots.get(BigInt(e.xmax)))==null?void 0:o.add(e.snapshot_mark))!=null?a:new Set([e.snapshot_mark]);this.xmaxSnapshots.set(BigInt(e.xmax),s);let i=(u=(h=this.snapshotsByDatabaseLsn.get(BigInt(e.database_lsn)))==null?void 0:h.add(e.snapshot_mark))!=null?u:new Set([e.snapshot_mark]);this.snapshotsByDatabaseLsn.set(BigInt(e.database_lsn),i)}removeSnapshot(e){this.activeSnapshots.delete(e)}shouldRejectMessage(e){let t=e.headers.txids||[];if(t.length===0)return!1;let s=Math.max(...t);for(let[i,o]of this.xmaxSnapshots.entries())if(s>=i)for(let a of o)this.removeSnapshot(a);return[...this.activeSnapshots.values()].some(i=>i.keys.has(e.key)&&Et(s,i))}lastSeenUpdate(e){for(let[t,s]of this.snapshotsByDatabaseLsn.entries())if(t<=e)for(let i of s)this.removeSnapshot(i)}};var Vs=new Set([st,le,H,ue,rt]);async function qt(r){return typeof r=="function"?r():r}async function Ws(r){let e=Object.entries(r),t=await Promise.all(e.map(async([s,i])=>{if(i===void 0)return[s,void 0];let o=await qt(i);return[s,Array.isArray(o)?o.join(","):o]}));return Object.fromEntries(t.filter(([s,i])=>i!==void 0))}async function Qs(r){if(!r)return{};let e=Object.entries(r),t=await Promise.all(e.map(async([s,i])=>[s,await qt(i)]));return Object.fromEntries(t)}function Ne(r){let e=new URL(r.origin+r.pathname);for(let[t,s]of r.searchParams)wt.includes(t)||e.searchParams.set(t,s);return e.searchParams.sort(),e.toString()}var ge,Ee,Se,ne,W,U,A,N,B,Q,v,ie,C,T,K,F,ye,k,ae,q,Re,z,be,Fe,G,$,Ae,oe,j,qe,$e,J,lt,_e,ut,dt,je,Y,X,xe,f,Lt,Be,me,Dt,ds,Ht,ht,fs,ps,ms,It,Nt,gs,Es,Bt,Ft,Ss,ys,Ot=class{constructor(e){d(this,f);d(this,ge,null);d(this,Ee);d(this,Se);d(this,ne);d(this,W,new Map);d(this,U,!1);d(this,A,"active");d(this,N);d(this,B);d(this,Q);d(this,v,!1);d(this,ie,!0);d(this,C,!1);d(this,T);d(this,K);d(this,F);d(this,ye);d(this,k);d(this,ae,!1);d(this,q);d(this,Re);d(this,z);d(this,be,Promise.resolve([]));d(this,Fe,new ct);d(this,G,0);d(this,$);d(this,Ae);d(this,oe);d(this,j);d(this,qe);d(this,$e,1e3);d(this,J,0);d(this,lt,3);d(this,_e,!1);d(this,ut,100);d(this,dt,5e3);d(this,je);d(this,Y);d(this,X,0);d(this,xe,3);var a,h,u,m;this.options=E({subscribe:!0},e),Ks(this.options),c(this,N,(a=this.options.offset)!=null?a:"-1"),c(this,B,""),c(this,T,this.options.handle);let t;if(e.columnMapper){let l=g=>{let S={};for(let[_,y]of Object.entries(g)){let O=e.columnMapper.decode(_);S[O]=y}return S};t=e.transformer?g=>e.transformer(l(g)):l}else t=e.transformer;c(this,ne,new Xe(e.parser,t)),c(this,ye,this.options.onError),c(this,K,(h=this.options.log)!=null?h:"full");let s=(u=e.fetchClient)!=null?u:(...l)=>fetch(...l),i=ce(E({},(m=e.backoffOptions)!=null?m:it),{onFailedAttempt:()=>{var l,g;c(this,C,!1),(g=(l=e.backoffOptions)==null?void 0:l.onFailedAttempt)==null||g.call(l)}}),o=os(s,i);c(this,Se,ls(hs(o))),c(this,Ee,cs(n(this,Se))),p(this,f,Ss).call(this)}get shapeHandle(){return n(this,T)}get error(){return n(this,ge)}get isUpToDate(){return n(this,v)}get lastOffset(){return n(this,N)}get mode(){return n(this,K)}subscribe(e,t=()=>{}){let s=Math.random();return n(this,W).set(s,[e,t]),n(this,U)||p(this,f,Be).call(this),()=>{n(this,W).delete(s)}}unsubscribeAll(){var e;n(this,W).clear(),(e=n(this,je))==null||e.call(this)}lastSyncedAt(){return n(this,Q)}lastSynced(){return n(this,Q)===void 0?1/0:Date.now()-n(this,Q)}isConnected(){return n(this,C)}isLoading(){return!n(this,v)}hasStarted(){return n(this,U)}isPaused(){return n(this,A)==="paused"}async forceDisconnectAndRefresh(){var e,t;c(this,ae,!0),n(this,v)&&!((e=n(this,k))!=null&&e.signal.aborted)&&((t=n(this,k))==null||t.abort(bt)),await p(this,f,gs).call(this),c(this,ae,!1)}async requestSnapshot(e){if(n(this,K)==="full")throw new Error(`Snapshot requests are not supported in ${n(this,K)} mode, as the consumer is guaranteed to observe all data`);n(this,U)||await p(this,f,Be).call(this),await p(this,f,Es).call(this),ve(this,G)._++;try{n(this,G)===1&&p(this,f,It).call(this);let{metadata:t,data:s}=await this.fetchSnapshot(e),i=s.concat([{headers:E({control:"snapshot-end"},t)},{headers:E({control:"subset-end"},e)}]);return n(this,Fe).addSnapshot(t,new Set(s.map(o=>o.key))),p(this,f,ht).call(this,i,!1),{metadata:t,data:s}}finally{ve(this,G)._--,n(this,G)===0&&p(this,f,Nt).call(this)}}async fetchSnapshot(e){var m;let{fetchUrl:t,requestHeaders:s}=await p(this,f,Dt).call(this,this.options.url,!0,e),i=await n(this,Ee).call(this,t.toString(),{headers:s});if(!i.ok)throw new x(i.status,void 0,void 0,Object.fromEntries([...i.headers.entries()]),t.toString());let o=(m=n(this,F))!=null?m:us(i.headers,{required:!0,url:t.toString()}),{metadata:a,data:h}=await i.json(),u=n(this,ne).parseSnapshotData(h,o);return{metadata:a,data:u}}};ge=new WeakMap,Ee=new WeakMap,Se=new WeakMap,ne=new WeakMap,W=new WeakMap,U=new WeakMap,A=new WeakMap,N=new WeakMap,B=new WeakMap,Q=new WeakMap,v=new WeakMap,ie=new WeakMap,C=new WeakMap,T=new WeakMap,K=new WeakMap,F=new WeakMap,ye=new WeakMap,k=new WeakMap,ae=new WeakMap,q=new WeakMap,Re=new WeakMap,z=new WeakMap,be=new WeakMap,Fe=new WeakMap,G=new WeakMap,$=new WeakMap,Ae=new WeakMap,oe=new WeakMap,j=new WeakMap,qe=new WeakMap,$e=new WeakMap,J=new WeakMap,lt=new WeakMap,_e=new WeakMap,ut=new WeakMap,dt=new WeakMap,je=new WeakMap,Y=new WeakMap,X=new WeakMap,xe=new WeakMap,f=new WeakSet,Lt=function(){return n(this,oe)!==void 0},Be=async function(){var e,t,s,i,o;c(this,U,!0);try{await p(this,f,me).call(this)}catch(a){if(c(this,ge,a),n(this,ye)){let h=await n(this,ye).call(this,a),u=!(a instanceof se);if(h&&typeof h=="object"&&u){h.params&&(this.options.params=E(E({},(e=this.options.params)!=null?e:{}),h.params)),h.headers&&(this.options.headers=E(E({},(t=this.options.headers)!=null?t:{}),h.headers)),c(this,ge,null),c(this,U,!1),await p(this,f,Be).call(this);return}a instanceof Error&&p(this,f,Ft).call(this,a),c(this,C,!1),(s=n(this,z))==null||s.call(this);return}throw a instanceof Error&&p(this,f,Ft).call(this,a),c(this,C,!1),(i=n(this,z))==null||i.call(this),a}c(this,C,!1),(o=n(this,z))==null||o.call(this)},me=async function(){var u,m;if(n(this,A)==="pause-requested"){c(this,A,"paused");return}if(!this.options.subscribe&&((u=this.options.signal)!=null&&u.aborted||n(this,v)))return;let e=n(this,A)==="paused";c(this,A,"active");let{url:t,signal:s}=this.options,{fetchUrl:i,requestHeaders:o}=await p(this,f,Dt).call(this,t,e),a=await p(this,f,ds).call(this,s),h=n(this,k);try{await p(this,f,fs).call(this,{fetchUrl:i,requestAbortController:h,headers:o,resumingFromPause:e})}catch(l){if((l instanceof x||l instanceof D)&&h.signal.aborted&&h.signal.reason===bt)return p(this,f,me).call(this);if(l instanceof D){let g=n(this,A);h.signal.aborted&&h.signal.reason===At&&g==="pause-requested"&&c(this,A,"paused");return}if(l instanceof Me)return p(this,f,me).call(this);if(!(l instanceof x))throw l;if(l.status==409){if(n(this,T)){let S=Ne(i);ot.markExpired(S,n(this,T))}let g=l.headers[ke]||`${n(this,T)}-next`;return p(this,f,ys).call(this,g),await p(this,f,Bt).call(this,Array.isArray(l.json)?l.json:[l.json]),p(this,f,me).call(this)}else throw l}finally{a&&s&&s.removeEventListener("abort",a),c(this,k,void 0)}return(m=n(this,Re))==null||m.call(this),p(this,f,me).call(this)},Dt=async function(e,t,s){var l,g,S,_,y,O;let[i,o]=await Promise.all([Qs(this.options.headers),this.options.params?Ws(zs(this.options.params)):void 0]);o&&Rs(o);let a=new URL(e);if(o){if(o.table&&w(a,ss,o.table),o.where&&typeof o.where=="string"){let L=Ze(o.where,(l=this.options.columnMapper)==null?void 0:l.encode);w(a,rs,L)}if(o.columns){let L=await qt((g=this.options.params)==null?void 0:g.columns);if(Array.isArray(L)){let V=L.map(String);this.options.columnMapper&&(V=V.map(this.options.columnMapper.encode));let Pe=V.map(Ce).join(",");w(a,yt,Pe)}else w(a,yt,o.columns)}o.replica&&w(a,ns,o.replica),o.params&&w(a,is,o.params);let b=E({},o);delete b.table,delete b.where,delete b.columns,delete b.replica,delete b.params;for(let[L,V]of Object.entries(b))w(a,L,V)}if(s){if(s.whereExpr){let b=at(s.whereExpr,(S=this.options.columnMapper)==null?void 0:S.encode);w(a,de,b),a.searchParams.set(xt,JSON.stringify(s.whereExpr))}else if(s.where&&typeof s.where=="string"){let b=Ze(s.where,(_=this.options.columnMapper)==null?void 0:_.encode);w(a,de,b)}if(s.params&&a.searchParams.set(De,JSON.stringify(s.params)),s.limit&&w(a,Oe,s.limit),s.offset&&w(a,Le,s.offset),s.orderByExpr){let b=Mt(s.orderByExpr,(y=this.options.columnMapper)==null?void 0:y.encode);w(a,fe,b),a.searchParams.set(Tt,JSON.stringify(s.orderByExpr))}else if(s.orderBy&&typeof s.orderBy=="string"){let b=Ze(s.orderBy,(O=this.options.columnMapper)==null?void 0:O.encode);w(a,fe,b)}}a.searchParams.set(ue,n(this,N)),a.searchParams.set(_t,n(this,K));let h=s!==void 0;n(this,v)&&!h&&(!n(this,ae)&&!t&&a.searchParams.set(H,"true"),a.searchParams.set(st,n(this,B))),n(this,T)&&a.searchParams.set(le,n(this,T));let u=Ne(a),m=ot.getExpiredHandle(u);return m&&a.searchParams.set(Ue,m),n(this,Y)&&a.searchParams.set(rt,n(this,Y)),a.searchParams.sort(),{fetchUrl:a,requestHeaders:i}},ds=async function(e){var t;if(c(this,k,new AbortController),e){let s=()=>{var i;(i=n(this,k))==null||i.abort(e.reason)};return e.addEventListener("abort",s,{once:!0}),e.aborted&&((t=n(this,k))==null||t.abort(e.reason)),s}},Ht=async function(e){var h,u,m,l;let{headers:t,status:s}=e,i=t.get(ke);if(i){let g=n(this,j)?Ne(n(this,j)):null,S=g?ot.getExpiredHandle(g):null;if(i!==S)c(this,T,i),n(this,Y)&&(c(this,Y,void 0),c(this,X,0));else{if(n(this,T)===void 0)throw ve(this,X)._++,await((h=e.body)==null?void 0:h.cancel()),n(this,X)>n(this,xe)?new x(502,void 0,void 0,{},(m=(u=n(this,j))==null?void 0:u.toString())!=null?m:"",`CDN continues serving stale cached responses after ${n(this,xe)} retry attempts. This indicates a severe proxy/CDN misconfiguration. Check that your proxy includes all query parameters (especially 'handle' and 'offset') in its cache key. For more information visit the troubleshooting guide: https://electric-sql.com/docs/guides/troubleshooting`):(console.warn(`[Electric] Received stale cached response with expired shape handle. This should not happen and indicates a proxy/CDN caching misconfiguration. The response contained handle "${i}" which was previously marked as expired. Check that your proxy includes all query parameters (especially 'handle' and 'offset') in its cache key. For more information visit the troubleshooting guide: https://electric-sql.com/docs/guides/troubleshooting Retrying with a random cache buster to bypass the stale cache (attempt ${n(this,X)}/${n(this,xe)}).`),c(this,Y,`${Date.now()}-${Math.random().toString(36).substring(2,9)}`),new Me(`Received stale cached response with expired handle "${i}". This indicates a proxy/CDN caching misconfiguration. Check that your proxy includes all query parameters (especially 'handle' and 'offset') in its cache key.`));console.warn(`[Electric] Received stale cached response with expired shape handle. This should not happen and indicates a proxy/CDN caching misconfiguration. The response contained handle "${i}" 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 "${n(this,T)}".`)}}let o=t.get(tt);o&&c(this,N,o);let a=t.get(es);a&&c(this,B,a),c(this,F,(l=n(this,F))!=null?l:us(t)),s===204&&c(this,Q,Date.now())},ht=async function(e,t=!1){var s;if(e.length>0){c(this,ie,!0);let i=e[e.length-1];if(gt(i)){if(t){let a=Zt(i);a&&c(this,N,a)}if(c(this,Q,Date.now()),c(this,v,!0),c(this,ie,!1),(s=n(this,Ae))==null||s.call(this),n(this,f,Lt)&&!t&&n(this,B)===n(this,oe))return;if(c(this,oe,void 0),n(this,j)){let a=Ne(n(this,j));Ut.recordUpToDate(a,n(this,B))}}let o=e.filter(a=>he(a)?!n(this,Fe).shouldRejectMessage(a):!0);await p(this,f,Bt).call(this,o)}},fs=async function(e){var s;if(c(this,j,e.fetchUrl),!n(this,v)&&!n(this,f,Lt)){let i=Ne(e.fetchUrl),o=Ut.shouldEnterReplayMode(i);o&&c(this,oe,o)}let t=(s=this.options.liveSse)!=null?s:this.options.experimentalLiveSse;return n(this,v)&&t&&!n(this,ae)&&!e.resumingFromPause&&!n(this,_e)?(e.fetchUrl.searchParams.set(as,"true"),e.fetchUrl.searchParams.set(Rt,"true"),p(this,f,ms).call(this,e)):p(this,f,ps).call(this,e)},ps=async function(e){let{fetchUrl:t,requestAbortController:s,headers:i}=e,o=await n(this,Ee).call(this,t.toString(),{signal:s.signal,headers:i});c(this,C,!0),await p(this,f,Ht).call(this,o);let a=n(this,F),u=await o.text()||"[]",m=n(this,ne).parse(u,a);await p(this,f,ht).call(this,m)},ms=async function(e){let{fetchUrl:t,requestAbortController:s,headers:i}=e,o=n(this,Se);c(this,qe,Date.now());let a=ce(E({},i),{Accept:"text/event-stream"});try{let h=[];await Ys(t.toString(),{headers:a,fetch:o,onopen:async u=>{c(this,C,!0),await p(this,f,Ht).call(this,u)},onmessage:u=>{if(u.data){let m=n(this,F),l=n(this,ne).parse(u.data,m);h.push(l),gt(l)&&(p(this,f,ht).call(this,h,!0),h=[])}},onerror:u=>{throw u},signal:s.signal})}catch(h){throw s.signal.aborted?new D:h}finally{let h=Date.now()-n(this,qe),u=s.signal.aborted;if(h<n(this,$e)&&!u)if(ve(this,J)._++,n(this,J)>=n(this,lt))c(this,_e,!0),console.warn("[Electric] SSE connections are closing immediately (possibly due to proxy buffering or misconfiguration). Falling back to long polling. Your proxy must support streaming SSE responses (not buffer the complete response). Configuration: Nginx add 'X-Accel-Buffering: no', Caddy add 'flush_interval -1' to reverse_proxy. Note: Do NOT disable caching entirely - Electric uses cache headers to enable request collapsing for efficiency.");else{let m=Math.min(n(this,dt),n(this,ut)*Math.pow(2,n(this,J))),l=Math.floor(Math.random()*m);await new Promise(g=>setTimeout(g,l))}else h>=n(this,$e)&&c(this,J,0)}},It=function(){var e;n(this,U)&&n(this,A)==="active"&&(c(this,A,"pause-requested"),(e=n(this,k))==null||e.abort(At))},Nt=function(){var e;if(n(this,U)&&(n(this,A)==="paused"||n(this,A)==="pause-requested")){if((e=this.options.signal)!=null&&e.aborted)return;n(this,A)==="pause-requested"&&c(this,A,"active"),p(this,f,Be).call(this)}},gs=async function(){return n(this,q)?n(this,q):(c(this,q,new Promise((e,t)=>{c(this,Re,e),c(this,z,t)})),n(this,q).finally(()=>{c(this,q,void 0),c(this,Re,void 0),c(this,z,void 0)}),n(this,q))},Es=async function(){if(n(this,ie))return n(this,$)?n(this,$):(c(this,$,new Promise(e=>{c(this,Ae,e)})),n(this,$).finally(()=>{c(this,$,void 0),c(this,Ae,void 0)}),n(this,$))},Bt=async function(e){return c(this,be,n(this,be).then(()=>Promise.all(Array.from(n(this,W).values()).map(async([t,s])=>{try{await t(e)}catch(i){queueMicrotask(()=>{throw i})}})))),n(this,be)},Ft=function(e){n(this,W).forEach(([t,s])=>{s==null||s(e)})},Ss=function(){if(typeof document=="object"&&typeof document.hidden=="boolean"&&typeof document.addEventListener=="function"){let e=()=>{document.hidden?p(this,f,It).call(this):p(this,f,Nt).call(this)};document.addEventListener("visibilitychange",e),c(this,je,()=>{document.removeEventListener("visibilitychange",e)})}},ys=function(e){c(this,N,"-1"),c(this,B,""),c(this,T,e),c(this,v,!1),c(this,ie,!0),c(this,C,!1),c(this,F,void 0),c(this,G,0),c(this,J,0),c(this,_e,!1),c(this,Y,void 0),c(this,X,0)},Ot.Replica={FULL:"full",DEFAULT:"default"};function us(r,e){let t=r.get(St);if(!t){if(e!=null&&e.required&&(e!=null&&e.url))throw new se(e.url,[St]);return{}}return JSON.parse(t)}function Rs(r){if(!r)return;let e=Object.keys(r).filter(t=>Vs.has(t));if(e.length>0)throw new ze(e)}function Ks(r){if(!r.url)throw new We;if(r.signal&&!(r.signal instanceof AbortSignal))throw new Qe;if(r.offset!==void 0&&r.offset!=="-1"&&r.offset!=="now"&&!r.handle)throw new Ke;Rs(r.params)}function w(r,e,t){if(!(t===void 0||t==null))if(typeof t=="string")r.searchParams.set(e,t);else if(typeof t=="object")for(let[s,i]of Object.entries(t))r.searchParams.set(`${e}[${s}]`,i);else r.searchParams.set(e,t.toString())}function zs(r){return Array.isArray(r.params)?ce(E({},r),{params:Object.fromEntries(r.params.map((e,t)=>[t+1,e]))}):r}var P,Z,ee,Ye,Te,we,te,R,As,_s,$t,ft,xs,jt,bs=class{constructor(e){d(this,R);d(this,P,new Map);d(this,Z,new Map);d(this,ee,new Set);d(this,Ye,new Set);d(this,Te,!1);d(this,we,"syncing");d(this,te,!1);this.stream=e,this.stream.subscribe(p(this,R,As).bind(this),p(this,R,xs).bind(this))}get isUpToDate(){return n(this,we)==="up-to-date"}get lastOffset(){return this.stream.lastOffset}get handle(){return this.stream.shapeHandle}get rows(){return this.value.then(e=>Array.from(e.values()))}get currentRows(){return Array.from(this.currentValue.values())}get value(){return new Promise((e,t)=>{if(this.stream.isUpToDate)e(this.currentValue);else{let s=this.subscribe(({value:i})=>{s(),n(this,te)&&t(n(this,te)),e(i)})}})}get currentValue(){return n(this,P)}get error(){return n(this,te)}lastSyncedAt(){return this.stream.lastSyncedAt()}lastSynced(){return this.stream.lastSynced()}isLoading(){return this.stream.isLoading()}isConnected(){return this.stream.isConnected()}get mode(){return this.stream.mode}async requestSnapshot(e){let t=JSON.stringify(e);n(this,Ye).add(t),await p(this,R,$t).call(this),await this.stream.requestSnapshot(e)}subscribe(e){let t=Math.random();return n(this,Z).set(t,e),()=>{n(this,Z).delete(t)}}unsubscribeAll(){n(this,Z).clear()}get numSubscribers(){return n(this,Z).size}};P=new WeakMap,Z=new WeakMap,ee=new WeakMap,Ye=new WeakMap,Te=new WeakMap,we=new WeakMap,te=new WeakMap,R=new WeakSet,As=function(e){let t=!1;e.forEach(s=>{if(he(s))if(t=p(this,R,ft).call(this,"syncing"),this.mode==="full")switch(s.headers.operation){case"insert":n(this,P).set(s.key,s.value);break;case"update":n(this,P).set(s.key,E(E({},n(this,P).get(s.key)),s.value));break;case"delete":n(this,P).delete(s.key);break}else switch(s.headers.operation){case"insert":n(this,ee).add(s.key),n(this,P).set(s.key,s.value);break;case"update":n(this,ee).has(s.key)&&n(this,P).set(s.key,E(E({},n(this,P).get(s.key)),s.value));break;case"delete":n(this,ee).has(s.key)&&(n(this,P).delete(s.key),n(this,ee).delete(s.key));break}if(et(s))switch(s.headers.control){case"up-to-date":t=p(this,R,ft).call(this,"up-to-date"),n(this,Te)&&(c(this,Te,!1),p(this,R,_s).call(this));break;case"must-refetch":n(this,P).clear(),n(this,ee).clear(),c(this,te,!1),t=p(this,R,ft).call(this,"syncing"),c(this,Te,!0);break}}),t&&p(this,R,jt).call(this)},_s=async function(){await p(this,R,$t).call(this),await Promise.all(Array.from(n(this,Ye)).map(async e=>{try{let t=JSON.parse(e);await this.stream.requestSnapshot(t)}catch(t){}}))},$t=async function(){this.stream.isUpToDate||await new Promise(e=>{let t=()=>{this.stream.isUpToDate&&(clearInterval(s),i(),e())},s=setInterval(t,10),i=this.stream.subscribe(()=>t(),()=>t());t()})},ft=function(e){let t=n(this,we)!==e;return c(this,we,e),t&&e==="up-to-date"},xs=function(e){e instanceof x&&(c(this,te,e),p(this,R,jt).call(this))},jt=function(){n(this,Z).forEach(e=>{e({value:this.currentValue,rows:this.currentRows})})};export{it as BackoffDefaults,wt as ELECTRIC_PROTOCOL_QUERY_PARAMS,x as FetchError,bs as Shape,Ot as ShapeStream,Jt as camelToSnake,at as compileExpression,Mt as compileOrderBy,Xt as createColumnMapper,he as isChangeMessage,et as isControlMessage,Et as isVisibleInSnapshot,qt as resolveValue,Os as snakeCamelMapper,mt as snakeToCamel};
|
|
6
6
|
//# sourceMappingURL=index.browser.mjs.map
|