gjendje 0.9.3 → 1.0.0
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 +24 -88
- package/dist/{chunk-ZCZG3Y2B.js → chunk-4ZTPYOIR.js} +32 -33
- package/dist/{chunk-XACGL7LY.cjs → chunk-MEVW62P4.cjs} +32 -33
- package/dist/index.cjs +28 -61
- package/dist/index.d.cts +6 -56
- package/dist/index.d.ts +6 -56
- package/dist/index.js +12 -40
- package/dist/server.cjs +5 -5
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +2 -2
- package/dist/{types-D-VJhL7I.d.cts → types-DbzCHTo8.d.cts} +5 -5
- package/dist/{types-D-VJhL7I.d.ts → types-DbzCHTo8.d.ts} +5 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
# gjendje
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Replaces storage backends with a unified API. Choose where state lives. The rest is handled.
|
|
6
|
+
|
|
7
|
+
- Zero runtime dependencies
|
|
8
|
+
- ~5 kB core (minified + brotli)
|
|
9
|
+
- TypeScript-first with full type inference
|
|
10
|
+
- 6 storage backends, one API
|
|
6
11
|
|
|
7
12
|
## Install
|
|
8
13
|
|
|
@@ -15,113 +20,44 @@ npm install gjendje
|
|
|
15
20
|
```ts
|
|
16
21
|
import { state } from 'gjendje'
|
|
17
22
|
|
|
18
|
-
|
|
19
|
-
const theme = state({ theme: 'light' }, { scope: 'local' })
|
|
20
|
-
|
|
21
|
-
// Or use dot notation
|
|
22
|
-
const theme = state.local({ theme: 'light' })
|
|
23
|
-
```
|
|
23
|
+
const store = state({ count: 0 })
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
function increment() {
|
|
26
|
+
store.set((prev) => ({ ...prev, count: prev.count + 1 }))
|
|
27
|
+
}
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
const user = state({ name: 'John', age: 30 })
|
|
29
|
+
const { counter} = store.get()
|
|
29
30
|
```
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
```ts
|
|
34
|
-
user.get() // { name: 'John', age: 30 }
|
|
35
|
-
const { name } = user.get() // Destructure specific values
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Updating values
|
|
39
|
-
|
|
40
|
-
Replace the entire state with `set`, or use an updater function:
|
|
41
|
-
|
|
42
|
-
```ts
|
|
43
|
-
user.set({ name: 'Jane', age: 25 })
|
|
44
|
-
user.set((prev) => ({ ...prev, age: prev.age + 1 }))
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
For object stores, `patch` lets you update specific properties without spreading:
|
|
48
|
-
|
|
49
|
-
```ts
|
|
50
|
-
const form = state({ name: '', email: '', age: 0 })
|
|
51
|
-
|
|
52
|
-
form.patch({ name: 'Alice' }) // Only updates name
|
|
53
|
-
form.patch({ name: 'Bob', age: 30 }) // Update multiple properties at once
|
|
54
|
-
```
|
|
32
|
+
[Examples](https://github.com/charliebeckstrand/gjendje/blob/main/docs/examples.md)
|
|
55
33
|
|
|
56
|
-
|
|
34
|
+
## Configure
|
|
57
35
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Call once at app initialization. Sets global defaults for all state instances.
|
|
61
|
-
|
|
62
|
-
```ts
|
|
63
|
-
import { configure } from 'gjendje'
|
|
64
|
-
|
|
65
|
-
configure({ scope: 'local' })
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Now every `state` call inherits that default:
|
|
69
|
-
|
|
70
|
-
```ts
|
|
71
|
-
const theme = state({ theme: 'light' })
|
|
72
|
-
|
|
73
|
-
theme.scope // 'local' — derived from configure
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
You can also configure global events:
|
|
77
|
-
|
|
78
|
-
```ts
|
|
79
|
-
configure({
|
|
80
|
-
onChange: ({ key, scope, value, previousValue }) => {
|
|
81
|
-
console.log(`[${key}] (${scope}) changed:`, previousValue, '→', value)
|
|
82
|
-
},
|
|
83
|
-
})
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
[Configure reference guide](https://github.com/charliebeckstrand/gjendje/blob/main/docs/configure.md)
|
|
36
|
+
[Configure guide](https://github.com/charliebeckstrand/gjendje/blob/main/docs/configure.md)
|
|
87
37
|
|
|
88
38
|
## Scopes
|
|
89
39
|
|
|
90
|
-
|
|
91
|
-
|----------|----------------------|--------------------|
|
|
92
|
-
| `memory` | In-memory | `state()` |
|
|
93
|
-
| `local` | `localStorage` | `state.local()` |
|
|
94
|
-
| `session` | `sessionStorage` | `state.session()` |
|
|
95
|
-
| `url` | `URLSearchParams` | `state.url()` |
|
|
96
|
-
| `bucket` | Storage Buckets API | `state.bucket()` |
|
|
97
|
-
| `server` | `AsyncLocalStorage` | `state.server()` |
|
|
40
|
+
`memory`, `local`, `session`, `url`, `bucket`, `server`
|
|
98
41
|
|
|
99
|
-
[Scope
|
|
42
|
+
[Scope guide](https://github.com/charliebeckstrand/gjendje/blob/main/docs/scopes.md)
|
|
100
43
|
|
|
101
44
|
## API
|
|
102
45
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
[API reference guide](https://github.com/charliebeckstrand/gjendje/blob/main/docs/api.md)
|
|
46
|
+
`get`, `peek`, `set`, `patch`, `reset`, `destroy`, `subscribe`, `watch`, `intercept`, `onChange`
|
|
106
47
|
|
|
107
|
-
|
|
48
|
+
[API reference](https://github.com/charliebeckstrand/gjendje/blob/main/docs/api.md)
|
|
108
49
|
|
|
109
|
-
|
|
110
|
-
Derives a reactive, read-only value from one or more state dependencies. Recomputes only when a dependency changes and caches the result between changes. Returns a `ReadonlyInstance` — no `set()` or `reset()`.
|
|
50
|
+
## Primitives
|
|
111
51
|
|
|
112
|
-
|
|
113
|
-
Lightweight single-dependency alternative to `computed`. No array allocation or dependency loop — just `source.get()` → `fn(value)`. Ideal for projecting a single field or transformation.
|
|
52
|
+
`computed`, `select`, `previous`, `readonly`, `collection`, `effect`
|
|
114
53
|
|
|
115
|
-
|
|
116
|
-
Reactive array with first-class mutation methods — `add`, `remove`, `update`, `find`, `findAll`, `has`, `clear`. Supports all the same scopes, persistence, validation, and migration as `state`.
|
|
54
|
+
[Primitives reference](https://github.com/charliebeckstrand/gjendje/blob/main/docs/primitives.md)
|
|
117
55
|
|
|
118
|
-
|
|
119
|
-
Runs a side effect immediately and re-runs whenever any dependency changes. The callback can return a cleanup function that runs before the next execution and on `stop()`. Returns an `EffectHandle` with a `stop()` method.
|
|
56
|
+
## Utilities
|
|
120
57
|
|
|
121
|
-
|
|
122
|
-
Creates a read-only view of any state or computed instance. Exposes `get`, `peek`, `subscribe`, and lifecycle — but no `set`, `reset`, `intercept`, or `use`. Zero runtime cost.
|
|
58
|
+
`configure`, `batch`, `snapshot`, `shallowEqual`, `withHistory`, `withWatch`, `withServerSession`
|
|
123
59
|
|
|
124
|
-
[
|
|
60
|
+
[Utilities reference](https://github.com/charliebeckstrand/gjendje/blob/main/docs/utilities.md)
|
|
125
61
|
|
|
126
62
|
## License
|
|
127
63
|
|
|
@@ -367,7 +367,7 @@ function createBucketAdapter(key, bucketOptions, options) {
|
|
|
367
367
|
const listeners = createListeners();
|
|
368
368
|
let lastNotifiedValue = defaultValue;
|
|
369
369
|
const notifyListeners = () => listeners.notify(lastNotifiedValue);
|
|
370
|
-
const fallbackStorage = fallbackScope === "
|
|
370
|
+
const fallbackStorage = fallbackScope === "session" ? sessionStorage : localStorage;
|
|
371
371
|
let delegate = createStorageAdapter(fallbackStorage, key, options);
|
|
372
372
|
let isDestroyed = false;
|
|
373
373
|
const ready = (async () => {
|
|
@@ -447,9 +447,9 @@ function createBucketAdapter(key, bucketOptions, options) {
|
|
|
447
447
|
};
|
|
448
448
|
}
|
|
449
449
|
|
|
450
|
-
// src/adapters/
|
|
450
|
+
// src/adapters/memory.ts
|
|
451
451
|
var RESOLVED = Promise.resolve();
|
|
452
|
-
function
|
|
452
|
+
function createMemoryAdapter(defaultValue) {
|
|
453
453
|
let current = defaultValue;
|
|
454
454
|
const listeners = /* @__PURE__ */ new Set();
|
|
455
455
|
const notifyListeners = () => {
|
|
@@ -537,7 +537,7 @@ function withSync(adapter, key, scope) {
|
|
|
537
537
|
// src/adapters/url.ts
|
|
538
538
|
function createUrlAdapter(key, defaultValue, serializer, persist) {
|
|
539
539
|
if (typeof window === "undefined") {
|
|
540
|
-
throw new Error("[
|
|
540
|
+
throw new Error("[gjendje] URL scope is not available in this environment.");
|
|
541
541
|
}
|
|
542
542
|
const listeners = createListeners();
|
|
543
543
|
const defaultSerialized = serializer.stringify(defaultValue);
|
|
@@ -597,7 +597,7 @@ function createUrlAdapter(key, defaultValue, serializer, persist) {
|
|
|
597
597
|
function isServer() {
|
|
598
598
|
return typeof window === "undefined" || typeof document === "undefined";
|
|
599
599
|
}
|
|
600
|
-
var BROWSER_SCOPES = /* @__PURE__ */ new Set(["session", "
|
|
600
|
+
var BROWSER_SCOPES = /* @__PURE__ */ new Set(["session", "local", "url", "bucket"]);
|
|
601
601
|
function afterHydration(fn) {
|
|
602
602
|
if (isServer()) return Promise.resolve();
|
|
603
603
|
return new Promise((resolve) => {
|
|
@@ -622,10 +622,10 @@ var _serverAdapterFactory;
|
|
|
622
622
|
function registerServerAdapter(factory) {
|
|
623
623
|
_serverAdapterFactory = factory;
|
|
624
624
|
}
|
|
625
|
-
var PERSISTENT_SCOPES = /* @__PURE__ */ new Set(["local", "session", "
|
|
625
|
+
var PERSISTENT_SCOPES = /* @__PURE__ */ new Set(["local", "session", "bucket"]);
|
|
626
626
|
var SYNCABLE_SCOPES = /* @__PURE__ */ new Set(["local", "bucket"]);
|
|
627
627
|
var RESOLVED2 = Promise.resolve();
|
|
628
|
-
var
|
|
628
|
+
var MEMORY_SHIM = {
|
|
629
629
|
ready: RESOLVED2,
|
|
630
630
|
get: () => void 0,
|
|
631
631
|
set: () => {
|
|
@@ -642,19 +642,18 @@ function resolveAdapter(storageKey, scope, options) {
|
|
|
642
642
|
switch (scope) {
|
|
643
643
|
case "memory":
|
|
644
644
|
case "render":
|
|
645
|
-
return
|
|
645
|
+
return createMemoryAdapter(options.default);
|
|
646
646
|
case "session":
|
|
647
|
-
case "tab":
|
|
648
647
|
if (typeof sessionStorage === "undefined") {
|
|
649
648
|
throw new Error(
|
|
650
|
-
'[
|
|
649
|
+
'[gjendje] sessionStorage is not available. Use ssr: true or scope: "memory" for server environments.'
|
|
651
650
|
);
|
|
652
651
|
}
|
|
653
652
|
return createStorageAdapter(sessionStorage, storageKey, options);
|
|
654
653
|
case "local":
|
|
655
654
|
if (typeof localStorage === "undefined") {
|
|
656
655
|
throw new Error(
|
|
657
|
-
'[
|
|
656
|
+
'[gjendje] localStorage is not available. Use ssr: true or scope: "server" for server environments.'
|
|
658
657
|
);
|
|
659
658
|
}
|
|
660
659
|
return createStorageAdapter(localStorage, storageKey, options);
|
|
@@ -671,21 +670,21 @@ function resolveAdapter(storageKey, scope, options) {
|
|
|
671
670
|
case "server":
|
|
672
671
|
if (!_serverAdapterFactory) {
|
|
673
672
|
throw new Error(
|
|
674
|
-
'[
|
|
673
|
+
'[gjendje] scope: "server" requires the server adapter. Import { withServerSession } from "gjendje" or "gjendje/server" to enable it.'
|
|
675
674
|
);
|
|
676
675
|
}
|
|
677
676
|
return _serverAdapterFactory(storageKey, options.default);
|
|
678
677
|
case "bucket": {
|
|
679
678
|
if (!options.bucket) {
|
|
680
679
|
throw new Error(
|
|
681
|
-
'[
|
|
680
|
+
'[gjendje] scope: "bucket" requires a bucket option. Example: { scope: "bucket", bucket: { name: "my-bucket" } }'
|
|
682
681
|
);
|
|
683
682
|
}
|
|
684
683
|
return createBucketAdapter(storageKey, options.bucket, options);
|
|
685
684
|
}
|
|
686
685
|
default: {
|
|
687
686
|
const _exhaustive = scope;
|
|
688
|
-
throw new Error(`[
|
|
687
|
+
throw new Error(`[gjendje] Unknown scope: ${_exhaustive}`);
|
|
689
688
|
}
|
|
690
689
|
}
|
|
691
690
|
}
|
|
@@ -902,15 +901,15 @@ var StateImpl = class {
|
|
|
902
901
|
});
|
|
903
902
|
}
|
|
904
903
|
};
|
|
905
|
-
var
|
|
904
|
+
var MemoryStateImpl = class extends StateImpl {
|
|
906
905
|
// Direct reference — avoids a getter cast on every get()/set() call
|
|
907
906
|
_r;
|
|
908
907
|
_hasIsEqual;
|
|
909
908
|
constructor(key, rKey, options, config) {
|
|
910
|
-
super(key, "
|
|
909
|
+
super(key, "memory", rKey, MEMORY_SHIM, options, config);
|
|
911
910
|
const rs = this._s;
|
|
912
911
|
rs.current = options.default;
|
|
913
|
-
rs.
|
|
912
|
+
rs.memoryListeners = void 0;
|
|
914
913
|
rs.notifyFn = void 0;
|
|
915
914
|
this._r = rs;
|
|
916
915
|
this._hasIsEqual = options.isEqual !== void 0;
|
|
@@ -954,9 +953,9 @@ var RenderStateImpl = class extends StateImpl {
|
|
|
954
953
|
}
|
|
955
954
|
subscribe(listener) {
|
|
956
955
|
const s = this._r;
|
|
957
|
-
if (!s.
|
|
956
|
+
if (!s.memoryListeners) {
|
|
958
957
|
const listeners = /* @__PURE__ */ new Set();
|
|
959
|
-
s.
|
|
958
|
+
s.memoryListeners = listeners;
|
|
960
959
|
s.notifyFn = () => {
|
|
961
960
|
for (const l of listeners) {
|
|
962
961
|
try {
|
|
@@ -967,7 +966,7 @@ var RenderStateImpl = class extends StateImpl {
|
|
|
967
966
|
}
|
|
968
967
|
};
|
|
969
968
|
}
|
|
970
|
-
const set = s.
|
|
969
|
+
const set = s.memoryListeners;
|
|
971
970
|
set.add(listener);
|
|
972
971
|
return () => {
|
|
973
972
|
set.delete(listener);
|
|
@@ -1038,7 +1037,7 @@ var RenderStateImpl = class extends StateImpl {
|
|
|
1038
1037
|
s.changeHandlers?.clear();
|
|
1039
1038
|
s.watchers?.clear();
|
|
1040
1039
|
s.watchUnsub?.();
|
|
1041
|
-
s.
|
|
1040
|
+
s.memoryListeners?.clear();
|
|
1042
1041
|
unregisterByKey(this._rKey);
|
|
1043
1042
|
this._config.onDestroy?.({ key: this.key, scope: this.scope });
|
|
1044
1043
|
if (s.resolveDestroyed) {
|
|
@@ -1048,12 +1047,12 @@ var RenderStateImpl = class extends StateImpl {
|
|
|
1048
1047
|
}
|
|
1049
1048
|
}
|
|
1050
1049
|
};
|
|
1051
|
-
function
|
|
1052
|
-
return new
|
|
1050
|
+
function createMemoryState(key, rKey, options, config) {
|
|
1051
|
+
return new MemoryStateImpl(key, rKey, options, config);
|
|
1053
1052
|
}
|
|
1054
1053
|
function createBase(key, options) {
|
|
1055
1054
|
if (!key) {
|
|
1056
|
-
throw new Error("[
|
|
1055
|
+
throw new Error("[gjendje] key must be a non-empty string.");
|
|
1057
1056
|
}
|
|
1058
1057
|
const config = getConfig();
|
|
1059
1058
|
if (config.keyPattern && !config.keyPattern.test(key)) {
|
|
@@ -1061,8 +1060,8 @@ function createBase(key, options) {
|
|
|
1061
1060
|
`[gjendje] Key "${key}" does not match the configured keyPattern ${config.keyPattern}.`
|
|
1062
1061
|
);
|
|
1063
1062
|
}
|
|
1064
|
-
const rawScope = options.scope ?? config.scope ?? "
|
|
1065
|
-
const scope = rawScope === "
|
|
1063
|
+
const rawScope = options.scope ?? config.scope ?? "memory";
|
|
1064
|
+
const scope = rawScope === "render" ? "memory" : rawScope;
|
|
1066
1065
|
const rKey = scopedKey(key, scope);
|
|
1067
1066
|
const existing = getRegistered(rKey);
|
|
1068
1067
|
if (existing && !existing.isDestroyed) return existing;
|
|
@@ -1072,7 +1071,7 @@ function createBase(key, options) {
|
|
|
1072
1071
|
);
|
|
1073
1072
|
}
|
|
1074
1073
|
const isSsrMode = (options.ssr ?? config.ssr) && BROWSER_SCOPES.has(scope);
|
|
1075
|
-
const
|
|
1074
|
+
const useMemoryFallback = isSsrMode && isServer();
|
|
1076
1075
|
const effectiveSync = options.sync ?? (config.sync && SYNCABLE_SCOPES.has(scope));
|
|
1077
1076
|
if (effectiveSync && !SYNCABLE_SCOPES.has(scope)) {
|
|
1078
1077
|
log(
|
|
@@ -1081,12 +1080,12 @@ function createBase(key, options) {
|
|
|
1081
1080
|
);
|
|
1082
1081
|
}
|
|
1083
1082
|
let instance;
|
|
1084
|
-
if (scope === "
|
|
1085
|
-
instance = new
|
|
1083
|
+
if (scope === "memory" && !isSsrMode) {
|
|
1084
|
+
instance = new MemoryStateImpl(key, rKey, options, config);
|
|
1086
1085
|
} else {
|
|
1087
1086
|
const storageKey = resolveStorageKey(key, options, config.prefix);
|
|
1088
|
-
const baseAdapter =
|
|
1089
|
-
const shouldSync = effectiveSync && SYNCABLE_SCOPES.has(scope) && !
|
|
1087
|
+
const baseAdapter = useMemoryFallback ? createMemoryAdapter(options.default) : resolveAdapter(storageKey, scope, options);
|
|
1088
|
+
const shouldSync = effectiveSync && SYNCABLE_SCOPES.has(scope) && !useMemoryFallback;
|
|
1090
1089
|
const adapter = shouldSync ? withSync(baseAdapter, storageKey, scope) : baseAdapter;
|
|
1091
1090
|
instance = new StateImpl(key, scope, rKey, adapter, options, config);
|
|
1092
1091
|
if (isSsrMode && !isServer()) {
|
|
@@ -1102,7 +1101,7 @@ function createBase(key, options) {
|
|
|
1102
1101
|
config.onHydrate?.({ key, scope, serverValue, clientValue });
|
|
1103
1102
|
realAdapter.destroy?.();
|
|
1104
1103
|
} catch (err) {
|
|
1105
|
-
log("debug", `Hydration adapter unavailable for state("${key}") \u2014 using
|
|
1104
|
+
log("debug", `Hydration adapter unavailable for state("${key}") \u2014 using memory fallback.`);
|
|
1106
1105
|
reportError(key, scope, err);
|
|
1107
1106
|
}
|
|
1108
1107
|
});
|
|
@@ -1112,4 +1111,4 @@ function createBase(key, options) {
|
|
|
1112
1111
|
return instance;
|
|
1113
1112
|
}
|
|
1114
1113
|
|
|
1115
|
-
export { batch, configure, createBase, createListeners,
|
|
1114
|
+
export { batch, configure, createBase, createListeners, createMemoryState, getConfig, getRegistered, getRegistry, log, notify, registerByKey, registerServerAdapter, scopedKey, shallowEqual };
|
|
@@ -369,7 +369,7 @@ function createBucketAdapter(key, bucketOptions, options) {
|
|
|
369
369
|
const listeners = createListeners();
|
|
370
370
|
let lastNotifiedValue = defaultValue;
|
|
371
371
|
const notifyListeners = () => listeners.notify(lastNotifiedValue);
|
|
372
|
-
const fallbackStorage = fallbackScope === "
|
|
372
|
+
const fallbackStorage = fallbackScope === "session" ? sessionStorage : localStorage;
|
|
373
373
|
let delegate = createStorageAdapter(fallbackStorage, key, options);
|
|
374
374
|
let isDestroyed = false;
|
|
375
375
|
const ready = (async () => {
|
|
@@ -449,9 +449,9 @@ function createBucketAdapter(key, bucketOptions, options) {
|
|
|
449
449
|
};
|
|
450
450
|
}
|
|
451
451
|
|
|
452
|
-
// src/adapters/
|
|
452
|
+
// src/adapters/memory.ts
|
|
453
453
|
var RESOLVED = Promise.resolve();
|
|
454
|
-
function
|
|
454
|
+
function createMemoryAdapter(defaultValue) {
|
|
455
455
|
let current = defaultValue;
|
|
456
456
|
const listeners = /* @__PURE__ */ new Set();
|
|
457
457
|
const notifyListeners = () => {
|
|
@@ -539,7 +539,7 @@ function withSync(adapter, key, scope) {
|
|
|
539
539
|
// src/adapters/url.ts
|
|
540
540
|
function createUrlAdapter(key, defaultValue, serializer, persist) {
|
|
541
541
|
if (typeof window === "undefined") {
|
|
542
|
-
throw new Error("[
|
|
542
|
+
throw new Error("[gjendje] URL scope is not available in this environment.");
|
|
543
543
|
}
|
|
544
544
|
const listeners = createListeners();
|
|
545
545
|
const defaultSerialized = serializer.stringify(defaultValue);
|
|
@@ -599,7 +599,7 @@ function createUrlAdapter(key, defaultValue, serializer, persist) {
|
|
|
599
599
|
function isServer() {
|
|
600
600
|
return typeof window === "undefined" || typeof document === "undefined";
|
|
601
601
|
}
|
|
602
|
-
var BROWSER_SCOPES = /* @__PURE__ */ new Set(["session", "
|
|
602
|
+
var BROWSER_SCOPES = /* @__PURE__ */ new Set(["session", "local", "url", "bucket"]);
|
|
603
603
|
function afterHydration(fn) {
|
|
604
604
|
if (isServer()) return Promise.resolve();
|
|
605
605
|
return new Promise((resolve) => {
|
|
@@ -624,10 +624,10 @@ var _serverAdapterFactory;
|
|
|
624
624
|
function registerServerAdapter(factory) {
|
|
625
625
|
_serverAdapterFactory = factory;
|
|
626
626
|
}
|
|
627
|
-
var PERSISTENT_SCOPES = /* @__PURE__ */ new Set(["local", "session", "
|
|
627
|
+
var PERSISTENT_SCOPES = /* @__PURE__ */ new Set(["local", "session", "bucket"]);
|
|
628
628
|
var SYNCABLE_SCOPES = /* @__PURE__ */ new Set(["local", "bucket"]);
|
|
629
629
|
var RESOLVED2 = Promise.resolve();
|
|
630
|
-
var
|
|
630
|
+
var MEMORY_SHIM = {
|
|
631
631
|
ready: RESOLVED2,
|
|
632
632
|
get: () => void 0,
|
|
633
633
|
set: () => {
|
|
@@ -644,19 +644,18 @@ function resolveAdapter(storageKey, scope, options) {
|
|
|
644
644
|
switch (scope) {
|
|
645
645
|
case "memory":
|
|
646
646
|
case "render":
|
|
647
|
-
return
|
|
647
|
+
return createMemoryAdapter(options.default);
|
|
648
648
|
case "session":
|
|
649
|
-
case "tab":
|
|
650
649
|
if (typeof sessionStorage === "undefined") {
|
|
651
650
|
throw new Error(
|
|
652
|
-
'[
|
|
651
|
+
'[gjendje] sessionStorage is not available. Use ssr: true or scope: "memory" for server environments.'
|
|
653
652
|
);
|
|
654
653
|
}
|
|
655
654
|
return createStorageAdapter(sessionStorage, storageKey, options);
|
|
656
655
|
case "local":
|
|
657
656
|
if (typeof localStorage === "undefined") {
|
|
658
657
|
throw new Error(
|
|
659
|
-
'[
|
|
658
|
+
'[gjendje] localStorage is not available. Use ssr: true or scope: "server" for server environments.'
|
|
660
659
|
);
|
|
661
660
|
}
|
|
662
661
|
return createStorageAdapter(localStorage, storageKey, options);
|
|
@@ -673,21 +672,21 @@ function resolveAdapter(storageKey, scope, options) {
|
|
|
673
672
|
case "server":
|
|
674
673
|
if (!_serverAdapterFactory) {
|
|
675
674
|
throw new Error(
|
|
676
|
-
'[
|
|
675
|
+
'[gjendje] scope: "server" requires the server adapter. Import { withServerSession } from "gjendje" or "gjendje/server" to enable it.'
|
|
677
676
|
);
|
|
678
677
|
}
|
|
679
678
|
return _serverAdapterFactory(storageKey, options.default);
|
|
680
679
|
case "bucket": {
|
|
681
680
|
if (!options.bucket) {
|
|
682
681
|
throw new Error(
|
|
683
|
-
'[
|
|
682
|
+
'[gjendje] scope: "bucket" requires a bucket option. Example: { scope: "bucket", bucket: { name: "my-bucket" } }'
|
|
684
683
|
);
|
|
685
684
|
}
|
|
686
685
|
return createBucketAdapter(storageKey, options.bucket, options);
|
|
687
686
|
}
|
|
688
687
|
default: {
|
|
689
688
|
const _exhaustive = scope;
|
|
690
|
-
throw new Error(`[
|
|
689
|
+
throw new Error(`[gjendje] Unknown scope: ${_exhaustive}`);
|
|
691
690
|
}
|
|
692
691
|
}
|
|
693
692
|
}
|
|
@@ -904,15 +903,15 @@ var StateImpl = class {
|
|
|
904
903
|
});
|
|
905
904
|
}
|
|
906
905
|
};
|
|
907
|
-
var
|
|
906
|
+
var MemoryStateImpl = class extends StateImpl {
|
|
908
907
|
// Direct reference — avoids a getter cast on every get()/set() call
|
|
909
908
|
_r;
|
|
910
909
|
_hasIsEqual;
|
|
911
910
|
constructor(key, rKey, options, config) {
|
|
912
|
-
super(key, "
|
|
911
|
+
super(key, "memory", rKey, MEMORY_SHIM, options, config);
|
|
913
912
|
const rs = this._s;
|
|
914
913
|
rs.current = options.default;
|
|
915
|
-
rs.
|
|
914
|
+
rs.memoryListeners = void 0;
|
|
916
915
|
rs.notifyFn = void 0;
|
|
917
916
|
this._r = rs;
|
|
918
917
|
this._hasIsEqual = options.isEqual !== void 0;
|
|
@@ -956,9 +955,9 @@ var RenderStateImpl = class extends StateImpl {
|
|
|
956
955
|
}
|
|
957
956
|
subscribe(listener) {
|
|
958
957
|
const s = this._r;
|
|
959
|
-
if (!s.
|
|
958
|
+
if (!s.memoryListeners) {
|
|
960
959
|
const listeners = /* @__PURE__ */ new Set();
|
|
961
|
-
s.
|
|
960
|
+
s.memoryListeners = listeners;
|
|
962
961
|
s.notifyFn = () => {
|
|
963
962
|
for (const l of listeners) {
|
|
964
963
|
try {
|
|
@@ -969,7 +968,7 @@ var RenderStateImpl = class extends StateImpl {
|
|
|
969
968
|
}
|
|
970
969
|
};
|
|
971
970
|
}
|
|
972
|
-
const set = s.
|
|
971
|
+
const set = s.memoryListeners;
|
|
973
972
|
set.add(listener);
|
|
974
973
|
return () => {
|
|
975
974
|
set.delete(listener);
|
|
@@ -1040,7 +1039,7 @@ var RenderStateImpl = class extends StateImpl {
|
|
|
1040
1039
|
s.changeHandlers?.clear();
|
|
1041
1040
|
s.watchers?.clear();
|
|
1042
1041
|
s.watchUnsub?.();
|
|
1043
|
-
s.
|
|
1042
|
+
s.memoryListeners?.clear();
|
|
1044
1043
|
unregisterByKey(this._rKey);
|
|
1045
1044
|
this._config.onDestroy?.({ key: this.key, scope: this.scope });
|
|
1046
1045
|
if (s.resolveDestroyed) {
|
|
@@ -1050,12 +1049,12 @@ var RenderStateImpl = class extends StateImpl {
|
|
|
1050
1049
|
}
|
|
1051
1050
|
}
|
|
1052
1051
|
};
|
|
1053
|
-
function
|
|
1054
|
-
return new
|
|
1052
|
+
function createMemoryState(key, rKey, options, config) {
|
|
1053
|
+
return new MemoryStateImpl(key, rKey, options, config);
|
|
1055
1054
|
}
|
|
1056
1055
|
function createBase(key, options) {
|
|
1057
1056
|
if (!key) {
|
|
1058
|
-
throw new Error("[
|
|
1057
|
+
throw new Error("[gjendje] key must be a non-empty string.");
|
|
1059
1058
|
}
|
|
1060
1059
|
const config = getConfig();
|
|
1061
1060
|
if (config.keyPattern && !config.keyPattern.test(key)) {
|
|
@@ -1063,8 +1062,8 @@ function createBase(key, options) {
|
|
|
1063
1062
|
`[gjendje] Key "${key}" does not match the configured keyPattern ${config.keyPattern}.`
|
|
1064
1063
|
);
|
|
1065
1064
|
}
|
|
1066
|
-
const rawScope = options.scope ?? config.scope ?? "
|
|
1067
|
-
const scope = rawScope === "
|
|
1065
|
+
const rawScope = options.scope ?? config.scope ?? "memory";
|
|
1066
|
+
const scope = rawScope === "render" ? "memory" : rawScope;
|
|
1068
1067
|
const rKey = scopedKey(key, scope);
|
|
1069
1068
|
const existing = getRegistered(rKey);
|
|
1070
1069
|
if (existing && !existing.isDestroyed) return existing;
|
|
@@ -1074,7 +1073,7 @@ function createBase(key, options) {
|
|
|
1074
1073
|
);
|
|
1075
1074
|
}
|
|
1076
1075
|
const isSsrMode = (options.ssr ?? config.ssr) && BROWSER_SCOPES.has(scope);
|
|
1077
|
-
const
|
|
1076
|
+
const useMemoryFallback = isSsrMode && isServer();
|
|
1078
1077
|
const effectiveSync = options.sync ?? (config.sync && SYNCABLE_SCOPES.has(scope));
|
|
1079
1078
|
if (effectiveSync && !SYNCABLE_SCOPES.has(scope)) {
|
|
1080
1079
|
log(
|
|
@@ -1083,12 +1082,12 @@ function createBase(key, options) {
|
|
|
1083
1082
|
);
|
|
1084
1083
|
}
|
|
1085
1084
|
let instance;
|
|
1086
|
-
if (scope === "
|
|
1087
|
-
instance = new
|
|
1085
|
+
if (scope === "memory" && !isSsrMode) {
|
|
1086
|
+
instance = new MemoryStateImpl(key, rKey, options, config);
|
|
1088
1087
|
} else {
|
|
1089
1088
|
const storageKey = resolveStorageKey(key, options, config.prefix);
|
|
1090
|
-
const baseAdapter =
|
|
1091
|
-
const shouldSync = effectiveSync && SYNCABLE_SCOPES.has(scope) && !
|
|
1089
|
+
const baseAdapter = useMemoryFallback ? createMemoryAdapter(options.default) : resolveAdapter(storageKey, scope, options);
|
|
1090
|
+
const shouldSync = effectiveSync && SYNCABLE_SCOPES.has(scope) && !useMemoryFallback;
|
|
1092
1091
|
const adapter = shouldSync ? withSync(baseAdapter, storageKey, scope) : baseAdapter;
|
|
1093
1092
|
instance = new StateImpl(key, scope, rKey, adapter, options, config);
|
|
1094
1093
|
if (isSsrMode && !isServer()) {
|
|
@@ -1104,7 +1103,7 @@ function createBase(key, options) {
|
|
|
1104
1103
|
config.onHydrate?.({ key, scope, serverValue, clientValue });
|
|
1105
1104
|
realAdapter.destroy?.();
|
|
1106
1105
|
} catch (err) {
|
|
1107
|
-
log("debug", `Hydration adapter unavailable for state("${key}") \u2014 using
|
|
1106
|
+
log("debug", `Hydration adapter unavailable for state("${key}") \u2014 using memory fallback.`);
|
|
1108
1107
|
reportError(key, scope, err);
|
|
1109
1108
|
}
|
|
1110
1109
|
});
|
|
@@ -1118,7 +1117,7 @@ exports.batch = batch;
|
|
|
1118
1117
|
exports.configure = configure;
|
|
1119
1118
|
exports.createBase = createBase;
|
|
1120
1119
|
exports.createListeners = createListeners;
|
|
1121
|
-
exports.
|
|
1120
|
+
exports.createMemoryState = createMemoryState;
|
|
1122
1121
|
exports.getConfig = getConfig;
|
|
1123
1122
|
exports.getRegistered = getRegistered;
|
|
1124
1123
|
exports.getRegistry = getRegistry;
|
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkMEVW62P4_cjs = require('./chunk-MEVW62P4.cjs');
|
|
4
4
|
|
|
5
5
|
// src/collection.ts
|
|
6
6
|
function collection(key, options) {
|
|
7
|
-
const base =
|
|
7
|
+
const base = chunkMEVW62P4_cjs.createBase(key, options);
|
|
8
8
|
const watchers = /* @__PURE__ */ new Map();
|
|
9
9
|
let prevItems = base.get();
|
|
10
10
|
const unsubscribe = base.subscribe((next) => {
|
|
@@ -139,7 +139,7 @@ function collection(key, options) {
|
|
|
139
139
|
// src/computed.ts
|
|
140
140
|
var computedCounter = 0;
|
|
141
141
|
function computed(deps, fn, options) {
|
|
142
|
-
const listeners =
|
|
142
|
+
const listeners = chunkMEVW62P4_cjs.createListeners();
|
|
143
143
|
const instanceKey = options?.key ?? `computed:${computedCounter++}`;
|
|
144
144
|
let cached;
|
|
145
145
|
let isDirty = true;
|
|
@@ -164,7 +164,7 @@ function computed(deps, fn, options) {
|
|
|
164
164
|
};
|
|
165
165
|
const markDirty = () => {
|
|
166
166
|
isDirty = true;
|
|
167
|
-
|
|
167
|
+
chunkMEVW62P4_cjs.notify(notifyListeners);
|
|
168
168
|
};
|
|
169
169
|
const unsubscribers = new Array(depLen);
|
|
170
170
|
for (let i = 0; i < depLen; i++) {
|
|
@@ -178,7 +178,7 @@ function computed(deps, fn, options) {
|
|
|
178
178
|
const hydratedPromise = Promise.all(deps.map((d) => d.hydrated)).then(() => void 0);
|
|
179
179
|
return {
|
|
180
180
|
key: instanceKey,
|
|
181
|
-
scope: "
|
|
181
|
+
scope: "memory",
|
|
182
182
|
get ready() {
|
|
183
183
|
return readyPromise;
|
|
184
184
|
},
|
|
@@ -224,7 +224,7 @@ function computed(deps, fn, options) {
|
|
|
224
224
|
|
|
225
225
|
// src/devtools.ts
|
|
226
226
|
function snapshot() {
|
|
227
|
-
const registry =
|
|
227
|
+
const registry = chunkMEVW62P4_cjs.getRegistry();
|
|
228
228
|
const result = [];
|
|
229
229
|
for (const instance of registry.values()) {
|
|
230
230
|
result.push({
|
|
@@ -407,7 +407,7 @@ function withWatch(instance) {
|
|
|
407
407
|
// src/previous.ts
|
|
408
408
|
var previousCounter = 0;
|
|
409
409
|
function previous(source, options) {
|
|
410
|
-
const listeners =
|
|
410
|
+
const listeners = chunkMEVW62P4_cjs.createListeners();
|
|
411
411
|
const instanceKey = options?.key ?? `previous:${previousCounter++}`;
|
|
412
412
|
let prev;
|
|
413
413
|
let current = source.get();
|
|
@@ -417,14 +417,14 @@ function previous(source, options) {
|
|
|
417
417
|
prev = current;
|
|
418
418
|
current = next;
|
|
419
419
|
if (old !== prev) {
|
|
420
|
-
|
|
420
|
+
chunkMEVW62P4_cjs.notify(() => listeners.notify(prev));
|
|
421
421
|
}
|
|
422
422
|
});
|
|
423
423
|
let destroyedPromise;
|
|
424
424
|
let resolveDestroyed;
|
|
425
425
|
return {
|
|
426
426
|
key: instanceKey,
|
|
427
|
-
scope: "
|
|
427
|
+
scope: "memory",
|
|
428
428
|
get ready() {
|
|
429
429
|
return source.ready;
|
|
430
430
|
},
|
|
@@ -479,7 +479,7 @@ function readonly(instance) {
|
|
|
479
479
|
// src/select.ts
|
|
480
480
|
var selectCounter = 0;
|
|
481
481
|
function select(source, fn, options) {
|
|
482
|
-
const listeners =
|
|
482
|
+
const listeners = chunkMEVW62P4_cjs.createListeners();
|
|
483
483
|
const instanceKey = options?.key ?? `select:${selectCounter++}`;
|
|
484
484
|
let cached;
|
|
485
485
|
let isDirty = true;
|
|
@@ -498,7 +498,7 @@ function select(source, fn, options) {
|
|
|
498
498
|
};
|
|
499
499
|
const markDirty = () => {
|
|
500
500
|
isDirty = true;
|
|
501
|
-
|
|
501
|
+
chunkMEVW62P4_cjs.notify(notifyListeners);
|
|
502
502
|
};
|
|
503
503
|
const unsubscribe = source.subscribe(markDirty);
|
|
504
504
|
recompute();
|
|
@@ -506,7 +506,7 @@ function select(source, fn, options) {
|
|
|
506
506
|
let resolveDestroyed;
|
|
507
507
|
return {
|
|
508
508
|
key: instanceKey,
|
|
509
|
-
scope: "
|
|
509
|
+
scope: "memory",
|
|
510
510
|
get ready() {
|
|
511
511
|
return source.ready;
|
|
512
512
|
},
|
|
@@ -551,36 +551,36 @@ function select(source, fn, options) {
|
|
|
551
551
|
// src/factory.ts
|
|
552
552
|
function createState(key, options) {
|
|
553
553
|
if (!key) {
|
|
554
|
-
throw new Error("[
|
|
554
|
+
throw new Error("[gjendje] key must be a non-empty string.");
|
|
555
555
|
}
|
|
556
|
-
const config =
|
|
556
|
+
const config = chunkMEVW62P4_cjs.getConfig();
|
|
557
557
|
if (config.keyPattern && !config.keyPattern.test(key)) {
|
|
558
558
|
throw new Error(
|
|
559
559
|
`[gjendje] Key "${key}" does not match the configured keyPattern ${config.keyPattern}.`
|
|
560
560
|
);
|
|
561
561
|
}
|
|
562
|
-
const rawScope = options.scope ?? config.scope ?? "
|
|
563
|
-
const scope = rawScope === "
|
|
564
|
-
const rKey =
|
|
565
|
-
const existing =
|
|
562
|
+
const rawScope = options.scope ?? config.scope ?? "memory";
|
|
563
|
+
const scope = rawScope === "render" ? "memory" : rawScope;
|
|
564
|
+
const rKey = chunkMEVW62P4_cjs.scopedKey(key, scope);
|
|
565
|
+
const existing = chunkMEVW62P4_cjs.getRegistered(rKey);
|
|
566
566
|
if (existing && !existing.isDestroyed) {
|
|
567
567
|
if (config.warnOnDuplicate) {
|
|
568
|
-
|
|
568
|
+
chunkMEVW62P4_cjs.log("warn", `Duplicate state("${key}") with scope "${scope}". Returning cached instance.`);
|
|
569
569
|
}
|
|
570
570
|
return existing;
|
|
571
571
|
}
|
|
572
|
-
if (scope === "
|
|
572
|
+
if (scope === "memory" && !options.ssr && !config.ssr) {
|
|
573
573
|
if (options.sync) {
|
|
574
|
-
|
|
574
|
+
chunkMEVW62P4_cjs.log(
|
|
575
575
|
"warn",
|
|
576
|
-
`sync: true is ignored for scope "
|
|
576
|
+
`sync: true is ignored for scope "memory". Only "local" and "bucket" scopes support cross-tab sync.`
|
|
577
577
|
);
|
|
578
578
|
}
|
|
579
|
-
const instance =
|
|
580
|
-
|
|
579
|
+
const instance = chunkMEVW62P4_cjs.createMemoryState(key, rKey, options, config);
|
|
580
|
+
chunkMEVW62P4_cjs.registerByKey(rKey, key, scope, instance, config);
|
|
581
581
|
return instance;
|
|
582
582
|
}
|
|
583
|
-
return
|
|
583
|
+
return chunkMEVW62P4_cjs.createBase(key, options);
|
|
584
584
|
}
|
|
585
585
|
|
|
586
586
|
// src/shortcuts.ts
|
|
@@ -594,14 +594,6 @@ function extractEntry(entry) {
|
|
|
594
594
|
const key = keys[0];
|
|
595
595
|
return [key, entry[key]];
|
|
596
596
|
}
|
|
597
|
-
var _deprecationWarned = /* @__PURE__ */ new Set();
|
|
598
|
-
function warnDeprecated(name) {
|
|
599
|
-
if (_deprecationWarned.has(name)) return;
|
|
600
|
-
_deprecationWarned.add(name);
|
|
601
|
-
console.warn(
|
|
602
|
-
`[gjendje] ${name}() is deprecated and will be removed in the next major version. Use state.${name}() instead. Example: state.${name}({ key: value })`
|
|
603
|
-
);
|
|
604
|
-
}
|
|
605
597
|
function _local(entry, options) {
|
|
606
598
|
const [key, defaultValue] = extractEntry(entry);
|
|
607
599
|
return createState(key, { ...options, default: defaultValue, scope: "local" });
|
|
@@ -641,51 +633,26 @@ _state.url = _url;
|
|
|
641
633
|
_state.bucket = _bucket;
|
|
642
634
|
_state.server = _server;
|
|
643
635
|
var state = _state;
|
|
644
|
-
function local(entry, options) {
|
|
645
|
-
warnDeprecated("local");
|
|
646
|
-
return _local(entry, options);
|
|
647
|
-
}
|
|
648
|
-
function session(entry, options) {
|
|
649
|
-
warnDeprecated("session");
|
|
650
|
-
return _session(entry, options);
|
|
651
|
-
}
|
|
652
|
-
function url(entry, options) {
|
|
653
|
-
warnDeprecated("url");
|
|
654
|
-
return _url(entry, options);
|
|
655
|
-
}
|
|
656
|
-
function server(entry, options) {
|
|
657
|
-
warnDeprecated("server");
|
|
658
|
-
return _server(entry, options);
|
|
659
|
-
}
|
|
660
|
-
function bucket(entry, options) {
|
|
661
|
-
warnDeprecated("bucket");
|
|
662
|
-
return _bucket(entry, options);
|
|
663
|
-
}
|
|
664
636
|
|
|
665
637
|
Object.defineProperty(exports, "batch", {
|
|
666
638
|
enumerable: true,
|
|
667
|
-
get: function () { return
|
|
639
|
+
get: function () { return chunkMEVW62P4_cjs.batch; }
|
|
668
640
|
});
|
|
669
641
|
Object.defineProperty(exports, "configure", {
|
|
670
642
|
enumerable: true,
|
|
671
|
-
get: function () { return
|
|
643
|
+
get: function () { return chunkMEVW62P4_cjs.configure; }
|
|
672
644
|
});
|
|
673
645
|
Object.defineProperty(exports, "shallowEqual", {
|
|
674
646
|
enumerable: true,
|
|
675
|
-
get: function () { return
|
|
647
|
+
get: function () { return chunkMEVW62P4_cjs.shallowEqual; }
|
|
676
648
|
});
|
|
677
|
-
exports.bucket = bucket;
|
|
678
649
|
exports.collection = collection;
|
|
679
650
|
exports.computed = computed;
|
|
680
651
|
exports.effect = effect;
|
|
681
|
-
exports.local = local;
|
|
682
652
|
exports.previous = previous;
|
|
683
653
|
exports.readonly = readonly;
|
|
684
654
|
exports.select = select;
|
|
685
|
-
exports.server = server;
|
|
686
|
-
exports.session = session;
|
|
687
655
|
exports.snapshot = snapshot;
|
|
688
656
|
exports.state = state;
|
|
689
|
-
exports.url = url;
|
|
690
657
|
exports.withHistory = withHistory;
|
|
691
658
|
exports.withWatch = withWatch;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BaseInstance, U as Unsubscribe, S as StateOptions, R as ReadonlyInstance, a as Scope, b as StateInstance } from './types-
|
|
2
|
-
export { A as Adapter, c as BucketOptions, E as Enhancer, L as Listener, d as Serializer } from './types-
|
|
1
|
+
import { B as BaseInstance, U as Unsubscribe, S as StateOptions, R as ReadonlyInstance, a as Scope, b as StateInstance } from './types-DbzCHTo8.cjs';
|
|
2
|
+
export { A as Adapter, c as BucketOptions, E as Enhancer, L as Listener, d as Serializer } from './types-DbzCHTo8.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Runs all state updates inside fn as a single batch.
|
|
@@ -173,7 +173,7 @@ interface ExpireContext {
|
|
|
173
173
|
expiredAt: number;
|
|
174
174
|
}
|
|
175
175
|
interface GjendjeConfig {
|
|
176
|
-
/** Default scope for all state instances. Defaults to `'
|
|
176
|
+
/** Default scope for all state instances. Defaults to `'memory'`. */
|
|
177
177
|
scope?: Scope | undefined;
|
|
178
178
|
/** Enforce a naming pattern for state keys. */
|
|
179
179
|
keyPattern?: RegExp | undefined;
|
|
@@ -183,7 +183,7 @@ interface GjendjeConfig {
|
|
|
183
183
|
maxKeys?: number | undefined;
|
|
184
184
|
/** Prepends to all storage keys (e.g. `myapp:theme`) */
|
|
185
185
|
prefix?: string | undefined;
|
|
186
|
-
/** Require a validate option for persisted scopes (local,
|
|
186
|
+
/** Require a validate option for persisted scopes (local, session, bucket). */
|
|
187
187
|
requireValidation?: boolean | undefined;
|
|
188
188
|
/** Enable SSR mode globally for all instances. */
|
|
189
189
|
ssr?: boolean | undefined;
|
|
@@ -287,7 +287,7 @@ interface HistoryOptions {
|
|
|
287
287
|
* Enhance a state instance with undo/redo capabilities.
|
|
288
288
|
*
|
|
289
289
|
* ```ts
|
|
290
|
-
* const counter = state('counter', { default: 0, scope: '
|
|
290
|
+
* const counter = state('counter', { default: 0, scope: 'memory' })
|
|
291
291
|
* const h = withHistory(counter)
|
|
292
292
|
*
|
|
293
293
|
* h.set(1)
|
|
@@ -423,56 +423,6 @@ interface StateFunction {
|
|
|
423
423
|
server: <T>(entry: Record<string, T>, options?: ShortcutOptions<T>) => StateInstance<T>;
|
|
424
424
|
}
|
|
425
425
|
declare const state: StateFunction;
|
|
426
|
-
/**
|
|
427
|
-
* @deprecated Use `state.local()` instead. Will be removed in the next major version.
|
|
428
|
-
*
|
|
429
|
-
* Create state stored in `localStorage`.
|
|
430
|
-
*
|
|
431
|
-
* ```ts
|
|
432
|
-
* const theme = state.local({ theme: 'light' })
|
|
433
|
-
* ```
|
|
434
|
-
*/
|
|
435
|
-
declare function local<T>(entry: Record<string, T>, options?: ShortcutOptions<T>): StateInstance<T>;
|
|
436
|
-
/**
|
|
437
|
-
* @deprecated Use `state.session()` instead. Will be removed in the next major version.
|
|
438
|
-
*
|
|
439
|
-
* Create state stored in `sessionStorage`.
|
|
440
|
-
*
|
|
441
|
-
* ```ts
|
|
442
|
-
* const draft = state.session({ draft: '' })
|
|
443
|
-
* ```
|
|
444
|
-
*/
|
|
445
|
-
declare function session<T>(entry: Record<string, T>, options?: ShortcutOptions<T>): StateInstance<T>;
|
|
446
|
-
/**
|
|
447
|
-
* @deprecated Use `state.url()` instead. Will be removed in the next major version.
|
|
448
|
-
*
|
|
449
|
-
* Create state stored in `URLSearchParams`.
|
|
450
|
-
*
|
|
451
|
-
* ```ts
|
|
452
|
-
* const filters = state.url({ q: '' })
|
|
453
|
-
* ```
|
|
454
|
-
*/
|
|
455
|
-
declare function url<T>(entry: Record<string, T>, options?: ShortcutOptions<T>): StateInstance<T>;
|
|
456
|
-
/**
|
|
457
|
-
* @deprecated Use `state.server()` instead. Will be removed in the next major version.
|
|
458
|
-
*
|
|
459
|
-
* Create state stored in server-side `AsyncLocalStorage`.
|
|
460
|
-
*
|
|
461
|
-
* ```ts
|
|
462
|
-
* const user = state.server({ user: null })
|
|
463
|
-
* ```
|
|
464
|
-
*/
|
|
465
|
-
declare function server<T>(entry: Record<string, T>, options?: ShortcutOptions<T>): StateInstance<T>;
|
|
466
|
-
/**
|
|
467
|
-
* @deprecated Use `state.bucket()` instead. Will be removed in the next major version.
|
|
468
|
-
*
|
|
469
|
-
* Create state stored in a Storage Bucket.
|
|
470
|
-
*
|
|
471
|
-
* ```ts
|
|
472
|
-
* const data = state.bucket({ cache: [] }, { bucket: { name: 'my-bucket' } })
|
|
473
|
-
* ```
|
|
474
|
-
*/
|
|
475
|
-
declare function bucket<T>(entry: Record<string, T>, options: BucketShortcutOptions<T>): StateInstance<T>;
|
|
476
426
|
|
|
477
427
|
/**
|
|
478
428
|
* Shallow equality check for primitives, arrays, and plain objects.
|
|
@@ -480,4 +430,4 @@ declare function bucket<T>(entry: Record<string, T>, options: BucketShortcutOpti
|
|
|
480
430
|
*/
|
|
481
431
|
declare function shallowEqual(a: unknown, b: unknown): boolean;
|
|
482
432
|
|
|
483
|
-
export { BaseInstance, type ChangeContext, type CollectionInstance, type ComputedInstance, type ComputedOptions, type DestroyContext, type EffectHandle, type ErrorContext, type ExpireContext, type GjendjeConfig, type HistoryOptions, type HydrateContext, type InterceptContext, type LogLevel, type MigrateContext, type PreviousInstance, type PreviousOptions, type QuotaExceededContext, ReadonlyInstance, type RegisterContext, type ResetContext, Scope, type SelectInstance, type SelectOptions, type StateFunction, StateInstance, StateOptions, type StateSnapshot, type SyncContext, Unsubscribe, type ValidationFailContext, type WithHistoryInstance, type WithWatch, batch,
|
|
433
|
+
export { BaseInstance, type ChangeContext, type CollectionInstance, type ComputedInstance, type ComputedOptions, type DestroyContext, type EffectHandle, type ErrorContext, type ExpireContext, type GjendjeConfig, type HistoryOptions, type HydrateContext, type InterceptContext, type LogLevel, type MigrateContext, type PreviousInstance, type PreviousOptions, type QuotaExceededContext, ReadonlyInstance, type RegisterContext, type ResetContext, Scope, type SelectInstance, type SelectOptions, type StateFunction, StateInstance, StateOptions, type StateSnapshot, type SyncContext, Unsubscribe, type ValidationFailContext, type WithHistoryInstance, type WithWatch, batch, collection, computed, configure, effect, previous, readonly, select, shallowEqual, snapshot, state, withHistory, withWatch };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BaseInstance, U as Unsubscribe, S as StateOptions, R as ReadonlyInstance, a as Scope, b as StateInstance } from './types-
|
|
2
|
-
export { A as Adapter, c as BucketOptions, E as Enhancer, L as Listener, d as Serializer } from './types-
|
|
1
|
+
import { B as BaseInstance, U as Unsubscribe, S as StateOptions, R as ReadonlyInstance, a as Scope, b as StateInstance } from './types-DbzCHTo8.js';
|
|
2
|
+
export { A as Adapter, c as BucketOptions, E as Enhancer, L as Listener, d as Serializer } from './types-DbzCHTo8.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Runs all state updates inside fn as a single batch.
|
|
@@ -173,7 +173,7 @@ interface ExpireContext {
|
|
|
173
173
|
expiredAt: number;
|
|
174
174
|
}
|
|
175
175
|
interface GjendjeConfig {
|
|
176
|
-
/** Default scope for all state instances. Defaults to `'
|
|
176
|
+
/** Default scope for all state instances. Defaults to `'memory'`. */
|
|
177
177
|
scope?: Scope | undefined;
|
|
178
178
|
/** Enforce a naming pattern for state keys. */
|
|
179
179
|
keyPattern?: RegExp | undefined;
|
|
@@ -183,7 +183,7 @@ interface GjendjeConfig {
|
|
|
183
183
|
maxKeys?: number | undefined;
|
|
184
184
|
/** Prepends to all storage keys (e.g. `myapp:theme`) */
|
|
185
185
|
prefix?: string | undefined;
|
|
186
|
-
/** Require a validate option for persisted scopes (local,
|
|
186
|
+
/** Require a validate option for persisted scopes (local, session, bucket). */
|
|
187
187
|
requireValidation?: boolean | undefined;
|
|
188
188
|
/** Enable SSR mode globally for all instances. */
|
|
189
189
|
ssr?: boolean | undefined;
|
|
@@ -287,7 +287,7 @@ interface HistoryOptions {
|
|
|
287
287
|
* Enhance a state instance with undo/redo capabilities.
|
|
288
288
|
*
|
|
289
289
|
* ```ts
|
|
290
|
-
* const counter = state('counter', { default: 0, scope: '
|
|
290
|
+
* const counter = state('counter', { default: 0, scope: 'memory' })
|
|
291
291
|
* const h = withHistory(counter)
|
|
292
292
|
*
|
|
293
293
|
* h.set(1)
|
|
@@ -423,56 +423,6 @@ interface StateFunction {
|
|
|
423
423
|
server: <T>(entry: Record<string, T>, options?: ShortcutOptions<T>) => StateInstance<T>;
|
|
424
424
|
}
|
|
425
425
|
declare const state: StateFunction;
|
|
426
|
-
/**
|
|
427
|
-
* @deprecated Use `state.local()` instead. Will be removed in the next major version.
|
|
428
|
-
*
|
|
429
|
-
* Create state stored in `localStorage`.
|
|
430
|
-
*
|
|
431
|
-
* ```ts
|
|
432
|
-
* const theme = state.local({ theme: 'light' })
|
|
433
|
-
* ```
|
|
434
|
-
*/
|
|
435
|
-
declare function local<T>(entry: Record<string, T>, options?: ShortcutOptions<T>): StateInstance<T>;
|
|
436
|
-
/**
|
|
437
|
-
* @deprecated Use `state.session()` instead. Will be removed in the next major version.
|
|
438
|
-
*
|
|
439
|
-
* Create state stored in `sessionStorage`.
|
|
440
|
-
*
|
|
441
|
-
* ```ts
|
|
442
|
-
* const draft = state.session({ draft: '' })
|
|
443
|
-
* ```
|
|
444
|
-
*/
|
|
445
|
-
declare function session<T>(entry: Record<string, T>, options?: ShortcutOptions<T>): StateInstance<T>;
|
|
446
|
-
/**
|
|
447
|
-
* @deprecated Use `state.url()` instead. Will be removed in the next major version.
|
|
448
|
-
*
|
|
449
|
-
* Create state stored in `URLSearchParams`.
|
|
450
|
-
*
|
|
451
|
-
* ```ts
|
|
452
|
-
* const filters = state.url({ q: '' })
|
|
453
|
-
* ```
|
|
454
|
-
*/
|
|
455
|
-
declare function url<T>(entry: Record<string, T>, options?: ShortcutOptions<T>): StateInstance<T>;
|
|
456
|
-
/**
|
|
457
|
-
* @deprecated Use `state.server()` instead. Will be removed in the next major version.
|
|
458
|
-
*
|
|
459
|
-
* Create state stored in server-side `AsyncLocalStorage`.
|
|
460
|
-
*
|
|
461
|
-
* ```ts
|
|
462
|
-
* const user = state.server({ user: null })
|
|
463
|
-
* ```
|
|
464
|
-
*/
|
|
465
|
-
declare function server<T>(entry: Record<string, T>, options?: ShortcutOptions<T>): StateInstance<T>;
|
|
466
|
-
/**
|
|
467
|
-
* @deprecated Use `state.bucket()` instead. Will be removed in the next major version.
|
|
468
|
-
*
|
|
469
|
-
* Create state stored in a Storage Bucket.
|
|
470
|
-
*
|
|
471
|
-
* ```ts
|
|
472
|
-
* const data = state.bucket({ cache: [] }, { bucket: { name: 'my-bucket' } })
|
|
473
|
-
* ```
|
|
474
|
-
*/
|
|
475
|
-
declare function bucket<T>(entry: Record<string, T>, options: BucketShortcutOptions<T>): StateInstance<T>;
|
|
476
426
|
|
|
477
427
|
/**
|
|
478
428
|
* Shallow equality check for primitives, arrays, and plain objects.
|
|
@@ -480,4 +430,4 @@ declare function bucket<T>(entry: Record<string, T>, options: BucketShortcutOpti
|
|
|
480
430
|
*/
|
|
481
431
|
declare function shallowEqual(a: unknown, b: unknown): boolean;
|
|
482
432
|
|
|
483
|
-
export { BaseInstance, type ChangeContext, type CollectionInstance, type ComputedInstance, type ComputedOptions, type DestroyContext, type EffectHandle, type ErrorContext, type ExpireContext, type GjendjeConfig, type HistoryOptions, type HydrateContext, type InterceptContext, type LogLevel, type MigrateContext, type PreviousInstance, type PreviousOptions, type QuotaExceededContext, ReadonlyInstance, type RegisterContext, type ResetContext, Scope, type SelectInstance, type SelectOptions, type StateFunction, StateInstance, StateOptions, type StateSnapshot, type SyncContext, Unsubscribe, type ValidationFailContext, type WithHistoryInstance, type WithWatch, batch,
|
|
433
|
+
export { BaseInstance, type ChangeContext, type CollectionInstance, type ComputedInstance, type ComputedOptions, type DestroyContext, type EffectHandle, type ErrorContext, type ExpireContext, type GjendjeConfig, type HistoryOptions, type HydrateContext, type InterceptContext, type LogLevel, type MigrateContext, type PreviousInstance, type PreviousOptions, type QuotaExceededContext, ReadonlyInstance, type RegisterContext, type ResetContext, Scope, type SelectInstance, type SelectOptions, type StateFunction, StateInstance, StateOptions, type StateSnapshot, type SyncContext, Unsubscribe, type ValidationFailContext, type WithHistoryInstance, type WithWatch, batch, collection, computed, configure, effect, previous, readonly, select, shallowEqual, snapshot, state, withHistory, withWatch };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createBase, createListeners, getRegistry, notify, getConfig, scopedKey, getRegistered, log,
|
|
2
|
-
export { batch, configure, shallowEqual } from './chunk-
|
|
1
|
+
import { createBase, createListeners, getRegistry, notify, getConfig, scopedKey, getRegistered, log, createMemoryState, registerByKey } from './chunk-4ZTPYOIR.js';
|
|
2
|
+
export { batch, configure, shallowEqual } from './chunk-4ZTPYOIR.js';
|
|
3
3
|
|
|
4
4
|
// src/collection.ts
|
|
5
5
|
function collection(key, options) {
|
|
@@ -177,7 +177,7 @@ function computed(deps, fn, options) {
|
|
|
177
177
|
const hydratedPromise = Promise.all(deps.map((d) => d.hydrated)).then(() => void 0);
|
|
178
178
|
return {
|
|
179
179
|
key: instanceKey,
|
|
180
|
-
scope: "
|
|
180
|
+
scope: "memory",
|
|
181
181
|
get ready() {
|
|
182
182
|
return readyPromise;
|
|
183
183
|
},
|
|
@@ -423,7 +423,7 @@ function previous(source, options) {
|
|
|
423
423
|
let resolveDestroyed;
|
|
424
424
|
return {
|
|
425
425
|
key: instanceKey,
|
|
426
|
-
scope: "
|
|
426
|
+
scope: "memory",
|
|
427
427
|
get ready() {
|
|
428
428
|
return source.ready;
|
|
429
429
|
},
|
|
@@ -505,7 +505,7 @@ function select(source, fn, options) {
|
|
|
505
505
|
let resolveDestroyed;
|
|
506
506
|
return {
|
|
507
507
|
key: instanceKey,
|
|
508
|
-
scope: "
|
|
508
|
+
scope: "memory",
|
|
509
509
|
get ready() {
|
|
510
510
|
return source.ready;
|
|
511
511
|
},
|
|
@@ -550,7 +550,7 @@ function select(source, fn, options) {
|
|
|
550
550
|
// src/factory.ts
|
|
551
551
|
function createState(key, options) {
|
|
552
552
|
if (!key) {
|
|
553
|
-
throw new Error("[
|
|
553
|
+
throw new Error("[gjendje] key must be a non-empty string.");
|
|
554
554
|
}
|
|
555
555
|
const config = getConfig();
|
|
556
556
|
if (config.keyPattern && !config.keyPattern.test(key)) {
|
|
@@ -558,8 +558,8 @@ function createState(key, options) {
|
|
|
558
558
|
`[gjendje] Key "${key}" does not match the configured keyPattern ${config.keyPattern}.`
|
|
559
559
|
);
|
|
560
560
|
}
|
|
561
|
-
const rawScope = options.scope ?? config.scope ?? "
|
|
562
|
-
const scope = rawScope === "
|
|
561
|
+
const rawScope = options.scope ?? config.scope ?? "memory";
|
|
562
|
+
const scope = rawScope === "render" ? "memory" : rawScope;
|
|
563
563
|
const rKey = scopedKey(key, scope);
|
|
564
564
|
const existing = getRegistered(rKey);
|
|
565
565
|
if (existing && !existing.isDestroyed) {
|
|
@@ -568,14 +568,14 @@ function createState(key, options) {
|
|
|
568
568
|
}
|
|
569
569
|
return existing;
|
|
570
570
|
}
|
|
571
|
-
if (scope === "
|
|
571
|
+
if (scope === "memory" && !options.ssr && !config.ssr) {
|
|
572
572
|
if (options.sync) {
|
|
573
573
|
log(
|
|
574
574
|
"warn",
|
|
575
|
-
`sync: true is ignored for scope "
|
|
575
|
+
`sync: true is ignored for scope "memory". Only "local" and "bucket" scopes support cross-tab sync.`
|
|
576
576
|
);
|
|
577
577
|
}
|
|
578
|
-
const instance =
|
|
578
|
+
const instance = createMemoryState(key, rKey, options, config);
|
|
579
579
|
registerByKey(rKey, key, scope, instance, config);
|
|
580
580
|
return instance;
|
|
581
581
|
}
|
|
@@ -593,14 +593,6 @@ function extractEntry(entry) {
|
|
|
593
593
|
const key = keys[0];
|
|
594
594
|
return [key, entry[key]];
|
|
595
595
|
}
|
|
596
|
-
var _deprecationWarned = /* @__PURE__ */ new Set();
|
|
597
|
-
function warnDeprecated(name) {
|
|
598
|
-
if (_deprecationWarned.has(name)) return;
|
|
599
|
-
_deprecationWarned.add(name);
|
|
600
|
-
console.warn(
|
|
601
|
-
`[gjendje] ${name}() is deprecated and will be removed in the next major version. Use state.${name}() instead. Example: state.${name}({ key: value })`
|
|
602
|
-
);
|
|
603
|
-
}
|
|
604
596
|
function _local(entry, options) {
|
|
605
597
|
const [key, defaultValue] = extractEntry(entry);
|
|
606
598
|
return createState(key, { ...options, default: defaultValue, scope: "local" });
|
|
@@ -640,25 +632,5 @@ _state.url = _url;
|
|
|
640
632
|
_state.bucket = _bucket;
|
|
641
633
|
_state.server = _server;
|
|
642
634
|
var state = _state;
|
|
643
|
-
function local(entry, options) {
|
|
644
|
-
warnDeprecated("local");
|
|
645
|
-
return _local(entry, options);
|
|
646
|
-
}
|
|
647
|
-
function session(entry, options) {
|
|
648
|
-
warnDeprecated("session");
|
|
649
|
-
return _session(entry, options);
|
|
650
|
-
}
|
|
651
|
-
function url(entry, options) {
|
|
652
|
-
warnDeprecated("url");
|
|
653
|
-
return _url(entry, options);
|
|
654
|
-
}
|
|
655
|
-
function server(entry, options) {
|
|
656
|
-
warnDeprecated("server");
|
|
657
|
-
return _server(entry, options);
|
|
658
|
-
}
|
|
659
|
-
function bucket(entry, options) {
|
|
660
|
-
warnDeprecated("bucket");
|
|
661
|
-
return _bucket(entry, options);
|
|
662
|
-
}
|
|
663
635
|
|
|
664
|
-
export {
|
|
636
|
+
export { collection, computed, effect, previous, readonly, select, snapshot, state, withHistory, withWatch };
|
package/dist/server.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkMEVW62P4_cjs = require('./chunk-MEVW62P4.cjs');
|
|
4
4
|
var async_hooks = require('async_hooks');
|
|
5
5
|
|
|
6
6
|
var als = new async_hooks.AsyncLocalStorage();
|
|
@@ -9,7 +9,7 @@ async function withServerSession(fn) {
|
|
|
9
9
|
return als.run(store, fn);
|
|
10
10
|
}
|
|
11
11
|
function createServerAdapter(key, defaultValue) {
|
|
12
|
-
const listeners =
|
|
12
|
+
const listeners = chunkMEVW62P4_cjs.createListeners();
|
|
13
13
|
function getStore() {
|
|
14
14
|
return als.getStore();
|
|
15
15
|
}
|
|
@@ -26,12 +26,12 @@ function createServerAdapter(key, defaultValue) {
|
|
|
26
26
|
const store = getStore();
|
|
27
27
|
if (!store) {
|
|
28
28
|
throw new Error(
|
|
29
|
-
"[
|
|
29
|
+
"[gjendje] Cannot set server-scoped state outside of a server session. Wrap your request handler with withServerSession()."
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
store.set(key, value);
|
|
33
33
|
lastNotifiedValue = value;
|
|
34
|
-
|
|
34
|
+
chunkMEVW62P4_cjs.notify(notifyListeners);
|
|
35
35
|
},
|
|
36
36
|
subscribe: listeners.subscribe,
|
|
37
37
|
destroy() {
|
|
@@ -39,7 +39,7 @@ function createServerAdapter(key, defaultValue) {
|
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
chunkMEVW62P4_cjs.registerServerAdapter(createServerAdapter);
|
|
43
43
|
|
|
44
44
|
exports.createServerAdapter = createServerAdapter;
|
|
45
45
|
exports.withServerSession = withServerSession;
|
package/dist/server.d.cts
CHANGED
package/dist/server.d.ts
CHANGED
package/dist/server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { registerServerAdapter, createListeners, notify } from './chunk-
|
|
1
|
+
import { registerServerAdapter, createListeners, notify } from './chunk-4ZTPYOIR.js';
|
|
2
2
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
3
3
|
|
|
4
4
|
var als = new AsyncLocalStorage();
|
|
@@ -24,7 +24,7 @@ function createServerAdapter(key, defaultValue) {
|
|
|
24
24
|
const store = getStore();
|
|
25
25
|
if (!store) {
|
|
26
26
|
throw new Error(
|
|
27
|
-
"[
|
|
27
|
+
"[gjendje] Cannot set server-scoped state outside of a server session. Wrap your request handler with withServerSession()."
|
|
28
28
|
);
|
|
29
29
|
}
|
|
30
30
|
store.set(key, value);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type Scope = 'memory' | 'render' | 'session' | '
|
|
1
|
+
type Scope = 'memory' | 'render' | 'session' | 'local' | 'url' | 'server' | 'bucket';
|
|
2
2
|
interface Adapter<T> {
|
|
3
3
|
get(): T;
|
|
4
4
|
set(value: T): void;
|
|
@@ -106,12 +106,12 @@ interface BucketOptions {
|
|
|
106
106
|
* Scope to use if the Storage Buckets API is not available.
|
|
107
107
|
* Defaults to 'local'.
|
|
108
108
|
*/
|
|
109
|
-
fallback?: 'local' | 'session'
|
|
109
|
+
fallback?: 'local' | 'session';
|
|
110
110
|
}
|
|
111
111
|
interface StateOptions<T> {
|
|
112
112
|
/** Initial / default value */
|
|
113
113
|
default: T;
|
|
114
|
-
/** Where state should live. Defaults to '
|
|
114
|
+
/** Where state should live. Defaults to 'memory'. */
|
|
115
115
|
scope?: Scope;
|
|
116
116
|
/**
|
|
117
117
|
* Storage bucket options. Required when scope is 'bucket'.
|
|
@@ -125,7 +125,7 @@ interface StateOptions<T> {
|
|
|
125
125
|
serialize?: Serializer<T>;
|
|
126
126
|
/**
|
|
127
127
|
* Enable SSR safety. When true:
|
|
128
|
-
* - On server: silently falls back to '
|
|
128
|
+
* - On server: silently falls back to 'memory' scope
|
|
129
129
|
* - On client before hydration: uses default value to match server output
|
|
130
130
|
* - On client after hydration: reads real storage and emits update if different
|
|
131
131
|
*/
|
|
@@ -156,7 +156,7 @@ interface StateOptions<T> {
|
|
|
156
156
|
* When true, any set() call is also sent to other open tabs,
|
|
157
157
|
* and incoming changes from other tabs update this instance.
|
|
158
158
|
*
|
|
159
|
-
* Works with
|
|
159
|
+
* Works with `local` and `bucket` scopes only.
|
|
160
160
|
*/
|
|
161
161
|
sync?: boolean;
|
|
162
162
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type Scope = 'memory' | 'render' | 'session' | '
|
|
1
|
+
type Scope = 'memory' | 'render' | 'session' | 'local' | 'url' | 'server' | 'bucket';
|
|
2
2
|
interface Adapter<T> {
|
|
3
3
|
get(): T;
|
|
4
4
|
set(value: T): void;
|
|
@@ -106,12 +106,12 @@ interface BucketOptions {
|
|
|
106
106
|
* Scope to use if the Storage Buckets API is not available.
|
|
107
107
|
* Defaults to 'local'.
|
|
108
108
|
*/
|
|
109
|
-
fallback?: 'local' | 'session'
|
|
109
|
+
fallback?: 'local' | 'session';
|
|
110
110
|
}
|
|
111
111
|
interface StateOptions<T> {
|
|
112
112
|
/** Initial / default value */
|
|
113
113
|
default: T;
|
|
114
|
-
/** Where state should live. Defaults to '
|
|
114
|
+
/** Where state should live. Defaults to 'memory'. */
|
|
115
115
|
scope?: Scope;
|
|
116
116
|
/**
|
|
117
117
|
* Storage bucket options. Required when scope is 'bucket'.
|
|
@@ -125,7 +125,7 @@ interface StateOptions<T> {
|
|
|
125
125
|
serialize?: Serializer<T>;
|
|
126
126
|
/**
|
|
127
127
|
* Enable SSR safety. When true:
|
|
128
|
-
* - On server: silently falls back to '
|
|
128
|
+
* - On server: silently falls back to 'memory' scope
|
|
129
129
|
* - On client before hydration: uses default value to match server output
|
|
130
130
|
* - On client after hydration: reads real storage and emits update if different
|
|
131
131
|
*/
|
|
@@ -156,7 +156,7 @@ interface StateOptions<T> {
|
|
|
156
156
|
* When true, any set() call is also sent to other open tabs,
|
|
157
157
|
* and incoming changes from other tabs update this instance.
|
|
158
158
|
*
|
|
159
|
-
* Works with
|
|
159
|
+
* Works with `local` and `bucket` scopes only.
|
|
160
160
|
*/
|
|
161
161
|
sync?: boolean;
|
|
162
162
|
/**
|