@sveltebase/state 0.3.4 → 0.4.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 +14 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/state.svelte.d.ts +31 -5
- package/dist/state.svelte.d.ts.map +1 -1
- package/dist/state.svelte.js +15 -6
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -5,12 +5,18 @@ Small state helpers for Svelte 5.
|
|
|
5
5
|
This package exports two classes:
|
|
6
6
|
|
|
7
7
|
- `State<T>`: simple reactive in-memory state
|
|
8
|
-
- `PersistentState<TSchema>`: reactive state backed by cookies and validated with
|
|
8
|
+
- `PersistentState<TSchema>`: reactive state backed by cookies and validated with a Standard Schema-compatible validator
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
12
12
|
~~~bash
|
|
13
|
-
bun add @sveltebase/state
|
|
13
|
+
bun add @sveltebase/state svelte
|
|
14
|
+
~~~
|
|
15
|
+
|
|
16
|
+
If you want to use `zod` as your schema library:
|
|
17
|
+
|
|
18
|
+
~~~bash
|
|
19
|
+
bun add zod
|
|
14
20
|
~~~
|
|
15
21
|
|
|
16
22
|
## Exports
|
|
@@ -46,7 +52,7 @@ Cookie-backed state with schema validation.
|
|
|
46
52
|
It:
|
|
47
53
|
|
|
48
54
|
- reads from cookies
|
|
49
|
-
- validates with
|
|
55
|
+
- validates with a Standard Schema-compatible validator
|
|
50
56
|
- writes updates back to cookies
|
|
51
57
|
- can load the initial value during SSR
|
|
52
58
|
|
|
@@ -97,10 +103,9 @@ export async function load({ cookies }) {
|
|
|
97
103
|
import { z } from "zod";
|
|
98
104
|
import { PersistentState } from "@sveltebase/state";
|
|
99
105
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
);
|
|
106
|
+
const localeSchema = z.enum(["en", "uz"]).default("en");
|
|
107
|
+
|
|
108
|
+
export const locale = new PersistentState("locale", localeSchema);
|
|
104
109
|
~~~
|
|
105
110
|
|
|
106
111
|
With this setup:
|
|
@@ -116,7 +121,7 @@ With this setup:
|
|
|
116
121
|
Creates a persistent state value.
|
|
117
122
|
|
|
118
123
|
- `key`: cookie name
|
|
119
|
-
- `schema`:
|
|
124
|
+
- `schema`: Standard Schema-compatible validator used for parsing and validation, such as a `zod` schema
|
|
120
125
|
|
|
121
126
|
### `persistentState.current`
|
|
122
127
|
|
|
@@ -149,4 +154,5 @@ type Cookie = {
|
|
|
149
154
|
- `PersistentState` stores JSON in cookies
|
|
150
155
|
- invalid cookie data falls back to the schema result
|
|
151
156
|
- `init(...)` is for server-side initialization
|
|
157
|
+
- any Standard Schema-compatible library can be used here, including `zod`
|
|
152
158
|
- 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;AAC3D,YAAY,
|
|
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,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,gBAAgB,EACjB,MAAM,mBAAmB,CAAC"}
|
package/dist/state.svelte.d.ts
CHANGED
|
@@ -1,17 +1,43 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
1
|
export type MaybeGetter<T> = T | (() => T);
|
|
3
|
-
export
|
|
2
|
+
export interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
3
|
+
readonly "~standard": {
|
|
4
|
+
readonly version: 1;
|
|
5
|
+
readonly vendor: string;
|
|
6
|
+
readonly validate: (value: unknown) => {
|
|
7
|
+
readonly value: Output;
|
|
8
|
+
readonly issues?: undefined;
|
|
9
|
+
} | {
|
|
10
|
+
readonly issues: ReadonlyArray<{
|
|
11
|
+
readonly message: string;
|
|
12
|
+
}>;
|
|
13
|
+
} | Promise<{
|
|
14
|
+
readonly value: Output;
|
|
15
|
+
readonly issues?: undefined;
|
|
16
|
+
} | {
|
|
17
|
+
readonly issues: ReadonlyArray<{
|
|
18
|
+
readonly message: string;
|
|
19
|
+
}>;
|
|
20
|
+
}>;
|
|
21
|
+
readonly types?: {
|
|
22
|
+
readonly input: Input;
|
|
23
|
+
readonly output: Output;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export type InferInput<TSchema extends StandardSchemaV1> = NonNullable<TSchema["~standard"]["types"]>["input"];
|
|
28
|
+
export type InferOutput<TSchema extends StandardSchemaV1> = NonNullable<TSchema["~standard"]["types"]>["output"];
|
|
29
|
+
export declare class PersistentState<TSchema extends StandardSchemaV1> {
|
|
4
30
|
#private;
|
|
5
31
|
private storageKey;
|
|
6
32
|
private schema;
|
|
7
33
|
constructor(key: string, schema: TSchema);
|
|
8
|
-
get current():
|
|
9
|
-
set current(newValue:
|
|
34
|
+
get current(): InferOutput<TSchema>;
|
|
35
|
+
set current(newValue: InferOutput<TSchema>);
|
|
10
36
|
init(cookies: MaybeGetter<{
|
|
11
37
|
name: string;
|
|
12
38
|
value: string;
|
|
13
39
|
}[]>): void;
|
|
14
|
-
set(fn: (value:
|
|
40
|
+
set(fn: (value: InferOutput<TSchema>) => InferOutput<TSchema>): void;
|
|
15
41
|
private static hydrate;
|
|
16
42
|
}
|
|
17
43
|
export declare class State<T> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.svelte.d.ts","sourceRoot":"","sources":["../src/state.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"state.svelte.d.ts","sourceRoot":"","sources":["../src/state.svelte.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAE3C,MAAM,WAAW,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;IAC/D,QAAQ,CAAC,WAAW,EAAE;QACpB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,CACjB,KAAK,EAAE,OAAO,KAEZ;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;SAAE,GACvD;YAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;gBAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,GAChE,OAAO,CACH;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;SAAE,GACvD;YAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;gBAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,CACnE,CAAC;QACN,QAAQ,CAAC,KAAK,CAAC,EAAE;YACf,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;YACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;SACzB,CAAC;KACH,CAAC;CACH;AAED,MAAM,MAAM,UAAU,CAAC,OAAO,SAAS,gBAAgB,IACrD,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAEtD,MAAM,MAAM,WAAW,CAAC,OAAO,SAAS,gBAAgB,IACtD,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAEvD,qBAAa,eAAe,CAAC,OAAO,SAAS,gBAAgB;;IAI3D,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAU;gBAEZ,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAmBxC,IAAI,OAAO,IAIW,WAAW,CAAC,OAAO,CAAC,CAFzC;IAED,IAAI,OAAO,CAAC,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,EAEzC;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,WAAW,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,OAAO,CAAC;IAIpE,OAAO,CAAC,MAAM,CAAC,OAAO;CAoBvB;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
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
1
|
import { Cookies } from "@sveltebase/utils";
|
|
3
2
|
export class PersistentState {
|
|
4
3
|
#value = $state();
|
|
@@ -25,7 +24,7 @@ export class PersistentState {
|
|
|
25
24
|
return this.#value;
|
|
26
25
|
}
|
|
27
26
|
set current(newValue) {
|
|
28
|
-
this.#value = this.schema
|
|
27
|
+
this.#value = parseSchema(this.schema, newValue);
|
|
29
28
|
}
|
|
30
29
|
init(cookies) {
|
|
31
30
|
if (this.#initialized || hasWindow()) {
|
|
@@ -38,7 +37,7 @@ export class PersistentState {
|
|
|
38
37
|
return;
|
|
39
38
|
}
|
|
40
39
|
try {
|
|
41
|
-
const parsed = this.schema
|
|
40
|
+
const parsed = parseSchema(this.schema, JSON.parse(rawCookie.value));
|
|
42
41
|
if (JSON.stringify(parsed) !== JSON.stringify(this.#value)) {
|
|
43
42
|
this.#value = parsed;
|
|
44
43
|
}
|
|
@@ -52,18 +51,18 @@ export class PersistentState {
|
|
|
52
51
|
}
|
|
53
52
|
static hydrate(key, schema) {
|
|
54
53
|
if (!hasWindow()) {
|
|
55
|
-
return schema
|
|
54
|
+
return parseSchema(schema, undefined);
|
|
56
55
|
}
|
|
57
56
|
const rawCookie = Cookies.get(key);
|
|
58
57
|
if (rawCookie) {
|
|
59
58
|
try {
|
|
60
|
-
return schema
|
|
59
|
+
return parseSchema(schema, JSON.parse(rawCookie));
|
|
61
60
|
}
|
|
62
61
|
catch {
|
|
63
62
|
console.warn(`[PersistentState] Invalid data for "${key}". Resetting.`);
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
|
-
return schema
|
|
65
|
+
return parseSchema(schema, undefined);
|
|
67
66
|
}
|
|
68
67
|
}
|
|
69
68
|
export class State {
|
|
@@ -84,6 +83,16 @@ export class State {
|
|
|
84
83
|
function unwrap(value) {
|
|
85
84
|
return typeof value === "function" ? value() : value;
|
|
86
85
|
}
|
|
86
|
+
function parseSchema(schema, value) {
|
|
87
|
+
const result = schema["~standard"].validate(value);
|
|
88
|
+
if (result instanceof Promise) {
|
|
89
|
+
throw new Error("[PersistentState] Async schemas are not supported.");
|
|
90
|
+
}
|
|
91
|
+
if (result.issues) {
|
|
92
|
+
throw new Error(result.issues.map((issue) => issue.message).join(", ") || "Validation failed.");
|
|
93
|
+
}
|
|
94
|
+
return result.value;
|
|
95
|
+
}
|
|
87
96
|
function hasWindow() {
|
|
88
97
|
return typeof window !== "undefined";
|
|
89
98
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltebase/state",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -18,8 +18,7 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@sveltebase/utils": "0.
|
|
22
|
-
"zod": "^4.1.11"
|
|
21
|
+
"@sveltebase/utils": "0.4.0"
|
|
23
22
|
},
|
|
24
23
|
"peerDependencies": {
|
|
25
24
|
"svelte": "^5.0.0"
|