@symbo.ls/fetch 3.7.0 → 3.7.3
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 +61 -0
- package/index.js +63 -14
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -682,6 +682,66 @@ const db = createAdapter({
|
|
|
682
682
|
})
|
|
683
683
|
```
|
|
684
684
|
|
|
685
|
+
## Language / i18n
|
|
686
|
+
|
|
687
|
+
Fetch automatically injects the current language into every request — both as a `lang` query parameter and as an `Accept-Language` header.
|
|
688
|
+
|
|
689
|
+
### Setting the language
|
|
690
|
+
|
|
691
|
+
Set the language in root state:
|
|
692
|
+
|
|
693
|
+
```js
|
|
694
|
+
state: { root: { lang: 'ka' } }
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
Or use the polyglot plugin which manages `state.root.lang` automatically.
|
|
698
|
+
|
|
699
|
+
### Per-request override
|
|
700
|
+
|
|
701
|
+
Override the language for a specific fetch by including `lang` in params:
|
|
702
|
+
|
|
703
|
+
```js
|
|
704
|
+
{
|
|
705
|
+
fetch: {
|
|
706
|
+
from: 'articles',
|
|
707
|
+
params: { lang: 'de' } // overrides global language for this request
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### How it works
|
|
713
|
+
|
|
714
|
+
1. `lang` is added to `params` (sent as query parameter / RPC argument)
|
|
715
|
+
2. `Accept-Language` header is set on the request
|
|
716
|
+
3. If `params.lang` is already set explicitly, it is not overwritten
|
|
717
|
+
|
|
718
|
+
This follows the same pattern as XMA's `t()` function where `state.root.lang` is the source of truth for the current language.
|
|
719
|
+
|
|
720
|
+
## Disabling fetch
|
|
721
|
+
|
|
722
|
+
Fetch is included by default in smbls. To disable it:
|
|
723
|
+
|
|
724
|
+
```js
|
|
725
|
+
import { createDefine } from '@symbo.ls/smbls'
|
|
726
|
+
|
|
727
|
+
// Disable fetch, keep everything else
|
|
728
|
+
const options = {
|
|
729
|
+
define: createDefine({ fetch: false })
|
|
730
|
+
}
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
## domql plugin
|
|
734
|
+
|
|
735
|
+
Fetch can also be used as a domql plugin:
|
|
736
|
+
|
|
737
|
+
```js
|
|
738
|
+
import { fetchPlugin } from '@symbo.ls/fetch'
|
|
739
|
+
|
|
740
|
+
context.plugins = [fetchPlugin]
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
When used as a plugin, fetch hooks into the `create` lifecycle to auto-execute fetch configs defined on elements.
|
|
744
|
+
|
|
685
745
|
## All `fetch` options
|
|
686
746
|
|
|
687
747
|
| Option | Type | Default | Description |
|
|
@@ -722,3 +782,4 @@ const db = createAdapter({
|
|
|
722
782
|
| `order` | string/object/array | — | Sort order |
|
|
723
783
|
| `headers` | object | — | Per-request headers (REST) |
|
|
724
784
|
| `baseUrl` | string | — | Per-request base URL (REST) |
|
|
785
|
+
| `lang` | string | auto from context/state | Language override (via params) |
|
package/index.js
CHANGED
|
@@ -257,13 +257,24 @@ const resolveParamsSync = (params) => {
|
|
|
257
257
|
return params
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
if (
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
260
|
+
const resolveLanguage = (element, context) => {
|
|
261
|
+
const root = element?.state?.root || context?.state?.root
|
|
262
|
+
if (root?.lang) return root.lang
|
|
263
|
+
return undefined
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const resolveParams = (params, element, context) => {
|
|
267
|
+
let resolved
|
|
268
|
+
if (!params) {
|
|
269
|
+
resolved = undefined
|
|
270
|
+
} else if (isFunction(params)) {
|
|
271
|
+
resolved = params(element, element.state)
|
|
272
|
+
} else {
|
|
273
|
+
resolved = {}
|
|
274
|
+
for (const key in params) {
|
|
275
|
+
const val = params[key]
|
|
276
|
+
resolved[key] = isFunction(val) ? val(element, element.state) : val
|
|
277
|
+
}
|
|
267
278
|
}
|
|
268
279
|
return resolved
|
|
269
280
|
}
|
|
@@ -304,7 +315,7 @@ const resolveAdapter = async (db, context) => {
|
|
|
304
315
|
db.__resolving = resolveDb(db)
|
|
305
316
|
const resolved = await db.__resolving
|
|
306
317
|
db.__resolved = resolved
|
|
307
|
-
context.
|
|
318
|
+
context.fetch = resolved
|
|
308
319
|
delete db.__resolving
|
|
309
320
|
|
|
310
321
|
// Auto-init auth when adapter supports it and db.auth is enabled
|
|
@@ -368,7 +379,7 @@ const setFetchStatus = (element, status) => {
|
|
|
368
379
|
// --- Core fetch runner ---
|
|
369
380
|
|
|
370
381
|
const runFetch = async (config, element, context, opts = {}) => {
|
|
371
|
-
const db = context?.
|
|
382
|
+
const db = context?.fetch
|
|
372
383
|
if (!db) return
|
|
373
384
|
|
|
374
385
|
// enabled check
|
|
@@ -396,7 +407,7 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
396
407
|
if (q) select = q.select || (q.length && q.join(',')) || undefined
|
|
397
408
|
}
|
|
398
409
|
|
|
399
|
-
const params = resolveParams(rawParams, element)
|
|
410
|
+
const params = resolveParams(rawParams, element, context)
|
|
400
411
|
const cacheConfig = parseCacheConfig(cacheRaw)
|
|
401
412
|
const retryConfig = resolveRetryConfig(config)
|
|
402
413
|
|
|
@@ -484,6 +495,12 @@ const runFetch = async (config, element, context, opts = {}) => {
|
|
|
484
495
|
|
|
485
496
|
const request = { from, select, params, single, limit, offset, order, headers, baseUrl }
|
|
486
497
|
|
|
498
|
+
// Inject language into request headers
|
|
499
|
+
const lang = resolveLanguage(element, context)
|
|
500
|
+
if (lang) {
|
|
501
|
+
request.headers = { ...request.headers, 'Accept-Language': lang }
|
|
502
|
+
}
|
|
503
|
+
|
|
487
504
|
// Pagination support
|
|
488
505
|
if (page !== undefined) {
|
|
489
506
|
if (isObject(page)) {
|
|
@@ -722,7 +739,7 @@ const rollbackOptimistic = (element, config) => {
|
|
|
722
739
|
// --- Mutation runner (insert/update/delete with optimistic + invalidation) ---
|
|
723
740
|
|
|
724
741
|
const runMutation = async (config, element, context) => {
|
|
725
|
-
const db = context?.
|
|
742
|
+
const db = context?.fetch
|
|
726
743
|
if (!db) return
|
|
727
744
|
|
|
728
745
|
const adapter = await resolveAdapter(db, context)
|
|
@@ -772,7 +789,13 @@ const runMutation = async (config, element, context) => {
|
|
|
772
789
|
if (!isFunction(fn)) return
|
|
773
790
|
|
|
774
791
|
const request = { from, data: mutationData, headers, baseUrl }
|
|
775
|
-
if (config.params) request.params = resolveParams(config.params, element)
|
|
792
|
+
if (config.params) request.params = resolveParams(config.params, element, context)
|
|
793
|
+
|
|
794
|
+
// Inject language into mutation request headers
|
|
795
|
+
const lang = resolveLanguage(element, context)
|
|
796
|
+
if (lang) {
|
|
797
|
+
request.headers = { ...request.headers, 'Accept-Language': lang }
|
|
798
|
+
}
|
|
776
799
|
|
|
777
800
|
const retryConfig = resolveRetryConfig(config)
|
|
778
801
|
const result = await withRetry(() => fn(request), retryConfig)
|
|
@@ -828,7 +851,7 @@ const runMutation = async (config, element, context) => {
|
|
|
828
851
|
|
|
829
852
|
export const executeFetch = (param, element, state, context) => {
|
|
830
853
|
if (!param) return
|
|
831
|
-
const db = context?.
|
|
854
|
+
const db = context?.fetch
|
|
832
855
|
if (!db) return
|
|
833
856
|
|
|
834
857
|
const fetchProp = exec(param, element)
|
|
@@ -933,7 +956,7 @@ export const queryClient = {
|
|
|
933
956
|
},
|
|
934
957
|
|
|
935
958
|
prefetchQuery: async (config, context) => {
|
|
936
|
-
const db = context?.
|
|
959
|
+
const db = context?.fetch
|
|
937
960
|
if (!db) return
|
|
938
961
|
|
|
939
962
|
const adapter = await resolveAdapter(db, context)
|
|
@@ -964,5 +987,31 @@ export const queryClient = {
|
|
|
964
987
|
clear: () => removeCache()
|
|
965
988
|
}
|
|
966
989
|
|
|
990
|
+
// --- Plugin interface ---
|
|
991
|
+
|
|
992
|
+
/**
|
|
993
|
+
* domql plugin for declarative data fetching.
|
|
994
|
+
*
|
|
995
|
+
* Usage:
|
|
996
|
+
* context.plugins = [fetchPlugin]
|
|
997
|
+
*
|
|
998
|
+
* Or with language:
|
|
999
|
+
* context.plugins = [fetchPlugin]
|
|
1000
|
+
* context.language = 'en'
|
|
1001
|
+
*
|
|
1002
|
+
* When used as a plugin, add `fetch` to `context.define` or
|
|
1003
|
+
* it is automatically registered via `defaultDefine.fetch`.
|
|
1004
|
+
*/
|
|
1005
|
+
export const fetchPlugin = {
|
|
1006
|
+
name: 'fetch',
|
|
1007
|
+
|
|
1008
|
+
// Hook into element creation to auto-execute fetch configs
|
|
1009
|
+
create (element) {
|
|
1010
|
+
const fetchProp = element.fetch || element.props?.fetch
|
|
1011
|
+
if (!fetchProp) return
|
|
1012
|
+
executeFetch(fetchProp, element, element.state, element.context)
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
967
1016
|
export { parseDuration }
|
|
968
1017
|
export default executeFetch
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/fetch",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.3",
|
|
4
4
|
"license": "CC-BY-NC-4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"adapters"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@domql/utils": "^3.7.
|
|
28
|
+
"@domql/utils": "^3.7.3"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"@supabase/supabase-js": "^2.0.0"
|