@sveltebase/state 0.3.2 → 0.3.4
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 +78 -114
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/state.svelte.d.ts +3 -2
- package/dist/state.svelte.d.ts.map +1 -1
- package/dist/state.svelte.js +8 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,80 +1,56 @@
|
|
|
1
1
|
# `@sveltebase/state`
|
|
2
2
|
|
|
3
|
-
Small
|
|
3
|
+
Small state helpers for Svelte 5.
|
|
4
4
|
|
|
5
|
-
This package
|
|
5
|
+
This package exports two classes:
|
|
6
6
|
|
|
7
|
-
- `State<T
|
|
8
|
-
- `PersistentState<TSchema
|
|
7
|
+
- `State<T>`: simple reactive in-memory state
|
|
8
|
+
- `PersistentState<TSchema>`: reactive state backed by cookies and validated with `zod`
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
bun add @sveltebase/state zod
|
|
14
|
-
|
|
12
|
+
~~~bash
|
|
13
|
+
bun add @sveltebase/state zod svelte
|
|
14
|
+
~~~
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
bun add svelte
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## What it exports
|
|
16
|
+
## Exports
|
|
23
17
|
|
|
24
18
|
- `State`
|
|
25
19
|
- `PersistentState`
|
|
26
20
|
|
|
27
21
|
## `State`
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
### Example
|
|
23
|
+
A tiny wrapper around a value.
|
|
32
24
|
|
|
33
|
-
|
|
25
|
+
~~~ts
|
|
34
26
|
import { State } from "@sveltebase/state";
|
|
35
27
|
|
|
36
|
-
const
|
|
28
|
+
const count = new State(0);
|
|
37
29
|
|
|
38
|
-
|
|
39
|
-
|
|
30
|
+
count.current = 1;
|
|
31
|
+
count.set((value) => value + 1);
|
|
40
32
|
|
|
41
|
-
console.log(
|
|
42
|
-
|
|
33
|
+
console.log(count.current); // 2
|
|
34
|
+
~~~
|
|
43
35
|
|
|
44
36
|
### API
|
|
45
37
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
#### `state.current`
|
|
51
|
-
|
|
52
|
-
Gets or sets the current value.
|
|
53
|
-
|
|
54
|
-
#### `state.set(updater)`
|
|
55
|
-
|
|
56
|
-
Updates the current value using a callback.
|
|
38
|
+
- `new State(initialValue)`
|
|
39
|
+
- `state.current`
|
|
40
|
+
- `state.set(updater)`
|
|
57
41
|
|
|
58
42
|
## `PersistentState`
|
|
59
43
|
|
|
60
|
-
|
|
44
|
+
Cookie-backed state with schema validation.
|
|
61
45
|
|
|
62
|
-
|
|
63
|
-
- hydrates from cookies in the browser
|
|
64
|
-
- can be initialized from request cookies during SSR
|
|
65
|
-
- writes changes back to cookies automatically
|
|
46
|
+
It:
|
|
66
47
|
|
|
67
|
-
|
|
48
|
+
- reads from cookies
|
|
49
|
+
- validates with `zod`
|
|
50
|
+
- writes updates back to cookies
|
|
51
|
+
- can load the initial value during SSR
|
|
68
52
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
bun add zod
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## Example
|
|
76
|
-
|
|
77
|
-
```ts
|
|
53
|
+
~~~ts
|
|
78
54
|
import { z } from "zod";
|
|
79
55
|
import { PersistentState } from "@sveltebase/state";
|
|
80
56
|
|
|
@@ -82,107 +58,95 @@ const themeSchema = z.enum(["light", "dark"]).default("light");
|
|
|
82
58
|
|
|
83
59
|
export const theme = new PersistentState("theme", themeSchema);
|
|
84
60
|
|
|
85
|
-
// read
|
|
86
|
-
console.log(theme.current);
|
|
87
|
-
|
|
88
|
-
// write
|
|
89
61
|
theme.current = "dark";
|
|
90
|
-
|
|
91
|
-
// update
|
|
92
62
|
theme.set((value) => (value === "dark" ? "light" : "dark"));
|
|
93
|
-
|
|
63
|
+
~~~
|
|
94
64
|
|
|
95
|
-
## SSR
|
|
65
|
+
## SSR setup
|
|
96
66
|
|
|
97
|
-
|
|
67
|
+
For SSR, return all cookies from `+layout.server.ts`, then initialize the state with `state.init(() => data.cookies)` so it loads the server value first.
|
|
98
68
|
|
|
99
|
-
|
|
100
|
-
import { z } from "zod";
|
|
101
|
-
import { PersistentState } from "@sveltebase/state";
|
|
69
|
+
### `src/routes/+layout.server.ts`
|
|
102
70
|
|
|
103
|
-
|
|
71
|
+
~~~ts
|
|
72
|
+
export async function load({ cookies }) {
|
|
73
|
+
return {
|
|
74
|
+
cookies: cookies.getAll()
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
~~~
|
|
104
78
|
|
|
105
|
-
|
|
79
|
+
### `src/routes/+layout.svelte`
|
|
106
80
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
|
|
81
|
+
~~~svelte
|
|
82
|
+
<script lang="ts">
|
|
83
|
+
import type { LayoutData } from "./$types";
|
|
84
|
+
import { locale } from "$lib/state";
|
|
111
85
|
|
|
112
|
-
|
|
113
|
-
```
|
|
86
|
+
let { data }: { data: LayoutData } = $props();
|
|
114
87
|
|
|
115
|
-
|
|
88
|
+
locale.init(() => data.cookies);
|
|
89
|
+
</script>
|
|
116
90
|
|
|
117
|
-
|
|
91
|
+
<slot />
|
|
92
|
+
~~~
|
|
118
93
|
|
|
119
|
-
|
|
120
|
-
- On updates, it writes the new value back to the cookie
|
|
121
|
-
- On the server, you can call `init(cookies)` to sync the initial value from request cookies
|
|
94
|
+
### `src/lib/state.ts`
|
|
122
95
|
|
|
123
|
-
|
|
96
|
+
~~~ts
|
|
97
|
+
import { z } from "zod";
|
|
98
|
+
import { PersistentState } from "@sveltebase/state";
|
|
99
|
+
|
|
100
|
+
export const locale = new PersistentState(
|
|
101
|
+
"locale",
|
|
102
|
+
z.enum(["en", "uz"]).default("en")
|
|
103
|
+
);
|
|
104
|
+
~~~
|
|
105
|
+
|
|
106
|
+
With this setup:
|
|
107
|
+
|
|
108
|
+
- on the server, `init` reads from `data.cookies`
|
|
109
|
+
- the initial SSR render uses that cookie value
|
|
110
|
+
- in the browser, updates keep syncing back to cookies
|
|
124
111
|
|
|
125
112
|
## API
|
|
126
113
|
|
|
127
114
|
### `new PersistentState(key, schema)`
|
|
128
115
|
|
|
129
|
-
Creates a persistent
|
|
116
|
+
Creates a persistent state value.
|
|
130
117
|
|
|
131
118
|
- `key`: cookie name
|
|
132
|
-
- `schema`: `zod` schema
|
|
119
|
+
- `schema`: `zod` schema for parsing and validation
|
|
133
120
|
|
|
134
121
|
### `persistentState.current`
|
|
135
122
|
|
|
136
|
-
Gets or sets the
|
|
123
|
+
Gets or sets the current value.
|
|
137
124
|
|
|
138
125
|
### `persistentState.set(updater)`
|
|
139
126
|
|
|
140
|
-
Updates the current value
|
|
127
|
+
Updates the current value.
|
|
141
128
|
|
|
142
129
|
### `persistentState.init(cookies)`
|
|
143
130
|
|
|
144
|
-
|
|
131
|
+
Loads the value from server cookies.
|
|
132
|
+
|
|
133
|
+
It accepts either:
|
|
145
134
|
|
|
146
|
-
|
|
135
|
+
- a cookie array
|
|
136
|
+
- a getter function like `() => data.cookies`
|
|
147
137
|
|
|
148
|
-
|
|
138
|
+
Expected cookie shape:
|
|
139
|
+
|
|
140
|
+
~~~ts
|
|
149
141
|
type Cookie = {
|
|
150
142
|
name: string;
|
|
151
143
|
value: string;
|
|
152
144
|
};
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
## Example with Svelte
|
|
156
|
-
|
|
157
|
-
```svelte
|
|
158
|
-
<script lang="ts">
|
|
159
|
-
import { z } from "zod";
|
|
160
|
-
import { State, PersistentState } from "@sveltebase/state";
|
|
161
|
-
|
|
162
|
-
const count = new State(0);
|
|
163
|
-
const locale = new PersistentState("locale", z.enum(["en", "uz"]).default("en"));
|
|
164
|
-
|
|
165
|
-
function increment() {
|
|
166
|
-
count.set((value) => value + 1);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function toggleLocale() {
|
|
170
|
-
locale.current = locale.current === "en" ? "uz" : "en";
|
|
171
|
-
}
|
|
172
|
-
</script>
|
|
173
|
-
|
|
174
|
-
<button onclick={increment}>
|
|
175
|
-
Count: {count.current}
|
|
176
|
-
</button>
|
|
177
|
-
|
|
178
|
-
<button onclick={toggleLocale}>
|
|
179
|
-
Locale: {locale.current}
|
|
180
|
-
</button>
|
|
181
|
-
```
|
|
145
|
+
~~~
|
|
182
146
|
|
|
183
147
|
## Notes
|
|
184
148
|
|
|
185
|
-
- `PersistentState`
|
|
186
|
-
-
|
|
187
|
-
-
|
|
149
|
+
- `PersistentState` stores JSON in cookies
|
|
150
|
+
- invalid cookie data falls back to the schema result
|
|
151
|
+
- `init(...)` is for server-side initialization
|
|
188
152
|
- this package is designed for Svelte 5
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/state.svelte.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
export type MaybeGetter<T> = T | (() => T);
|
|
2
3
|
export declare class PersistentState<TSchema extends z.ZodTypeAny> {
|
|
3
4
|
#private;
|
|
4
5
|
private storageKey;
|
|
@@ -6,10 +7,10 @@ export declare class PersistentState<TSchema extends z.ZodTypeAny> {
|
|
|
6
7
|
constructor(key: string, schema: TSchema);
|
|
7
8
|
get current(): z.output<TSchema>;
|
|
8
9
|
set current(newValue: z.output<TSchema>);
|
|
9
|
-
init(cookies: {
|
|
10
|
+
init(cookies: MaybeGetter<{
|
|
10
11
|
name: string;
|
|
11
12
|
value: string;
|
|
12
|
-
}[]): void;
|
|
13
|
+
}[]>): void;
|
|
13
14
|
set(fn: (value: z.output<TSchema>) => z.output<TSchema>): void;
|
|
14
15
|
private static hydrate;
|
|
15
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.svelte.d.ts","sourceRoot":"","sources":["../src/state.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,qBAAa,eAAe,CAAC,OAAO,SAAS,CAAC,CAAC,UAAU;;
|
|
1
|
+
{"version":3,"file":"state.svelte.d.ts","sourceRoot":"","sources":["../src/state.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAE3C,qBAAa,eAAe,CAAC,OAAO,SAAS,CAAC,CAAC,UAAU;;IAIvD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAU;gBAEZ,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAmBxC,IAAI,OAAO,IAIW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAFtC;IAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAEtC;IAEM,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAyB5D,GAAG,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IAI9D,OAAO,CAAC,MAAM,CAAC,OAAO;CAiBvB;AAED,qBAAa,KAAK,CAAC,CAAC;;gBAGN,YAAY,EAAE,CAAC;IAI3B,IAAI,OAAO,IAIQ,CAAC,CAFnB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,EAEnB;IAED,GAAG,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC;CAGxB"}
|
package/dist/state.svelte.js
CHANGED
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { Cookies } from "@sveltebase/utils";
|
|
3
3
|
export class PersistentState {
|
|
4
4
|
#value = $state();
|
|
5
|
+
#initialized = false;
|
|
5
6
|
storageKey;
|
|
6
7
|
schema;
|
|
7
8
|
constructor(key, schema) {
|
|
@@ -27,10 +28,12 @@ export class PersistentState {
|
|
|
27
28
|
this.#value = this.schema.parse(newValue);
|
|
28
29
|
}
|
|
29
30
|
init(cookies) {
|
|
30
|
-
if (hasWindow()) {
|
|
31
|
+
if (this.#initialized || hasWindow()) {
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
this.#initialized = true;
|
|
35
|
+
const resolvedCookies = unwrap(cookies);
|
|
36
|
+
const rawCookie = resolvedCookies.find((cookie) => cookie.name === this.storageKey);
|
|
34
37
|
if (!rawCookie) {
|
|
35
38
|
return;
|
|
36
39
|
}
|
|
@@ -78,6 +81,9 @@ export class State {
|
|
|
78
81
|
this.#internalState = fn(this.#internalState);
|
|
79
82
|
}
|
|
80
83
|
}
|
|
84
|
+
function unwrap(value) {
|
|
85
|
+
return typeof value === "function" ? value() : value;
|
|
86
|
+
}
|
|
81
87
|
function hasWindow() {
|
|
82
88
|
return typeof window !== "undefined";
|
|
83
89
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltebase/state",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@sveltebase/utils": "0.3.
|
|
21
|
+
"@sveltebase/utils": "0.3.4",
|
|
22
22
|
"zod": "^4.1.11"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|