seitu 0.1.0 → 0.2.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 +3 -3
- package/dist/core/index.d.ts +1 -1
- package/dist/core/schema-store.d.ts +19 -0
- package/dist/core/subscription.d.ts +6 -0
- package/dist/core.js +1 -1
- package/dist/react/hooks.d.ts +54 -10
- package/dist/react.js +12 -9
- package/dist/web/index.d.ts +2 -0
- package/dist/web/local-storage-value.d.ts +68 -0
- package/dist/web/local-storage.d.ts +50 -0
- package/dist/web/media-query.d.ts +4 -2
- package/dist/web/scroll-state.d.ts +25 -8
- package/dist/web/session-storage-value.d.ts +35 -23
- package/dist/web/session-storage.d.ts +34 -13
- package/dist/web/web-storage-value.d.ts +18 -0
- package/dist/web/web-storage.d.ts +11 -0
- package/dist/web.js +116 -83
- package/package.json +1 -1
- package/dist/core/store.d.ts +0 -107
- /package/dist/core/{store.test.d.ts → schema-store.test.d.ts} +0 -0
- /package/dist/web/{session-storage-value.test.d.ts → web-storage-value.test.d.ts} +0 -0
- /package/dist/web/{session-storage.test.d.ts → web-storage.test.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -15,10 +15,10 @@ To quick start you only need to write the following code:
|
|
|
15
15
|
|
|
16
16
|
```tsx
|
|
17
17
|
import { useSubscription } from 'seitu/react'
|
|
18
|
-
import {
|
|
18
|
+
import { createSessionStorageValue } from 'seitu/web'
|
|
19
19
|
import * as z from 'zod'
|
|
20
20
|
|
|
21
|
-
const value =
|
|
21
|
+
const value = createSessionStorageValue({
|
|
22
22
|
key: 'test',
|
|
23
23
|
defaultValue: 0,
|
|
24
24
|
schema: z.number(),
|
|
@@ -30,7 +30,7 @@ value.remove()
|
|
|
30
30
|
value.subscribe(v => console.log(v))
|
|
31
31
|
|
|
32
32
|
function Counter() {
|
|
33
|
-
const count = useSubscription(
|
|
33
|
+
const count = useSubscription(value)
|
|
34
34
|
|
|
35
35
|
return (
|
|
36
36
|
<div>
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './store';
|
|
1
|
+
export * from './schema-store';
|
|
2
2
|
export * from './subscription';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
import type { Simplify } from '../utils';
|
|
3
|
+
import type { Readable, Subscribable, Writable } from './index';
|
|
4
|
+
export type SchemaStoreSchema = Record<string, StandardSchemaV1<unknown, unknown>>;
|
|
5
|
+
export type SchemaStoreOutput<S extends SchemaStoreSchema> = Simplify<{
|
|
6
|
+
[K in keyof S]: StandardSchemaV1.InferOutput<S[K]>;
|
|
7
|
+
}>;
|
|
8
|
+
export interface SchemaStore<O extends Record<string, unknown>> extends Subscribable<O>, Readable<O>, Writable<Partial<O>> {
|
|
9
|
+
getDefaultValue: <K extends keyof O>(key: K) => O[K];
|
|
10
|
+
}
|
|
11
|
+
export interface SchemaStoreOptions<S extends Record<string, StandardSchemaV1>> {
|
|
12
|
+
schemas: S;
|
|
13
|
+
defaultValues: SchemaStoreOutput<S>;
|
|
14
|
+
provider: {
|
|
15
|
+
get: () => SchemaStoreOutput<S>;
|
|
16
|
+
set: (value: Partial<SchemaStoreOutput<S>>) => void;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export declare function createSchemaStore<S extends Record<string, StandardSchemaV1>>(options: SchemaStoreOptions<S>): SchemaStore<SchemaStoreOutput<S>>;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
export interface Subscribable<V> {
|
|
2
2
|
'subscribe': (callback: (value: V) => any) => () => void;
|
|
3
3
|
'~': {
|
|
4
|
+
/**
|
|
5
|
+
* Type type with returned value of the subscription.
|
|
6
|
+
*/
|
|
4
7
|
output: V;
|
|
8
|
+
/**
|
|
9
|
+
* A function that notifies all subscribers that the value has changed.
|
|
10
|
+
*/
|
|
5
11
|
notify: () => void;
|
|
6
12
|
};
|
|
7
13
|
}
|
package/dist/core.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { n as e, t } from "./core-CuCUF5Aj.js";
|
|
2
|
-
export { e as
|
|
2
|
+
export { e as createSchemaStore, t as createSubscription };
|
package/dist/react/hooks.d.ts
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import type { Readable, Subscribable } from '../core/index';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
export type UseSubscriptionSource<S extends Subscribable<any> & Readable<any>> = S | (() => S);
|
|
4
|
+
export interface UseSubscriptionOptions<S extends Subscribable<any> & Readable<any>, R = S['~']['output']> {
|
|
5
|
+
selector?: (value: S['~']['output']) => R;
|
|
6
|
+
deps?: React.DependencyList;
|
|
7
|
+
}
|
|
2
8
|
/**
|
|
3
|
-
* Use this hook to subscribe to a reactive value.
|
|
4
|
-
*
|
|
9
|
+
* Use this hook to subscribe to a reactive value. Accepts a subscription object
|
|
10
|
+
* directly, or a factory function that is called only once on first render —
|
|
11
|
+
* subsequent renders reuse the cached subscription unless dependency array changes.
|
|
5
12
|
*
|
|
6
|
-
* @
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
13
|
+
* @example Inline subscription
|
|
9
14
|
* ```tsx twoslash title="/app/page.tsx"
|
|
10
15
|
* 'use client'
|
|
11
16
|
*
|
|
12
|
-
* import {
|
|
17
|
+
* import { createSessionStorageValue } from 'seitu/web'
|
|
13
18
|
* import { useSubscription } from 'seitu/react'
|
|
14
19
|
* import * as z from 'zod'
|
|
15
20
|
*
|
|
16
21
|
* export default function Page() {
|
|
17
|
-
* const value = useSubscription(() =>
|
|
22
|
+
* const value = useSubscription(() => createSessionStorageValue({
|
|
18
23
|
* key: 'test',
|
|
19
24
|
* defaultValue: 0,
|
|
20
25
|
* schema: z.number(),
|
|
@@ -24,7 +29,26 @@ import type { Readable, Subscribable } from '../core/index';
|
|
|
24
29
|
* }
|
|
25
30
|
* ```
|
|
26
31
|
*
|
|
27
|
-
* @example
|
|
32
|
+
* @example Instance outside of component
|
|
33
|
+
* ```tsx twoslash title="/app/page.tsx"
|
|
34
|
+
* 'use client'
|
|
35
|
+
*
|
|
36
|
+
* import { createSessionStorage } from 'seitu/web'
|
|
37
|
+
* import { useSubscription } from 'seitu/react'
|
|
38
|
+
* import * as z from 'zod'
|
|
39
|
+
*
|
|
40
|
+
* const sessionStorage = createSessionStorage({
|
|
41
|
+
* schemas: { count: z.number(), name: z.string() },
|
|
42
|
+
* defaultValues: { count: 0, name: '' },
|
|
43
|
+
* })
|
|
44
|
+
*
|
|
45
|
+
* export default function Page() {
|
|
46
|
+
* const value = useSubscription(sessionStorage)
|
|
47
|
+
* return <div>{value.count}</div>
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @example Subscription with selector
|
|
28
52
|
* ```tsx twoslash title="/app/page.tsx"
|
|
29
53
|
* 'use client'
|
|
30
54
|
*
|
|
@@ -42,10 +66,30 @@ import type { Readable, Subscribable } from '../core/index';
|
|
|
42
66
|
*
|
|
43
67
|
* export default function Page() {
|
|
44
68
|
* // Usage with selector, re-renders only when count changes
|
|
45
|
-
* const count = useSubscription(
|
|
69
|
+
* const count = useSubscription(sessionStorage, { selector: value => value.count })
|
|
46
70
|
*
|
|
47
71
|
* return <div>{count}</div>
|
|
48
72
|
* }
|
|
49
73
|
* ```
|
|
74
|
+
*
|
|
75
|
+
* @example Ref example
|
|
76
|
+
* ```tsx twoslash title="/app/page.tsx"
|
|
77
|
+
* 'use client'
|
|
78
|
+
*
|
|
79
|
+
* import * as React from 'react'
|
|
80
|
+
* import { scrollState } from 'seitu/web'
|
|
81
|
+
* import { useSubscription } from 'seitu/react'
|
|
82
|
+
*
|
|
83
|
+
* export default function Page() {
|
|
84
|
+
* const [ref, setRef] = React.useState<HTMLDivElement | null>(null)
|
|
85
|
+
* const state = useSubscription(() => scrollState({ element: ref, direction: 'vertical' }), { deps: [ref] })
|
|
86
|
+
*
|
|
87
|
+
* return (
|
|
88
|
+
* <div ref={setRef}>
|
|
89
|
+
* {String(state.top.value)}
|
|
90
|
+
* </div>
|
|
91
|
+
* )
|
|
92
|
+
* }
|
|
93
|
+
* ```
|
|
50
94
|
*/
|
|
51
|
-
export declare function useSubscription<S extends Subscribable<any> & Readable<any>, R = S['~']['output']>(
|
|
95
|
+
export declare function useSubscription<S extends Subscribable<any> & Readable<any> = Subscribable<any> & Readable<any>, R = S['~']['output']>(source: UseSubscriptionSource<S>, options?: UseSubscriptionOptions<S, R>): R;
|
package/dist/react.js
CHANGED
|
@@ -1778,14 +1778,17 @@ var t = Object.create, n = Object.defineProperty, r = Object.getOwnPropertyDescr
|
|
|
1778
1778
|
};
|
|
1779
1779
|
}))(), 1);
|
|
1780
1780
|
function Ze(t, n) {
|
|
1781
|
-
let r = e.useRef(
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1781
|
+
let { selector: r, deps: i = [] } = n ?? {}, a = typeof t == "function", o = e.useRef(t);
|
|
1782
|
+
if (!a && t !== o.current) throw Error("useSubscription detected a new object on re-render. Either create the subscription outside the component or wrap it in a factory: useSubscription(() => yourSubscription(...))");
|
|
1783
|
+
o.current = t;
|
|
1784
|
+
let s = a ? t : () => t, c = e.useRef(s);
|
|
1785
|
+
c.current = s;
|
|
1786
|
+
let l = e.useMemo(() => c.current(), i);
|
|
1787
|
+
if (!l.get || !l.subscribe) throw Error("Subscription is not valid. It must have a get and subscribe method.");
|
|
1788
|
+
let [u, d] = e.useState(() => r ? r(l.get()) : l.get()), f = e.useEffectEvent(() => u);
|
|
1789
|
+
return e.useEffect(() => l.subscribe((e) => {
|
|
1790
|
+
let t = r ? r(e) : e;
|
|
1791
|
+
(0, Xe.default)(t, f()) || d(t);
|
|
1792
|
+
}), [l, r]), u;
|
|
1790
1793
|
}
|
|
1791
1794
|
export { Ze as useSubscription };
|
package/dist/web/index.d.ts
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
import type { LocalStorage } from './local-storage';
|
|
3
|
+
import type { WebStorageValue as LocalStorageValue, WebStorageValueOptionsWithSchema as LocalStorageValueOptionsWithSchema, WebStorageValueOptionsWithStorage as LocalStorageValueOptionsWithStorage } from './web-storage-value';
|
|
4
|
+
export type { LocalStorageValue, LocalStorageValueOptionsWithSchema, LocalStorageValueOptionsWithStorage, };
|
|
5
|
+
/**
|
|
6
|
+
* Creates a reactive handle for a single localStorage value.
|
|
7
|
+
*
|
|
8
|
+
* Two modes:
|
|
9
|
+
* - **Schema mode** (`schema`, `key`, `defaultValue`): standalone key with validation. Missing or
|
|
10
|
+
* invalid stored data returns `defaultValue`.
|
|
11
|
+
* - **Storage mode** (`storage`, `key`): binds to one key of a `createLocalStorage` instance.
|
|
12
|
+
* Type and default come from that storage.
|
|
13
|
+
*
|
|
14
|
+
* @example Vanilla
|
|
15
|
+
* ```ts twoslash title="local-storage-value.ts"
|
|
16
|
+
* import { createLocalStorageValue } from 'seitu/web'
|
|
17
|
+
* import * as z from 'zod'
|
|
18
|
+
*
|
|
19
|
+
* const value = createLocalStorageValue({
|
|
20
|
+
* key: 'count',
|
|
21
|
+
* defaultValue: 0,
|
|
22
|
+
* schema: z.number(),
|
|
23
|
+
* })
|
|
24
|
+
* value.get() // 0
|
|
25
|
+
* value.set(1)
|
|
26
|
+
* value.set(v => v + 1)
|
|
27
|
+
* value.subscribe(v => console.log(v))
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example Storage mode
|
|
31
|
+
* ```ts twoslash title="local-storage-value.ts"
|
|
32
|
+
* import { createLocalStorage, createLocalStorageValue } from 'seitu/web'
|
|
33
|
+
* import * as z from 'zod'
|
|
34
|
+
*
|
|
35
|
+
* const storage = createLocalStorage({
|
|
36
|
+
* schemas: { count: z.number(), name: z.string() },
|
|
37
|
+
* defaultValues: { count: 0, name: '' },
|
|
38
|
+
* })
|
|
39
|
+
* const count = createLocalStorageValue({ storage, key: 'count' })
|
|
40
|
+
* count.set(5)
|
|
41
|
+
* storage.get().count === 5 // true
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @example React
|
|
45
|
+
* ```tsx twoslash title="page.tsx"
|
|
46
|
+
* 'use client'
|
|
47
|
+
*
|
|
48
|
+
* import { createLocalStorageValue } from 'seitu/web'
|
|
49
|
+
* import { useSubscription } from 'seitu/react'
|
|
50
|
+
* import * as z from 'zod'
|
|
51
|
+
*
|
|
52
|
+
* export default function Page() {
|
|
53
|
+
* const { value: count } = useSubscription(() => createLocalStorageValue({
|
|
54
|
+
* key: 'count',
|
|
55
|
+
* defaultValue: 0,
|
|
56
|
+
* schema: z.number(),
|
|
57
|
+
* }))
|
|
58
|
+
*
|
|
59
|
+
* return (
|
|
60
|
+
* <div>
|
|
61
|
+
* <span>{count}</span>
|
|
62
|
+
* </div>
|
|
63
|
+
* )
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function createLocalStorageValue<Storage extends LocalStorage<any>, K extends keyof Storage['~']['output']>(options: LocalStorageValueOptionsWithStorage<Storage, K>): LocalStorageValue<Storage['~']['output'][K]>;
|
|
68
|
+
export declare function createLocalStorageValue<S extends StandardSchemaV1<unknown>>(options: LocalStorageValueOptionsWithSchema<S>): LocalStorageValue<StandardSchemaV1.InferOutput<S>>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { SchemaStoreOutput, SchemaStoreSchema } from '../core/index';
|
|
2
|
+
import type { WebStorage as LocalStorage, WebStorageOptions as LocalStorageOptions } from './web-storage';
|
|
3
|
+
export type { LocalStorage, LocalStorageOptions };
|
|
4
|
+
/**
|
|
5
|
+
* Creates a reactive handle for a localStorage instance.
|
|
6
|
+
*
|
|
7
|
+
* @example Vanilla
|
|
8
|
+
* ```ts twoslash title="local-storage.ts"
|
|
9
|
+
* import { createLocalStorage } from 'seitu/web'
|
|
10
|
+
* import * as z from 'zod'
|
|
11
|
+
*
|
|
12
|
+
* const localStorage = createLocalStorage({
|
|
13
|
+
* schemas: {
|
|
14
|
+
* token: z.string().nullable(),
|
|
15
|
+
* preferences: z.object({ theme: z.enum(['light', 'dark']) }),
|
|
16
|
+
* },
|
|
17
|
+
* defaultValues: { token: null, preferences: { theme: 'light' } },
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* localStorage.get() // { token: null, preferences: { theme: 'light' } }
|
|
21
|
+
* localStorage.set({ token: 'abc' })
|
|
22
|
+
* localStorage.get() // { token: 'abc', preferences: { theme: 'light' } }
|
|
23
|
+
* localStorage.subscribe(console.log)
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example React
|
|
27
|
+
* ```tsx twoslash title="page.tsx"
|
|
28
|
+
* 'use client'
|
|
29
|
+
*
|
|
30
|
+
* import { createLocalStorage } from 'seitu/web'
|
|
31
|
+
* import { useSubscription } from 'seitu/react'
|
|
32
|
+
* import * as z from 'zod'
|
|
33
|
+
*
|
|
34
|
+
* const localStorage = createLocalStorage({
|
|
35
|
+
* schemas: { count: z.number(), name: z.string() },
|
|
36
|
+
* defaultValues: { count: 0, name: '' },
|
|
37
|
+
* })
|
|
38
|
+
*
|
|
39
|
+
* export default function Page() {
|
|
40
|
+
* const { value } = useSubscription(localStorage)
|
|
41
|
+
* return (
|
|
42
|
+
* <div>
|
|
43
|
+
* <span>{value.count}</span>
|
|
44
|
+
* <span>{value.name}</span>
|
|
45
|
+
* </div>
|
|
46
|
+
* )
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function createLocalStorage<S extends SchemaStoreSchema>(options: LocalStorageOptions<S>): LocalStorage<SchemaStoreOutput<S>>;
|
|
@@ -31,7 +31,7 @@ export interface MediaQueryOptions<T extends string> {
|
|
|
31
31
|
/**
|
|
32
32
|
* Creates a handle for a media query.
|
|
33
33
|
*
|
|
34
|
-
* @example
|
|
34
|
+
* @example Vanilla
|
|
35
35
|
* ```ts twoslash title="media-query.ts"
|
|
36
36
|
* import { mediaQuery } from 'seitu/web'
|
|
37
37
|
* import { useSubscription } from 'seitu/react'
|
|
@@ -47,6 +47,7 @@ export interface MediaQueryOptions<T extends string> {
|
|
|
47
47
|
* console.log(state)
|
|
48
48
|
* ```
|
|
49
49
|
*
|
|
50
|
+
* @example React
|
|
50
51
|
* ```tsx twoslash title="page.tsx"
|
|
51
52
|
* import { mediaQuery } from 'seitu/web'
|
|
52
53
|
* import { useSubscription } from 'seitu/react'
|
|
@@ -55,11 +56,12 @@ export interface MediaQueryOptions<T extends string> {
|
|
|
55
56
|
*
|
|
56
57
|
* // Usage with some function component
|
|
57
58
|
* function Layout() {
|
|
58
|
-
* const matches = useSubscription(
|
|
59
|
+
* const { value: matches } = useSubscription(isDesktop)
|
|
59
60
|
* return matches ? 'i am desktop' : 'i am mobile'
|
|
60
61
|
* }
|
|
61
62
|
* ```
|
|
62
63
|
*
|
|
64
|
+
* @example Errors
|
|
63
65
|
* ```tsx twoslash
|
|
64
66
|
* import { mediaQuery } from 'seitu/web'
|
|
65
67
|
* import { useSubscription } from 'seitu/react'
|
|
@@ -31,7 +31,7 @@ export interface ScrollStateOptions {
|
|
|
31
31
|
/**
|
|
32
32
|
* Creates a reactive handle that tracks scroll position of an element relative to each edge.
|
|
33
33
|
*
|
|
34
|
-
* @example
|
|
34
|
+
* @example Vanilla
|
|
35
35
|
* ```ts twoslash
|
|
36
36
|
* import { scrollState } from 'seitu/web'
|
|
37
37
|
*
|
|
@@ -42,17 +42,18 @@ export interface ScrollStateOptions {
|
|
|
42
42
|
* })
|
|
43
43
|
*
|
|
44
44
|
* scroll.subscribe(state => {
|
|
45
|
-
* console.log(state.top.value)
|
|
46
|
-
* console.log(state.top.remaining)
|
|
47
|
-
* console.log(state.bottom.value)
|
|
48
|
-
* console.log(state.bottom.remaining)
|
|
45
|
+
* console.log(state.top.value)
|
|
46
|
+
* console.log(state.top.remaining)
|
|
47
|
+
* console.log(state.bottom.value)
|
|
48
|
+
* console.log(state.bottom.remaining)
|
|
49
49
|
* })
|
|
50
50
|
*
|
|
51
51
|
* const state = scroll.get()
|
|
52
52
|
* console.log(state)
|
|
53
53
|
* ```
|
|
54
54
|
*
|
|
55
|
-
*
|
|
55
|
+
* @example React
|
|
56
|
+
* ```tsx twoslash title="page.tsx"
|
|
56
57
|
* import { scrollState } from 'seitu/web'
|
|
57
58
|
* import { useSubscription } from 'seitu/react'
|
|
58
59
|
*
|
|
@@ -62,8 +63,24 @@ export interface ScrollStateOptions {
|
|
|
62
63
|
* })
|
|
63
64
|
*
|
|
64
65
|
* function Layout() {
|
|
65
|
-
* const state = useSubscription(
|
|
66
|
-
*
|
|
66
|
+
* const { value: state, ref } = useSubscription(scroll)
|
|
67
|
+
*
|
|
68
|
+
* return (
|
|
69
|
+
* <div ref={ref}>
|
|
70
|
+
* <div>
|
|
71
|
+
* {state.top.value ? 'scrolled' : 'at the top'}
|
|
72
|
+
* </div>
|
|
73
|
+
* <div>
|
|
74
|
+
* {state.bottom.value ? 'scrolled' : 'at the bottom'}
|
|
75
|
+
* </div>
|
|
76
|
+
* <div>
|
|
77
|
+
* {state.left.value ? 'scrolled' : 'at the left'}
|
|
78
|
+
* </div>
|
|
79
|
+
* <div>
|
|
80
|
+
* {state.right.value ? 'scrolled' : 'at the right'}
|
|
81
|
+
* </div>
|
|
82
|
+
* </div>
|
|
83
|
+
* )
|
|
67
84
|
* }
|
|
68
85
|
* ```
|
|
69
86
|
*/
|
|
@@ -1,18 +1,7 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
-
import type { Readable, Subscribable, Writable } from '../core/index';
|
|
3
2
|
import type { SessionStorage } from './session-storage';
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
export interface SessionStorageValueOptionsWithStorage<Storage extends SessionStorage<any>, K extends keyof Storage['~']['output']> {
|
|
7
|
-
storage: Storage;
|
|
8
|
-
key: K;
|
|
9
|
-
}
|
|
10
|
-
export interface SessionStorageValueOptionsWithSchema<S extends StandardSchemaV1<unknown>> {
|
|
11
|
-
schema: S;
|
|
12
|
-
key: string;
|
|
13
|
-
defaultValue: StandardSchemaV1.InferOutput<S>;
|
|
14
|
-
}
|
|
15
|
-
export type SessionStorageValueOptions = SessionStorageValueOptionsWithStorage<SessionStorage<any>, string> | SessionStorageValueOptionsWithSchema<StandardSchemaV1<unknown>>;
|
|
3
|
+
import type { WebStorageValue as SessionStorageValue, WebStorageValueOptionsWithSchema as SessionStorageValueOptionsWithSchema, WebStorageValueOptionsWithStorage as SessionStorageValueOptionsWithStorage } from './web-storage-value';
|
|
4
|
+
export type { SessionStorageValue, SessionStorageValueOptionsWithSchema, SessionStorageValueOptionsWithStorage, };
|
|
16
5
|
/**
|
|
17
6
|
* Creates a reactive handle for a single sessionStorage value.
|
|
18
7
|
*
|
|
@@ -22,12 +11,12 @@ export type SessionStorageValueOptions = SessionStorageValueOptionsWithStorage<S
|
|
|
22
11
|
* - **Storage mode** (`storage`, `key`): binds to one key of a `createSessionStorage` instance.
|
|
23
12
|
* Type and default come from that storage.
|
|
24
13
|
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```ts twoslash
|
|
27
|
-
* import {
|
|
14
|
+
* @example Vanilla
|
|
15
|
+
* ```ts twoslash title="session-storage-value.ts"
|
|
16
|
+
* import { createSessionStorageValue } from 'seitu/web'
|
|
28
17
|
* import * as z from 'zod'
|
|
29
18
|
*
|
|
30
|
-
* const value =
|
|
19
|
+
* const value = createSessionStorageValue({
|
|
31
20
|
* key: 'count',
|
|
32
21
|
* defaultValue: 0,
|
|
33
22
|
* schema: z.number(),
|
|
@@ -38,19 +27,42 @@ export type SessionStorageValueOptions = SessionStorageValueOptionsWithStorage<S
|
|
|
38
27
|
* value.subscribe(v => console.log(v))
|
|
39
28
|
* ```
|
|
40
29
|
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```ts twoslash
|
|
43
|
-
* import { createSessionStorage,
|
|
30
|
+
* @example Storage mode
|
|
31
|
+
* ```ts twoslash title="session-storage-value.ts"
|
|
32
|
+
* import { createSessionStorage, createSessionStorageValue } from 'seitu/web'
|
|
44
33
|
* import * as z from 'zod'
|
|
45
34
|
*
|
|
46
35
|
* const storage = createSessionStorage({
|
|
47
36
|
* schemas: { count: z.number(), name: z.string() },
|
|
48
37
|
* defaultValues: { count: 0, name: '' },
|
|
49
38
|
* })
|
|
50
|
-
* const count =
|
|
39
|
+
* const count = createSessionStorageValue({ storage, key: 'count' })
|
|
51
40
|
* count.set(5)
|
|
52
41
|
* storage.get().count === 5 // true
|
|
53
42
|
* ```
|
|
43
|
+
*
|
|
44
|
+
* @example React
|
|
45
|
+
* ```tsx twoslash title="page.tsx"
|
|
46
|
+
* 'use client'
|
|
47
|
+
*
|
|
48
|
+
* import { createSessionStorageValue } from 'seitu/web'
|
|
49
|
+
* import { useSubscription } from 'seitu/react'
|
|
50
|
+
* import * as z from 'zod'
|
|
51
|
+
*
|
|
52
|
+
* export default function Page() {
|
|
53
|
+
* const { value: count } = useSubscription(() => createSessionStorageValue({
|
|
54
|
+
* key: 'count',
|
|
55
|
+
* defaultValue: 0,
|
|
56
|
+
* schema: z.number(),
|
|
57
|
+
* }))
|
|
58
|
+
*
|
|
59
|
+
* return (
|
|
60
|
+
* <div>
|
|
61
|
+
* <span>{count}</span>
|
|
62
|
+
* </div>
|
|
63
|
+
* )
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
54
66
|
*/
|
|
55
|
-
export declare function
|
|
56
|
-
export declare function
|
|
67
|
+
export declare function createSessionStorageValue<Storage extends SessionStorage<any>, K extends keyof Storage['~']['output']>(options: SessionStorageValueOptionsWithStorage<Storage, K>): SessionStorageValue<Storage['~']['output'][K]>;
|
|
68
|
+
export declare function createSessionStorageValue<S extends StandardSchemaV1<unknown>>(options: SessionStorageValueOptionsWithSchema<S>): SessionStorageValue<StandardSchemaV1.InferOutput<S>>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { SchemaStoreOutput, SchemaStoreSchema } from '../core/index';
|
|
2
|
+
import type { WebStorage as SessionStorage, WebStorageOptions as SessionStorageOptions } from './web-storage';
|
|
3
|
+
export type { SessionStorage, SessionStorageOptions };
|
|
3
4
|
/**
|
|
4
5
|
* Creates a reactive handle for a sessionStorage instance.
|
|
5
6
|
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts twoslash
|
|
7
|
+
* @example Vanilla
|
|
8
|
+
* ```ts twoslash title="session-storage.ts"
|
|
8
9
|
* import { createSessionStorage } from 'seitu/web'
|
|
9
10
|
* import * as z from 'zod'
|
|
10
11
|
*
|
|
@@ -16,14 +17,34 @@ export type SessionStorage<O extends Record<string, unknown>> = Store<O>;
|
|
|
16
17
|
* defaultValues: { token: null, preferences: { theme: 'light' } },
|
|
17
18
|
* })
|
|
18
19
|
*
|
|
19
|
-
* sessionStorage.get()
|
|
20
|
-
* sessionStorage.
|
|
21
|
-
* sessionStorage.
|
|
22
|
-
* sessionStorage.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
20
|
+
* sessionStorage.get() // { token: null, preferences: { theme: 'light' } }
|
|
21
|
+
* sessionStorage.set({ token: 'abc' })
|
|
22
|
+
* sessionStorage.get() // { token: 'abc', preferences: { theme: 'light' } }
|
|
23
|
+
* sessionStorage.subscribe(console.log)
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example React
|
|
27
|
+
* ```tsx twoslash title="page.tsx"
|
|
28
|
+
* 'use client'
|
|
29
|
+
*
|
|
30
|
+
* import { createSessionStorage } from 'seitu/web'
|
|
31
|
+
* import { useSubscription } from 'seitu/react'
|
|
32
|
+
* import * as z from 'zod'
|
|
33
|
+
*
|
|
34
|
+
* const sessionStorage = createSessionStorage({
|
|
35
|
+
* schemas: { count: z.number(), name: z.string() },
|
|
36
|
+
* defaultValues: { count: 0, name: '' },
|
|
37
|
+
* })
|
|
38
|
+
*
|
|
39
|
+
* export default function Page() {
|
|
40
|
+
* const { value } = useSubscription(sessionStorage)
|
|
41
|
+
* return (
|
|
42
|
+
* <div>
|
|
43
|
+
* <span>{value.count}</span>
|
|
44
|
+
* <span>{value.name}</span>
|
|
45
|
+
* </div>
|
|
46
|
+
* )
|
|
47
|
+
* }
|
|
27
48
|
* ```
|
|
28
49
|
*/
|
|
29
|
-
export declare function createSessionStorage<S extends
|
|
50
|
+
export declare function createSessionStorage<S extends SchemaStoreSchema>(options: SessionStorageOptions<S>): SessionStorage<SchemaStoreOutput<S>>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
import type { Readable, Subscribable, Writable } from '../core/index';
|
|
3
|
+
import type { WebStorage } from './web-storage';
|
|
4
|
+
export interface WebStorageValue<V> extends Subscribable<V>, Readable<V>, Writable<V> {
|
|
5
|
+
}
|
|
6
|
+
export interface WebStorageValueOptionsWithStorage<Storage extends WebStorage<any>, K extends keyof Storage['~']['output']> {
|
|
7
|
+
storage: Storage;
|
|
8
|
+
key: K;
|
|
9
|
+
}
|
|
10
|
+
export interface WebStorageValueOptionsWithSchema<S extends StandardSchemaV1<unknown>> {
|
|
11
|
+
schema: S;
|
|
12
|
+
key: string;
|
|
13
|
+
defaultValue: StandardSchemaV1.InferOutput<S>;
|
|
14
|
+
}
|
|
15
|
+
export declare function createWebStorageValue<Storage extends WebStorage<any>, K extends keyof Storage['~']['output']>(options: WebStorageValueOptionsWithStorage<Storage, K>): WebStorageValue<Storage['~']['output'][K]>;
|
|
16
|
+
export declare function createWebStorageValue<S extends StandardSchemaV1<unknown>>(options: WebStorageValueOptionsWithSchema<S> & {
|
|
17
|
+
kind: 'sessionStorage' | 'localStorage';
|
|
18
|
+
}): WebStorageValue<StandardSchemaV1.InferOutput<S>>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SchemaStore, SchemaStoreOptions, SchemaStoreOutput, SchemaStoreSchema } from '../core/index';
|
|
2
|
+
export interface WebStorageOptions<S extends SchemaStoreSchema> extends Omit<SchemaStoreOptions<S>, 'provider'> {
|
|
3
|
+
}
|
|
4
|
+
export interface WebStorage<O extends Record<string, unknown>> extends SchemaStore<O> {
|
|
5
|
+
'~': {
|
|
6
|
+
kind: 'sessionStorage' | 'localStorage';
|
|
7
|
+
} & SchemaStore<O>['~'];
|
|
8
|
+
}
|
|
9
|
+
export declare function createWebStorage<S extends SchemaStoreSchema>(options: WebStorageOptions<S> & {
|
|
10
|
+
kind: 'sessionStorage' | 'localStorage';
|
|
11
|
+
}): WebStorage<SchemaStoreOutput<S>>;
|
package/dist/web.js
CHANGED
|
@@ -1,5 +1,91 @@
|
|
|
1
1
|
import { n as e, r as t, t as n } from "./core-CuCUF5Aj.js";
|
|
2
|
-
function r(
|
|
2
|
+
function r(n) {
|
|
3
|
+
let { kind: r, ...i } = n, a = e({
|
|
4
|
+
...i,
|
|
5
|
+
provider: {
|
|
6
|
+
get: () => {
|
|
7
|
+
if (typeof window > "u") return i.defaultValues;
|
|
8
|
+
let e = window[r], n = { ...i.defaultValues };
|
|
9
|
+
for (let r in n) {
|
|
10
|
+
let a = t(e.getItem(r)), o = i.schemas[r]["~standard"].validate(a);
|
|
11
|
+
if (o instanceof Promise) throw TypeError("[createWebSchemaStore] Validation schema should not return a Promise.");
|
|
12
|
+
o.issues && console.warn(JSON.stringify(o.issues, null, 2), { cause: o.issues }), n[r] = o.issues ? i.defaultValues[r] : o.value;
|
|
13
|
+
}
|
|
14
|
+
return n;
|
|
15
|
+
},
|
|
16
|
+
set: (e) => {
|
|
17
|
+
if (typeof window > "u") return;
|
|
18
|
+
let t = window[r];
|
|
19
|
+
Object.entries(e).forEach(([e, n]) => {
|
|
20
|
+
t.setItem(e, typeof n == "string" ? n : JSON.stringify(n));
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return typeof window < "u" && window.addEventListener("storage", () => {
|
|
26
|
+
a["~"].notify();
|
|
27
|
+
}), {
|
|
28
|
+
...a,
|
|
29
|
+
"~": {
|
|
30
|
+
kind: r,
|
|
31
|
+
...a["~"]
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function i(e) {
|
|
36
|
+
return r({
|
|
37
|
+
kind: "localStorage",
|
|
38
|
+
...e
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function a(e) {
|
|
42
|
+
let r = "storage" in e ? e.storage["~"].kind : e.kind, i = `${r}Value`;
|
|
43
|
+
if ("schema" in e && e.defaultValue === void 0) throw Error(`[${i}] Default value is required`);
|
|
44
|
+
if (e.key === void 0) throw Error(`[${i}] Key is required`);
|
|
45
|
+
if (!("schema" in e || "storage" in e)) throw Error(`[${i}] Either schema or storage must be provided`);
|
|
46
|
+
let a = ("schema" in e ? e.defaultValue : e.storage.getDefaultValue(e.key)) ?? null, { subscribe: o, notify: s } = n(), c = () => {
|
|
47
|
+
if (typeof window > "u") return a;
|
|
48
|
+
let n = window[r].getItem(e.key);
|
|
49
|
+
if (n === null) return a;
|
|
50
|
+
let i = t(n);
|
|
51
|
+
try {
|
|
52
|
+
if ("schema" in e) {
|
|
53
|
+
let t = e.schema["~standard"].validate(i);
|
|
54
|
+
if (t instanceof Promise) throw TypeError("Validation schema should not return a Promise.");
|
|
55
|
+
return t.issues ? (console.error(JSON.stringify(t.issues, null, 2), { cause: t.issues }), a) : t.value;
|
|
56
|
+
} else return i;
|
|
57
|
+
} catch {
|
|
58
|
+
return a !== void 0 && typeof a != "string" ? a : i;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
get: c,
|
|
63
|
+
set: (t) => {
|
|
64
|
+
if (typeof window > "u") return;
|
|
65
|
+
let n = window[r], i = typeof t == "function" ? t(c()) : t;
|
|
66
|
+
n.setItem(e.key, typeof i == "string" ? i : JSON.stringify(i)), window.dispatchEvent(new Event("storage")), s();
|
|
67
|
+
},
|
|
68
|
+
subscribe: (t) => {
|
|
69
|
+
let n = o(() => t(c())), r = (n) => {
|
|
70
|
+
n.key === e.key && t(c());
|
|
71
|
+
};
|
|
72
|
+
return typeof window < "u" && window.addEventListener("storage", r), () => {
|
|
73
|
+
n(), typeof window < "u" && window.removeEventListener("storage", r);
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
"~": {
|
|
77
|
+
output: null,
|
|
78
|
+
notify: s
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function o(e) {
|
|
83
|
+
return "storage" in e ? a(e) : a({
|
|
84
|
+
...e,
|
|
85
|
+
kind: "localStorage"
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function s(e) {
|
|
3
89
|
let { subscribe: t, notify: r } = n(), i = () => {
|
|
4
90
|
if (typeof window > "u") return e.defaultMatches ?? !1;
|
|
5
91
|
try {
|
|
@@ -23,109 +109,56 @@ function r(e) {
|
|
|
23
109
|
}
|
|
24
110
|
};
|
|
25
111
|
}
|
|
26
|
-
var
|
|
112
|
+
var c = {
|
|
27
113
|
value: !1,
|
|
28
114
|
remaining: 0
|
|
29
115
|
};
|
|
30
|
-
function
|
|
31
|
-
let { direction: t = "both", threshold: r = 0 } = e, { subscribe:
|
|
32
|
-
let n = e.element,
|
|
116
|
+
function l(e) {
|
|
117
|
+
let { direction: t = "both", threshold: r = 0 } = e, { subscribe: i, notify: a } = n(), o = () => {
|
|
118
|
+
let n = e.element, i = (e, t) => ({
|
|
33
119
|
value: e,
|
|
34
120
|
remaining: Math.max(0, t)
|
|
35
121
|
});
|
|
36
122
|
if (!n) return {
|
|
37
|
-
top:
|
|
38
|
-
bottom:
|
|
39
|
-
left:
|
|
40
|
-
right:
|
|
123
|
+
top: c,
|
|
124
|
+
bottom: c,
|
|
125
|
+
left: c,
|
|
126
|
+
right: c
|
|
41
127
|
};
|
|
42
|
-
let
|
|
128
|
+
let a = n.scrollTop, o = n.scrollHeight - n.scrollTop - n.clientHeight, s = n.scrollLeft, l = n.scrollWidth - n.scrollLeft - n.clientWidth;
|
|
43
129
|
return {
|
|
44
|
-
top: t === "horizontal" ?
|
|
45
|
-
bottom: t === "horizontal" ?
|
|
46
|
-
left: t === "vertical" ?
|
|
47
|
-
right: t === "vertical" ?
|
|
130
|
+
top: t === "horizontal" ? c : i(a > r, a),
|
|
131
|
+
bottom: t === "horizontal" ? c : i(o <= r, o),
|
|
132
|
+
left: t === "vertical" ? c : i(s > r, s),
|
|
133
|
+
right: t === "vertical" ? c : i(l <= r, l)
|
|
48
134
|
};
|
|
49
135
|
};
|
|
50
136
|
return {
|
|
51
|
-
get:
|
|
137
|
+
get: o,
|
|
52
138
|
subscribe: (t) => {
|
|
53
139
|
let n = e.element;
|
|
54
|
-
if (!n) return t(
|
|
55
|
-
let r =
|
|
56
|
-
return n.addEventListener("scroll",
|
|
57
|
-
r(), n.removeEventListener("scroll",
|
|
140
|
+
if (!n) return t(o()), () => {};
|
|
141
|
+
let r = i(() => t(o())), a = () => t(o());
|
|
142
|
+
return n.addEventListener("scroll", a, { passive: !0 }), () => {
|
|
143
|
+
r(), n.removeEventListener("scroll", a);
|
|
58
144
|
};
|
|
59
145
|
},
|
|
60
146
|
"~": {
|
|
61
147
|
output: null,
|
|
62
|
-
notify:
|
|
148
|
+
notify: a
|
|
63
149
|
}
|
|
64
150
|
};
|
|
65
151
|
}
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
get: () => {
|
|
71
|
-
if (typeof window > "u") return n.defaultValues;
|
|
72
|
-
let e = { ...n.defaultValues };
|
|
73
|
-
for (let r in e) {
|
|
74
|
-
let i = t(window.sessionStorage.getItem(r)), a = n.schemas[r]["~standard"].validate(i);
|
|
75
|
-
if (a instanceof Promise) throw TypeError("[createSessionStorage] Validation schema should not return a Promise.");
|
|
76
|
-
a.issues && console.warn(JSON.stringify(a.issues, null, 2), { cause: a.issues }), e[r] = a.issues ? n.defaultValues[r] : a.value;
|
|
77
|
-
}
|
|
78
|
-
return e;
|
|
79
|
-
},
|
|
80
|
-
set: (e) => {
|
|
81
|
-
typeof window > "u" || Object.entries(e).forEach(([e, t]) => {
|
|
82
|
-
window.sessionStorage.setItem(e, typeof t == "string" ? t : JSON.stringify(t));
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
152
|
+
function u(e) {
|
|
153
|
+
return r({
|
|
154
|
+
kind: "sessionStorage",
|
|
155
|
+
...e
|
|
86
156
|
});
|
|
87
|
-
return typeof window < "u" && window.addEventListener("storage", () => {
|
|
88
|
-
r["~"].notify();
|
|
89
|
-
}), r;
|
|
90
157
|
}
|
|
91
|
-
function
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (typeof window > "u") return r;
|
|
97
|
-
let n = window.sessionStorage.getItem(e.key);
|
|
98
|
-
if (n === null) return r;
|
|
99
|
-
let i = t(n);
|
|
100
|
-
try {
|
|
101
|
-
if ("schema" in e) {
|
|
102
|
-
let t = e.schema["~standard"].validate(i);
|
|
103
|
-
if (t instanceof Promise) throw TypeError("Validation schema should not return a Promise.");
|
|
104
|
-
return t.issues ? (console.error(JSON.stringify(t.issues, null, 2), { cause: t.issues }), r) : t.value;
|
|
105
|
-
} else return i;
|
|
106
|
-
} catch {
|
|
107
|
-
return r !== void 0 && typeof r != "string" ? r : i;
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
return {
|
|
111
|
-
get: o,
|
|
112
|
-
set: (t) => {
|
|
113
|
-
if (typeof window > "u") return;
|
|
114
|
-
let n = typeof t == "function" ? t(o()) : t;
|
|
115
|
-
window.sessionStorage.setItem(e.key, typeof n == "string" ? n : JSON.stringify(n)), window.dispatchEvent(new Event("storage")), a();
|
|
116
|
-
},
|
|
117
|
-
subscribe: (t) => {
|
|
118
|
-
let n = i(() => t(o())), r = (n) => {
|
|
119
|
-
n.key === e.key && t(o());
|
|
120
|
-
};
|
|
121
|
-
return typeof window < "u" && window.addEventListener("storage", r), () => {
|
|
122
|
-
n(), typeof window < "u" && window.removeEventListener("storage", r);
|
|
123
|
-
};
|
|
124
|
-
},
|
|
125
|
-
"~": {
|
|
126
|
-
output: null,
|
|
127
|
-
notify: a
|
|
128
|
-
}
|
|
129
|
-
};
|
|
158
|
+
function d(e) {
|
|
159
|
+
return "storage" in e ? a(e) : a({
|
|
160
|
+
...e,
|
|
161
|
+
kind: "sessionStorage"
|
|
162
|
+
});
|
|
130
163
|
}
|
|
131
|
-
export { o as
|
|
164
|
+
export { i as createLocalStorage, o as createLocalStorageValue, u as createSessionStorage, d as createSessionStorageValue, s as mediaQuery, l as scrollState };
|
package/package.json
CHANGED
package/dist/core/store.d.ts
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
-
import type { Simplify } from '../utils';
|
|
3
|
-
import type { Readable, Subscribable, Writable } from './index';
|
|
4
|
-
export type StoreSchema = Record<string, StandardSchemaV1<unknown, unknown>>;
|
|
5
|
-
export type StoreOutput<S extends StoreSchema> = Simplify<{
|
|
6
|
-
[K in keyof S]: StandardSchemaV1.InferOutput<S[K]>;
|
|
7
|
-
}>;
|
|
8
|
-
export interface Store<O extends Record<string, unknown>> extends Subscribable<O>, Readable<O>, Writable<O> {
|
|
9
|
-
getDefaultValue: <K extends keyof O>(key: K) => O[K];
|
|
10
|
-
}
|
|
11
|
-
export interface StoreOptions<S extends Record<string, StandardSchemaV1>> {
|
|
12
|
-
/**
|
|
13
|
-
* Schemas for each storage key (one validator per key).
|
|
14
|
-
* Use this when each key has its own type; for a single compound schema use a wrapper with one key.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```ts
|
|
18
|
-
* const store = createStore({
|
|
19
|
-
* schemas: {
|
|
20
|
-
* token: z.string().nullable(),
|
|
21
|
-
* preferences: z.object({ theme: z.enum(['light', 'dark']) }),
|
|
22
|
-
* },
|
|
23
|
-
* defaultValues: { token: null, preferences: { theme: 'light' } },
|
|
24
|
-
* provider: {
|
|
25
|
-
* get: () => ({
|
|
26
|
-
* token: window.localStorage.getItem('token'),
|
|
27
|
-
* preferences: window.localStorage.getItem('preferences'),
|
|
28
|
-
* }),
|
|
29
|
-
* set: (value) => {
|
|
30
|
-
* window.localStorage.setItem('token', value.token ?? '')
|
|
31
|
-
* window.localStorage.setItem('preferences', JSON.stringify(value.preferences))
|
|
32
|
-
* },
|
|
33
|
-
* },
|
|
34
|
-
* })
|
|
35
|
-
* ```
|
|
36
|
-
*/
|
|
37
|
-
schemas: S;
|
|
38
|
-
/**
|
|
39
|
-
* The default values to use for the storage.
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```ts
|
|
43
|
-
* const store = createStore({
|
|
44
|
-
* schemas: {
|
|
45
|
-
* token: z.string().nullable(),
|
|
46
|
-
* preferences: z.object({ theme: z.enum(['light', 'dark']) }),
|
|
47
|
-
* },
|
|
48
|
-
* defaultValues: {
|
|
49
|
-
* token: null,
|
|
50
|
-
* preferences: { theme: 'light' },
|
|
51
|
-
* },
|
|
52
|
-
* provider: {
|
|
53
|
-
* get: () => ({
|
|
54
|
-
* token: window.localStorage.getItem('token'),
|
|
55
|
-
* preferences: window.localStorage.getItem('preferences'),
|
|
56
|
-
* }),
|
|
57
|
-
* set: (value) => {
|
|
58
|
-
* window.localStorage.setItem('token', value.token ?? '')
|
|
59
|
-
* window.localStorage.setItem('preferences', JSON.stringify(value.preferences))
|
|
60
|
-
* },
|
|
61
|
-
* },
|
|
62
|
-
* })
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
defaultValues: StoreOutput<S>;
|
|
66
|
-
provider: {
|
|
67
|
-
get: () => StoreOutput<S>;
|
|
68
|
-
set: (value: StoreOutput<S>) => void;
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Creates a reactive handle for a storage instance.
|
|
73
|
-
*
|
|
74
|
-
* @example
|
|
75
|
-
* ```ts twoslash
|
|
76
|
-
* import { createStore } from 'seitu'
|
|
77
|
-
* import * as z from 'zod'
|
|
78
|
-
*
|
|
79
|
-
* const store = createStore({
|
|
80
|
-
* schemas: {
|
|
81
|
-
* token: z.string().nullable(),
|
|
82
|
-
* preferences: z.object({ theme: z.enum(['light', 'dark']) }),
|
|
83
|
-
* },
|
|
84
|
-
* defaultValues: { token: null, preferences: { theme: 'light' } },
|
|
85
|
-
* provider: {
|
|
86
|
-
* get: () => ({
|
|
87
|
-
* token: window.localStorage.getItem('token'),
|
|
88
|
-
* preferences: JSON.parse(window.localStorage.getItem('preferences') ?? '{"theme":"light"}'),
|
|
89
|
-
* }),
|
|
90
|
-
* set: (value) => {
|
|
91
|
-
* window.localStorage.setItem('token', value.token ?? '')
|
|
92
|
-
* window.localStorage.setItem('preferences', JSON.stringify(value.preferences))
|
|
93
|
-
* },
|
|
94
|
-
* },
|
|
95
|
-
* })
|
|
96
|
-
*
|
|
97
|
-
* store.get().token // null
|
|
98
|
-
* store.get().preferences // { theme: 'light' }
|
|
99
|
-
* store.set({ token: '123', preferences: { theme: 'dark' } })
|
|
100
|
-
* store.get().token // '123'
|
|
101
|
-
* store.get().preferences // { theme: 'dark' }
|
|
102
|
-
* store.subscribe(value => console.log(value))
|
|
103
|
-
* store.set({ token: '456', preferences: { theme: 'light' } })
|
|
104
|
-
* // { token: '456', preferences: { theme: 'light' } }
|
|
105
|
-
* ```
|
|
106
|
-
*/
|
|
107
|
-
export declare function createStore<S extends Record<string, StandardSchemaV1>>(options: StoreOptions<S>): Store<StoreOutput<S>>;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|