@symbo.ls/fetch 3.14.662 → 3.14.664
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 +42 -0
- package/adapters/rest.js +9 -4
- package/dist/cjs/adapters/rest.js +1 -1
- package/dist/cjs/early.js +1 -1
- package/dist/cjs/earlyScript.js +15 -16
- package/dist/cjs/index.js +1 -1
- package/dist/esm/adapters/rest.js +1 -1
- package/dist/esm/early.js +1 -1
- package/dist/esm/earlyScript.js +14 -15
- package/dist/esm/index.js +1 -1
- package/early.js +70 -14
- package/earlyScript.js +16 -19
- package/index.js +42 -45
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# @symbo.ls/fetch
|
|
2
2
|
|
|
3
|
+
## 3.14.664
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Performance pass on the 3.14.827–3.14.832 batch, and opt-in View Transitions.
|
|
8
|
+
|
|
9
|
+
- Element create is faster than 3.14.826 again (kekela-like 4,068-element tree: create CPU min 1,265–1,355 ms vs 1,361–1,532 ms on 3.14.826). Per-definition caching of the extends merge layers (46,330 → 13,600 entries), no per-element source-text reads, one attribute writer.
|
|
10
|
+
- `css()` 3x faster (21 → 7 µs per call), byte-identical CSS output.
|
|
11
|
+
- Helmet renders a head layer only when its values change (20 `root.update({})` → 0 head renders, was 40). One runtime head writer: `applyElementMetadata`.
|
|
12
|
+
- brender/mermaid: registry script is escaped on the ISR and non-adopt paths; head/SSR output byte-identical otherwise.
|
|
13
|
+
- View Transitions for page switches (opt-in), `viewTransitionName` / `viewTransitionClass` flat props, `designSystem.viewTransition` animations.
|
|
14
|
+
- utils exports shared helpers used by helmet, frank, fetch and polyglot (escapeHtml, jsonForScript, alternateLinkKey, faviconLinkKey, bareLibraryKey, librarySpecsFor, polyglotLangStorageKey, ...).
|
|
15
|
+
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- @symbo.ls/signal@3.14.787
|
|
18
|
+
- @symbo.ls/utils@3.14.786
|
|
19
|
+
|
|
20
|
+
## 3.14.663
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Server rendering is correct and fast, opt-in hydration, and Cloudflare deploys run the full build (FW-BRENDER-HYDRATION-AND-CF-DEPLOY-PROVIDER-1, FW-PUBLISH-TIME-PRERENDER-SSRCACHE-1).
|
|
25
|
+
|
|
26
|
+
Behaviour changes (check these first):
|
|
27
|
+
|
|
28
|
+
- `smbls build` copies `public/` into the output root (never replacing a file the bundler wrote), so `_redirects`, `_headers` and `404.html` ship with every bundler.
|
|
29
|
+
- Booting over a pre-rendered page removes only `style[data-emotion="smbls"]` and `style[data-brender]`; the host page's own `<style>` tags stay.
|
|
30
|
+
- The Cloudflare worker (`renderProjectHtml` without eval) keeps the client render instead of painting a wrong pre-render; a stored pre-render (`ssrCache` / `__ssr`) is still served. `ssrWithoutEval: true` opts back in.
|
|
31
|
+
|
|
32
|
+
Fixes:
|
|
33
|
+
|
|
34
|
+
- Every server render after the first one paints its theme colours again (linkedom made `deepClone` copy nothing nested).
|
|
35
|
+
- Server pages ship their own reset, keyframes and `:root` once, also in the Cloudflare worker (`generateGlobalCSS` read the wrong keys, wrote files and cached across projects).
|
|
36
|
+
- A pre-render waits for its own requests instead of a flat 2 s; server renders stop rescanning the head for every inserted rule.
|
|
37
|
+
- The server render gets the project's `globalScope` and context keys, as the client does; a `<select>` with a value no longer drops its parent.
|
|
38
|
+
|
|
39
|
+
New, opt-in:
|
|
40
|
+
|
|
41
|
+
- Hydration: `hydrate: true` (or `window.__BRENDER_HYDRATE__` from the server, with `__BR_REGISTRY__`) adopts the server DOM instead of replacing it; a mismatch falls back to a fresh node, a throw to the fresh render. brender `renderPage({ adoptDom })` ships the registry and the recorded GET answers; `@symbo.ls/fetch` exports `createEarlySeedScript`, `earlyKey`, `EARLY_KEY`.
|
|
42
|
+
- `smbls deploy --provider cloudflare [--target pages|workers] [--dry-run] [--no-brender]` runs the full `smbls build` pipeline; `--target workers` writes Workers Static Assets config.
|
|
43
|
+
- `smbls publish --ssr` (or `"prerender": true` in `symbols.json`) pre-renders every static route and stores it as `__ssr`, which the platform renderer serves; off by default.
|
|
44
|
+
|
|
3
45
|
## 3.14.662
|
|
4
46
|
|
|
5
47
|
### Patch Changes
|
package/adapters/rest.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { openEarly, takeEarly, earlyKey, isScalarParams, withReads } from '../early.js'
|
|
3
|
+
import { openEarly, takeEarly, earlyKey, isScalarParams, withReads, queryHeaderEntries } from '../early.js'
|
|
4
4
|
|
|
5
5
|
// `buildUrl` and `selectQuery` are the address of a GET. The pre-boot script
|
|
6
6
|
// of `fetch.early` (earlyScript.js) embeds both BY SOURCE, so an early request
|
|
@@ -143,7 +143,9 @@ const isPassThroughBody = (value) =>
|
|
|
143
143
|
// instead — a later source wins and keeps its own spelling, and a null or
|
|
144
144
|
// undefined value removes the header. A source may be any fetch HeadersInit:
|
|
145
145
|
// a plain object, a Headers instance or an array of [name, value] pairs.
|
|
146
|
-
|
|
146
|
+
// Exported: brender's request recorder reads a fetch() call's headers the
|
|
147
|
+
// same way (render.js requestShape).
|
|
148
|
+
export const headerEntries = (source) => {
|
|
147
149
|
if (Array.isArray(source)) return source
|
|
148
150
|
if (typeof source.entries === 'function') return source.entries()
|
|
149
151
|
return Object.entries(source)
|
|
@@ -197,7 +199,7 @@ const NO_TYPE = { 'Content-Type': undefined }
|
|
|
197
199
|
const openReads = (config) => {
|
|
198
200
|
if (!config || typeof config !== 'object') return null
|
|
199
201
|
const params = {}
|
|
200
|
-
for (const
|
|
202
|
+
for (const { header, param } of queryHeaderEntries(config.query)) params[header] = param
|
|
201
203
|
return { params, rpc: config.rpc === 'get' }
|
|
202
204
|
}
|
|
203
205
|
|
|
@@ -205,7 +207,10 @@ const openReads = (config) => {
|
|
|
205
207
|
// is no CORS-safelisted header for application/json: dropped from a read GET.
|
|
206
208
|
const CONTENT_TYPE = 'content-type'
|
|
207
209
|
|
|
208
|
-
|
|
210
|
+
// `url` with `query` set in its query string. Embedded BY SOURCE in the
|
|
211
|
+
// pre-boot script (earlyScript.js), which moves the same configured headers
|
|
212
|
+
// into its GETs' URLs — self-contained like buildUrl.
|
|
213
|
+
export const withQuery = (url, query) => {
|
|
209
214
|
const names = Object.keys(query)
|
|
210
215
|
if (!names.length) return url
|
|
211
216
|
const parsed = new URL(url)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var B=Object.defineProperty;var
|
|
1
|
+
"use strict";var B=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var M=(t,e)=>{for(var r in e)B(t,r,{get:e[r],enumerable:!0})},Q=(t,e,r,l)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of G(e))!z.call(t,s)&&s!==r&&B(t,s,{get:()=>e[s],enumerable:!(l=F(e,s))||l.enumerable});return t};var K=t=>Q(B({},"__esModule",{value:!0}),t);var ot={};M(ot,{buildUrl:()=>H,headerEntries:()=>Y,restAdapter:()=>D,selectQuery:()=>W,setup:()=>st,withQuery:()=>L});module.exports=K(ot);var f=require("../early.js");const H=(t,e,r)=>{const l=e&&!e.startsWith("/")?"/":"",s=new URL(`${t}${l}${e}`);if(r)for(const c in r){const o=r[c];o!=null&&s.searchParams.set(c,typeof o=="object"?JSON.stringify(o):o)}return s.toString()},W=({params:t,select:e,limit:r,offset:l,order:s,single:c})=>{const o={...t};return e&&(o.select=e),r&&(o.limit=r),l&&(o.offset=l),c&&(o.single=!0),s&&(typeof s=="string"?o.order=s:Array.isArray(s)?o.order=s.map(T=>`${T.by}:${T.asc===!1?"desc":"asc"}`).join(","):s.by&&(o.order=`${s.by}:${s.asc===!1?"desc":"asc"}`)),o},q=t=>Object.prototype.toString.call(t).slice(8,-1),J=["auto","json","text","blob","arrayBuffer","stream","response"],V={json:async t=>{const e=await t.text();return e?JSON.parse(e):null},text:t=>t.text(),blob:t=>t.blob(),arrayBuffer:t=>t.arrayBuffer(),stream:t=>t.body,response:t=>t},v=t=>{const e=t.headers.get("content-type");return e&&e.includes("json")?t.json():t.text()},X=async t=>{const e=await t.text(),r=t.headers.get("content-type");if(e&&r&&r.includes("json"))try{return JSON.parse(e)}catch{}return e},I=(t,e)=>t?.message||t?.error||e.statusText||`HTTP ${e.status}`,h=async(t,e,r,l)=>{const s=r??"auto";if(!J.includes(s))throw new TypeError(`@symbo.ls/fetch rest: unknown responseType "${s}" \u2014 use one of: ${J.join(", ")}`);const c=l&&await l||await globalThis.fetch(t,e);if(s==="auto"){const o=await v(c);return{data:o,error:c.ok?null:I(o,c),status:c.status}}if(!c.ok){const o=await X(s==="response"?c.clone():c);return{data:s==="response"?c:o,error:I(o,c),status:c.status}}return{data:await V[s](c),error:null,status:c.status}},Z=["FormData","Blob","File","URLSearchParams","ReadableStream","ArrayBuffer"],C=t=>t!==null&&typeof t=="object"&&(ArrayBuffer.isView(t)||Z.includes(q(t))),Y=t=>Array.isArray(t)?t:typeof t.entries=="function"?t.entries():Object.entries(t),N=(...t)=>{const e={},r=new Map;for(const l of t)if(l)for(const[s,c]of Y(l)){const o=s.toLowerCase();if(r.has(o)&&delete e[r.get(o)],c==null){r.delete(o);continue}r.set(o,s),e[s]=c}return e},tt={"Content-Type":"application/json"},et={"Content-Type":void 0},nt=t=>{if(!t||typeof t!="object")return null;const e={};for(const{header:r,param:l}of(0,f.queryHeaderEntries)(t.query))e[r]=l;return{params:e,rpc:t.rpc==="get"}},rt="content-type",L=(t,e)=>{const r=Object.keys(e);if(!r.length)return t;const l=new URL(t);for(const s of r)l.searchParams.set(s,e[s]);return l.toString()},st=async({url:t,headers:e,auth:r,fetchOptions:l,early:s,reads:c})=>{if(!t)throw new Error("@symbo.ls/fetch rest: url is required");return D(t,e,r,l,s,c)},D=(t,e={},r,l={},s,c)=>{let o=r?.token||null;const T=(0,f.openEarly)((0,f.withReads)(s,c),e),j=nt(c),_=n=>{if(!j)return null;const a={},u={},i={};for(const d in n){const p=d.toLowerCase();if(p==="authorization")return null;if(p===rt)continue;u[d]=n[d];const y=j.params[p];y?i[y]=n[d]:a[d]=n[d]}return{headers:a,adoptHeaders:u,query:i}},A=(n,a)=>{if(!T)return null;let u="";for(const i in a){const d=i.toLowerCase();if(d==="accept-language")u=String(a[i]);else if(T.carried[d]!==a[i])return null}try{return(0,f.takeEarly)((0,f.earlyKey)(n(),u),T.maxAge)}catch{return null}},R=()=>o?{Authorization:`Bearer ${o}`}:null,U=n=>N(e,R(),n),S=n=>({...l,...n}),P=(n,a,u)=>{if(!C(a))return S({method:n,headers:N(e,R(),tt,u),body:JSON.stringify(a)});const i={method:n,headers:N(e,R(),et,u),body:a};return q(a)==="ReadableStream"&&(i.duplex="half"),S(i)},$=(n,a)=>{const u=a||t;if(n&&(n.startsWith("http://")||n.startsWith("https://")))return n;const i=n&&!n.startsWith("/")?"/":"";return`${u}${i}${n||""}`};return{name:"rest",setToken:n=>{o=n},getSession:async()=>{if(!r?.sessionUrl)return o?{token:o}:null;const n=await h($(r.sessionUrl,r.baseUrl),S({headers:U()}));return n.error?null:n.data},signIn:async n=>{if(!r?.signInUrl)throw new Error("rest: auth.signInUrl not configured");const a=await h($(r.signInUrl,r.baseUrl),P("POST",n));return a.data?.token&&(o=a.data.token),a},signOut:async()=>(r?.signOutUrl&&await h($(r.signOutUrl,r.baseUrl),S({method:"POST",headers:U()})),o=null,{error:null}),select:({from:n,params:a,select:u,limit:i,offset:d,order:p,single:y,headers:w,baseUrl:g,responseType:m})=>{const b=H(g||t,n||"",W({params:a,select:u,limit:i,offset:d,order:p,single:y})),E=U(w),O=_(E);if(O){const k=S({headers:O.headers});return h(L(b,O.query),k,m,A(()=>b,O.adoptHeaders))}const x=S({headers:E});return h(b,x,m,A(()=>b,x.headers))},rpc:async({from:n,params:a,headers:u,baseUrl:i,responseType:d,read:p})=>{const y=(0,f.isScalarParams)(a),w=()=>H(i||t,`rpc/${n}`,a),g=k=>h($(`rpc/${n}`,i),P("POST",a,u),d,k),m=U(u),b=p===!0&&j&&j.rpc&&y?_(m):null;let E=null;if(b)try{E=w()}catch{E=null}if(!E)return g(T&&T.rpc&&y?A(w,m):null);const O=S({method:"GET",headers:b.headers}),x=await h(L(E,b.query),O,d,A(()=>E,b.adoptHeaders));return x.status===405?g(null):x},insert:({from:n,data:a,headers:u,baseUrl:i,responseType:d})=>h($(n,i),P("POST",a,u),d),update:({from:n,data:a,params:u,method:i,headers:d,baseUrl:p,responseType:y})=>{const w=u?.id||a?.id,g=w?`${n}/${w}`:n;return h($(g,p),P(i||"PATCH",a,d),y)},upsert:({from:n,data:a,params:u,method:i,headers:d,baseUrl:p,responseType:y})=>{const w=u?.id||a?.id,g=w?`${n}/${w}`:n;return h($(g,p),P(i||"PUT",a,d),y)},delete:({from:n,params:a,headers:u,baseUrl:i,responseType:d})=>{const p=a?.id,y=p?`${n}/${p}`:n;return h($(y,i),S({method:"DELETE",headers:U(u)}),d)}}};
|
package/dist/cjs/early.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var y=Object.defineProperty;var
|
|
1
|
+
"use strict";var y=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var w=(e,r)=>{for(var n in r)y(e,n,{get:r[n],enumerable:!0})},j=(e,r,n,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of k(r))!E.call(e,o)&&o!==n&&y(e,o,{get:()=>r[o],enumerable:!(t=A(r,o))||t.enumerable});return e};var v=e=>j(y({},"__esModule",{value:!0}),e);var Y={};w(Y,{EARLY_KEY:()=>b,EARLY_MAX_AGE:()=>a,createEarlySeedScript:()=>O,dropEarly:()=>P,earlyKey:()=>m,isScalarParams:()=>S,matchEarlyRoute:()=>R,openEarly:()=>q,queryHeaderEntries:()=>x,takeEarly:()=>L,withReads:()=>T});module.exports=v(Y);var h=require("@symbo.ls/utils");const b="@symbo.ls/fetch:EARLY",a=3e4,m=(e,r)=>{const n=new URL(e);return n.searchParams.sort(),n.toString()+" "+(r||"")},S=e=>{if(e==null)return!0;if(typeof e!="object"||Array.isArray(e))return!1;const r=Object.getPrototypeOf(e);if(r!==Object.prototype&&r!==null)return!1;for(const n in e){const t=e[n];if(!(t===void 0||typeof t=="string"||typeof t=="boolean")&&!(typeof t=="number"&&isFinite(t)))return!1}return!0},R=(e,r)=>{const n=s=>String(s).split("/").filter(Boolean),t=n(r);let o=null;for(let s=0;s<e.length;s++){const i=n(e[s]),c=i[i.length-1]==="*",f=c?i.length-1:i.length;if(c?t.length<f:t.length!==f)continue;const g={};let u=c?-1:0,p=!0;for(let l=0;l<f;l++)if(i[l].charAt(0)===":"){try{g[i[l].slice(1)]=decodeURIComponent(t[l])}catch{p=!1;break}u+=1}else if(i[l]===t[l])u+=3;else{p=!1;break}p&&(!o||u>o.score)&&(o={index:s,params:g,score:u})}return o&&{index:o.index,params:o.params}},d=()=>Symbol.for(b),x=(e,r)=>{const n=[];for(const t in e||{}){const o=t.toLowerCase(),s={name:t,header:o,param:e[t],found:!1,value:void 0};for(const i in r||{})i.toLowerCase()===o&&(s.found=!0,s.value=r[i]);n.push(s)}return n},T=(e,r)=>{if(!e||typeof e!="object"||!r||typeof r!="object")return e;const n={...e};return n.query===void 0&&r.query!==void 0&&(n.query=r.query),n.rpc===void 0&&r.rpc!==void 0&&(n.rpc=r.rpc),n},q=(e,r)=>{const n=d();if(!e||typeof e!="object"){const s=globalThis[n];return s&&s.seeded?{carried:{},rpc:!1,maxAge:a}:null}globalThis[n]||(globalThis[n]={entries:{}});const t={};for(const{header:s,found:i,value:c}of x(e.query,r))i&&(t[s]=c);const o=typeof e.maxAge=="number"&&e.maxAge>=0?e.maxAge:a;return{carried:t,rpc:e.rpc==="get",maxAge:o}},L=(e,r=a)=>{const n=globalThis[d()],t=n&&n.entries&&n.entries[e];return!t||(delete n.entries[e],!(Date.now()-t.time<=r))?null:Promise.resolve(t.answer).then(o=>o&&o.ok&&!o.bodyUsed?o:null,()=>null)},P=()=>{const e=globalThis[d()];e&&e.entries&&(e.entries={})},O=e=>{const r=(Array.isArray(e)?e:[]).filter(t=>t&&typeof t.url=="string"&&typeof t.body=="string");if(!r.length)return"";const n=(0,h.jsonForScript)(r.map(t=>({k:m(t.url,t.lang||""),s:t.status||200,t:t.type||"application/json",b:t.body})));return"<script>(function(){try{var k=Symbol.for("+JSON.stringify(b)+"),r=globalThis[k]||(globalThis[k]={entries:{}}),t=Date.now(),l="+n+';r.seeded=true;r.entries=r.entries||{};for(var i=0;i<l.length;i++){var e=l[i];r.entries[e.k]={time:t,answer:Promise.resolve(new Response(e.b,{status:e.s,headers:{"content-type":e.t}}))}}}catch(e){}})()<\/script>'};
|
package/dist/cjs/earlyScript.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`),
|
|
1
|
+
"use strict";var f=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var v=(e,r)=>{for(var t in r)f(e,t,{get:r[t],enumerable:!0})},q=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of p(r))!d.call(e,o)&&o!==t&&f(e,o,{get:()=>r[o],enumerable:!(n=m(r,o))||n.enumerable});return e};var S=e=>q(f({},"__esModule",{value:!0}),e);var K={};v(K,{createEarlyScript:()=>h,default:()=>E});module.exports=S(K);var c=require("@symbo.ls/utils"),s=require("./adapters/rest.js"),a=require("./early.js");const b=["credentials","mode","cache","redirect","referrerPolicy","priority"],g=e=>{try{return new Function(e),!0}catch{return!1}},w=(e,r)=>{const t=typeof e=="function"?e.toString():String(e).trim();if(g("return ("+t+")"))return"("+t+")";if(g("return ({"+t+"})"))return"Object.values({"+t+"})[0]";throw new Error(`@symbo.ls/fetch early: the request function of ${r} does not compile on its own`)},y=(e,r)=>typeof e=="function"||typeof e=="string"?w(e,r):JSON.stringify(Array.isArray(e)?e:[]),O=e=>{const r=e.state&&typeof e.state.lang=="string"?e.state.lang:"",t=e.polyglot;return t&&typeof t=="object"?{storage:(0,c.polyglotLangStorageKey)(t),fallback:(0,c.polyglotFallbackLang)(r,t)}:{storage:"",fallback:r}},$=(e,r)=>{const t={};for(const{name:n,param:o,found:i,value:u}of(0,a.queryHeaderEntries)(e,r)){if(!i)throw new Error(`@symbo.ls/fetch early.query: "${n}" is not one of the adapter's configured headers`);t[o]=u}return t},k=e=>{const r={};for(const t of b)e&&e[t]!==void 0&&(r[t]=e[t]);return r.cache===void 0&&(r.cache="no-store"),r},h=(e={})=>{const r=e&&e.fetch,t=r&&(0,a.withReads)(r.early,r.reads);if(!t||typeof t!="object"||r.adapter!=="rest"||!r.url)return"";const n=t.routes&&typeof t.routes=="object"?Object.keys(t.routes):[];if(!n.length&&!t.always)return"";const o={url:r.url,query:$(t.query,r.headers),rpc:t.rpc==="get",fetchOptions:k(r.fetchOptions),lang:O(e)},i=n.map(l=>`[${JSON.stringify(l)}, ${y(t.routes[l],JSON.stringify(l))}]`).join(`,
|
|
2
|
+
`),u=t.always?y(t.always,"`always`"):"[]";return`/* @symbo.ls/fetch \u2014 fetch.early: the first view's requests, sent before the app boots */
|
|
3
3
|
;(function () {
|
|
4
4
|
var g = globalThis
|
|
5
|
-
var K = Symbol.for(${JSON.stringify(
|
|
5
|
+
var K = Symbol.for(${JSON.stringify(a.EARLY_KEY)})
|
|
6
6
|
if (g[K] || typeof g.fetch !== 'function' || !g.location) return
|
|
7
|
-
var registry = g[K] = {
|
|
8
|
-
var config = ${JSON.stringify(
|
|
9
|
-
var buildUrl = ${
|
|
10
|
-
var selectQuery = ${
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var
|
|
7
|
+
var registry = g[K] = { entries: {} }
|
|
8
|
+
var config = ${JSON.stringify(o)}
|
|
9
|
+
var buildUrl = ${s.buildUrl.toString()}
|
|
10
|
+
var selectQuery = ${s.selectQuery.toString()}
|
|
11
|
+
var withQuery = ${s.withQuery.toString()}
|
|
12
|
+
var earlyKey = ${a.earlyKey.toString()}
|
|
13
|
+
var isScalarParams = ${a.isScalarParams.toString()}
|
|
14
|
+
var matchEarlyRoute = ${a.matchEarlyRoute.toString()}
|
|
15
|
+
var always = ${u}
|
|
15
16
|
var routes = [
|
|
16
|
-
${
|
|
17
|
+
${i}
|
|
17
18
|
]
|
|
18
19
|
var storage = function (key) {
|
|
19
20
|
try { return key ? g.localStorage.getItem(key) : null } catch (e) { return null }
|
|
@@ -42,12 +43,10 @@
|
|
|
42
43
|
var language = request.lang === false ? '' : lang
|
|
43
44
|
var key = earlyKey(url, language)
|
|
44
45
|
if (registry.entries[key]) continue
|
|
45
|
-
var address = new URL(url)
|
|
46
|
-
for (var name in config.query) address.searchParams.set(name, config.query[name])
|
|
47
46
|
var options = Object.assign({}, config.fetchOptions, { method: 'GET' })
|
|
48
47
|
if (language) options.headers = { 'Accept-Language': language }
|
|
49
|
-
registry.entries[key] = { time: Date.now(), answer: g.fetch(
|
|
48
|
+
registry.entries[key] = { time: Date.now(), answer: g.fetch(withQuery(url, config.query), options).catch(function () { return null }) }
|
|
50
49
|
} catch (e) {}
|
|
51
50
|
}
|
|
52
51
|
})()
|
|
53
|
-
`.replace(/<\/script/gi,"<\\/script")};var E=
|
|
52
|
+
`.replace(/<\/script/gi,"<\\/script")};var E=h;
|
package/dist/cjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var ct=Object.create;var he=Object.defineProperty;var ft=Object.getOwnPropertyDescriptor;var lt=Object.getOwnPropertyNames;var dt=Object.getPrototypeOf,pt=Object.prototype.hasOwnProperty;var ht=(e,t)=>{for(var r in t)he(e,r,{get:t[r],enumerable:!0})},Be=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of lt(t))!pt.call(e,o)&&o!==r&&he(e,o,{get:()=>t[o],enumerable:!(s=ft(t,o))||s.enumerable});return e};var Ge=(e,t,r)=>(r=e!=null?ct(dt(e)):{},Be(t||!e||!e.__esModule?he(r,"default",{value:e,enumerable:!0}):r,e)),_t=e=>Be(he({},"__esModule",{value:!0}),e);var Ut={};ht(Ut,{createAdapter:()=>Tt,default:()=>Nt,executeFetch:()=>$e,fetchFunctions:()=>It,fetchPlugin:()=>qt,hasAdapter:()=>wt,initAdapterAuth:()=>Fe,parseDuration:()=>ee,queryClient:()=>ie,registerAdapter:()=>gt,resolveDb:()=>ot});module.exports=_t(Ut);var i=require("@symbo.ls/utils"),st=require("@symbo.ls/signal"),nt=require("./early.js");const yt=["select","rpc","insert","update","upsert","delete","subscribe"],Ke={rest:()=>import("./adapters/rest.js"),local:()=>import("./adapters/local.js")},_e=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),X=(()=>{if(typeof globalThis<"u"&&globalThis[_e])return globalThis[_e];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,_e,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[_e]}catch{}return e})(),ye=Symbol.for("@symbo.ls/fetch:PENDING_ADAPTERS"),Ae=(()=>{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})(),St=5e3,bt=e=>new Promise(t=>{if(X[e])return t(X[e]);const r=Ae[e]||=[];let s=!1;const o=()=>{s||(s=!0,t(X[e]||null))};r.push(o),setTimeout(o,St)}),gt=(e,t)=>{X[e]=t;const r=Ae[e];if(r&&r.length){Ae[e]=[];for(const s of r)s()}},wt=e=>typeof e=="string"&&!!(X[e]||Ke[e]),Tt=e=>{const t={};for(const r of yt)e[r]&&(t[r]=e[r]);return t.name=e.name||"custom",t},ot=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]||Ke[s];if(!o&&(o=await bt(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},v=new Map,K=new Map,R=new Map;let I=0;const q=new Map,Ce=new WeakMap,Me=(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,d=r?`${r}:`:"",_=s?`:${s}`:"",h=o?":p"+JSON.stringify(o):"",D=n!=null?":c"+JSON.stringify(n):"";return`${u}:${c}:${d}${JSON.stringify(t||"")}${a?":infinite":""}${h}${D}${_}`},re=e=>v.get(e)||null,se=(e,t,r,s=++I,o=!1)=>{const n={data:t,error:r,time:Date.now(),stale:o,seq:s};v.set(e,n);const u=K.get(e);if(u)for(const c of u)(0,i.isFunction)(c)&&c(n);return n},Se=(e,t)=>{const r=e?v.get(e):null;return r&&!r.error&&r.seq>t?r:null},Le=(e,t)=>(q.get(e)||0)>t,be=e=>{if(e){v.delete(e),q.set(e,++I);return}for(const[t]of v)q.set(t,++I);for(const[t]of R)q.set(t,++I);v.clear()},$t=(e,t)=>(K.has(e)||K.set(e,new Set),K.get(e).add(t),()=>{const r=K.get(e);r&&(r.delete(t),r.size===0&&K.delete(e))}),ke=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},x=new Set,xe=e=>!!e.ref&&e.element.__ref===e.ref,vt=({config:e,element:t,context:r})=>{try{return Ie(e,t,r)}catch{return null}};let ge=null;const Ft=()=>{ge||(ge=setInterval(()=>{const e=Date.now();for(const[t,r]of v){const s=K.get(t);!(s&&s.size>0)&&e-r.time>(r.gcTime||3e5)&&v.delete(t)}for(const[t]of q)!v.has(t)&&!R.has(t)&&q.delete(t);for(const t of x)xe(t)||x.delete(t)},3e4),ge.unref&&ge.unref())};Ft();const Ve=3,Oe=e=>Math.min(1e3*2**e,3e4),We=(e,t)=>{const r=e.retry;return r===void 0&&t?{count:0}:r===!1?{count:0}:r===!0||r===void 0?{count:Ve,delay:Oe}:typeof r=="number"?{count:r,delay:Oe}:{count:r.count??Ve,delay:(0,i.isFunction)(r.delay)?r.delay:typeof r.delay=="number"?()=>r.delay:Oe}},Ye=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}},Z={focus:new Set,online:new Set};let Je=!1;const Et=()=>{if(Je||typeof window>"u")return;Je=!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)},He=(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},Dt=["insert","update","upsert","delete"],Xe=e=>Dt.includes(e),Re=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},we=(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,Ie=(e,t,r)=>Me(e,Te(e.params,t,r),we(t,r),ne(t,r),oe(e.page,t),oe(e.cursor,t)),Fe=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)})},qe=async(e,t)=>{if((0,i.isFunction)(e.select))return e.auth!==!1&&await Fe(e,t),e;if(e.__resolved)return e.auth!==!1&&await Fe(e.__resolved,t),e.__resolved;if(e.__resolving)return e.__resolving;e.__resolving=ot(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 Fe(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)},E=(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},ve=e=>e.responseType==="stream"||e.responseType==="response",Pt=["Blob","File","ArrayBuffer","ReadableStream","Response"],Ne=e=>e!==null&&typeof e=="object"&&(ArrayBuffer.isView(e)||Pt.includes(Object.prototype.toString.call(e).slice(8,-1))),Q=(e,t,r,s={})=>{if(!r&&Ne(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)&&!Ne(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})}},C=(e,t)=>{const r=e?.__ref;r&&(r.__fetchStatus={...t,isError:!!t.error},r.__fetching=t.isFetching,r.__fetchError=t.error)},Ze=(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)},N=async(e,t,r,s={})=>{const o=r?.fetch;if(!o||!t||!t.__ref)return;const n=t.__ref,u=we(t,r);(!n.__fetchScopeOwner||n.__fetchScopeOwner.scope!==u)&&(n.__fetchScopeOwner={scope:u});const c=n.__fetchScopeOwner,a=()=>t.__ref===n&&n.__fetchScopeOwner===c&&we(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 d=await qe(o,r);if(!d||!a())return;const{from:_,method:h,query:D,params:Ee,cache:De,transform:P,single:ue,auth:ce,fields:V,as:L,limit:$,offset:U,order:b,headers:te,baseUrl:m,responseType:W,page:T,cursor:M,infinite:z,placeholderData:Y,initialData:J,select:g,keepPreviousData:k}=e;let j=(0,i.isString)(g)?g:void 0;if(D&&(0,i.isFunction)(t.getQuery)){const p=t.getQuery(d.name||"paths");p&&(j=p.select||p.length&&p.join(",")||j)}const B=Te(Ee,t,r),A=oe(T,t),Pe=oe(M,t),fe=Re(e),le=ve(e)||fe?null:ke(De),at=We(e,fe||Xe(h)),ze=ne(t,r),y=le?Me(e,B,u,ze,A,Pe):null;if(!n.__fetchInitialized&&y&&(n.__fetchInitialized=!0,J!==void 0)){const p=(0,i.isFunction)(J)?J():J;se(y,p,null)}if((h==="select"||h==="rpc")&&y&&le&&!s.refresh&&!s.force){const p=re(y);if(p&&!p.error){const f=Date.now()-p.time,w=p.stale||f>(le.staleTime||0);z&&(0,i.isArray)(p.data)&&!n.__pages&&(n.__pages=[p.data],Ze(n,e,p.data));let l=p.data;if((0,i.isFunction)(g)&&(l=g(l,t,t.state)),P&&(l=P(l,t,t.state)),!a())return;if(!w){C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),Q(t,l,L);return}Q(t,l,L)}else if(Y!==void 0){const f=(0,i.isFunction)(Y)?Y(t,t.state):Y;f!==void 0&&Q(t,f,L)}}const de=y&&!s.force?R.get(y):null;if(de&&!Le(y,Ce.get(de)||0)){const p=f=>{C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:f,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",f),E(e,t,"onFetchError",f)};try{const f=await Promise.race([de,new Promise((w,l)=>setTimeout(()=>l("DEDUP_TIMEOUT"),15e3))]);if(!a())return;if(f?.error)p(f.error);else if(f?.data!==void 0){const w=!z&&Se(y,Ce.get(de)||0);let l=w?w.data:f.data;if((0,i.isFunction)(g)&&(l=g(l,t,t.state)),P&&(l=P(l,t,t.state)),!a())return;Q(t,l,L),F(t,"onFetchComplete",l),E(e,t,"onFetchComplete",l)}}catch(f){if(!a())return;f!=="DEDUP_TIMEOUT"&&p(f)}return}const it=!re(y)?.data;C(t,{isFetching:!0,isLoading:it,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),F(t,"onFetchStart"),E(e,t,"onFetchStart");const O=r?.analyze?.emitNetwork,me=O?typeof performance<"u"?performance.now():Date.now():0;O&&O({phase:"start",mode:"query",from:_,method:h,cacheKey:y,lang:ze});const ut=async()=>{if(!a())return;if(ce!==!1&&d.auth!==!1&&d.getSession){const l=await d.getSession();if(!a())return;if(ce===!0&&!l){const S={message:"Not authenticated"};return C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:S,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",S),E(e,t,"onFetchError",S),{data:null,error:S}}}const p=d[h];if(!(0,i.isFunction)(p))return{data:null,error:{message:`Method "${h}" not found on adapter`}};const f={from:_,select:j,params:B,single:ue,limit:$,offset:U,order:b,headers:te,baseUrl:m};W!==void 0&&(f.responseType=W);const w=ne(t,r);if(w&&(f.headers={...f.headers,"Accept-Language":w}),A!==void 0){if((0,i.isObject)(A))A.offset!==void 0&&(f.offset=A.offset),A.limit!==void 0&&(f.limit=A.limit),A.cursor!==void 0&&(f.params={...f.params,cursor:A.cursor});else if(typeof A=="number"){const l=e.pageSize||$||20;f.offset=(A-1)*l,f.limit=l}}if(Pe!==void 0&&(f.params={...f.params,cursor:Pe}),h==="insert"||h==="update"||h==="upsert"){let l;if(V===!0||e.on==="submit")l=ae(t);else if((0,i.isArray)(V)){const S=ae(t);l={};for(const G of V)l[G]=S[G]}else t.state?.parse?l=t.state.parse():(0,i.isObject)(t.state)&&(l={...t.state});P&&(l=P(l,t,t.state)),f.data=l}if(h==="rpc"){let l=B;if(e.on==="submit"){const S=ae(t);l=e.transformParams?e.transformParams(S,t,t.state):S}f.params=l,f.read=!fe&&e.read!==!1}if(h==="subscribe"){if((0,i.isFunction)(n.__unsubscribe)){const S=n.__unsubscribe;n.__unsubscribe=null;try{S()}catch{}}const l=d.subscribe({from:_,params:B,on:e.subscribeOn},(S,G,je)=>{a()&&(Q(t,S,L),F(t,"onFetchComplete",S),E(e,t,"onFetchComplete",S))});return a()?(n.__unsubscribe=l,{data:null,error:null,subscribed:!0}):((0,i.isFunction)(l)&&l(),{data:null,error:null,subscribed:!0})}return p(f)},H=++I,pe=Ye(ut,at);Ce.set(pe,H),y&&R.set(y,pe);try{const p=await pe;if(fe&&e.invalidates&&p&&!p.error&&!p.subscribed&&tt(e.invalidates,_),!a()||p?.subscribed)return;const{data:f,error:w}=p||{};if(w){y&&!Se(y,H)&&se(y,null,w,H),C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:w,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",w),E(e,t,"onFetchError",w),O&&O({phase:"error",mode:"query",from:_,method:h,cacheKey:y,error:w.message||w,durationMs:(typeof performance<"u"?performance.now():Date.now())-me});return}if(f!==void 0){let l=f;if((h==="select"||h==="rpc")&&y){const G=!z&&Se(y,H);if(G)l=G.data;else{const je=se(y,f,null,H,Le(y,H));je.gcTime=le?.gcTime||3e5}}let S=l;if(z&&(0,i.isArray)(f)&&((!n.__pages||!s.direction)&&(n.__pages=[]),s.direction==="previous"?n.__pages.unshift(f):n.__pages.push(f),S=n.__pages.flat(),Ze(n,e,f)),(0,i.isFunction)(g)&&(S=g(S,t,t.state)),P&&(S=P(S,t,t.state)),!a())return;C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),(!k||S!==void 0)&&Q(t,S,L),F(t,"onFetchComplete",S),E(e,t,"onFetchComplete",S),O&&O({phase:"success",mode:"query",ok:!0,from:_,method:h,cacheKey:y,durationMs:(typeof performance<"u"?performance.now():Date.now())-me})}}catch(p){if(!a())return;C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:p,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",p),E(e,t,"onFetchError",p),O&&O({phase:"error",mode:"query",from:_,method:h,cacheKey:y,error:p.message||String(p),durationMs:(typeof performance<"u"?performance.now():Date.now())-me})}finally{y&&R.get(y)===pe&&R.delete(y)}},mt=(e,t,r)=>{const s=e.on,o=t.__ref;if(!o)return;o.__fetchListeners||(o.__fetchListeners=[]);const n=e.__runner||N;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"&&At(e,t,r,n)},At=(e,t,r,s)=>{const o=t.__ref;let n;const u=(0,st.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,Promise.resolve().then(()=>s(e,t,r)))});Array.isArray(o.__effects)?o.__effects.push(u):o.__fetchListeners.push(()=>u.dispose())},Ct=(e,t,r)=>{const s=t.__ref;s.__fetchCleanups||(s.__fetchCleanups=[]),Et();const o=e.refetchInterval;if(o){const a=typeof o=="number"?o:ee(o);if(a>0){const d=setInterval(()=>{(e.refetchIntervalInBackground||typeof document>"u"||document.visibilityState==="visible")&&N(e,t,r,{force:!0})},a);s.__fetchCleanups.push(()=>clearInterval(d))}}const n=ve(e),u=e.refetchOnWindowFocus===void 0?!n:e.refetchOnWindowFocus!==!1,c=e.refetchOnReconnect===void 0?!n:e.refetchOnReconnect!==!1;if(u){const a=()=>{const d=Ie(e,t,r),_=re(d),h=ke(e.cache);(!_||_.stale||Date.now()-_.time>(h?.staleTime||0))&&N(e,t,r,{force:!0})};Z.focus.add(a),s.__fetchCleanups.push(()=>Z.focus.delete(a))}if(c){const a=()=>N(e,t,r,{force:!0});Z.online.add(a),s.__fetchCleanups.push(()=>Z.online.delete(a))}},Mt=(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&&Q(e,u,o),n},Ue=(e,t)=>{const r=e.__ref;if(!r||!t.optimistic)return;const s=r.__optimisticSnapshot;s!==void 0&&(Q(e,s,t.as),delete r.__optimisticSnapshot)},Qe=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},Lt=e=>{const t=[];for(const r of x){if(!xe(r)){x.delete(r);continue}const s=vt(r);s&&e(s)&&t.push(N(r.config,r.element,r.context,{refresh:!0}))}return Promise.allSettled(t).then(()=>{})},et=e=>{(0,nt.dropEarly)();for(const[t,r]of v)e(t)&&(r.stale=!0,q.set(t,++I));for(const[t]of R)!v.has(t)&&e(t)&&q.set(t,++I);return Lt(e)},tt=(e,t)=>{const r=((0,i.isArray)(e)?e:[e]).map(s=>s===!0||s==="*"?o=>o.startsWith(t+":"):s?Qe(s):()=>!1);return et(s=>r.some(o=>o(s)))},kt=e=>{for(const[t]of v)e(t)&&be(t);for(const[t]of R)e(t)&&q.set(t,++I)},Ot=async(e,t,r)=>{const s=r?.fetch;if(!s)return;const o=await qe(s,r);if(!o)return;const n=t.__ref,{method:u,from:c,fields:a,transform:d,as:_,on:h,auth:D,headers:Ee,baseUrl:De,responseType:P,invalidates:ue,optimistic:ce,onMutate:V,onSuccess:L,onError:$,onSettled:U}=e;let b;if(a===!0||h==="submit")b=ae(t);else if((0,i.isArray)(a)){const T=ae(t);b={};for(const M of a)b[M]=T[M]}else t.state?.parse?b=t.state.parse():(0,i.isObject)(t.state)&&(b={...t.state});d&&(b=d(b,t,t.state)),(0,i.isFunction)(V)&&V(b,t,t.state);const te=ce?Mt(t,e,b):null;n.__fetching=!0,C(t,{isFetching:!0,isLoading:!1,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),F(t,"onFetchStart"),E(e,t,"onFetchStart");const m=r?.analyze?.emitNetwork,W=m?typeof performance<"u"?performance.now():Date.now():0;m&&m({phase:"start",mode:"mutation",from:c,method:u});try{if(D!==!1&&o.auth!==!1&&o.getSession){const j=await o.getSession();if(D===!0&&!j){te!==void 0&&Ue(t,e);const B={message:"Not authenticated"};F(t,"onFetchError",B),E(e,t,"onFetchError",B);return}}const T=o[u];if(!(0,i.isFunction)(T))return;const M={from:c,data:b,headers:Ee,baseUrl:De};P!==void 0&&(M.responseType=P),e.params&&(M.params=Te(e.params,t,r));const z=ne(t,r);z&&(M.headers={...M.headers,"Accept-Language":z});const Y=We(e,!0),J=await Ye(()=>T(M),Y),{data:g,error:k}=J||{};if(k){te!==void 0&&Ue(t,e),C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:k,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",k),(0,i.isFunction)($)&&$(k,b,t),(0,i.isFunction)(U)&&U(null,k,b,t),m&&m({phase:"error",mode:"mutation",from:c,method:u,error:k.message||String(k),durationMs:(typeof performance<"u"?performance.now():Date.now())-W});return}if(delete n.__optimisticSnapshot,C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),g!==void 0&&(_||!Ne(g))){const j=_?{[_]:g}:g;t.state?.update&&t.state.update(j,{preventFetch:!0})}F(t,"onFetchComplete",g),E(e,t,"onFetchComplete",g),(0,i.isFunction)(L)&&L(g,b,t),(0,i.isFunction)(U)&&U(g,null,b,t),m&&m({phase:"success",mode:"mutation",ok:!0,from:c,method:u,durationMs:(typeof performance<"u"?performance.now():Date.now())-W}),ue&&tt(ue,c)}catch(T){te!==void 0&&Ue(t,e),C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:T,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",T),E(e,t,"onFetchError",T),(0,i.isFunction)($)&&$(T,b,t),(0,i.isFunction)(U)&&U(null,T,b,t),m&&m({phase:"error",mode:"mutation",from:c,method:u,error:T.message||String(T),durationMs:(typeof performance<"u"?performance.now():Date.now())-W})}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);(0,i.isFunction)(e.__unsubscribe)&&t(e.__unsubscribe);for(const r of e.__fetchMounted||[])x.delete(r);e.__fetchCleanups=[],e.__fetchListeners=[],e.__unsubscribe=null,e.__fetchMounted=[]},$e=(e,t,r,s)=>{if(!e||!s?.fetch)return;const n=(0,i.exec)(e,t);if(!n)return;const u=(0,i.isArray)(n)?n.map(a=>He((0,i.exec)(a,t),t)).filter(Boolean):[He(n,t)].filter(Boolean),c=t.__ref;if(c.__fetchMounted)for(const a of c.__fetchMounted)x.delete(a);c.__fetchMounted=[],!c.__fetchDisposer&&(0,i.isArray)(c.__effects)&&(c.__fetchDisposer={dispose:()=>Rt(c)},c.__effects.push(c.__fetchDisposer));for(const a of u){const d=Xe(a.method),_=d?Ot:N,h=!d&&!Re(a)&&a.method!=="subscribe";if(a.on==="create"?_(a,t,s):Promise.resolve().then(()=>{mt({...a,__runner:_},t,s)}),h&&a.on==="create"&&((a.refetchInterval||a.refetchOnWindowFocus!==!1||a.refetchOnReconnect!==!1)&&Ct(a,t,s),!ve(a))){const D={element:t,ref:c,config:a,context:s};x.add(D),c.__fetchMounted.push(D)}}c.refetch=a=>{for(const d of u)N(d,t,s,{force:!0,...a})},c.fetchNextPage=()=>{const a=u[0];if(!a||!a.infinite)return;const d=c.__nextPageParam;if(d==null)return;const _={...a,cursor:d};N(_,t,s,{direction:"next",force:!0})},c.fetchPreviousPage=()=>{const a=u[0];if(!a||!a.infinite)return;const d=c.__prevPageParam;if(d==null)return;const _={...a,cursor:d};N(_,t,s,{direction:"previous",force:!0})}},ie={invalidateQueries:e=>et(Qe(e)),removeQueries:e=>{if(!e){be();return}kt(Qe(e))},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;const s=await qe(r,t);if(!s)return;const o=e.method||"select",n=we(null,t),u=ne(null,t),c=Me({...e,method:o},e.params,n,u),a=s[o];if(!(0,i.isFunction)(a))return;const d={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&&(d.headers={...d.headers,"Accept-Language":u}),e.responseType!==void 0&&(d.responseType=e.responseType),o==="rpc"&&(d.read=!Re(e)&&e.read!==!1);const _=++I,h=await a(d);if(h?.data!==void 0&&!h?.error&&!ve(e)&&!Se(c,_)){const D=se(c,h.data,null,_,Le(c,_));D.gcTime=ke(e.cache)?.gcTime||3e5}return h},getCache:()=>v,clear:()=>be(),dropNonLang:e=>{if(!e)return;const t=`:${e}`;for(const[r]of v)r.match(/:([a-z]{2,3})$/i)&&(r.endsWith(t)||be(r))}},rt=(e,t)=>(0,i.isObject)(e)?Ie({method:"select",...e},t,t?.context):e,It={invalidateQueries(e){return ie.invalidateQueries(e)},removeQueries(e){return ie.removeQueries(e)},getQueryData(e){return ie.getQueryData(rt(e,this))},setQueryData(e,t){return ie.setQueryData(rt(e,this),t)}},qt={name:"fetch",create(e){const t=e.fetch;t&&(e.parent||R.clear(),$e(t,e,e.state,e.context))}};var Nt=$e;
|
|
1
|
+
"use strict";var bt=Object.create;var he=Object.defineProperty;var St=Object.getOwnPropertyDescriptor;var wt=Object.getOwnPropertyNames;var gt=Object.getPrototypeOf,Tt=Object.prototype.hasOwnProperty;var mt=(e,t)=>{for(var r in t)he(e,r,{get:t[r],enumerable:!0})},Ve=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of wt(t))!Tt.call(e,o)&&o!==r&&he(e,o,{get:()=>t[o],enumerable:!(s=St(t,o))||s.enumerable});return e};var We=(e,t,r)=>(r=e!=null?bt(gt(e)):{},Ve(t||!e||!e.__esModule?he(r,"default",{value:e,enumerable:!0}):r,e)),vt=e=>Ve(he({},"__esModule",{value:!0}),e);var Bt={};mt(Bt,{EARLY_KEY:()=>Z.EARLY_KEY,createAdapter:()=>Ct,createEarlySeedScript:()=>Z.createEarlySeedScript,default:()=>Yt,earlyKey:()=>Z.earlyKey,executeFetch:()=>Be,fetchFunctions:()=>jt,fetchPlugin:()=>Kt,hasAdapter:()=>At,initAdapterAuth:()=>De,parseDuration:()=>X,queryClient:()=>ae,registerAdapter:()=>Ft,resolveDb:()=>pt});module.exports=vt(Bt);var i=require("@symbo.ls/utils"),lt=require("@symbo.ls/signal"),dt=require("./early.js"),Z=require("./early.js");const Et=["select","rpc","insert","update","upsert","delete","subscribe"],Je={rest:()=>import("./adapters/rest.js"),local:()=>import("./adapters/local.js")},_e=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),J=(()=>{if(typeof globalThis<"u"&&globalThis[_e])return globalThis[_e];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,_e,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[_e]}catch{}return e})(),ye=Symbol.for("@symbo.ls/fetch:PENDING_ADAPTERS"),ke=(()=>{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})(),Dt=5e3,Pt=e=>new Promise(t=>{if(J[e])return t(J[e]);const r=ke[e]||=[];let s=!1;const o=()=>{s||(s=!0,t(J[e]||null))};r.push(o),setTimeout(o,Dt)}),Ft=(e,t)=>{J[e]=t;const r=ke[e];if(r&&r.length){ke[e]=[];for(const s of r)s()}},At=e=>typeof e=="string"&&!!(J[e]||Je[e]),Ct=e=>{const t={};for(const r of Et)e[r]&&(t[r]=e[r]);return t.name=e.name||"custom",t},pt=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=J[s]||Je[s];if(!o&&(o=await Pt(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)},X=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,K=new Map,I=new Map;let be=0;const Se=new Map,Oe=new WeakMap,Le=(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}`},te=e=>m.get(e)||null,re=(e,t,r,s=++be,o=!1)=>{const n={data:t,error:r,time:Date.now(),stale:o,seq:s};m.set(e,n);const u=K.get(e);if(u)for(const c of u)(0,i.isFunction)(c)&&c(n);return n},we=(e,t)=>{const r=e?m.get(e):null;return r&&!r.error&&r.seq>t?r:null},Re=(e,t)=>(Se.get(e)||0)>t,ge=e=>{Se.set(e,++be)},He=e=>{m.delete(e),ge(e)},xt=(e,t)=>(K.has(e)||K.set(e,new Set),K.get(e).add(t),()=>{const r=K.get(e);r&&(r.delete(t),r.size===0&&K.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)}:(0,i.isString)(e)?{staleTime:X(e),gcTime:3e5}:{staleTime:X(e.stale||e.staleTime)||6e4,gcTime:X(e.gc||e.gcTime||e.expire)||3e5,key:e.key},Y=new Set,Xe=e=>!!e.ref&&e.element.__ref===e.ref,Mt=({config:e,element:t,context:r})=>{try{return Ue(e,t,r)}catch{return null}};let Te=null;const kt=()=>{Te||(Te=setInterval(()=>{const e=Date.now();for(const[t,r]of m){const s=K.get(t);!(s&&s.size>0)&&e-r.time>(r.gcTime||3e5)&&m.delete(t)}for(const[t]of Se)!m.has(t)&&!I.has(t)&&Se.delete(t);for(const t of Y)Xe(t)||Y.delete(t)},3e4),Te.unref&&Te.unref())};kt();const Ze=3,qe=e=>Math.min(1e3*2**e,3e4),et=(e,t)=>{const r=e.retry;return r===void 0&&t?{count:0}:r===!1?{count:0}:r===!0||r===void 0?{count:Ze,delay:qe}:typeof r=="number"?{count:r,delay:qe}:{count:r.count??Ze,delay:(0,i.isFunction)(r.delay)?r.delay:typeof r.delay=="number"?()=>r.delay:qe}},tt=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}},H={focus:new Set,online:new Set};let rt=!1;const Ot=()=>{if(rt||typeof window>"u")return;rt=!0;const e=()=>{for(const r of H.focus)r()},t=()=>{for(const r of H.online)r()};window.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&e()}),window.addEventListener("focus",e),window.addEventListener("online",t)},st=(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},Lt=["insert","update","upsert","delete"],nt=e=>Lt.includes(e),Ne=e=>e.mutation===!0?!0:e.mutation===!1||e.method!=="rpc"?!1:e.on==="submit"||e.on==="click"||e.invalidates!=null,se=(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},ve=(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},ne=(e,t)=>(0,i.isFunction)(e)?e(t,t.state):e,Ue=(e,t,r)=>Le(e,ve(e.params,t,r),me(t,r),se(t,r),ne(e.page,t),ne(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)})},Qe=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=pt(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},F=(e,t,...r)=>{const s=(0,i.isFunction)(e[t])?e[t]:null;s&&s.call(e,...r,e,e.state,e.context)},k=(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)},oe=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},Ee=e=>e.responseType==="stream"||e.responseType==="response",Rt=["Blob","File","ArrayBuffer","ReadableStream","Response"],$e=e=>e!==null&&typeof e=="object"&&(ArrayBuffer.isView(e)||Rt.includes(Object.prototype.toString.call(e).slice(8,-1))),q=(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 u=r.slice(2);t&&typeof t=="object"&&!Array.isArray(t)&&!$e(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})}},ze=Object.freeze({isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),je=e=>({isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:e,status:"error",fetchStatus:"idle"}),N=(e,t)=>{const r=e?.__ref;r&&(r.__fetchStatus={...t,isError:!!t.error},r.__fetching=t.isFetching,r.__fetchError=t.error)},ot=(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)},O=async(e,t,r,s={})=>{const o=r?.fetch;if(!o||!t||!t.__ref)return;const n=t.__ref,u=me(t,r);(!n.__fetchScopeOwner||n.__fetchScopeOwner.scope!==u)&&(n.__fetchScopeOwner={scope:u});const c=n.__fetchScopeOwner,a=()=>t.__ref===n&&n.__fetchScopeOwner===c&&me(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 Qe(o,r);if(!l||!a())return;const{from:h,method:p,query:v,params:Pe,cache:Fe,transform:U,single:ie,auth:ue,fields:B,as:A,limit:Q,offset:L,order:S,headers:ee,baseUrl:E,responseType:G,page:g,cursor:P,infinite:$,placeholderData:x,initialData:V,select:T,keepPreviousData:C}=e,z=f=>((0,i.isFunction)(T)&&(f=T(f,t,t.state)),U&&(f=U(f,t,t.state)),f),R=f=>{N(t,je(f)),F(t,"onFetchError",f),k(e,t,"onFetchError",f)};let Ae=(0,i.isString)(T)?T:void 0;if(v&&(0,i.isFunction)(t.getQuery)){const f=t.getQuery(l.name||"paths");f&&(Ae=f.select||f.length&&f.join(",")||Ae)}const ce=ve(Pe,t,r),D=ne(g,t),Ce=ne(P,t),fe=Ne(e),le=Ee(e)||fe?null:Ie(Fe),ht=et(e,fe||nt(p)),Ge=se(t,r),y=le?Le(e,ce,u,Ge,D,Ce):null;if(!n.__fetchInitialized&&y&&(n.__fetchInitialized=!0,V!==void 0)){const f=(0,i.isFunction)(V)?V():V;re(y,f,null)}if((p==="select"||p==="rpc")&&y&&le&&!s.refresh&&!s.force){const f=te(y);if(f&&!f.error){const d=Date.now()-f.time,w=f.stale||d>(le.staleTime||0);$&&(0,i.isArray)(f.data)&&!n.__pages&&(n.__pages=[f.data],ot(n,e,f.data));const _=z(f.data);if(!a())return;if(!w){N(t,ze),q(t,_,A);return}q(t,_,A)}else if(x!==void 0){const d=(0,i.isFunction)(x)?x(t,t.state):x;d!==void 0&&q(t,d,A)}}const de=y&&!s.force?I.get(y):null;if(de&&!Re(y,Oe.get(de)||0)){try{const f=await Promise.race([de,new Promise((d,w)=>setTimeout(()=>w("DEDUP_TIMEOUT"),15e3))]);if(!a())return;if(f?.error)R(f.error);else if(f?.data!==void 0){const d=!$&&we(y,Oe.get(de)||0),w=z(d?d.data:f.data);if(!a())return;q(t,w,A),F(t,"onFetchComplete",w),k(e,t,"onFetchComplete",w)}}catch(f){if(!a())return;f!=="DEDUP_TIMEOUT"&&R(f)}return}const _t=!te(y)?.data;N(t,{isFetching:!0,isLoading:_t,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),F(t,"onFetchStart"),k(e,t,"onFetchStart");const M=r?.analyze?.emitNetwork,Me=M?typeof performance<"u"?performance.now():Date.now():0;M&&M({phase:"start",mode:"query",from:h,method:p,cacheKey:y,lang:Ge});const yt=async()=>{if(!a())return;if(ue!==!1&&l.auth!==!1&&l.getSession){const _=await l.getSession();if(!a())return;if(ue===!0&&!_){const b={message:"Not authenticated"};return R(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:Ae,params:ce,single:ie,limit:Q,offset:L,order:S,headers:ee,baseUrl:E};G!==void 0&&(d.responseType=G);const w=se(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||Q||20;d.offset=(D-1)*_,d.limit=_}}if(Ce!==void 0&&(d.params={...d.params,cursor:Ce}),p==="insert"||p==="update"||p==="upsert"){let _;if(B===!0||e.on==="submit")_=oe(t);else if((0,i.isArray)(B)){const b=oe(t);_={};for(const j of B)_[j]=b[j]}else t.state?.parse?_=t.state.parse():(0,i.isObject)(t.state)&&(_={...t.state});U&&(_=U(_,t,t.state)),d.data=_}if(p==="rpc"){let _=ce;if(e.on==="submit"){const b=oe(t);_=e.transformParams?e.transformParams(b,t,t.state):b}d.params=_,d.read=!fe&&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:ce,on:e.subscribeOn},(b,j,xe)=>{a()&&(q(t,b,A),F(t,"onFetchComplete",b),k(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)},W=++be,pe=tt(yt,ht);Oe.set(pe,W),y&&I.set(y,pe);try{const f=await pe;if(fe&&e.invalidates&&f&&!f.error&&!f.subscribed&&it(e.invalidates,h),!a()||f?.subscribed)return;const{data:d,error:w}=f||{};if(w){y&&!we(y,W)&&re(y,null,w,W),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())-Me});return}if(d!==void 0){let _=d;if((p==="select"||p==="rpc")&&y){const j=!$&&we(y,W);if(j)_=j.data;else{const xe=re(y,d,null,W,Re(y,W));xe.gcTime=le?.gcTime||3e5}}let b=_;if($&&(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(),ot(n,e,d)),b=z(b),!a())return;N(t,ze),(!C||b!==void 0)&&q(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())-Me})}}catch(f){if(!a())return;R(f),M&&M({phase:"error",mode:"query",from:h,method:p,cacheKey:y,error:f.message||String(f),durationMs:(typeof performance<"u"?performance.now():Date.now())-Me})}finally{y&&I.get(y)===pe&&I.delete(y)}},It=(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 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"&&qt(e,t,r,n)},qt=(e,t,r,s)=>{const o=t.__ref;let n;const u=(0,lt.createEffect)(()=>{let c;try{c=JSON.stringify([ve(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,ne(e.page,t)??null])}catch{return}if(n===void 0){n=c;return}c!==n&&(n=c,Promise.resolve().then(()=>s(e,t,r)))});Array.isArray(o.__effects)?o.__effects.push(u):o.__fetchListeners.push(()=>u.dispose())},Nt=(e,t,r)=>{const s=t.__ref;s.__fetchCleanups||(s.__fetchCleanups=[]),Ot();const o=e.refetchInterval;if(o){const a=typeof o=="number"?o:X(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=Ee(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=Ue(e,t,r),h=te(l),p=Ie(e.cache);(!h||h.stale||Date.now()-h.time>(p?.staleTime||0))&&O(e,t,r,{force:!0})};H.focus.add(a),s.__fetchCleanups.push(()=>H.focus.delete(a))}if(c){const a=()=>O(e,t,r,{force:!0});H.online.add(a),s.__fetchCleanups.push(()=>H.online.delete(a))}},Ut=(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&&q(e,u,o),n},Ke=(e,t)=>{const r=e.__ref;if(!r||!t.optimistic)return;const s=r.__optimisticSnapshot;s!==void 0&&(q(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},Qt=e=>{const t=[];for(const r of Y){if(!Xe(r)){Y.delete(r);continue}const s=Mt(r);s&&e(s)&&t.push(O(r.config,r.element,r.context,{refresh:!0}))}return Promise.allSettled(t).then(()=>{})},at=e=>{(0,dt.dropEarly)();for(const[t,r]of m)e(t)&&(r.stale=!0,ge(t));for(const[t]of I)!m.has(t)&&e(t)&&ge(t);return Qt(e)},it=(e,t)=>{const r=((0,i.isArray)(e)?e:[e]).map(s=>s===!0||s==="*"?o=>o.startsWith(t+":"):s?Ye(s):()=>!1);return at(s=>r.some(o=>o(s)))},ut=e=>{for(const[t]of m)e(t)&&He(t);for(const[t]of I)e(t)&&ge(t)},ct=()=>!0,$t=async(e,t,r)=>{const s=r?.fetch;if(!s)return;const o=await Qe(s,r);if(!o)return;const n=t.__ref,{method:u,from:c,fields:a,transform:l,as:h,on:p,auth:v,headers:Pe,baseUrl:Fe,responseType:U,invalidates:ie,optimistic:ue,onMutate:B,onSuccess:A,onError:Q,onSettled:L}=e;let S;if(a===!0||p==="submit")S=oe(t);else if((0,i.isArray)(a)){const g=oe(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)(B)&&B(S,t,t.state);const ee=ue?Ut(t,e,S):null;N(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:c,method:u});try{if(v!==!1&&o.auth!==!1&&o.getSession){const z=await o.getSession();if(v===!0&&!z){ee!==void 0&&Ke(t,e);const R={message:"Not authenticated"};F(t,"onFetchError",R),k(e,t,"onFetchError",R);return}}const g=o[u];if(!(0,i.isFunction)(g))return;const P={from:c,data:S,headers:Pe,baseUrl:Fe};U!==void 0&&(P.responseType=U),e.params&&(P.params=ve(e.params,t,r));const $=se(t,r);$&&(P.headers={...P.headers,"Accept-Language":$});const x=et(e,!0),V=await tt(()=>g(P),x),{data:T,error:C}=V||{};if(C){ee!==void 0&&Ke(t,e),N(t,je(C)),F(t,"onFetchError",C),(0,i.isFunction)(Q)&&Q(C,S,t),(0,i.isFunction)(L)&&L(null,C,S,t),E&&E({phase:"error",mode:"mutation",from:c,method:u,error:C.message||String(C),durationMs:(typeof performance<"u"?performance.now():Date.now())-G});return}if(delete n.__optimisticSnapshot,N(t,ze),T!==void 0&&(h||!$e(T))){const z=h?{[h]:T}:T;t.state?.update&&t.state.update(z,{preventFetch:!0})}F(t,"onFetchComplete",T),k(e,t,"onFetchComplete",T),(0,i.isFunction)(A)&&A(T,S,t),(0,i.isFunction)(L)&&L(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}),ie&&it(ie,c)}catch(g){ee!==void 0&&Ke(t,e),N(t,je(g)),F(t,"onFetchError",g),k(e,t,"onFetchError",g),(0,i.isFunction)(Q)&&Q(g,S,t),(0,i.isFunction)(L)&&L(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}},zt=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||[])Y.delete(r);e.__fetchCleanups=[],e.__fetchListeners=[],e.__unsubscribe=null,e.__fetchMounted=[]},Be=(e,t,r,s)=>{if(!e||!s?.fetch)return;const n=(0,i.exec)(e,t);if(!n)return;const u=(0,i.isArray)(n)?n.map(a=>st((0,i.exec)(a,t),t)).filter(Boolean):[st(n,t)].filter(Boolean),c=t.__ref;if(c.__fetchMounted)for(const a of c.__fetchMounted)Y.delete(a);c.__fetchMounted=[],!c.__fetchDisposer&&(0,i.isArray)(c.__effects)&&(c.__fetchDisposer={dispose:()=>zt(c)},c.__effects.push(c.__fetchDisposer));for(const a of u){const l=nt(a.method),h=l?$t:O,p=!l&&!Ne(a)&&a.method!=="subscribe";if(a.on==="create"?h(a,t,s):Promise.resolve().then(()=>{It({...a,__runner:h},t,s)}),p&&a.on==="create"&&((a.refetchInterval||a.refetchOnWindowFocus!==!1||a.refetchOnReconnect!==!1)&&Nt(a,t,s),!Ee(a))){const v={element:t,ref:c,config:a,context:s};Y.add(v),c.__fetchMounted.push(v)}}c.refetch=a=>{for(const l of u)O(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};O(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};O(h,t,s,{direction:"previous",force:!0})}},ae={invalidateQueries:e=>at(Ye(e)),removeQueries:e=>{ut(e?Ye(e):ct)},getQueryData:e=>te(e)?.data??void 0,setQueryData:(e,t)=>{const r=te(e),s=(0,i.isFunction)(t)?t(r?.data):t;re(e,s,null)},prefetchQuery:async(e,t)=>{const r=t?.fetch;if(!r)return;const s=await Qe(r,t);if(!s)return;const o=e.method||"select",n=me(null,t),u=se(null,t),c=Le({...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=!Ne(e)&&e.read!==!1);const h=++be,p=await a(l);if(p?.data!==void 0&&!p?.error&&!Ee(e)&&!we(c,h)){const v=re(c,p.data,null,h,Re(c,h));v.gcTime=Ie(e.cache)?.gcTime||3e5}return p},getCache:()=>m,clear:()=>ut(ct),dropNonLang:e=>{if(!e)return;const t=`:${e}`;for(const[r]of m)r.match(/:([a-z]{2,3})$/i)&&(r.endsWith(t)||He(r))}},ft=(e,t)=>(0,i.isObject)(e)?Ue({method:"select",...e},t,t?.context):e,jt={invalidateQueries(e){return ae.invalidateQueries(e)},removeQueries(e){return ae.removeQueries(e)},getQueryData(e){return ae.getQueryData(ft(e,this))},setQueryData(e,t){return ae.setQueryData(ft(e,this),t)}},Kt={name:"fetch",create(e){const t=e.fetch;t&&(e.parent||I.clear(),Be(t,e,e.state,e.context))}};var Yt=Be;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{openEarly as J,takeEarly as I,earlyKey as W,isScalarParams as Y,withReads as D}from"../early.js";const N=(t,n,
|
|
1
|
+
import{openEarly as J,takeEarly as I,earlyKey as W,isScalarParams as Y,withReads as D,queryHeaderEntries as F}from"../early.js";const N=(t,n,r)=>{const d=n&&!n.startsWith("/")?"/":"",a=new URL(`${t}${d}${n}`);if(r)for(const c in r){const s=r[c];s!=null&&a.searchParams.set(c,typeof s=="object"?JSON.stringify(s):s)}return a.toString()},G=({params:t,select:n,limit:r,offset:d,order:a,single:c})=>{const s={...t};return n&&(s.select=n),r&&(s.limit=r),d&&(s.offset=d),c&&(s.single=!0),a&&(typeof a=="string"?s.order=a:Array.isArray(a)?s.order=a.map(b=>`${b.by}:${b.asc===!1?"desc":"asc"}`).join(","):a.by&&(s.order=`${a.by}:${a.asc===!1?"desc":"asc"}`)),s},H=t=>Object.prototype.toString.call(t).slice(8,-1),L=["auto","json","text","blob","arrayBuffer","stream","response"],z={json:async t=>{const n=await t.text();return n?JSON.parse(n):null},text:t=>t.text(),blob:t=>t.blob(),arrayBuffer:t=>t.arrayBuffer(),stream:t=>t.body,response:t=>t},M=t=>{const n=t.headers.get("content-type");return n&&n.includes("json")?t.json():t.text()},Q=async t=>{const n=await t.text(),r=t.headers.get("content-type");if(n&&r&&r.includes("json"))try{return JSON.parse(n)}catch{}return n},_=(t,n)=>t?.message||t?.error||n.statusText||`HTTP ${n.status}`,f=async(t,n,r,d)=>{const a=r??"auto";if(!L.includes(a))throw new TypeError(`@symbo.ls/fetch rest: unknown responseType "${a}" \u2014 use one of: ${L.join(", ")}`);const c=d&&await d||await globalThis.fetch(t,n);if(a==="auto"){const s=await M(c);return{data:s,error:c.ok?null:_(s,c),status:c.status}}if(!c.ok){const s=await Q(a==="response"?c.clone():c);return{data:a==="response"?c:s,error:_(s,c),status:c.status}}return{data:await z[a](c),error:null,status:c.status}},K=["FormData","Blob","File","URLSearchParams","ReadableStream","ArrayBuffer"],V=t=>t!==null&&typeof t=="object"&&(ArrayBuffer.isView(t)||K.includes(H(t))),v=t=>Array.isArray(t)?t:typeof t.entries=="function"?t.entries():Object.entries(t),R=(...t)=>{const n={},r=new Map;for(const d of t)if(d)for(const[a,c]of v(d)){const s=a.toLowerCase();if(r.has(s)&&delete n[r.get(s)],c==null){r.delete(s);continue}r.set(s,a),n[a]=c}return n},X={"Content-Type":"application/json"},Z={"Content-Type":void 0},C=t=>{if(!t||typeof t!="object")return null;const n={};for(const{header:r,param:d}of F(t.query))n[r]=d;return{params:n,rpc:t.rpc==="get"}},tt="content-type",q=(t,n)=>{const r=Object.keys(n);if(!r.length)return t;const d=new URL(t);for(const a of r)d.searchParams.set(a,n[a]);return d.toString()},st=async({url:t,headers:n,auth:r,fetchOptions:d,early:a,reads:c})=>{if(!t)throw new Error("@symbo.ls/fetch rest: url is required");return et(t,n,r,d,a,c)},et=(t,n={},r,d={},a,c)=>{let s=r?.token||null;const b=J(D(a,c),n),x=C(c),B=e=>{if(!x)return null;const o={},l={},i={};for(const u in e){const p=u.toLowerCase();if(p==="authorization")return null;if(p===tt)continue;l[u]=e[u];const y=x.params[p];y?i[y]=e[u]:o[u]=e[u]}return{headers:o,adoptHeaders:l,query:i}},j=(e,o)=>{if(!b)return null;let l="";for(const i in o){const u=i.toLowerCase();if(u==="accept-language")l=String(o[i]);else if(b.carried[u]!==o[i])return null}try{return I(W(e(),l),b.maxAge)}catch{return null}},k=()=>s?{Authorization:`Bearer ${s}`}:null,O=e=>R(n,k(),e),T=e=>({...d,...e}),U=(e,o,l)=>{if(!V(o))return T({method:e,headers:R(n,k(),X,l),body:JSON.stringify(o)});const i={method:e,headers:R(n,k(),Z,l),body:o};return H(o)==="ReadableStream"&&(i.duplex="half"),T(i)},S=(e,o)=>{const l=o||t;if(e&&(e.startsWith("http://")||e.startsWith("https://")))return e;const i=e&&!e.startsWith("/")?"/":"";return`${l}${i}${e||""}`};return{name:"rest",setToken:e=>{s=e},getSession:async()=>{if(!r?.sessionUrl)return s?{token:s}:null;const e=await f(S(r.sessionUrl,r.baseUrl),T({headers:O()}));return e.error?null:e.data},signIn:async e=>{if(!r?.signInUrl)throw new Error("rest: auth.signInUrl not configured");const o=await f(S(r.signInUrl,r.baseUrl),U("POST",e));return o.data?.token&&(s=o.data.token),o},signOut:async()=>(r?.signOutUrl&&await f(S(r.signOutUrl,r.baseUrl),T({method:"POST",headers:O()})),s=null,{error:null}),select:({from:e,params:o,select:l,limit:i,offset:u,order:p,single:y,headers:h,baseUrl:$,responseType:P})=>{const w=N($||t,e||"",G({params:o,select:l,limit:i,offset:u,order:p,single:y})),g=O(h),E=B(g);if(E){const A=T({headers:E.headers});return f(q(w,E.query),A,P,j(()=>w,E.adoptHeaders))}const m=T({headers:g});return f(w,m,P,j(()=>w,m.headers))},rpc:async({from:e,params:o,headers:l,baseUrl:i,responseType:u,read:p})=>{const y=Y(o),h=()=>N(i||t,`rpc/${e}`,o),$=A=>f(S(`rpc/${e}`,i),U("POST",o,l),u,A),P=O(l),w=p===!0&&x&&x.rpc&&y?B(P):null;let g=null;if(w)try{g=h()}catch{g=null}if(!g)return $(b&&b.rpc&&y?j(h,P):null);const E=T({method:"GET",headers:w.headers}),m=await f(q(g,w.query),E,u,j(()=>g,w.adoptHeaders));return m.status===405?$(null):m},insert:({from:e,data:o,headers:l,baseUrl:i,responseType:u})=>f(S(e,i),U("POST",o,l),u),update:({from:e,data:o,params:l,method:i,headers:u,baseUrl:p,responseType:y})=>{const h=l?.id||o?.id,$=h?`${e}/${h}`:e;return f(S($,p),U(i||"PATCH",o,u),y)},upsert:({from:e,data:o,params:l,method:i,headers:u,baseUrl:p,responseType:y})=>{const h=l?.id||o?.id,$=h?`${e}/${h}`:e;return f(S($,p),U(i||"PUT",o,u),y)},delete:({from:e,params:o,headers:l,baseUrl:i,responseType:u})=>{const p=o?.id,y=p?`${e}/${p}`:e;return f(S(y,i),T({method:"DELETE",headers:O(l)}),u)}}};export{N as buildUrl,v as headerEntries,et as restAdapter,G as selectQuery,st as setup,q as withQuery};
|
package/dist/esm/early.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{jsonForScript as g}from"@symbo.ls/utils";const b="@symbo.ls/fetch:EARLY",p=3e4,h=(e,n)=>{const r=new URL(e);return r.searchParams.sort(),r.toString()+" "+(n||"")},k=e=>{if(e==null)return!0;if(typeof e!="object"||Array.isArray(e))return!1;const n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return!1;for(const r in e){const t=e[r];if(!(t===void 0||typeof t=="string"||typeof t=="boolean")&&!(typeof t=="number"&&isFinite(t)))return!1}return!0},E=(e,n)=>{const r=s=>String(s).split("/").filter(Boolean),t=r(n);let o=null;for(let s=0;s<e.length;s++){const i=r(e[s]),c=i[i.length-1]==="*",a=c?i.length-1:i.length;if(c?t.length<a:t.length!==a)continue;const d={};let u=c?-1:0,f=!0;for(let l=0;l<a;l++)if(i[l].charAt(0)===":"){try{d[i[l].slice(1)]=decodeURIComponent(t[l])}catch{f=!1;break}u+=1}else if(i[l]===t[l])u+=3;else{f=!1;break}f&&(!o||u>o.score)&&(o={index:s,params:d,score:u})}return o&&{index:o.index,params:o.params}},y=()=>Symbol.for(b),m=(e,n)=>{const r=[];for(const t in e||{}){const o=t.toLowerCase(),s={name:t,header:o,param:e[t],found:!1,value:void 0};for(const i in n||{})i.toLowerCase()===o&&(s.found=!0,s.value=n[i]);r.push(s)}return r},w=(e,n)=>{if(!e||typeof e!="object"||!n||typeof n!="object")return e;const r={...e};return r.query===void 0&&n.query!==void 0&&(r.query=n.query),r.rpc===void 0&&n.rpc!==void 0&&(r.rpc=n.rpc),r},j=(e,n)=>{const r=y();if(!e||typeof e!="object"){const s=globalThis[r];return s&&s.seeded?{carried:{},rpc:!1,maxAge:p}:null}globalThis[r]||(globalThis[r]={entries:{}});const t={};for(const{header:s,found:i,value:c}of m(e.query,n))i&&(t[s]=c);const o=typeof e.maxAge=="number"&&e.maxAge>=0?e.maxAge:p;return{carried:t,rpc:e.rpc==="get",maxAge:o}},v=(e,n=p)=>{const r=globalThis[y()],t=r&&r.entries&&r.entries[e];return!t||(delete r.entries[e],!(Date.now()-t.time<=n))?null:Promise.resolve(t.answer).then(o=>o&&o.ok&&!o.bodyUsed?o:null,()=>null)},S=()=>{const e=globalThis[y()];e&&e.entries&&(e.entries={})},R=e=>{const n=(Array.isArray(e)?e:[]).filter(t=>t&&typeof t.url=="string"&&typeof t.body=="string");if(!n.length)return"";const r=g(n.map(t=>({k:h(t.url,t.lang||""),s:t.status||200,t:t.type||"application/json",b:t.body})));return"<script>(function(){try{var k=Symbol.for("+JSON.stringify(b)+"),r=globalThis[k]||(globalThis[k]={entries:{}}),t=Date.now(),l="+r+';r.seeded=true;r.entries=r.entries||{};for(var i=0;i<l.length;i++){var e=l[i];r.entries[e.k]={time:t,answer:Promise.resolve(new Response(e.b,{status:e.s,headers:{"content-type":e.t}}))}}}catch(e){}})()<\/script>'};export{b as EARLY_KEY,p as EARLY_MAX_AGE,R as createEarlySeedScript,S as dropEarly,h as earlyKey,k as isScalarParams,E as matchEarlyRoute,j as openEarly,m as queryHeaderEntries,v as takeEarly,w as withReads};
|
package/dist/esm/earlyScript.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`),
|
|
1
|
+
import{polyglotLangStorageKey as l,polyglotFallbackLang as f}from"@symbo.ls/utils";import{buildUrl as g,selectQuery as y,withQuery as h}from"./adapters/rest.js";import{EARLY_KEY as m,earlyKey as p,isScalarParams as d,matchEarlyRoute as v,withReads as q,queryHeaderEntries as S}from"./early.js";const b=["credentials","mode","cache","redirect","referrerPolicy","priority"],i=r=>{try{return new Function(r),!0}catch{return!1}},w=(r,t)=>{const e=typeof r=="function"?r.toString():String(r).trim();if(i("return ("+e+")"))return"("+e+")";if(i("return ({"+e+"})"))return"Object.values({"+e+"})[0]";throw new Error(`@symbo.ls/fetch early: the request function of ${t} does not compile on its own`)},u=(r,t)=>typeof r=="function"||typeof r=="string"?w(r,t):JSON.stringify(Array.isArray(r)?r:[]),O=r=>{const t=r.state&&typeof r.state.lang=="string"?r.state.lang:"",e=r.polyglot;return e&&typeof e=="object"?{storage:l(e),fallback:f(t,e)}:{storage:"",fallback:t}},$=(r,t)=>{const e={};for(const{name:a,param:o,found:n,value:s}of S(r,t)){if(!n)throw new Error(`@symbo.ls/fetch early.query: "${a}" is not one of the adapter's configured headers`);e[o]=s}return e},k=r=>{const t={};for(const e of b)r&&r[e]!==void 0&&(t[e]=r[e]);return t.cache===void 0&&(t.cache="no-store"),t},E=(r={})=>{const t=r&&r.fetch,e=t&&q(t.early,t.reads);if(!e||typeof e!="object"||t.adapter!=="rest"||!t.url)return"";const a=e.routes&&typeof e.routes=="object"?Object.keys(e.routes):[];if(!a.length&&!e.always)return"";const o={url:t.url,query:$(e.query,t.headers),rpc:e.rpc==="get",fetchOptions:k(t.fetchOptions),lang:O(r)},n=a.map(c=>`[${JSON.stringify(c)}, ${u(e.routes[c],JSON.stringify(c))}]`).join(`,
|
|
2
|
+
`),s=e.always?u(e.always,"`always`"):"[]";return`/* @symbo.ls/fetch \u2014 fetch.early: the first view's requests, sent before the app boots */
|
|
3
3
|
;(function () {
|
|
4
4
|
var g = globalThis
|
|
5
|
-
var K = Symbol.for(${JSON.stringify(
|
|
5
|
+
var K = Symbol.for(${JSON.stringify(m)})
|
|
6
6
|
if (g[K] || typeof g.fetch !== 'function' || !g.location) return
|
|
7
|
-
var registry = g[K] = {
|
|
7
|
+
var registry = g[K] = { entries: {} }
|
|
8
8
|
var config = ${JSON.stringify(o)}
|
|
9
|
-
var buildUrl = ${
|
|
10
|
-
var selectQuery = ${
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var
|
|
9
|
+
var buildUrl = ${g.toString()}
|
|
10
|
+
var selectQuery = ${y.toString()}
|
|
11
|
+
var withQuery = ${h.toString()}
|
|
12
|
+
var earlyKey = ${p.toString()}
|
|
13
|
+
var isScalarParams = ${d.toString()}
|
|
14
|
+
var matchEarlyRoute = ${v.toString()}
|
|
15
|
+
var always = ${s}
|
|
15
16
|
var routes = [
|
|
16
|
-
${
|
|
17
|
+
${n}
|
|
17
18
|
]
|
|
18
19
|
var storage = function (key) {
|
|
19
20
|
try { return key ? g.localStorage.getItem(key) : null } catch (e) { return null }
|
|
@@ -42,12 +43,10 @@ import{buildUrl as l,selectQuery as f}from"./adapters/rest.js";import{EARLY_KEY
|
|
|
42
43
|
var language = request.lang === false ? '' : lang
|
|
43
44
|
var key = earlyKey(url, language)
|
|
44
45
|
if (registry.entries[key]) continue
|
|
45
|
-
var address = new URL(url)
|
|
46
|
-
for (var name in config.query) address.searchParams.set(name, config.query[name])
|
|
47
46
|
var options = Object.assign({}, config.fetchOptions, { method: 'GET' })
|
|
48
47
|
if (language) options.headers = { 'Accept-Language': language }
|
|
49
|
-
registry.entries[key] = { time: Date.now(), answer: g.fetch(
|
|
48
|
+
registry.entries[key] = { time: Date.now(), answer: g.fetch(withQuery(url, config.query), options).catch(function () { return null }) }
|
|
50
49
|
} catch (e) {}
|
|
51
50
|
}
|
|
52
51
|
})()
|
|
53
|
-
`.replace(/<\/script/gi,"<\\/script")};var
|
|
52
|
+
`.replace(/<\/script/gi,"<\\/script")};var A=E;export{E as createEarlyScript,A as default};
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isArray as Q,isFunction as l,isObject as Z,isString as _e,exec as Ge}from"@symbo.ls/utils";import{createEffect as it}from"@symbo.ls/signal";import{dropEarly as ut}from"./early.js";const ct=["select","rpc","insert","update","upsert","delete","subscribe"],Ke={rest:()=>import("./adapters/rest.js"),local:()=>import("./adapters/local.js")},ye=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),ee=(()=>{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})(),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})(),ft=5e3,lt=e=>new Promise(t=>{if(ee[e])return t(ee[e]);const r=Ce[e]||=[];let s=!1;const o=()=>{s||(s=!0,t(ee[e]||null))};r.push(o),setTimeout(o,ft)}),Ct=(e,t)=>{ee[e]=t;const r=Ce[e];if(r&&r.length){Ce[e]=[];for(const s of r)s()}},Mt=e=>typeof e=="string"&&!!(ee[e]||Ke[e]),Lt=e=>{const t={};for(const r of ct)e[r]&&(t[r]=e[r]);return t.name=e.name||"custom",t},dt=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=ee[s]||Ke[s];if(!o&&(o=await lt(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)},se=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},v=new Map,x=new Map,R=new Map;let I=0;const q=new Map,Me=new WeakMap,Le=(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,d=r?`${r}:`:"",_=s?`:${s}`:"",h=o?":p"+JSON.stringify(o):"",D=n!=null?":c"+JSON.stringify(n):"";return`${i}:${u}:${d}${JSON.stringify(t||"")}${a?":infinite":""}${h}${D}${_}`},ne=e=>v.get(e)||null,oe=(e,t,r,s=++I,o=!1)=>{const n={data:t,error:r,time:Date.now(),stale:o,seq:s};v.set(e,n);const i=x.get(e);if(i)for(const u of i)l(u)&&u(n);return n},be=(e,t)=>{const r=e?v.get(e):null;return r&&!r.error&&r.seq>t?r:null},ke=(e,t)=>(q.get(e)||0)>t,ge=e=>{if(e){v.delete(e),q.set(e,++I);return}for(const[t]of v)q.set(t,++I);for(const[t]of R)q.set(t,++I);v.clear()},kt=(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))}),Oe=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:se(e),gcTime:3e5}:{staleTime:se(e.stale||e.staleTime)||6e4,gcTime:se(e.gc||e.gcTime||e.expire)||3e5,key:e.key},V=new Set,xe=e=>!!e.ref&&e.element.__ref===e.ref,pt=({config:e,element:t,context:r})=>{try{return qe(e,t,r)}catch{return null}};let we=null;const ht=()=>{we||(we=setInterval(()=>{const e=Date.now();for(const[t,r]of v){const s=x.get(t);!(s&&s.size>0)&&e-r.time>(r.gcTime||3e5)&&v.delete(t)}for(const[t]of q)!v.has(t)&&!R.has(t)&&q.delete(t);for(const t of V)xe(t)||V.delete(t)},3e4),we.unref&&we.unref())};ht();const Ve=3,Re=e=>Math.min(1e3*2**e,3e4),We=(e,t)=>{const r=e.retry;return r===void 0&&t?{count:0}:r===!1?{count:0}:r===!0||r===void 0?{count:Ve,delay:Re}:typeof r=="number"?{count:r,delay:Re}:{count:r.count??Ve,delay:l(r.delay)?r.delay:typeof r.delay=="number"?()=>r.delay:Re}},Ye=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=l(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=l(s)?s(n,i):s;await new Promise(a=>setTimeout(a,u));continue}throw i}return{data:null,error:o}},te={focus:new Set,online:new Set};let Je=!1;const _t=()=>{if(Je||typeof window>"u")return;Je=!0;const e=()=>{for(const r of te.focus)r()},t=()=>{for(const r of te.online)r()};window.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&e()}),window.addEventListener("focus",e),window.addEventListener("online",t)},He=(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(Z(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},yt=["insert","update","upsert","delete"],Xe=e=>yt.includes(e),Ie=e=>e.mutation===!0?!0:e.mutation===!1||e.method!=="rpc"?!1:e.on==="submit"||e.on==="click"||e.invalidates!=null,ae=(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},ve=(e,t,r)=>{let s;if(!e)s=void 0;else if(l(e))s=e(t,t.state);else{s={};for(const o in e){const n=e[o];s[o]=l(n)?n(t,t.state):n}}return s},ie=(e,t)=>l(e)?e(t,t.state):e,qe=(e,t,r)=>Le(e,ve(e.params,t,r),Te(t,r),ae(t,r),ie(e.page,t),ie(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(l(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=dt(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},F=(e,t,...r)=>{const s=l(e[t])?e[t]:null;s&&s.call(e,...r,e,e.state,e.context)},E=(e,t,r,...s)=>{const o=e&&l(e[r])?e[r]:null;o&&o.call(t,...s,t,t.state,t.context)},ue=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},Fe=e=>e.responseType==="stream"||e.responseType==="response",St=["Blob","File","ArrayBuffer","ReadableStream","Response"],Qe=e=>e!==null&&typeof e=="object"&&(ArrayBuffer.isView(e)||St.includes(Object.prototype.toString.call(e).slice(8,-1))),$=(e,t,r,s={})=>{if(!r&&Qe(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)&&!Qe(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})}},C=(e,t)=>{const r=e?.__ref;r&&(r.__fetchStatus={...t,isError:!!t.error},r.__fetching=t.isFetching,r.__fetchError=t.error)},Ze=(e,t,r)=>{const s=e.__pages&&e.__pages.length?e.__pages:[r];l(t.getNextPageParam)&&(e.__nextPageParam=t.getNextPageParam(s[s.length-1],s),e.__hasNextPage=e.__nextPageParam!=null),l(t.getPreviousPageParam)&&(e.__prevPageParam=t.getPreviousPageParam(s[0],s),e.__hasPreviousPage=e.__prevPageParam!=null)},N=async(e,t,r,s={})=>{const o=r?.fetch;if(!o||!t||!t.__ref)return;const n=t.__ref,i=Te(t,r);(!n.__fetchScopeOwner||n.__fetchScopeOwner.scope!==i)&&(n.__fetchScopeOwner={scope:i});const u=n.__fetchScopeOwner,a=()=>t.__ref===n&&n.__fetchScopeOwner===u&&Te(t,r)===i;if(e.enabled===!1||l(e.enabled)&&!e.enabled(t,t.state)||e.skip===!0||l(e.skip)&&e.skip(t,t.state))return;const d=await Ue(o,r);if(!d||!a())return;const{from:_,method:h,query:D,params:De,cache:Pe,transform:P,single:ce,auth:fe,fields:W,as:L,limit:z,offset:U,order:b,headers:re,baseUrl:m,responseType:Y,page:T,cursor:M,infinite:j,placeholderData:J,initialData:H,select:g,keepPreviousData:k}=e;let B=_e(g)?g:void 0;if(D&&l(t.getQuery)){const p=t.getQuery(d.name||"paths");p&&(B=p.select||p.length&&p.join(",")||B)}const G=ve(De,t,r),A=ie(T,t),me=ie(M,t),le=Ie(e),de=Fe(e)||le?null:Oe(Pe),nt=We(e,le||Xe(h)),je=ae(t,r),y=de?Le(e,G,i,je,A,me):null;if(!n.__fetchInitialized&&y&&(n.__fetchInitialized=!0,H!==void 0)){const p=l(H)?H():H;oe(y,p,null)}if((h==="select"||h==="rpc")&&y&&de&&!s.refresh&&!s.force){const p=ne(y);if(p&&!p.error){const c=Date.now()-p.time,w=p.stale||c>(de.staleTime||0);j&&Q(p.data)&&!n.__pages&&(n.__pages=[p.data],Ze(n,e,p.data));let f=p.data;if(l(g)&&(f=g(f,t,t.state)),P&&(f=P(f,t,t.state)),!a())return;if(!w){C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),$(t,f,L);return}$(t,f,L)}else if(J!==void 0){const c=l(J)?J(t,t.state):J;c!==void 0&&$(t,c,L)}}const pe=y&&!s.force?R.get(y):null;if(pe&&!ke(y,Me.get(pe)||0)){const p=c=>{C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:c,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",c),E(e,t,"onFetchError",c)};try{const c=await Promise.race([pe,new Promise((w,f)=>setTimeout(()=>f("DEDUP_TIMEOUT"),15e3))]);if(!a())return;if(c?.error)p(c.error);else if(c?.data!==void 0){const w=!j&&be(y,Me.get(pe)||0);let f=w?w.data:c.data;if(l(g)&&(f=g(f,t,t.state)),P&&(f=P(f,t,t.state)),!a())return;$(t,f,L),F(t,"onFetchComplete",f),E(e,t,"onFetchComplete",f)}}catch(c){if(!a())return;c!=="DEDUP_TIMEOUT"&&p(c)}return}const ot=!ne(y)?.data;C(t,{isFetching:!0,isLoading:ot,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),F(t,"onFetchStart"),E(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:_,method:h,cacheKey:y,lang:je});const at=async()=>{if(!a())return;if(fe!==!1&&d.auth!==!1&&d.getSession){const f=await d.getSession();if(!a())return;if(fe===!0&&!f){const S={message:"Not authenticated"};return C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:S,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",S),E(e,t,"onFetchError",S),{data:null,error:S}}}const p=d[h];if(!l(p))return{data:null,error:{message:`Method "${h}" not found on adapter`}};const c={from:_,select:B,params:G,single:ce,limit:z,offset:U,order:b,headers:re,baseUrl:m};Y!==void 0&&(c.responseType=Y);const w=ae(t,r);if(w&&(c.headers={...c.headers,"Accept-Language":w}),A!==void 0){if(Z(A))A.offset!==void 0&&(c.offset=A.offset),A.limit!==void 0&&(c.limit=A.limit),A.cursor!==void 0&&(c.params={...c.params,cursor:A.cursor});else if(typeof A=="number"){const f=e.pageSize||z||20;c.offset=(A-1)*f,c.limit=f}}if(me!==void 0&&(c.params={...c.params,cursor:me}),h==="insert"||h==="update"||h==="upsert"){let f;if(W===!0||e.on==="submit")f=ue(t);else if(Q(W)){const S=ue(t);f={};for(const K of W)f[K]=S[K]}else t.state?.parse?f=t.state.parse():Z(t.state)&&(f={...t.state});P&&(f=P(f,t,t.state)),c.data=f}if(h==="rpc"){let f=G;if(e.on==="submit"){const S=ue(t);f=e.transformParams?e.transformParams(S,t,t.state):S}c.params=f,c.read=!le&&e.read!==!1}if(h==="subscribe"){if(l(n.__unsubscribe)){const S=n.__unsubscribe;n.__unsubscribe=null;try{S()}catch{}}const f=d.subscribe({from:_,params:G,on:e.subscribeOn},(S,K,Be)=>{a()&&($(t,S,L),F(t,"onFetchComplete",S),E(e,t,"onFetchComplete",S))});return a()?(n.__unsubscribe=f,{data:null,error:null,subscribed:!0}):(l(f)&&f(),{data:null,error:null,subscribed:!0})}return p(c)},X=++I,he=Ye(at,nt);Me.set(he,X),y&&R.set(y,he);try{const p=await he;if(le&&e.invalidates&&p&&!p.error&&!p.subscribed&&tt(e.invalidates,_),!a()||p?.subscribed)return;const{data:c,error:w}=p||{};if(w){y&&!be(y,X)&&oe(y,null,w,X),C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:w,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",w),E(e,t,"onFetchError",w),O&&O({phase:"error",mode:"query",from:_,method:h,cacheKey:y,error:w.message||w,durationMs:(typeof performance<"u"?performance.now():Date.now())-Ae});return}if(c!==void 0){let f=c;if((h==="select"||h==="rpc")&&y){const K=!j&&be(y,X);if(K)f=K.data;else{const Be=oe(y,c,null,X,ke(y,X));Be.gcTime=de?.gcTime||3e5}}let S=f;if(j&&Q(c)&&((!n.__pages||!s.direction)&&(n.__pages=[]),s.direction==="previous"?n.__pages.unshift(c):n.__pages.push(c),S=n.__pages.flat(),Ze(n,e,c)),l(g)&&(S=g(S,t,t.state)),P&&(S=P(S,t,t.state)),!a())return;C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),(!k||S!==void 0)&&$(t,S,L),F(t,"onFetchComplete",S),E(e,t,"onFetchComplete",S),O&&O({phase:"success",mode:"query",ok:!0,from:_,method:h,cacheKey:y,durationMs:(typeof performance<"u"?performance.now():Date.now())-Ae})}}catch(p){if(!a())return;C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:p,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",p),E(e,t,"onFetchError",p),O&&O({phase:"error",mode:"query",from:_,method:h,cacheKey:y,error:p.message||String(p),durationMs:(typeof performance<"u"?performance.now():Date.now())-Ae})}finally{y&&R.get(y)===he&&R.delete(y)}},bt=(e,t,r)=>{const s=e.on,o=t.__ref;if(!o)return;o.__fetchListeners||(o.__fetchListeners=[]);const n=e.__runner||N;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"&>(e,t,r,n)},gt=(e,t,r,s)=>{const o=t.__ref;let n;const i=it(()=>{let u;try{u=JSON.stringify([ve(e.params,t,r)??null,l(e.enabled)?!!e.enabled(t,t.state):e.enabled!==!1,l(e.skip)?!!e.skip(t,t.state):e.skip===!0,ie(e.page,t)??null])}catch{return}if(n===void 0){n=u;return}u!==n&&(n=u,Promise.resolve().then(()=>s(e,t,r)))});Array.isArray(o.__effects)?o.__effects.push(i):o.__fetchListeners.push(()=>i.dispose())},wt=(e,t,r)=>{const s=t.__ref;s.__fetchCleanups||(s.__fetchCleanups=[]),_t();const o=e.refetchInterval;if(o){const a=typeof o=="number"?o:se(o);if(a>0){const d=setInterval(()=>{(e.refetchIntervalInBackground||typeof document>"u"||document.visibilityState==="visible")&&N(e,t,r,{force:!0})},a);s.__fetchCleanups.push(()=>clearInterval(d))}}const n=Fe(e),i=e.refetchOnWindowFocus===void 0?!n:e.refetchOnWindowFocus!==!1,u=e.refetchOnReconnect===void 0?!n:e.refetchOnReconnect!==!1;if(i){const a=()=>{const d=qe(e,t,r),_=ne(d),h=Oe(e.cache);(!_||_.stale||Date.now()-_.time>(h?.staleTime||0))&&N(e,t,r,{force:!0})};te.focus.add(a),s.__fetchCleanups.push(()=>te.focus.delete(a))}if(u){const a=()=>N(e,t,r,{force:!0});te.online.add(a),s.__fetchCleanups.push(()=>te.online.delete(a))}},Tt=(e,t,r)=>{if(!t.optimistic)return null;const s=e.__ref,o=t.as,n=e.state?.parse?e.state.parse():Z(e.state)?{...e.state}:e.state;s.__optimisticSnapshot=n;const i=l(t.optimistic)?t.optimistic(r,n,e):t.optimistic;return i!==void 0&&$(e,i,o),n},$e=(e,t)=>{const r=e.__ref;if(!r||!t.optimistic)return;const s=r.__optimisticSnapshot;s!==void 0&&($(e,s,t.as),delete r.__optimisticSnapshot)},ze=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)):l(e)?t=>{try{return!!e(t)}catch{return!1}}:()=>!1},vt=e=>{const t=[];for(const r of V){if(!xe(r)){V.delete(r);continue}const s=pt(r);s&&e(s)&&t.push(N(r.config,r.element,r.context,{refresh:!0}))}return Promise.allSettled(t).then(()=>{})},et=e=>{ut();for(const[t,r]of v)e(t)&&(r.stale=!0,q.set(t,++I));for(const[t]of R)!v.has(t)&&e(t)&&q.set(t,++I);return vt(e)},tt=(e,t)=>{const r=(Q(e)?e:[e]).map(s=>s===!0||s==="*"?o=>o.startsWith(t+":"):s?ze(s):()=>!1);return et(s=>r.some(o=>o(s)))},Ft=e=>{for(const[t]of v)e(t)&&ge(t);for(const[t]of R)e(t)&&q.set(t,++I)},Et=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:i,from:u,fields:a,transform:d,as:_,on:h,auth:D,headers:De,baseUrl:Pe,responseType:P,invalidates:ce,optimistic:fe,onMutate:W,onSuccess:L,onError:z,onSettled:U}=e;let b;if(a===!0||h==="submit")b=ue(t);else if(Q(a)){const T=ue(t);b={};for(const M of a)b[M]=T[M]}else t.state?.parse?b=t.state.parse():Z(t.state)&&(b={...t.state});d&&(b=d(b,t,t.state)),l(W)&&W(b,t,t.state);const re=fe?Tt(t,e,b):null;n.__fetching=!0,C(t,{isFetching:!0,isLoading:!1,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),F(t,"onFetchStart"),E(e,t,"onFetchStart");const m=r?.analyze?.emitNetwork,Y=m?typeof performance<"u"?performance.now():Date.now():0;m&&m({phase:"start",mode:"mutation",from:u,method:i});try{if(D!==!1&&o.auth!==!1&&o.getSession){const B=await o.getSession();if(D===!0&&!B){re!==void 0&&$e(t,e);const G={message:"Not authenticated"};F(t,"onFetchError",G),E(e,t,"onFetchError",G);return}}const T=o[i];if(!l(T))return;const M={from:u,data:b,headers:De,baseUrl:Pe};P!==void 0&&(M.responseType=P),e.params&&(M.params=ve(e.params,t,r));const j=ae(t,r);j&&(M.headers={...M.headers,"Accept-Language":j});const J=We(e,!0),H=await Ye(()=>T(M),J),{data:g,error:k}=H||{};if(k){re!==void 0&&$e(t,e),C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:k,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",k),l(z)&&z(k,b,t),l(U)&&U(null,k,b,t),m&&m({phase:"error",mode:"mutation",from:u,method:i,error:k.message||String(k),durationMs:(typeof performance<"u"?performance.now():Date.now())-Y});return}if(delete n.__optimisticSnapshot,C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),g!==void 0&&(_||!Qe(g))){const B=_?{[_]:g}:g;t.state?.update&&t.state.update(B,{preventFetch:!0})}F(t,"onFetchComplete",g),E(e,t,"onFetchComplete",g),l(L)&&L(g,b,t),l(U)&&U(g,null,b,t),m&&m({phase:"success",mode:"mutation",ok:!0,from:u,method:i,durationMs:(typeof performance<"u"?performance.now():Date.now())-Y}),ce&&tt(ce,u)}catch(T){re!==void 0&&$e(t,e),C(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:T,status:"error",fetchStatus:"idle"}),F(t,"onFetchError",T),E(e,t,"onFetchError",T),l(z)&&z(T,b,t),l(U)&&U(null,T,b,t),m&&m({phase:"error",mode:"mutation",from:u,method:i,error:T.message||String(T),durationMs:(typeof performance<"u"?performance.now():Date.now())-Y})}finally{n.__fetching=!1}},Dt=e=>{const t=r=>{try{r()}catch{}};for(const r of e.__fetchCleanups||[])t(r);for(const r of e.__fetchListeners||[])t(r);l(e.__unsubscribe)&&t(e.__unsubscribe);for(const r of e.__fetchMounted||[])V.delete(r);e.__fetchCleanups=[],e.__fetchListeners=[],e.__unsubscribe=null,e.__fetchMounted=[]},rt=(e,t,r,s)=>{if(!e||!s?.fetch)return;const n=Ge(e,t);if(!n)return;const i=Q(n)?n.map(a=>He(Ge(a,t),t)).filter(Boolean):[He(n,t)].filter(Boolean),u=t.__ref;if(u.__fetchMounted)for(const a of u.__fetchMounted)V.delete(a);u.__fetchMounted=[],!u.__fetchDisposer&&Q(u.__effects)&&(u.__fetchDisposer={dispose:()=>Dt(u)},u.__effects.push(u.__fetchDisposer));for(const a of i){const d=Xe(a.method),_=d?Et:N,h=!d&&!Ie(a)&&a.method!=="subscribe";if(a.on==="create"?_(a,t,s):Promise.resolve().then(()=>{bt({...a,__runner:_},t,s)}),h&&a.on==="create"&&((a.refetchInterval||a.refetchOnWindowFocus!==!1||a.refetchOnReconnect!==!1)&&wt(a,t,s),!Fe(a))){const D={element:t,ref:u,config:a,context:s};V.add(D),u.__fetchMounted.push(D)}}u.refetch=a=>{for(const d of i)N(d,t,s,{force:!0,...a})},u.fetchNextPage=()=>{const a=i[0];if(!a||!a.infinite)return;const d=u.__nextPageParam;if(d==null)return;const _={...a,cursor:d};N(_,t,s,{direction:"next",force:!0})},u.fetchPreviousPage=()=>{const a=i[0];if(!a||!a.infinite)return;const d=u.__prevPageParam;if(d==null)return;const _={...a,cursor:d};N(_,t,s,{direction:"previous",force:!0})}},Ee={invalidateQueries:e=>et(ze(e)),removeQueries:e=>{if(!e){ge();return}Ft(ze(e))},getQueryData:e=>ne(e)?.data??void 0,setQueryData:(e,t)=>{const r=ne(e),s=l(t)?t(r?.data):t;oe(e,s,null)},prefetchQuery:async(e,t)=>{const r=t?.fetch;if(!r)return;const s=await Ue(r,t);if(!s)return;const o=e.method||"select",n=Te(null,t),i=ae(null,t),u=Le({...e,method:o},e.params,n,i),a=s[o];if(!l(a))return;const d={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&&(d.headers={...d.headers,"Accept-Language":i}),e.responseType!==void 0&&(d.responseType=e.responseType),o==="rpc"&&(d.read=!Ie(e)&&e.read!==!1);const _=++I,h=await a(d);if(h?.data!==void 0&&!h?.error&&!Fe(e)&&!be(u,_)){const D=oe(u,h.data,null,_,ke(u,_));D.gcTime=Oe(e.cache)?.gcTime||3e5}return h},getCache:()=>v,clear:()=>ge(),dropNonLang:e=>{if(!e)return;const t=`:${e}`;for(const[r]of v)r.match(/:([a-z]{2,3})$/i)&&(r.endsWith(t)||ge(r))}},st=(e,t)=>Z(e)?qe({method:"select",...e},t,t?.context):e,Ot={invalidateQueries(e){return Ee.invalidateQueries(e)},removeQueries(e){return Ee.removeQueries(e)},getQueryData(e){return Ee.getQueryData(st(e,this))},setQueryData(e,t){return Ee.setQueryData(st(e,this),t)}},Rt={name:"fetch",create(e){const t=e.fetch;t&&(e.parent||R.clear(),rt(t,e,e.state,e.context))}};var It=rt;export{Lt as createAdapter,It as default,rt as executeFetch,Ot as fetchFunctions,Rt as fetchPlugin,Mt as hasAdapter,Ne as initAdapterAuth,se as parseDuration,Ee as queryClient,Ct as registerAdapter,dt as resolveDb};
|
|
1
|
+
import{isArray as I,isFunction as f,isObject as H,isString as he,exec as Ve}from"@symbo.ls/utils";import{createEffect as ht}from"@symbo.ls/signal";import{dropEarly as _t}from"./early.js";const yt=["select","rpc","insert","update","upsert","delete","subscribe"],We={rest:()=>import("./adapters/rest.js"),local:()=>import("./adapters/local.js")},_e=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),X=(()=>{if(typeof globalThis<"u"&&globalThis[_e])return globalThis[_e];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,_e,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[_e]}catch{}return e})(),ye=Symbol.for("@symbo.ls/fetch:PENDING_ADAPTERS"),ke=(()=>{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})(),bt=5e3,St=e=>new Promise(t=>{if(X[e])return t(X[e]);const r=ke[e]||=[];let s=!1;const o=()=>{s||(s=!0,t(X[e]||null))};r.push(o),setTimeout(o,bt)}),It=(e,t)=>{X[e]=t;const r=ke[e];if(r&&r.length){ke[e]=[];for(const s of r)s()}},qt=e=>typeof e=="string"&&!!(X[e]||We[e]),Nt=e=>{const t={};for(const r of yt)e[r]&&(t[r]=e[r]);return t.name=e.name||"custom",t},wt=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]||We[s];if(!o&&(o=await St(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)},te=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,Y=new Map,q=new Map;let be=0;const Se=new Map,Oe=new WeakMap,Le=(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}`},re=e=>m.get(e)||null,se=(e,t,r,s=++be,o=!1)=>{const n={data:t,error:r,time:Date.now(),stale:o,seq:s};m.set(e,n);const i=Y.get(e);if(i)for(const u of i)f(u)&&u(n);return n},we=(e,t)=>{const r=e?m.get(e):null;return r&&!r.error&&r.seq>t?r:null},Re=(e,t)=>(Se.get(e)||0)>t,ge=e=>{Se.set(e,++be)},Je=e=>{m.delete(e),ge(e)},Ut=(e,t)=>(Y.has(e)||Y.set(e,new Set),Y.get(e).add(t),()=>{const r=Y.get(e);r&&(r.delete(t),r.size===0&&Y.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)}:he(e)?{staleTime:te(e),gcTime:3e5}:{staleTime:te(e.stale||e.staleTime)||6e4,gcTime:te(e.gc||e.gcTime||e.expire)||3e5,key:e.key},B=new Set,He=e=>!!e.ref&&e.element.__ref===e.ref,gt=({config:e,element:t,context:r})=>{try{return Ue(e,t,r)}catch{return null}};let Te=null;const Tt=()=>{Te||(Te=setInterval(()=>{const e=Date.now();for(const[t,r]of m){const s=Y.get(t);!(s&&s.size>0)&&e-r.time>(r.gcTime||3e5)&&m.delete(t)}for(const[t]of Se)!m.has(t)&&!q.has(t)&&Se.delete(t);for(const t of B)He(t)||B.delete(t)},3e4),Te.unref&&Te.unref())};Tt();const Xe=3,qe=e=>Math.min(1e3*2**e,3e4),Ze=(e,t)=>{const r=e.retry;return r===void 0&&t?{count:0}:r===!1?{count:0}:r===!0||r===void 0?{count:Xe,delay:qe}:typeof r=="number"?{count:r,delay:qe}:{count:r.count??Xe,delay:f(r.delay)?r.delay:typeof r.delay=="number"?()=>r.delay:qe}},et=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 tt=!1;const mt=()=>{if(tt||typeof window>"u")return;tt=!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)},rt=(e,t)=>{const r=t.__ref;if(e===!0)return{from:r.__state||t.key,method:"select",query:!0,on:"create"};if(he(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},vt=["insert","update","upsert","delete"],st=e=>vt.includes(e),Ne=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},ve=(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},oe=(e,t)=>f(e)?e(t,t.state):e,Ue=(e,t,r)=>Le(e,ve(e.params,t,r),me(t,r),ne(t,r),oe(e.page,t),oe(e.cursor,t)),Qe=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)})},$e=async(e,t)=>{if(f(e.select))return e.auth!==!1&&await Qe(e,t),e;if(e.__resolved)return e.auth!==!1&&await Qe(e.__resolved,t),e.__resolved;if(e.__resolving)return e.__resolving;e.__resolving=wt(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 Qe(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)},ae=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},Ee=e=>e.responseType==="stream"||e.responseType==="response",Et=["Blob","File","ArrayBuffer","ReadableStream","Response"],ze=e=>e!==null&&typeof e=="object"&&(ArrayBuffer.isView(e)||Et.includes(Object.prototype.toString.call(e).slice(8,-1))),N=(e,t,r,s={})=>{if(!r&&ze(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)&&!ze(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})}},je=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"}),U=(e,t)=>{const r=e?.__ref;r&&(r.__fetchStatus={...t,isError:!!t.error},r.__fetching=t.isFetching,r.__fetchError=t.error)},nt=(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=me(t,r);(!n.__fetchScopeOwner||n.__fetchScopeOwner.scope!==i)&&(n.__fetchScopeOwner={scope:i});const u=n.__fetchScopeOwner,a=()=>t.__ref===n&&n.__fetchScopeOwner===u&&me(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 $e(o,r);if(!l||!a())return;const{from:h,method:p,query:v,params:Pe,cache:Fe,transform:Q,single:ie,auth:ue,fields:G,as:A,limit:$,offset:L,order:S,headers:ee,baseUrl:E,responseType:x,page:g,cursor:P,infinite:z,placeholderData:V,initialData:W,select:T,keepPreviousData:C}=e,j=c=>(f(T)&&(c=T(c,t,t.state)),Q&&(c=Q(c,t,t.state)),c),R=c=>{U(t,Ke(c)),F(t,"onFetchError",c),k(e,t,"onFetchError",c)};let Ae=he(T)?T:void 0;if(v&&f(t.getQuery)){const c=t.getQuery(l.name||"paths");c&&(Ae=c.select||c.length&&c.join(",")||Ae)}const ce=ve(Pe,t,r),D=oe(g,t),Ce=oe(P,t),fe=Ne(e),le=Ee(e)||fe?null:Ie(Fe),lt=Ze(e,fe||st(p)),Ge=ne(t,r),y=le?Le(e,ce,i,Ge,D,Ce):null;if(!n.__fetchInitialized&&y&&(n.__fetchInitialized=!0,W!==void 0)){const c=f(W)?W():W;se(y,c,null)}if((p==="select"||p==="rpc")&&y&&le&&!s.refresh&&!s.force){const c=re(y);if(c&&!c.error){const d=Date.now()-c.time,w=c.stale||d>(le.staleTime||0);z&&I(c.data)&&!n.__pages&&(n.__pages=[c.data],nt(n,e,c.data));const _=j(c.data);if(!a())return;if(!w){U(t,je),N(t,_,A);return}N(t,_,A)}else if(V!==void 0){const d=f(V)?V(t,t.state):V;d!==void 0&&N(t,d,A)}}const de=y&&!s.force?q.get(y):null;if(de&&!Re(y,Oe.get(de)||0)){try{const c=await Promise.race([de,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=!z&&we(y,Oe.get(de)||0),w=j(d?d.data:c.data);if(!a())return;N(t,w,A),F(t,"onFetchComplete",w),k(e,t,"onFetchComplete",w)}}catch(c){if(!a())return;c!=="DEDUP_TIMEOUT"&&R(c)}return}const dt=!re(y)?.data;U(t,{isFetching:!0,isLoading:dt,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),F(t,"onFetchStart"),k(e,t,"onFetchStart");const M=r?.analyze?.emitNetwork,Me=M?typeof performance<"u"?performance.now():Date.now():0;M&&M({phase:"start",mode:"query",from:h,method:p,cacheKey:y,lang:Ge});const pt=async()=>{if(!a())return;if(ue!==!1&&l.auth!==!1&&l.getSession){const _=await l.getSession();if(!a())return;if(ue===!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:Ae,params:ce,single:ie,limit:$,offset:L,order:S,headers:ee,baseUrl:E};x!==void 0&&(d.responseType=x);const w=ne(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||$||20;d.offset=(D-1)*_,d.limit=_}}if(Ce!==void 0&&(d.params={...d.params,cursor:Ce}),p==="insert"||p==="update"||p==="upsert"){let _;if(G===!0||e.on==="submit")_=ae(t);else if(I(G)){const b=ae(t);_={};for(const K of G)_[K]=b[K]}else t.state?.parse?_=t.state.parse():H(t.state)&&(_={...t.state});Q&&(_=Q(_,t,t.state)),d.data=_}if(p==="rpc"){let _=ce;if(e.on==="submit"){const b=ae(t);_=e.transformParams?e.transformParams(b,t,t.state):b}d.params=_,d.read=!fe&&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:ce,on:e.subscribeOn},(b,K,xe)=>{a()&&(N(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=++be,pe=et(pt,lt);Oe.set(pe,J),y&&q.set(y,pe);try{const c=await pe;if(fe&&e.invalidates&&c&&!c.error&&!c.subscribed&&at(e.invalidates,h),!a()||c?.subscribed)return;const{data:d,error:w}=c||{};if(w){y&&!we(y,J)&&se(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())-Me});return}if(d!==void 0){let _=d;if((p==="select"||p==="rpc")&&y){const K=!z&&we(y,J);if(K)_=K.data;else{const xe=se(y,d,null,J,Re(y,J));xe.gcTime=le?.gcTime||3e5}}let b=_;if(z&&I(d)&&((!n.__pages||!s.direction)&&(n.__pages=[]),s.direction==="previous"?n.__pages.unshift(d):n.__pages.push(d),b=n.__pages.flat(),nt(n,e,d)),b=j(b),!a())return;U(t,je),(!C||b!==void 0)&&N(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())-Me})}}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())-Me})}finally{y&&q.get(y)===pe&&q.delete(y)}},Dt=(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"&&Pt(e,t,r,n)},Pt=(e,t,r,s)=>{const o=t.__ref;let n;const i=ht(()=>{let u;try{u=JSON.stringify([ve(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,oe(e.page,t)??null])}catch{return}if(n===void 0){n=u;return}u!==n&&(n=u,Promise.resolve().then(()=>s(e,t,r)))});Array.isArray(o.__effects)?o.__effects.push(i):o.__fetchListeners.push(()=>i.dispose())},Ft=(e,t,r)=>{const s=t.__ref;s.__fetchCleanups||(s.__fetchCleanups=[]),mt();const o=e.refetchInterval;if(o){const a=typeof o=="number"?o:te(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=Ee(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=Ue(e,t,r),h=re(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))}},At=(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&&N(e,i,o),n},Ye=(e,t)=>{const r=e.__ref;if(!r||!t.optimistic)return;const s=r.__optimisticSnapshot;s!==void 0&&(N(e,s,t.as),delete r.__optimisticSnapshot)},Be=e=>{if(!e)return()=>!0;if(he(e))return t=>t.includes(e);if(I(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},Ct=e=>{const t=[];for(const r of B){if(!He(r)){B.delete(r);continue}const s=gt(r);s&&e(s)&&t.push(O(r.config,r.element,r.context,{refresh:!0}))}return Promise.allSettled(t).then(()=>{})},ot=e=>{_t();for(const[t,r]of m)e(t)&&(r.stale=!0,ge(t));for(const[t]of q)!m.has(t)&&e(t)&&ge(t);return Ct(e)},at=(e,t)=>{const r=(I(e)?e:[e]).map(s=>s===!0||s==="*"?o=>o.startsWith(t+":"):s?Be(s):()=>!1);return ot(s=>r.some(o=>o(s)))},it=e=>{for(const[t]of m)e(t)&&Je(t);for(const[t]of q)e(t)&&ge(t)},ut=()=>!0,Mt=async(e,t,r)=>{const s=r?.fetch;if(!s)return;const o=await $e(s,r);if(!o)return;const n=t.__ref,{method:i,from:u,fields:a,transform:l,as:h,on:p,auth:v,headers:Pe,baseUrl:Fe,responseType:Q,invalidates:ie,optimistic:ue,onMutate:G,onSuccess:A,onError:$,onSettled:L}=e;let S;if(a===!0||p==="submit")S=ae(t);else if(I(a)){const g=ae(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(G)&&G(S,t,t.state);const ee=ue?At(t,e,S):null;U(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,x=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 j=await o.getSession();if(v===!0&&!j){ee!==void 0&&Ye(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:Pe,baseUrl:Fe};Q!==void 0&&(P.responseType=Q),e.params&&(P.params=ve(e.params,t,r));const z=ne(t,r);z&&(P.headers={...P.headers,"Accept-Language":z});const V=Ze(e,!0),W=await et(()=>g(P),V),{data:T,error:C}=W||{};if(C){ee!==void 0&&Ye(t,e),U(t,Ke(C)),F(t,"onFetchError",C),f($)&&$(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())-x});return}if(delete n.__optimisticSnapshot,U(t,je),T!==void 0&&(h||!ze(T))){const j=h?{[h]:T}:T;t.state?.update&&t.state.update(j,{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())-x}),ie&&at(ie,u)}catch(g){ee!==void 0&&Ye(t,e),U(t,Ke(g)),F(t,"onFetchError",g),k(e,t,"onFetchError",g),f($)&&$(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())-x})}finally{n.__fetching=!1}},kt=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||[])B.delete(r);e.__fetchCleanups=[],e.__fetchListeners=[],e.__unsubscribe=null,e.__fetchMounted=[]},ct=(e,t,r,s)=>{if(!e||!s?.fetch)return;const n=Ve(e,t);if(!n)return;const i=I(n)?n.map(a=>rt(Ve(a,t),t)).filter(Boolean):[rt(n,t)].filter(Boolean),u=t.__ref;if(u.__fetchMounted)for(const a of u.__fetchMounted)B.delete(a);u.__fetchMounted=[],!u.__fetchDisposer&&I(u.__effects)&&(u.__fetchDisposer={dispose:()=>kt(u)},u.__effects.push(u.__fetchDisposer));for(const a of i){const l=st(a.method),h=l?Mt:O,p=!l&&!Ne(a)&&a.method!=="subscribe";if(a.on==="create"?h(a,t,s):Promise.resolve().then(()=>{Dt({...a,__runner:h},t,s)}),p&&a.on==="create"&&((a.refetchInterval||a.refetchOnWindowFocus!==!1||a.refetchOnReconnect!==!1)&&Ft(a,t,s),!Ee(a))){const v={element:t,ref:u,config:a,context:s};B.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})}},De={invalidateQueries:e=>ot(Be(e)),removeQueries:e=>{it(e?Be(e):ut)},getQueryData:e=>re(e)?.data??void 0,setQueryData:(e,t)=>{const r=re(e),s=f(t)?t(r?.data):t;se(e,s,null)},prefetchQuery:async(e,t)=>{const r=t?.fetch;if(!r)return;const s=await $e(r,t);if(!s)return;const o=e.method||"select",n=me(null,t),i=ne(null,t),u=Le({...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=!Ne(e)&&e.read!==!1);const h=++be,p=await a(l);if(p?.data!==void 0&&!p?.error&&!Ee(e)&&!we(u,h)){const v=se(u,p.data,null,h,Re(u,h));v.gcTime=Ie(e.cache)?.gcTime||3e5}return p},getCache:()=>m,clear:()=>it(ut),dropNonLang:e=>{if(!e)return;const t=`:${e}`;for(const[r]of m)r.match(/:([a-z]{2,3})$/i)&&(r.endsWith(t)||Je(r))}},ft=(e,t)=>H(e)?Ue({method:"select",...e},t,t?.context):e,Qt={invalidateQueries(e){return De.invalidateQueries(e)},removeQueries(e){return De.removeQueries(e)},getQueryData(e){return De.getQueryData(ft(e,this))},setQueryData(e,t){return De.setQueryData(ft(e,this),t)}},$t={name:"fetch",create(e){const t=e.fetch;t&&(e.parent||q.clear(),ct(t,e,e.state,e.context))}};import{earlyKey as Yt,EARLY_KEY as Bt,createEarlySeedScript as Gt}from"./early.js";var zt=ct;export{Bt as EARLY_KEY,Nt as createAdapter,Gt as createEarlySeedScript,zt as default,Yt as earlyKey,ct as executeFetch,Qt as fetchFunctions,$t as fetchPlugin,qt as hasAdapter,Qe as initAdapterAuth,te as parseDuration,De as queryClient,It as registerAdapter,wt as resolveDb};
|
package/early.js
CHANGED
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
// the pre-boot script runs before any module, so a global is the only thing
|
|
14
14
|
// it can hand over through; the Symbol keeps it off the visible namespace and
|
|
15
15
|
// shared by every copy of this package (same rationale as CUSTOM_ADAPTERS).
|
|
16
|
-
// {
|
|
17
|
-
// The script creates it; an adapter that finds none creates it
|
|
18
|
-
//
|
|
19
|
-
//
|
|
16
|
+
// { entries: { [earlyKey]: { time, answer: Promise<Response|null> } }, seeded? }
|
|
17
|
+
// The script creates it; an adapter that finds none creates it, so a pre-boot
|
|
18
|
+
// script that arrives after the app booted (an async script on a cold cache)
|
|
19
|
+
// finds one and sends nothing: no call would be left to adopt its answers.
|
|
20
20
|
//
|
|
21
21
|
// The pure helpers below (earlyKey, isScalarParams, matchEarlyRoute) are ALSO
|
|
22
22
|
// embedded into the pre-boot script by source (`fn.toString()`), so the script
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
// self-contained: no reference to anything outside their own parameters and
|
|
25
25
|
// the platform's built-ins (URL, decodeURIComponent, …).
|
|
26
26
|
|
|
27
|
+
import { jsonForScript } from '@symbo.ls/utils'
|
|
28
|
+
|
|
27
29
|
export const EARLY_KEY = '@symbo.ls/fetch:EARLY'
|
|
28
30
|
|
|
29
31
|
// How long an early answer stays adoptable, counted from when the pre-boot
|
|
@@ -97,6 +99,30 @@ export const matchEarlyRoute = (patterns, path) => {
|
|
|
97
99
|
|
|
98
100
|
const registryKey = () => Symbol.for(EARLY_KEY)
|
|
99
101
|
|
|
102
|
+
// The configured headers a `query` mapping (header name → query parameter —
|
|
103
|
+
// `reads.query`, `early.query`) moves into the URL: one entry per mapped name,
|
|
104
|
+
// `{ name, header: lower-cased name, param, found, value }`, matched against
|
|
105
|
+
// `headers` case-insensitively (of two spellings the later wins, as the
|
|
106
|
+
// adapter's mergeHeaders does). One reading for the three that need it: the
|
|
107
|
+
// adapter's anonymous reads (rest.js openReads), the early hand-off
|
|
108
|
+
// (openEarly) and the pre-boot script's build (earlyScript.js queryParams) —
|
|
109
|
+
// so the key the script sends is the key the adapter expects.
|
|
110
|
+
export const queryHeaderEntries = (mapping, headers) => {
|
|
111
|
+
const entries = []
|
|
112
|
+
for (const name in mapping || {}) {
|
|
113
|
+
const header = name.toLowerCase()
|
|
114
|
+
const entry = { name, header, param: mapping[name], found: false, value: undefined }
|
|
115
|
+
for (const key in headers || {}) {
|
|
116
|
+
if (key.toLowerCase() === header) {
|
|
117
|
+
entry.found = true
|
|
118
|
+
entry.value = headers[key]
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
entries.push(entry)
|
|
122
|
+
}
|
|
123
|
+
return entries
|
|
124
|
+
}
|
|
125
|
+
|
|
100
126
|
// `fetch.early` with its `query` and `rpc` defaulting to the adapter's
|
|
101
127
|
// `reads` (adapters/rest.js): the same two options, declared once, drive both
|
|
102
128
|
// the pre-boot script and the adapter's own GETs. Used by both sides — the
|
|
@@ -117,19 +143,23 @@ export const withReads = (early, reads) => {
|
|
|
117
143
|
// name → configured value), whether RPCs went as GETs, and the answer age.
|
|
118
144
|
// No `early` config → null, and the adapter never looks (the opt-in).
|
|
119
145
|
export const openEarly = (config, headers) => {
|
|
120
|
-
if (!config || typeof config !== 'object') return null
|
|
121
146
|
const key = registryKey()
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
147
|
+
if (!config || typeof config !== 'object') {
|
|
148
|
+
// A server-seeded registry (createEarlySeedScript: the answers a
|
|
149
|
+
// brender pre-render already got) is adoptable without `fetch.early`:
|
|
150
|
+
// the page carries the answers, nothing is sent early. Only a call with
|
|
151
|
+
// no header beyond Accept-Language can take one — exactly what the
|
|
152
|
+
// server recorded (an anonymous GET).
|
|
153
|
+
const seeded = globalThis[key]
|
|
154
|
+
if (seeded && seeded.seeded) return { carried: {}, rpc: false, maxAge: EARLY_MAX_AGE }
|
|
155
|
+
return null
|
|
126
156
|
}
|
|
127
|
-
registry
|
|
157
|
+
// Any registry closes the hand-off: the pre-boot script sends nothing once
|
|
158
|
+
// one exists (earlyScript.js).
|
|
159
|
+
if (!globalThis[key]) globalThis[key] = { entries: {} }
|
|
128
160
|
const carried = {}
|
|
129
|
-
for (const
|
|
130
|
-
|
|
131
|
-
if (header.toLowerCase() === name.toLowerCase()) carried[header.toLowerCase()] = headers[header]
|
|
132
|
-
}
|
|
161
|
+
for (const { header, found, value } of queryHeaderEntries(config.query, headers)) {
|
|
162
|
+
if (found) carried[header] = value
|
|
133
163
|
}
|
|
134
164
|
const maxAge = typeof config.maxAge === 'number' && config.maxAge >= 0 ? config.maxAge : EARLY_MAX_AGE
|
|
135
165
|
return { carried, rpc: config.rpc === 'get', maxAge }
|
|
@@ -158,3 +188,29 @@ export const dropEarly = () => {
|
|
|
158
188
|
const registry = globalThis[registryKey()]
|
|
159
189
|
if (registry && registry.entries) registry.entries = {}
|
|
160
190
|
}
|
|
191
|
+
|
|
192
|
+
// --- Server-seeded answers (FW-BRENDER-HYDRATION-AND-CF-DEPLOY-PROVIDER-1) ---
|
|
193
|
+
// A @symbo.ls/brender pre-render records the anonymous GETs its fetch
|
|
194
|
+
// adapter made (url, Accept-Language, status, content type, body). The page
|
|
195
|
+
// carries them as this script, which runs before the app and fills the same
|
|
196
|
+
// registry a `fetch.early` pre-boot script fills — keyed with earlyKey, so
|
|
197
|
+
// the REST adapter adopts each answer for the first call that asks for
|
|
198
|
+
// exactly that request instead of asking the network again. Marked
|
|
199
|
+
// `seeded`, so an adapter without `fetch.early` adopts them too (openEarly).
|
|
200
|
+
// `entries`: [{ url, lang, status, type, body }]. JSON is embedded with
|
|
201
|
+
// utils jsonForScript, so a body can never close the <script>.
|
|
202
|
+
export const createEarlySeedScript = (entries) => {
|
|
203
|
+
const list = (Array.isArray(entries) ? entries : []).filter((e) => e && typeof e.url === 'string' && typeof e.body === 'string')
|
|
204
|
+
if (!list.length) return ''
|
|
205
|
+
const json = jsonForScript(list.map((e) => ({
|
|
206
|
+
k: earlyKey(e.url, e.lang || ''),
|
|
207
|
+
s: e.status || 200,
|
|
208
|
+
t: e.type || 'application/json',
|
|
209
|
+
b: e.body
|
|
210
|
+
})))
|
|
211
|
+
return '<script>(function(){try{var k=Symbol.for(' + JSON.stringify(EARLY_KEY) + '),' +
|
|
212
|
+
'r=globalThis[k]||(globalThis[k]={entries:{}}),t=Date.now(),l=' + json + ';' +
|
|
213
|
+
'r.seeded=true;r.entries=r.entries||{};' +
|
|
214
|
+
'for(var i=0;i<l.length;i++){var e=l[i];r.entries[e.k]={time:t,answer:Promise.resolve(new Response(e.b,{status:e.s,headers:{"content-type":e.t}}))}}' +
|
|
215
|
+
'}catch(e){}})()</script>'
|
|
216
|
+
}
|
package/earlyScript.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// before any module, so it carries everything itself: the adapter's address,
|
|
9
9
|
// the configured headers it sends as query parameters, the language rule and
|
|
10
10
|
// the declared requests as data, and the address helpers BY SOURCE — the REST
|
|
11
|
-
// adapter's own buildUrl / selectQuery and early.js's earlyKey /
|
|
11
|
+
// adapter's own buildUrl / selectQuery / withQuery and early.js's earlyKey /
|
|
12
12
|
// isScalarParams / matchEarlyRoute — so an early request has exactly the
|
|
13
13
|
// address and identity the adapter computes for the call that adopts it.
|
|
14
14
|
//
|
|
@@ -36,13 +36,9 @@
|
|
|
36
36
|
// makes (they send none). `ctx` is { path, query (URLSearchParams), lang,
|
|
37
37
|
// storage(key) → localStorage value or null }.
|
|
38
38
|
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
|
|
42
|
-
// polyglot's own default for where it keeps the chosen language
|
|
43
|
-
// (@symbo.ls/polyglot STORAGE_KEY_LANG): the script must read the same slot
|
|
44
|
-
// the app will, or its requests ask in another language than the app's.
|
|
45
|
-
const POLYGLOT_LANG_KEY = 'smbls_lang'
|
|
39
|
+
import { polyglotLangStorageKey, polyglotFallbackLang } from '@symbo.ls/utils'
|
|
40
|
+
import { buildUrl, selectQuery, withQuery } from './adapters/rest.js'
|
|
41
|
+
import { EARLY_KEY, earlyKey, isScalarParams, matchEarlyRoute, withReads, queryHeaderEntries } from './early.js'
|
|
46
42
|
|
|
47
43
|
// The fetch() options an early GET may copy from the adapter's — the ones
|
|
48
44
|
// that change what comes back. Headers never: every header but the language
|
|
@@ -78,13 +74,16 @@ const requestsSource = (requests, where) => {
|
|
|
78
74
|
|
|
79
75
|
// The language the app will ask in on its first view: polyglot's stored
|
|
80
76
|
// choice, else the project's `state.lang`, else polyglot's default — the
|
|
81
|
-
// order polyglot's initPolyglot
|
|
82
|
-
//
|
|
77
|
+
// slot and the order polyglot's initPolyglot uses, from the same utils
|
|
78
|
+
// helpers (polyglotLangStorageKey, polyglotFallbackLang): the script must
|
|
79
|
+
// read what the app will, or its requests ask in another language than the
|
|
80
|
+
// app's. No polyglot: `state.lang`, or none (a declarative fetch then sends
|
|
81
|
+
// no Accept-Language either).
|
|
83
82
|
const languageRule = (project) => {
|
|
84
83
|
const stateLang = project.state && typeof project.state.lang === 'string' ? project.state.lang : ''
|
|
85
84
|
const polyglot = project.polyglot
|
|
86
85
|
if (polyglot && typeof polyglot === 'object') {
|
|
87
|
-
return { storage: polyglot
|
|
86
|
+
return { storage: polyglotLangStorageKey(polyglot), fallback: polyglotFallbackLang(stateLang, polyglot) }
|
|
88
87
|
}
|
|
89
88
|
return { storage: '', fallback: stateLang }
|
|
90
89
|
}
|
|
@@ -94,10 +93,9 @@ const languageRule = (project) => {
|
|
|
94
93
|
// for: those GETs would go out without the key and be refused, every time.
|
|
95
94
|
const queryParams = (mapping, headers) => {
|
|
96
95
|
const params = {}
|
|
97
|
-
for (const name
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
params[mapping[name]] = headers[header]
|
|
96
|
+
for (const { name, param, found, value } of queryHeaderEntries(mapping, headers)) {
|
|
97
|
+
if (!found) throw new Error(`@symbo.ls/fetch early.query: "${name}" is not one of the adapter's configured headers`)
|
|
98
|
+
params[param] = value
|
|
101
99
|
}
|
|
102
100
|
return params
|
|
103
101
|
}
|
|
@@ -150,10 +148,11 @@ export const createEarlyScript = (project = {}) => {
|
|
|
150
148
|
var g = globalThis
|
|
151
149
|
var K = Symbol.for(${JSON.stringify(EARLY_KEY)})
|
|
152
150
|
if (g[K] || typeof g.fetch !== 'function' || !g.location) return
|
|
153
|
-
var registry = g[K] = {
|
|
151
|
+
var registry = g[K] = { entries: {} }
|
|
154
152
|
var config = ${JSON.stringify(config)}
|
|
155
153
|
var buildUrl = ${buildUrl.toString()}
|
|
156
154
|
var selectQuery = ${selectQuery.toString()}
|
|
155
|
+
var withQuery = ${withQuery.toString()}
|
|
157
156
|
var earlyKey = ${earlyKey.toString()}
|
|
158
157
|
var isScalarParams = ${isScalarParams.toString()}
|
|
159
158
|
var matchEarlyRoute = ${matchEarlyRoute.toString()}
|
|
@@ -188,11 +187,9 @@ export const createEarlyScript = (project = {}) => {
|
|
|
188
187
|
var language = request.lang === false ? '' : lang
|
|
189
188
|
var key = earlyKey(url, language)
|
|
190
189
|
if (registry.entries[key]) continue
|
|
191
|
-
var address = new URL(url)
|
|
192
|
-
for (var name in config.query) address.searchParams.set(name, config.query[name])
|
|
193
190
|
var options = Object.assign({}, config.fetchOptions, { method: 'GET' })
|
|
194
191
|
if (language) options.headers = { 'Accept-Language': language }
|
|
195
|
-
registry.entries[key] = { time: Date.now(), answer: g.fetch(
|
|
192
|
+
registry.entries[key] = { time: Date.now(), answer: g.fetch(withQuery(url, config.query), options).catch(function () { return null }) }
|
|
196
193
|
} catch (e) {}
|
|
197
194
|
}
|
|
198
195
|
})()
|
package/index.js
CHANGED
|
@@ -277,17 +277,14 @@ const newerEntry = (key, seq) => {
|
|
|
277
277
|
// A request that started before its key's last invalidation (or removal).
|
|
278
278
|
const isOutdated = (key, seq) => (invalidatedAt.get(key) || 0) > seq
|
|
279
279
|
|
|
280
|
+
// Every request on `key` that started before now is outdated from here on.
|
|
281
|
+
const markInvalidated = (key) => { invalidatedAt.set(key, ++fetchSeq) }
|
|
282
|
+
|
|
280
283
|
// Removing an entry also marks its key, so a reply still in flight writes
|
|
281
284
|
// its rows back as stale, never as fresh.
|
|
282
285
|
const removeCache = (key) => {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
invalidatedAt.set(key, ++fetchSeq)
|
|
286
|
-
return
|
|
287
|
-
}
|
|
288
|
-
for (const [cacheKey] of cacheStore) invalidatedAt.set(cacheKey, ++fetchSeq)
|
|
289
|
-
for (const [inFlightKey] of activeQueries) invalidatedAt.set(inFlightKey, ++fetchSeq)
|
|
290
|
-
cacheStore.clear()
|
|
286
|
+
cacheStore.delete(key)
|
|
287
|
+
markInvalidated(key)
|
|
291
288
|
}
|
|
292
289
|
|
|
293
290
|
const subscribeToCacheKey = (key, callback) => {
|
|
@@ -671,6 +668,10 @@ const updateElementState = (element, data, stateKey, options = {}) => {
|
|
|
671
668
|
}
|
|
672
669
|
}
|
|
673
670
|
|
|
671
|
+
// The settled statuses (setFetchStatus copies, so one object serves every write).
|
|
672
|
+
const SUCCESS = Object.freeze({ isFetching: false, isLoading: false, isStale: false, isSuccess: true, error: null, status: 'success', fetchStatus: 'idle' })
|
|
673
|
+
const errorStatus = (error) => ({ isFetching: false, isLoading: false, isStale: false, isSuccess: false, error, status: 'error', fetchStatus: 'idle' })
|
|
674
|
+
|
|
674
675
|
const setFetchStatus = (element, status) => {
|
|
675
676
|
// Element may have been torn down (route change, modal close, parent
|
|
676
677
|
// unmount) between the runFetch entry guard and this call site —
|
|
@@ -754,6 +755,20 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
754
755
|
keepPreviousData
|
|
755
756
|
} = config
|
|
756
757
|
|
|
758
|
+
// The rows as the element gets them: `select` (a function) then `transform`.
|
|
759
|
+
const shape = (data) => {
|
|
760
|
+
if (isFunction(selectTransform)) data = selectTransform(data, element, element.state)
|
|
761
|
+
if (transform) data = transform(data, element, element.state)
|
|
762
|
+
return data
|
|
763
|
+
}
|
|
764
|
+
// This query failed: its status, then the element's and the config's
|
|
765
|
+
// onFetchError.
|
|
766
|
+
const fail = (error) => {
|
|
767
|
+
setFetchStatus(element, errorStatus(error))
|
|
768
|
+
triggerCallback(element, 'onFetchError', error)
|
|
769
|
+
triggerConfigCallback(config, element, 'onFetchError', error)
|
|
770
|
+
}
|
|
771
|
+
|
|
757
772
|
let select = isString(selectTransform) ? selectTransform : undefined
|
|
758
773
|
if (query && isFunction(element.getQuery)) {
|
|
759
774
|
const q = element.getQuery(adapter.name || 'paths')
|
|
@@ -805,14 +820,12 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
805
820
|
ref.__pages = [cached.data]
|
|
806
821
|
setPageCursors(ref, config, cached.data)
|
|
807
822
|
}
|
|
808
|
-
|
|
809
|
-
if (isFunction(selectTransform)) data = selectTransform(data, element, element.state)
|
|
810
|
-
if (transform) data = transform(data, element, element.state)
|
|
823
|
+
const data = shape(cached.data)
|
|
811
824
|
if (!isCurrent()) return
|
|
812
825
|
// The status first: the state update re-renders, and a render that
|
|
813
826
|
// reads `__fetchStatus` must see the answer it renders (report #25).
|
|
814
827
|
if (!isStale) {
|
|
815
|
-
setFetchStatus(element,
|
|
828
|
+
setFetchStatus(element, SUCCESS)
|
|
816
829
|
updateElementState(element, data, stateKey)
|
|
817
830
|
return
|
|
818
831
|
}
|
|
@@ -834,11 +847,6 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
834
847
|
// The shared request failed: so did this query, with the same error. It
|
|
835
848
|
// used to read an error answer as null rows (onFetchComplete(null)) and a
|
|
836
849
|
// thrown one as nothing at all.
|
|
837
|
-
const fail = (error) => {
|
|
838
|
-
setFetchStatus(element, { isFetching: false, isLoading: false, isStale: false, isSuccess: false, error, status: 'error', fetchStatus: 'idle' })
|
|
839
|
-
triggerCallback(element, 'onFetchError', error)
|
|
840
|
-
triggerConfigCallback(config, element, 'onFetchError', error)
|
|
841
|
-
}
|
|
842
850
|
try {
|
|
843
851
|
const result = await Promise.race([existing, new Promise((_, r) => setTimeout(() => r('DEDUP_TIMEOUT'), 15000))])
|
|
844
852
|
if (!isCurrent()) return
|
|
@@ -848,9 +856,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
848
856
|
// A request that started later (an invalidation's refetch) may have
|
|
849
857
|
// landed first: its rows are the newer answer.
|
|
850
858
|
const newer = !infinite && newerEntry(cacheKey, requestSeqs.get(existing) || 0)
|
|
851
|
-
|
|
852
|
-
if (isFunction(selectTransform)) finalData = selectTransform(finalData, element, element.state)
|
|
853
|
-
if (transform) finalData = transform(finalData, element, element.state)
|
|
859
|
+
const finalData = shape(newer ? newer.data : result.data)
|
|
854
860
|
if (!isCurrent()) return
|
|
855
861
|
updateElementState(element, finalData, stateKey)
|
|
856
862
|
triggerCallback(element, 'onFetchComplete', finalData)
|
|
@@ -891,9 +897,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
891
897
|
if (!isCurrent()) return
|
|
892
898
|
if (auth === true && !session) {
|
|
893
899
|
const err = { message: 'Not authenticated' }
|
|
894
|
-
|
|
895
|
-
triggerCallback(element, 'onFetchError', err)
|
|
896
|
-
triggerConfigCallback(config, element, 'onFetchError', err)
|
|
900
|
+
fail(err)
|
|
897
901
|
return { data: null, error: err }
|
|
898
902
|
}
|
|
899
903
|
}
|
|
@@ -1011,9 +1015,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
1011
1015
|
if (error) {
|
|
1012
1016
|
// An older request's failure never replaces a newer answer.
|
|
1013
1017
|
if (cacheKey && !newerEntry(cacheKey, requestSeq)) setCacheEntry(cacheKey, null, error, requestSeq)
|
|
1014
|
-
|
|
1015
|
-
triggerCallback(element, 'onFetchError', error)
|
|
1016
|
-
triggerConfigCallback(config, element, 'onFetchError', error)
|
|
1018
|
+
fail(error)
|
|
1017
1019
|
if (_emitNet) _emitNet({
|
|
1018
1020
|
phase: 'error', mode: 'query', from, method, cacheKey,
|
|
1019
1021
|
error: error.message || error,
|
|
@@ -1057,14 +1059,13 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
1057
1059
|
setPageCursors(ref, config, data)
|
|
1058
1060
|
}
|
|
1059
1061
|
|
|
1060
|
-
|
|
1061
|
-
if (transform) finalData = transform(finalData, element, element.state)
|
|
1062
|
+
finalData = shape(finalData)
|
|
1062
1063
|
if (!isCurrent()) return
|
|
1063
1064
|
|
|
1064
1065
|
// The status first: the state update re-renders, and a render that
|
|
1065
1066
|
// reads `__fetchStatus` saw the request still pending beside its own
|
|
1066
1067
|
// rows (report #25).
|
|
1067
|
-
setFetchStatus(element,
|
|
1068
|
+
setFetchStatus(element, SUCCESS)
|
|
1068
1069
|
|
|
1069
1070
|
// keepPreviousData — don't clear state while fetching new page
|
|
1070
1071
|
if (!keepPreviousData || finalData !== undefined) {
|
|
@@ -1080,9 +1081,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
1080
1081
|
}
|
|
1081
1082
|
} catch (e) {
|
|
1082
1083
|
if (!isCurrent()) return
|
|
1083
|
-
|
|
1084
|
-
triggerCallback(element, 'onFetchError', e)
|
|
1085
|
-
triggerConfigCallback(config, element, 'onFetchError', e)
|
|
1084
|
+
fail(e)
|
|
1086
1085
|
if (_emitNet) _emitNet({
|
|
1087
1086
|
phase: 'error', mode: 'query', from, method, cacheKey,
|
|
1088
1087
|
error: e.message || String(e),
|
|
@@ -1309,10 +1308,10 @@ const invalidateMatching = (matches) => {
|
|
|
1309
1308
|
for (const [key, entry] of cacheStore) {
|
|
1310
1309
|
if (!matches(key)) continue
|
|
1311
1310
|
entry.stale = true
|
|
1312
|
-
|
|
1311
|
+
markInvalidated(key)
|
|
1313
1312
|
}
|
|
1314
1313
|
for (const [key] of activeQueries) {
|
|
1315
|
-
if (!cacheStore.has(key) && matches(key))
|
|
1314
|
+
if (!cacheStore.has(key) && matches(key)) markInvalidated(key)
|
|
1316
1315
|
}
|
|
1317
1316
|
return refreshMounted(matches)
|
|
1318
1317
|
}
|
|
@@ -1334,10 +1333,12 @@ const removeMatching = (matches) => {
|
|
|
1334
1333
|
if (matches(key)) removeCache(key)
|
|
1335
1334
|
}
|
|
1336
1335
|
for (const [key] of activeQueries) {
|
|
1337
|
-
if (matches(key))
|
|
1336
|
+
if (matches(key)) markInvalidated(key)
|
|
1338
1337
|
}
|
|
1339
1338
|
}
|
|
1340
1339
|
|
|
1340
|
+
const ALL_KEYS = () => true
|
|
1341
|
+
|
|
1341
1342
|
// --- Mutation runner (insert/update/delete with optimistic + invalidation) ---
|
|
1342
1343
|
|
|
1343
1344
|
const runMutation = async (config, element, context) => {
|
|
@@ -1372,7 +1373,6 @@ const runMutation = async (config, element, context) => {
|
|
|
1372
1373
|
// Apply optimistic update
|
|
1373
1374
|
const snapshot = optimistic ? applyOptimisticUpdate(element, config, mutationData) : null
|
|
1374
1375
|
|
|
1375
|
-
ref.__fetching = true
|
|
1376
1376
|
setFetchStatus(element, { isFetching: true, isLoading: false, isStale: false, isSuccess: false, error: null, status: 'pending', fetchStatus: 'fetching' })
|
|
1377
1377
|
triggerCallback(element, 'onFetchStart')
|
|
1378
1378
|
triggerConfigCallback(config, element, 'onFetchStart')
|
|
@@ -1412,7 +1412,7 @@ const runMutation = async (config, element, context) => {
|
|
|
1412
1412
|
|
|
1413
1413
|
if (error) {
|
|
1414
1414
|
if (snapshot !== undefined) rollbackOptimistic(element, config)
|
|
1415
|
-
setFetchStatus(element,
|
|
1415
|
+
setFetchStatus(element, errorStatus(error))
|
|
1416
1416
|
triggerCallback(element, 'onFetchError', error)
|
|
1417
1417
|
if (isFunction(onError)) onError(error, mutationData, element)
|
|
1418
1418
|
if (isFunction(onSettled)) onSettled(null, error, mutationData, element)
|
|
@@ -1427,7 +1427,7 @@ const runMutation = async (config, element, context) => {
|
|
|
1427
1427
|
delete ref.__optimisticSnapshot
|
|
1428
1428
|
|
|
1429
1429
|
// The status first, as for a query: the state update re-renders.
|
|
1430
|
-
setFetchStatus(element,
|
|
1430
|
+
setFetchStatus(element, SUCCESS)
|
|
1431
1431
|
|
|
1432
1432
|
// A body value (Blob, stream, …) lands in state only under `as`.
|
|
1433
1433
|
if (data !== undefined && (stateKey || !isBodyValue(data))) {
|
|
@@ -1448,7 +1448,7 @@ const runMutation = async (config, element, context) => {
|
|
|
1448
1448
|
if (invalidates) runInvalidates(invalidates, from)
|
|
1449
1449
|
} catch (e) {
|
|
1450
1450
|
if (snapshot !== undefined) rollbackOptimistic(element, config)
|
|
1451
|
-
setFetchStatus(element,
|
|
1451
|
+
setFetchStatus(element, errorStatus(e))
|
|
1452
1452
|
triggerCallback(element, 'onFetchError', e)
|
|
1453
1453
|
triggerConfigCallback(config, element, 'onFetchError', e)
|
|
1454
1454
|
if (isFunction(onError)) onError(e, mutationData, element)
|
|
@@ -1582,11 +1582,7 @@ export const queryClient = {
|
|
|
1582
1582
|
// Drops every matching entry (same matches). A mounted query keeps the rows
|
|
1583
1583
|
// it shows; the next mount loads them afresh.
|
|
1584
1584
|
removeQueries: (keyOrPattern) => {
|
|
1585
|
-
|
|
1586
|
-
removeCache()
|
|
1587
|
-
return
|
|
1588
|
-
}
|
|
1589
|
-
removeMatching(keyMatcher(keyOrPattern))
|
|
1585
|
+
removeMatching(keyOrPattern ? keyMatcher(keyOrPattern) : ALL_KEYS)
|
|
1590
1586
|
},
|
|
1591
1587
|
|
|
1592
1588
|
getQueryData: (key) => {
|
|
@@ -1646,7 +1642,7 @@ export const queryClient = {
|
|
|
1646
1642
|
},
|
|
1647
1643
|
|
|
1648
1644
|
getCache: () => cacheStore,
|
|
1649
|
-
clear: () =>
|
|
1645
|
+
clear: () => removeMatching(ALL_KEYS),
|
|
1650
1646
|
|
|
1651
1647
|
// Drop every cache entry whose lang suffix isn't `keepLang`.
|
|
1652
1648
|
// Cache keys are of the form `${from}:${method}:${params}[:lang]` — entries
|
|
@@ -1724,4 +1720,5 @@ export const fetchPlugin = {
|
|
|
1724
1720
|
}
|
|
1725
1721
|
|
|
1726
1722
|
export { parseDuration }
|
|
1723
|
+
export { earlyKey, EARLY_KEY, createEarlySeedScript } from './early.js'
|
|
1727
1724
|
export default executeFetch
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/fetch",
|
|
3
|
-
"version": "3.14.
|
|
3
|
+
"version": "3.14.664",
|
|
4
4
|
"license": "CC-BY-NC-4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"adapters"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@symbo.ls/signal": "^3.14.
|
|
45
|
-
"@symbo.ls/utils": "^3.14.
|
|
44
|
+
"@symbo.ls/signal": "^3.14.787",
|
|
45
|
+
"@symbo.ls/utils": "^3.14.786"
|
|
46
46
|
},
|
|
47
47
|
"sideEffects": false,
|
|
48
48
|
"publishConfig": {
|