seitu 0.9.1 → 0.10.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/dist/core/schema-store.d.ts +10 -12
- package/dist/core/store.d.ts +1 -1
- package/dist/core/subscription.d.ts +1 -0
- package/dist/core-Dldv77Xv.js +167 -0
- package/dist/core.js +2 -2
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/validation.d.ts +27 -0
- package/dist/validate.d.ts +23 -0
- package/dist/web/index.d.ts +0 -4
- package/dist/web/web-storage-value.d.ts +59 -11
- package/dist/web/web-storage.d.ts +56 -11
- package/dist/web.js +34 -206
- package/package.json +5 -1
- package/dist/core-vtgV_plC.js +0 -187
- package/dist/web/local-storage-value.d.ts +0 -68
- package/dist/web/local-storage.d.ts +0 -50
- package/dist/web/session-storage-value.d.ts +0 -68
- package/dist/web/session-storage.d.ts +0 -50
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ValidationObjectSchemas, ValidationObjectSchemasOutput } from '../validate';
|
|
3
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
4
|
export interface SchemaStore<O extends Record<string, unknown>> extends Subscribable<O>, Readable<O>, Writable<Partial<O>, O> {
|
|
9
|
-
|
|
5
|
+
'~': {
|
|
6
|
+
getDefaultValue: <K extends keyof O>(key: K) => O[K];
|
|
7
|
+
} & Subscribable<O>['~'];
|
|
10
8
|
}
|
|
11
9
|
export interface SchemaStoreOptions<S extends Record<string, StandardSchemaV1>> {
|
|
12
10
|
schemas: S;
|
|
13
|
-
defaultValues:
|
|
11
|
+
defaultValues: ValidationObjectSchemasOutput<S>;
|
|
14
12
|
/**
|
|
15
13
|
* The provider to use for the schema store. If not provided, the schema store will
|
|
16
14
|
* use an in-memory provider.
|
|
@@ -35,10 +33,10 @@ export interface SchemaStoreOptions<S extends Record<string, StandardSchemaV1>>
|
|
|
35
33
|
* store.subscribe(console.log)
|
|
36
34
|
* ```
|
|
37
35
|
*/
|
|
38
|
-
export declare function createSchemaStore<S extends Record<string, StandardSchemaV1>>(options: SchemaStoreOptions<S>): SchemaStore<
|
|
39
|
-
export interface SchemaStoreProvider<S extends
|
|
40
|
-
get: () =>
|
|
41
|
-
set: (value: Partial<
|
|
36
|
+
export declare function createSchemaStore<S extends Record<string, StandardSchemaV1>>(options: SchemaStoreOptions<S>): SchemaStore<ValidationObjectSchemasOutput<S>>;
|
|
37
|
+
export interface SchemaStoreProvider<S extends ValidationObjectSchemas> {
|
|
38
|
+
get: () => ValidationObjectSchemasOutput<S>;
|
|
39
|
+
set: (value: Partial<ValidationObjectSchemasOutput<S>>) => void;
|
|
42
40
|
}
|
|
43
41
|
/**
|
|
44
42
|
* Creates an in-memory provider for a schema store. Use as the state backing when you don't
|
|
@@ -56,4 +54,4 @@ export interface SchemaStoreProvider<S extends SchemaStoreSchema> {
|
|
|
56
54
|
* })
|
|
57
55
|
* ```
|
|
58
56
|
*/
|
|
59
|
-
export declare function createSchemaStoreMemoryProvider<S extends
|
|
57
|
+
export declare function createSchemaStoreMemoryProvider<S extends ValidationObjectSchemas>(): SchemaStoreProvider<S>;
|
package/dist/core/store.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Readable, Subscribable, Writable } from './subscription';
|
|
|
2
2
|
export interface Store<T> extends Readable<T>, Writable<T, T>, Subscribable<T> {
|
|
3
3
|
}
|
|
4
4
|
/**
|
|
5
|
-
* Creates a simple reactive store (minimal TanStack Store
|
|
5
|
+
* Creates a simple reactive store (minimal TanStack Store-style API).
|
|
6
6
|
*
|
|
7
7
|
* - **Standalone**: use `get()`, `set(value | updater)`, `subscribe(callback)` for any state.
|
|
8
8
|
* - **With schema-store**: use as the state backing for a memory provider.
|
|
@@ -26,6 +26,7 @@ export interface Writable<T, P = T> {
|
|
|
26
26
|
export interface Removable {
|
|
27
27
|
remove: () => void;
|
|
28
28
|
}
|
|
29
|
+
export declare function createReadableSubscription<T>(get: () => T, subscribe: (callback: () => any, options?: SubscribeOptions) => () => void, notify: () => void): Readable<T> & Subscribable<T>;
|
|
29
30
|
export declare function createSubscription(options?: {
|
|
30
31
|
onFirstSubscribe?: () => (void | (() => void));
|
|
31
32
|
}): {
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
//#region src/core/subscription.ts
|
|
2
|
+
function e(e, t, n) {
|
|
3
|
+
return {
|
|
4
|
+
get: e,
|
|
5
|
+
subscribe(n, r) {
|
|
6
|
+
return t(() => n(e()), r);
|
|
7
|
+
},
|
|
8
|
+
"~": {
|
|
9
|
+
output: null,
|
|
10
|
+
notify: n
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function t(e) {
|
|
15
|
+
let t = /* @__PURE__ */ new Set(), n = () => t.forEach((e) => e()), r;
|
|
16
|
+
return {
|
|
17
|
+
subscribe(n, i) {
|
|
18
|
+
return t.size === 0 && e?.onFirstSubscribe && (r = e.onFirstSubscribe() ?? void 0), i?.immediate && n(), t.add(n), () => {
|
|
19
|
+
t.delete(n), t.size === 0 && (r?.(), r = void 0);
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
notify: n
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/core/computed.ts
|
|
27
|
+
function n(n, r) {
|
|
28
|
+
let i = Array.isArray(n) ? n : [n], a = !Array.isArray(n), { subscribe: o, notify: s } = t({ onFirstSubscribe() {
|
|
29
|
+
let e = i.map((e) => e.subscribe(() => s()));
|
|
30
|
+
return () => e.forEach((e) => e());
|
|
31
|
+
} });
|
|
32
|
+
return e(() => r(a ? i[0].get() : i.map((e) => e.get())), o, s);
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/core/debounce.ts
|
|
36
|
+
function r(n, r) {
|
|
37
|
+
let i = n.get(), a, { subscribe: o, notify: s } = t({ onFirstSubscribe() {
|
|
38
|
+
let e = n.subscribe(() => {
|
|
39
|
+
clearTimeout(a), a = setTimeout(() => {
|
|
40
|
+
i = n.get(), s();
|
|
41
|
+
}, r);
|
|
42
|
+
});
|
|
43
|
+
return () => {
|
|
44
|
+
clearTimeout(a), e();
|
|
45
|
+
};
|
|
46
|
+
} });
|
|
47
|
+
return e(() => i, o, s);
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/core/debounce-fn.ts
|
|
51
|
+
function i(n, r) {
|
|
52
|
+
let i, a, { subscribe: o, notify: s } = t();
|
|
53
|
+
return Object.assign((...e) => {
|
|
54
|
+
clearTimeout(a), a = setTimeout(() => {
|
|
55
|
+
i = n(...e), s();
|
|
56
|
+
}, r);
|
|
57
|
+
}, e(() => i, o, s));
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/utils.ts
|
|
61
|
+
function a(e) {
|
|
62
|
+
if (typeof e != "string") return e;
|
|
63
|
+
try {
|
|
64
|
+
return JSON.parse(e);
|
|
65
|
+
} catch {
|
|
66
|
+
return e;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/validate.ts
|
|
71
|
+
function o(e, t, n) {
|
|
72
|
+
let r = a(t), i = e["~standard"].validate(r);
|
|
73
|
+
if (i instanceof Promise) throw TypeError(`[${n.label}] Validation schema should not return a Promise.`);
|
|
74
|
+
if (!i.issues) return i.value;
|
|
75
|
+
if (n.onError) {
|
|
76
|
+
let t = n.onError(i.issues, r);
|
|
77
|
+
if (t !== void 0) {
|
|
78
|
+
let r = e["~standard"].validate(t);
|
|
79
|
+
if (r instanceof Promise) throw TypeError(`[${n.label}] Validation schema should not return a Promise.`);
|
|
80
|
+
if (r.issues) console.warn(`[${n.label}] Returned value invalid, returned default value instead`, JSON.stringify(r.issues, null, 2), { cause: r.issues });
|
|
81
|
+
else return r.value;
|
|
82
|
+
}
|
|
83
|
+
} else console.warn(`[${n.label}] Returned value invalid, returned default value instead`, JSON.stringify(i.issues, null, 2), { cause: i.issues });
|
|
84
|
+
return n.defaultValue;
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/core/schema-store.ts
|
|
88
|
+
function s(n) {
|
|
89
|
+
let { subscribe: r, notify: i } = t(), a = { ...n.defaultValues }, s = n.provider ?? c(), l = () => {
|
|
90
|
+
let e = { ...a };
|
|
91
|
+
for (let [t, r] of Object.entries(n.schemas)) e[t] = o(r, s.get()[t], {
|
|
92
|
+
defaultValue: a[t],
|
|
93
|
+
label: `createSchemaStore:${String(t)}`
|
|
94
|
+
});
|
|
95
|
+
return e;
|
|
96
|
+
}, u = e(l, r, i);
|
|
97
|
+
return {
|
|
98
|
+
...u,
|
|
99
|
+
set: (e) => {
|
|
100
|
+
let t = typeof e == "function" ? e(l()) : e;
|
|
101
|
+
s.set(t), i();
|
|
102
|
+
},
|
|
103
|
+
"~": {
|
|
104
|
+
...u["~"],
|
|
105
|
+
getDefaultValue: (e) => a[e]
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function c() {
|
|
110
|
+
let e = l({});
|
|
111
|
+
return {
|
|
112
|
+
get: () => e.get(),
|
|
113
|
+
set: (t) => {
|
|
114
|
+
e.set(t);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/core/store.ts
|
|
120
|
+
function l(n) {
|
|
121
|
+
let r = n, { subscribe: i, notify: a } = t();
|
|
122
|
+
return {
|
|
123
|
+
...e(() => r, i, a),
|
|
124
|
+
set: (e) => {
|
|
125
|
+
let t = typeof e == "function" ? e(r) : e;
|
|
126
|
+
t !== r && (r = t, a());
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/core/throttle.ts
|
|
132
|
+
function u(n, r) {
|
|
133
|
+
let i = n.get(), a, o = !1, { subscribe: s, notify: c } = t({ onFirstSubscribe() {
|
|
134
|
+
let e = n.subscribe(() => {
|
|
135
|
+
if (a) {
|
|
136
|
+
o = !0;
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
i = n.get(), c(), a = setTimeout(() => {
|
|
140
|
+
a = void 0, o && (o = !1, i = n.get(), c());
|
|
141
|
+
}, r);
|
|
142
|
+
});
|
|
143
|
+
return () => {
|
|
144
|
+
clearTimeout(a), a = void 0, o = !1, e();
|
|
145
|
+
};
|
|
146
|
+
} });
|
|
147
|
+
return e(() => i, s, c);
|
|
148
|
+
}
|
|
149
|
+
//#endregion
|
|
150
|
+
//#region src/core/throttle-fn.ts
|
|
151
|
+
function d(n, r) {
|
|
152
|
+
let i, a, o, { subscribe: s, notify: c } = t();
|
|
153
|
+
return Object.assign((...e) => {
|
|
154
|
+
if (a) {
|
|
155
|
+
o = e;
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
i = n(...e), c(), a = setTimeout(() => {
|
|
159
|
+
if (a = void 0, o) {
|
|
160
|
+
let e = o;
|
|
161
|
+
o = void 0, i = n(...e), c();
|
|
162
|
+
}
|
|
163
|
+
}, r);
|
|
164
|
+
}, e(() => i, s, c));
|
|
165
|
+
}
|
|
166
|
+
//#endregion
|
|
167
|
+
export { c as a, n as c, s as i, e as l, u as n, i as o, l as r, r as s, d as t, t as u };
|
package/dist/core.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, c as t, i as n, l as r, n as i,
|
|
2
|
-
export {
|
|
1
|
+
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c, u as l } from "./core-Dldv77Xv.js";
|
|
2
|
+
export { t as createComputed, s as createDebounce, a as createDebounceFn, r as createReadableSubscription, n as createSchemaStore, e as createSchemaStoreMemoryProvider, o as createStore, l as createSubscription, i as createThrottle, c as createThrottleFn };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './validation';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ValidationSchemaErrorProps } from '../validate';
|
|
2
|
+
/**
|
|
3
|
+
* Repair broken web storage value object if value was object but not all keys are in the default value object.
|
|
4
|
+
*
|
|
5
|
+
* @returns A new object with the existing keys in the value object that are not in the default value object.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createWebStorageValue } from 'seitu/web'
|
|
10
|
+
* import { repairWebStorageValueObjectWithDefault } from 'seitu/utils'
|
|
11
|
+
* import * as z from 'zod'
|
|
12
|
+
*
|
|
13
|
+
* const value = createWebStorageValue({
|
|
14
|
+
* type: 'localStorage',
|
|
15
|
+
* schema: z.object({ a: z.number(), b: z.string() }),
|
|
16
|
+
* key: 'storage-key',
|
|
17
|
+
* defaultValue: { a: 0, b: 'default' },
|
|
18
|
+
* onValidationError: repairWebStorageValueObjectWithDefault,
|
|
19
|
+
* })
|
|
20
|
+
* value.get() // { a: 0, b: 'default' }
|
|
21
|
+
* window.localStorage.setItem('storage-key', JSON.stringify({ a: 1 }))
|
|
22
|
+
* value.get() // { a: 1, b: 'default' }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function repairWebStorageValueObjectWithDefault<O extends Record<string, unknown>>(props: ValidationSchemaErrorProps<O>): O & {
|
|
26
|
+
[k: string]: any;
|
|
27
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
import type { Simplify } from './utils';
|
|
3
|
+
export type ValidationObjectSchemas = Record<string, StandardSchemaV1<unknown, unknown>>;
|
|
4
|
+
export type ValidationObjectSchemasOutput<S extends ValidationObjectSchemas> = Simplify<{
|
|
5
|
+
[K in keyof S]: StandardSchemaV1.InferOutput<S[K]>;
|
|
6
|
+
}>;
|
|
7
|
+
export interface ValidationSchemaErrorProps<O> {
|
|
8
|
+
defaultValue: O;
|
|
9
|
+
issues: StandardSchemaV1.Issue[];
|
|
10
|
+
value: unknown;
|
|
11
|
+
}
|
|
12
|
+
export interface ValidationSchemasErrorProps<O extends Record<string, unknown>> {
|
|
13
|
+
defaultValue: O[keyof O];
|
|
14
|
+
issues: StandardSchemaV1.Issue[];
|
|
15
|
+
value: unknown;
|
|
16
|
+
key: keyof O;
|
|
17
|
+
}
|
|
18
|
+
export interface ValidateSchemaOptions {
|
|
19
|
+
defaultValue: unknown;
|
|
20
|
+
label: string;
|
|
21
|
+
onError?: (issues: readonly StandardSchemaV1.Issue[], parsed: unknown) => unknown;
|
|
22
|
+
}
|
|
23
|
+
export declare function validateSchema(schema: StandardSchemaV1, value: unknown, options: ValidateSchemaOptions): unknown;
|
package/dist/web/index.d.ts
CHANGED
|
@@ -1,26 +1,74 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
2
|
import type { Readable, Removable, Subscribable, Writable } from '../core/index';
|
|
3
|
+
import type { ValidationSchemaErrorProps, ValidationSchemasErrorProps } from '../validate';
|
|
3
4
|
import type { WebStorage } from './web-storage';
|
|
4
5
|
export interface WebStorageValue<V> extends Subscribable<V>, Readable<V>, Writable<V>, Removable {
|
|
5
6
|
}
|
|
6
7
|
export interface WebStorageValueOptionsWithStorage<Storage extends WebStorage<any>, K extends keyof Storage['~']['output']> {
|
|
7
8
|
storage: Storage;
|
|
8
9
|
key: K;
|
|
9
|
-
onValidationError?: (props:
|
|
10
|
-
issues: StandardSchemaV1.Issue[];
|
|
11
|
-
value: unknown;
|
|
12
|
-
}) => void;
|
|
10
|
+
onValidationError?: (props: ValidationSchemasErrorProps<Storage['~']['output']>) => void;
|
|
13
11
|
}
|
|
14
12
|
export interface WebStorageValueOptionsWithSchema<S extends StandardSchemaV1<unknown>> {
|
|
13
|
+
type: 'localStorage' | 'sessionStorage';
|
|
15
14
|
schema: S;
|
|
16
15
|
key: string;
|
|
17
16
|
defaultValue: StandardSchemaV1.InferOutput<S>;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Handle validation errors.
|
|
19
|
+
*
|
|
20
|
+
* If returns a value, it will be used as the value to validate and return.
|
|
21
|
+
* If returns undefined, the default value will be returned.
|
|
22
|
+
*/
|
|
23
|
+
onValidationError?: (props: ValidationSchemaErrorProps<StandardSchemaV1.InferOutput<S>>) => void | StandardSchemaV1.InferOutput<S>;
|
|
22
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates a reactive handle for a localStorage or sessionStorage instance.
|
|
27
|
+
*
|
|
28
|
+
* @example Vanilla
|
|
29
|
+
* ```ts twoslash title="session-storage.ts"
|
|
30
|
+
* import { createWebStorage } from 'seitu/web'
|
|
31
|
+
* import * as z from 'zod'
|
|
32
|
+
*
|
|
33
|
+
* const sessionStorage = createWebStorage({
|
|
34
|
+
* type: 'sessionStorage',
|
|
35
|
+
* schemas: {
|
|
36
|
+
* token: z.string().nullable(),
|
|
37
|
+
* preferences: z.object({ theme: z.enum(['light', 'dark']) }),
|
|
38
|
+
* },
|
|
39
|
+
* defaultValues: { token: null, preferences: { theme: 'light' } },
|
|
40
|
+
* })
|
|
41
|
+
*
|
|
42
|
+
* sessionStorage.get() // { token: null, preferences: { theme: 'light' } }
|
|
43
|
+
* sessionStorage.set({ token: 'abc' })
|
|
44
|
+
* sessionStorage.get() // { token: 'abc', preferences: { theme: 'light' } }
|
|
45
|
+
* sessionStorage.subscribe(console.log)
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @example React
|
|
49
|
+
* ```tsx twoslash title="page.tsx"
|
|
50
|
+
* 'use client'
|
|
51
|
+
*
|
|
52
|
+
* import { createWebStorage } from 'seitu/web'
|
|
53
|
+
* import { useSubscription } from 'seitu/react'
|
|
54
|
+
* import * as z from 'zod'
|
|
55
|
+
*
|
|
56
|
+
* const sessionStorage = createWebStorage({
|
|
57
|
+
* type: 'sessionStorage',
|
|
58
|
+
* schemas: { count: z.number(), name: z.string() },
|
|
59
|
+
* defaultValues: { count: 0, name: '' },
|
|
60
|
+
* })
|
|
61
|
+
*
|
|
62
|
+
* export default function Page() {
|
|
63
|
+
* const value = useSubscription(sessionStorage)
|
|
64
|
+
* return (
|
|
65
|
+
* <div>
|
|
66
|
+
* <span>{value.count}</span>
|
|
67
|
+
* <span>{value.name}</span>
|
|
68
|
+
* </div>
|
|
69
|
+
* )
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
23
73
|
export declare function createWebStorageValue<Storage extends WebStorage<any>, K extends keyof Storage['~']['output']>(options: WebStorageValueOptionsWithStorage<Storage, K>): WebStorageValue<Storage['~']['output'][K]>;
|
|
24
|
-
export declare function createWebStorageValue<S extends StandardSchemaV1<unknown>>(options: WebStorageValueOptionsWithSchema<S>
|
|
25
|
-
kind: 'sessionStorage' | 'localStorage';
|
|
26
|
-
}): WebStorageValue<StandardSchemaV1.InferOutput<S>>;
|
|
74
|
+
export declare function createWebStorageValue<S extends StandardSchemaV1<unknown>>(options: WebStorageValueOptionsWithSchema<S>): WebStorageValue<StandardSchemaV1.InferOutput<S>>;
|
|
@@ -1,18 +1,63 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
-
import type { SchemaStore, SchemaStoreOptions
|
|
3
|
-
|
|
2
|
+
import type { SchemaStore, SchemaStoreOptions } from '../core/index';
|
|
3
|
+
import type { ValidationObjectSchemas, ValidationObjectSchemasOutput, ValidationSchemasErrorProps } from '../validate';
|
|
4
|
+
export interface WebStorageOptions<S extends ValidationObjectSchemas> extends Omit<SchemaStoreOptions<S>, 'provider'> {
|
|
5
|
+
type: 'localStorage' | 'sessionStorage';
|
|
4
6
|
keyTransform?: (key: keyof S) => string;
|
|
5
|
-
onValidationError?: <
|
|
6
|
-
issues: StandardSchemaV1.Issue[];
|
|
7
|
-
key: K;
|
|
8
|
-
value: unknown;
|
|
9
|
-
}) => void | StandardSchemaV1.InferOutput<S[K]>;
|
|
7
|
+
onValidationError?: (props: ValidationSchemasErrorProps<ValidationObjectSchemasOutput<S>>) => void | StandardSchemaV1.InferOutput<S[keyof S]>;
|
|
10
8
|
}
|
|
11
9
|
export interface WebStorage<O extends Record<string, unknown>> extends SchemaStore<O> {
|
|
12
10
|
'~': {
|
|
13
|
-
|
|
11
|
+
getDefaultValue: <K extends keyof O>(key: K) => O[K];
|
|
12
|
+
type: 'localStorage' | 'sessionStorage';
|
|
14
13
|
} & SchemaStore<O>['~'];
|
|
15
14
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Creates a reactive handle for a localStorage or sessionStorage instance.
|
|
17
|
+
*
|
|
18
|
+
* @example Vanilla
|
|
19
|
+
* ```ts twoslash title="session-storage.ts"
|
|
20
|
+
* import { createWebStorage } from 'seitu/web'
|
|
21
|
+
* import * as z from 'zod'
|
|
22
|
+
*
|
|
23
|
+
* const sessionStorage = createWebStorage({
|
|
24
|
+
* type: 'sessionStorage',
|
|
25
|
+
* schemas: {
|
|
26
|
+
* token: z.string().nullable(),
|
|
27
|
+
* preferences: z.object({ theme: z.enum(['light', 'dark']) }),
|
|
28
|
+
* },
|
|
29
|
+
* defaultValues: { token: null, preferences: { theme: 'light' } },
|
|
30
|
+
* })
|
|
31
|
+
*
|
|
32
|
+
* sessionStorage.get() // { token: null, preferences: { theme: 'light' } }
|
|
33
|
+
* sessionStorage.set({ token: 'abc' })
|
|
34
|
+
* sessionStorage.get() // { token: 'abc', preferences: { theme: 'light' } }
|
|
35
|
+
* sessionStorage.subscribe(console.log)
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @example React
|
|
39
|
+
* ```tsx twoslash title="page.tsx"
|
|
40
|
+
* 'use client'
|
|
41
|
+
*
|
|
42
|
+
* import { createWebStorage } from 'seitu/web'
|
|
43
|
+
* import { useSubscription } from 'seitu/react'
|
|
44
|
+
* import * as z from 'zod'
|
|
45
|
+
*
|
|
46
|
+
* const sessionStorage = createWebStorage({
|
|
47
|
+
* type: 'sessionStorage',
|
|
48
|
+
* schemas: { count: z.number(), name: z.string() },
|
|
49
|
+
* defaultValues: { count: 0, name: '' },
|
|
50
|
+
* })
|
|
51
|
+
*
|
|
52
|
+
* export default function Page() {
|
|
53
|
+
* const value = useSubscription(sessionStorage)
|
|
54
|
+
* return (
|
|
55
|
+
* <div>
|
|
56
|
+
* <span>{value.count}</span>
|
|
57
|
+
* <span>{value.name}</span>
|
|
58
|
+
* </div>
|
|
59
|
+
* )
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function createWebStorage<S extends ValidationObjectSchemas>(options: WebStorageOptions<S>): WebStorage<ValidationObjectSchemasOutput<S>>;
|
package/dist/web.js
CHANGED
|
@@ -1,181 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { l as e, u as t } from "./core-Dldv77Xv.js";
|
|
2
2
|
//#region src/web/is-online.ts
|
|
3
3
|
function n() {
|
|
4
|
-
let { subscribe:
|
|
5
|
-
typeof window < "u" && (window.removeEventListener("online",
|
|
6
|
-
}) })
|
|
7
|
-
return
|
|
8
|
-
get: r,
|
|
9
|
-
subscribe: (t, n) => e(() => t(r()), n),
|
|
10
|
-
"~": {
|
|
11
|
-
output: null,
|
|
12
|
-
notify: n
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
//#endregion
|
|
17
|
-
//#region src/web/web-storage.ts
|
|
18
|
-
function r(n) {
|
|
19
|
-
let r = !1, { subscribe: i, notify: a } = t({ onFirstSubscribe: () => {
|
|
20
|
-
let e = () => {
|
|
21
|
-
r || a();
|
|
22
|
-
};
|
|
23
|
-
return typeof window < "u" && window.addEventListener("storage", e), () => {
|
|
24
|
-
typeof window < "u" && window.removeEventListener("storage", e);
|
|
25
|
-
};
|
|
26
|
-
} }), o = { ...n.defaultValues }, s = () => {
|
|
27
|
-
if (typeof window > "u") return n.defaultValues;
|
|
28
|
-
let t = window[n.kind], r = { ...n.defaultValues };
|
|
29
|
-
for (let i in r) {
|
|
30
|
-
let a = t.getItem(n.keyTransform ? n.keyTransform(i) : i);
|
|
31
|
-
if (a === null) {
|
|
32
|
-
r[i] = n.defaultValues[i];
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
let o = e(a), s = n.schemas[i]["~standard"].validate(o);
|
|
36
|
-
if (s instanceof Promise) throw TypeError("[createWebStorage] Validation schema should not return a Promise.");
|
|
37
|
-
if (s.issues) if (n.onValidationError) {
|
|
38
|
-
let e = n.onValidationError({
|
|
39
|
-
issues: [...s.issues],
|
|
40
|
-
key: i,
|
|
41
|
-
value: o
|
|
42
|
-
});
|
|
43
|
-
if (e !== void 0) {
|
|
44
|
-
let t = n.schemas[i]["~standard"].validate(e);
|
|
45
|
-
if (t instanceof Promise) throw TypeError("[createWebStorage] Validation schema should not return a Promise.");
|
|
46
|
-
t.issues ? console.warn(`[createWebStorage] Returned value invalid for key ${i}, returned default value instead`, JSON.stringify(t.issues, null, 2), { cause: t.issues }) : r[i] = t.value;
|
|
47
|
-
}
|
|
48
|
-
} else console.warn(`[createWebStorage] Returned value invalid for key ${i}, returned default value instead`, JSON.stringify(s.issues, null, 2), { cause: s.issues }), r[i] = n.defaultValues[i];
|
|
49
|
-
else r[i] = s.value;
|
|
50
|
-
}
|
|
51
|
-
return r;
|
|
52
|
-
};
|
|
53
|
-
return {
|
|
54
|
-
get: s,
|
|
55
|
-
set: (e) => {
|
|
56
|
-
let t = typeof e == "function" ? e(s()) : e;
|
|
57
|
-
if (typeof window > "u") return;
|
|
58
|
-
let i = window[n.kind];
|
|
59
|
-
r = !0, Object.entries(t).forEach(([e, t]) => {
|
|
60
|
-
let r = typeof t == "string" ? t : JSON.stringify(t);
|
|
61
|
-
i.setItem(n.keyTransform ? n.keyTransform(e) : e, r), window.dispatchEvent(new StorageEvent("storage", {
|
|
62
|
-
key: n.keyTransform ? n.keyTransform(e) : e,
|
|
63
|
-
newValue: r
|
|
64
|
-
}));
|
|
65
|
-
}), r = !1, a();
|
|
66
|
-
},
|
|
67
|
-
getDefaultValue: (e) => o[e],
|
|
68
|
-
subscribe: (e, t = {}) => i(() => e(s()), t),
|
|
69
|
-
"~": {
|
|
70
|
-
kind: n.kind,
|
|
71
|
-
output: null,
|
|
72
|
-
notify: a
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
//#endregion
|
|
77
|
-
//#region src/web/local-storage.ts
|
|
78
|
-
function i(e) {
|
|
79
|
-
return r({
|
|
80
|
-
kind: "localStorage",
|
|
81
|
-
...e
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
//#endregion
|
|
85
|
-
//#region src/web/web-storage-value.ts
|
|
86
|
-
function a(n) {
|
|
87
|
-
let r = "storage" in n ? n.storage["~"].kind : n.kind, i = !1, a = `${r}Value`;
|
|
88
|
-
if ("schema" in n && n.defaultValue === void 0) throw Error(`[${a}] Default value is required`);
|
|
89
|
-
if (n.key === void 0) throw Error(`[${a}] Key is required`);
|
|
90
|
-
if (!("schema" in n || "storage" in n)) throw Error(`[${a}] Either schema or storage must be provided`);
|
|
91
|
-
let o = ("schema" in n ? n.defaultValue : n.storage.getDefaultValue(n.key)) ?? null, { subscribe: s, notify: c } = t({ onFirstSubscribe: () => {
|
|
92
|
-
let e = (e) => {
|
|
93
|
-
i || e.key === n.key && c();
|
|
94
|
-
};
|
|
95
|
-
return typeof window < "u" && window.addEventListener("storage", e), () => {
|
|
96
|
-
typeof window < "u" && window.removeEventListener("storage", e);
|
|
97
|
-
};
|
|
98
|
-
} }), l = () => {
|
|
99
|
-
if (typeof window > "u") return o;
|
|
100
|
-
let t = window[r].getItem(n.key);
|
|
101
|
-
if (t === null) return o;
|
|
102
|
-
let i = e(t);
|
|
103
|
-
try {
|
|
104
|
-
if ("schema" in n) {
|
|
105
|
-
let e = n.schema["~standard"].validate(i);
|
|
106
|
-
if (e instanceof Promise) throw TypeError("Validation schema should not return a Promise.");
|
|
107
|
-
if (e.issues) {
|
|
108
|
-
if (n.onValidationError) {
|
|
109
|
-
let t = n.onValidationError({
|
|
110
|
-
issues: [...e.issues],
|
|
111
|
-
value: i
|
|
112
|
-
});
|
|
113
|
-
if (t !== void 0) {
|
|
114
|
-
let e = n.schema["~standard"].validate(t);
|
|
115
|
-
if (e instanceof Promise) throw TypeError("Validation schema should not return a Promise.");
|
|
116
|
-
if (e.issues) console.warn(`[${a}] Returned value invalid for key ${n.key}, returned default value instead`, JSON.stringify(e.issues, null, 2), { cause: e.issues });
|
|
117
|
-
else return e.value;
|
|
118
|
-
}
|
|
119
|
-
} else console.warn(`[${a}] Returned value invalid for key ${n.key}, returned default value instead`, JSON.stringify(e.issues, null, 2), { cause: e.issues });
|
|
120
|
-
return o;
|
|
121
|
-
}
|
|
122
|
-
return e.value;
|
|
123
|
-
} else return i;
|
|
124
|
-
} catch {
|
|
125
|
-
return o !== void 0 && typeof o != "string" ? o : i;
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
return {
|
|
129
|
-
get: l,
|
|
130
|
-
set: (e) => {
|
|
131
|
-
if (typeof window > "u") return;
|
|
132
|
-
let t = window[r], a = typeof e == "function" ? e(l()) : e;
|
|
133
|
-
i = !0, t.setItem(n.key, typeof a == "string" ? a : JSON.stringify(a)), window.dispatchEvent(new StorageEvent("storage", {
|
|
134
|
-
key: n.key,
|
|
135
|
-
newValue: a
|
|
136
|
-
})), i = !1, c();
|
|
137
|
-
},
|
|
138
|
-
subscribe: (e, t = {}) => s(() => e(l()), t),
|
|
139
|
-
remove: () => {
|
|
140
|
-
typeof window > "u" || window[r].removeItem(n.key);
|
|
141
|
-
},
|
|
142
|
-
"~": {
|
|
143
|
-
output: null,
|
|
144
|
-
notify: c
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
//#endregion
|
|
149
|
-
//#region src/web/local-storage-value.ts
|
|
150
|
-
function o(e) {
|
|
151
|
-
return "storage" in e ? a(e) : a({
|
|
152
|
-
...e,
|
|
153
|
-
kind: "localStorage"
|
|
154
|
-
});
|
|
4
|
+
let { subscribe: n, notify: r } = t({ onFirstSubscribe: () => (typeof window < "u" && (window.addEventListener("online", r), window.addEventListener("offline", r)), () => {
|
|
5
|
+
typeof window < "u" && (window.removeEventListener("online", r), window.removeEventListener("offline", r));
|
|
6
|
+
}) });
|
|
7
|
+
return e(() => typeof navigator > "u" ? !0 : navigator.onLine, n, r);
|
|
155
8
|
}
|
|
156
9
|
//#endregion
|
|
157
10
|
//#region src/web/media-query.ts
|
|
158
|
-
function
|
|
159
|
-
let
|
|
160
|
-
|
|
161
|
-
}) })
|
|
162
|
-
return
|
|
163
|
-
get: a,
|
|
164
|
-
subscribe: (e, t = {}) => r(() => e(a()), t),
|
|
165
|
-
"~": {
|
|
166
|
-
output: null,
|
|
167
|
-
notify: i
|
|
168
|
-
}
|
|
169
|
-
};
|
|
11
|
+
function r(n) {
|
|
12
|
+
let r = typeof window > "u" ? null : window.matchMedia(n.query), { subscribe: i, notify: a } = t({ onFirstSubscribe: () => (r?.addEventListener("change", a), () => {
|
|
13
|
+
r?.removeEventListener("change", a);
|
|
14
|
+
}) });
|
|
15
|
+
return e(() => r?.matches ?? n.defaultMatches ?? !1, i, a);
|
|
170
16
|
}
|
|
171
17
|
//#endregion
|
|
172
18
|
//#region src/web/scroll-state.ts
|
|
173
|
-
var
|
|
19
|
+
var i = {
|
|
174
20
|
reached: !1,
|
|
175
21
|
remaining: 0
|
|
176
22
|
};
|
|
177
|
-
function
|
|
178
|
-
let { direction: n = "both", threshold: r = 0 } = e,
|
|
23
|
+
function a(e) {
|
|
24
|
+
let { direction: n = "both", threshold: r = 0 } = e, a = typeof r == "number" ? {
|
|
179
25
|
top: r,
|
|
180
26
|
bottom: r,
|
|
181
27
|
left: r,
|
|
@@ -185,56 +31,38 @@ function l(e) {
|
|
|
185
31
|
bottom: r.bottom ?? 0,
|
|
186
32
|
left: r.left ?? 0,
|
|
187
33
|
right: r.right ?? 0
|
|
188
|
-
},
|
|
189
|
-
let e =
|
|
34
|
+
}, o = () => typeof e.element == "function" ? e.element() : e.element, s = () => {
|
|
35
|
+
let e = o(), t = (e, t) => ({
|
|
190
36
|
reached: e,
|
|
191
37
|
remaining: Math.max(0, t)
|
|
192
38
|
});
|
|
193
39
|
if (!e) return {
|
|
194
|
-
top:
|
|
195
|
-
bottom:
|
|
196
|
-
left:
|
|
197
|
-
right:
|
|
40
|
+
top: i,
|
|
41
|
+
bottom: i,
|
|
42
|
+
left: i,
|
|
43
|
+
right: i
|
|
198
44
|
};
|
|
199
|
-
let r = e.scrollTop,
|
|
45
|
+
let r = e.scrollTop, s = e.scrollHeight - e.scrollTop - e.clientHeight, c = e.scrollLeft, l = e.scrollWidth - e.scrollLeft - e.clientWidth;
|
|
200
46
|
return {
|
|
201
|
-
top: n === "horizontal" ?
|
|
202
|
-
bottom: n === "horizontal" ?
|
|
203
|
-
left: n === "vertical" ?
|
|
204
|
-
right: n === "vertical" ?
|
|
47
|
+
top: n === "horizontal" ? i : t(r <= a.top, r),
|
|
48
|
+
bottom: n === "horizontal" ? i : t(s <= a.bottom, s),
|
|
49
|
+
left: n === "vertical" ? i : t(c <= a.left, c),
|
|
50
|
+
right: n === "vertical" ? i : t(l <= a.right, l)
|
|
205
51
|
};
|
|
206
|
-
}
|
|
52
|
+
}, { subscribe: c, notify: l } = t({ onFirstSubscribe() {
|
|
53
|
+
let e = o();
|
|
54
|
+
if (!e) return;
|
|
55
|
+
let t = () => l();
|
|
56
|
+
return e.addEventListener("scroll", t, { passive: !0 }), () => e.removeEventListener("scroll", t);
|
|
57
|
+
} });
|
|
207
58
|
return {
|
|
208
|
-
get:
|
|
209
|
-
subscribe: (e, t = {}) => {
|
|
210
|
-
let n = s();
|
|
211
|
-
if (!n) return e(l()), () => {};
|
|
212
|
-
let r = i(() => e(l()), t), a = () => e(l());
|
|
213
|
-
return n.addEventListener("scroll", a, { passive: !0 }), () => {
|
|
214
|
-
r(), n.removeEventListener("scroll", a);
|
|
215
|
-
};
|
|
216
|
-
},
|
|
59
|
+
get: s,
|
|
60
|
+
subscribe: (e, t = {}) => o() ? c(() => e(s()), t) : (e(s()), () => {}),
|
|
217
61
|
"~": {
|
|
218
62
|
output: null,
|
|
219
|
-
notify:
|
|
63
|
+
notify: l
|
|
220
64
|
}
|
|
221
65
|
};
|
|
222
66
|
}
|
|
223
67
|
//#endregion
|
|
224
|
-
|
|
225
|
-
function u(e) {
|
|
226
|
-
return r({
|
|
227
|
-
kind: "sessionStorage",
|
|
228
|
-
...e
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
//#endregion
|
|
232
|
-
//#region src/web/session-storage-value.ts
|
|
233
|
-
function d(e) {
|
|
234
|
-
return "storage" in e ? a(e) : a({
|
|
235
|
-
...e,
|
|
236
|
-
kind: "sessionStorage"
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
//#endregion
|
|
240
|
-
export { n as createIsOnline, i as createLocalStorage, o as createLocalStorageValue, s as createMediaQuery, l as createScrollState, u as createSessionStorage, d as createSessionStorageValue };
|
|
68
|
+
export { n as createIsOnline, r as createMediaQuery, a as createScrollState };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "seitu",
|
|
3
3
|
"displayName": "Seitu",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.10.0",
|
|
6
6
|
"private": false,
|
|
7
7
|
"author": "Valerii Strilets",
|
|
8
8
|
"license": "MIT",
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
"./vue": {
|
|
40
40
|
"types": "./dist/vue/index.d.ts",
|
|
41
41
|
"import": "./dist/vue.js"
|
|
42
|
+
},
|
|
43
|
+
"./utils": {
|
|
44
|
+
"types": "./dist/utils/index.d.ts",
|
|
45
|
+
"import": "./dist/utils.js"
|
|
42
46
|
}
|
|
43
47
|
},
|
|
44
48
|
"main": "./dist/core.js",
|
package/dist/core-vtgV_plC.js
DELETED
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
//#region src/core/subscription.ts
|
|
2
|
-
function e(e) {
|
|
3
|
-
let t = /* @__PURE__ */ new Set(), n = () => t.forEach((e) => e()), r;
|
|
4
|
-
return {
|
|
5
|
-
subscribe(n, i) {
|
|
6
|
-
return t.size === 0 && e?.onFirstSubscribe && (r = e.onFirstSubscribe() ?? void 0), i?.immediate && n(), t.add(n), () => {
|
|
7
|
-
t.delete(n), t.size === 0 && (r?.(), r = void 0);
|
|
8
|
-
};
|
|
9
|
-
},
|
|
10
|
-
notify: n
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/core/computed.ts
|
|
15
|
-
function t(t, n) {
|
|
16
|
-
let { subscribe: r, notify: i } = e(), a = Array.isArray(t) ? t : [t], o = !Array.isArray(t), s = () => n(o ? a[0].get() : a.map((e) => e.get()));
|
|
17
|
-
for (let e of a) e.subscribe(() => i());
|
|
18
|
-
return {
|
|
19
|
-
get: s,
|
|
20
|
-
subscribe(e, t) {
|
|
21
|
-
return r(() => e(s()), t);
|
|
22
|
-
},
|
|
23
|
-
"~": {
|
|
24
|
-
output: null,
|
|
25
|
-
notify: i
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
//#endregion
|
|
30
|
-
//#region src/core/debounce.ts
|
|
31
|
-
function n(t, n) {
|
|
32
|
-
let r = t.get(), i, { subscribe: a, notify: o } = e({ onFirstSubscribe() {
|
|
33
|
-
let e = t.subscribe(() => {
|
|
34
|
-
clearTimeout(i), i = setTimeout(() => {
|
|
35
|
-
r = t.get(), o();
|
|
36
|
-
}, n);
|
|
37
|
-
});
|
|
38
|
-
return () => {
|
|
39
|
-
clearTimeout(i), e();
|
|
40
|
-
};
|
|
41
|
-
} }), s = () => r;
|
|
42
|
-
return {
|
|
43
|
-
get: s,
|
|
44
|
-
subscribe(e, t) {
|
|
45
|
-
return a(() => e(s()), t);
|
|
46
|
-
},
|
|
47
|
-
"~": {
|
|
48
|
-
output: null,
|
|
49
|
-
notify: o
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
//#endregion
|
|
54
|
-
//#region src/core/debounce-fn.ts
|
|
55
|
-
function r(t, n) {
|
|
56
|
-
let r, i, { subscribe: a, notify: o } = e(), s = () => r;
|
|
57
|
-
return Object.assign((...e) => {
|
|
58
|
-
clearTimeout(i), i = setTimeout(() => {
|
|
59
|
-
r = t(...e), o();
|
|
60
|
-
}, n);
|
|
61
|
-
}, {
|
|
62
|
-
get: s,
|
|
63
|
-
subscribe: (e, t) => a(() => e(s()), t),
|
|
64
|
-
"~": {
|
|
65
|
-
output: void 0,
|
|
66
|
-
notify: o
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
//#endregion
|
|
71
|
-
//#region src/utils.ts
|
|
72
|
-
function i(e) {
|
|
73
|
-
if (typeof e != "string") return e;
|
|
74
|
-
try {
|
|
75
|
-
return JSON.parse(e);
|
|
76
|
-
} catch {
|
|
77
|
-
return e;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
//#endregion
|
|
81
|
-
//#region src/core/schema-store.ts
|
|
82
|
-
function a(t) {
|
|
83
|
-
let { subscribe: n, notify: r } = e(), a = { ...t.defaultValues }, s = t.provider ?? o(), c = () => {
|
|
84
|
-
let e = { ...a };
|
|
85
|
-
for (let [n, r] of Object.entries(t.schemas)) {
|
|
86
|
-
let t = s.get()[n], o = r["~standard"].validate(i(t));
|
|
87
|
-
if (o instanceof Promise) throw TypeError("[createStorage] Validation schema should not return a Promise.");
|
|
88
|
-
o.issues && console.warn(`[createSchemaStore] Returned value invalid for key ${String(n)}, returned default value instead`, JSON.stringify(o.issues, null, 2), { cause: o.issues }), e[n] = o.issues ? a[n] : o.value;
|
|
89
|
-
}
|
|
90
|
-
return e;
|
|
91
|
-
};
|
|
92
|
-
return {
|
|
93
|
-
get: c,
|
|
94
|
-
set: (e) => {
|
|
95
|
-
let t = typeof e == "function" ? e(c()) : e;
|
|
96
|
-
s.set(t), r();
|
|
97
|
-
},
|
|
98
|
-
getDefaultValue: (e) => a[e],
|
|
99
|
-
subscribe: (e, t) => n(() => e(c()), t),
|
|
100
|
-
"~": {
|
|
101
|
-
output: null,
|
|
102
|
-
notify: r
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
function o() {
|
|
107
|
-
let e = s({});
|
|
108
|
-
return {
|
|
109
|
-
get: () => e.get(),
|
|
110
|
-
set: (t) => {
|
|
111
|
-
e.set(t);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
//#endregion
|
|
116
|
-
//#region src/core/store.ts
|
|
117
|
-
function s(t) {
|
|
118
|
-
let n = t, { subscribe: r, notify: i } = e(), a = () => n;
|
|
119
|
-
return {
|
|
120
|
-
get: a,
|
|
121
|
-
set: (e) => {
|
|
122
|
-
let t = typeof e == "function" ? e(n) : e;
|
|
123
|
-
t !== n && (n = t, i());
|
|
124
|
-
},
|
|
125
|
-
subscribe(e, t) {
|
|
126
|
-
return r(() => e(a()), t);
|
|
127
|
-
},
|
|
128
|
-
"~": {
|
|
129
|
-
output: null,
|
|
130
|
-
notify: i
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
//#endregion
|
|
135
|
-
//#region src/core/throttle.ts
|
|
136
|
-
function c(t, n) {
|
|
137
|
-
let r = t.get(), i, a = !1, { subscribe: o, notify: s } = e({ onFirstSubscribe() {
|
|
138
|
-
let e = t.subscribe(() => {
|
|
139
|
-
if (i) {
|
|
140
|
-
a = !0;
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
r = t.get(), s(), i = setTimeout(() => {
|
|
144
|
-
i = void 0, a && (a = !1, r = t.get(), s());
|
|
145
|
-
}, n);
|
|
146
|
-
});
|
|
147
|
-
return () => {
|
|
148
|
-
clearTimeout(i), i = void 0, a = !1, e();
|
|
149
|
-
};
|
|
150
|
-
} }), c = () => r;
|
|
151
|
-
return {
|
|
152
|
-
get: c,
|
|
153
|
-
subscribe(e, t) {
|
|
154
|
-
return o(() => e(c()), t);
|
|
155
|
-
},
|
|
156
|
-
"~": {
|
|
157
|
-
output: null,
|
|
158
|
-
notify: s
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
//#endregion
|
|
163
|
-
//#region src/core/throttle-fn.ts
|
|
164
|
-
function l(t, n) {
|
|
165
|
-
let r, i, a, { subscribe: o, notify: s } = e(), c = () => r;
|
|
166
|
-
return Object.assign((...e) => {
|
|
167
|
-
if (i) {
|
|
168
|
-
a = e;
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
r = t(...e), s(), i = setTimeout(() => {
|
|
172
|
-
if (i = void 0, a) {
|
|
173
|
-
let e = a;
|
|
174
|
-
a = void 0, r = t(...e), s();
|
|
175
|
-
}
|
|
176
|
-
}, n);
|
|
177
|
-
}, {
|
|
178
|
-
get: c,
|
|
179
|
-
subscribe: (e, t) => o(() => e(c()), t),
|
|
180
|
-
"~": {
|
|
181
|
-
output: void 0,
|
|
182
|
-
notify: s
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
//#endregion
|
|
187
|
-
export { o as a, n as c, a as i, t as l, c as n, i as o, s as r, r as s, l as t, e as u };
|
|
@@ -1,68 +0,0 @@
|
|
|
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 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>>;
|
|
@@ -1,50 +0,0 @@
|
|
|
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>>;
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
-
import type { SessionStorage } from './session-storage';
|
|
3
|
-
import type { WebStorageValue as SessionStorageValue, WebStorageValueOptionsWithSchema as SessionStorageValueOptionsWithSchema, WebStorageValueOptionsWithStorage as SessionStorageValueOptionsWithStorage } from './web-storage-value';
|
|
4
|
-
export type { SessionStorageValue, SessionStorageValueOptionsWithSchema, SessionStorageValueOptionsWithStorage, };
|
|
5
|
-
/**
|
|
6
|
-
* Creates a reactive handle for a single sessionStorage 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 `createSessionStorage` instance.
|
|
12
|
-
* Type and default come from that storage.
|
|
13
|
-
*
|
|
14
|
-
* @example Vanilla
|
|
15
|
-
* ```ts twoslash title="session-storage-value.ts"
|
|
16
|
-
* import { createSessionStorageValue } from 'seitu/web'
|
|
17
|
-
* import * as z from 'zod'
|
|
18
|
-
*
|
|
19
|
-
* const value = createSessionStorageValue({
|
|
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="session-storage-value.ts"
|
|
32
|
-
* import { createSessionStorage, createSessionStorageValue } from 'seitu/web'
|
|
33
|
-
* import * as z from 'zod'
|
|
34
|
-
*
|
|
35
|
-
* const storage = createSessionStorage({
|
|
36
|
-
* schemas: { count: z.number(), name: z.string() },
|
|
37
|
-
* defaultValues: { count: 0, name: '' },
|
|
38
|
-
* })
|
|
39
|
-
* const count = createSessionStorageValue({ 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 { createSessionStorageValue } from 'seitu/web'
|
|
49
|
-
* import { useSubscription } from 'seitu/react'
|
|
50
|
-
* import * as z from 'zod'
|
|
51
|
-
*
|
|
52
|
-
* export default function Page() {
|
|
53
|
-
* const 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
|
-
* ```
|
|
66
|
-
*/
|
|
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,50 +0,0 @@
|
|
|
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 };
|
|
4
|
-
/**
|
|
5
|
-
* Creates a reactive handle for a sessionStorage instance.
|
|
6
|
-
*
|
|
7
|
-
* @example Vanilla
|
|
8
|
-
* ```ts twoslash title="session-storage.ts"
|
|
9
|
-
* import { createSessionStorage } from 'seitu/web'
|
|
10
|
-
* import * as z from 'zod'
|
|
11
|
-
*
|
|
12
|
-
* const sessionStorage = createSessionStorage({
|
|
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
|
-
* 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
|
-
* }
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
export declare function createSessionStorage<S extends SchemaStoreSchema>(options: SessionStorageOptions<S>): SessionStorage<SchemaStoreOutput<S>>;
|