@symbo.ls/fetch 3.14.665 → 3.14.666
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/CHANGELOG.md +10 -0
- package/README.md +8 -2
- package/dist/cjs/index.js +1 -1
- package/dist/esm/index.js +1 -1
- package/index.js +191 -127
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @symbo.ls/fetch
|
|
2
2
|
|
|
3
|
+
## 3.14.666
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Cross-tenant isolation for server renders, and the wider CLI production gate.
|
|
8
|
+
|
|
9
|
+
- fetch: a server render context (`isolateFetchCache`, set by brender) has its own query store — cache, requests in flight, invalidations and mounted queries — so two renders of different projects in one process never share rows, in sequence or at the same time; a server render binds no browser-only refetch (no focus / online listeners, no `refetchInterval` timer), so no request of one page lands in another page's seed and the process exits when the work is done.
|
|
10
|
+
- brender: renders that start together share one framework bundle; every render owns its `location`, Web Storage and `history`.
|
|
11
|
+
- cli: destructive platform writes (project delete, transfer, members, invites, library changes, version writes) print the target and need a typed "production" or `--yes` for production; `project create` is not gated.
|
|
12
|
+
|
|
3
13
|
## 3.14.665
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -241,6 +241,8 @@ Each tick sends a request, also while the cached entry is still fresh.
|
|
|
241
241
|
{ fetch: { from: 'alerts', refetchInterval: '1m', refetchIntervalInBackground: true } }
|
|
242
242
|
```
|
|
243
243
|
|
|
244
|
+
Focus, reconnect and interval refetches belong to a live page. A server render (brender) binds none of them: its page is markup once the render ends ([one cache per render](#server-seeded-answers-brender)).
|
|
245
|
+
|
|
244
246
|
## Placeholder data
|
|
245
247
|
|
|
246
248
|
Show temporary data immediately while the real query loads:
|
|
@@ -562,6 +564,8 @@ Global cache management, importable anywhere:
|
|
|
562
564
|
import { queryClient } from '@symbo.ls/fetch'
|
|
563
565
|
```
|
|
564
566
|
|
|
567
|
+
It manages the page's cache. A server render has a cache of its own ([one per render](#server-seeded-answers-brender)): its elements reach it through `el.call`, and `prefetchQuery` takes its context.
|
|
568
|
+
|
|
565
569
|
Project code (components, pages, functions) cannot import it — frank serializes an import of `@symbo.ls/fetch` to a stub. It calls the same controls through `el.call` instead (see [From project code](#from-project-code-elcall)).
|
|
566
570
|
|
|
567
571
|
### Cache keys
|
|
@@ -629,7 +633,7 @@ await queryClient.prefetchQuery({
|
|
|
629
633
|
}, context)
|
|
630
634
|
```
|
|
631
635
|
|
|
632
|
-
The prefetched entry has the key an element of that context builds for the same query — with its language and tenant scope from `context.state.root` — and the request carries the same `Accept-Language`, so a later mount reads it without a request.
|
|
636
|
+
The prefetched entry has the key an element of that context builds for the same query — with its language and tenant scope from `context.state.root` — and the request carries the same `Accept-Language`, so a later mount reads it without a request. It lands in that context's cache: a server render's own (`isolateFetchCache`), else the page's.
|
|
633
637
|
|
|
634
638
|
## From project code (`el.call`)
|
|
635
639
|
|
|
@@ -644,6 +648,8 @@ When `fetch` is configured, smbls registers the query client's controls as proje
|
|
|
644
648
|
|
|
645
649
|
`getQueryData` / `setQueryData` take a key, or a fetch config — `{ from, method, params }` — whose key is built the way the calling element would build it (params resolved with that element, its language and tenant scope).
|
|
646
650
|
|
|
651
|
+
Each works on the calling element's cache: the page's in a browser, its own render's in a server render (`isolateFetchCache`) — what a render's project code writes, removes or invalidates stays in that render.
|
|
652
|
+
|
|
647
653
|
A write made through `getDB()` does not know which queries it changed — invalidate them after it:
|
|
648
654
|
|
|
649
655
|
```js
|
|
@@ -754,7 +760,7 @@ A page pre-rendered by `@symbo.ls/brender` carries the answers its render got, s
|
|
|
754
760
|
- **Recorded on the server:** a GET whose only headers are `Accept` / `Accept-Language` — an anonymous read; with `reads` its configured key travels in the query string, so a keyed backend's reads (Supabase) count, and read-only RPCs (`reads.rpc: 'get'`, `read: true`) too — with an ok JSON or text answer. Never a POST, a call with `Authorization` or another header.
|
|
755
761
|
- **Read on the client:** the REST adapter reads the block when it opens (the block goes once read). A call takes a seeded answer when it sends exactly the recorded request: the same URL (query included) and `Accept-Language`, no other header. Each answer is taken once, within 30 s, and read without a `Response` — its data lands in the task the app booted in. Without `fetch.early` too.
|
|
756
762
|
- **Build side:** `createEarlySeedBlock(entries)` (`entries`: `[{ url, lang, status, type, body }]`); `createEarlySeedScript(entries)` is the older inline form.
|
|
757
|
-
- **One query cache per render:** a context with `isolateFetchCache: true` (brender sets it on every render)
|
|
763
|
+
- **One query cache per render:** a context with `isolateFetchCache: true` (brender sets it on every render) has a cache of its own — its entries, its requests in flight, its invalidations and its mounted queries — made at its first query and dropped with the context. A render starts empty and makes every request its markup depends on itself, so its seed carries every answer it shows, even when an earlier page read the same key. Renders in one process — one after another or at once, of one project or of several — never share a row, a request in flight or an invalidation, and a request that outlives its render never reaches another one. `queryClient` stays the page's cache; a render's own is reached through its elements (`el.call('invalidateQueries', …)`, `getQueryData`, …) and `prefetchQuery(config, context)`. Such a context also binds no window focus, reconnect or `refetchInterval` refetch: once its markup is taken, a render's queries leave no listener, no timer and no request behind. A browser context never sets it; the cache works as described above.
|
|
758
764
|
|
|
759
765
|
`requestsInFlight()` and `whenRequestsIdle()` (from `@symbo.ls/fetch`) count the REST adapter's requests from the call until the body is read — `smbls` holds the hydration window over a pre-rendered page open until the first view's requests are done.
|
|
760
766
|
|
package/dist/cjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var gt=Object.create;var _e=Object.defineProperty;var Tt=Object.getOwnPropertyDescriptor;var mt=Object.getOwnPropertyNames;var vt=Object.getPrototypeOf,Et=Object.prototype.hasOwnProperty;var Dt=(e,t)=>{for(var r in t)_e(e,r,{get:t[r],enumerable:!0})},Xe=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of mt(t))!Et.call(e,o)&&o!==r&&_e(e,o,{get:()=>t[o],enumerable:!(s=Tt(t,o))||s.enumerable});return e};var Ze=(e,t,r)=>(r=e!=null?gt(vt(e)):{},Xe(t||!e||!e.__esModule?_e(r,"default",{value:e,enumerable:!0}):r,e)),Pt=e=>Xe(_e({},"__esModule",{value:!0}),e);var Vt={};Dt(Vt,{EARLY_KEY:()=>A.EARLY_KEY,SEED_BLOCK:()=>A.SEED_BLOCK,createAdapter:()=>Lt,createEarlySeedBlock:()=>A.createEarlySeedBlock,createEarlySeedScript:()=>A.createEarlySeedScript,default:()=>Wt,earlyKey:()=>A.earlyKey,executeFetch:()=>Ve,fetchFunctions:()=>Yt,fetchPlugin:()=>Gt,hasAdapter:()=>Ot,initAdapterAuth:()=>Pe,parseDuration:()=>ee,queryClient:()=>ie,registerAdapter:()=>kt,requestsInFlight:()=>Fe.requestsInFlight,resolveDb:()=>yt,whenRequestsIdle:()=>Fe.whenRequestsIdle});module.exports=Pt(Vt);var i=require("@symbo.ls/utils"),ht=require("@symbo.ls/signal"),_t=require("./early.js"),Ft=Ze(require("./adapters/rest.js"),1),A=require("./early.js"),Fe=require("./inflight.js");const At=["select","rpc","insert","update","upsert","delete","subscribe"],et={rest:()=>Promise.resolve(Ft),local:()=>import("./adapters/local.js")},ye=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),H=(()=>{if(typeof globalThis<"u"&&globalThis[ye])return globalThis[ye];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,ye,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[ye]}catch{}return e})(),be=Symbol.for("@symbo.ls/fetch:PENDING_ADAPTERS"),Le=(()=>{if(typeof globalThis<"u"&&globalThis[be])return globalThis[be];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,be,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[be]}catch{}return e})(),Ct=5e3,Mt=e=>new Promise(t=>{if(H[e])return t(H[e]);const r=Le[e]||=[];let s=!1;const o=()=>{s||(s=!0,t(H[e]||null))};r.push(o),setTimeout(o,Ct)}),kt=(e,t)=>{H[e]=t;const r=Le[e];if(r&&r.length){Le[e]=[];for(const s of r)s()}},Ot=e=>typeof e=="string"&&!!(H[e]||et[e]),Lt=e=>{const t={};for(const r of At)e[r]&&(t[r]=e[r]);return t.name=e.name||"custom",t},yt=async e=>{if(!e)return null;if(typeof e.select=="function")return e;const{adapter:t,...r}=e,s=typeof t=="string"?t:typeof e=="string"?e:null;if(!s)return null;let o=H[s]||et[s];if(!o&&(o=await Mt(s),!o))throw new Error(`Unknown db adapter: "${s}". Use registerAdapter() for adapters with optional deps.`);const n=await o();if(!n||typeof n.setup!="function")throw new Error(`Adapter "${s}" loader returned a module without a setup() function. Got keys: [${Object.keys(n||{}).join(", ")}]. Likely a bundler chunk-resolution issue.`);return n.setup(r)},ee=e=>{if(!e)return 0;if(typeof e=="number")return e;const t=e.match(/^(\d+)(ms|s|m|h)$/);if(!t)return 0;const r=parseInt(t[1]),s=t[2];return s==="ms"?r:s==="s"?r*1e3:s==="m"?r*6e4:s==="h"?r*36e5:0},m=new Map,x=new Map,I=new Map;let Se=0;const we=new Map,Re=new WeakMap,qe=(e,t,r,s,o=e.page,n=e.cursor)=>{if(e.cache?.key)return e.cache.key;const{from:u,method:c,infinite:a}=e,l=r?`${r}:`:"",h=s?`:${s}`:"",p=o?":p"+JSON.stringify(o):"",v=n!=null?":c"+JSON.stringify(n):"";return`${u}:${c}:${l}${JSON.stringify(t||"")}${a?":infinite":""}${p}${v}${h}`},re=e=>m.get(e)||null,se=(e,t,r,s=++Se,o=!1)=>{const n={data:t,error:r,time:Date.now(),stale:o,seq:s};m.set(e,n);const u=x.get(e);if(u)for(const c of u)(0,i.isFunction)(c)&&c(n);return n},ge=(e,t)=>{const r=e?m.get(e):null;return r&&!r.error&&r.seq>t?r:null},Ie=(e,t)=>(we.get(e)||0)>t,Te=e=>{we.set(e,++Se)},tt=e=>{m.delete(e),Te(e)},Ht=(e,t)=>(x.has(e)||x.set(e,new Set),x.get(e).add(t),()=>{const r=x.get(e);r&&(r.delete(t),r.size===0&&x.delete(e))}),Ne=e=>!e&&e!==!1?{staleTime:6e4,gcTime:3e5}:e===!1?null:e===!0?{staleTime:6e4,gcTime:3e5}:typeof e=="number"?{staleTime:e,gcTime:Math.max(e*5,3e5)}:(0,i.isString)(e)?{staleTime:ee(e),gcTime:3e5}:{staleTime:ee(e.stale||e.staleTime)||6e4,gcTime:ee(e.gc||e.gcTime||e.expire)||3e5,key:e.key},N=new Set,rt=e=>!!e.ref&&e.element.__ref===e.ref,Rt=({config:e,element:t,context:r})=>{try{return $e(e,t,r)}catch{return null}};let me=null;const qt=()=>{me||(me=setInterval(()=>{const e=Date.now();for(const[t,r]of m){const s=x.get(t);!(s&&s.size>0)&&e-r.time>(r.gcTime||3e5)&&m.delete(t)}for(const[t]of we)!m.has(t)&&!I.has(t)&&we.delete(t);for(const t of N)rt(t)||N.delete(t)},3e4),me.unref&&me.unref())};qt();const st=3,Ue=e=>Math.min(1e3*2**e,3e4),nt=(e,t)=>{const r=e.retry;return r===void 0&&t?{count:0}:r===!1?{count:0}:r===!0||r===void 0?{count:st,delay:Ue}:typeof r=="number"?{count:r,delay:Ue}:{count:r.count??st,delay:(0,i.isFunction)(r.delay)?r.delay:typeof r.delay=="number"?()=>r.delay:Ue}},ot=async(e,t)=>{const{count:r,delay:s}=t;let o;for(let n=0;n<=r;n++)try{const u=await e();if(u?.error){if(o=u.error,n<r){const c=(0,i.isFunction)(s)?s(n,o):s;await new Promise(a=>setTimeout(a,c));continue}return u}return u}catch(u){if(o=u,n<r){const c=(0,i.isFunction)(s)?s(n,u):s;await new Promise(a=>setTimeout(a,c));continue}throw u}return{data:null,error:o}},X={focus:new Set,online:new Set};let at=!1;const It=()=>{if(at||typeof window>"u")return;at=!0;const e=()=>{for(const r of X.focus)r()},t=()=>{for(const r of X.online)r()};window.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&e()}),window.addEventListener("focus",e),window.addEventListener("online",t)},it=(e,t)=>{const r=t.__ref;if(e===!0)return{from:r.__state||t.key,method:"select",query:!0,on:"create"};if((0,i.isString)(e))return{from:e,method:"select",query:!0,on:"create"};if((0,i.isObject)(e)){const s={...e};return s.from=s.from||r.__state||t.key,s.method=s.method||"select",s.on=s.on||"create",s.query===void 0&&(s.query=!0),s}return null},Nt=["insert","update","upsert","delete"],ut=e=>Nt.includes(e),Qe=e=>e.mutation===!0?!0:e.mutation===!1||e.method!=="rpc"?!1:e.on==="submit"||e.on==="click"||e.invalidates!=null,ne=(e,t)=>{const r=e?.state?.root||t?.state?.root;if(r?.lang)return r.lang},ve=(e,t)=>{const s=(e?.state?.root||t?.state?.root)?.__fetchScope;return s?String(s):void 0},Ee=(e,t,r)=>{let s;if(!e)s=void 0;else if((0,i.isFunction)(e))s=e(t,t.state);else{s={};for(const o in e){const n=e[o];s[o]=(0,i.isFunction)(n)?n(t,t.state):n}}return s},oe=(e,t)=>(0,i.isFunction)(e)?e(t,t.state):e,$e=(e,t,r)=>qe(e,Ee(e.params,t,r),ve(t,r),ne(t,r),oe(e.page,t),oe(e.cursor,t)),Pe=async(e,t)=>{if(!e||e.__authInitialized||(e.__authInitialized=!0,!e.getSession))return;const r=(s,o)=>{const n=t.state?.root;n?.update&&n.update({auth:{user:s,session:o,loading:!1}})};try{const s=await e.getSession();r(s?.user||null,s)}catch(s){console.warn("[fetch] Failed to restore auth session:",s.message)}e.onAuthStateChange&&e.onAuthStateChange((s,o)=>{r(o?.user||null,o)})},ze=async(e,t)=>{if((0,i.isFunction)(e.select))return e.auth!==!1&&await Pe(e,t),e;if(e.__resolved)return e.auth!==!1&&await Pe(e.__resolved,t),e.__resolved;if(e.__resolving)return e.__resolving;e.__resolving=yt(e);const r=await e.__resolving;return delete e.__resolving,r?(r.auth=e.auth,r.url=e.url,r.key=e.key,e.__resolved=r,t.fetch=r,e.auth!==!1&&await Pe(r,t),r):null},F=(e,t,...r)=>{const s=(0,i.isFunction)(e[t])?e[t]:null;s&&s.call(e,...r,e,e.state,e.context)},O=(e,t,r,...s)=>{const o=e&&(0,i.isFunction)(e[r])?e[r]:null;o&&o.call(t,...s,t,t.state,t.context)},ae=e=>{const t={},r=e.node;if(!r)return t;if(r.tagName==="FORM"){const o=new FormData(r);for(const[n,u]of o.entries())t[n]=u;return t}const s=r.querySelectorAll("input, textarea, select");for(let o=0;o<s.length;o++){const n=s[o],u=n.name||n.getAttribute("name");u&&(n.type==="checkbox"?t[u]=n.checked:n.type==="file"?t[u]=n.files:t[u]=n.value)}return t},De=e=>e.responseType==="stream"||e.responseType==="response",Ut=["Blob","File","ArrayBuffer","ReadableStream","Response"],je=e=>e!==null&&typeof e=="object"&&(ArrayBuffer.isView(e)||Ut.includes(Object.prototype.toString.call(e).slice(8,-1))),U=(e,t,r,s={})=>{if(!r&&je(t))return;const o=r&&r.startsWith("~/"),n=o&&e.state?.root||e.state;if(n?.update)if(o){const u=r.slice(2);t&&typeof t=="object"&&!Array.isArray(t)&&!je(t)&&u in t?n.update(t,{preventFetch:!0,...s}):n.update({[u]:t},{preventFetch:!0,...s})}else{const u=r?{[r]:t}:t;n.update(u,{preventFetch:!0,...s})}},Be=Object.freeze({isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),Ke=e=>({isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:e,status:"error",fetchStatus:"idle"}),Q=(e,t)=>{const r=e?.__ref;r&&(r.__fetchStatus={...t,isError:!!t.error},r.__fetching=t.isFetching,r.__fetchError=t.error)},ct=(e,t,r)=>{const s=e.__pages&&e.__pages.length?e.__pages:[r];(0,i.isFunction)(t.getNextPageParam)&&(e.__nextPageParam=t.getNextPageParam(s[s.length-1],s),e.__hasNextPage=e.__nextPageParam!=null),(0,i.isFunction)(t.getPreviousPageParam)&&(e.__prevPageParam=t.getPreviousPageParam(s[0],s),e.__hasPreviousPage=e.__prevPageParam!=null)},L=async(e,t,r,s={})=>{const o=r?.fetch;if(!o||!t||!t.__ref)return;const n=t.__ref,u=ve(t,r);(!n.__fetchScopeOwner||n.__fetchScopeOwner.scope!==u)&&(n.__fetchScopeOwner={scope:u});const c=n.__fetchScopeOwner,a=()=>t.__ref===n&&n.__fetchScopeOwner===c&&ve(t,r)===u;if(e.enabled===!1||(0,i.isFunction)(e.enabled)&&!e.enabled(t,t.state)||e.skip===!0||(0,i.isFunction)(e.skip)&&e.skip(t,t.state))return;const l=await ze(o,r);if(!l||!a())return;const{from:h,method:p,query:v,params:Ae,cache:Ce,transform:$,single:ue,auth:ce,fields:Y,as:C,limit:z,offset:R,order:S,headers:te,baseUrl:E,responseType:G,page:g,cursor:P,infinite:j,placeholderData:W,initialData:V,select:T,keepPreviousData:M}=e,B=f=>((0,i.isFunction)(T)&&(f=T(f,t,t.state)),$&&(f=$(f,t,t.state)),f),q=f=>{Q(t,Ke(f)),F(t,"onFetchError",f),O(e,t,"onFetchError",f)};let Me=(0,i.isString)(T)?T:void 0;if(v&&(0,i.isFunction)(t.getQuery)){const f=t.getQuery(l.name||"paths");f&&(Me=f.select||f.length&&f.join(",")||Me)}const fe=Ee(Ae,t,r),D=oe(g,t),ke=oe(P,t),le=Qe(e),de=De(e)||le?null:Ne(Ce),bt=nt(e,le||ut(p)),Je=ne(t,r),y=de?qe(e,fe,u,Je,D,ke):null;if(!n.__fetchInitialized&&y&&(n.__fetchInitialized=!0,V!==void 0)){const f=(0,i.isFunction)(V)?V():V;se(y,f,null)}if((p==="select"||p==="rpc")&&y&&de&&!s.refresh&&!s.force){const f=re(y);if(f&&!f.error){const d=Date.now()-f.time,w=f.stale||d>(de.staleTime||0);j&&(0,i.isArray)(f.data)&&!n.__pages&&(n.__pages=[f.data],ct(n,e,f.data));const _=B(f.data);if(!a())return;if(!w){Q(t,Be),U(t,_,C);return}U(t,_,C)}else if(W!==void 0){const d=(0,i.isFunction)(W)?W(t,t.state):W;d!==void 0&&U(t,d,C)}}const pe=y&&!s.force?I.get(y):null;if(pe&&!Ie(y,Re.get(pe)||0)){try{const f=await Promise.race([pe,new Promise((d,w)=>setTimeout(()=>w("DEDUP_TIMEOUT"),15e3))]);if(!a())return;if(f?.error)q(f.error);else if(f?.data!==void 0){const d=!j&&ge(y,Re.get(pe)||0),w=B(d?d.data:f.data);if(!a())return;U(t,w,C),F(t,"onFetchComplete",w),O(e,t,"onFetchComplete",w)}}catch(f){if(!a())return;f!=="DEDUP_TIMEOUT"&&q(f)}return}const St=!re(y)?.data;Q(t,{isFetching:!0,isLoading:St,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),F(t,"onFetchStart"),O(e,t,"onFetchStart");const k=r?.analyze?.emitNetwork,Oe=k?typeof performance<"u"?performance.now():Date.now():0;k&&k({phase:"start",mode:"query",from:h,method:p,cacheKey:y,lang:Je});const wt=async()=>{if(!a())return;if(ce!==!1&&l.auth!==!1&&l.getSession){const _=await l.getSession();if(!a())return;if(ce===!0&&!_){const b={message:"Not authenticated"};return q(b),{data:null,error:b}}}const f=l[p];if(!(0,i.isFunction)(f))return{data:null,error:{message:`Method "${p}" not found on adapter`}};const d={from:h,select:Me,params:fe,single:ue,limit:z,offset:R,order:S,headers:te,baseUrl:E};G!==void 0&&(d.responseType=G);const w=ne(t,r);if(w&&(d.headers={...d.headers,"Accept-Language":w}),D!==void 0){if((0,i.isObject)(D))D.offset!==void 0&&(d.offset=D.offset),D.limit!==void 0&&(d.limit=D.limit),D.cursor!==void 0&&(d.params={...d.params,cursor:D.cursor});else if(typeof D=="number"){const _=e.pageSize||z||20;d.offset=(D-1)*_,d.limit=_}}if(ke!==void 0&&(d.params={...d.params,cursor:ke}),p==="insert"||p==="update"||p==="upsert"){let _;if(Y===!0||e.on==="submit")_=ae(t);else if((0,i.isArray)(Y)){const b=ae(t);_={};for(const K of Y)_[K]=b[K]}else t.state?.parse?_=t.state.parse():(0,i.isObject)(t.state)&&(_={...t.state});$&&(_=$(_,t,t.state)),d.data=_}if(p==="rpc"){let _=fe;if(e.on==="submit"){const b=ae(t);_=e.transformParams?e.transformParams(b,t,t.state):b}d.params=_,d.read=!le&&e.read!==!1}if(p==="subscribe"){if((0,i.isFunction)(n.__unsubscribe)){const b=n.__unsubscribe;n.__unsubscribe=null;try{b()}catch{}}const _=l.subscribe({from:h,params:fe,on:e.subscribeOn},(b,K,He)=>{a()&&(U(t,b,C),F(t,"onFetchComplete",b),O(e,t,"onFetchComplete",b))});return a()?(n.__unsubscribe=_,{data:null,error:null,subscribed:!0}):((0,i.isFunction)(_)&&_(),{data:null,error:null,subscribed:!0})}return f(d)},J=++Se,he=ot(wt,bt);Re.set(he,J),y&&I.set(y,he);try{const f=await he;if(le&&e.invalidates&&f&&!f.error&&!f.subscribed&<(e.invalidates,h),!a()||f?.subscribed)return;const{data:d,error:w}=f||{};if(w){y&&!ge(y,J)&&se(y,null,w,J),q(w),k&&k({phase:"error",mode:"query",from:h,method:p,cacheKey:y,error:w.message||w,durationMs:(typeof performance<"u"?performance.now():Date.now())-Oe});return}if(d!==void 0){let _=d;if((p==="select"||p==="rpc")&&y){const K=!j&&ge(y,J);if(K)_=K.data;else{const He=se(y,d,null,J,Ie(y,J));He.gcTime=de?.gcTime||3e5}}let b=_;if(j&&(0,i.isArray)(d)&&((!n.__pages||!s.direction)&&(n.__pages=[]),s.direction==="previous"?n.__pages.unshift(d):n.__pages.push(d),b=n.__pages.flat(),ct(n,e,d)),b=B(b),!a())return;Q(t,Be),(!M||b!==void 0)&&U(t,b,C),F(t,"onFetchComplete",b),O(e,t,"onFetchComplete",b),k&&k({phase:"success",mode:"query",ok:!0,from:h,method:p,cacheKey:y,durationMs:(typeof performance<"u"?performance.now():Date.now())-Oe})}}catch(f){if(!a())return;q(f),k&&k({phase:"error",mode:"query",from:h,method:p,cacheKey:y,error:f.message||String(f),durationMs:(typeof performance<"u"?performance.now():Date.now())-Oe})}finally{y&&I.get(y)===he&&I.delete(y)}},Qt=(e,t,r)=>{const s=e.on,o=t.__ref;if(!o)return;o.__fetchListeners||(o.__fetchListeners=[]);const n=e.__runner||L;if(s==="submit"){const u=a=>{a.preventDefault(),n(e,t,r)},c=t.node;c&&(c.addEventListener("submit",u),o.__fetchListeners.push(()=>c.removeEventListener("submit",u)))}else if(s==="click"){const u=()=>n(e,t,r),c=t.node;c&&(c.addEventListener("click",u),o.__fetchListeners.push(()=>c.removeEventListener("click",u)))}else s==="stateChange"&&$t(e,t,r,n)},$t=(e,t,r,s)=>{const o=t.__ref;let n;const u=(0,ht.createEffect)(()=>{let c;try{c=JSON.stringify([Ee(e.params,t,r)??null,(0,i.isFunction)(e.enabled)?!!e.enabled(t,t.state):e.enabled!==!1,(0,i.isFunction)(e.skip)?!!e.skip(t,t.state):e.skip===!0,oe(e.page,t)??null])}catch{return}if(n===void 0){n=c;return}c!==n&&(n=c,queueMicrotask(()=>s(e,t,r)))});Array.isArray(o.__effects)?o.__effects.push(u):o.__fetchListeners.push(()=>u.dispose())},zt=(e,t,r)=>{const s=t.__ref;s.__fetchCleanups||(s.__fetchCleanups=[]),It();const o=e.refetchInterval;if(o){const a=typeof o=="number"?o:ee(o);if(a>0){const l=setInterval(()=>{(e.refetchIntervalInBackground||typeof document>"u"||document.visibilityState==="visible")&&L(e,t,r,{force:!0})},a);s.__fetchCleanups.push(()=>clearInterval(l))}}const n=De(e),u=e.refetchOnWindowFocus===void 0?!n:e.refetchOnWindowFocus!==!1,c=e.refetchOnReconnect===void 0?!n:e.refetchOnReconnect!==!1;if(u){const a=()=>{const l=$e(e,t,r),h=re(l),p=Ne(e.cache);(!h||h.stale||Date.now()-h.time>(p?.staleTime||0))&&L(e,t,r,{force:!0})};X.focus.add(a),s.__fetchCleanups.push(()=>X.focus.delete(a))}if(c){const a=()=>L(e,t,r,{force:!0});X.online.add(a),s.__fetchCleanups.push(()=>X.online.delete(a))}},jt=(e,t,r)=>{if(!t.optimistic)return null;const s=e.__ref,o=t.as,n=e.state?.parse?e.state.parse():(0,i.isObject)(e.state)?{...e.state}:e.state;s.__optimisticSnapshot=n;const u=(0,i.isFunction)(t.optimistic)?t.optimistic(r,n,e):t.optimistic;return u!==void 0&&U(e,u,o),n},xe=(e,t)=>{const r=e.__ref;if(!r||!t.optimistic)return;const s=r.__optimisticSnapshot;s!==void 0&&(U(e,s,t.as),delete r.__optimisticSnapshot)},Ye=e=>{if(!e)return()=>!0;if((0,i.isString)(e))return t=>t.includes(e);if((0,i.isArray)(e)){const t=e.join(":");return r=>r.includes(t)}return e instanceof RegExp?t=>(e.lastIndex=0,e.test(t)):(0,i.isFunction)(e)?t=>{try{return!!e(t)}catch{return!1}}:()=>!1},Bt=e=>{const t=[];for(const r of N){if(!rt(r)){N.delete(r);continue}const s=Rt(r);s&&e(s)&&t.push(L(r.config,r.element,r.context,{refresh:!0}))}return Promise.allSettled(t).then(()=>{})},ft=e=>{(0,_t.dropEarly)();for(const[t,r]of m)e(t)&&(r.stale=!0,Te(t));for(const[t]of I)!m.has(t)&&e(t)&&Te(t);return Bt(e)},lt=(e,t)=>{const r=((0,i.isArray)(e)?e:[e]).map(s=>s===!0||s==="*"?o=>o.startsWith(t+":"):s?Ye(s):()=>!1);return ft(s=>r.some(o=>o(s)))},Ge=e=>{for(const[t]of m)e(t)&&tt(t);for(const[t]of I)e(t)&&Te(t)},We=()=>!0,dt=new WeakSet,Z=e=>{!e||!e.isolateFetchCache||dt.has(e)||(dt.add(e),Ge(We),N.clear())},Kt=async(e,t,r)=>{const s=r?.fetch;if(!s)return;const o=await ze(s,r);if(!o)return;const n=t.__ref,{method:u,from:c,fields:a,transform:l,as:h,on:p,auth:v,headers:Ae,baseUrl:Ce,responseType:$,invalidates:ue,optimistic:ce,onMutate:Y,onSuccess:C,onError:z,onSettled:R}=e;let S;if(a===!0||p==="submit")S=ae(t);else if((0,i.isArray)(a)){const g=ae(t);S={};for(const P of a)S[P]=g[P]}else t.state?.parse?S=t.state.parse():(0,i.isObject)(t.state)&&(S={...t.state});l&&(S=l(S,t,t.state)),(0,i.isFunction)(Y)&&Y(S,t,t.state);const te=ce?jt(t,e,S):null;Q(t,{isFetching:!0,isLoading:!1,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),F(t,"onFetchStart"),O(e,t,"onFetchStart");const E=r?.analyze?.emitNetwork,G=E?typeof performance<"u"?performance.now():Date.now():0;E&&E({phase:"start",mode:"mutation",from:c,method:u});try{if(v!==!1&&o.auth!==!1&&o.getSession){const B=await o.getSession();if(v===!0&&!B){te!==void 0&&xe(t,e);const q={message:"Not authenticated"};F(t,"onFetchError",q),O(e,t,"onFetchError",q);return}}const g=o[u];if(!(0,i.isFunction)(g))return;const P={from:c,data:S,headers:Ae,baseUrl:Ce};$!==void 0&&(P.responseType=$),e.params&&(P.params=Ee(e.params,t,r));const j=ne(t,r);j&&(P.headers={...P.headers,"Accept-Language":j});const W=nt(e,!0),V=await ot(()=>g(P),W),{data:T,error:M}=V||{};if(M){te!==void 0&&xe(t,e),Q(t,Ke(M)),F(t,"onFetchError",M),(0,i.isFunction)(z)&&z(M,S,t),(0,i.isFunction)(R)&&R(null,M,S,t),E&&E({phase:"error",mode:"mutation",from:c,method:u,error:M.message||String(M),durationMs:(typeof performance<"u"?performance.now():Date.now())-G});return}if(delete n.__optimisticSnapshot,Q(t,Be),T!==void 0&&(h||!je(T))){const B=h?{[h]:T}:T;t.state?.update&&t.state.update(B,{preventFetch:!0})}F(t,"onFetchComplete",T),O(e,t,"onFetchComplete",T),(0,i.isFunction)(C)&&C(T,S,t),(0,i.isFunction)(R)&&R(T,null,S,t),E&&E({phase:"success",mode:"mutation",ok:!0,from:c,method:u,durationMs:(typeof performance<"u"?performance.now():Date.now())-G}),ue&<(ue,c)}catch(g){te!==void 0&&xe(t,e),Q(t,Ke(g)),F(t,"onFetchError",g),O(e,t,"onFetchError",g),(0,i.isFunction)(z)&&z(g,S,t),(0,i.isFunction)(R)&&R(null,g,S,t),E&&E({phase:"error",mode:"mutation",from:c,method:u,error:g.message||String(g),durationMs:(typeof performance<"u"?performance.now():Date.now())-G})}finally{n.__fetching=!1}},xt=e=>{const t=r=>{try{r()}catch{}};for(const r of e.__fetchCleanups||[])t(r);for(const r of e.__fetchListeners||[])t(r);(0,i.isFunction)(e.__unsubscribe)&&t(e.__unsubscribe);for(const r of e.__fetchMounted||[])N.delete(r);e.__fetchCleanups=[],e.__fetchListeners=[],e.__unsubscribe=null,e.__fetchMounted=[]},Ve=(e,t,r,s)=>{if(!e||!s?.fetch)return;Z(s);const n=(0,i.exec)(e,t);if(!n)return;const u=(0,i.isArray)(n)?n.map(a=>it((0,i.exec)(a,t),t)).filter(Boolean):[it(n,t)].filter(Boolean),c=t.__ref;if(c.__fetchMounted)for(const a of c.__fetchMounted)N.delete(a);c.__fetchMounted=[],!c.__fetchDisposer&&(0,i.isArray)(c.__effects)&&(c.__fetchDisposer={dispose:()=>xt(c)},c.__effects.push(c.__fetchDisposer));for(const a of u){const l=ut(a.method),h=l?Kt:L,p=!l&&!Qe(a)&&a.method!=="subscribe";if(a.on==="create"?h(a,t,s):queueMicrotask(()=>Qt({...a,__runner:h},t,s)),p&&a.on==="create"&&((a.refetchInterval||a.refetchOnWindowFocus!==!1||a.refetchOnReconnect!==!1)&&zt(a,t,s),!De(a))){const v={element:t,ref:c,config:a,context:s};N.add(v),c.__fetchMounted.push(v)}}c.refetch=a=>{for(const l of u)L(l,t,s,{force:!0,...a})},c.fetchNextPage=()=>{const a=u[0];if(!a||!a.infinite)return;const l=c.__nextPageParam;if(l==null)return;const h={...a,cursor:l};L(h,t,s,{direction:"next",force:!0})},c.fetchPreviousPage=()=>{const a=u[0];if(!a||!a.infinite)return;const l=c.__prevPageParam;if(l==null)return;const h={...a,cursor:l};L(h,t,s,{direction:"previous",force:!0})}},ie={invalidateQueries:e=>ft(Ye(e)),removeQueries:e=>{Ge(e?Ye(e):We)},getQueryData:e=>re(e)?.data??void 0,setQueryData:(e,t)=>{const r=re(e),s=(0,i.isFunction)(t)?t(r?.data):t;se(e,s,null)},prefetchQuery:async(e,t)=>{const r=t?.fetch;if(!r)return;Z(t);const s=await ze(r,t);if(!s)return;const o=e.method||"select",n=ve(null,t),u=ne(null,t),c=qe({...e,method:o},e.params,n,u),a=s[o];if(!(0,i.isFunction)(a))return;const l={from:e.from,params:e.params,limit:e.limit,offset:e.offset,order:e.order,single:e.single,headers:e.headers,baseUrl:e.baseUrl};u&&(l.headers={...l.headers,"Accept-Language":u}),e.responseType!==void 0&&(l.responseType=e.responseType),o==="rpc"&&(l.read=!Qe(e)&&e.read!==!1);const h=++Se,p=await a(l);if(p?.data!==void 0&&!p?.error&&!De(e)&&!ge(c,h)){const v=se(c,p.data,null,h,Ie(c,h));v.gcTime=Ne(e.cache)?.gcTime||3e5}return p},getCache:()=>m,clear:()=>Ge(We),dropNonLang:e=>{if(!e)return;const t=`:${e}`;for(const[r]of m)r.match(/:([a-z]{2,3})$/i)&&(r.endsWith(t)||tt(r))}},pt=(e,t)=>(0,i.isObject)(e)?$e({method:"select",...e},t,t?.context):e,Yt={invalidateQueries(e){return Z(this?.context),ie.invalidateQueries(e)},removeQueries(e){return Z(this?.context),ie.removeQueries(e)},getQueryData(e){return Z(this?.context),ie.getQueryData(pt(e,this))},setQueryData(e,t){return Z(this?.context),ie.setQueryData(pt(e,this),t)}},Gt={name:"fetch",create(e){const t=e.fetch;t&&(e.parent||I.clear(),Ve(t,e,e.state,e.context))}};var Wt=Ve;
|
|
1
|
+
"use strict";var gt=Object.create;var _e=Object.defineProperty;var vt=Object.getOwnPropertyDescriptor;var mt=Object.getOwnPropertyNames;var Tt=Object.getPrototypeOf,Et=Object.prototype.hasOwnProperty;var Dt=(e,t)=>{for(var r in t)_e(e,r,{get:t[r],enumerable:!0})},xe=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of mt(t))!Et.call(e,o)&&o!==r&&_e(e,o,{get:()=>t[o],enumerable:!(s=vt(t,o))||s.enumerable});return e};var Je=(e,t,r)=>(r=e!=null?gt(Tt(e)):{},xe(t||!e||!e.__esModule?_e(r,"default",{value:e,enumerable:!0}):r,e)),Pt=e=>xe(_e({},"__esModule",{value:!0}),e);var Jt={};Dt(Jt,{EARLY_KEY:()=>M.EARLY_KEY,SEED_BLOCK:()=>M.SEED_BLOCK,createAdapter:()=>Lt,createEarlySeedBlock:()=>M.createEarlySeedBlock,createEarlySeedScript:()=>M.createEarlySeedScript,default:()=>xt,earlyKey:()=>M.earlyKey,executeFetch:()=>Ge,fetchFunctions:()=>Wt,fetchPlugin:()=>Vt,hasAdapter:()=>Ot,initAdapterAuth:()=>De,parseDuration:()=>ee,queryClient:()=>Gt,registerAdapter:()=>kt,requestsInFlight:()=>Pe.requestsInFlight,resolveDb:()=>yt,whenRequestsIdle:()=>Pe.whenRequestsIdle});module.exports=Pt(Jt);var i=require("@symbo.ls/utils"),ht=require("@symbo.ls/signal"),_t=require("./early.js"),Ft=Je(require("./adapters/rest.js"),1),M=require("./early.js"),Pe=require("./inflight.js");const At=["select","rpc","insert","update","upsert","delete","subscribe"],He={rest:()=>Promise.resolve(Ft),local:()=>import("./adapters/local.js")},ye=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),X=(()=>{if(typeof globalThis<"u"&&globalThis[ye])return globalThis[ye];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,ye,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[ye]}catch{}return e})(),be=Symbol.for("@symbo.ls/fetch:PENDING_ADAPTERS"),Me=(()=>{if(typeof globalThis<"u"&&globalThis[be])return globalThis[be];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,be,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[be]}catch{}return e})(),Ct=5e3,Mt=e=>new Promise(t=>{if(X[e])return t(X[e]);const r=Me[e]||=[];let s=!1;const o=()=>{s||(s=!0,t(X[e]||null))};r.push(o),setTimeout(o,Ct)}),kt=(e,t)=>{X[e]=t;const r=Me[e];if(r&&r.length){Me[e]=[];for(const s of r)s()}},Ot=e=>typeof e=="string"&&!!(X[e]||He[e]),Lt=e=>{const t={};for(const r of At)e[r]&&(t[r]=e[r]);return t.name=e.name||"custom",t},yt=async e=>{if(!e)return null;if(typeof e.select=="function")return e;const{adapter:t,...r}=e,s=typeof t=="string"?t:typeof e=="string"?e:null;if(!s)return null;let o=X[s]||He[s];if(!o&&(o=await Mt(s),!o))throw new Error(`Unknown db adapter: "${s}". Use registerAdapter() for adapters with optional deps.`);const n=await o();if(!n||typeof n.setup!="function")throw new Error(`Adapter "${s}" loader returned a module without a setup() function. Got keys: [${Object.keys(n||{}).join(", ")}]. Likely a bundler chunk-resolution issue.`);return n.setup(r)},ee=e=>{if(!e)return 0;if(typeof e=="number")return e;const t=e.match(/^(\d+)(ms|s|m|h)$/);if(!t)return 0;const r=parseInt(t[1]),s=t[2];return s==="ms"?r:s==="s"?r*1e3:s==="m"?r*6e4:s==="h"?r*36e5:0},Xe=e=>!!e&&!!e.isolateFetchCache,Ze=()=>({cache:new Map,subscribers:new Map,active:new Map,invalidatedAt:new Map,mounted:new Set}),A=Ze(),et=new WeakMap,P=e=>{if(!Xe(e))return A;let t=et.get(e);return t||et.set(e,t=Ze()),t};let Se=0;const ke=new WeakMap,Oe=(e,t,r,s,o=e.page,n=e.cursor)=>{if(e.cache?.key)return e.cache.key;const{from:a,method:c,infinite:f}=e,y=r?`${r}:`:"",u=s?`:${s}`:"",d=o?":p"+JSON.stringify(o):"",S=n!=null?":c"+JSON.stringify(n):"";return`${a}:${c}:${y}${JSON.stringify(t||"")}${f?":infinite":""}${d}${S}${u}`},re=(e,t)=>e.cache.get(t)||null,se=(e,t,r,s,o=++Se,n=!1)=>{const a={data:r,error:s,time:Date.now(),stale:n,seq:o};e.cache.set(t,a);const c=e.subscribers.get(t);if(c)for(const f of c)(0,i.isFunction)(f)&&f(a);return a},we=(e,t,r)=>{const s=t?e.cache.get(t):null;return s&&!s.error&&s.seq>r?s:null},Le=(e,t,r)=>(e.invalidatedAt.get(t)||0)>r,ge=(e,t)=>{e.invalidatedAt.set(t,++Se)},tt=(e,t)=>{e.cache.delete(t),ge(e,t)},Xt=(e,t,r)=>{const{subscribers:s}=e;return s.has(t)||s.set(t,new Set),s.get(t).add(r),()=>{const o=s.get(t);o&&(o.delete(r),o.size===0&&s.delete(t))}},Re=e=>!e&&e!==!1?{staleTime:6e4,gcTime:3e5}:e===!1?null:e===!0?{staleTime:6e4,gcTime:3e5}:typeof e=="number"?{staleTime:e,gcTime:Math.max(e*5,3e5)}:(0,i.isString)(e)?{staleTime:ee(e),gcTime:3e5}:{staleTime:ee(e.stale||e.staleTime)||6e4,gcTime:ee(e.gc||e.gcTime||e.expire)||3e5,key:e.key},rt=e=>!!e.ref&&e.element.__ref===e.ref,Rt=({config:e,element:t,context:r})=>{try{return Ne(e,t,r)}catch{return null}};let ve=null;const It=()=>{ve||(ve=setInterval(()=>{const e=Date.now(),{cache:t,subscribers:r,active:s,invalidatedAt:o,mounted:n}=A;for(const[a,c]of t){const f=r.get(a);!(f&&f.size>0)&&e-c.time>(c.gcTime||3e5)&&t.delete(a)}for(const[a]of o)!t.has(a)&&!s.has(a)&&o.delete(a);for(const a of n)rt(a)||n.delete(a)},3e4),ve.unref&&ve.unref())};It();const st=3,Ie=e=>Math.min(1e3*2**e,3e4),nt=(e,t)=>{const r=e.retry;return r===void 0&&t?{count:0}:r===!1?{count:0}:r===!0||r===void 0?{count:st,delay:Ie}:typeof r=="number"?{count:r,delay:Ie}:{count:r.count??st,delay:(0,i.isFunction)(r.delay)?r.delay:typeof r.delay=="number"?()=>r.delay:Ie}},ot=async(e,t)=>{const{count:r,delay:s}=t;let o;for(let n=0;n<=r;n++)try{const a=await e();if(a?.error){if(o=a.error,n<r){const c=(0,i.isFunction)(s)?s(n,o):s;await new Promise(f=>setTimeout(f,c));continue}return a}return a}catch(a){if(o=a,n<r){const c=(0,i.isFunction)(s)?s(n,a):s;await new Promise(f=>setTimeout(f,c));continue}throw a}return{data:null,error:o}},Z={focus:new Set,online:new Set};let at=!1;const qt=()=>{if(at||typeof window>"u")return;at=!0;const e=()=>{for(const r of Z.focus)r()},t=()=>{for(const r of Z.online)r()};window.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&e()}),window.addEventListener("focus",e),window.addEventListener("online",t)},it=(e,t)=>{const r=t.__ref;if(e===!0)return{from:r.__state||t.key,method:"select",query:!0,on:"create"};if((0,i.isString)(e))return{from:e,method:"select",query:!0,on:"create"};if((0,i.isObject)(e)){const s={...e};return s.from=s.from||r.__state||t.key,s.method=s.method||"select",s.on=s.on||"create",s.query===void 0&&(s.query=!0),s}return null},Nt=["insert","update","upsert","delete"],ct=e=>Nt.includes(e),qe=e=>e.mutation===!0?!0:e.mutation===!1||e.method!=="rpc"?!1:e.on==="submit"||e.on==="click"||e.invalidates!=null,ne=(e,t)=>{const r=e?.state?.root||t?.state?.root;if(r?.lang)return r.lang},me=(e,t)=>{const s=(e?.state?.root||t?.state?.root)?.__fetchScope;return s?String(s):void 0},Te=(e,t,r)=>{let s;if(!e)s=void 0;else if((0,i.isFunction)(e))s=e(t,t.state);else{s={};for(const o in e){const n=e[o];s[o]=(0,i.isFunction)(n)?n(t,t.state):n}}return s},oe=(e,t)=>(0,i.isFunction)(e)?e(t,t.state):e,Ne=(e,t,r)=>Oe(e,Te(e.params,t,r),me(t,r),ne(t,r),oe(e.page,t),oe(e.cursor,t)),De=async(e,t)=>{if(!e||e.__authInitialized||(e.__authInitialized=!0,!e.getSession))return;const r=(s,o)=>{const n=t.state?.root;n?.update&&n.update({auth:{user:s,session:o,loading:!1}})};try{const s=await e.getSession();r(s?.user||null,s)}catch(s){console.warn("[fetch] Failed to restore auth session:",s.message)}e.onAuthStateChange&&e.onAuthStateChange((s,o)=>{r(o?.user||null,o)})},Ue=async(e,t)=>{if((0,i.isFunction)(e.select))return e.auth!==!1&&await De(e,t),e;if(e.__resolved)return e.auth!==!1&&await De(e.__resolved,t),e.__resolved;if(e.__resolving)return e.__resolving;e.__resolving=yt(e);const r=await e.__resolving;return delete e.__resolving,r?(r.auth=e.auth,r.url=e.url,r.key=e.key,e.__resolved=r,t.fetch=r,e.auth!==!1&&await De(r,t),r):null},C=(e,t,...r)=>{const s=(0,i.isFunction)(e[t])?e[t]:null;s&&s.call(e,...r,e,e.state,e.context)},R=(e,t,r,...s)=>{const o=e&&(0,i.isFunction)(e[r])?e[r]:null;o&&o.call(t,...s,t,t.state,t.context)},ae=e=>{const t={},r=e.node;if(!r)return t;if(r.tagName==="FORM"){const o=new FormData(r);for(const[n,a]of o.entries())t[n]=a;return t}const s=r.querySelectorAll("input, textarea, select");for(let o=0;o<s.length;o++){const n=s[o],a=n.name||n.getAttribute("name");a&&(n.type==="checkbox"?t[a]=n.checked:n.type==="file"?t[a]=n.files:t[a]=n.value)}return t},Ee=e=>e.responseType==="stream"||e.responseType==="response",Ut=["Blob","File","ArrayBuffer","ReadableStream","Response"],$e=e=>e!==null&&typeof e=="object"&&(ArrayBuffer.isView(e)||Ut.includes(Object.prototype.toString.call(e).slice(8,-1))),U=(e,t,r,s={})=>{if(!r&&$e(t))return;const o=r&&r.startsWith("~/"),n=o&&e.state?.root||e.state;if(n?.update)if(o){const a=r.slice(2);t&&typeof t=="object"&&!Array.isArray(t)&&!$e(t)&&a in t?n.update(t,{preventFetch:!0,...s}):n.update({[a]:t},{preventFetch:!0,...s})}else{const a=r?{[r]:t}:t;n.update(a,{preventFetch:!0,...s})}},Qe=Object.freeze({isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),ze=e=>({isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:e,status:"error",fetchStatus:"idle"}),$=(e,t)=>{const r=e?.__ref;r&&(r.__fetchStatus={...t,isError:!!t.error},r.__fetching=t.isFetching,r.__fetchError=t.error)},ut=(e,t,r)=>{const s=e.__pages&&e.__pages.length?e.__pages:[r];(0,i.isFunction)(t.getNextPageParam)&&(e.__nextPageParam=t.getNextPageParam(s[s.length-1],s),e.__hasNextPage=e.__nextPageParam!=null),(0,i.isFunction)(t.getPreviousPageParam)&&(e.__prevPageParam=t.getPreviousPageParam(s[0],s),e.__hasPreviousPage=e.__prevPageParam!=null)},I=async(e,t,r,s={})=>{const o=r?.fetch;if(!o||!t||!t.__ref)return;const n=t.__ref,a=me(t,r);(!n.__fetchScopeOwner||n.__fetchScopeOwner.scope!==a)&&(n.__fetchScopeOwner={scope:a});const c=n.__fetchScopeOwner,f=()=>t.__ref===n&&n.__fetchScopeOwner===c&&me(t,r)===a;if(e.enabled===!1||(0,i.isFunction)(e.enabled)&&!e.enabled(t,t.state)||e.skip===!0||(0,i.isFunction)(e.skip)&&e.skip(t,t.state))return;const y=await Ue(o,r);if(!y||!f())return;const{from:u,method:d,query:S,params:Q,cache:G,transform:z,single:ce,auth:ue,fields:W,as:k,limit:j,offset:q,order:w,headers:te,baseUrl:E,responseType:V,page:m,cursor:F,infinite:B,placeholderData:x,initialData:J,select:T,keepPreviousData:O}=e,K=l=>((0,i.isFunction)(T)&&(l=T(l,t,t.state)),z&&(l=z(l,t,t.state)),l),N=l=>{$(t,ze(l)),C(t,"onFetchError",l),R(e,t,"onFetchError",l)};let Fe=(0,i.isString)(T)?T:void 0;if(S&&(0,i.isFunction)(t.getQuery)){const l=t.getQuery(y.name||"paths");l&&(Fe=l.select||l.length&&l.join(",")||Fe)}const fe=Te(Q,t,r),D=oe(m,t),Ae=oe(F,t),le=qe(e),de=Ee(e)||le?null:Re(G),bt=nt(e,le||ct(d)),We=ne(t,r),_=de?Oe(e,fe,a,We,D,Ae):null,v=P(r);if(!n.__fetchInitialized&&_&&(n.__fetchInitialized=!0,J!==void 0)){const l=(0,i.isFunction)(J)?J():J;se(v,_,l,null)}if((d==="select"||d==="rpc")&&_&&de&&!s.refresh&&!s.force){const l=re(v,_);if(l&&!l.error){const p=Date.now()-l.time,g=l.stale||p>(de.staleTime||0);B&&(0,i.isArray)(l.data)&&!n.__pages&&(n.__pages=[l.data],ut(n,e,l.data));const h=K(l.data);if(!f())return;if(!g){$(t,Qe),U(t,h,k);return}U(t,h,k)}else if(x!==void 0){const p=(0,i.isFunction)(x)?x(t,t.state):x;p!==void 0&&U(t,p,k)}}const pe=_&&!s.force?v.active.get(_):null;if(pe&&!Le(v,_,ke.get(pe)||0)){try{const l=await Promise.race([pe,new Promise((p,g)=>setTimeout(()=>g("DEDUP_TIMEOUT"),15e3))]);if(!f())return;if(l?.error)N(l.error);else if(l?.data!==void 0){const p=!B&&we(v,_,ke.get(pe)||0),g=K(p?p.data:l.data);if(!f())return;U(t,g,k),C(t,"onFetchComplete",g),R(e,t,"onFetchComplete",g)}}catch(l){if(!f())return;l!=="DEDUP_TIMEOUT"&&N(l)}return}const St=!re(v,_)?.data;$(t,{isFetching:!0,isLoading:St,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),C(t,"onFetchStart"),R(e,t,"onFetchStart");const L=r?.analyze?.emitNetwork,Ce=L?typeof performance<"u"?performance.now():Date.now():0;L&&L({phase:"start",mode:"query",from:u,method:d,cacheKey:_,lang:We});const wt=async()=>{if(!f())return;if(ue!==!1&&y.auth!==!1&&y.getSession){const h=await y.getSession();if(!f())return;if(ue===!0&&!h){const b={message:"Not authenticated"};return N(b),{data:null,error:b}}}const l=y[d];if(!(0,i.isFunction)(l))return{data:null,error:{message:`Method "${d}" not found on adapter`}};const p={from:u,select:Fe,params:fe,single:ce,limit:j,offset:q,order:w,headers:te,baseUrl:E};V!==void 0&&(p.responseType=V);const g=ne(t,r);if(g&&(p.headers={...p.headers,"Accept-Language":g}),D!==void 0){if((0,i.isObject)(D))D.offset!==void 0&&(p.offset=D.offset),D.limit!==void 0&&(p.limit=D.limit),D.cursor!==void 0&&(p.params={...p.params,cursor:D.cursor});else if(typeof D=="number"){const h=e.pageSize||j||20;p.offset=(D-1)*h,p.limit=h}}if(Ae!==void 0&&(p.params={...p.params,cursor:Ae}),d==="insert"||d==="update"||d==="upsert"){let h;if(W===!0||e.on==="submit")h=ae(t);else if((0,i.isArray)(W)){const b=ae(t);h={};for(const Y of W)h[Y]=b[Y]}else t.state?.parse?h=t.state.parse():(0,i.isObject)(t.state)&&(h={...t.state});z&&(h=z(h,t,t.state)),p.data=h}if(d==="rpc"){let h=fe;if(e.on==="submit"){const b=ae(t);h=e.transformParams?e.transformParams(b,t,t.state):b}p.params=h,p.read=!le&&e.read!==!1}if(d==="subscribe"){if((0,i.isFunction)(n.__unsubscribe)){const b=n.__unsubscribe;n.__unsubscribe=null;try{b()}catch{}}const h=y.subscribe({from:u,params:fe,on:e.subscribeOn},(b,Y,Ve)=>{f()&&(U(t,b,k),C(t,"onFetchComplete",b),R(e,t,"onFetchComplete",b))});return f()?(n.__unsubscribe=h,{data:null,error:null,subscribed:!0}):((0,i.isFunction)(h)&&h(),{data:null,error:null,subscribed:!0})}return l(p)},H=++Se,he=ot(wt,bt);ke.set(he,H),_&&v.active.set(_,he);try{const l=await he;if(le&&e.invalidates&&l&&!l.error&&!l.subscribed&&ft(v,e.invalidates,u),!f()||l?.subscribed)return;const{data:p,error:g}=l||{};if(g){_&&!we(v,_,H)&&se(v,_,null,g,H),N(g),L&&L({phase:"error",mode:"query",from:u,method:d,cacheKey:_,error:g.message||g,durationMs:(typeof performance<"u"?performance.now():Date.now())-Ce});return}if(p!==void 0){let h=p;if((d==="select"||d==="rpc")&&_){const Y=!B&&we(v,_,H);if(Y)h=Y.data;else{const Ve=se(v,_,p,null,H,Le(v,_,H));Ve.gcTime=de?.gcTime||3e5}}let b=h;if(B&&(0,i.isArray)(p)&&((!n.__pages||!s.direction)&&(n.__pages=[]),s.direction==="previous"?n.__pages.unshift(p):n.__pages.push(p),b=n.__pages.flat(),ut(n,e,p)),b=K(b),!f())return;$(t,Qe),(!O||b!==void 0)&&U(t,b,k),C(t,"onFetchComplete",b),R(e,t,"onFetchComplete",b),L&&L({phase:"success",mode:"query",ok:!0,from:u,method:d,cacheKey:_,durationMs:(typeof performance<"u"?performance.now():Date.now())-Ce})}}catch(l){if(!f())return;N(l),L&&L({phase:"error",mode:"query",from:u,method:d,cacheKey:_,error:l.message||String(l),durationMs:(typeof performance<"u"?performance.now():Date.now())-Ce})}finally{_&&v.active.get(_)===he&&v.active.delete(_)}},$t=(e,t,r)=>{const s=e.on,o=t.__ref;if(!o)return;o.__fetchListeners||(o.__fetchListeners=[]);const n=e.__runner||I;if(s==="submit"){const a=f=>{f.preventDefault(),n(e,t,r)},c=t.node;c&&(c.addEventListener("submit",a),o.__fetchListeners.push(()=>c.removeEventListener("submit",a)))}else if(s==="click"){const a=()=>n(e,t,r),c=t.node;c&&(c.addEventListener("click",a),o.__fetchListeners.push(()=>c.removeEventListener("click",a)))}else s==="stateChange"&&Qt(e,t,r,n)},Qt=(e,t,r,s)=>{const o=t.__ref;let n;const a=(0,ht.createEffect)(()=>{let c;try{c=JSON.stringify([Te(e.params,t,r)??null,(0,i.isFunction)(e.enabled)?!!e.enabled(t,t.state):e.enabled!==!1,(0,i.isFunction)(e.skip)?!!e.skip(t,t.state):e.skip===!0,oe(e.page,t)??null])}catch{return}if(n===void 0){n=c;return}c!==n&&(n=c,queueMicrotask(()=>s(e,t,r)))});Array.isArray(o.__effects)?o.__effects.push(a):o.__fetchListeners.push(()=>a.dispose())},zt=(e,t,r)=>{const s=t.__ref;s.__fetchCleanups||(s.__fetchCleanups=[]),qt();const o=e.refetchInterval;if(o){const f=typeof o=="number"?o:ee(o);if(f>0){const y=setInterval(()=>{(e.refetchIntervalInBackground||typeof document>"u"||document.visibilityState==="visible")&&I(e,t,r,{force:!0})},f);s.__fetchCleanups.push(()=>clearInterval(y))}}const n=Ee(e),a=e.refetchOnWindowFocus===void 0?!n:e.refetchOnWindowFocus!==!1,c=e.refetchOnReconnect===void 0?!n:e.refetchOnReconnect!==!1;if(a){const f=()=>{const y=Ne(e,t,r),u=re(P(r),y),d=Re(e.cache);(!u||u.stale||Date.now()-u.time>(d?.staleTime||0))&&I(e,t,r,{force:!0})};Z.focus.add(f),s.__fetchCleanups.push(()=>Z.focus.delete(f))}if(c){const f=()=>I(e,t,r,{force:!0});Z.online.add(f),s.__fetchCleanups.push(()=>Z.online.delete(f))}},jt=(e,t,r)=>{if(!t.optimistic)return null;const s=e.__ref,o=t.as,n=e.state?.parse?e.state.parse():(0,i.isObject)(e.state)?{...e.state}:e.state;s.__optimisticSnapshot=n;const a=(0,i.isFunction)(t.optimistic)?t.optimistic(r,n,e):t.optimistic;return a!==void 0&&U(e,a,o),n},je=(e,t)=>{const r=e.__ref;if(!r||!t.optimistic)return;const s=r.__optimisticSnapshot;s!==void 0&&(U(e,s,t.as),delete r.__optimisticSnapshot)},ie=e=>{if(!e)return()=>!0;if((0,i.isString)(e))return t=>t.includes(e);if((0,i.isArray)(e)){const t=e.join(":");return r=>r.includes(t)}return e instanceof RegExp?t=>(e.lastIndex=0,e.test(t)):(0,i.isFunction)(e)?t=>{try{return!!e(t)}catch{return!1}}:()=>!1},Bt=(e,t)=>{const r=[];for(const s of e.mounted){if(!rt(s)){e.mounted.delete(s);continue}const o=Rt(s);o&&t(o)&&r.push(I(s.config,s.element,s.context,{refresh:!0}))}return Promise.allSettled(r).then(()=>{})},Be=(e,t)=>{(0,_t.dropEarly)();for(const[r,s]of e.cache)t(r)&&(s.stale=!0,ge(e,r));for(const[r]of e.active)!e.cache.has(r)&&t(r)&&ge(e,r);return Bt(e,t)},ft=(e,t,r)=>{const s=((0,i.isArray)(t)?t:[t]).map(o=>o===!0||o==="*"?n=>n.startsWith(r+":"):o?ie(o):()=>!1);return Be(e,o=>s.some(n=>n(o)))},Ke=(e,t)=>{for(const[r]of e.cache)t(r)&&tt(e,r);for(const[r]of e.active)t(r)&&ge(e,r)},Ye=()=>!0,lt=(e,t)=>re(e,t)?.data??void 0,dt=(e,t,r)=>{const s=re(e,t),o=(0,i.isFunction)(r)?r(s?.data):r;se(e,t,o,null)},Kt=async(e,t,r)=>{const s=r?.fetch;if(!s)return;const o=await Ue(s,r);if(!o)return;const n=t.__ref,{method:a,from:c,fields:f,transform:y,as:u,on:d,auth:S,headers:Q,baseUrl:G,responseType:z,invalidates:ce,optimistic:ue,onMutate:W,onSuccess:k,onError:j,onSettled:q}=e;let w;if(f===!0||d==="submit")w=ae(t);else if((0,i.isArray)(f)){const m=ae(t);w={};for(const F of f)w[F]=m[F]}else t.state?.parse?w=t.state.parse():(0,i.isObject)(t.state)&&(w={...t.state});y&&(w=y(w,t,t.state)),(0,i.isFunction)(W)&&W(w,t,t.state);const te=ue?jt(t,e,w):null;$(t,{isFetching:!0,isLoading:!1,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),C(t,"onFetchStart"),R(e,t,"onFetchStart");const E=r?.analyze?.emitNetwork,V=E?typeof performance<"u"?performance.now():Date.now():0;E&&E({phase:"start",mode:"mutation",from:c,method:a});try{if(S!==!1&&o.auth!==!1&&o.getSession){const K=await o.getSession();if(S===!0&&!K){te!==void 0&&je(t,e);const N={message:"Not authenticated"};C(t,"onFetchError",N),R(e,t,"onFetchError",N);return}}const m=o[a];if(!(0,i.isFunction)(m))return;const F={from:c,data:w,headers:Q,baseUrl:G};z!==void 0&&(F.responseType=z),e.params&&(F.params=Te(e.params,t,r));const B=ne(t,r);B&&(F.headers={...F.headers,"Accept-Language":B});const x=nt(e,!0),J=await ot(()=>m(F),x),{data:T,error:O}=J||{};if(O){te!==void 0&&je(t,e),$(t,ze(O)),C(t,"onFetchError",O),(0,i.isFunction)(j)&&j(O,w,t),(0,i.isFunction)(q)&&q(null,O,w,t),E&&E({phase:"error",mode:"mutation",from:c,method:a,error:O.message||String(O),durationMs:(typeof performance<"u"?performance.now():Date.now())-V});return}if(delete n.__optimisticSnapshot,$(t,Qe),T!==void 0&&(u||!$e(T))){const K=u?{[u]:T}:T;t.state?.update&&t.state.update(K,{preventFetch:!0})}C(t,"onFetchComplete",T),R(e,t,"onFetchComplete",T),(0,i.isFunction)(k)&&k(T,w,t),(0,i.isFunction)(q)&&q(T,null,w,t),E&&E({phase:"success",mode:"mutation",ok:!0,from:c,method:a,durationMs:(typeof performance<"u"?performance.now():Date.now())-V}),ce&&ft(P(r),ce,c)}catch(m){te!==void 0&&je(t,e),$(t,ze(m)),C(t,"onFetchError",m),R(e,t,"onFetchError",m),(0,i.isFunction)(j)&&j(m,w,t),(0,i.isFunction)(q)&&q(null,m,w,t),E&&E({phase:"error",mode:"mutation",from:c,method:a,error:m.message||String(m),durationMs:(typeof performance<"u"?performance.now():Date.now())-V})}finally{n.__fetching=!1}},Yt=e=>{const t=r=>{try{r()}catch{}};for(const r of e.__fetchCleanups||[])t(r);for(const r of e.__fetchListeners||[])t(r);(0,i.isFunction)(e.__unsubscribe)&&t(e.__unsubscribe);for(const r of e.__fetchMounted||[])P(r.context).mounted.delete(r);e.__fetchCleanups=[],e.__fetchListeners=[],e.__unsubscribe=null,e.__fetchMounted=[]},Ge=(e,t,r,s)=>{if(!e||!s?.fetch)return;const n=(0,i.exec)(e,t);if(!n)return;const a=(0,i.isArray)(n)?n.map(u=>it((0,i.exec)(u,t),t)).filter(Boolean):[it(n,t)].filter(Boolean),c=t.__ref,f=P(s);if(c.__fetchMounted)for(const u of c.__fetchMounted)f.mounted.delete(u);c.__fetchMounted=[],!c.__fetchDisposer&&(0,i.isArray)(c.__effects)&&(c.__fetchDisposer={dispose:()=>Yt(c)},c.__effects.push(c.__fetchDisposer));const y=!Xe(s);for(const u of a){const d=ct(u.method),S=d?Kt:I,Q=!d&&!qe(u)&&u.method!=="subscribe";if(u.on==="create"?S(u,t,s):queueMicrotask(()=>$t({...u,__runner:S},t,s)),Q&&u.on==="create"&&(y&&(u.refetchInterval||u.refetchOnWindowFocus!==!1||u.refetchOnReconnect!==!1)&&zt(u,t,s),!Ee(u))){const G={element:t,ref:c,config:u,context:s};f.mounted.add(G),c.__fetchMounted.push(G)}}c.refetch=u=>{for(const d of a)I(d,t,s,{force:!0,...u})},c.fetchNextPage=()=>{const u=a[0];if(!u||!u.infinite)return;const d=c.__nextPageParam;if(d==null)return;const S={...u,cursor:d};I(S,t,s,{direction:"next",force:!0})},c.fetchPreviousPage=()=>{const u=a[0];if(!u||!u.infinite)return;const d=c.__prevPageParam;if(d==null)return;const S={...u,cursor:d};I(S,t,s,{direction:"previous",force:!0})}},Gt={invalidateQueries:e=>Be(A,ie(e)),removeQueries:e=>{Ke(A,e?ie(e):Ye)},getQueryData:e=>lt(A,e),setQueryData:(e,t)=>{dt(A,e,t)},prefetchQuery:async(e,t)=>{const r=t?.fetch;if(!r)return;const s=P(t),o=await Ue(r,t);if(!o)return;const n=e.method||"select",a=me(null,t),c=ne(null,t),f=Oe({...e,method:n},e.params,a,c),y=o[n];if(!(0,i.isFunction)(y))return;const u={from:e.from,params:e.params,limit:e.limit,offset:e.offset,order:e.order,single:e.single,headers:e.headers,baseUrl:e.baseUrl};c&&(u.headers={...u.headers,"Accept-Language":c}),e.responseType!==void 0&&(u.responseType=e.responseType),n==="rpc"&&(u.read=!qe(e)&&e.read!==!1);const d=++Se,S=await y(u);if(S?.data!==void 0&&!S?.error&&!Ee(e)&&!we(s,f,d)){const Q=se(s,f,S.data,null,d,Le(s,f,d));Q.gcTime=Re(e.cache)?.gcTime||3e5}return S},getCache:()=>A.cache,clear:()=>Ke(A,Ye),dropNonLang:e=>{if(!e)return;const t=`:${e}`;for(const[r]of A.cache)r.match(/:([a-z]{2,3})$/i)&&(r.endsWith(t)||tt(A,r))}},pt=(e,t)=>(0,i.isObject)(e)?Ne({method:"select",...e},t,t?.context):e,Wt={invalidateQueries(e){return Be(P(this?.context),ie(e))},removeQueries(e){Ke(P(this?.context),e?ie(e):Ye)},getQueryData(e){return lt(P(this?.context),pt(e,this))},setQueryData(e,t){dt(P(this?.context),pt(e,this),t)}},Vt={name:"fetch",create(e){const t=e.fetch;t&&(e.parent||P(e.context).active.clear(),Ge(t,e,e.state,e.context))}};var xt=Ge;
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isArray as q,isFunction as f,isObject as H,isString as _e,exec as He}from"@symbo.ls/utils";import{createEffect as yt}from"@symbo.ls/signal";import{dropEarly as bt}from"./early.js";import*as St from"./adapters/rest.js";const wt=["select","rpc","insert","update","upsert","delete","subscribe"],Xe={rest:()=>Promise.resolve(St),local:()=>import("./adapters/local.js")},ye=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),X=(()=>{if(typeof globalThis<"u"&&globalThis[ye])return globalThis[ye];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,ye,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[ye]}catch{}return e})(),be=Symbol.for("@symbo.ls/fetch:PENDING_ADAPTERS"),Oe=(()=>{if(typeof globalThis<"u"&&globalThis[be])return globalThis[be];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,be,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[be]}catch{}return e})(),gt=5e3,Tt=e=>new Promise(t=>{if(X[e])return t(X[e]);const r=Oe[e]||=[];let s=!1;const o=()=>{s||(s=!0,t(X[e]||null))};r.push(o),setTimeout(o,gt)}),Ut=(e,t)=>{X[e]=t;const r=Oe[e];if(r&&r.length){Oe[e]=[];for(const s of r)s()}},Qt=e=>typeof e=="string"&&!!(X[e]||Xe[e]),$t=e=>{const t={};for(const r of wt)e[r]&&(t[r]=e[r]);return t.name=e.name||"custom",t},mt=async e=>{if(!e)return null;if(typeof e.select=="function")return e;const{adapter:t,...r}=e,s=typeof t=="string"?t:typeof e=="string"?e:null;if(!s)return null;let o=X[s]||Xe[s];if(!o&&(o=await Tt(s),!o))throw new Error(`Unknown db adapter: "${s}". Use registerAdapter() for adapters with optional deps.`);const n=await o();if(!n||typeof n.setup!="function")throw new Error(`Adapter "${s}" loader returned a module without a setup() function. Got keys: [${Object.keys(n||{}).join(", ")}]. Likely a bundler chunk-resolution issue.`);return n.setup(r)},re=e=>{if(!e)return 0;if(typeof e=="number")return e;const t=e.match(/^(\d+)(ms|s|m|h)$/);if(!t)return 0;const r=parseInt(t[1]),s=t[2];return s==="ms"?r:s==="s"?r*1e3:s==="m"?r*6e4:s==="h"?r*36e5:0},m=new Map,x=new Map,I=new Map;let Se=0;const we=new Map,Le=new WeakMap,Re=(e,t,r,s,o=e.page,n=e.cursor)=>{if(e.cache?.key)return e.cache.key;const{from:i,method:u,infinite:a}=e,l=r?`${r}:`:"",h=s?`:${s}`:"",p=o?":p"+JSON.stringify(o):"",v=n!=null?":c"+JSON.stringify(n):"";return`${i}:${u}:${l}${JSON.stringify(t||"")}${a?":infinite":""}${p}${v}${h}`},se=e=>m.get(e)||null,ne=(e,t,r,s=++Se,o=!1)=>{const n={data:t,error:r,time:Date.now(),stale:o,seq:s};m.set(e,n);const i=x.get(e);if(i)for(const u of i)f(u)&&u(n);return n},ge=(e,t)=>{const r=e?m.get(e):null;return r&&!r.error&&r.seq>t?r:null},qe=(e,t)=>(we.get(e)||0)>t,Te=e=>{we.set(e,++Se)},Ze=e=>{m.delete(e),Te(e)},zt=(e,t)=>(x.has(e)||x.set(e,new Set),x.get(e).add(t),()=>{const r=x.get(e);r&&(r.delete(t),r.size===0&&x.delete(e))}),Ie=e=>!e&&e!==!1?{staleTime:6e4,gcTime:3e5}:e===!1?null:e===!0?{staleTime:6e4,gcTime:3e5}:typeof e=="number"?{staleTime:e,gcTime:Math.max(e*5,3e5)}:_e(e)?{staleTime:re(e),gcTime:3e5}:{staleTime:re(e.stale||e.staleTime)||6e4,gcTime:re(e.gc||e.gcTime||e.expire)||3e5,key:e.key},N=new Set,et=e=>!!e.ref&&e.element.__ref===e.ref,vt=({config:e,element:t,context:r})=>{try{return Qe(e,t,r)}catch{return null}};let me=null;const Et=()=>{me||(me=setInterval(()=>{const e=Date.now();for(const[t,r]of m){const s=x.get(t);!(s&&s.size>0)&&e-r.time>(r.gcTime||3e5)&&m.delete(t)}for(const[t]of we)!m.has(t)&&!I.has(t)&&we.delete(t);for(const t of N)et(t)||N.delete(t)},3e4),me.unref&&me.unref())};Et();const tt=3,Ne=e=>Math.min(1e3*2**e,3e4),rt=(e,t)=>{const r=e.retry;return r===void 0&&t?{count:0}:r===!1?{count:0}:r===!0||r===void 0?{count:tt,delay:Ne}:typeof r=="number"?{count:r,delay:Ne}:{count:r.count??tt,delay:f(r.delay)?r.delay:typeof r.delay=="number"?()=>r.delay:Ne}},st=async(e,t)=>{const{count:r,delay:s}=t;let o;for(let n=0;n<=r;n++)try{const i=await e();if(i?.error){if(o=i.error,n<r){const u=f(s)?s(n,o):s;await new Promise(a=>setTimeout(a,u));continue}return i}return i}catch(i){if(o=i,n<r){const u=f(s)?s(n,i):s;await new Promise(a=>setTimeout(a,u));continue}throw i}return{data:null,error:o}},Z={focus:new Set,online:new Set};let nt=!1;const Dt=()=>{if(nt||typeof window>"u")return;nt=!0;const e=()=>{for(const r of Z.focus)r()},t=()=>{for(const r of Z.online)r()};window.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&e()}),window.addEventListener("focus",e),window.addEventListener("online",t)},ot=(e,t)=>{const r=t.__ref;if(e===!0)return{from:r.__state||t.key,method:"select",query:!0,on:"create"};if(_e(e))return{from:e,method:"select",query:!0,on:"create"};if(H(e)){const s={...e};return s.from=s.from||r.__state||t.key,s.method=s.method||"select",s.on=s.on||"create",s.query===void 0&&(s.query=!0),s}return null},Pt=["insert","update","upsert","delete"],at=e=>Pt.includes(e),Ue=e=>e.mutation===!0?!0:e.mutation===!1||e.method!=="rpc"?!1:e.on==="submit"||e.on==="click"||e.invalidates!=null,oe=(e,t)=>{const r=e?.state?.root||t?.state?.root;if(r?.lang)return r.lang},ve=(e,t)=>{const s=(e?.state?.root||t?.state?.root)?.__fetchScope;return s?String(s):void 0},Ee=(e,t,r)=>{let s;if(!e)s=void 0;else if(f(e))s=e(t,t.state);else{s={};for(const o in e){const n=e[o];s[o]=f(n)?n(t,t.state):n}}return s},ae=(e,t)=>f(e)?e(t,t.state):e,Qe=(e,t,r)=>Re(e,Ee(e.params,t,r),ve(t,r),oe(t,r),ae(e.page,t),ae(e.cursor,t)),$e=async(e,t)=>{if(!e||e.__authInitialized||(e.__authInitialized=!0,!e.getSession))return;const r=(s,o)=>{const n=t.state?.root;n?.update&&n.update({auth:{user:s,session:o,loading:!1}})};try{const s=await e.getSession();r(s?.user||null,s)}catch(s){console.warn("[fetch] Failed to restore auth session:",s.message)}e.onAuthStateChange&&e.onAuthStateChange((s,o)=>{r(o?.user||null,o)})},ze=async(e,t)=>{if(f(e.select))return e.auth!==!1&&await $e(e,t),e;if(e.__resolved)return e.auth!==!1&&await $e(e.__resolved,t),e.__resolved;if(e.__resolving)return e.__resolving;e.__resolving=mt(e);const r=await e.__resolving;return delete e.__resolving,r?(r.auth=e.auth,r.url=e.url,r.key=e.key,e.__resolved=r,t.fetch=r,e.auth!==!1&&await $e(r,t),r):null},F=(e,t,...r)=>{const s=f(e[t])?e[t]:null;s&&s.call(e,...r,e,e.state,e.context)},k=(e,t,r,...s)=>{const o=e&&f(e[r])?e[r]:null;o&&o.call(t,...s,t,t.state,t.context)},ie=e=>{const t={},r=e.node;if(!r)return t;if(r.tagName==="FORM"){const o=new FormData(r);for(const[n,i]of o.entries())t[n]=i;return t}const s=r.querySelectorAll("input, textarea, select");for(let o=0;o<s.length;o++){const n=s[o],i=n.name||n.getAttribute("name");i&&(n.type==="checkbox"?t[i]=n.checked:n.type==="file"?t[i]=n.files:t[i]=n.value)}return t},De=e=>e.responseType==="stream"||e.responseType==="response",Ft=["Blob","File","ArrayBuffer","ReadableStream","Response"],je=e=>e!==null&&typeof e=="object"&&(ArrayBuffer.isView(e)||Ft.includes(Object.prototype.toString.call(e).slice(8,-1))),U=(e,t,r,s={})=>{if(!r&&je(t))return;const o=r&&r.startsWith("~/"),n=o&&e.state?.root||e.state;if(n?.update)if(o){const i=r.slice(2);t&&typeof t=="object"&&!Array.isArray(t)&&!je(t)&&i in t?n.update(t,{preventFetch:!0,...s}):n.update({[i]:t},{preventFetch:!0,...s})}else{const i=r?{[r]:t}:t;n.update(i,{preventFetch:!0,...s})}},Be=Object.freeze({isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),Ke=e=>({isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:e,status:"error",fetchStatus:"idle"}),Q=(e,t)=>{const r=e?.__ref;r&&(r.__fetchStatus={...t,isError:!!t.error},r.__fetching=t.isFetching,r.__fetchError=t.error)},it=(e,t,r)=>{const s=e.__pages&&e.__pages.length?e.__pages:[r];f(t.getNextPageParam)&&(e.__nextPageParam=t.getNextPageParam(s[s.length-1],s),e.__hasNextPage=e.__nextPageParam!=null),f(t.getPreviousPageParam)&&(e.__prevPageParam=t.getPreviousPageParam(s[0],s),e.__hasPreviousPage=e.__prevPageParam!=null)},O=async(e,t,r,s={})=>{const o=r?.fetch;if(!o||!t||!t.__ref)return;const n=t.__ref,i=ve(t,r);(!n.__fetchScopeOwner||n.__fetchScopeOwner.scope!==i)&&(n.__fetchScopeOwner={scope:i});const u=n.__fetchScopeOwner,a=()=>t.__ref===n&&n.__fetchScopeOwner===u&&ve(t,r)===i;if(e.enabled===!1||f(e.enabled)&&!e.enabled(t,t.state)||e.skip===!0||f(e.skip)&&e.skip(t,t.state))return;const l=await ze(o,r);if(!l||!a())return;const{from:h,method:p,query:v,params:Fe,cache:Ae,transform:$,single:ue,auth:ce,fields:Y,as:A,limit:z,offset:L,order:S,headers:te,baseUrl:E,responseType:G,page:g,cursor:P,infinite:j,placeholderData:W,initialData:V,select:T,keepPreviousData:C}=e,B=c=>(f(T)&&(c=T(c,t,t.state)),$&&(c=$(c,t,t.state)),c),R=c=>{Q(t,Ke(c)),F(t,"onFetchError",c),k(e,t,"onFetchError",c)};let Ce=_e(T)?T:void 0;if(v&&f(t.getQuery)){const c=t.getQuery(l.name||"paths");c&&(Ce=c.select||c.length&&c.join(",")||Ce)}const fe=Ee(Fe,t,r),D=ae(g,t),Me=ae(P,t),le=Ue(e),de=De(e)||le?null:Ie(Ae),pt=rt(e,le||at(p)),Ve=oe(t,r),y=de?Re(e,fe,i,Ve,D,Me):null;if(!n.__fetchInitialized&&y&&(n.__fetchInitialized=!0,V!==void 0)){const c=f(V)?V():V;ne(y,c,null)}if((p==="select"||p==="rpc")&&y&&de&&!s.refresh&&!s.force){const c=se(y);if(c&&!c.error){const d=Date.now()-c.time,w=c.stale||d>(de.staleTime||0);j&&q(c.data)&&!n.__pages&&(n.__pages=[c.data],it(n,e,c.data));const _=B(c.data);if(!a())return;if(!w){Q(t,Be),U(t,_,A);return}U(t,_,A)}else if(W!==void 0){const d=f(W)?W(t,t.state):W;d!==void 0&&U(t,d,A)}}const pe=y&&!s.force?I.get(y):null;if(pe&&!qe(y,Le.get(pe)||0)){try{const c=await Promise.race([pe,new Promise((d,w)=>setTimeout(()=>w("DEDUP_TIMEOUT"),15e3))]);if(!a())return;if(c?.error)R(c.error);else if(c?.data!==void 0){const d=!j&&ge(y,Le.get(pe)||0),w=B(d?d.data:c.data);if(!a())return;U(t,w,A),F(t,"onFetchComplete",w),k(e,t,"onFetchComplete",w)}}catch(c){if(!a())return;c!=="DEDUP_TIMEOUT"&&R(c)}return}const ht=!se(y)?.data;Q(t,{isFetching:!0,isLoading:ht,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),F(t,"onFetchStart"),k(e,t,"onFetchStart");const M=r?.analyze?.emitNetwork,ke=M?typeof performance<"u"?performance.now():Date.now():0;M&&M({phase:"start",mode:"query",from:h,method:p,cacheKey:y,lang:Ve});const _t=async()=>{if(!a())return;if(ce!==!1&&l.auth!==!1&&l.getSession){const _=await l.getSession();if(!a())return;if(ce===!0&&!_){const b={message:"Not authenticated"};return R(b),{data:null,error:b}}}const c=l[p];if(!f(c))return{data:null,error:{message:`Method "${p}" not found on adapter`}};const d={from:h,select:Ce,params:fe,single:ue,limit:z,offset:L,order:S,headers:te,baseUrl:E};G!==void 0&&(d.responseType=G);const w=oe(t,r);if(w&&(d.headers={...d.headers,"Accept-Language":w}),D!==void 0){if(H(D))D.offset!==void 0&&(d.offset=D.offset),D.limit!==void 0&&(d.limit=D.limit),D.cursor!==void 0&&(d.params={...d.params,cursor:D.cursor});else if(typeof D=="number"){const _=e.pageSize||z||20;d.offset=(D-1)*_,d.limit=_}}if(Me!==void 0&&(d.params={...d.params,cursor:Me}),p==="insert"||p==="update"||p==="upsert"){let _;if(Y===!0||e.on==="submit")_=ie(t);else if(q(Y)){const b=ie(t);_={};for(const K of Y)_[K]=b[K]}else t.state?.parse?_=t.state.parse():H(t.state)&&(_={...t.state});$&&(_=$(_,t,t.state)),d.data=_}if(p==="rpc"){let _=fe;if(e.on==="submit"){const b=ie(t);_=e.transformParams?e.transformParams(b,t,t.state):b}d.params=_,d.read=!le&&e.read!==!1}if(p==="subscribe"){if(f(n.__unsubscribe)){const b=n.__unsubscribe;n.__unsubscribe=null;try{b()}catch{}}const _=l.subscribe({from:h,params:fe,on:e.subscribeOn},(b,K,Je)=>{a()&&(U(t,b,A),F(t,"onFetchComplete",b),k(e,t,"onFetchComplete",b))});return a()?(n.__unsubscribe=_,{data:null,error:null,subscribed:!0}):(f(_)&&_(),{data:null,error:null,subscribed:!0})}return c(d)},J=++Se,he=st(_t,pt);Le.set(he,J),y&&I.set(y,he);try{const c=await he;if(le&&e.invalidates&&c&&!c.error&&!c.subscribed&&ct(e.invalidates,h),!a()||c?.subscribed)return;const{data:d,error:w}=c||{};if(w){y&&!ge(y,J)&&ne(y,null,w,J),R(w),M&&M({phase:"error",mode:"query",from:h,method:p,cacheKey:y,error:w.message||w,durationMs:(typeof performance<"u"?performance.now():Date.now())-ke});return}if(d!==void 0){let _=d;if((p==="select"||p==="rpc")&&y){const K=!j&&ge(y,J);if(K)_=K.data;else{const Je=ne(y,d,null,J,qe(y,J));Je.gcTime=de?.gcTime||3e5}}let b=_;if(j&&q(d)&&((!n.__pages||!s.direction)&&(n.__pages=[]),s.direction==="previous"?n.__pages.unshift(d):n.__pages.push(d),b=n.__pages.flat(),it(n,e,d)),b=B(b),!a())return;Q(t,Be),(!C||b!==void 0)&&U(t,b,A),F(t,"onFetchComplete",b),k(e,t,"onFetchComplete",b),M&&M({phase:"success",mode:"query",ok:!0,from:h,method:p,cacheKey:y,durationMs:(typeof performance<"u"?performance.now():Date.now())-ke})}}catch(c){if(!a())return;R(c),M&&M({phase:"error",mode:"query",from:h,method:p,cacheKey:y,error:c.message||String(c),durationMs:(typeof performance<"u"?performance.now():Date.now())-ke})}finally{y&&I.get(y)===he&&I.delete(y)}},At=(e,t,r)=>{const s=e.on,o=t.__ref;if(!o)return;o.__fetchListeners||(o.__fetchListeners=[]);const n=e.__runner||O;if(s==="submit"){const i=a=>{a.preventDefault(),n(e,t,r)},u=t.node;u&&(u.addEventListener("submit",i),o.__fetchListeners.push(()=>u.removeEventListener("submit",i)))}else if(s==="click"){const i=()=>n(e,t,r),u=t.node;u&&(u.addEventListener("click",i),o.__fetchListeners.push(()=>u.removeEventListener("click",i)))}else s==="stateChange"&&Ct(e,t,r,n)},Ct=(e,t,r,s)=>{const o=t.__ref;let n;const i=yt(()=>{let u;try{u=JSON.stringify([Ee(e.params,t,r)??null,f(e.enabled)?!!e.enabled(t,t.state):e.enabled!==!1,f(e.skip)?!!e.skip(t,t.state):e.skip===!0,ae(e.page,t)??null])}catch{return}if(n===void 0){n=u;return}u!==n&&(n=u,queueMicrotask(()=>s(e,t,r)))});Array.isArray(o.__effects)?o.__effects.push(i):o.__fetchListeners.push(()=>i.dispose())},Mt=(e,t,r)=>{const s=t.__ref;s.__fetchCleanups||(s.__fetchCleanups=[]),Dt();const o=e.refetchInterval;if(o){const a=typeof o=="number"?o:re(o);if(a>0){const l=setInterval(()=>{(e.refetchIntervalInBackground||typeof document>"u"||document.visibilityState==="visible")&&O(e,t,r,{force:!0})},a);s.__fetchCleanups.push(()=>clearInterval(l))}}const n=De(e),i=e.refetchOnWindowFocus===void 0?!n:e.refetchOnWindowFocus!==!1,u=e.refetchOnReconnect===void 0?!n:e.refetchOnReconnect!==!1;if(i){const a=()=>{const l=Qe(e,t,r),h=se(l),p=Ie(e.cache);(!h||h.stale||Date.now()-h.time>(p?.staleTime||0))&&O(e,t,r,{force:!0})};Z.focus.add(a),s.__fetchCleanups.push(()=>Z.focus.delete(a))}if(u){const a=()=>O(e,t,r,{force:!0});Z.online.add(a),s.__fetchCleanups.push(()=>Z.online.delete(a))}},kt=(e,t,r)=>{if(!t.optimistic)return null;const s=e.__ref,o=t.as,n=e.state?.parse?e.state.parse():H(e.state)?{...e.state}:e.state;s.__optimisticSnapshot=n;const i=f(t.optimistic)?t.optimistic(r,n,e):t.optimistic;return i!==void 0&&U(e,i,o),n},xe=(e,t)=>{const r=e.__ref;if(!r||!t.optimistic)return;const s=r.__optimisticSnapshot;s!==void 0&&(U(e,s,t.as),delete r.__optimisticSnapshot)},Ye=e=>{if(!e)return()=>!0;if(_e(e))return t=>t.includes(e);if(q(e)){const t=e.join(":");return r=>r.includes(t)}return e instanceof RegExp?t=>(e.lastIndex=0,e.test(t)):f(e)?t=>{try{return!!e(t)}catch{return!1}}:()=>!1},Ot=e=>{const t=[];for(const r of N){if(!et(r)){N.delete(r);continue}const s=vt(r);s&&e(s)&&t.push(O(r.config,r.element,r.context,{refresh:!0}))}return Promise.allSettled(t).then(()=>{})},ut=e=>{bt();for(const[t,r]of m)e(t)&&(r.stale=!0,Te(t));for(const[t]of I)!m.has(t)&&e(t)&&Te(t);return Ot(e)},ct=(e,t)=>{const r=(q(e)?e:[e]).map(s=>s===!0||s==="*"?o=>o.startsWith(t+":"):s?Ye(s):()=>!1);return ut(s=>r.some(o=>o(s)))},Ge=e=>{for(const[t]of m)e(t)&&Ze(t);for(const[t]of I)e(t)&&Te(t)},We=()=>!0,ft=new WeakSet,ee=e=>{!e||!e.isolateFetchCache||ft.has(e)||(ft.add(e),Ge(We),N.clear())},Lt=async(e,t,r)=>{const s=r?.fetch;if(!s)return;const o=await ze(s,r);if(!o)return;const n=t.__ref,{method:i,from:u,fields:a,transform:l,as:h,on:p,auth:v,headers:Fe,baseUrl:Ae,responseType:$,invalidates:ue,optimistic:ce,onMutate:Y,onSuccess:A,onError:z,onSettled:L}=e;let S;if(a===!0||p==="submit")S=ie(t);else if(q(a)){const g=ie(t);S={};for(const P of a)S[P]=g[P]}else t.state?.parse?S=t.state.parse():H(t.state)&&(S={...t.state});l&&(S=l(S,t,t.state)),f(Y)&&Y(S,t,t.state);const te=ce?kt(t,e,S):null;Q(t,{isFetching:!0,isLoading:!1,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),F(t,"onFetchStart"),k(e,t,"onFetchStart");const E=r?.analyze?.emitNetwork,G=E?typeof performance<"u"?performance.now():Date.now():0;E&&E({phase:"start",mode:"mutation",from:u,method:i});try{if(v!==!1&&o.auth!==!1&&o.getSession){const B=await o.getSession();if(v===!0&&!B){te!==void 0&&xe(t,e);const R={message:"Not authenticated"};F(t,"onFetchError",R),k(e,t,"onFetchError",R);return}}const g=o[i];if(!f(g))return;const P={from:u,data:S,headers:Fe,baseUrl:Ae};$!==void 0&&(P.responseType=$),e.params&&(P.params=Ee(e.params,t,r));const j=oe(t,r);j&&(P.headers={...P.headers,"Accept-Language":j});const W=rt(e,!0),V=await st(()=>g(P),W),{data:T,error:C}=V||{};if(C){te!==void 0&&xe(t,e),Q(t,Ke(C)),F(t,"onFetchError",C),f(z)&&z(C,S,t),f(L)&&L(null,C,S,t),E&&E({phase:"error",mode:"mutation",from:u,method:i,error:C.message||String(C),durationMs:(typeof performance<"u"?performance.now():Date.now())-G});return}if(delete n.__optimisticSnapshot,Q(t,Be),T!==void 0&&(h||!je(T))){const B=h?{[h]:T}:T;t.state?.update&&t.state.update(B,{preventFetch:!0})}F(t,"onFetchComplete",T),k(e,t,"onFetchComplete",T),f(A)&&A(T,S,t),f(L)&&L(T,null,S,t),E&&E({phase:"success",mode:"mutation",ok:!0,from:u,method:i,durationMs:(typeof performance<"u"?performance.now():Date.now())-G}),ue&&ct(ue,u)}catch(g){te!==void 0&&xe(t,e),Q(t,Ke(g)),F(t,"onFetchError",g),k(e,t,"onFetchError",g),f(z)&&z(g,S,t),f(L)&&L(null,g,S,t),E&&E({phase:"error",mode:"mutation",from:u,method:i,error:g.message||String(g),durationMs:(typeof performance<"u"?performance.now():Date.now())-G})}finally{n.__fetching=!1}},Rt=e=>{const t=r=>{try{r()}catch{}};for(const r of e.__fetchCleanups||[])t(r);for(const r of e.__fetchListeners||[])t(r);f(e.__unsubscribe)&&t(e.__unsubscribe);for(const r of e.__fetchMounted||[])N.delete(r);e.__fetchCleanups=[],e.__fetchListeners=[],e.__unsubscribe=null,e.__fetchMounted=[]},lt=(e,t,r,s)=>{if(!e||!s?.fetch)return;ee(s);const n=He(e,t);if(!n)return;const i=q(n)?n.map(a=>ot(He(a,t),t)).filter(Boolean):[ot(n,t)].filter(Boolean),u=t.__ref;if(u.__fetchMounted)for(const a of u.__fetchMounted)N.delete(a);u.__fetchMounted=[],!u.__fetchDisposer&&q(u.__effects)&&(u.__fetchDisposer={dispose:()=>Rt(u)},u.__effects.push(u.__fetchDisposer));for(const a of i){const l=at(a.method),h=l?Lt:O,p=!l&&!Ue(a)&&a.method!=="subscribe";if(a.on==="create"?h(a,t,s):queueMicrotask(()=>At({...a,__runner:h},t,s)),p&&a.on==="create"&&((a.refetchInterval||a.refetchOnWindowFocus!==!1||a.refetchOnReconnect!==!1)&&Mt(a,t,s),!De(a))){const v={element:t,ref:u,config:a,context:s};N.add(v),u.__fetchMounted.push(v)}}u.refetch=a=>{for(const l of i)O(l,t,s,{force:!0,...a})},u.fetchNextPage=()=>{const a=i[0];if(!a||!a.infinite)return;const l=u.__nextPageParam;if(l==null)return;const h={...a,cursor:l};O(h,t,s,{direction:"next",force:!0})},u.fetchPreviousPage=()=>{const a=i[0];if(!a||!a.infinite)return;const l=u.__prevPageParam;if(l==null)return;const h={...a,cursor:l};O(h,t,s,{direction:"previous",force:!0})}},Pe={invalidateQueries:e=>ut(Ye(e)),removeQueries:e=>{Ge(e?Ye(e):We)},getQueryData:e=>se(e)?.data??void 0,setQueryData:(e,t)=>{const r=se(e),s=f(t)?t(r?.data):t;ne(e,s,null)},prefetchQuery:async(e,t)=>{const r=t?.fetch;if(!r)return;ee(t);const s=await ze(r,t);if(!s)return;const o=e.method||"select",n=ve(null,t),i=oe(null,t),u=Re({...e,method:o},e.params,n,i),a=s[o];if(!f(a))return;const l={from:e.from,params:e.params,limit:e.limit,offset:e.offset,order:e.order,single:e.single,headers:e.headers,baseUrl:e.baseUrl};i&&(l.headers={...l.headers,"Accept-Language":i}),e.responseType!==void 0&&(l.responseType=e.responseType),o==="rpc"&&(l.read=!Ue(e)&&e.read!==!1);const h=++Se,p=await a(l);if(p?.data!==void 0&&!p?.error&&!De(e)&&!ge(u,h)){const v=ne(u,p.data,null,h,qe(u,h));v.gcTime=Ie(e.cache)?.gcTime||3e5}return p},getCache:()=>m,clear:()=>Ge(We),dropNonLang:e=>{if(!e)return;const t=`:${e}`;for(const[r]of m)r.match(/:([a-z]{2,3})$/i)&&(r.endsWith(t)||Ze(r))}},dt=(e,t)=>H(e)?Qe({method:"select",...e},t,t?.context):e,jt={invalidateQueries(e){return ee(this?.context),Pe.invalidateQueries(e)},removeQueries(e){return ee(this?.context),Pe.removeQueries(e)},getQueryData(e){return ee(this?.context),Pe.getQueryData(dt(e,this))},setQueryData(e,t){return ee(this?.context),Pe.setQueryData(dt(e,this),t)}},Bt={name:"fetch",create(e){const t=e.fetch;t&&(e.parent||I.clear(),lt(t,e,e.state,e.context))}};import{earlyKey as Gt,EARLY_KEY as Wt,createEarlySeedScript as Vt,createEarlySeedBlock as Jt,SEED_BLOCK as Ht}from"./early.js";import{requestsInFlight as Zt,whenRequestsIdle as er}from"./inflight.js";var Kt=lt;export{Wt as EARLY_KEY,Ht as SEED_BLOCK,$t as createAdapter,Jt as createEarlySeedBlock,Vt as createEarlySeedScript,Kt as default,Gt as earlyKey,lt as executeFetch,jt as fetchFunctions,Bt as fetchPlugin,Qt as hasAdapter,$e as initAdapterAuth,re as parseDuration,Pe as queryClient,Ut as registerAdapter,Zt as requestsInFlight,mt as resolveDb,er as whenRequestsIdle};
|
|
1
|
+
import{isArray as N,isFunction as d,isObject as X,isString as ye,exec as Ve}from"@symbo.ls/utils";import{createEffect as yt}from"@symbo.ls/signal";import{dropEarly as bt}from"./early.js";import*as St from"./adapters/rest.js";const wt=["select","rpc","insert","update","upsert","delete","subscribe"],xe={rest:()=>Promise.resolve(St),local:()=>import("./adapters/local.js")},be=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),Z=(()=>{if(typeof globalThis<"u"&&globalThis[be])return globalThis[be];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,be,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[be]}catch{}return e})(),Se=Symbol.for("@symbo.ls/fetch:PENDING_ADAPTERS"),Ce=(()=>{if(typeof globalThis<"u"&&globalThis[Se])return globalThis[Se];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,Se,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[Se]}catch{}return e})(),gt=5e3,vt=e=>new Promise(t=>{if(Z[e])return t(Z[e]);const r=Ce[e]||=[];let s=!1;const o=()=>{s||(s=!0,t(Z[e]||null))};r.push(o),setTimeout(o,gt)}),Ut=(e,t)=>{Z[e]=t;const r=Ce[e];if(r&&r.length){Ce[e]=[];for(const s of r)s()}},$t=e=>typeof e=="string"&&!!(Z[e]||xe[e]),Qt=e=>{const t={};for(const r of wt)e[r]&&(t[r]=e[r]);return t.name=e.name||"custom",t},mt=async e=>{if(!e)return null;if(typeof e.select=="function")return e;const{adapter:t,...r}=e,s=typeof t=="string"?t:typeof e=="string"?e:null;if(!s)return null;let o=Z[s]||xe[s];if(!o&&(o=await vt(s),!o))throw new Error(`Unknown db adapter: "${s}". Use registerAdapter() for adapters with optional deps.`);const n=await o();if(!n||typeof n.setup!="function")throw new Error(`Adapter "${s}" loader returned a module without a setup() function. Got keys: [${Object.keys(n||{}).join(", ")}]. Likely a bundler chunk-resolution issue.`);return n.setup(r)},re=e=>{if(!e)return 0;if(typeof e=="number")return e;const t=e.match(/^(\d+)(ms|s|m|h)$/);if(!t)return 0;const r=parseInt(t[1]),s=t[2];return s==="ms"?r:s==="s"?r*1e3:s==="m"?r*6e4:s==="h"?r*36e5:0},Je=e=>!!e&&!!e.isolateFetchCache,He=()=>({cache:new Map,subscribers:new Map,active:new Map,invalidatedAt:new Map,mounted:new Set}),A=He(),Xe=new WeakMap,P=e=>{if(!Je(e))return A;let t=Xe.get(e);return t||Xe.set(e,t=He()),t};let we=0;const Me=new WeakMap,ke=(e,t,r,s,o=e.page,n=e.cursor)=>{if(e.cache?.key)return e.cache.key;const{from:a,method:i,infinite:u}=e,y=r?`${r}:`:"",c=s?`:${s}`:"",l=o?":p"+JSON.stringify(o):"",S=n!=null?":c"+JSON.stringify(n):"";return`${a}:${i}:${y}${JSON.stringify(t||"")}${u?":infinite":""}${l}${S}${c}`},se=(e,t)=>e.cache.get(t)||null,ne=(e,t,r,s,o=++we,n=!1)=>{const a={data:r,error:s,time:Date.now(),stale:n,seq:o};e.cache.set(t,a);const i=e.subscribers.get(t);if(i)for(const u of i)d(u)&&u(a);return a},ge=(e,t,r)=>{const s=t?e.cache.get(t):null;return s&&!s.error&&s.seq>r?s:null},Oe=(e,t,r)=>(e.invalidatedAt.get(t)||0)>r,ve=(e,t)=>{e.invalidatedAt.set(t,++we)},Ze=(e,t)=>{e.cache.delete(t),ve(e,t)},zt=(e,t,r)=>{const{subscribers:s}=e;return s.has(t)||s.set(t,new Set),s.get(t).add(r),()=>{const o=s.get(t);o&&(o.delete(r),o.size===0&&s.delete(t))}},Le=e=>!e&&e!==!1?{staleTime:6e4,gcTime:3e5}:e===!1?null:e===!0?{staleTime:6e4,gcTime:3e5}:typeof e=="number"?{staleTime:e,gcTime:Math.max(e*5,3e5)}:ye(e)?{staleTime:re(e),gcTime:3e5}:{staleTime:re(e.stale||e.staleTime)||6e4,gcTime:re(e.gc||e.gcTime||e.expire)||3e5,key:e.key},et=e=>!!e.ref&&e.element.__ref===e.ref,Tt=({config:e,element:t,context:r})=>{try{return qe(e,t,r)}catch{return null}};let me=null;const Et=()=>{me||(me=setInterval(()=>{const e=Date.now(),{cache:t,subscribers:r,active:s,invalidatedAt:o,mounted:n}=A;for(const[a,i]of t){const u=r.get(a);!(u&&u.size>0)&&e-i.time>(i.gcTime||3e5)&&t.delete(a)}for(const[a]of o)!t.has(a)&&!s.has(a)&&o.delete(a);for(const a of n)et(a)||n.delete(a)},3e4),me.unref&&me.unref())};Et();const tt=3,Re=e=>Math.min(1e3*2**e,3e4),rt=(e,t)=>{const r=e.retry;return r===void 0&&t?{count:0}:r===!1?{count:0}:r===!0||r===void 0?{count:tt,delay:Re}:typeof r=="number"?{count:r,delay:Re}:{count:r.count??tt,delay:d(r.delay)?r.delay:typeof r.delay=="number"?()=>r.delay:Re}},st=async(e,t)=>{const{count:r,delay:s}=t;let o;for(let n=0;n<=r;n++)try{const a=await e();if(a?.error){if(o=a.error,n<r){const i=d(s)?s(n,o):s;await new Promise(u=>setTimeout(u,i));continue}return a}return a}catch(a){if(o=a,n<r){const i=d(s)?s(n,a):s;await new Promise(u=>setTimeout(u,i));continue}throw a}return{data:null,error:o}},ee={focus:new Set,online:new Set};let nt=!1;const Dt=()=>{if(nt||typeof window>"u")return;nt=!0;const e=()=>{for(const r of ee.focus)r()},t=()=>{for(const r of ee.online)r()};window.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&e()}),window.addEventListener("focus",e),window.addEventListener("online",t)},ot=(e,t)=>{const r=t.__ref;if(e===!0)return{from:r.__state||t.key,method:"select",query:!0,on:"create"};if(ye(e))return{from:e,method:"select",query:!0,on:"create"};if(X(e)){const s={...e};return s.from=s.from||r.__state||t.key,s.method=s.method||"select",s.on=s.on||"create",s.query===void 0&&(s.query=!0),s}return null},Pt=["insert","update","upsert","delete"],at=e=>Pt.includes(e),Ie=e=>e.mutation===!0?!0:e.mutation===!1||e.method!=="rpc"?!1:e.on==="submit"||e.on==="click"||e.invalidates!=null,oe=(e,t)=>{const r=e?.state?.root||t?.state?.root;if(r?.lang)return r.lang},Te=(e,t)=>{const s=(e?.state?.root||t?.state?.root)?.__fetchScope;return s?String(s):void 0},Ee=(e,t,r)=>{let s;if(!e)s=void 0;else if(d(e))s=e(t,t.state);else{s={};for(const o in e){const n=e[o];s[o]=d(n)?n(t,t.state):n}}return s},ae=(e,t)=>d(e)?e(t,t.state):e,qe=(e,t,r)=>ke(e,Ee(e.params,t,r),Te(t,r),oe(t,r),ae(e.page,t),ae(e.cursor,t)),Ne=async(e,t)=>{if(!e||e.__authInitialized||(e.__authInitialized=!0,!e.getSession))return;const r=(s,o)=>{const n=t.state?.root;n?.update&&n.update({auth:{user:s,session:o,loading:!1}})};try{const s=await e.getSession();r(s?.user||null,s)}catch(s){console.warn("[fetch] Failed to restore auth session:",s.message)}e.onAuthStateChange&&e.onAuthStateChange((s,o)=>{r(o?.user||null,o)})},Ue=async(e,t)=>{if(d(e.select))return e.auth!==!1&&await Ne(e,t),e;if(e.__resolved)return e.auth!==!1&&await Ne(e.__resolved,t),e.__resolved;if(e.__resolving)return e.__resolving;e.__resolving=mt(e);const r=await e.__resolving;return delete e.__resolving,r?(r.auth=e.auth,r.url=e.url,r.key=e.key,e.__resolved=r,t.fetch=r,e.auth!==!1&&await Ne(r,t),r):null},C=(e,t,...r)=>{const s=d(e[t])?e[t]:null;s&&s.call(e,...r,e,e.state,e.context)},L=(e,t,r,...s)=>{const o=e&&d(e[r])?e[r]:null;o&&o.call(t,...s,t,t.state,t.context)},ie=e=>{const t={},r=e.node;if(!r)return t;if(r.tagName==="FORM"){const o=new FormData(r);for(const[n,a]of o.entries())t[n]=a;return t}const s=r.querySelectorAll("input, textarea, select");for(let o=0;o<s.length;o++){const n=s[o],a=n.name||n.getAttribute("name");a&&(n.type==="checkbox"?t[a]=n.checked:n.type==="file"?t[a]=n.files:t[a]=n.value)}return t},De=e=>e.responseType==="stream"||e.responseType==="response",Ft=["Blob","File","ArrayBuffer","ReadableStream","Response"],$e=e=>e!==null&&typeof e=="object"&&(ArrayBuffer.isView(e)||Ft.includes(Object.prototype.toString.call(e).slice(8,-1))),U=(e,t,r,s={})=>{if(!r&&$e(t))return;const o=r&&r.startsWith("~/"),n=o&&e.state?.root||e.state;if(n?.update)if(o){const a=r.slice(2);t&&typeof t=="object"&&!Array.isArray(t)&&!$e(t)&&a in t?n.update(t,{preventFetch:!0,...s}):n.update({[a]:t},{preventFetch:!0,...s})}else{const a=r?{[r]:t}:t;n.update(a,{preventFetch:!0,...s})}},Qe=Object.freeze({isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),ze=e=>({isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:e,status:"error",fetchStatus:"idle"}),$=(e,t)=>{const r=e?.__ref;r&&(r.__fetchStatus={...t,isError:!!t.error},r.__fetching=t.isFetching,r.__fetchError=t.error)},it=(e,t,r)=>{const s=e.__pages&&e.__pages.length?e.__pages:[r];d(t.getNextPageParam)&&(e.__nextPageParam=t.getNextPageParam(s[s.length-1],s),e.__hasNextPage=e.__nextPageParam!=null),d(t.getPreviousPageParam)&&(e.__prevPageParam=t.getPreviousPageParam(s[0],s),e.__hasPreviousPage=e.__prevPageParam!=null)},R=async(e,t,r,s={})=>{const o=r?.fetch;if(!o||!t||!t.__ref)return;const n=t.__ref,a=Te(t,r);(!n.__fetchScopeOwner||n.__fetchScopeOwner.scope!==a)&&(n.__fetchScopeOwner={scope:a});const i=n.__fetchScopeOwner,u=()=>t.__ref===n&&n.__fetchScopeOwner===i&&Te(t,r)===a;if(e.enabled===!1||d(e.enabled)&&!e.enabled(t,t.state)||e.skip===!0||d(e.skip)&&e.skip(t,t.state))return;const y=await Ue(o,r);if(!y||!u())return;const{from:c,method:l,query:S,params:Q,cache:G,transform:z,single:ue,auth:fe,fields:W,as:M,limit:j,offset:I,order:w,headers:te,baseUrl:E,responseType:V,page:m,cursor:F,infinite:B,placeholderData:x,initialData:J,select:T,keepPreviousData:k}=e,K=f=>(d(T)&&(f=T(f,t,t.state)),z&&(f=z(f,t,t.state)),f),q=f=>{$(t,ze(f)),C(t,"onFetchError",f),L(e,t,"onFetchError",f)};let Pe=ye(T)?T:void 0;if(S&&d(t.getQuery)){const f=t.getQuery(y.name||"paths");f&&(Pe=f.select||f.length&&f.join(",")||Pe)}const le=Ee(Q,t,r),D=ae(m,t),Fe=ae(F,t),de=Ie(e),pe=De(e)||de?null:Le(G),pt=rt(e,de||at(l)),Ge=oe(t,r),_=pe?ke(e,le,a,Ge,D,Fe):null,v=P(r);if(!n.__fetchInitialized&&_&&(n.__fetchInitialized=!0,J!==void 0)){const f=d(J)?J():J;ne(v,_,f,null)}if((l==="select"||l==="rpc")&&_&&pe&&!s.refresh&&!s.force){const f=se(v,_);if(f&&!f.error){const p=Date.now()-f.time,g=f.stale||p>(pe.staleTime||0);B&&N(f.data)&&!n.__pages&&(n.__pages=[f.data],it(n,e,f.data));const h=K(f.data);if(!u())return;if(!g){$(t,Qe),U(t,h,M);return}U(t,h,M)}else if(x!==void 0){const p=d(x)?x(t,t.state):x;p!==void 0&&U(t,p,M)}}const he=_&&!s.force?v.active.get(_):null;if(he&&!Oe(v,_,Me.get(he)||0)){try{const f=await Promise.race([he,new Promise((p,g)=>setTimeout(()=>g("DEDUP_TIMEOUT"),15e3))]);if(!u())return;if(f?.error)q(f.error);else if(f?.data!==void 0){const p=!B&&ge(v,_,Me.get(he)||0),g=K(p?p.data:f.data);if(!u())return;U(t,g,M),C(t,"onFetchComplete",g),L(e,t,"onFetchComplete",g)}}catch(f){if(!u())return;f!=="DEDUP_TIMEOUT"&&q(f)}return}const ht=!se(v,_)?.data;$(t,{isFetching:!0,isLoading:ht,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),C(t,"onFetchStart"),L(e,t,"onFetchStart");const O=r?.analyze?.emitNetwork,Ae=O?typeof performance<"u"?performance.now():Date.now():0;O&&O({phase:"start",mode:"query",from:c,method:l,cacheKey:_,lang:Ge});const _t=async()=>{if(!u())return;if(fe!==!1&&y.auth!==!1&&y.getSession){const h=await y.getSession();if(!u())return;if(fe===!0&&!h){const b={message:"Not authenticated"};return q(b),{data:null,error:b}}}const f=y[l];if(!d(f))return{data:null,error:{message:`Method "${l}" not found on adapter`}};const p={from:c,select:Pe,params:le,single:ue,limit:j,offset:I,order:w,headers:te,baseUrl:E};V!==void 0&&(p.responseType=V);const g=oe(t,r);if(g&&(p.headers={...p.headers,"Accept-Language":g}),D!==void 0){if(X(D))D.offset!==void 0&&(p.offset=D.offset),D.limit!==void 0&&(p.limit=D.limit),D.cursor!==void 0&&(p.params={...p.params,cursor:D.cursor});else if(typeof D=="number"){const h=e.pageSize||j||20;p.offset=(D-1)*h,p.limit=h}}if(Fe!==void 0&&(p.params={...p.params,cursor:Fe}),l==="insert"||l==="update"||l==="upsert"){let h;if(W===!0||e.on==="submit")h=ie(t);else if(N(W)){const b=ie(t);h={};for(const Y of W)h[Y]=b[Y]}else t.state?.parse?h=t.state.parse():X(t.state)&&(h={...t.state});z&&(h=z(h,t,t.state)),p.data=h}if(l==="rpc"){let h=le;if(e.on==="submit"){const b=ie(t);h=e.transformParams?e.transformParams(b,t,t.state):b}p.params=h,p.read=!de&&e.read!==!1}if(l==="subscribe"){if(d(n.__unsubscribe)){const b=n.__unsubscribe;n.__unsubscribe=null;try{b()}catch{}}const h=y.subscribe({from:c,params:le,on:e.subscribeOn},(b,Y,We)=>{u()&&(U(t,b,M),C(t,"onFetchComplete",b),L(e,t,"onFetchComplete",b))});return u()?(n.__unsubscribe=h,{data:null,error:null,subscribed:!0}):(d(h)&&h(),{data:null,error:null,subscribed:!0})}return f(p)},H=++we,_e=st(_t,pt);Me.set(_e,H),_&&v.active.set(_,_e);try{const f=await _e;if(de&&e.invalidates&&f&&!f.error&&!f.subscribed&&ct(v,e.invalidates,c),!u()||f?.subscribed)return;const{data:p,error:g}=f||{};if(g){_&&!ge(v,_,H)&&ne(v,_,null,g,H),q(g),O&&O({phase:"error",mode:"query",from:c,method:l,cacheKey:_,error:g.message||g,durationMs:(typeof performance<"u"?performance.now():Date.now())-Ae});return}if(p!==void 0){let h=p;if((l==="select"||l==="rpc")&&_){const Y=!B&&ge(v,_,H);if(Y)h=Y.data;else{const We=ne(v,_,p,null,H,Oe(v,_,H));We.gcTime=pe?.gcTime||3e5}}let b=h;if(B&&N(p)&&((!n.__pages||!s.direction)&&(n.__pages=[]),s.direction==="previous"?n.__pages.unshift(p):n.__pages.push(p),b=n.__pages.flat(),it(n,e,p)),b=K(b),!u())return;$(t,Qe),(!k||b!==void 0)&&U(t,b,M),C(t,"onFetchComplete",b),L(e,t,"onFetchComplete",b),O&&O({phase:"success",mode:"query",ok:!0,from:c,method:l,cacheKey:_,durationMs:(typeof performance<"u"?performance.now():Date.now())-Ae})}}catch(f){if(!u())return;q(f),O&&O({phase:"error",mode:"query",from:c,method:l,cacheKey:_,error:f.message||String(f),durationMs:(typeof performance<"u"?performance.now():Date.now())-Ae})}finally{_&&v.active.get(_)===_e&&v.active.delete(_)}},At=(e,t,r)=>{const s=e.on,o=t.__ref;if(!o)return;o.__fetchListeners||(o.__fetchListeners=[]);const n=e.__runner||R;if(s==="submit"){const a=u=>{u.preventDefault(),n(e,t,r)},i=t.node;i&&(i.addEventListener("submit",a),o.__fetchListeners.push(()=>i.removeEventListener("submit",a)))}else if(s==="click"){const a=()=>n(e,t,r),i=t.node;i&&(i.addEventListener("click",a),o.__fetchListeners.push(()=>i.removeEventListener("click",a)))}else s==="stateChange"&&Ct(e,t,r,n)},Ct=(e,t,r,s)=>{const o=t.__ref;let n;const a=yt(()=>{let i;try{i=JSON.stringify([Ee(e.params,t,r)??null,d(e.enabled)?!!e.enabled(t,t.state):e.enabled!==!1,d(e.skip)?!!e.skip(t,t.state):e.skip===!0,ae(e.page,t)??null])}catch{return}if(n===void 0){n=i;return}i!==n&&(n=i,queueMicrotask(()=>s(e,t,r)))});Array.isArray(o.__effects)?o.__effects.push(a):o.__fetchListeners.push(()=>a.dispose())},Mt=(e,t,r)=>{const s=t.__ref;s.__fetchCleanups||(s.__fetchCleanups=[]),Dt();const o=e.refetchInterval;if(o){const u=typeof o=="number"?o:re(o);if(u>0){const y=setInterval(()=>{(e.refetchIntervalInBackground||typeof document>"u"||document.visibilityState==="visible")&&R(e,t,r,{force:!0})},u);s.__fetchCleanups.push(()=>clearInterval(y))}}const n=De(e),a=e.refetchOnWindowFocus===void 0?!n:e.refetchOnWindowFocus!==!1,i=e.refetchOnReconnect===void 0?!n:e.refetchOnReconnect!==!1;if(a){const u=()=>{const y=qe(e,t,r),c=se(P(r),y),l=Le(e.cache);(!c||c.stale||Date.now()-c.time>(l?.staleTime||0))&&R(e,t,r,{force:!0})};ee.focus.add(u),s.__fetchCleanups.push(()=>ee.focus.delete(u))}if(i){const u=()=>R(e,t,r,{force:!0});ee.online.add(u),s.__fetchCleanups.push(()=>ee.online.delete(u))}},kt=(e,t,r)=>{if(!t.optimistic)return null;const s=e.__ref,o=t.as,n=e.state?.parse?e.state.parse():X(e.state)?{...e.state}:e.state;s.__optimisticSnapshot=n;const a=d(t.optimistic)?t.optimistic(r,n,e):t.optimistic;return a!==void 0&&U(e,a,o),n},je=(e,t)=>{const r=e.__ref;if(!r||!t.optimistic)return;const s=r.__optimisticSnapshot;s!==void 0&&(U(e,s,t.as),delete r.__optimisticSnapshot)},ce=e=>{if(!e)return()=>!0;if(ye(e))return t=>t.includes(e);if(N(e)){const t=e.join(":");return r=>r.includes(t)}return e instanceof RegExp?t=>(e.lastIndex=0,e.test(t)):d(e)?t=>{try{return!!e(t)}catch{return!1}}:()=>!1},Ot=(e,t)=>{const r=[];for(const s of e.mounted){if(!et(s)){e.mounted.delete(s);continue}const o=Tt(s);o&&t(o)&&r.push(R(s.config,s.element,s.context,{refresh:!0}))}return Promise.allSettled(r).then(()=>{})},Be=(e,t)=>{bt();for(const[r,s]of e.cache)t(r)&&(s.stale=!0,ve(e,r));for(const[r]of e.active)!e.cache.has(r)&&t(r)&&ve(e,r);return Ot(e,t)},ct=(e,t,r)=>{const s=(N(t)?t:[t]).map(o=>o===!0||o==="*"?n=>n.startsWith(r+":"):o?ce(o):()=>!1);return Be(e,o=>s.some(n=>n(o)))},Ke=(e,t)=>{for(const[r]of e.cache)t(r)&&Ze(e,r);for(const[r]of e.active)t(r)&&ve(e,r)},Ye=()=>!0,ut=(e,t)=>se(e,t)?.data??void 0,ft=(e,t,r)=>{const s=se(e,t),o=d(r)?r(s?.data):r;ne(e,t,o,null)},Lt=async(e,t,r)=>{const s=r?.fetch;if(!s)return;const o=await Ue(s,r);if(!o)return;const n=t.__ref,{method:a,from:i,fields:u,transform:y,as:c,on:l,auth:S,headers:Q,baseUrl:G,responseType:z,invalidates:ue,optimistic:fe,onMutate:W,onSuccess:M,onError:j,onSettled:I}=e;let w;if(u===!0||l==="submit")w=ie(t);else if(N(u)){const m=ie(t);w={};for(const F of u)w[F]=m[F]}else t.state?.parse?w=t.state.parse():X(t.state)&&(w={...t.state});y&&(w=y(w,t,t.state)),d(W)&&W(w,t,t.state);const te=fe?kt(t,e,w):null;$(t,{isFetching:!0,isLoading:!1,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),C(t,"onFetchStart"),L(e,t,"onFetchStart");const E=r?.analyze?.emitNetwork,V=E?typeof performance<"u"?performance.now():Date.now():0;E&&E({phase:"start",mode:"mutation",from:i,method:a});try{if(S!==!1&&o.auth!==!1&&o.getSession){const K=await o.getSession();if(S===!0&&!K){te!==void 0&&je(t,e);const q={message:"Not authenticated"};C(t,"onFetchError",q),L(e,t,"onFetchError",q);return}}const m=o[a];if(!d(m))return;const F={from:i,data:w,headers:Q,baseUrl:G};z!==void 0&&(F.responseType=z),e.params&&(F.params=Ee(e.params,t,r));const B=oe(t,r);B&&(F.headers={...F.headers,"Accept-Language":B});const x=rt(e,!0),J=await st(()=>m(F),x),{data:T,error:k}=J||{};if(k){te!==void 0&&je(t,e),$(t,ze(k)),C(t,"onFetchError",k),d(j)&&j(k,w,t),d(I)&&I(null,k,w,t),E&&E({phase:"error",mode:"mutation",from:i,method:a,error:k.message||String(k),durationMs:(typeof performance<"u"?performance.now():Date.now())-V});return}if(delete n.__optimisticSnapshot,$(t,Qe),T!==void 0&&(c||!$e(T))){const K=c?{[c]:T}:T;t.state?.update&&t.state.update(K,{preventFetch:!0})}C(t,"onFetchComplete",T),L(e,t,"onFetchComplete",T),d(M)&&M(T,w,t),d(I)&&I(T,null,w,t),E&&E({phase:"success",mode:"mutation",ok:!0,from:i,method:a,durationMs:(typeof performance<"u"?performance.now():Date.now())-V}),ue&&ct(P(r),ue,i)}catch(m){te!==void 0&&je(t,e),$(t,ze(m)),C(t,"onFetchError",m),L(e,t,"onFetchError",m),d(j)&&j(m,w,t),d(I)&&I(null,m,w,t),E&&E({phase:"error",mode:"mutation",from:i,method:a,error:m.message||String(m),durationMs:(typeof performance<"u"?performance.now():Date.now())-V})}finally{n.__fetching=!1}},Rt=e=>{const t=r=>{try{r()}catch{}};for(const r of e.__fetchCleanups||[])t(r);for(const r of e.__fetchListeners||[])t(r);d(e.__unsubscribe)&&t(e.__unsubscribe);for(const r of e.__fetchMounted||[])P(r.context).mounted.delete(r);e.__fetchCleanups=[],e.__fetchListeners=[],e.__unsubscribe=null,e.__fetchMounted=[]},lt=(e,t,r,s)=>{if(!e||!s?.fetch)return;const n=Ve(e,t);if(!n)return;const a=N(n)?n.map(c=>ot(Ve(c,t),t)).filter(Boolean):[ot(n,t)].filter(Boolean),i=t.__ref,u=P(s);if(i.__fetchMounted)for(const c of i.__fetchMounted)u.mounted.delete(c);i.__fetchMounted=[],!i.__fetchDisposer&&N(i.__effects)&&(i.__fetchDisposer={dispose:()=>Rt(i)},i.__effects.push(i.__fetchDisposer));const y=!Je(s);for(const c of a){const l=at(c.method),S=l?Lt:R,Q=!l&&!Ie(c)&&c.method!=="subscribe";if(c.on==="create"?S(c,t,s):queueMicrotask(()=>At({...c,__runner:S},t,s)),Q&&c.on==="create"&&(y&&(c.refetchInterval||c.refetchOnWindowFocus!==!1||c.refetchOnReconnect!==!1)&&Mt(c,t,s),!De(c))){const G={element:t,ref:i,config:c,context:s};u.mounted.add(G),i.__fetchMounted.push(G)}}i.refetch=c=>{for(const l of a)R(l,t,s,{force:!0,...c})},i.fetchNextPage=()=>{const c=a[0];if(!c||!c.infinite)return;const l=i.__nextPageParam;if(l==null)return;const S={...c,cursor:l};R(S,t,s,{direction:"next",force:!0})},i.fetchPreviousPage=()=>{const c=a[0];if(!c||!c.infinite)return;const l=i.__prevPageParam;if(l==null)return;const S={...c,cursor:l};R(S,t,s,{direction:"previous",force:!0})}},jt={invalidateQueries:e=>Be(A,ce(e)),removeQueries:e=>{Ke(A,e?ce(e):Ye)},getQueryData:e=>ut(A,e),setQueryData:(e,t)=>{ft(A,e,t)},prefetchQuery:async(e,t)=>{const r=t?.fetch;if(!r)return;const s=P(t),o=await Ue(r,t);if(!o)return;const n=e.method||"select",a=Te(null,t),i=oe(null,t),u=ke({...e,method:n},e.params,a,i),y=o[n];if(!d(y))return;const c={from:e.from,params:e.params,limit:e.limit,offset:e.offset,order:e.order,single:e.single,headers:e.headers,baseUrl:e.baseUrl};i&&(c.headers={...c.headers,"Accept-Language":i}),e.responseType!==void 0&&(c.responseType=e.responseType),n==="rpc"&&(c.read=!Ie(e)&&e.read!==!1);const l=++we,S=await y(c);if(S?.data!==void 0&&!S?.error&&!De(e)&&!ge(s,u,l)){const Q=ne(s,u,S.data,null,l,Oe(s,u,l));Q.gcTime=Le(e.cache)?.gcTime||3e5}return S},getCache:()=>A.cache,clear:()=>Ke(A,Ye),dropNonLang:e=>{if(!e)return;const t=`:${e}`;for(const[r]of A.cache)r.match(/:([a-z]{2,3})$/i)&&(r.endsWith(t)||Ze(A,r))}},dt=(e,t)=>X(e)?qe({method:"select",...e},t,t?.context):e,Bt={invalidateQueries(e){return Be(P(this?.context),ce(e))},removeQueries(e){Ke(P(this?.context),e?ce(e):Ye)},getQueryData(e){return ut(P(this?.context),dt(e,this))},setQueryData(e,t){ft(P(this?.context),dt(e,this),t)}},Kt={name:"fetch",create(e){const t=e.fetch;t&&(e.parent||P(e.context).active.clear(),lt(t,e,e.state,e.context))}};import{earlyKey as Vt,EARLY_KEY as xt,createEarlySeedScript as Jt,createEarlySeedBlock as Ht,SEED_BLOCK as Xt}from"./early.js";import{requestsInFlight as er,whenRequestsIdle as tr}from"./inflight.js";var Yt=lt;export{xt as EARLY_KEY,Xt as SEED_BLOCK,Qt as createAdapter,Ht as createEarlySeedBlock,Jt as createEarlySeedScript,Yt as default,Vt as earlyKey,lt as executeFetch,Bt as fetchFunctions,Kt as fetchPlugin,$t as hasAdapter,Ne as initAdapterAuth,re as parseDuration,jt as queryClient,Ut as registerAdapter,er as requestsInFlight,mt as resolveDb,tr as whenRequestsIdle};
|
package/index.js
CHANGED
|
@@ -212,20 +212,81 @@ const parseDuration = (val) => {
|
|
|
212
212
|
return 0
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
// ---
|
|
215
|
+
// --- Server renders ---
|
|
216
|
+
//
|
|
217
|
+
// A context that sets `isolateFetchCache` is one server render:
|
|
218
|
+
// @symbo.ls/brender sets it on every render, and no browser host sets it.
|
|
219
|
+
// Such a context has a query store of its own (Query stores) and binds no
|
|
220
|
+
// browser-only refetch (executeFetch). Window focus, reconnect and
|
|
221
|
+
// `refetchInterval` keep a live page's data fresh; a server render is markup
|
|
222
|
+
// once it ends, and its tree is never disposed, so what a query bound there
|
|
223
|
+
// stayed for the life of the process: a focus / online callback per query
|
|
224
|
+
// element in the module-level listener sets (about 2.5 MB of tree per render
|
|
225
|
+
// kept alive), and an interval that kept firing — with
|
|
226
|
+
// `refetchIntervalInBackground` it asked the tenant's database again every
|
|
227
|
+
// period, and a request that landed during the NEXT render was recorded in
|
|
228
|
+
// that render's fetch seed (brender records the GETs made while it renders),
|
|
229
|
+
// so one tenant's page carried another's rows.
|
|
230
|
+
const isServerRender = (context) => !!context && !!context.isolateFetchCache
|
|
231
|
+
|
|
232
|
+
// --- Query stores ---
|
|
233
|
+
//
|
|
234
|
+
// A store is one query cache: its entries, the requests in flight (the
|
|
235
|
+
// dedup), the invalidation marks and the mounted queries. A browser page has
|
|
236
|
+
// one, the module's (`pageStore`), shared by every context that does not set
|
|
237
|
+
// `isolateFetchCache` — the cache works as it always has, and `queryClient`
|
|
238
|
+
// is its handle.
|
|
239
|
+
//
|
|
240
|
+
// A context that sets `isolateFetchCache` has a store of its own, made on its
|
|
241
|
+
// first use and dropped with the context. @symbo.ls/brender sets it on every
|
|
242
|
+
// server render. A server renders page after page, and project after
|
|
243
|
+
// project, through ONE module instance of this plugin (`smbls build`, a
|
|
244
|
+
// worker isolate, a host rendering several tenants), and a key carries no
|
|
245
|
+
// project identity (`posts:select:""`). With one store, a page answered from
|
|
246
|
+
// the rows an earlier page left made no request, so its fetch seed (recorded
|
|
247
|
+
// from requests) did not carry them (xma.info, 2026-10-16); and two renders
|
|
248
|
+
// of different projects read each other's rows — a render that overlapped
|
|
249
|
+
// another joined its request in flight (its own database never asked), a
|
|
250
|
+
// reply that landed after the other render's newer one took that render's
|
|
251
|
+
// rows, a finished render's late reply served the next render's later
|
|
252
|
+
// mounts, and one render's first query wiped the other's cache, mounted
|
|
253
|
+
// queries and project-code writes. 3.14.665 emptied the one store when a new
|
|
254
|
+
// render ran its first query, which only covered renders that never overlap.
|
|
255
|
+
// Keyed by the context object, a render's store is reached only through its
|
|
256
|
+
// own elements (runFetch, executeFetch, the project functions) and through
|
|
257
|
+
// prefetchQuery given its context: every render starts empty and makes its
|
|
258
|
+
// own requests, and nothing of one render is visible to another, at any
|
|
259
|
+
// timing. The flag travels on the context, so the copy of this plugin that
|
|
260
|
+
// runs the render — the one inside a server bundle — keeps the store; nothing
|
|
261
|
+
// from outside that copy has to reach it.
|
|
262
|
+
const createStore = () => ({
|
|
263
|
+
cache: new Map(), // key -> entry
|
|
264
|
+
subscribers: new Map(), // key -> Set of callbacks
|
|
265
|
+
active: new Map(), // key -> in-flight promise (dedup)
|
|
266
|
+
invalidatedAt: new Map(), // key -> seq of the key's last invalidation or removal
|
|
267
|
+
mounted: new Set() // the queries on screen (see Mounted queries)
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
const pageStore = createStore()
|
|
271
|
+
const renderStores = new WeakMap() // isolating context -> its store
|
|
272
|
+
|
|
273
|
+
const storeOf = (context) => {
|
|
274
|
+
if (!isServerRender(context)) return pageStore
|
|
275
|
+
let store = renderStores.get(context)
|
|
276
|
+
if (!store) renderStores.set(context, (store = createStore()))
|
|
277
|
+
return store
|
|
278
|
+
}
|
|
216
279
|
|
|
217
|
-
|
|
218
|
-
const querySubscribers = new Map() // key -> Set of elements
|
|
219
|
-
const activeQueries = new Map() // key -> Promise (deduplication)
|
|
280
|
+
// --- Query cache ---
|
|
220
281
|
|
|
221
282
|
// Request order. Every request a query sends, every cache write and every
|
|
222
283
|
// invalidation takes the next number. A reply then knows whether it is older
|
|
223
284
|
// than its key's last invalidation (its rows may predate the write: kept, but
|
|
224
285
|
// never served as fresh) and whether a request that started after it has
|
|
225
286
|
// already written its answer (that newer answer wins — a slow reply never
|
|
226
|
-
// puts old rows back over it).
|
|
287
|
+
// puts old rows back over it). One order for every store: a number is only
|
|
288
|
+
// ever compared with numbers of the same store's keys.
|
|
227
289
|
let fetchSeq = 0
|
|
228
|
-
const invalidatedAt = new Map() // key -> seq of the key's last invalidation or removal
|
|
229
290
|
const requestSeqs = new WeakMap() // in-flight promise -> seq of its request
|
|
230
291
|
|
|
231
292
|
// The cache (and dedup) key of a query. runFetch writes its entry under it and
|
|
@@ -258,12 +319,12 @@ const queryCacheKey = (config, params, scope, lang, page = config.page, cursor =
|
|
|
258
319
|
return `${from}:${method}:${scopeSeg}${JSON.stringify(params || '')}${infinite ? ':infinite' : ''}${pageSeg}${cursorSeg}${langSuffix}`
|
|
259
320
|
}
|
|
260
321
|
|
|
261
|
-
const getCacheEntry = (key) =>
|
|
322
|
+
const getCacheEntry = (store, key) => store.cache.get(key) || null
|
|
262
323
|
|
|
263
324
|
// `seq` is the request the rows came from (a direct write — setQueryData,
|
|
264
325
|
// initialData, a prefetch — is its own, current one); `stale` is set for rows
|
|
265
326
|
// whose request started before the key's last invalidation.
|
|
266
|
-
const setCacheEntry = (key, data, error, seq = ++fetchSeq, stale = false) => {
|
|
327
|
+
const setCacheEntry = (store, key, data, error, seq = ++fetchSeq, stale = false) => {
|
|
267
328
|
const entry = {
|
|
268
329
|
data,
|
|
269
330
|
error,
|
|
@@ -271,10 +332,10 @@ const setCacheEntry = (key, data, error, seq = ++fetchSeq, stale = false) => {
|
|
|
271
332
|
stale,
|
|
272
333
|
seq
|
|
273
334
|
}
|
|
274
|
-
|
|
335
|
+
store.cache.set(key, entry)
|
|
275
336
|
|
|
276
337
|
// Notify all subscribers of this query
|
|
277
|
-
const subs =
|
|
338
|
+
const subs = store.subscribers.get(key)
|
|
278
339
|
if (subs) {
|
|
279
340
|
for (const sub of subs) {
|
|
280
341
|
if (isFunction(sub)) sub(entry)
|
|
@@ -286,32 +347,33 @@ const setCacheEntry = (key, data, error, seq = ++fetchSeq, stale = false) => {
|
|
|
286
347
|
|
|
287
348
|
// The entry a request that started after `seq` wrote (an error aside): the
|
|
288
349
|
// newer answer, which an older reply must not replace.
|
|
289
|
-
const newerEntry = (key, seq) => {
|
|
290
|
-
const entry = key ?
|
|
350
|
+
const newerEntry = (store, key, seq) => {
|
|
351
|
+
const entry = key ? store.cache.get(key) : null
|
|
291
352
|
return entry && !entry.error && entry.seq > seq ? entry : null
|
|
292
353
|
}
|
|
293
354
|
|
|
294
355
|
// A request that started before its key's last invalidation (or removal).
|
|
295
|
-
const isOutdated = (key, seq) => (invalidatedAt.get(key) || 0) > seq
|
|
356
|
+
const isOutdated = (store, key, seq) => (store.invalidatedAt.get(key) || 0) > seq
|
|
296
357
|
|
|
297
358
|
// Every request on `key` that started before now is outdated from here on.
|
|
298
|
-
const markInvalidated = (key) => { invalidatedAt.set(key, ++fetchSeq) }
|
|
359
|
+
const markInvalidated = (store, key) => { store.invalidatedAt.set(key, ++fetchSeq) }
|
|
299
360
|
|
|
300
361
|
// Removing an entry also marks its key, so a reply still in flight writes
|
|
301
362
|
// its rows back as stale, never as fresh.
|
|
302
|
-
const removeCache = (key) => {
|
|
303
|
-
|
|
304
|
-
markInvalidated(key)
|
|
363
|
+
const removeCache = (store, key) => {
|
|
364
|
+
store.cache.delete(key)
|
|
365
|
+
markInvalidated(store, key)
|
|
305
366
|
}
|
|
306
367
|
|
|
307
|
-
const subscribeToCacheKey = (key, callback) => {
|
|
308
|
-
|
|
309
|
-
|
|
368
|
+
const subscribeToCacheKey = (store, key, callback) => {
|
|
369
|
+
const { subscribers } = store
|
|
370
|
+
if (!subscribers.has(key)) subscribers.set(key, new Set())
|
|
371
|
+
subscribers.get(key).add(callback)
|
|
310
372
|
return () => {
|
|
311
|
-
const subs =
|
|
373
|
+
const subs = subscribers.get(key)
|
|
312
374
|
if (subs) {
|
|
313
375
|
subs.delete(callback)
|
|
314
|
-
if (subs.size === 0)
|
|
376
|
+
if (subs.size === 0) subscribers.delete(key)
|
|
315
377
|
}
|
|
316
378
|
}
|
|
317
379
|
}
|
|
@@ -334,15 +396,14 @@ const parseCacheConfig = (cache) => {
|
|
|
334
396
|
// --- Mounted queries ---
|
|
335
397
|
//
|
|
336
398
|
// The queries on screen: one record per element and `on: 'create'` query
|
|
337
|
-
// config, registered by executeFetch
|
|
338
|
-
// CURRENT key it selects (TanStack's
|
|
339
|
-
// on the old rows until their next
|
|
340
|
-
//
|
|
341
|
-
//
|
|
342
|
-
// element was removed (`__ref` gone or
|
|
343
|
-
// registry is walked: an invalidation, or
|
|
344
|
-
|
|
345
|
-
|
|
399
|
+
// config, registered by executeFetch in its context's store (`mounted`). An
|
|
400
|
+
// invalidation refetches the ones whose CURRENT key it selects (TanStack's
|
|
401
|
+
// "active" queries) instead of leaving them on the old rows until their next
|
|
402
|
+
// mount or a window focus. The key is computed when needed — the same
|
|
403
|
+
// resolution as the focus check — because params, language and tenant scope
|
|
404
|
+
// can move after mount. A record whose element was removed (`__ref` gone or
|
|
405
|
+
// replaced) is dropped whenever the registry is walked: an invalidation, or
|
|
406
|
+
// the GC sweep.
|
|
346
407
|
const isMounted = (record) => !!record.ref && record.element.__ref === record.ref
|
|
347
408
|
|
|
348
409
|
const mountedKey = ({ config, element, context }) => {
|
|
@@ -354,6 +415,9 @@ const mountedKey = ({ config, element, context }) => {
|
|
|
354
415
|
}
|
|
355
416
|
|
|
356
417
|
// --- GC ---
|
|
418
|
+
//
|
|
419
|
+
// Sweeps the page store. A render's store is not swept: it goes with its
|
|
420
|
+
// context.
|
|
357
421
|
|
|
358
422
|
let gcTimer = null
|
|
359
423
|
|
|
@@ -361,20 +425,21 @@ const startGC = () => {
|
|
|
361
425
|
if (gcTimer) return
|
|
362
426
|
gcTimer = setInterval(() => {
|
|
363
427
|
const now = Date.now()
|
|
364
|
-
|
|
365
|
-
|
|
428
|
+
const { cache, subscribers, active, invalidatedAt, mounted } = pageStore
|
|
429
|
+
for (const [key, entry] of cache) {
|
|
430
|
+
const subs = subscribers.get(key)
|
|
366
431
|
const hasSubscribers = subs && subs.size > 0
|
|
367
432
|
if (!hasSubscribers && (now - entry.time) > (entry.gcTime || 300000)) {
|
|
368
|
-
|
|
433
|
+
cache.delete(key)
|
|
369
434
|
}
|
|
370
435
|
}
|
|
371
436
|
// What nothing can need any more: an invalidation mark matters while its
|
|
372
437
|
// key has rows or a request out, and a removed element is not mounted.
|
|
373
438
|
for (const [key] of invalidatedAt) {
|
|
374
|
-
if (!
|
|
439
|
+
if (!cache.has(key) && !active.has(key)) invalidatedAt.delete(key)
|
|
375
440
|
}
|
|
376
|
-
for (const record of
|
|
377
|
-
if (!isMounted(record))
|
|
441
|
+
for (const record of mounted) {
|
|
442
|
+
if (!isMounted(record)) mounted.delete(record)
|
|
378
443
|
}
|
|
379
444
|
}, 30000)
|
|
380
445
|
if (gcTimer.unref) gcTimer.unref()
|
|
@@ -510,10 +575,12 @@ const resolveLanguage = (element, context) => {
|
|
|
510
575
|
// state — `root.__fetchScope` — so the SAME (from, method, params) tuple
|
|
511
576
|
// yields DIFFERENT cache/dedup keys per tenant. Without it the cache is
|
|
512
577
|
// tenant-blind: org A's cached `workspaceProject.people:list:""` entry (AND its
|
|
513
|
-
// in
|
|
578
|
+
// request in flight, the dedup) is served / dedup-collapsed for org B, so a
|
|
514
579
|
// page mounted right after an org switch renders the previous tenant's rows.
|
|
515
580
|
// Read generically (same pattern as resolveLanguage) so the plugin stays
|
|
516
581
|
// app-agnostic — apps that never set it get byte-identical keys to before.
|
|
582
|
+
// (Tenants in ONE page share its store, so they need a scope; separate server
|
|
583
|
+
// renders have separate stores — see Query stores.)
|
|
517
584
|
const resolveScope = (element, context) => {
|
|
518
585
|
const root = element?.state?.root || context?.state?.root
|
|
519
586
|
const scope = root?.__fetchScope
|
|
@@ -810,13 +877,15 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
810
877
|
// tenant so an org/workspace switch never serves — or dedup-collapses into —
|
|
811
878
|
// the previous tenant's entry, while keeping `from:method` as the key prefix.
|
|
812
879
|
const cacheKey = cacheConfig ? queryCacheKey(config, params, scope, lang, pageValue, cursorValue) : null
|
|
880
|
+
// The store this run reads and writes: its context's (storeOf).
|
|
881
|
+
const store = storeOf(context)
|
|
813
882
|
|
|
814
883
|
// Apply initial/placeholder data on first mount
|
|
815
884
|
if (!ref.__fetchInitialized && cacheKey) {
|
|
816
885
|
ref.__fetchInitialized = true
|
|
817
886
|
if (initialData !== undefined) {
|
|
818
887
|
const initData = isFunction(initialData) ? initialData() : initialData
|
|
819
|
-
setCacheEntry(cacheKey, initData, null)
|
|
888
|
+
setCacheEntry(store, cacheKey, initData, null)
|
|
820
889
|
}
|
|
821
890
|
}
|
|
822
891
|
|
|
@@ -827,7 +896,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
827
896
|
// dedup, so while the entry was fresh every one of those answered from the
|
|
828
897
|
// cache and sent nothing — a poll shorter than the stale time never polled.
|
|
829
898
|
if ((method === 'select' || method === 'rpc') && cacheKey && cacheConfig && !opts.refresh && !opts.force) {
|
|
830
|
-
const cached = getCacheEntry(cacheKey)
|
|
899
|
+
const cached = getCacheEntry(store, cacheKey)
|
|
831
900
|
if (cached && !cached.error) {
|
|
832
901
|
const age = Date.now() - cached.time
|
|
833
902
|
const isStale = cached.stale || age > (cacheConfig.staleTime || 0)
|
|
@@ -859,8 +928,8 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
859
928
|
// Deduplication — if same query is already in-flight, share the promise (with
|
|
860
929
|
// timeout). Never one that started before the key's last invalidation: its
|
|
861
930
|
// reply may predate the write.
|
|
862
|
-
const existing = cacheKey && !opts.force ?
|
|
863
|
-
if (existing && !isOutdated(cacheKey, requestSeqs.get(existing) || 0)) {
|
|
931
|
+
const existing = cacheKey && !opts.force ? store.active.get(cacheKey) : null
|
|
932
|
+
if (existing && !isOutdated(store, cacheKey, requestSeqs.get(existing) || 0)) {
|
|
864
933
|
// The shared request failed: so did this query, with the same error. It
|
|
865
934
|
// used to read an error answer as null rows (onFetchComplete(null)) and a
|
|
866
935
|
// thrown one as nothing at all.
|
|
@@ -872,7 +941,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
872
941
|
} else if (result?.data !== undefined) {
|
|
873
942
|
// A request that started later (an invalidation's refetch) may have
|
|
874
943
|
// landed first: its rows are the newer answer.
|
|
875
|
-
const newer = !infinite && newerEntry(cacheKey, requestSeqs.get(existing) || 0)
|
|
944
|
+
const newer = !infinite && newerEntry(store, cacheKey, requestSeqs.get(existing) || 0)
|
|
876
945
|
const finalData = shape(newer ? newer.data : result.data)
|
|
877
946
|
if (!isCurrent()) return
|
|
878
947
|
updateElementState(element, finalData, stateKey)
|
|
@@ -889,7 +958,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
889
958
|
}
|
|
890
959
|
|
|
891
960
|
// Set loading status
|
|
892
|
-
const isFirstLoad = !getCacheEntry(cacheKey)?.data
|
|
961
|
+
const isFirstLoad = !getCacheEntry(store, cacheKey)?.data
|
|
893
962
|
setFetchStatus(element, {
|
|
894
963
|
isFetching: true,
|
|
895
964
|
isLoading: isFirstLoad,
|
|
@@ -1015,14 +1084,14 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
1015
1084
|
requestSeqs.set(fetchPromise, requestSeq)
|
|
1016
1085
|
|
|
1017
1086
|
// Store for deduplication
|
|
1018
|
-
if (cacheKey)
|
|
1087
|
+
if (cacheKey) store.active.set(cacheKey, fetchPromise)
|
|
1019
1088
|
|
|
1020
1089
|
try {
|
|
1021
1090
|
const result = await fetchPromise
|
|
1022
1091
|
// An action's write happened whatever became of the element that fired
|
|
1023
1092
|
// it (a dialog that closed on submit): its `invalidates` runs on success.
|
|
1024
1093
|
if (action && config.invalidates && result && !result.error && !result.subscribed) {
|
|
1025
|
-
runInvalidates(config.invalidates, from)
|
|
1094
|
+
runInvalidates(store, config.invalidates, from)
|
|
1026
1095
|
}
|
|
1027
1096
|
if (!isCurrent()) return
|
|
1028
1097
|
if (result?.subscribed) return
|
|
@@ -1031,7 +1100,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
1031
1100
|
|
|
1032
1101
|
if (error) {
|
|
1033
1102
|
// An older request's failure never replaces a newer answer.
|
|
1034
|
-
if (cacheKey && !newerEntry(cacheKey, requestSeq)) setCacheEntry(cacheKey, null, error, requestSeq)
|
|
1103
|
+
if (cacheKey && !newerEntry(store, cacheKey, requestSeq)) setCacheEntry(store, cacheKey, null, error, requestSeq)
|
|
1035
1104
|
fail(error)
|
|
1036
1105
|
if (_emitNet) _emitNet({
|
|
1037
1106
|
phase: 'error', mode: 'query', from, method, cacheKey,
|
|
@@ -1048,12 +1117,12 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
1048
1117
|
// A request that started later has written its newer rows already:
|
|
1049
1118
|
// show those, leave the cache alone. (Not for an infinite query —
|
|
1050
1119
|
// each of its replies is one page, not the whole answer.)
|
|
1051
|
-
const newer = !infinite && newerEntry(cacheKey, requestSeq)
|
|
1120
|
+
const newer = !infinite && newerEntry(store, cacheKey, requestSeq)
|
|
1052
1121
|
if (newer) {
|
|
1053
1122
|
rows = newer.data
|
|
1054
1123
|
} else {
|
|
1055
1124
|
// Invalidated while this request was out: kept, never served as fresh.
|
|
1056
|
-
const entry = setCacheEntry(cacheKey, data, null, requestSeq, isOutdated(cacheKey, requestSeq))
|
|
1125
|
+
const entry = setCacheEntry(store, cacheKey, data, null, requestSeq, isOutdated(store, cacheKey, requestSeq))
|
|
1057
1126
|
entry.gcTime = cacheConfig?.gcTime || 300000
|
|
1058
1127
|
}
|
|
1059
1128
|
}
|
|
@@ -1106,7 +1175,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
1106
1175
|
})
|
|
1107
1176
|
} finally {
|
|
1108
1177
|
// A forced refetch may have replaced this key while the old request ran.
|
|
1109
|
-
if (cacheKey &&
|
|
1178
|
+
if (cacheKey && store.active.get(cacheKey) === fetchPromise) store.active.delete(cacheKey)
|
|
1110
1179
|
}
|
|
1111
1180
|
}
|
|
1112
1181
|
|
|
@@ -1215,7 +1284,7 @@ const bindAutoRefetch = (config, element, context) => {
|
|
|
1215
1284
|
if (onFocusEnabled) {
|
|
1216
1285
|
const onFocus = () => {
|
|
1217
1286
|
const cacheKey = elementQueryKey(config, element, context)
|
|
1218
|
-
const entry = getCacheEntry(cacheKey)
|
|
1287
|
+
const entry = getCacheEntry(storeOf(context), cacheKey)
|
|
1219
1288
|
const cacheConfig = parseCacheConfig(config.cache)
|
|
1220
1289
|
if (!entry || entry.stale || (Date.now() - entry.time) > (cacheConfig?.staleTime || 0)) {
|
|
1221
1290
|
runFetch(config, element, context, { force: true })
|
|
@@ -1298,15 +1367,15 @@ const keyMatcher = (match) => {
|
|
|
1298
1367
|
return () => false
|
|
1299
1368
|
}
|
|
1300
1369
|
|
|
1301
|
-
// Refetch the mounted queries whose current key `matches` selects.
|
|
1302
|
-
// on a key sends the request; the others on that key share it
|
|
1303
|
-
// dedup, which never shares a request that started before the
|
|
1304
|
-
// invalidation — so no one is handed the pre-write rows.
|
|
1305
|
-
const refreshMounted = (matches) => {
|
|
1370
|
+
// Refetch the mounted queries of `store` whose current key `matches` selects.
|
|
1371
|
+
// The first on a key sends the request; the others on that key share it
|
|
1372
|
+
// through the dedup, which never shares a request that started before the
|
|
1373
|
+
// key's invalidation — so no one is handed the pre-write rows.
|
|
1374
|
+
const refreshMounted = (store, matches) => {
|
|
1306
1375
|
const runs = []
|
|
1307
|
-
for (const record of
|
|
1376
|
+
for (const record of store.mounted) {
|
|
1308
1377
|
if (!isMounted(record)) {
|
|
1309
|
-
|
|
1378
|
+
store.mounted.delete(record)
|
|
1310
1379
|
continue
|
|
1311
1380
|
}
|
|
1312
1381
|
const key = mountedKey(record)
|
|
@@ -1315,67 +1384,54 @@ const refreshMounted = (matches) => {
|
|
|
1315
1384
|
return Promise.allSettled(runs).then(() => {})
|
|
1316
1385
|
}
|
|
1317
1386
|
|
|
1318
|
-
// Mark every key `matches` selects as invalidated — its cache
|
|
1319
|
-
// a first load still in flight outdated — then refetch the
|
|
1320
|
-
// those keys; resolves once those refetches settle. The
|
|
1321
|
-
// script asked for (early.js) are dropped as well: an
|
|
1322
|
-
// write happened, and they may predate it.
|
|
1323
|
-
const invalidateMatching = (matches) => {
|
|
1387
|
+
// Mark every key of `store` that `matches` selects as invalidated — its cache
|
|
1388
|
+
// entry stale, and a first load still in flight outdated — then refetch the
|
|
1389
|
+
// mounted queries on those keys; resolves once those refetches settle. The
|
|
1390
|
+
// answers the pre-boot script asked for (early.js) are dropped as well: an
|
|
1391
|
+
// invalidation means a write happened, and they may predate it.
|
|
1392
|
+
const invalidateMatching = (store, matches) => {
|
|
1324
1393
|
dropEarly()
|
|
1325
|
-
for (const [key, entry] of
|
|
1394
|
+
for (const [key, entry] of store.cache) {
|
|
1326
1395
|
if (!matches(key)) continue
|
|
1327
1396
|
entry.stale = true
|
|
1328
|
-
markInvalidated(key)
|
|
1397
|
+
markInvalidated(store, key)
|
|
1329
1398
|
}
|
|
1330
|
-
for (const [key] of
|
|
1331
|
-
if (!
|
|
1399
|
+
for (const [key] of store.active) {
|
|
1400
|
+
if (!store.cache.has(key) && matches(key)) markInvalidated(store, key)
|
|
1332
1401
|
}
|
|
1333
|
-
return refreshMounted(matches)
|
|
1402
|
+
return refreshMounted(store, matches)
|
|
1334
1403
|
}
|
|
1335
1404
|
|
|
1336
1405
|
// A write's `invalidates`: `true` or '*' selects every query of the write's
|
|
1337
1406
|
// own `from`; anything else — or each item of a list — is a match as
|
|
1338
1407
|
// invalidateQueries takes it. (Whole keys only, before: the documented
|
|
1339
1408
|
// `invalidates: ['posts']` matched no real key.)
|
|
1340
|
-
const runInvalidates = (invalidates, from) => {
|
|
1409
|
+
const runInvalidates = (store, invalidates, from) => {
|
|
1341
1410
|
const matchers = (isArray(invalidates) ? invalidates : [invalidates]).map((match) => {
|
|
1342
1411
|
if (match === true || match === '*') return (key) => key.startsWith(from + ':')
|
|
1343
1412
|
return match ? keyMatcher(match) : () => false
|
|
1344
1413
|
})
|
|
1345
|
-
return invalidateMatching((key) => matchers.some((matches) => matches(key)))
|
|
1414
|
+
return invalidateMatching(store, (key) => matchers.some((matches) => matches(key)))
|
|
1346
1415
|
}
|
|
1347
1416
|
|
|
1348
|
-
const removeMatching = (matches) => {
|
|
1349
|
-
for (const [key] of
|
|
1350
|
-
if (matches(key)) removeCache(key)
|
|
1417
|
+
const removeMatching = (store, matches) => {
|
|
1418
|
+
for (const [key] of store.cache) {
|
|
1419
|
+
if (matches(key)) removeCache(store, key)
|
|
1351
1420
|
}
|
|
1352
|
-
for (const [key] of
|
|
1353
|
-
if (matches(key)) markInvalidated(key)
|
|
1421
|
+
for (const [key] of store.active) {
|
|
1422
|
+
if (matches(key)) markInvalidated(store, key)
|
|
1354
1423
|
}
|
|
1355
1424
|
}
|
|
1356
1425
|
|
|
1357
1426
|
const ALL_KEYS = () => true
|
|
1358
1427
|
|
|
1359
|
-
//
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
// boot; xma.info, 2026-10-16), and in an isolate serving several projects,
|
|
1367
|
-
// another project's rows under the same key. A context that sets
|
|
1368
|
-
// `isolateFetchCache` (brender sets it on every render) starts from an empty
|
|
1369
|
-
// cache: the first query it runs drops every entry an earlier context left,
|
|
1370
|
-
// marks the requests still out as outdated (never shared with it, never
|
|
1371
|
-
// written back as fresh) and forgets the queries mounted before it (an
|
|
1372
|
-
// invalidation it makes refetches its own). A browser context never sets it.
|
|
1373
|
-
const isolatedContexts = new WeakSet()
|
|
1374
|
-
const enterContext = (context) => {
|
|
1375
|
-
if (!context || !context.isolateFetchCache || isolatedContexts.has(context)) return
|
|
1376
|
-
isolatedContexts.add(context)
|
|
1377
|
-
removeMatching(ALL_KEYS)
|
|
1378
|
-
mountedQueries.clear()
|
|
1428
|
+
// What getQueryData / setQueryData do, on one store.
|
|
1429
|
+
const readQueryData = (store, key) => getCacheEntry(store, key)?.data ?? undefined
|
|
1430
|
+
|
|
1431
|
+
const writeQueryData = (store, key, updater) => {
|
|
1432
|
+
const existing = getCacheEntry(store, key)
|
|
1433
|
+
const data = isFunction(updater) ? updater(existing?.data) : updater
|
|
1434
|
+
setCacheEntry(store, key, data, null)
|
|
1379
1435
|
}
|
|
1380
1436
|
|
|
1381
1437
|
// --- Mutation runner (insert/update/delete with optimistic + invalidation) ---
|
|
@@ -1484,7 +1540,7 @@ const runMutation = async (config, element, context) => {
|
|
|
1484
1540
|
})
|
|
1485
1541
|
|
|
1486
1542
|
// Invalidate related queries — the mounted ones refetch now
|
|
1487
|
-
if (invalidates) runInvalidates(invalidates, from)
|
|
1543
|
+
if (invalidates) runInvalidates(storeOf(context), invalidates, from)
|
|
1488
1544
|
} catch (e) {
|
|
1489
1545
|
if (snapshot !== undefined) rollbackOptimistic(element, config)
|
|
1490
1546
|
setFetchStatus(element, errorStatus(e))
|
|
@@ -1515,7 +1571,7 @@ const releaseFetch = (ref) => {
|
|
|
1515
1571
|
for (const cleanup of ref.__fetchCleanups || []) release(cleanup)
|
|
1516
1572
|
for (const cleanup of ref.__fetchListeners || []) release(cleanup)
|
|
1517
1573
|
if (isFunction(ref.__unsubscribe)) release(ref.__unsubscribe)
|
|
1518
|
-
for (const record of ref.__fetchMounted || [])
|
|
1574
|
+
for (const record of ref.__fetchMounted || []) storeOf(record.context).mounted.delete(record)
|
|
1519
1575
|
ref.__fetchCleanups = []
|
|
1520
1576
|
ref.__fetchListeners = []
|
|
1521
1577
|
ref.__unsubscribe = null
|
|
@@ -1526,7 +1582,6 @@ export const executeFetch = (param, element, state, context) => {
|
|
|
1526
1582
|
if (!param) return
|
|
1527
1583
|
const db = context?.fetch
|
|
1528
1584
|
if (!db) return
|
|
1529
|
-
enterContext(context)
|
|
1530
1585
|
|
|
1531
1586
|
const fetchProp = exec(param, element)
|
|
1532
1587
|
if (!fetchProp) return
|
|
@@ -1535,11 +1590,13 @@ export const executeFetch = (param, element, state, context) => {
|
|
|
1535
1590
|
? fetchProp.map(c => resolveFetchConfig(exec(c, element), element)).filter(Boolean)
|
|
1536
1591
|
: [resolveFetchConfig(fetchProp, element)].filter(Boolean)
|
|
1537
1592
|
|
|
1538
|
-
// This element's mounted queries (refetched by an invalidation)
|
|
1539
|
-
// replaces its configs, so it replaces their
|
|
1593
|
+
// This element's mounted queries (refetched by an invalidation), in its
|
|
1594
|
+
// context's store. A re-run replaces its configs, so it replaces their
|
|
1595
|
+
// records too.
|
|
1540
1596
|
const ref = element.__ref
|
|
1597
|
+
const store = storeOf(context)
|
|
1541
1598
|
if (ref.__fetchMounted) {
|
|
1542
|
-
for (const record of ref.__fetchMounted)
|
|
1599
|
+
for (const record of ref.__fetchMounted) store.mounted.delete(record)
|
|
1543
1600
|
}
|
|
1544
1601
|
ref.__fetchMounted = []
|
|
1545
1602
|
|
|
@@ -1554,6 +1611,10 @@ export const executeFetch = (param, element, state, context) => {
|
|
|
1554
1611
|
ref.__effects.push(ref.__fetchDisposer)
|
|
1555
1612
|
}
|
|
1556
1613
|
|
|
1614
|
+
// Window focus, reconnect and an interval refresh a live page; a server
|
|
1615
|
+
// render binds none of them (isServerRender).
|
|
1616
|
+
const browserRefetch = !isServerRender(context)
|
|
1617
|
+
|
|
1557
1618
|
for (const config of configs) {
|
|
1558
1619
|
const isMutation = isMutationMethod(config.method)
|
|
1559
1620
|
const runner = isMutation ? runMutation : runFetch
|
|
@@ -1571,13 +1632,13 @@ export const executeFetch = (param, element, state, context) => {
|
|
|
1571
1632
|
|
|
1572
1633
|
// Bind auto-refetch for queries
|
|
1573
1634
|
if (isQuery && config.on === 'create') {
|
|
1574
|
-
if (config.refetchInterval || config.refetchOnWindowFocus !== false || config.refetchOnReconnect !== false) {
|
|
1635
|
+
if (browserRefetch && (config.refetchInterval || config.refetchOnWindowFocus !== false || config.refetchOnReconnect !== false)) {
|
|
1575
1636
|
bindAutoRefetch(config, element, context)
|
|
1576
1637
|
}
|
|
1577
1638
|
// A single-use body has no cache key to invalidate.
|
|
1578
1639
|
if (!isSingleUse(config)) {
|
|
1579
1640
|
const record = { element, ref, config, context }
|
|
1580
|
-
|
|
1641
|
+
store.mounted.add(record)
|
|
1581
1642
|
ref.__fetchMounted.push(record)
|
|
1582
1643
|
}
|
|
1583
1644
|
}
|
|
@@ -1610,35 +1671,36 @@ export const executeFetch = (param, element, state, context) => {
|
|
|
1610
1671
|
}
|
|
1611
1672
|
|
|
1612
1673
|
// --- Query client (global cache management) ---
|
|
1674
|
+
//
|
|
1675
|
+
// The page store's handle (see Query stores): a browser page's cache. A
|
|
1676
|
+
// render context's store is reached through its own elements — the project
|
|
1677
|
+
// functions below, `el.call('invalidateQueries', …)` — and prefetchQuery,
|
|
1678
|
+
// which takes the context.
|
|
1613
1679
|
|
|
1614
1680
|
export const queryClient = {
|
|
1615
1681
|
// Marks every matching entry stale and refetches the mounted queries on
|
|
1616
1682
|
// those keys; resolves once those refetches settle. `keyOrPattern`: nothing
|
|
1617
1683
|
// (every key), a key prefix or substring, a list of key parts (joined with
|
|
1618
1684
|
// ':'), a RegExp, or a predicate `(key) => boolean`.
|
|
1619
|
-
invalidateQueries: (keyOrPattern) => invalidateMatching(keyMatcher(keyOrPattern)),
|
|
1685
|
+
invalidateQueries: (keyOrPattern) => invalidateMatching(pageStore, keyMatcher(keyOrPattern)),
|
|
1620
1686
|
|
|
1621
1687
|
// Drops every matching entry (same matches). A mounted query keeps the rows
|
|
1622
1688
|
// it shows; the next mount loads them afresh.
|
|
1623
1689
|
removeQueries: (keyOrPattern) => {
|
|
1624
|
-
removeMatching(keyOrPattern ? keyMatcher(keyOrPattern) : ALL_KEYS)
|
|
1690
|
+
removeMatching(pageStore, keyOrPattern ? keyMatcher(keyOrPattern) : ALL_KEYS)
|
|
1625
1691
|
},
|
|
1626
1692
|
|
|
1627
|
-
getQueryData: (key) =>
|
|
1628
|
-
const entry = getCacheEntry(key)
|
|
1629
|
-
return entry?.data ?? undefined
|
|
1630
|
-
},
|
|
1693
|
+
getQueryData: (key) => readQueryData(pageStore, key),
|
|
1631
1694
|
|
|
1632
1695
|
setQueryData: (key, updater) => {
|
|
1633
|
-
|
|
1634
|
-
const data = isFunction(updater) ? updater(existing?.data) : updater
|
|
1635
|
-
setCacheEntry(key, data, null)
|
|
1696
|
+
writeQueryData(pageStore, key, updater)
|
|
1636
1697
|
},
|
|
1637
1698
|
|
|
1699
|
+
// Into the store of `context` — a render context's own, else the page's.
|
|
1638
1700
|
prefetchQuery: async (config, context) => {
|
|
1639
1701
|
const db = context?.fetch
|
|
1640
1702
|
if (!db) return
|
|
1641
|
-
|
|
1703
|
+
const store = storeOf(context)
|
|
1642
1704
|
|
|
1643
1705
|
const adapter = await resolveAdapter(db, context)
|
|
1644
1706
|
if (!adapter) return
|
|
@@ -1673,16 +1735,16 @@ export const queryClient = {
|
|
|
1673
1735
|
|
|
1674
1736
|
// Ordered like a query's reply: never over newer rows, stale when the key
|
|
1675
1737
|
// was invalidated while the prefetch was out.
|
|
1676
|
-
if (result?.data !== undefined && !result?.error && !isSingleUse(config) && !newerEntry(cacheKey, requestSeq)) {
|
|
1677
|
-
const entry = setCacheEntry(cacheKey, result.data, null, requestSeq, isOutdated(cacheKey, requestSeq))
|
|
1738
|
+
if (result?.data !== undefined && !result?.error && !isSingleUse(config) && !newerEntry(store, cacheKey, requestSeq)) {
|
|
1739
|
+
const entry = setCacheEntry(store, cacheKey, result.data, null, requestSeq, isOutdated(store, cacheKey, requestSeq))
|
|
1678
1740
|
entry.gcTime = parseCacheConfig(config.cache)?.gcTime || 300000
|
|
1679
1741
|
}
|
|
1680
1742
|
|
|
1681
1743
|
return result
|
|
1682
1744
|
},
|
|
1683
1745
|
|
|
1684
|
-
getCache: () =>
|
|
1685
|
-
clear: () => removeMatching(ALL_KEYS),
|
|
1746
|
+
getCache: () => pageStore.cache,
|
|
1747
|
+
clear: () => removeMatching(pageStore, ALL_KEYS),
|
|
1686
1748
|
|
|
1687
1749
|
// Drop every cache entry whose lang suffix isn't `keepLang`.
|
|
1688
1750
|
// Cache keys are of the form `${from}:${method}:${params}[:lang]` — entries
|
|
@@ -1697,14 +1759,14 @@ export const queryClient = {
|
|
|
1697
1759
|
dropNonLang: (keepLang) => {
|
|
1698
1760
|
if (!keepLang) return
|
|
1699
1761
|
const keepSuffix = `:${keepLang}`
|
|
1700
|
-
for (const [key] of
|
|
1762
|
+
for (const [key] of pageStore.cache) {
|
|
1701
1763
|
// Entry without any lang suffix: presence of `:` in middle but not
|
|
1702
1764
|
// matching any 2-3 letter ISO suffix at the end. Conservative: keep
|
|
1703
1765
|
// entries whose tail doesn't look like `:xx` or `:xxx`.
|
|
1704
1766
|
const tailMatch = key.match(/:([a-z]{2,3})$/i)
|
|
1705
1767
|
if (!tailMatch) continue // no lang suffix → keep
|
|
1706
1768
|
if (key.endsWith(keepSuffix)) continue // matches keepLang → keep
|
|
1707
|
-
removeCache(key)
|
|
1769
|
+
removeCache(pageStore, key)
|
|
1708
1770
|
}
|
|
1709
1771
|
}
|
|
1710
1772
|
}
|
|
@@ -1724,13 +1786,15 @@ const keyFor = (keyOrConfig, element) => {
|
|
|
1724
1786
|
return elementQueryKey({ method: 'select', ...keyOrConfig }, element, element?.context)
|
|
1725
1787
|
}
|
|
1726
1788
|
|
|
1727
|
-
// Each
|
|
1728
|
-
// a server render's
|
|
1789
|
+
// Each works on the caller's store (storeOf its context), as a query does:
|
|
1790
|
+
// in a server render, the render's own — what its project code writes,
|
|
1791
|
+
// removes or invalidates stays in that render; in a browser page, the page
|
|
1792
|
+
// store, as queryClient.
|
|
1729
1793
|
export const fetchFunctions = {
|
|
1730
|
-
invalidateQueries (keyOrPattern) {
|
|
1731
|
-
removeQueries (keyOrPattern) {
|
|
1732
|
-
getQueryData (keyOrConfig) {
|
|
1733
|
-
setQueryData (keyOrConfig, updater) {
|
|
1794
|
+
invalidateQueries (keyOrPattern) { return invalidateMatching(storeOf(this?.context), keyMatcher(keyOrPattern)) },
|
|
1795
|
+
removeQueries (keyOrPattern) { removeMatching(storeOf(this?.context), keyOrPattern ? keyMatcher(keyOrPattern) : ALL_KEYS) },
|
|
1796
|
+
getQueryData (keyOrConfig) { return readQueryData(storeOf(this?.context), keyFor(keyOrConfig, this)) },
|
|
1797
|
+
setQueryData (keyOrConfig, updater) { writeQueryData(storeOf(this?.context), keyFor(keyOrConfig, this), updater) }
|
|
1734
1798
|
}
|
|
1735
1799
|
|
|
1736
1800
|
// --- Plugin interface ---
|
|
@@ -1756,7 +1820,7 @@ export const fetchPlugin = {
|
|
|
1756
1820
|
const fetchProp = element.fetch
|
|
1757
1821
|
if (!fetchProp) return
|
|
1758
1822
|
// Clear stale in-flight queries on root element creation
|
|
1759
|
-
if (!element.parent)
|
|
1823
|
+
if (!element.parent) storeOf(element.context).active.clear()
|
|
1760
1824
|
executeFetch(fetchProp, element, element.state, element.context)
|
|
1761
1825
|
}
|
|
1762
1826
|
}
|