@symbo.ls/fetch 3.14.659 → 3.14.660
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/README.md +89 -9
- package/adapters/rest.js +165 -48
- package/dist/cjs/adapters/rest.js +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/adapters/rest.js +1 -1
- package/dist/esm/index.js +1 -1
- package/index.js +47 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -572,6 +572,83 @@ await queryClient.prefetchQuery({
|
|
|
572
572
|
{ fetch: { from: '/users', baseUrl: 'https://api.example.com/auth', headers: { 'X-Custom': 'value' } } }
|
|
573
573
|
```
|
|
574
574
|
|
|
575
|
+
### Per-call headers
|
|
576
|
+
|
|
577
|
+
A call's `headers` merge over the adapter's configured `headers` and its token. Names match case-insensitively and the call's value wins, so one call can send its own Bearer token (for example a per-user token). A `null` value removes a configured header. `headers` can be a plain object, a `Headers` instance or an array of `[name, value]` pairs.
|
|
578
|
+
|
|
579
|
+
```js
|
|
580
|
+
const db = await el.getDB()
|
|
581
|
+
await db.select({ from: '/me', headers: { Authorization: `Bearer ${userToken}` } })
|
|
582
|
+
await db.select({ from: '/public/feed', headers: { Authorization: null } }) // no token on this call
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
### `responseType`
|
|
586
|
+
|
|
587
|
+
`responseType` sets how the REST adapter reads the response body. It works on `select`, `rpc`, `insert`, `update`, `upsert` and `delete`, and on the declarative `fetch` options.
|
|
588
|
+
|
|
589
|
+
| Value | `data` on success |
|
|
590
|
+
|-------|-------------------|
|
|
591
|
+
| `'auto'` (default) | JSON when the `content-type` contains `json`, else text |
|
|
592
|
+
| `'json'` | parsed JSON, whatever the `content-type` says (`null` for an empty body) |
|
|
593
|
+
| `'text'` | the body as a string |
|
|
594
|
+
| `'blob'` | a `Blob` — binary bytes and the content type stay intact (audio, xlsx, csv) |
|
|
595
|
+
| `'arrayBuffer'` | an `ArrayBuffer` |
|
|
596
|
+
| `'stream'` | the body `ReadableStream`, returned before the body is read (`null` when there is no body) |
|
|
597
|
+
| `'response'` | the raw `Response`, unread (use it when you need the response headers) |
|
|
598
|
+
|
|
599
|
+
A failed response keeps the `{ data, error, status }` contract for every type. The adapter reads the body (JSON by `content-type`, else text) for the message. `error` is its `message` or `error` field, else the status text. With a type other than `'auto'`, `error` falls back to `HTTP <status>` when both are empty (an HTTP/2 response has no status text). `data` is the error body. With `'response'`, `data` stays the unread `Response`, and the message comes from a copy. An unknown `responseType` throws before the request is sent.
|
|
600
|
+
|
|
601
|
+
Read a streamed (SSE) answer chunk by chunk:
|
|
602
|
+
|
|
603
|
+
```js
|
|
604
|
+
const db = await el.getDB()
|
|
605
|
+
const { data: stream, error } = await db.insert({ from: '/ask', data: { question }, responseType: 'stream' })
|
|
606
|
+
if (error) return
|
|
607
|
+
const reader = stream.pipeThrough(new TextDecoderStream()).getReader()
|
|
608
|
+
while (true) {
|
|
609
|
+
const { value, done } = await reader.read()
|
|
610
|
+
if (done) break
|
|
611
|
+
onChunk(value) // 'data: …\n\n' lines, as the server sends them
|
|
612
|
+
}
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
Download a file as a Blob:
|
|
616
|
+
|
|
617
|
+
```js
|
|
618
|
+
const { data: blob, error } = await db.select({ from: '/finops/report.xlsx', params: { month: 9 }, responseType: 'blob' })
|
|
619
|
+
if (!error) el.state.update({ reportUrl: URL.createObjectURL(blob) }) // blob.type is the server's content-type
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
In a declarative `fetch`:
|
|
623
|
+
|
|
624
|
+
```js
|
|
625
|
+
{ state: { answerAudio: null }, fetch: { from: '/voice/answer', responseType: 'blob', as: 'answerAudio' } }
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
- A `Blob`, `ArrayBuffer`, stream or `Response` goes into state only under `as`, as the value itself. Without `as`, read it in `transform` or `onFetchComplete`.
|
|
629
|
+
- A `'stream'` or `'response'` body can be read once. So these queries are never cached or deduplicated. They send the request again on window focus or reconnect only when `refetchOnWindowFocus: true` or `refetchOnReconnect: true` is set.
|
|
630
|
+
|
|
631
|
+
### Request bodies
|
|
632
|
+
|
|
633
|
+
The REST adapter sends `data` (`insert`, `update`, `upsert`, `signIn`) and `params` (`rpc`) like this:
|
|
634
|
+
|
|
635
|
+
- `FormData`, `Blob` / `File`, `ArrayBuffer`, typed arrays / `DataView`, `URLSearchParams` and `ReadableStream` go to `fetch` as they are. The adapter sets no `Content-Type` for them, and it drops a configured one. `fetch` then writes the right one: the multipart boundary, the Blob's type or the form-urlencoded type. A per-call `Content-Type` header still applies. A `ReadableStream` is sent with `duplex: 'half'`.
|
|
636
|
+
- Every other value (plain objects, arrays, strings, …) is JSON-encoded with `Content-Type: application/json`, as before.
|
|
637
|
+
|
|
638
|
+
Upload a recording as multipart form data:
|
|
639
|
+
|
|
640
|
+
```js
|
|
641
|
+
const form = new FormData()
|
|
642
|
+
form.append('audio', recording, 'voice.webm') // a Blob, e.g. from MediaRecorder
|
|
643
|
+
const { data: reply, error } = await db.insert({ from: '/voice', data: form, responseType: 'blob' })
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
In a declarative mutation, return the `FormData` from `transform`:
|
|
647
|
+
|
|
648
|
+
```js
|
|
649
|
+
{ tag: 'form', fetch: { method: 'insert', from: '/upload', on: 'submit', transform: (data, el) => new FormData(el.node) } }
|
|
650
|
+
```
|
|
651
|
+
|
|
575
652
|
## State inheritance
|
|
576
653
|
|
|
577
654
|
When `state` is a string, the element inherits that key from the parent state. Fetch uses the same string as the default `from` (table name), so declaring `state` is often enough:
|
|
@@ -664,14 +741,16 @@ const { data, error } = await db.select({ from: 'articles' })
|
|
|
664
741
|
|
|
665
742
|
## Adapter interface
|
|
666
743
|
|
|
667
|
-
All return `{ data, error }
|
|
744
|
+
All return `{ data, error }` (the REST adapter adds `status`).
|
|
668
745
|
|
|
669
746
|
```js
|
|
670
|
-
db.select({ from, select, params, limit, offset, order, single, headers, baseUrl })
|
|
671
|
-
db.insert({ from, data, select, headers, baseUrl })
|
|
672
|
-
db.update({ from, data, params, method, headers, baseUrl }) // method: 'PUT' | 'PATCH'
|
|
673
|
-
db.
|
|
674
|
-
db.
|
|
747
|
+
db.select({ from, select, params, limit, offset, order, single, headers, baseUrl, responseType })
|
|
748
|
+
db.insert({ from, data, select, headers, baseUrl, responseType })
|
|
749
|
+
db.update({ from, data, params, method, headers, baseUrl, responseType }) // method: 'PUT' | 'PATCH'
|
|
750
|
+
db.upsert({ from, data, params, method, headers, baseUrl, responseType }) // method defaults to 'PUT'
|
|
751
|
+
db.delete({ from, params, headers, baseUrl, responseType })
|
|
752
|
+
db.rpc({ from, params, headers, baseUrl, responseType })
|
|
753
|
+
// responseType (REST): 'auto' | 'json' | 'text' | 'blob' | 'arrayBuffer' | 'stream' | 'response'
|
|
675
754
|
|
|
676
755
|
// Auth (adapter-dependent — implemented by adapters that manage sessions)
|
|
677
756
|
db.getSession()
|
|
@@ -824,8 +903,8 @@ When used as a plugin, fetch hooks into the `create` lifecycle to auto-execute f
|
|
|
824
903
|
| `getPreviousPageParam` | function | — | `(firstPage, allPages) => cursor \| null` |
|
|
825
904
|
| `refetchInterval` | number/string | — | Polling interval |
|
|
826
905
|
| `refetchIntervalInBackground` | boolean | `false` | Poll when tab hidden |
|
|
827
|
-
| `refetchOnWindowFocus` | boolean | `true` | Refetch on tab focus |
|
|
828
|
-
| `refetchOnReconnect` | boolean | `true` | Refetch on online |
|
|
906
|
+
| `refetchOnWindowFocus` | boolean | `true` (`false` for `'stream'` / `'response'`) | Refetch on tab focus |
|
|
907
|
+
| `refetchOnReconnect` | boolean | `true` (`false` for `'stream'` / `'response'`) | Refetch on online |
|
|
829
908
|
| `optimistic` | any/function | — | Optimistic update data |
|
|
830
909
|
| `invalidates` | string/array/boolean | — | Cache keys to invalidate after mutation |
|
|
831
910
|
| `onMutate` | function | — | Before mutation fires |
|
|
@@ -840,6 +919,7 @@ When used as a plugin, fetch hooks into the `create` lifecycle to auto-execute f
|
|
|
840
919
|
| `limit` | number | — | Row limit |
|
|
841
920
|
| `offset` | number | — | Row offset |
|
|
842
921
|
| `order` | string/object/array | — | Sort order |
|
|
843
|
-
| `headers` | object | — | Per-request headers (REST) |
|
|
922
|
+
| `headers` | object | — | Per-request headers (REST); merged over the configured headers and the token |
|
|
844
923
|
| `baseUrl` | string | — | Per-request base URL (REST) |
|
|
924
|
+
| `responseType` | string | `'auto'` | How the body is read (REST): `auto`, `json`, `text`, `blob`, `arrayBuffer`, `stream`, `response` |
|
|
845
925
|
| `lang` | string | auto from context/state | Language override (via params) |
|
package/adapters/rest.js
CHANGED
|
@@ -14,15 +14,131 @@ const buildUrl = (base, from, params) => {
|
|
|
14
14
|
return url.toString()
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const
|
|
18
|
-
|
|
17
|
+
const typeTag = (value) => Object.prototype.toString.call(value).slice(8, -1)
|
|
18
|
+
|
|
19
|
+
// --- Responses ---
|
|
20
|
+
//
|
|
21
|
+
// `responseType` picks how a response body is read. 'auto' is the reader this
|
|
22
|
+
// adapter always had — JSON when the content-type says so, text otherwise — and
|
|
23
|
+
// stays the default. The others return what fetch() gives: a Blob or an
|
|
24
|
+
// ArrayBuffer for binary downloads (audio, xlsx, csv), the body ReadableStream
|
|
25
|
+
// for chunk-by-chunk reads (SSE), or the Response itself. 'stream' and
|
|
26
|
+
// 'response' return WITHOUT reading the body, so each chunk reaches the caller
|
|
27
|
+
// as the server sends it instead of as one string once the stream has ended.
|
|
28
|
+
const RESPONSE_TYPES = ['auto', 'json', 'text', 'blob', 'arrayBuffer', 'stream', 'response']
|
|
29
|
+
|
|
30
|
+
const READERS = {
|
|
31
|
+
// An empty body (204, 205) is null rather than a JSON syntax error.
|
|
32
|
+
json: async (res) => {
|
|
33
|
+
const text = await res.text()
|
|
34
|
+
return text ? JSON.parse(text) : null
|
|
35
|
+
},
|
|
36
|
+
text: (res) => res.text(),
|
|
37
|
+
blob: (res) => res.blob(),
|
|
38
|
+
arrayBuffer: (res) => res.arrayBuffer(),
|
|
39
|
+
stream: (res) => res.body,
|
|
40
|
+
response: (res) => res
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const readAuto = (res) => {
|
|
19
44
|
const contentType = res.headers.get('content-type')
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
45
|
+
return contentType && contentType.includes('json') ? res.json() : res.text()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// A failed response is read for its message whatever `responseType` asked for:
|
|
49
|
+
// the caller checks `error` first, and a Blob or a stream of an error page
|
|
50
|
+
// carries no message. Unlike 'auto', a body that claims JSON but does not parse
|
|
51
|
+
// stays text instead of throwing.
|
|
52
|
+
const readErrorBody = async (res) => {
|
|
53
|
+
const text = await res.text()
|
|
54
|
+
const contentType = res.headers.get('content-type')
|
|
55
|
+
if (text && contentType && contentType.includes('json')) {
|
|
56
|
+
try { return JSON.parse(text) } catch (_) { /* not JSON after all — keep the text */ }
|
|
57
|
+
}
|
|
58
|
+
return text
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const errorMessage = (body, res) => body?.message || body?.error || res.statusText
|
|
62
|
+
|
|
63
|
+
const request = async (url, options, responseType) => {
|
|
64
|
+
const type = responseType == null ? 'auto' : responseType
|
|
65
|
+
if (!RESPONSE_TYPES.includes(type)) {
|
|
66
|
+
throw new TypeError(`@symbo.ls/fetch rest: unknown responseType "${type}" — use one of: ${RESPONSE_TYPES.join(', ')}`)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const res = await globalThis.fetch(url, options)
|
|
70
|
+
|
|
71
|
+
if (type === 'auto') {
|
|
72
|
+
const data = await readAuto(res)
|
|
73
|
+
return { data, error: res.ok ? null : errorMessage(data, res), status: res.status }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!res.ok) {
|
|
77
|
+
// 'response' reads a copy, so the caller still gets the Response unread
|
|
78
|
+
// (Retry-After and the other headers included). `HTTP <status>` keeps the
|
|
79
|
+
// error truthy when there is neither a message nor a status text — HTTP/2
|
|
80
|
+
// responses carry no status text at all.
|
|
81
|
+
const body = await readErrorBody(type === 'response' ? res.clone() : res)
|
|
82
|
+
return {
|
|
83
|
+
data: type === 'response' ? res : body,
|
|
84
|
+
error: errorMessage(body, res) || `HTTP ${res.status}`,
|
|
85
|
+
status: res.status
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { data: await READERS[type](res), error: null, status: res.status }
|
|
24
90
|
}
|
|
25
91
|
|
|
92
|
+
// --- Request bodies ---
|
|
93
|
+
//
|
|
94
|
+
// fetch() takes these bodies as they are and derives their Content-Type from
|
|
95
|
+
// the value: the multipart boundary for FormData, `blob.type` for a Blob or a
|
|
96
|
+
// File, x-www-form-urlencoded for URLSearchParams. JSON-encoding them turned a
|
|
97
|
+
// FormData upload into the string '{}', and a forced Content-Type loses the
|
|
98
|
+
// multipart boundary. Detection reads the toStringTag, so a value from another
|
|
99
|
+
// realm (an iframe) counts too. Anything else is JSON-encoded, as before.
|
|
100
|
+
const PASS_THROUGH_TAGS = ['FormData', 'Blob', 'File', 'URLSearchParams', 'ReadableStream', 'ArrayBuffer']
|
|
101
|
+
|
|
102
|
+
const isPassThroughBody = (value) =>
|
|
103
|
+
value !== null && typeof value === 'object' &&
|
|
104
|
+
(ArrayBuffer.isView(value) || PASS_THROUGH_TAGS.includes(typeTag(value)))
|
|
105
|
+
|
|
106
|
+
// --- Headers ---
|
|
107
|
+
//
|
|
108
|
+
// Header names are case-insensitive, object keys are not: spreading
|
|
109
|
+
// `{ authorization }` over `{ Authorization }` kept BOTH keys, and fetch()
|
|
110
|
+
// joined them into one "Bearer a, Bearer b" value. Merge by lower-cased name
|
|
111
|
+
// instead — a later source wins and keeps its own spelling, and a null or
|
|
112
|
+
// undefined value removes the header. A source may be any fetch HeadersInit:
|
|
113
|
+
// a plain object, a Headers instance or an array of [name, value] pairs.
|
|
114
|
+
const headerEntries = (source) => {
|
|
115
|
+
if (Array.isArray(source)) return source
|
|
116
|
+
if (typeof source.entries === 'function') return source.entries()
|
|
117
|
+
return Object.entries(source)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const mergeHeaders = (...sources) => {
|
|
121
|
+
const merged = {}
|
|
122
|
+
const keyOf = new Map()
|
|
123
|
+
for (const source of sources) {
|
|
124
|
+
if (!source) continue
|
|
125
|
+
for (const [name, value] of headerEntries(source)) {
|
|
126
|
+
const lower = name.toLowerCase()
|
|
127
|
+
if (keyOf.has(lower)) delete merged[keyOf.get(lower)]
|
|
128
|
+
if (value === undefined || value === null) {
|
|
129
|
+
keyOf.delete(lower)
|
|
130
|
+
continue
|
|
131
|
+
}
|
|
132
|
+
keyOf.set(lower, name)
|
|
133
|
+
merged[name] = value
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return merged
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const JSON_TYPE = { 'Content-Type': 'application/json' }
|
|
140
|
+
const NO_TYPE = { 'Content-Type': undefined }
|
|
141
|
+
|
|
26
142
|
export const setup = async ({ url, headers, auth, fetchOptions }) => {
|
|
27
143
|
if (!url) throw new Error('@symbo.ls/fetch rest: url is required')
|
|
28
144
|
return restAdapter(url, headers, auth, fetchOptions)
|
|
@@ -31,16 +147,32 @@ export const setup = async ({ url, headers, auth, fetchOptions }) => {
|
|
|
31
147
|
export const restAdapter = (baseUrl, defaultHeaders = {}, authConfig, defaultFetchOptions = {}) => {
|
|
32
148
|
let token = authConfig?.token || null
|
|
33
149
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
150
|
+
// Precedence, lowest first: the configured headers, the adapter's token, the
|
|
151
|
+
// body's Content-Type, then the call's own `headers` — so one call can send
|
|
152
|
+
// its own Bearer token (a per-user token) or its own Content-Type.
|
|
153
|
+
const tokenHeader = () => token ? { Authorization: `Bearer ${token}` } : null
|
|
39
154
|
|
|
40
|
-
const
|
|
155
|
+
const getHeaders = (extra) => mergeHeaders(defaultHeaders, tokenHeader(), extra)
|
|
41
156
|
|
|
42
157
|
const getFetchOptions = (opts) => ({ ...defaultFetchOptions, ...opts })
|
|
43
158
|
|
|
159
|
+
// Options for a request that carries a body. A pass-through body gets no
|
|
160
|
+
// Content-Type from the adapter (NO_TYPE also drops a configured one), so
|
|
161
|
+
// fetch() sets the right one; an explicit per-call Content-Type still wins.
|
|
162
|
+
const withBody = (method, body, extra) => {
|
|
163
|
+
if (!isPassThroughBody(body)) {
|
|
164
|
+
return getFetchOptions({
|
|
165
|
+
method,
|
|
166
|
+
headers: mergeHeaders(defaultHeaders, tokenHeader(), JSON_TYPE, extra),
|
|
167
|
+
body: JSON.stringify(body)
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
const opts = { method, headers: mergeHeaders(defaultHeaders, tokenHeader(), NO_TYPE, extra), body }
|
|
171
|
+
// fetch() rejects a streamed request body unless it is half duplex.
|
|
172
|
+
if (typeTag(body) === 'ReadableStream') opts.duplex = 'half'
|
|
173
|
+
return getFetchOptions(opts)
|
|
174
|
+
}
|
|
175
|
+
|
|
44
176
|
const resolveUrl = (from, base) => {
|
|
45
177
|
const b = base || baseUrl
|
|
46
178
|
if (from && (from.startsWith('http://') || from.startsWith('https://'))) return from
|
|
@@ -67,11 +199,10 @@ export const restAdapter = (baseUrl, defaultHeaders = {}, authConfig, defaultFet
|
|
|
67
199
|
|
|
68
200
|
signIn: async (credentials) => {
|
|
69
201
|
if (!authConfig?.signInUrl) throw new Error('rest: auth.signInUrl not configured')
|
|
70
|
-
const result = await request(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}))
|
|
202
|
+
const result = await request(
|
|
203
|
+
resolveUrl(authConfig.signInUrl, authConfig.baseUrl),
|
|
204
|
+
withBody('POST', credentials)
|
|
205
|
+
)
|
|
75
206
|
if (result.data?.token) token = result.data.token
|
|
76
207
|
return result
|
|
77
208
|
},
|
|
@@ -87,8 +218,9 @@ export const restAdapter = (baseUrl, defaultHeaders = {}, authConfig, defaultFet
|
|
|
87
218
|
return { error: null }
|
|
88
219
|
},
|
|
89
220
|
|
|
90
|
-
// CRUD
|
|
91
|
-
|
|
221
|
+
// CRUD — every call takes `headers` (merged over the configured ones),
|
|
222
|
+
// `baseUrl` and `responseType`.
|
|
223
|
+
select: ({ from, params, select, limit, offset, order, single, headers, baseUrl: fromBase, responseType }) => {
|
|
92
224
|
const allParams = { ...params }
|
|
93
225
|
if (select) allParams.select = select
|
|
94
226
|
if (limit) allParams.limit = limit
|
|
@@ -105,32 +237,21 @@ export const restAdapter = (baseUrl, defaultHeaders = {}, authConfig, defaultFet
|
|
|
105
237
|
}
|
|
106
238
|
return request(
|
|
107
239
|
buildUrl(fromBase || baseUrl, from || '', allParams),
|
|
108
|
-
getFetchOptions({ headers: getHeaders(headers) })
|
|
240
|
+
getFetchOptions({ headers: getHeaders(headers) }),
|
|
241
|
+
responseType
|
|
109
242
|
)
|
|
110
243
|
},
|
|
111
244
|
|
|
112
|
-
rpc: ({ from, params, headers, baseUrl: fromBase }) =>
|
|
113
|
-
request(resolveUrl(`rpc/${from}`, fromBase),
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
insert: ({ from, data, headers, baseUrl: fromBase }) =>
|
|
120
|
-
request(resolveUrl(from, fromBase), getFetchOptions({
|
|
121
|
-
method: 'POST',
|
|
122
|
-
headers: getJsonHeaders(headers),
|
|
123
|
-
body: JSON.stringify(data)
|
|
124
|
-
})),
|
|
125
|
-
|
|
126
|
-
update: ({ from, data, params, method, headers, baseUrl: fromBase }) => {
|
|
245
|
+
rpc: ({ from, params, headers, baseUrl: fromBase, responseType }) =>
|
|
246
|
+
request(resolveUrl(`rpc/${from}`, fromBase), withBody('POST', params, headers), responseType),
|
|
247
|
+
|
|
248
|
+
insert: ({ from, data, headers, baseUrl: fromBase, responseType }) =>
|
|
249
|
+
request(resolveUrl(from, fromBase), withBody('POST', data, headers), responseType),
|
|
250
|
+
|
|
251
|
+
update: ({ from, data, params, method, headers, baseUrl: fromBase, responseType }) => {
|
|
127
252
|
const id = params?.id || data?.id
|
|
128
253
|
const path = id ? `${from}/${id}` : from
|
|
129
|
-
return request(resolveUrl(path, fromBase),
|
|
130
|
-
method: method || 'PATCH',
|
|
131
|
-
headers: getJsonHeaders(headers),
|
|
132
|
-
body: JSON.stringify(data)
|
|
133
|
-
}))
|
|
254
|
+
return request(resolveUrl(path, fromBase), withBody(method || 'PATCH', data, headers), responseType)
|
|
134
255
|
},
|
|
135
256
|
|
|
136
257
|
// Create-or-replace by id. PUT-by-id is the REST-idiomatic upsert (unlike
|
|
@@ -138,23 +259,19 @@ export const restAdapter = (baseUrl, defaultHeaders = {}, authConfig, defaultFet
|
|
|
138
259
|
// treat "PUT to an id that doesn't exist yet" as a create). Callers that
|
|
139
260
|
// need different upsert semantics for their backend can still pass
|
|
140
261
|
// `method` to override.
|
|
141
|
-
upsert: ({ from, data, params, method, headers, baseUrl: fromBase }) => {
|
|
262
|
+
upsert: ({ from, data, params, method, headers, baseUrl: fromBase, responseType }) => {
|
|
142
263
|
const id = params?.id || data?.id
|
|
143
264
|
const path = id ? `${from}/${id}` : from
|
|
144
|
-
return request(resolveUrl(path, fromBase),
|
|
145
|
-
method: method || 'PUT',
|
|
146
|
-
headers: getJsonHeaders(headers),
|
|
147
|
-
body: JSON.stringify(data)
|
|
148
|
-
}))
|
|
265
|
+
return request(resolveUrl(path, fromBase), withBody(method || 'PUT', data, headers), responseType)
|
|
149
266
|
},
|
|
150
267
|
|
|
151
|
-
delete: ({ from, params, headers, baseUrl: fromBase }) => {
|
|
268
|
+
delete: ({ from, params, headers, baseUrl: fromBase, responseType }) => {
|
|
152
269
|
const id = params?.id
|
|
153
270
|
const path = id ? `${from}/${id}` : from
|
|
154
271
|
return request(resolveUrl(path, fromBase), getFetchOptions({
|
|
155
272
|
method: 'DELETE',
|
|
156
273
|
headers: getHeaders(headers)
|
|
157
|
-
}))
|
|
274
|
+
}), responseType)
|
|
158
275
|
}
|
|
159
276
|
}
|
|
160
277
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var $=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var N=(t,e)=>{for(var n in e)$(t,n,{get:e[n],enumerable:!0})},_=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of B(e))!R.call(t,r)&&r!==n&&$(t,r,{get:()=>e[r],enumerable:!(o=x(e,r))||o.enumerable});return t};var H=t=>_($({},"__esModule",{value:!0}),t);var M={};N(M,{restAdapter:()=>j,setup:()=>G});module.exports=H(M);const J=(t,e,n)=>{const o=e&&!e.startsWith("/")?"/":"",r=new URL(`${t}${o}${e}`);if(n)for(const l in n){const u=n[l];u!=null&&r.searchParams.set(l,typeof u=="object"?JSON.stringify(u):u)}return r.toString()},P=t=>Object.prototype.toString.call(t).slice(8,-1),E=["auto","json","text","blob","arrayBuffer","stream","response"],m={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},I=t=>{const e=t.headers.get("content-type");return e&&e.includes("json")?t.json():t.text()},L=async t=>{const e=await t.text(),n=t.headers.get("content-type");if(e&&n&&n.includes("json"))try{return JSON.parse(e)}catch{}return e},A=(t,e)=>t?.message||t?.error||e.statusText,p=async(t,e,n)=>{const o=n??"auto";if(!E.includes(o))throw new TypeError(`@symbo.ls/fetch rest: unknown responseType "${o}" \u2014 use one of: ${E.join(", ")}`);const r=await globalThis.fetch(t,e);if(o==="auto"){const l=await I(r);return{data:l,error:r.ok?null:A(l,r),status:r.status}}if(!r.ok){const l=await L(o==="response"?r.clone():r);return{data:o==="response"?r:l,error:A(l,r)||`HTTP ${r.status}`,status:r.status}}return{data:await m[o](r),error:null,status:r.status}},W=["FormData","Blob","File","URLSearchParams","ReadableStream","ArrayBuffer"],D=t=>t!==null&&typeof t=="object"&&(ArrayBuffer.isView(t)||W.includes(P(t))),F=t=>Array.isArray(t)?t:typeof t.entries=="function"?t.entries():Object.entries(t),O=(...t)=>{const e={},n=new Map;for(const o of t)if(o)for(const[r,l]of F(o)){const u=r.toLowerCase();if(n.has(u)&&delete e[n.get(u)],l==null){n.delete(u);continue}n.set(u,r),e[r]=l}return e},Y={"Content-Type":"application/json"},q={"Content-Type":void 0},G=async({url:t,headers:e,auth:n,fetchOptions:o})=>{if(!t)throw new Error("@symbo.ls/fetch rest: url is required");return j(t,e,n,o)},j=(t,e={},n,o={})=>{let r=n?.token||null;const l=()=>r?{Authorization:`Bearer ${r}`}:null,u=s=>O(e,l(),s),w=s=>({...o,...s}),S=(s,a,i)=>{if(!D(a))return w({method:s,headers:O(e,l(),Y,i),body:JSON.stringify(a)});const c={method:s,headers:O(e,l(),q,i),body:a};return P(a)==="ReadableStream"&&(c.duplex="half"),w(c)},f=(s,a)=>{const i=a||t;if(s&&(s.startsWith("http://")||s.startsWith("https://")))return s;const c=s&&!s.startsWith("/")?"/":"";return`${i}${c}${s||""}`};return{name:"rest",setToken:s=>{r=s},getSession:async()=>{if(!n?.sessionUrl)return r?{token:r}:null;const s=await p(f(n.sessionUrl,n.baseUrl),w({headers:u()}));return s.error?null:s.data},signIn:async s=>{if(!n?.signInUrl)throw new Error("rest: auth.signInUrl not configured");const a=await p(f(n.signInUrl,n.baseUrl),S("POST",s));return a.data?.token&&(r=a.data.token),a},signOut:async()=>(n?.signOutUrl&&await p(f(n.signOutUrl,n.baseUrl),w({method:"POST",headers:u()})),r=null,{error:null}),select:({from:s,params:a,select:i,limit:c,offset:y,order:d,single:b,headers:T,baseUrl:U,responseType:k})=>{const h={...a};return i&&(h.select=i),c&&(h.limit=c),y&&(h.offset=y),b&&(h.single=!0),d&&(typeof d=="string"?h.order=d:Array.isArray(d)?h.order=d.map(g=>`${g.by}:${g.asc===!1?"desc":"asc"}`).join(","):d.by&&(h.order=`${d.by}:${d.asc===!1?"desc":"asc"}`)),p(J(U||t,s||"",h),w({headers:u(T)}),k)},rpc:({from:s,params:a,headers:i,baseUrl:c,responseType:y})=>p(f(`rpc/${s}`,c),S("POST",a,i),y),insert:({from:s,data:a,headers:i,baseUrl:c,responseType:y})=>p(f(s,c),S("POST",a,i),y),update:({from:s,data:a,params:i,method:c,headers:y,baseUrl:d,responseType:b})=>{const T=i?.id||a?.id,U=T?`${s}/${T}`:s;return p(f(U,d),S(c||"PATCH",a,y),b)},upsert:({from:s,data:a,params:i,method:c,headers:y,baseUrl:d,responseType:b})=>{const T=i?.id||a?.id,U=T?`${s}/${T}`:s;return p(f(U,d),S(c||"PUT",a,y),b)},delete:({from:s,params:a,headers:i,baseUrl:c,responseType:y})=>{const d=a?.id,b=d?`${s}/${d}`:s;return p(f(b,c),w({method:"DELETE",headers:u(i)}),y)}}};
|
package/dist/cjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var It=Object.create;var ot=Object.defineProperty;var qt=Object.getOwnPropertyDescriptor;var Ut=Object.getOwnPropertyNames;var zt=Object.getPrototypeOf,jt=Object.prototype.hasOwnProperty;var Gt=(e,t)=>{for(var r in t)ot(e,r,{get:t[r],enumerable:!0})},Ft=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Ut(t))!jt.call(e,i)&&i!==r&&ot(e,i,{get:()=>t[i],enumerable:!(s=qt(t,i))||s.enumerable});return e};var Et=(e,t,r)=>(r=e!=null?It(zt(e)):{},Ft(t||!e||!e.__esModule?ot(r,"default",{value:e,enumerable:!0}):r,e)),Qt=e=>Ft(ot({},"__esModule",{value:!0}),e);var ne={};Gt(ne,{createAdapter:()=>Jt,default:()=>ae,executeFetch:()=>Tt,fetchPlugin:()=>ie,initAdapterAuth:()=>ut,parseDuration:()=>G,queryClient:()=>oe,registerAdapter:()=>Bt,resolveDb:()=>$t});module.exports=Qt(ne);var n=require("@symbo.ls/utils");const Wt=["select","rpc","insert","update","upsert","delete","subscribe"],xt={rest:()=>import("./adapters/rest.js"),local:()=>import("./adapters/local.js")},it=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),Y=(()=>{if(typeof globalThis<"u"&&globalThis[it])return globalThis[it];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,it,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[it]}catch{}return e})(),at=Symbol.for("@symbo.ls/fetch:PENDING_ADAPTERS"),gt=(()=>{if(typeof globalThis<"u"&&globalThis[at])return globalThis[at];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,at,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[at]}catch{}return e})(),Kt=5e3,Yt=e=>new Promise(t=>{if(Y[e])return t(Y[e]);const r=gt[e]||=[];let s=!1;const i=()=>{s||(s=!0,t(Y[e]||null))};r.push(i),setTimeout(i,Kt)}),Bt=(e,t)=>{Y[e]=t;const r=gt[e];if(r&&r.length){gt[e]=[];for(const s of r)s()}},Jt=e=>{const t={};for(const r of Wt)e[r]&&(t[r]=e[r]);return t.name=e.name||"custom",t},$t=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 i=Y[s]||xt[s];if(!i&&(i=await Yt(s),!i))throw new Error(`Unknown db adapter: "${s}". Use registerAdapter() for adapters with optional deps.`);const o=await i();if(!o||typeof o.setup!="function")throw new Error(`Adapter "${s}" loader returned a module without a setup() function. Got keys: [${Object.keys(o||{}).join(", ")}]. Likely a bundler chunk-resolution issue.`);return o.setup(r)},G=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,N=new Map,z=new Map,Ht=(e,t,r)=>{if(e.cache?.key)return e.cache.key;const s=Zt(e.params),i=r?`${r}:`:"",o=`${e.from}:${e.method}:${i}${JSON.stringify(s||"")}`;return t?`${o}:${t}`:o},B=e=>v.get(e)||null,J=(e,t,r)=>{const s=v.get(e),i={data:t,error:r,time:Date.now(),stale:!1};v.set(e,i);const o=N.get(e);if(o)for(const a of o)(0,n.isFunction)(a)&&a(i);return i},H=e=>{if(e){const t=v.get(e);t&&(t.stale=!0);return}for(const[,t]of v)t.stale=!0},nt=e=>{if(e){v.delete(e);return}v.clear()},le=(e,t)=>(N.has(e)||N.set(e,new Set),N.get(e).add(t),()=>{const r=N.get(e);r&&(r.delete(t),r.size===0&&N.delete(e))}),St=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,n.isString)(e)?{staleTime:G(e),gcTime:3e5}:{staleTime:G(e.stale||e.staleTime)||6e4,gcTime:G(e.gc||e.gcTime||e.expire)||3e5,key:e.key};let ft=null;const Vt=()=>{ft||(ft=setInterval(()=>{const e=Date.now();for(const[t,r]of v){const s=N.get(t);!(s&&s.size>0)&&e-r.time>(r.gcTime||3e5)&&v.delete(t)}},3e4),ft.unref&&ft.unref())};Vt();const Dt=3,wt=e=>Math.min(1e3*2**e,3e4),Ct=e=>{const t=e.retry;return t===!1?{count:0}:t===!0||t===void 0?{count:Dt,delay:wt}:typeof t=="number"?{count:t,delay:wt}:{count:t.count??Dt,delay:(0,n.isFunction)(t.delay)?t.delay:typeof t.delay=="number"?()=>t.delay:wt}},Pt=async(e,t)=>{const{count:r,delay:s}=t;let i;for(let o=0;o<=r;o++)try{const a=await e();if(a?.error){if(i=a.error,o<r){const l=(0,n.isFunction)(s)?s(o,i):s;await new Promise(f=>setTimeout(f,l));continue}return a}return a}catch(a){if(i=a,o<r){const l=(0,n.isFunction)(s)?s(o,a):s;await new Promise(f=>setTimeout(f,l));continue}throw a}return{data:null,error:i}},j={focus:new Set,online:new Set};let At=!1;const Xt=()=>{if(At||typeof window>"u")return;At=!0;const e=()=>{for(const r of j.focus)r()},t=()=>{for(const r of j.online)r()};window.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&e()}),window.addEventListener("focus",e),window.addEventListener("online",t)},Lt=(e,t)=>{const r=t.__ref;if(e===!0)return{from:r.__state||t.key,method:"select",query:!0,on:"create"};if((0,n.isString)(e))return{from:e,method:"select",query:!0,on:"create"};if((0,n.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},Zt=e=>(!e||(0,n.isFunction)(e),e),ct=(e,t)=>{const r=e?.state?.root||t?.state?.root;if(r?.lang)return r.lang},bt=(e,t)=>{const s=(e?.state?.root||t?.state?.root)?.__fetchScope;return s?String(s):void 0},kt=(e,t,r)=>{let s;if(!e)s=void 0;else if((0,n.isFunction)(e))s=e(t,t.state);else{s={};for(const i in e){const o=e[i];s[i]=(0,n.isFunction)(o)?o(t,t.state):o}}return s},ut=async(e,t)=>{if(!e||e.__authInitialized||(e.__authInitialized=!0,!e.getSession))return;const r=(s,i)=>{const o=t.state?.root;o?.update&&o.update({auth:{user:s,session:i,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,i)=>{r(i?.user||null,i)})},vt=async(e,t)=>{if((0,n.isFunction)(e.select))return e.auth!==!1&&await ut(e,t),e;if(e.__resolved)return e.auth!==!1&&await ut(e.__resolved,t),e.__resolved;if(e.__resolving)return e.__resolving;e.__resolving=$t(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 ut(r,t),r):null},D=(e,t,...r)=>{const s=(0,n.isFunction)(e[t])?e[t]:null;s&&s.call(e,...r,e,e.state,e.context)},P=(e,t,r,...s)=>{const i=e&&(0,n.isFunction)(e[r])?e[r]:null;i&&i.call(t,...s,t,t.state,t.context)},V=e=>{const t={},r=e.node;if(!r)return t;if(r.tagName==="FORM"){const i=new FormData(r);for(const[o,a]of i.entries())t[o]=a;return t}const s=r.querySelectorAll("input, textarea, select");for(let i=0;i<s.length;i++){const o=s[i],a=o.name||o.getAttribute("name");a&&(o.type==="checkbox"?t[a]=o.checked:o.type==="file"?t[a]=o.files:t[a]=o.value)}return t},I=(e,t,r,s={})=>{const i=r&&r.startsWith("~/"),o=i&&e.state?.root||e.state;if(o?.update)if(i){const a=r.slice(2);t&&typeof t=="object"&&!Array.isArray(t)&&a in t?o.update(t,{preventFetch:!0,...s}):o.update({[a]:t},{preventFetch:!0,...s})}else{const a=r?{[r]:t}:t;o.update(a,{preventFetch:!0,...s})}},k=(e,t)=>{const r=e?.__ref;r&&(r.__fetchStatus=t,r.__fetching=t.isFetching,r.__fetchError=t.error)},R=async(e,t,r,s={})=>{const i=r?.fetch;if(!i||!t||!t.__ref)return;const o=t.__ref,a=bt(t,r);(!o.__fetchScopeOwner||o.__fetchScopeOwner.scope!==a)&&(o.__fetchScopeOwner={scope:a});const l=o.__fetchScopeOwner,f=()=>t.__ref===o&&o.__fetchScopeOwner===l&&bt(t,r)===a;if(e.enabled===!1||(0,n.isFunction)(e.enabled)&&!e.enabled(t,t.state)||e.skip===!0||(0,n.isFunction)(e.skip)&&e.skip(t,t.state))return;const h=await vt(i,r);if(!h||!f())return;const{from:g,method:S,query:X,params:lt,cache:Z,transform:T,single:dt,auth:Q,fields:q,as:A,limit:$,offset:w,order:W,headers:C,baseUrl:x,page:p,cursor:L,getNextPageParam:K,getPreviousPageParam:tt,infinite:et,placeholderData:F,initialData:E,select:m,keepPreviousData:O}=e;let U=(0,n.isString)(m)?m:void 0;if(X&&(0,n.isFunction)(t.getQuery)){const d=t.getQuery(h.name||"paths");d&&(U=d.select||d.length&&d.join(",")||U)}const rt=kt(lt,t,r),st=St(Z),Mt=Ct(e),ht=ct(t,r),Ot=ht?`:${ht}`:"",Rt=a?`${a}:`:"",_=st?Z?.key||`${g}:${S}:${Rt}${JSON.stringify(rt||"")}${et?":infinite":""}${p?":p"+JSON.stringify(p):""}${Ot}`:null;if(!o.__fetchInitialized&&_&&(o.__fetchInitialized=!0,E!==void 0)){const d=(0,n.isFunction)(E)?E():E;J(_,d,null)}if((S==="select"||S==="rpc")&&_&&st){const d=B(_);if(d&&!d.error){const u=Date.now()-d.time,y=d.stale||u>(st.staleTime||0);let c=d.data;if((0,n.isFunction)(m)&&(c=m(c,t,t.state)),T&&(c=T(c,t,t.state)),!f())return;if(I(t,c,A),!y){k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"});return}}else if(F!==void 0){const u=(0,n.isFunction)(F)?F(t,t.state):F;u!==void 0&&I(t,u,A)}}if(_&&z.has(_)&&!s.force){const d=z.get(_);try{const u=await Promise.race([d,new Promise((y,c)=>setTimeout(()=>c("DEDUP_TIMEOUT"),15e3))]);if(!f())return;if(u?.data!==void 0){let y=u.data;if((0,n.isFunction)(m)&&(y=m(y,t,t.state)),T&&(y=T(y,t,t.state)),!f())return;I(t,y,A),D(t,"onFetchComplete",y),P(e,t,"onFetchComplete",y)}}catch{if(!f())return}return}const Nt=!B(_)?.data;k(t,{isFetching:!0,isLoading:Nt,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),D(t,"onFetchStart"),P(e,t,"onFetchStart");const M=r?.analyze?.emitNetwork,pt=M?typeof performance<"u"?performance.now():Date.now():0;M&&M({phase:"start",mode:"query",from:g,method:S,cacheKey:_,lang:ht});const _t=Pt(async()=>{if(!f())return;if(Q!==!1&&h.auth!==!1&&h.getSession){const c=await h.getSession();if(!f())return;if(Q===!0&&!c){const b={message:"Not authenticated"};return k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:b,status:"error",fetchStatus:"idle"}),D(t,"onFetchError",b),P(e,t,"onFetchError",b),{data:null,error:b}}}const d=h[S];if(!(0,n.isFunction)(d))return{data:null,error:{message:`Method "${S}" not found on adapter`}};const u={from:g,select:U,params:rt,single:dt,limit:$,offset:w,order:W,headers:C,baseUrl:x},y=ct(t,r);if(y&&(u.headers={...u.headers,"Accept-Language":y}),p!==void 0){if((0,n.isObject)(p))p.offset!==void 0&&(u.offset=p.offset),p.limit!==void 0&&(u.limit=p.limit),p.cursor!==void 0&&(u.params={...u.params,cursor:p.cursor});else if(typeof p=="number"){const c=e.pageSize||$||20;u.offset=(p-1)*c,u.limit=c}}if(L!==void 0&&(u.params={...u.params,cursor:L}),S==="insert"||S==="update"||S==="upsert"){let c;if(q===!0||e.on==="submit")c=V(t);else if((0,n.isArray)(q)){const b=V(t);c={};for(const yt of q)c[yt]=b[yt]}else t.state?.parse?c=t.state.parse():(0,n.isObject)(t.state)&&(c={...t.state});T&&(c=T(c,t,t.state)),u.data=c}if(S==="rpc"){let c=rt;if(e.on==="submit"){const b=V(t);c=e.transformParams?e.transformParams(b,t,t.state):b}u.params=c}if(S==="subscribe"){const c=h.subscribe({from:g,params:rt,on:e.subscribeOn},(b,yt,ce)=>{f()&&(I(t,b,A),D(t,"onFetchComplete",b),P(e,t,"onFetchComplete",b))});return f()?(o.__unsubscribe=c,{data:null,error:null,subscribed:!0}):((0,n.isFunction)(c)&&c(),{data:null,error:null,subscribed:!0})}return d(u)},Mt);_&&z.set(_,_t);try{const d=await _t;if(!f()||d?.subscribed)return;const{data:u,error:y}=d||{};if(y){_&&J(_,null,y),k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:y,status:"error",fetchStatus:"idle"}),D(t,"onFetchError",y),P(e,t,"onFetchError",y),M&&M({phase:"error",mode:"query",from:g,method:S,cacheKey:_,error:y.message||y,durationMs:(typeof performance<"u"?performance.now():Date.now())-pt});return}if(u!==void 0){if((S==="select"||S==="rpc")&&_){const b=J(_,u,null);b.gcTime=st?.gcTime||3e5}let c=u;if(et&&(0,n.isArray)(u)&&(o.__pages||(o.__pages=[]),s.direction==="previous"?o.__pages.unshift(u):o.__pages.push(u),c=o.__pages.flat(),K&&(o.__nextPageParam=K(u,o.__pages),o.__hasNextPage=o.__nextPageParam!=null),tt&&(o.__prevPageParam=tt(u,o.__pages),o.__hasPreviousPage=o.__prevPageParam!=null)),(0,n.isFunction)(m)&&(c=m(c,t,t.state)),T&&(c=T(c,t,t.state)),!f())return;(!O||c!==void 0)&&I(t,c,A),k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),D(t,"onFetchComplete",c),P(e,t,"onFetchComplete",c),M&&M({phase:"success",mode:"query",ok:!0,from:g,method:S,cacheKey:_,durationMs:(typeof performance<"u"?performance.now():Date.now())-pt})}}catch(d){if(!f())return;k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:d,status:"error",fetchStatus:"idle"}),D(t,"onFetchError",d),P(e,t,"onFetchError",d),M&&M({phase:"error",mode:"query",from:g,method:S,cacheKey:_,error:d.message||String(d),durationMs:(typeof performance<"u"?performance.now():Date.now())-pt})}finally{_&&z.get(_)===_t&&z.delete(_)}},te=(e,t,r)=>{const s=e.on,i=t.__ref;i.__fetchListeners||(i.__fetchListeners=[]);const o=e.__runner||R;if(s==="submit"){const a=f=>{f.preventDefault(),o(e,t,r)},l=t.node;l&&(l.addEventListener("submit",a),i.__fetchListeners.push(()=>l.removeEventListener("submit",a)))}else if(s==="click"){const a=()=>o(e,t,r),l=t.node;l&&(l.addEventListener("click",a),i.__fetchListeners.push(()=>l.removeEventListener("click",a)))}else s==="stateChange"&&(i.__fetchOnStateChange=()=>o(e,t,r))},ee=(e,t,r)=>{const s=t.__ref;s.__fetchCleanups||(s.__fetchCleanups=[]),Xt();const i=e.refetchInterval;if(i){const o=typeof i=="number"?i:G(i);if(o>0){const a=setInterval(()=>{(e.refetchIntervalInBackground||typeof document>"u"||document.visibilityState==="visible")&&R(e,t,r,{force:!0})},o);s.__fetchCleanups.push(()=>clearInterval(a))}}if(e.refetchOnWindowFocus!==!1){const o=()=>{const a=ct(t,r),l=bt(t,r),f=Ht(e,a,l),h=B(f),g=St(e.cache);(!h||h.stale||Date.now()-h.time>(g?.staleTime||0))&&R(e,t,r,{force:!0})};j.focus.add(o),s.__fetchCleanups.push(()=>j.focus.delete(o))}if(e.refetchOnReconnect!==!1){const o=()=>R(e,t,r,{force:!0});j.online.add(o),s.__fetchCleanups.push(()=>j.online.delete(o))}},re=(e,t,r)=>{if(!t.optimistic)return null;const s=e.__ref,i=t.as,o=e.state?.parse?e.state.parse():(0,n.isObject)(e.state)?{...e.state}:e.state;s.__optimisticSnapshot=o;const a=(0,n.isFunction)(t.optimistic)?t.optimistic(r,o,e):t.optimistic;return a!==void 0&&I(e,a,i),o},mt=(e,t)=>{const r=e.__ref,s=r.__optimisticSnapshot;s!==void 0&&(I(e,s,t.as),delete r.__optimisticSnapshot)},se=async(e,t,r)=>{const s=r?.fetch;if(!s)return;const i=await vt(s,r);if(!i)return;const o=t.__ref,{method:a,from:l,fields:f,transform:h,as:g,on:S,auth:X,headers:lt,baseUrl:Z,invalidates:T,optimistic:dt,onMutate:Q,onSuccess:q,onError:A,onSettled:$}=e;let w;if(f===!0||S==="submit")w=V(t);else if((0,n.isArray)(f)){const p=V(t);w={};for(const L of f)w[L]=p[L]}else t.state?.parse?w=t.state.parse():(0,n.isObject)(t.state)&&(w={...t.state});h&&(w=h(w,t,t.state)),(0,n.isFunction)(Q)&&Q(w,t,t.state);const W=dt?re(t,e,w):null;o.__fetching=!0,k(t,{isFetching:!0,isLoading:!1,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),D(t,"onFetchStart"),P(e,t,"onFetchStart");const C=r?.analyze?.emitNetwork,x=C?typeof performance<"u"?performance.now():Date.now():0;C&&C({phase:"start",mode:"mutation",from:l,method:a});try{if(X!==!1&&i.auth!==!1&&i.getSession){const m=await i.getSession();if(X===!0&&!m){W!==void 0&&mt(t,e);const O={message:"Not authenticated"};D(t,"onFetchError",O),P(e,t,"onFetchError",O);return}}const p=i[a];if(!(0,n.isFunction)(p))return;const L={from:l,data:w,headers:lt,baseUrl:Z};e.params&&(L.params=kt(e.params,t,r));const K=ct(t,r);K&&(L.headers={...L.headers,"Accept-Language":K});const tt=Ct(e),et=await Pt(()=>p(L),tt),{data:F,error:E}=et||{};if(E){W!==void 0&&mt(t,e),k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:E,status:"error",fetchStatus:"idle"}),D(t,"onFetchError",E),(0,n.isFunction)(A)&&A(E,w,t),(0,n.isFunction)($)&&$(null,E,w,t),C&&C({phase:"error",mode:"mutation",from:l,method:a,error:E.message||String(E),durationMs:(typeof performance<"u"?performance.now():Date.now())-x});return}if(delete o.__optimisticSnapshot,F!==void 0){const m=g?{[g]:F}:F;t.state?.update&&t.state.update(m,{preventFetch:!0})}if(k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),D(t,"onFetchComplete",F),P(e,t,"onFetchComplete",F),(0,n.isFunction)(q)&&q(F,w,t),(0,n.isFunction)($)&&$(F,null,w,t),C&&C({phase:"success",mode:"mutation",ok:!0,from:l,method:a,durationMs:(typeof performance<"u"?performance.now():Date.now())-x}),T){const m=(0,n.isArray)(T)?T:[T];for(const O of m)if(O===!0||O==="*")for(const[U]of v)U.startsWith(l+":")&&H(U);else H(O)}}catch(p){W!==void 0&&mt(t,e),k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:p,status:"error",fetchStatus:"idle"}),D(t,"onFetchError",p),P(e,t,"onFetchError",p),(0,n.isFunction)(A)&&A(p,w,t),(0,n.isFunction)($)&&$(null,p,w,t),C&&C({phase:"error",mode:"mutation",from:l,method:a,error:p.message||String(p),durationMs:(typeof performance<"u"?performance.now():Date.now())-x})}finally{o.__fetching=!1}},Tt=(e,t,r,s)=>{if(!e||!s?.fetch)return;const o=(0,n.exec)(e,t);if(!o)return;const a=(0,n.isArray)(o)?o.map(f=>Lt((0,n.exec)(f,t),t)).filter(Boolean):[Lt(o,t)].filter(Boolean);for(const f of a){const h=f.method==="insert"||f.method==="update"||f.method==="upsert"||f.method==="delete",g=h?se:R;f.on==="create"?g(f,t,s):Promise.resolve().then(()=>{te({...f,__runner:g},t,s)}),!h&&f.on==="create"&&(f.refetchInterval||f.refetchOnWindowFocus!==!1||f.refetchOnReconnect!==!1)&&ee(f,t,s)}const l=t.__ref;l.refetch=f=>{for(const h of a)R(h,t,s,{force:!0,...f})},l.fetchNextPage=()=>{const f=a[0];if(!f||!f.infinite)return;const h=l.__nextPageParam;if(h==null)return;const g={...f,cursor:h};R(g,t,s,{direction:"next",force:!0})},l.fetchPreviousPage=()=>{const f=a[0];if(!f||!f.infinite)return;const h=l.__prevPageParam;if(h==null)return;const g={...f,cursor:h};R(g,t,s,{direction:"previous",force:!0})}},oe={invalidateQueries:e=>{if(!e){H();return}if((0,n.isString)(e))for(const[t]of v)(t.startsWith(e)||t.includes(e))&&H(t);else if((0,n.isArray)(e)){const t=e.join(":");for(const[r]of v)r.includes(t)&&H(r)}},removeQueries:e=>{if(!e){nt();return}if((0,n.isString)(e))for(const[t]of v)(t.startsWith(e)||t.includes(e))&&nt(t)},getQueryData:e=>B(e)?.data??void 0,setQueryData:(e,t)=>{const r=B(e),s=(0,n.isFunction)(t)?t(r?.data):t;J(e,s,null)},prefetchQuery:async(e,t)=>{const r=t?.fetch;if(!r)return;const s=await vt(r,t);if(!s)return;const i=e.cache?.key||`${e.from}:${e.method||"select"}:${JSON.stringify(e.params||"")}`,o=s[e.method||"select"];if(!(0,n.isFunction)(o))return;const a=await o({from:e.from,params:e.params,limit:e.limit,offset:e.offset,order:e.order,single:e.single});if(a?.data!==void 0&&!a?.error){const l=J(i,a.data,null);l.gcTime=St(e.cache)?.gcTime||3e5}return a},getCache:()=>v,clear:()=>nt(),dropNonLang:e=>{if(!e)return;const t=`:${e}`;for(const[r]of v)r.match(/:([a-z]{2,3})$/i)&&(r.endsWith(t)||nt(r))}},ie={name:"fetch",create(e){const t=e.fetch;t&&(e.parent||z.clear(),Tt(t,e,e.state,e.context))}};var ae=Tt;
|
|
1
|
+
"use strict";var zt=Object.create;var at=Object.defineProperty;var jt=Object.getOwnPropertyDescriptor;var Bt=Object.getOwnPropertyNames;var Gt=Object.getPrototypeOf,Qt=Object.prototype.hasOwnProperty;var Wt=(t,e)=>{for(var s in e)at(t,s,{get:e[s],enumerable:!0})},Ct=(t,e,s,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Bt(e))!Qt.call(t,o)&&o!==s&&at(t,o,{get:()=>e[o],enumerable:!(r=jt(e,o))||r.enumerable});return t};var Pt=(t,e,s)=>(s=t!=null?zt(Gt(t)):{},Ct(e||!t||!t.__esModule?at(s,"default",{value:t,enumerable:!0}):s,t)),Yt=t=>Ct(at({},"__esModule",{value:!0}),t);var le={};Wt(le,{createAdapter:()=>Xt,default:()=>ue,executeFetch:()=>Dt,fetchPlugin:()=>ce,initAdapterAuth:()=>ht,parseDuration:()=>Y,queryClient:()=>fe,registerAdapter:()=>Ht,resolveDb:()=>Mt});module.exports=Yt(le);var f=require("@symbo.ls/utils");const xt=["select","rpc","insert","update","upsert","delete","subscribe"],Kt={rest:()=>import("./adapters/rest.js"),local:()=>import("./adapters/local.js")},ft=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),V=(()=>{if(typeof globalThis<"u"&&globalThis[ft])return globalThis[ft];const t={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,ft,{value:t,writable:!1,configurable:!1,enumerable:!1}),globalThis[ft]}catch{}return t})(),ct=Symbol.for("@symbo.ls/fetch:PENDING_ADAPTERS"),St=(()=>{if(typeof globalThis<"u"&&globalThis[ct])return globalThis[ct];const t={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,ct,{value:t,writable:!1,configurable:!1,enumerable:!1}),globalThis[ct]}catch{}return t})(),Jt=5e3,Vt=t=>new Promise(e=>{if(V[t])return e(V[t]);const s=St[t]||=[];let r=!1;const o=()=>{r||(r=!0,e(V[t]||null))};s.push(o),setTimeout(o,Jt)}),Ht=(t,e)=>{V[t]=e;const s=St[t];if(s&&s.length){St[t]=[];for(const r of s)r()}},Xt=t=>{const e={};for(const s of xt)t[s]&&(e[s]=t[s]);return e.name=t.name||"custom",e},Mt=async t=>{if(!t)return null;if(typeof t.select=="function")return t;const{adapter:e,...s}=t,r=typeof e=="string"?e:typeof t=="string"?t:null;if(!r)return null;let o=V[r]||Kt[r];if(!o&&(o=await Vt(r),!o))throw new Error(`Unknown db adapter: "${r}". Use registerAdapter() for adapters with optional deps.`);const n=await o();if(!n||typeof n.setup!="function")throw new Error(`Adapter "${r}" loader returned a module without a setup() function. Got keys: [${Object.keys(n||{}).join(", ")}]. Likely a bundler chunk-resolution issue.`);return n.setup(s)},Y=t=>{if(!t)return 0;if(typeof t=="number")return t;const e=t.match(/^(\d+)(ms|s|m|h)$/);if(!e)return 0;const s=parseInt(e[1]),r=e[2];return r==="ms"?s:r==="s"?s*1e3:r==="m"?s*6e4:r==="h"?s*36e5:0},T=new Map,U=new Map,Q=new Map,Zt=(t,e,s)=>{if(t.cache?.key)return t.cache.key;const r=se(t.params),o=s?`${s}:`:"",n=`${t.from}:${t.method}:${o}${JSON.stringify(r||"")}`;return e?`${n}:${e}`:n},H=t=>T.get(t)||null,X=(t,e,s)=>{const r=T.get(t),o={data:e,error:s,time:Date.now(),stale:!1};T.set(t,o);const n=U.get(t);if(n)for(const a of n)(0,f.isFunction)(a)&&a(o);return o},Z=t=>{if(t){const e=T.get(t);e&&(e.stale=!0);return}for(const[,e]of T)e.stale=!0},ut=t=>{if(t){T.delete(t);return}T.clear()},_e=(t,e)=>(U.has(t)||U.set(t,new Set),U.get(t).add(e),()=>{const s=U.get(t);s&&(s.delete(e),s.size===0&&U.delete(t))}),bt=t=>!t&&t!==!1?{staleTime:6e4,gcTime:3e5}:t===!1?null:t===!0?{staleTime:6e4,gcTime:3e5}:typeof t=="number"?{staleTime:t,gcTime:Math.max(t*5,3e5)}:(0,f.isString)(t)?{staleTime:Y(t),gcTime:3e5}:{staleTime:Y(t.stale||t.staleTime)||6e4,gcTime:Y(t.gc||t.gcTime||t.expire)||3e5,key:t.key};let lt=null;const te=()=>{lt||(lt=setInterval(()=>{const t=Date.now();for(const[e,s]of T){const r=U.get(e);!(r&&r.size>0)&&t-s.time>(s.gcTime||3e5)&&T.delete(e)}},3e4),lt.unref&<.unref())};te();const At=3,wt=t=>Math.min(1e3*2**t,3e4),Lt=t=>{const e=t.retry;return e===!1?{count:0}:e===!0||e===void 0?{count:At,delay:wt}:typeof e=="number"?{count:e,delay:wt}:{count:e.count??At,delay:(0,f.isFunction)(e.delay)?e.delay:typeof e.delay=="number"?()=>e.delay:wt}},Ot=async(t,e)=>{const{count:s,delay:r}=e;let o;for(let n=0;n<=s;n++)try{const a=await t();if(a?.error){if(o=a.error,n<s){const u=(0,f.isFunction)(r)?r(n,o):r;await new Promise(i=>setTimeout(i,u));continue}return a}return a}catch(a){if(o=a,n<s){const u=(0,f.isFunction)(r)?r(n,a):r;await new Promise(i=>setTimeout(i,u));continue}throw a}return{data:null,error:o}},W={focus:new Set,online:new Set};let Rt=!1;const ee=()=>{if(Rt||typeof window>"u")return;Rt=!0;const t=()=>{for(const s of W.focus)s()},e=()=>{for(const s of W.online)s()};window.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&t()}),window.addEventListener("focus",t),window.addEventListener("online",e)},kt=(t,e)=>{const s=e.__ref;if(t===!0)return{from:s.__state||e.key,method:"select",query:!0,on:"create"};if((0,f.isString)(t))return{from:t,method:"select",query:!0,on:"create"};if((0,f.isObject)(t)){const r={...t};return r.from=r.from||s.__state||e.key,r.method=r.method||"select",r.on=r.on||"create",r.query===void 0&&(r.query=!0),r}return null},se=t=>(!t||(0,f.isFunction)(t),t),dt=(t,e)=>{const s=t?.state?.root||e?.state?.root;if(s?.lang)return s.lang},Tt=(t,e)=>{const r=(t?.state?.root||e?.state?.root)?.__fetchScope;return r?String(r):void 0},$t=(t,e,s)=>{let r;if(!t)r=void 0;else if((0,f.isFunction)(t))r=t(e,e.state);else{r={};for(const o in t){const n=t[o];r[o]=(0,f.isFunction)(n)?n(e,e.state):n}}return r},ht=async(t,e)=>{if(!t||t.__authInitialized||(t.__authInitialized=!0,!t.getSession))return;const s=(r,o)=>{const n=e.state?.root;n?.update&&n.update({auth:{user:r,session:o,loading:!1}})};try{const r=await t.getSession();s(r?.user||null,r)}catch(r){console.warn("[fetch] Failed to restore auth session:",r.message)}t.onAuthStateChange&&t.onAuthStateChange((r,o)=>{s(o?.user||null,o)})},mt=async(t,e)=>{if((0,f.isFunction)(t.select))return t.auth!==!1&&await ht(t,e),t;if(t.__resolved)return t.auth!==!1&&await ht(t.__resolved,e),t.__resolved;if(t.__resolving)return t.__resolving;t.__resolving=Mt(t);const s=await t.__resolving;return delete t.__resolving,s?(s.auth=t.auth,s.url=t.url,s.key=t.key,t.__resolved=s,e.fetch=s,t.auth!==!1&&await ht(s,e),s):null},E=(t,e,...s)=>{const r=(0,f.isFunction)(t[e])?t[e]:null;r&&r.call(t,...s,t,t.state,t.context)},A=(t,e,s,...r)=>{const o=t&&(0,f.isFunction)(t[s])?t[s]:null;o&&o.call(e,...r,e,e.state,e.context)},tt=t=>{const e={},s=t.node;if(!s)return e;if(s.tagName==="FORM"){const o=new FormData(s);for(const[n,a]of o.entries())e[n]=a;return e}const r=s.querySelectorAll("input, textarea, select");for(let o=0;o<r.length;o++){const n=r[o],a=n.name||n.getAttribute("name");a&&(n.type==="checkbox"?e[a]=n.checked:n.type==="file"?e[a]=n.files:e[a]=n.value)}return e},vt=t=>t.responseType==="stream"||t.responseType==="response",re=["Blob","File","ArrayBuffer","ReadableStream","Response"],Ft=t=>t!==null&&typeof t=="object"&&(ArrayBuffer.isView(t)||re.includes(Object.prototype.toString.call(t).slice(8,-1))),q=(t,e,s,r={})=>{if(!s&&Ft(e))return;const o=s&&s.startsWith("~/"),n=o&&t.state?.root||t.state;if(n?.update)if(o){const a=s.slice(2);e&&typeof e=="object"&&!Array.isArray(e)&&!Ft(e)&&a in e?n.update(e,{preventFetch:!0,...r}):n.update({[a]:e},{preventFetch:!0,...r})}else{const a=s?{[s]:e}:e;n.update(a,{preventFetch:!0,...r})}},L=(t,e)=>{const s=t?.__ref;s&&(s.__fetchStatus=e,s.__fetching=e.isFetching,s.__fetchError=e.error)},N=async(t,e,s,r={})=>{const o=s?.fetch;if(!o||!e||!e.__ref)return;const n=e.__ref,a=Tt(e,s);(!n.__fetchScopeOwner||n.__fetchScopeOwner.scope!==a)&&(n.__fetchScopeOwner={scope:a});const u=n.__fetchScopeOwner,i=()=>e.__ref===n&&n.__fetchScopeOwner===u&&Tt(e,s)===a;if(t.enabled===!1||(0,f.isFunction)(t.enabled)&&!t.enabled(e,e.state)||t.skip===!0||(0,f.isFunction)(t.skip)&&t.skip(e,e.state))return;const h=await mt(o,s);if(!h||!i())return;const{from:g,method:S,query:R,params:x,cache:et,transform:D,single:z,auth:st,fields:j,as:k,limit:I,offset:$,order:b,headers:K,baseUrl:C,responseType:B,page:p,cursor:P,getNextPageParam:J,getPreviousPageParam:rt,infinite:nt,placeholderData:v,initialData:F,select:m,keepPreviousData:M}=t;let G=(0,f.isString)(m)?m:void 0;if(R&&(0,f.isFunction)(e.getQuery)){const d=e.getQuery(h.name||"paths");d&&(G=d.select||d.length&&d.join(",")||G)}const ot=$t(x,e,s),it=vt(t)?null:bt(et),Nt=Lt(t),pt=dt(e,s),It=pt?`:${pt}`:"",Ut=a?`${a}:`:"",_=it?et?.key||`${g}:${S}:${Ut}${JSON.stringify(ot||"")}${nt?":infinite":""}${p?":p"+JSON.stringify(p):""}${It}`:null;if(!n.__fetchInitialized&&_&&(n.__fetchInitialized=!0,F!==void 0)){const d=(0,f.isFunction)(F)?F():F;X(_,d,null)}if((S==="select"||S==="rpc")&&_&&it){const d=H(_);if(d&&!d.error){const l=Date.now()-d.time,y=d.stale||l>(it.staleTime||0);let c=d.data;if((0,f.isFunction)(m)&&(c=m(c,e,e.state)),D&&(c=D(c,e,e.state)),!i())return;if(q(e,c,k),!y){L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"});return}}else if(v!==void 0){const l=(0,f.isFunction)(v)?v(e,e.state):v;l!==void 0&&q(e,l,k)}}if(_&&Q.has(_)&&!r.force){const d=Q.get(_);try{const l=await Promise.race([d,new Promise((y,c)=>setTimeout(()=>c("DEDUP_TIMEOUT"),15e3))]);if(!i())return;if(l?.data!==void 0){let y=l.data;if((0,f.isFunction)(m)&&(y=m(y,e,e.state)),D&&(y=D(y,e,e.state)),!i())return;q(e,y,k),E(e,"onFetchComplete",y),A(t,e,"onFetchComplete",y)}}catch{if(!i())return}return}const qt=!H(_)?.data;L(e,{isFetching:!0,isLoading:qt,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),E(e,"onFetchStart"),A(t,e,"onFetchStart");const O=s?.analyze?.emitNetwork,_t=O?typeof performance<"u"?performance.now():Date.now():0;O&&O({phase:"start",mode:"query",from:g,method:S,cacheKey:_,lang:pt});const yt=Ot(async()=>{if(!i())return;if(st!==!1&&h.auth!==!1&&h.getSession){const c=await h.getSession();if(!i())return;if(st===!0&&!c){const w={message:"Not authenticated"};return L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:w,status:"error",fetchStatus:"idle"}),E(e,"onFetchError",w),A(t,e,"onFetchError",w),{data:null,error:w}}}const d=h[S];if(!(0,f.isFunction)(d))return{data:null,error:{message:`Method "${S}" not found on adapter`}};const l={from:g,select:G,params:ot,single:z,limit:I,offset:$,order:b,headers:K,baseUrl:C};B!==void 0&&(l.responseType=B);const y=dt(e,s);if(y&&(l.headers={...l.headers,"Accept-Language":y}),p!==void 0){if((0,f.isObject)(p))p.offset!==void 0&&(l.offset=p.offset),p.limit!==void 0&&(l.limit=p.limit),p.cursor!==void 0&&(l.params={...l.params,cursor:p.cursor});else if(typeof p=="number"){const c=t.pageSize||I||20;l.offset=(p-1)*c,l.limit=c}}if(P!==void 0&&(l.params={...l.params,cursor:P}),S==="insert"||S==="update"||S==="upsert"){let c;if(j===!0||t.on==="submit")c=tt(e);else if((0,f.isArray)(j)){const w=tt(e);c={};for(const gt of j)c[gt]=w[gt]}else e.state?.parse?c=e.state.parse():(0,f.isObject)(e.state)&&(c={...e.state});D&&(c=D(c,e,e.state)),l.data=c}if(S==="rpc"){let c=ot;if(t.on==="submit"){const w=tt(e);c=t.transformParams?t.transformParams(w,e,e.state):w}l.params=c}if(S==="subscribe"){const c=h.subscribe({from:g,params:ot,on:t.subscribeOn},(w,gt,he)=>{i()&&(q(e,w,k),E(e,"onFetchComplete",w),A(t,e,"onFetchComplete",w))});return i()?(n.__unsubscribe=c,{data:null,error:null,subscribed:!0}):((0,f.isFunction)(c)&&c(),{data:null,error:null,subscribed:!0})}return d(l)},Nt);_&&Q.set(_,yt);try{const d=await yt;if(!i()||d?.subscribed)return;const{data:l,error:y}=d||{};if(y){_&&X(_,null,y),L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:y,status:"error",fetchStatus:"idle"}),E(e,"onFetchError",y),A(t,e,"onFetchError",y),O&&O({phase:"error",mode:"query",from:g,method:S,cacheKey:_,error:y.message||y,durationMs:(typeof performance<"u"?performance.now():Date.now())-_t});return}if(l!==void 0){if((S==="select"||S==="rpc")&&_){const w=X(_,l,null);w.gcTime=it?.gcTime||3e5}let c=l;if(nt&&(0,f.isArray)(l)&&(n.__pages||(n.__pages=[]),r.direction==="previous"?n.__pages.unshift(l):n.__pages.push(l),c=n.__pages.flat(),J&&(n.__nextPageParam=J(l,n.__pages),n.__hasNextPage=n.__nextPageParam!=null),rt&&(n.__prevPageParam=rt(l,n.__pages),n.__hasPreviousPage=n.__prevPageParam!=null)),(0,f.isFunction)(m)&&(c=m(c,e,e.state)),D&&(c=D(c,e,e.state)),!i())return;(!M||c!==void 0)&&q(e,c,k),L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),E(e,"onFetchComplete",c),A(t,e,"onFetchComplete",c),O&&O({phase:"success",mode:"query",ok:!0,from:g,method:S,cacheKey:_,durationMs:(typeof performance<"u"?performance.now():Date.now())-_t})}}catch(d){if(!i())return;L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:d,status:"error",fetchStatus:"idle"}),E(e,"onFetchError",d),A(t,e,"onFetchError",d),O&&O({phase:"error",mode:"query",from:g,method:S,cacheKey:_,error:d.message||String(d),durationMs:(typeof performance<"u"?performance.now():Date.now())-_t})}finally{_&&Q.get(_)===yt&&Q.delete(_)}},ne=(t,e,s)=>{const r=t.on,o=e.__ref;o.__fetchListeners||(o.__fetchListeners=[]);const n=t.__runner||N;if(r==="submit"){const a=i=>{i.preventDefault(),n(t,e,s)},u=e.node;u&&(u.addEventListener("submit",a),o.__fetchListeners.push(()=>u.removeEventListener("submit",a)))}else if(r==="click"){const a=()=>n(t,e,s),u=e.node;u&&(u.addEventListener("click",a),o.__fetchListeners.push(()=>u.removeEventListener("click",a)))}else r==="stateChange"&&(o.__fetchOnStateChange=()=>n(t,e,s))},oe=(t,e,s)=>{const r=e.__ref;r.__fetchCleanups||(r.__fetchCleanups=[]),ee();const o=t.refetchInterval;if(o){const i=typeof o=="number"?o:Y(o);if(i>0){const h=setInterval(()=>{(t.refetchIntervalInBackground||typeof document>"u"||document.visibilityState==="visible")&&N(t,e,s,{force:!0})},i);r.__fetchCleanups.push(()=>clearInterval(h))}}const n=vt(t),a=t.refetchOnWindowFocus===void 0?!n:t.refetchOnWindowFocus!==!1,u=t.refetchOnReconnect===void 0?!n:t.refetchOnReconnect!==!1;if(a){const i=()=>{const h=dt(e,s),g=Tt(e,s),S=Zt(t,h,g),R=H(S),x=bt(t.cache);(!R||R.stale||Date.now()-R.time>(x?.staleTime||0))&&N(t,e,s,{force:!0})};W.focus.add(i),r.__fetchCleanups.push(()=>W.focus.delete(i))}if(u){const i=()=>N(t,e,s,{force:!0});W.online.add(i),r.__fetchCleanups.push(()=>W.online.delete(i))}},ie=(t,e,s)=>{if(!e.optimistic)return null;const r=t.__ref,o=e.as,n=t.state?.parse?t.state.parse():(0,f.isObject)(t.state)?{...t.state}:t.state;r.__optimisticSnapshot=n;const a=(0,f.isFunction)(e.optimistic)?e.optimistic(s,n,t):e.optimistic;return a!==void 0&&q(t,a,o),n},Et=(t,e)=>{const s=t.__ref,r=s.__optimisticSnapshot;r!==void 0&&(q(t,r,e.as),delete s.__optimisticSnapshot)},ae=async(t,e,s)=>{const r=s?.fetch;if(!r)return;const o=await mt(r,s);if(!o)return;const n=e.__ref,{method:a,from:u,fields:i,transform:h,as:g,on:S,auth:R,headers:x,baseUrl:et,responseType:D,invalidates:z,optimistic:st,onMutate:j,onSuccess:k,onError:I,onSettled:$}=t;let b;if(i===!0||S==="submit")b=tt(e);else if((0,f.isArray)(i)){const p=tt(e);b={};for(const P of i)b[P]=p[P]}else e.state?.parse?b=e.state.parse():(0,f.isObject)(e.state)&&(b={...e.state});h&&(b=h(b,e,e.state)),(0,f.isFunction)(j)&&j(b,e,e.state);const K=st?ie(e,t,b):null;n.__fetching=!0,L(e,{isFetching:!0,isLoading:!1,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),E(e,"onFetchStart"),A(t,e,"onFetchStart");const C=s?.analyze?.emitNetwork,B=C?typeof performance<"u"?performance.now():Date.now():0;C&&C({phase:"start",mode:"mutation",from:u,method:a});try{if(R!==!1&&o.auth!==!1&&o.getSession){const m=await o.getSession();if(R===!0&&!m){K!==void 0&&Et(e,t);const M={message:"Not authenticated"};E(e,"onFetchError",M),A(t,e,"onFetchError",M);return}}const p=o[a];if(!(0,f.isFunction)(p))return;const P={from:u,data:b,headers:x,baseUrl:et};D!==void 0&&(P.responseType=D),t.params&&(P.params=$t(t.params,e,s));const J=dt(e,s);J&&(P.headers={...P.headers,"Accept-Language":J});const rt=Lt(t),nt=await Ot(()=>p(P),rt),{data:v,error:F}=nt||{};if(F){K!==void 0&&Et(e,t),L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:F,status:"error",fetchStatus:"idle"}),E(e,"onFetchError",F),(0,f.isFunction)(I)&&I(F,b,e),(0,f.isFunction)($)&&$(null,F,b,e),C&&C({phase:"error",mode:"mutation",from:u,method:a,error:F.message||String(F),durationMs:(typeof performance<"u"?performance.now():Date.now())-B});return}if(delete n.__optimisticSnapshot,v!==void 0&&(g||!Ft(v))){const m=g?{[g]:v}:v;e.state?.update&&e.state.update(m,{preventFetch:!0})}if(L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),E(e,"onFetchComplete",v),A(t,e,"onFetchComplete",v),(0,f.isFunction)(k)&&k(v,b,e),(0,f.isFunction)($)&&$(v,null,b,e),C&&C({phase:"success",mode:"mutation",ok:!0,from:u,method:a,durationMs:(typeof performance<"u"?performance.now():Date.now())-B}),z){const m=(0,f.isArray)(z)?z:[z];for(const M of m)if(M===!0||M==="*")for(const[G]of T)G.startsWith(u+":")&&Z(G);else Z(M)}}catch(p){K!==void 0&&Et(e,t),L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:p,status:"error",fetchStatus:"idle"}),E(e,"onFetchError",p),A(t,e,"onFetchError",p),(0,f.isFunction)(I)&&I(p,b,e),(0,f.isFunction)($)&&$(null,p,b,e),C&&C({phase:"error",mode:"mutation",from:u,method:a,error:p.message||String(p),durationMs:(typeof performance<"u"?performance.now():Date.now())-B})}finally{n.__fetching=!1}},Dt=(t,e,s,r)=>{if(!t||!r?.fetch)return;const n=(0,f.exec)(t,e);if(!n)return;const a=(0,f.isArray)(n)?n.map(i=>kt((0,f.exec)(i,e),e)).filter(Boolean):[kt(n,e)].filter(Boolean);for(const i of a){const h=i.method==="insert"||i.method==="update"||i.method==="upsert"||i.method==="delete",g=h?ae:N;i.on==="create"?g(i,e,r):Promise.resolve().then(()=>{ne({...i,__runner:g},e,r)}),!h&&i.on==="create"&&(i.refetchInterval||i.refetchOnWindowFocus!==!1||i.refetchOnReconnect!==!1)&&oe(i,e,r)}const u=e.__ref;u.refetch=i=>{for(const h of a)N(h,e,r,{force:!0,...i})},u.fetchNextPage=()=>{const i=a[0];if(!i||!i.infinite)return;const h=u.__nextPageParam;if(h==null)return;const g={...i,cursor:h};N(g,e,r,{direction:"next",force:!0})},u.fetchPreviousPage=()=>{const i=a[0];if(!i||!i.infinite)return;const h=u.__prevPageParam;if(h==null)return;const g={...i,cursor:h};N(g,e,r,{direction:"previous",force:!0})}},fe={invalidateQueries:t=>{if(!t){Z();return}if((0,f.isString)(t))for(const[e]of T)(e.startsWith(t)||e.includes(t))&&Z(e);else if((0,f.isArray)(t)){const e=t.join(":");for(const[s]of T)s.includes(e)&&Z(s)}},removeQueries:t=>{if(!t){ut();return}if((0,f.isString)(t))for(const[e]of T)(e.startsWith(t)||e.includes(t))&&ut(e)},getQueryData:t=>H(t)?.data??void 0,setQueryData:(t,e)=>{const s=H(t),r=(0,f.isFunction)(e)?e(s?.data):e;X(t,r,null)},prefetchQuery:async(t,e)=>{const s=e?.fetch;if(!s)return;const r=await mt(s,e);if(!r)return;const o=t.cache?.key||`${t.from}:${t.method||"select"}:${JSON.stringify(t.params||"")}`,n=r[t.method||"select"];if(!(0,f.isFunction)(n))return;const a={from:t.from,params:t.params,limit:t.limit,offset:t.offset,order:t.order,single:t.single,headers:t.headers,baseUrl:t.baseUrl};t.responseType!==void 0&&(a.responseType=t.responseType);const u=await n(a);if(u?.data!==void 0&&!u?.error&&!vt(t)){const i=X(o,u.data,null);i.gcTime=bt(t.cache)?.gcTime||3e5}return u},getCache:()=>T,clear:()=>ut(),dropNonLang:t=>{if(!t)return;const e=`:${t}`;for(const[s]of T)s.match(/:([a-z]{2,3})$/i)&&(s.endsWith(e)||ut(s))}},ce={name:"fetch",create(t){const e=t.fetch;e&&(t.parent||Q.clear(),Dt(e,t,t.state,t.context))}};var ue=Dt;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const j=(t,r,n)=>{const c=r&&!r.startsWith("/")?"/":"",s=new URL(`${t}${c}${r}`);if(n)for(const l in n){const u=n[l];u!=null&&s.searchParams.set(l,typeof u=="object"?JSON.stringify(u):u)}return s.toString()},g=t=>Object.prototype.toString.call(t).slice(8,-1),P=["auto","json","text","blob","arrayBuffer","stream","response"],k={json:async t=>{const r=await t.text();return r?JSON.parse(r):null},text:t=>t.text(),blob:t=>t.blob(),arrayBuffer:t=>t.arrayBuffer(),stream:t=>t.body,response:t=>t},x=t=>{const r=t.headers.get("content-type");return r&&r.includes("json")?t.json():t.text()},B=async t=>{const r=await t.text(),n=t.headers.get("content-type");if(r&&n&&n.includes("json"))try{return JSON.parse(r)}catch{}return r},E=(t,r)=>t?.message||t?.error||r.statusText,p=async(t,r,n)=>{const c=n??"auto";if(!P.includes(c))throw new TypeError(`@symbo.ls/fetch rest: unknown responseType "${c}" \u2014 use one of: ${P.join(", ")}`);const s=await globalThis.fetch(t,r);if(c==="auto"){const l=await x(s);return{data:l,error:s.ok?null:E(l,s),status:s.status}}if(!s.ok){const l=await B(c==="response"?s.clone():s);return{data:c==="response"?s:l,error:E(l,s)||`HTTP ${s.status}`,status:s.status}}return{data:await k[c](s),error:null,status:s.status}},R=["FormData","Blob","File","URLSearchParams","ReadableStream","ArrayBuffer"],N=t=>t!==null&&typeof t=="object"&&(ArrayBuffer.isView(t)||R.includes(g(t))),_=t=>Array.isArray(t)?t:typeof t.entries=="function"?t.entries():Object.entries(t),$=(...t)=>{const r={},n=new Map;for(const c of t)if(c)for(const[s,l]of _(c)){const u=s.toLowerCase();if(n.has(u)&&delete r[n.get(u)],l==null){n.delete(u);continue}n.set(u,s),r[s]=l}return r},H={"Content-Type":"application/json"},J={"Content-Type":void 0},L=async({url:t,headers:r,auth:n,fetchOptions:c})=>{if(!t)throw new Error("@symbo.ls/fetch rest: url is required");return m(t,r,n,c)},m=(t,r={},n,c={})=>{let s=n?.token||null;const l=()=>s?{Authorization:`Bearer ${s}`}:null,u=e=>$(r,l(),e),w=e=>({...c,...e}),S=(e,a,o)=>{if(!N(a))return w({method:e,headers:$(r,l(),H,o),body:JSON.stringify(a)});const i={method:e,headers:$(r,l(),J,o),body:a};return g(a)==="ReadableStream"&&(i.duplex="half"),w(i)},f=(e,a)=>{const o=a||t;if(e&&(e.startsWith("http://")||e.startsWith("https://")))return e;const i=e&&!e.startsWith("/")?"/":"";return`${o}${i}${e||""}`};return{name:"rest",setToken:e=>{s=e},getSession:async()=>{if(!n?.sessionUrl)return s?{token:s}:null;const e=await p(f(n.sessionUrl,n.baseUrl),w({headers:u()}));return e.error?null:e.data},signIn:async e=>{if(!n?.signInUrl)throw new Error("rest: auth.signInUrl not configured");const a=await p(f(n.signInUrl,n.baseUrl),S("POST",e));return a.data?.token&&(s=a.data.token),a},signOut:async()=>(n?.signOutUrl&&await p(f(n.signOutUrl,n.baseUrl),w({method:"POST",headers:u()})),s=null,{error:null}),select:({from:e,params:a,select:o,limit:i,offset:y,order:d,single:b,headers:T,baseUrl:U,responseType:A})=>{const h={...a};return o&&(h.select=o),i&&(h.limit=i),y&&(h.offset=y),b&&(h.single=!0),d&&(typeof d=="string"?h.order=d:Array.isArray(d)?h.order=d.map(O=>`${O.by}:${O.asc===!1?"desc":"asc"}`).join(","):d.by&&(h.order=`${d.by}:${d.asc===!1?"desc":"asc"}`)),p(j(U||t,e||"",h),w({headers:u(T)}),A)},rpc:({from:e,params:a,headers:o,baseUrl:i,responseType:y})=>p(f(`rpc/${e}`,i),S("POST",a,o),y),insert:({from:e,data:a,headers:o,baseUrl:i,responseType:y})=>p(f(e,i),S("POST",a,o),y),update:({from:e,data:a,params:o,method:i,headers:y,baseUrl:d,responseType:b})=>{const T=o?.id||a?.id,U=T?`${e}/${T}`:e;return p(f(U,d),S(i||"PATCH",a,y),b)},upsert:({from:e,data:a,params:o,method:i,headers:y,baseUrl:d,responseType:b})=>{const T=o?.id||a?.id,U=T?`${e}/${T}`:e;return p(f(U,d),S(i||"PUT",a,y),b)},delete:({from:e,params:a,headers:o,baseUrl:i,responseType:y})=>{const d=a?.id,b=d?`${e}/${d}`:e;return p(f(b,i),w({method:"DELETE",headers:u(o)}),y)}}};export{m as restAdapter,L as setup};
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isArray as z,isFunction as u,isObject as Y,isString as B,exec as Et}from"@symbo.ls/utils";const It=["select","rpc","insert","update","upsert","delete","subscribe"],qt={rest:()=>import("./adapters/rest.js"),local:()=>import("./adapters/local.js")},nt=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),J=(()=>{if(typeof globalThis<"u"&&globalThis[nt])return globalThis[nt];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,nt,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[nt]}catch{}return e})(),ft=Symbol.for("@symbo.ls/fetch:PENDING_ADAPTERS"),St=(()=>{if(typeof globalThis<"u"&&globalThis[ft])return globalThis[ft];const e={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,ft,{value:e,writable:!1,configurable:!1,enumerable:!1}),globalThis[ft]}catch{}return e})(),Ut=5e3,zt=e=>new Promise(t=>{if(J[e])return t(J[e]);const r=St[e]||=[];let s=!1;const i=()=>{s||(s=!0,t(J[e]||null))};r.push(i),setTimeout(i,Ut)}),Zt=(e,t)=>{J[e]=t;const r=St[e];if(r&&r.length){St[e]=[];for(const s of r)s()}},te=e=>{const t={};for(const r of It)e[r]&&(t[r]=e[r]);return t.name=e.name||"custom",t},jt=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 i=J[s]||qt[s];if(!i&&(i=await zt(s),!i))throw new Error(`Unknown db adapter: "${s}". Use registerAdapter() for adapters with optional deps.`);const o=await i();if(!o||typeof o.setup!="function")throw new Error(`Adapter "${s}" loader returned a module without a setup() function. Got keys: [${Object.keys(o||{}).join(", ")}]. Likely a bundler chunk-resolution issue.`);return o.setup(r)},H=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,N=new Map,j=new Map,Gt=(e,t,r)=>{if(e.cache?.key)return e.cache.key;const s=xt(e.params),i=r?`${r}:`:"",o=`${e.from}:${e.method}:${i}${JSON.stringify(s||"")}`;return t?`${o}:${t}`:o},V=e=>v.get(e)||null,X=(e,t,r)=>{const s=v.get(e),i={data:t,error:r,time:Date.now(),stale:!1};v.set(e,i);const o=N.get(e);if(o)for(const a of o)u(a)&&a(i);return i},Z=e=>{if(e){const t=v.get(e);t&&(t.stale=!0);return}for(const[,t]of v)t.stale=!0},ct=e=>{if(e){v.delete(e);return}v.clear()},ee=(e,t)=>(N.has(e)||N.set(e,new Set),N.get(e).add(t),()=>{const r=N.get(e);r&&(r.delete(t),r.size===0&&N.delete(e))}),wt=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)}:B(e)?{staleTime:H(e),gcTime:3e5}:{staleTime:H(e.stale||e.staleTime)||6e4,gcTime:H(e.gc||e.gcTime||e.expire)||3e5,key:e.key};let ut=null;const Qt=()=>{ut||(ut=setInterval(()=>{const e=Date.now();for(const[t,r]of v){const s=N.get(t);!(s&&s.size>0)&&e-r.time>(r.gcTime||3e5)&&v.delete(t)}},3e4),ut.unref&&ut.unref())};Qt();const Dt=3,bt=e=>Math.min(1e3*2**e,3e4),Ct=e=>{const t=e.retry;return t===!1?{count:0}:t===!0||t===void 0?{count:Dt,delay:bt}:typeof t=="number"?{count:t,delay:bt}:{count:t.count??Dt,delay:u(t.delay)?t.delay:typeof t.delay=="number"?()=>t.delay:bt}},Pt=async(e,t)=>{const{count:r,delay:s}=t;let i;for(let o=0;o<=r;o++)try{const a=await e();if(a?.error){if(i=a.error,o<r){const l=u(s)?s(o,i):s;await new Promise(n=>setTimeout(n,l));continue}return a}return a}catch(a){if(i=a,o<r){const l=u(s)?s(o,a):s;await new Promise(n=>setTimeout(n,l));continue}throw a}return{data:null,error:i}},G={focus:new Set,online:new Set};let At=!1;const Wt=()=>{if(At||typeof window>"u")return;At=!0;const e=()=>{for(const r of G.focus)r()},t=()=>{for(const r of G.online)r()};window.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&e()}),window.addEventListener("focus",e),window.addEventListener("online",t)},Lt=(e,t)=>{const r=t.__ref;if(e===!0)return{from:r.__state||t.key,method:"select",query:!0,on:"create"};if(B(e))return{from:e,method:"select",query:!0,on:"create"};if(Y(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},xt=e=>(!e||u(e),e),lt=(e,t)=>{const r=e?.state?.root||t?.state?.root;if(r?.lang)return r.lang},vt=(e,t)=>{const s=(e?.state?.root||t?.state?.root)?.__fetchScope;return s?String(s):void 0},kt=(e,t,r)=>{let s;if(!e)s=void 0;else if(u(e))s=e(t,t.state);else{s={};for(const i in e){const o=e[i];s[i]=u(o)?o(t,t.state):o}}return s},mt=async(e,t)=>{if(!e||e.__authInitialized||(e.__authInitialized=!0,!e.getSession))return;const r=(s,i)=>{const o=t.state?.root;o?.update&&o.update({auth:{user:s,session:i,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,i)=>{r(i?.user||null,i)})},Tt=async(e,t)=>{if(u(e.select))return e.auth!==!1&&await mt(e,t),e;if(e.__resolved)return e.auth!==!1&&await mt(e.__resolved,t),e.__resolved;if(e.__resolving)return e.__resolving;e.__resolving=jt(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 mt(r,t),r):null},D=(e,t,...r)=>{const s=u(e[t])?e[t]:null;s&&s.call(e,...r,e,e.state,e.context)},P=(e,t,r,...s)=>{const i=e&&u(e[r])?e[r]:null;i&&i.call(t,...s,t,t.state,t.context)},tt=e=>{const t={},r=e.node;if(!r)return t;if(r.tagName==="FORM"){const i=new FormData(r);for(const[o,a]of i.entries())t[o]=a;return t}const s=r.querySelectorAll("input, textarea, select");for(let i=0;i<s.length;i++){const o=s[i],a=o.name||o.getAttribute("name");a&&(o.type==="checkbox"?t[a]=o.checked:o.type==="file"?t[a]=o.files:t[a]=o.value)}return t},I=(e,t,r,s={})=>{const i=r&&r.startsWith("~/"),o=i&&e.state?.root||e.state;if(o?.update)if(i){const a=r.slice(2);t&&typeof t=="object"&&!Array.isArray(t)&&a in t?o.update(t,{preventFetch:!0,...s}):o.update({[a]:t},{preventFetch:!0,...s})}else{const a=r?{[r]:t}:t;o.update(a,{preventFetch:!0,...s})}},k=(e,t)=>{const r=e?.__ref;r&&(r.__fetchStatus=t,r.__fetching=t.isFetching,r.__fetchError=t.error)},R=async(e,t,r,s={})=>{const i=r?.fetch;if(!i||!t||!t.__ref)return;const o=t.__ref,a=vt(t,r);(!o.__fetchScopeOwner||o.__fetchScopeOwner.scope!==a)&&(o.__fetchScopeOwner={scope:a});const l=o.__fetchScopeOwner,n=()=>t.__ref===o&&o.__fetchScopeOwner===l&&vt(t,r)===a;if(e.enabled===!1||u(e.enabled)&&!e.enabled(t,t.state)||e.skip===!0||u(e.skip)&&e.skip(t,t.state))return;const h=await Tt(i,r);if(!h||!n())return;const{from:g,method:S,query:et,params:dt,cache:rt,transform:T,single:ht,auth:Q,fields:q,as:A,limit:$,offset:w,order:W,headers:C,baseUrl:x,page:p,cursor:L,getNextPageParam:K,getPreviousPageParam:st,infinite:ot,placeholderData:F,initialData:E,select:m,keepPreviousData:O}=e;let U=B(m)?m:void 0;if(et&&u(t.getQuery)){const d=t.getQuery(h.name||"paths");d&&(U=d.select||d.length&&d.join(",")||U)}const it=kt(dt,t,r),at=wt(rt),Mt=Ct(e),pt=lt(t,r),Ot=pt?`:${pt}`:"",Rt=a?`${a}:`:"",_=at?rt?.key||`${g}:${S}:${Rt}${JSON.stringify(it||"")}${ot?":infinite":""}${p?":p"+JSON.stringify(p):""}${Ot}`:null;if(!o.__fetchInitialized&&_&&(o.__fetchInitialized=!0,E!==void 0)){const d=u(E)?E():E;X(_,d,null)}if((S==="select"||S==="rpc")&&_&&at){const d=V(_);if(d&&!d.error){const c=Date.now()-d.time,y=d.stale||c>(at.staleTime||0);let f=d.data;if(u(m)&&(f=m(f,t,t.state)),T&&(f=T(f,t,t.state)),!n())return;if(I(t,f,A),!y){k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"});return}}else if(F!==void 0){const c=u(F)?F(t,t.state):F;c!==void 0&&I(t,c,A)}}if(_&&j.has(_)&&!s.force){const d=j.get(_);try{const c=await Promise.race([d,new Promise((y,f)=>setTimeout(()=>f("DEDUP_TIMEOUT"),15e3))]);if(!n())return;if(c?.data!==void 0){let y=c.data;if(u(m)&&(y=m(y,t,t.state)),T&&(y=T(y,t,t.state)),!n())return;I(t,y,A),D(t,"onFetchComplete",y),P(e,t,"onFetchComplete",y)}}catch{if(!n())return}return}const Nt=!V(_)?.data;k(t,{isFetching:!0,isLoading:Nt,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),D(t,"onFetchStart"),P(e,t,"onFetchStart");const M=r?.analyze?.emitNetwork,_t=M?typeof performance<"u"?performance.now():Date.now():0;M&&M({phase:"start",mode:"query",from:g,method:S,cacheKey:_,lang:pt});const yt=Pt(async()=>{if(!n())return;if(Q!==!1&&h.auth!==!1&&h.getSession){const f=await h.getSession();if(!n())return;if(Q===!0&&!f){const b={message:"Not authenticated"};return k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:b,status:"error",fetchStatus:"idle"}),D(t,"onFetchError",b),P(e,t,"onFetchError",b),{data:null,error:b}}}const d=h[S];if(!u(d))return{data:null,error:{message:`Method "${S}" not found on adapter`}};const c={from:g,select:U,params:it,single:ht,limit:$,offset:w,order:W,headers:C,baseUrl:x},y=lt(t,r);if(y&&(c.headers={...c.headers,"Accept-Language":y}),p!==void 0){if(Y(p))p.offset!==void 0&&(c.offset=p.offset),p.limit!==void 0&&(c.limit=p.limit),p.cursor!==void 0&&(c.params={...c.params,cursor:p.cursor});else if(typeof p=="number"){const f=e.pageSize||$||20;c.offset=(p-1)*f,c.limit=f}}if(L!==void 0&&(c.params={...c.params,cursor:L}),S==="insert"||S==="update"||S==="upsert"){let f;if(q===!0||e.on==="submit")f=tt(t);else if(z(q)){const b=tt(t);f={};for(const gt of q)f[gt]=b[gt]}else t.state?.parse?f=t.state.parse():Y(t.state)&&(f={...t.state});T&&(f=T(f,t,t.state)),c.data=f}if(S==="rpc"){let f=it;if(e.on==="submit"){const b=tt(t);f=e.transformParams?e.transformParams(b,t,t.state):b}c.params=f}if(S==="subscribe"){const f=h.subscribe({from:g,params:it,on:e.subscribeOn},(b,gt,Vt)=>{n()&&(I(t,b,A),D(t,"onFetchComplete",b),P(e,t,"onFetchComplete",b))});return n()?(o.__unsubscribe=f,{data:null,error:null,subscribed:!0}):(u(f)&&f(),{data:null,error:null,subscribed:!0})}return d(c)},Mt);_&&j.set(_,yt);try{const d=await yt;if(!n()||d?.subscribed)return;const{data:c,error:y}=d||{};if(y){_&&X(_,null,y),k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:y,status:"error",fetchStatus:"idle"}),D(t,"onFetchError",y),P(e,t,"onFetchError",y),M&&M({phase:"error",mode:"query",from:g,method:S,cacheKey:_,error:y.message||y,durationMs:(typeof performance<"u"?performance.now():Date.now())-_t});return}if(c!==void 0){if((S==="select"||S==="rpc")&&_){const b=X(_,c,null);b.gcTime=at?.gcTime||3e5}let f=c;if(ot&&z(c)&&(o.__pages||(o.__pages=[]),s.direction==="previous"?o.__pages.unshift(c):o.__pages.push(c),f=o.__pages.flat(),K&&(o.__nextPageParam=K(c,o.__pages),o.__hasNextPage=o.__nextPageParam!=null),st&&(o.__prevPageParam=st(c,o.__pages),o.__hasPreviousPage=o.__prevPageParam!=null)),u(m)&&(f=m(f,t,t.state)),T&&(f=T(f,t,t.state)),!n())return;(!O||f!==void 0)&&I(t,f,A),k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),D(t,"onFetchComplete",f),P(e,t,"onFetchComplete",f),M&&M({phase:"success",mode:"query",ok:!0,from:g,method:S,cacheKey:_,durationMs:(typeof performance<"u"?performance.now():Date.now())-_t})}}catch(d){if(!n())return;k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:d,status:"error",fetchStatus:"idle"}),D(t,"onFetchError",d),P(e,t,"onFetchError",d),M&&M({phase:"error",mode:"query",from:g,method:S,cacheKey:_,error:d.message||String(d),durationMs:(typeof performance<"u"?performance.now():Date.now())-_t})}finally{_&&j.get(_)===yt&&j.delete(_)}},Kt=(e,t,r)=>{const s=e.on,i=t.__ref;i.__fetchListeners||(i.__fetchListeners=[]);const o=e.__runner||R;if(s==="submit"){const a=n=>{n.preventDefault(),o(e,t,r)},l=t.node;l&&(l.addEventListener("submit",a),i.__fetchListeners.push(()=>l.removeEventListener("submit",a)))}else if(s==="click"){const a=()=>o(e,t,r),l=t.node;l&&(l.addEventListener("click",a),i.__fetchListeners.push(()=>l.removeEventListener("click",a)))}else s==="stateChange"&&(i.__fetchOnStateChange=()=>o(e,t,r))},Yt=(e,t,r)=>{const s=t.__ref;s.__fetchCleanups||(s.__fetchCleanups=[]),Wt();const i=e.refetchInterval;if(i){const o=typeof i=="number"?i:H(i);if(o>0){const a=setInterval(()=>{(e.refetchIntervalInBackground||typeof document>"u"||document.visibilityState==="visible")&&R(e,t,r,{force:!0})},o);s.__fetchCleanups.push(()=>clearInterval(a))}}if(e.refetchOnWindowFocus!==!1){const o=()=>{const a=lt(t,r),l=vt(t,r),n=Gt(e,a,l),h=V(n),g=wt(e.cache);(!h||h.stale||Date.now()-h.time>(g?.staleTime||0))&&R(e,t,r,{force:!0})};G.focus.add(o),s.__fetchCleanups.push(()=>G.focus.delete(o))}if(e.refetchOnReconnect!==!1){const o=()=>R(e,t,r,{force:!0});G.online.add(o),s.__fetchCleanups.push(()=>G.online.delete(o))}},Bt=(e,t,r)=>{if(!t.optimistic)return null;const s=e.__ref,i=t.as,o=e.state?.parse?e.state.parse():Y(e.state)?{...e.state}:e.state;s.__optimisticSnapshot=o;const a=u(t.optimistic)?t.optimistic(r,o,e):t.optimistic;return a!==void 0&&I(e,a,i),o},Ft=(e,t)=>{const r=e.__ref,s=r.__optimisticSnapshot;s!==void 0&&(I(e,s,t.as),delete r.__optimisticSnapshot)},Jt=async(e,t,r)=>{const s=r?.fetch;if(!s)return;const i=await Tt(s,r);if(!i)return;const o=t.__ref,{method:a,from:l,fields:n,transform:h,as:g,on:S,auth:et,headers:dt,baseUrl:rt,invalidates:T,optimistic:ht,onMutate:Q,onSuccess:q,onError:A,onSettled:$}=e;let w;if(n===!0||S==="submit")w=tt(t);else if(z(n)){const p=tt(t);w={};for(const L of n)w[L]=p[L]}else t.state?.parse?w=t.state.parse():Y(t.state)&&(w={...t.state});h&&(w=h(w,t,t.state)),u(Q)&&Q(w,t,t.state);const W=ht?Bt(t,e,w):null;o.__fetching=!0,k(t,{isFetching:!0,isLoading:!1,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),D(t,"onFetchStart"),P(e,t,"onFetchStart");const C=r?.analyze?.emitNetwork,x=C?typeof performance<"u"?performance.now():Date.now():0;C&&C({phase:"start",mode:"mutation",from:l,method:a});try{if(et!==!1&&i.auth!==!1&&i.getSession){const m=await i.getSession();if(et===!0&&!m){W!==void 0&&Ft(t,e);const O={message:"Not authenticated"};D(t,"onFetchError",O),P(e,t,"onFetchError",O);return}}const p=i[a];if(!u(p))return;const L={from:l,data:w,headers:dt,baseUrl:rt};e.params&&(L.params=kt(e.params,t,r));const K=lt(t,r);K&&(L.headers={...L.headers,"Accept-Language":K});const st=Ct(e),ot=await Pt(()=>p(L),st),{data:F,error:E}=ot||{};if(E){W!==void 0&&Ft(t,e),k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:E,status:"error",fetchStatus:"idle"}),D(t,"onFetchError",E),u(A)&&A(E,w,t),u($)&&$(null,E,w,t),C&&C({phase:"error",mode:"mutation",from:l,method:a,error:E.message||String(E),durationMs:(typeof performance<"u"?performance.now():Date.now())-x});return}if(delete o.__optimisticSnapshot,F!==void 0){const m=g?{[g]:F}:F;t.state?.update&&t.state.update(m,{preventFetch:!0})}if(k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),D(t,"onFetchComplete",F),P(e,t,"onFetchComplete",F),u(q)&&q(F,w,t),u($)&&$(F,null,w,t),C&&C({phase:"success",mode:"mutation",ok:!0,from:l,method:a,durationMs:(typeof performance<"u"?performance.now():Date.now())-x}),T){const m=z(T)?T:[T];for(const O of m)if(O===!0||O==="*")for(const[U]of v)U.startsWith(l+":")&&Z(U);else Z(O)}}catch(p){W!==void 0&&Ft(t,e),k(t,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:p,status:"error",fetchStatus:"idle"}),D(t,"onFetchError",p),P(e,t,"onFetchError",p),u(A)&&A(p,w,t),u($)&&$(null,p,w,t),C&&C({phase:"error",mode:"mutation",from:l,method:a,error:p.message||String(p),durationMs:(typeof performance<"u"?performance.now():Date.now())-x})}finally{o.__fetching=!1}},$t=(e,t,r,s)=>{if(!e||!s?.fetch)return;const o=Et(e,t);if(!o)return;const a=z(o)?o.map(n=>Lt(Et(n,t),t)).filter(Boolean):[Lt(o,t)].filter(Boolean);for(const n of a){const h=n.method==="insert"||n.method==="update"||n.method==="upsert"||n.method==="delete",g=h?Jt:R;n.on==="create"?g(n,t,s):Promise.resolve().then(()=>{Kt({...n,__runner:g},t,s)}),!h&&n.on==="create"&&(n.refetchInterval||n.refetchOnWindowFocus!==!1||n.refetchOnReconnect!==!1)&&Yt(n,t,s)}const l=t.__ref;l.refetch=n=>{for(const h of a)R(h,t,s,{force:!0,...n})},l.fetchNextPage=()=>{const n=a[0];if(!n||!n.infinite)return;const h=l.__nextPageParam;if(h==null)return;const g={...n,cursor:h};R(g,t,s,{direction:"next",force:!0})},l.fetchPreviousPage=()=>{const n=a[0];if(!n||!n.infinite)return;const h=l.__prevPageParam;if(h==null)return;const g={...n,cursor:h};R(g,t,s,{direction:"previous",force:!0})}},re={invalidateQueries:e=>{if(!e){Z();return}if(B(e))for(const[t]of v)(t.startsWith(e)||t.includes(e))&&Z(t);else if(z(e)){const t=e.join(":");for(const[r]of v)r.includes(t)&&Z(r)}},removeQueries:e=>{if(!e){ct();return}if(B(e))for(const[t]of v)(t.startsWith(e)||t.includes(e))&&ct(t)},getQueryData:e=>V(e)?.data??void 0,setQueryData:(e,t)=>{const r=V(e),s=u(t)?t(r?.data):t;X(e,s,null)},prefetchQuery:async(e,t)=>{const r=t?.fetch;if(!r)return;const s=await Tt(r,t);if(!s)return;const i=e.cache?.key||`${e.from}:${e.method||"select"}:${JSON.stringify(e.params||"")}`,o=s[e.method||"select"];if(!u(o))return;const a=await o({from:e.from,params:e.params,limit:e.limit,offset:e.offset,order:e.order,single:e.single});if(a?.data!==void 0&&!a?.error){const l=X(i,a.data,null);l.gcTime=wt(e.cache)?.gcTime||3e5}return a},getCache:()=>v,clear:()=>ct(),dropNonLang:e=>{if(!e)return;const t=`:${e}`;for(const[r]of v)r.match(/:([a-z]{2,3})$/i)&&(r.endsWith(t)||ct(r))}},se={name:"fetch",create(e){const t=e.fetch;t&&(e.parent||j.clear(),$t(t,e,e.state,e.context))}};var oe=$t;export{te as createAdapter,oe as default,$t as executeFetch,se as fetchPlugin,mt as initAdapterAuth,H as parseDuration,re as queryClient,Zt as registerAdapter,jt as resolveDb};
|
|
1
|
+
import{isArray as Q,isFunction as l,isObject as V,isString as H,exec as Pt}from"@symbo.ls/utils";const zt=["select","rpc","insert","update","upsert","delete","subscribe"],jt={rest:()=>import("./adapters/rest.js"),local:()=>import("./adapters/local.js")},ut=Symbol.for("@symbo.ls/fetch:CUSTOM_ADAPTERS"),X=(()=>{if(typeof globalThis<"u"&&globalThis[ut])return globalThis[ut];const t={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,ut,{value:t,writable:!1,configurable:!1,enumerable:!1}),globalThis[ut]}catch{}return t})(),lt=Symbol.for("@symbo.ls/fetch:PENDING_ADAPTERS"),bt=(()=>{if(typeof globalThis<"u"&&globalThis[lt])return globalThis[lt];const t={};if(typeof globalThis<"u")try{return Object.defineProperty(globalThis,lt,{value:t,writable:!1,configurable:!1,enumerable:!1}),globalThis[lt]}catch{}return t})(),Bt=5e3,Gt=t=>new Promise(e=>{if(X[t])return e(X[t]);const s=bt[t]||=[];let r=!1;const o=()=>{r||(r=!0,e(X[t]||null))};s.push(o),setTimeout(o,Bt)}),re=(t,e)=>{X[t]=e;const s=bt[t];if(s&&s.length){bt[t]=[];for(const r of s)r()}},ne=t=>{const e={};for(const s of zt)t[s]&&(e[s]=t[s]);return e.name=t.name||"custom",e},Qt=async t=>{if(!t)return null;if(typeof t.select=="function")return t;const{adapter:e,...s}=t,r=typeof e=="string"?e:typeof t=="string"?t:null;if(!r)return null;let o=X[r]||jt[r];if(!o&&(o=await Gt(r),!o))throw new Error(`Unknown db adapter: "${r}". Use registerAdapter() for adapters with optional deps.`);const n=await o();if(!n||typeof n.setup!="function")throw new Error(`Adapter "${r}" loader returned a module without a setup() function. Got keys: [${Object.keys(n||{}).join(", ")}]. Likely a bundler chunk-resolution issue.`);return n.setup(s)},Z=t=>{if(!t)return 0;if(typeof t=="number")return t;const e=t.match(/^(\d+)(ms|s|m|h)$/);if(!e)return 0;const s=parseInt(e[1]),r=e[2];return r==="ms"?s:r==="s"?s*1e3:r==="m"?s*6e4:r==="h"?s*36e5:0},T=new Map,U=new Map,W=new Map,Wt=(t,e,s)=>{if(t.cache?.key)return t.cache.key;const r=Kt(t.params),o=s?`${s}:`:"",n=`${t.from}:${t.method}:${o}${JSON.stringify(r||"")}`;return e?`${n}:${e}`:n},tt=t=>T.get(t)||null,et=(t,e,s)=>{const r=T.get(t),o={data:e,error:s,time:Date.now(),stale:!1};T.set(t,o);const n=U.get(t);if(n)for(const a of n)l(a)&&a(o);return o},st=t=>{if(t){const e=T.get(t);e&&(e.stale=!0);return}for(const[,e]of T)e.stale=!0},dt=t=>{if(t){T.delete(t);return}T.clear()},oe=(t,e)=>(U.has(t)||U.set(t,new Set),U.get(t).add(e),()=>{const s=U.get(t);s&&(s.delete(e),s.size===0&&U.delete(t))}),wt=t=>!t&&t!==!1?{staleTime:6e4,gcTime:3e5}:t===!1?null:t===!0?{staleTime:6e4,gcTime:3e5}:typeof t=="number"?{staleTime:t,gcTime:Math.max(t*5,3e5)}:H(t)?{staleTime:Z(t),gcTime:3e5}:{staleTime:Z(t.stale||t.staleTime)||6e4,gcTime:Z(t.gc||t.gcTime||t.expire)||3e5,key:t.key};let ht=null;const Yt=()=>{ht||(ht=setInterval(()=>{const t=Date.now();for(const[e,s]of T){const r=U.get(e);!(r&&r.size>0)&&t-s.time>(s.gcTime||3e5)&&T.delete(e)}},3e4),ht.unref&&ht.unref())};Yt();const At=3,Tt=t=>Math.min(1e3*2**t,3e4),Lt=t=>{const e=t.retry;return e===!1?{count:0}:e===!0||e===void 0?{count:At,delay:Tt}:typeof e=="number"?{count:e,delay:Tt}:{count:e.count??At,delay:l(e.delay)?e.delay:typeof e.delay=="number"?()=>e.delay:Tt}},Ot=async(t,e)=>{const{count:s,delay:r}=e;let o;for(let n=0;n<=s;n++)try{const a=await t();if(a?.error){if(o=a.error,n<s){const c=l(r)?r(n,o):r;await new Promise(i=>setTimeout(i,c));continue}return a}return a}catch(a){if(o=a,n<s){const c=l(r)?r(n,a):r;await new Promise(i=>setTimeout(i,c));continue}throw a}return{data:null,error:o}},Y={focus:new Set,online:new Set};let Rt=!1;const xt=()=>{if(Rt||typeof window>"u")return;Rt=!0;const t=()=>{for(const s of Y.focus)s()},e=()=>{for(const s of Y.online)s()};window.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&t()}),window.addEventListener("focus",t),window.addEventListener("online",e)},kt=(t,e)=>{const s=e.__ref;if(t===!0)return{from:s.__state||e.key,method:"select",query:!0,on:"create"};if(H(t))return{from:t,method:"select",query:!0,on:"create"};if(V(t)){const r={...t};return r.from=r.from||s.__state||e.key,r.method=r.method||"select",r.on=r.on||"create",r.query===void 0&&(r.query=!0),r}return null},Kt=t=>(!t||l(t),t),pt=(t,e)=>{const s=t?.state?.root||e?.state?.root;if(s?.lang)return s.lang},mt=(t,e)=>{const r=(t?.state?.root||e?.state?.root)?.__fetchScope;return r?String(r):void 0},$t=(t,e,s)=>{let r;if(!t)r=void 0;else if(l(t))r=t(e,e.state);else{r={};for(const o in t){const n=t[o];r[o]=l(n)?n(e,e.state):n}}return r},vt=async(t,e)=>{if(!t||t.__authInitialized||(t.__authInitialized=!0,!t.getSession))return;const s=(r,o)=>{const n=e.state?.root;n?.update&&n.update({auth:{user:r,session:o,loading:!1}})};try{const r=await t.getSession();s(r?.user||null,r)}catch(r){console.warn("[fetch] Failed to restore auth session:",r.message)}t.onAuthStateChange&&t.onAuthStateChange((r,o)=>{s(o?.user||null,o)})},Ft=async(t,e)=>{if(l(t.select))return t.auth!==!1&&await vt(t,e),t;if(t.__resolved)return t.auth!==!1&&await vt(t.__resolved,e),t.__resolved;if(t.__resolving)return t.__resolving;t.__resolving=Qt(t);const s=await t.__resolving;return delete t.__resolving,s?(s.auth=t.auth,s.url=t.url,s.key=t.key,t.__resolved=s,e.fetch=s,t.auth!==!1&&await vt(s,e),s):null},E=(t,e,...s)=>{const r=l(t[e])?t[e]:null;r&&r.call(t,...s,t,t.state,t.context)},A=(t,e,s,...r)=>{const o=t&&l(t[s])?t[s]:null;o&&o.call(e,...r,e,e.state,e.context)},rt=t=>{const e={},s=t.node;if(!s)return e;if(s.tagName==="FORM"){const o=new FormData(s);for(const[n,a]of o.entries())e[n]=a;return e}const r=s.querySelectorAll("input, textarea, select");for(let o=0;o<r.length;o++){const n=r[o],a=n.name||n.getAttribute("name");a&&(n.type==="checkbox"?e[a]=n.checked:n.type==="file"?e[a]=n.files:e[a]=n.value)}return e},Et=t=>t.responseType==="stream"||t.responseType==="response",Jt=["Blob","File","ArrayBuffer","ReadableStream","Response"],Dt=t=>t!==null&&typeof t=="object"&&(ArrayBuffer.isView(t)||Jt.includes(Object.prototype.toString.call(t).slice(8,-1))),q=(t,e,s,r={})=>{if(!s&&Dt(e))return;const o=s&&s.startsWith("~/"),n=o&&t.state?.root||t.state;if(n?.update)if(o){const a=s.slice(2);e&&typeof e=="object"&&!Array.isArray(e)&&!Dt(e)&&a in e?n.update(e,{preventFetch:!0,...r}):n.update({[a]:e},{preventFetch:!0,...r})}else{const a=s?{[s]:e}:e;n.update(a,{preventFetch:!0,...r})}},L=(t,e)=>{const s=t?.__ref;s&&(s.__fetchStatus=e,s.__fetching=e.isFetching,s.__fetchError=e.error)},N=async(t,e,s,r={})=>{const o=s?.fetch;if(!o||!e||!e.__ref)return;const n=e.__ref,a=mt(e,s);(!n.__fetchScopeOwner||n.__fetchScopeOwner.scope!==a)&&(n.__fetchScopeOwner={scope:a});const c=n.__fetchScopeOwner,i=()=>e.__ref===n&&n.__fetchScopeOwner===c&&mt(e,s)===a;if(t.enabled===!1||l(t.enabled)&&!t.enabled(e,e.state)||t.skip===!0||l(t.skip)&&t.skip(e,e.state))return;const h=await Ft(o,s);if(!h||!i())return;const{from:g,method:S,query:R,params:x,cache:nt,transform:D,single:z,auth:ot,fields:j,as:k,limit:I,offset:$,order:b,headers:K,baseUrl:C,responseType:B,page:p,cursor:P,getNextPageParam:J,getPreviousPageParam:it,infinite:at,placeholderData:v,initialData:F,select:m,keepPreviousData:M}=t;let G=H(m)?m:void 0;if(R&&l(e.getQuery)){const d=e.getQuery(h.name||"paths");d&&(G=d.select||d.length&&d.join(",")||G)}const ft=$t(x,e,s),ct=Et(t)?null:wt(nt),Nt=Lt(t),_t=pt(e,s),It=_t?`:${_t}`:"",Ut=a?`${a}:`:"",_=ct?nt?.key||`${g}:${S}:${Ut}${JSON.stringify(ft||"")}${at?":infinite":""}${p?":p"+JSON.stringify(p):""}${It}`:null;if(!n.__fetchInitialized&&_&&(n.__fetchInitialized=!0,F!==void 0)){const d=l(F)?F():F;et(_,d,null)}if((S==="select"||S==="rpc")&&_&&ct){const d=tt(_);if(d&&!d.error){const u=Date.now()-d.time,y=d.stale||u>(ct.staleTime||0);let f=d.data;if(l(m)&&(f=m(f,e,e.state)),D&&(f=D(f,e,e.state)),!i())return;if(q(e,f,k),!y){L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"});return}}else if(v!==void 0){const u=l(v)?v(e,e.state):v;u!==void 0&&q(e,u,k)}}if(_&&W.has(_)&&!r.force){const d=W.get(_);try{const u=await Promise.race([d,new Promise((y,f)=>setTimeout(()=>f("DEDUP_TIMEOUT"),15e3))]);if(!i())return;if(u?.data!==void 0){let y=u.data;if(l(m)&&(y=m(y,e,e.state)),D&&(y=D(y,e,e.state)),!i())return;q(e,y,k),E(e,"onFetchComplete",y),A(t,e,"onFetchComplete",y)}}catch{if(!i())return}return}const qt=!tt(_)?.data;L(e,{isFetching:!0,isLoading:qt,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),E(e,"onFetchStart"),A(t,e,"onFetchStart");const O=s?.analyze?.emitNetwork,yt=O?typeof performance<"u"?performance.now():Date.now():0;O&&O({phase:"start",mode:"query",from:g,method:S,cacheKey:_,lang:_t});const gt=Ot(async()=>{if(!i())return;if(ot!==!1&&h.auth!==!1&&h.getSession){const f=await h.getSession();if(!i())return;if(ot===!0&&!f){const w={message:"Not authenticated"};return L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:w,status:"error",fetchStatus:"idle"}),E(e,"onFetchError",w),A(t,e,"onFetchError",w),{data:null,error:w}}}const d=h[S];if(!l(d))return{data:null,error:{message:`Method "${S}" not found on adapter`}};const u={from:g,select:G,params:ft,single:z,limit:I,offset:$,order:b,headers:K,baseUrl:C};B!==void 0&&(u.responseType=B);const y=pt(e,s);if(y&&(u.headers={...u.headers,"Accept-Language":y}),p!==void 0){if(V(p))p.offset!==void 0&&(u.offset=p.offset),p.limit!==void 0&&(u.limit=p.limit),p.cursor!==void 0&&(u.params={...u.params,cursor:p.cursor});else if(typeof p=="number"){const f=t.pageSize||I||20;u.offset=(p-1)*f,u.limit=f}}if(P!==void 0&&(u.params={...u.params,cursor:P}),S==="insert"||S==="update"||S==="upsert"){let f;if(j===!0||t.on==="submit")f=rt(e);else if(Q(j)){const w=rt(e);f={};for(const St of j)f[St]=w[St]}else e.state?.parse?f=e.state.parse():V(e.state)&&(f={...e.state});D&&(f=D(f,e,e.state)),u.data=f}if(S==="rpc"){let f=ft;if(t.on==="submit"){const w=rt(e);f=t.transformParams?t.transformParams(w,e,e.state):w}u.params=f}if(S==="subscribe"){const f=h.subscribe({from:g,params:ft,on:t.subscribeOn},(w,St,ee)=>{i()&&(q(e,w,k),E(e,"onFetchComplete",w),A(t,e,"onFetchComplete",w))});return i()?(n.__unsubscribe=f,{data:null,error:null,subscribed:!0}):(l(f)&&f(),{data:null,error:null,subscribed:!0})}return d(u)},Nt);_&&W.set(_,gt);try{const d=await gt;if(!i()||d?.subscribed)return;const{data:u,error:y}=d||{};if(y){_&&et(_,null,y),L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:y,status:"error",fetchStatus:"idle"}),E(e,"onFetchError",y),A(t,e,"onFetchError",y),O&&O({phase:"error",mode:"query",from:g,method:S,cacheKey:_,error:y.message||y,durationMs:(typeof performance<"u"?performance.now():Date.now())-yt});return}if(u!==void 0){if((S==="select"||S==="rpc")&&_){const w=et(_,u,null);w.gcTime=ct?.gcTime||3e5}let f=u;if(at&&Q(u)&&(n.__pages||(n.__pages=[]),r.direction==="previous"?n.__pages.unshift(u):n.__pages.push(u),f=n.__pages.flat(),J&&(n.__nextPageParam=J(u,n.__pages),n.__hasNextPage=n.__nextPageParam!=null),it&&(n.__prevPageParam=it(u,n.__pages),n.__hasPreviousPage=n.__prevPageParam!=null)),l(m)&&(f=m(f,e,e.state)),D&&(f=D(f,e,e.state)),!i())return;(!M||f!==void 0)&&q(e,f,k),L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),E(e,"onFetchComplete",f),A(t,e,"onFetchComplete",f),O&&O({phase:"success",mode:"query",ok:!0,from:g,method:S,cacheKey:_,durationMs:(typeof performance<"u"?performance.now():Date.now())-yt})}}catch(d){if(!i())return;L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:d,status:"error",fetchStatus:"idle"}),E(e,"onFetchError",d),A(t,e,"onFetchError",d),O&&O({phase:"error",mode:"query",from:g,method:S,cacheKey:_,error:d.message||String(d),durationMs:(typeof performance<"u"?performance.now():Date.now())-yt})}finally{_&&W.get(_)===gt&&W.delete(_)}},Vt=(t,e,s)=>{const r=t.on,o=e.__ref;o.__fetchListeners||(o.__fetchListeners=[]);const n=t.__runner||N;if(r==="submit"){const a=i=>{i.preventDefault(),n(t,e,s)},c=e.node;c&&(c.addEventListener("submit",a),o.__fetchListeners.push(()=>c.removeEventListener("submit",a)))}else if(r==="click"){const a=()=>n(t,e,s),c=e.node;c&&(c.addEventListener("click",a),o.__fetchListeners.push(()=>c.removeEventListener("click",a)))}else r==="stateChange"&&(o.__fetchOnStateChange=()=>n(t,e,s))},Ht=(t,e,s)=>{const r=e.__ref;r.__fetchCleanups||(r.__fetchCleanups=[]),xt();const o=t.refetchInterval;if(o){const i=typeof o=="number"?o:Z(o);if(i>0){const h=setInterval(()=>{(t.refetchIntervalInBackground||typeof document>"u"||document.visibilityState==="visible")&&N(t,e,s,{force:!0})},i);r.__fetchCleanups.push(()=>clearInterval(h))}}const n=Et(t),a=t.refetchOnWindowFocus===void 0?!n:t.refetchOnWindowFocus!==!1,c=t.refetchOnReconnect===void 0?!n:t.refetchOnReconnect!==!1;if(a){const i=()=>{const h=pt(e,s),g=mt(e,s),S=Wt(t,h,g),R=tt(S),x=wt(t.cache);(!R||R.stale||Date.now()-R.time>(x?.staleTime||0))&&N(t,e,s,{force:!0})};Y.focus.add(i),r.__fetchCleanups.push(()=>Y.focus.delete(i))}if(c){const i=()=>N(t,e,s,{force:!0});Y.online.add(i),r.__fetchCleanups.push(()=>Y.online.delete(i))}},Xt=(t,e,s)=>{if(!e.optimistic)return null;const r=t.__ref,o=e.as,n=t.state?.parse?t.state.parse():V(t.state)?{...t.state}:t.state;r.__optimisticSnapshot=n;const a=l(e.optimistic)?e.optimistic(s,n,t):e.optimistic;return a!==void 0&&q(t,a,o),n},Ct=(t,e)=>{const s=t.__ref,r=s.__optimisticSnapshot;r!==void 0&&(q(t,r,e.as),delete s.__optimisticSnapshot)},Zt=async(t,e,s)=>{const r=s?.fetch;if(!r)return;const o=await Ft(r,s);if(!o)return;const n=e.__ref,{method:a,from:c,fields:i,transform:h,as:g,on:S,auth:R,headers:x,baseUrl:nt,responseType:D,invalidates:z,optimistic:ot,onMutate:j,onSuccess:k,onError:I,onSettled:$}=t;let b;if(i===!0||S==="submit")b=rt(e);else if(Q(i)){const p=rt(e);b={};for(const P of i)b[P]=p[P]}else e.state?.parse?b=e.state.parse():V(e.state)&&(b={...e.state});h&&(b=h(b,e,e.state)),l(j)&&j(b,e,e.state);const K=ot?Xt(e,t,b):null;n.__fetching=!0,L(e,{isFetching:!0,isLoading:!1,isStale:!1,isSuccess:!1,error:null,status:"pending",fetchStatus:"fetching"}),E(e,"onFetchStart"),A(t,e,"onFetchStart");const C=s?.analyze?.emitNetwork,B=C?typeof performance<"u"?performance.now():Date.now():0;C&&C({phase:"start",mode:"mutation",from:c,method:a});try{if(R!==!1&&o.auth!==!1&&o.getSession){const m=await o.getSession();if(R===!0&&!m){K!==void 0&&Ct(e,t);const M={message:"Not authenticated"};E(e,"onFetchError",M),A(t,e,"onFetchError",M);return}}const p=o[a];if(!l(p))return;const P={from:c,data:b,headers:x,baseUrl:nt};D!==void 0&&(P.responseType=D),t.params&&(P.params=$t(t.params,e,s));const J=pt(e,s);J&&(P.headers={...P.headers,"Accept-Language":J});const it=Lt(t),at=await Ot(()=>p(P),it),{data:v,error:F}=at||{};if(F){K!==void 0&&Ct(e,t),L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:F,status:"error",fetchStatus:"idle"}),E(e,"onFetchError",F),l(I)&&I(F,b,e),l($)&&$(null,F,b,e),C&&C({phase:"error",mode:"mutation",from:c,method:a,error:F.message||String(F),durationMs:(typeof performance<"u"?performance.now():Date.now())-B});return}if(delete n.__optimisticSnapshot,v!==void 0&&(g||!Dt(v))){const m=g?{[g]:v}:v;e.state?.update&&e.state.update(m,{preventFetch:!0})}if(L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!0,error:null,status:"success",fetchStatus:"idle"}),E(e,"onFetchComplete",v),A(t,e,"onFetchComplete",v),l(k)&&k(v,b,e),l($)&&$(v,null,b,e),C&&C({phase:"success",mode:"mutation",ok:!0,from:c,method:a,durationMs:(typeof performance<"u"?performance.now():Date.now())-B}),z){const m=Q(z)?z:[z];for(const M of m)if(M===!0||M==="*")for(const[G]of T)G.startsWith(c+":")&&st(G);else st(M)}}catch(p){K!==void 0&&Ct(e,t),L(e,{isFetching:!1,isLoading:!1,isStale:!1,isSuccess:!1,error:p,status:"error",fetchStatus:"idle"}),E(e,"onFetchError",p),A(t,e,"onFetchError",p),l(I)&&I(p,b,e),l($)&&$(null,p,b,e),C&&C({phase:"error",mode:"mutation",from:c,method:a,error:p.message||String(p),durationMs:(typeof performance<"u"?performance.now():Date.now())-B})}finally{n.__fetching=!1}},Mt=(t,e,s,r)=>{if(!t||!r?.fetch)return;const n=Pt(t,e);if(!n)return;const a=Q(n)?n.map(i=>kt(Pt(i,e),e)).filter(Boolean):[kt(n,e)].filter(Boolean);for(const i of a){const h=i.method==="insert"||i.method==="update"||i.method==="upsert"||i.method==="delete",g=h?Zt:N;i.on==="create"?g(i,e,r):Promise.resolve().then(()=>{Vt({...i,__runner:g},e,r)}),!h&&i.on==="create"&&(i.refetchInterval||i.refetchOnWindowFocus!==!1||i.refetchOnReconnect!==!1)&&Ht(i,e,r)}const c=e.__ref;c.refetch=i=>{for(const h of a)N(h,e,r,{force:!0,...i})},c.fetchNextPage=()=>{const i=a[0];if(!i||!i.infinite)return;const h=c.__nextPageParam;if(h==null)return;const g={...i,cursor:h};N(g,e,r,{direction:"next",force:!0})},c.fetchPreviousPage=()=>{const i=a[0];if(!i||!i.infinite)return;const h=c.__prevPageParam;if(h==null)return;const g={...i,cursor:h};N(g,e,r,{direction:"previous",force:!0})}},ie={invalidateQueries:t=>{if(!t){st();return}if(H(t))for(const[e]of T)(e.startsWith(t)||e.includes(t))&&st(e);else if(Q(t)){const e=t.join(":");for(const[s]of T)s.includes(e)&&st(s)}},removeQueries:t=>{if(!t){dt();return}if(H(t))for(const[e]of T)(e.startsWith(t)||e.includes(t))&&dt(e)},getQueryData:t=>tt(t)?.data??void 0,setQueryData:(t,e)=>{const s=tt(t),r=l(e)?e(s?.data):e;et(t,r,null)},prefetchQuery:async(t,e)=>{const s=e?.fetch;if(!s)return;const r=await Ft(s,e);if(!r)return;const o=t.cache?.key||`${t.from}:${t.method||"select"}:${JSON.stringify(t.params||"")}`,n=r[t.method||"select"];if(!l(n))return;const a={from:t.from,params:t.params,limit:t.limit,offset:t.offset,order:t.order,single:t.single,headers:t.headers,baseUrl:t.baseUrl};t.responseType!==void 0&&(a.responseType=t.responseType);const c=await n(a);if(c?.data!==void 0&&!c?.error&&!Et(t)){const i=et(o,c.data,null);i.gcTime=wt(t.cache)?.gcTime||3e5}return c},getCache:()=>T,clear:()=>dt(),dropNonLang:t=>{if(!t)return;const e=`:${t}`;for(const[s]of T)s.match(/:([a-z]{2,3})$/i)&&(s.endsWith(e)||dt(s))}},ae={name:"fetch",create(t){const e=t.fetch;e&&(t.parent||W.clear(),Mt(e,t,t.state,t.context))}};var fe=Mt;export{ne as createAdapter,fe as default,Mt as executeFetch,ae as fetchPlugin,vt as initAdapterAuth,Z as parseDuration,ie as queryClient,re as registerAdapter,Qt as resolveDb};
|
package/index.js
CHANGED
|
@@ -521,9 +521,30 @@ const collectFormData = (element) => {
|
|
|
521
521
|
return data
|
|
522
522
|
}
|
|
523
523
|
|
|
524
|
+
// --- Response kinds (REST `responseType`) ---
|
|
525
|
+
|
|
526
|
+
// 'stream' and 'response' hand back a body that can be read ONCE. A cached or
|
|
527
|
+
// dedup-shared copy would reach its second reader already locked or used, so
|
|
528
|
+
// such queries skip the cache and the in-flight dedup, and they re-request on
|
|
529
|
+
// window focus / reconnect only when the config asks for it.
|
|
530
|
+
const isSingleUse = (config) => config.responseType === 'stream' || config.responseType === 'response'
|
|
531
|
+
|
|
532
|
+
// A response body the adapter returned as-is (Blob, ArrayBuffer, typed array,
|
|
533
|
+
// ReadableStream, Response). Such a value only lands in state under `as`:
|
|
534
|
+
// merging one into state would walk its prototype's enumerable members
|
|
535
|
+
// (`size`, `getReader`, …) into state keys. Detection reads the toStringTag,
|
|
536
|
+
// so values from another realm count too.
|
|
537
|
+
const BODY_VALUE_TAGS = ['Blob', 'File', 'ArrayBuffer', 'ReadableStream', 'Response']
|
|
538
|
+
const isBodyValue = (value) =>
|
|
539
|
+
value !== null && typeof value === 'object' &&
|
|
540
|
+
(ArrayBuffer.isView(value) || BODY_VALUE_TAGS.includes(Object.prototype.toString.call(value).slice(8, -1)))
|
|
541
|
+
|
|
524
542
|
// --- State update helpers ---
|
|
525
543
|
|
|
526
544
|
const updateElementState = (element, data, stateKey, options = {}) => {
|
|
545
|
+
// Nothing to merge — `transform` / `onFetchComplete` still receive it.
|
|
546
|
+
if (!stateKey && isBodyValue(data)) return
|
|
547
|
+
|
|
527
548
|
const isRoot = stateKey && stateKey.startsWith('~/')
|
|
528
549
|
const target = isRoot ? (element.state?.root || element.state) : element.state
|
|
529
550
|
if (!target?.update) return
|
|
@@ -532,7 +553,7 @@ const updateElementState = (element, data, stateKey, options = {}) => {
|
|
|
532
553
|
const key = stateKey.slice(2)
|
|
533
554
|
// If transform returned an object containing the key itself, spread on root
|
|
534
555
|
// e.g. transform returns { transactions: [...], totalSaved: 755 } for as: '~/transactions'
|
|
535
|
-
if (data && typeof data === 'object' && !Array.isArray(data) && key in data) {
|
|
556
|
+
if (data && typeof data === 'object' && !Array.isArray(data) && !isBodyValue(data) && key in data) {
|
|
536
557
|
target.update(data, { preventFetch: true, ...options })
|
|
537
558
|
} else {
|
|
538
559
|
target.update({ [key]: data }, { preventFetch: true, ...options })
|
|
@@ -598,7 +619,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
598
619
|
const {
|
|
599
620
|
from, method, query, params: rawParams, cache: cacheRaw, transform,
|
|
600
621
|
single, auth, fields, as: stateKey, limit, offset, order,
|
|
601
|
-
headers, baseUrl,
|
|
622
|
+
headers, baseUrl, responseType,
|
|
602
623
|
// Pagination
|
|
603
624
|
page, cursor, getNextPageParam, getPreviousPageParam, infinite,
|
|
604
625
|
// TanStack-style options
|
|
@@ -613,7 +634,8 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
613
634
|
}
|
|
614
635
|
|
|
615
636
|
const params = resolveParams(rawParams, element, context)
|
|
616
|
-
|
|
637
|
+
// No cache key for a single-use body: no cache entry, no dedup sharing.
|
|
638
|
+
const cacheConfig = isSingleUse(config) ? null : parseCacheConfig(cacheRaw)
|
|
617
639
|
const retryConfig = resolveRetryConfig(config)
|
|
618
640
|
const lang = resolveLanguage(element, context)
|
|
619
641
|
|
|
@@ -720,6 +742,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
720
742
|
if (!isFunction(fn)) return { data: null, error: { message: `Method "${method}" not found on adapter` } }
|
|
721
743
|
|
|
722
744
|
const request = { from, select, params, single, limit, offset, order, headers, baseUrl }
|
|
745
|
+
if (responseType !== undefined) request.responseType = responseType
|
|
723
746
|
|
|
724
747
|
// Inject language into request headers
|
|
725
748
|
const lang = resolveLanguage(element, context)
|
|
@@ -936,8 +959,15 @@ const bindAutoRefetch = (config, element, context) => {
|
|
|
936
959
|
}
|
|
937
960
|
}
|
|
938
961
|
|
|
962
|
+
// A single-use body has no cache entry to go stale, so without an explicit
|
|
963
|
+
// opt-in every focus / reconnect would send the request again (re-asking a
|
|
964
|
+
// streamed answer, say). Other queries keep both on by default.
|
|
965
|
+
const singleUse = isSingleUse(config)
|
|
966
|
+
const onFocusEnabled = config.refetchOnWindowFocus === undefined ? !singleUse : config.refetchOnWindowFocus !== false
|
|
967
|
+
const onReconnectEnabled = config.refetchOnReconnect === undefined ? !singleUse : config.refetchOnReconnect !== false
|
|
968
|
+
|
|
939
969
|
// refetchOnWindowFocus
|
|
940
|
-
if (
|
|
970
|
+
if (onFocusEnabled) {
|
|
941
971
|
const onFocus = () => {
|
|
942
972
|
const lang = resolveLanguage(element, context)
|
|
943
973
|
const scope = resolveScope(element, context)
|
|
@@ -953,7 +983,7 @@ const bindAutoRefetch = (config, element, context) => {
|
|
|
953
983
|
}
|
|
954
984
|
|
|
955
985
|
// refetchOnReconnect
|
|
956
|
-
if (
|
|
986
|
+
if (onReconnectEnabled) {
|
|
957
987
|
const onOnline = () => runFetch(config, element, context, { force: true })
|
|
958
988
|
globalListeners.online.add(onOnline)
|
|
959
989
|
ref.__fetchCleanups.push(() => globalListeners.online.delete(onOnline))
|
|
@@ -1001,7 +1031,7 @@ const runMutation = async (config, element, context) => {
|
|
|
1001
1031
|
if (!adapter) return
|
|
1002
1032
|
|
|
1003
1033
|
const ref = element.__ref
|
|
1004
|
-
const { method, from, fields, transform, as: stateKey, on: trigger, auth, headers, baseUrl, invalidates, optimistic, onMutate, onSuccess, onError, onSettled } = config
|
|
1034
|
+
const { method, from, fields, transform, as: stateKey, on: trigger, auth, headers, baseUrl, responseType, invalidates, optimistic, onMutate, onSuccess, onError, onSettled } = config
|
|
1005
1035
|
|
|
1006
1036
|
// Collect mutation data
|
|
1007
1037
|
let mutationData
|
|
@@ -1050,6 +1080,7 @@ const runMutation = async (config, element, context) => {
|
|
|
1050
1080
|
if (!isFunction(fn)) return
|
|
1051
1081
|
|
|
1052
1082
|
const request = { from, data: mutationData, headers, baseUrl }
|
|
1083
|
+
if (responseType !== undefined) request.responseType = responseType
|
|
1053
1084
|
if (config.params) request.params = resolveParams(config.params, element, context)
|
|
1054
1085
|
|
|
1055
1086
|
// Inject language into mutation request headers
|
|
@@ -1078,7 +1109,8 @@ const runMutation = async (config, element, context) => {
|
|
|
1078
1109
|
|
|
1079
1110
|
delete ref.__optimisticSnapshot
|
|
1080
1111
|
|
|
1081
|
-
|
|
1112
|
+
// A body value (Blob, stream, …) lands in state only under `as`.
|
|
1113
|
+
if (data !== undefined && (stateKey || !isBodyValue(data))) {
|
|
1082
1114
|
const finalData = stateKey ? { [stateKey]: data } : data
|
|
1083
1115
|
if (element.state?.update) element.state.update(finalData, { preventFetch: true })
|
|
1084
1116
|
}
|
|
@@ -1243,16 +1275,20 @@ export const queryClient = {
|
|
|
1243
1275
|
const fn = adapter[config.method || 'select']
|
|
1244
1276
|
if (!isFunction(fn)) return
|
|
1245
1277
|
|
|
1246
|
-
const
|
|
1278
|
+
const request = {
|
|
1247
1279
|
from: config.from,
|
|
1248
1280
|
params: config.params,
|
|
1249
1281
|
limit: config.limit,
|
|
1250
1282
|
offset: config.offset,
|
|
1251
1283
|
order: config.order,
|
|
1252
|
-
single: config.single
|
|
1253
|
-
|
|
1284
|
+
single: config.single,
|
|
1285
|
+
headers: config.headers,
|
|
1286
|
+
baseUrl: config.baseUrl
|
|
1287
|
+
}
|
|
1288
|
+
if (config.responseType !== undefined) request.responseType = config.responseType
|
|
1289
|
+
const result = await fn(request)
|
|
1254
1290
|
|
|
1255
|
-
if (result?.data !== undefined && !result?.error) {
|
|
1291
|
+
if (result?.data !== undefined && !result?.error && !isSingleUse(config)) {
|
|
1256
1292
|
const entry = setCacheEntry(cacheKey, result.data, null)
|
|
1257
1293
|
entry.gcTime = parseCacheConfig(config.cache)?.gcTime || 300000
|
|
1258
1294
|
}
|