seitu 0.0.1 → 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 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 { sessionStorageValue } from 'seitu/web'
18
+ import { createSessionStorageValue } from 'seitu/web'
19
19
  import * as z from 'zod'
20
20
 
21
- const value = sessionStorageValue({
21
+ const value = createSessionStorageValue({
22
22
  key: 'test',
23
23
  defaultValue: 0,
24
24
  schema: z.number(),
@@ -1 +1,2 @@
1
+ export * from './schema-store';
1
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>>;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,19 +1,23 @@
1
1
  export interface Subscribable<V> {
2
2
  'subscribe': (callback: (value: V) => any) => () => void;
3
- '~types': {
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
+ */
11
+ notify: () => void;
5
12
  };
6
13
  }
7
14
  export interface Readable<T> {
8
15
  get: () => T;
9
16
  }
10
- export interface Writable<T, P extends Partial<T> = T> {
11
- set: (value: T | ((prev: P) => T)) => any;
17
+ export interface Writable<T> {
18
+ set: (value: T | ((prev: T) => T)) => any;
12
19
  }
13
- export interface Removable {
14
- remove: () => void;
15
- }
16
- export declare function createSubscription<V>(): {
17
- subscribe: (callback: (value: V) => any) => () => void;
18
- notify: (value: V) => void;
20
+ export declare function createSubscription<T = void>(): {
21
+ subscribe: (callback: (payload: T) => any) => () => void;
22
+ notify: (payload: T) => void;
19
23
  };
@@ -0,0 +1,48 @@
1
+ function e(e) {
2
+ if (typeof e != "string") return e;
3
+ try {
4
+ return JSON.parse(e);
5
+ } catch {
6
+ return e;
7
+ }
8
+ }
9
+ function t(t) {
10
+ let { subscribe: r, notify: i } = n(), a = { ...t.defaultValues }, o = () => {
11
+ let n = { ...a };
12
+ for (let [r, i] of Object.entries(t.schemas)) {
13
+ let o = t.provider.get()[r], s = i["~standard"].validate(e(o));
14
+ if (s instanceof Promise) throw TypeError("[createStorage] Validation schema should not return a Promise.");
15
+ s.issues && console.warn(JSON.stringify(s.issues, null, 2), { cause: s.issues }), n[r] = s.issues ? a[r] : s.value;
16
+ }
17
+ return n;
18
+ };
19
+ return {
20
+ get: o,
21
+ set: (e) => {
22
+ let n = typeof e == "function" ? e(o()) : e;
23
+ t.provider.set(n), i();
24
+ },
25
+ getDefaultValue: (e) => a[e],
26
+ subscribe: (e) => r(() => {
27
+ e(o());
28
+ }),
29
+ "~": {
30
+ output: null,
31
+ notify: i
32
+ }
33
+ };
34
+ }
35
+ function n() {
36
+ let e = new Set();
37
+ return {
38
+ subscribe(t) {
39
+ return e.add(t), () => {
40
+ e.delete(t);
41
+ };
42
+ },
43
+ notify(t) {
44
+ e.forEach((e) => e(t));
45
+ }
46
+ };
47
+ }
48
+ export { t as n, e as r, n as t };
package/dist/core.js CHANGED
@@ -1,14 +1,2 @@
1
- function e() {
2
- let e = new Set();
3
- return {
4
- subscribe(t) {
5
- return e.add(t), () => {
6
- e.delete(t);
7
- };
8
- },
9
- notify(t) {
10
- e.forEach((e) => e(t));
11
- }
12
- };
13
- }
14
- export { e as createSubscription };
1
+ import { n as e, t } from "./core-CuCUF5Aj.js";
2
+ export { e as createSchemaStore, t as createSubscription };
@@ -1,19 +1,25 @@
1
- import type { Readable, Subscribable } from '../core/subscription';
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 access a subscription for any function that implements the Subscription interface.
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.
4
12
  *
5
- * @kind hook
6
- *
7
- * @example
13
+ * @example Inline subscription
8
14
  * ```tsx twoslash title="/app/page.tsx"
9
15
  * 'use client'
10
16
  *
11
- * import { sessionStorageValue } from 'seitu/web'
17
+ * import { createSessionStorageValue } from 'seitu/web'
12
18
  * import { useSubscription } from 'seitu/react'
13
19
  * import * as z from 'zod'
14
20
  *
15
21
  * export default function Page() {
16
- * const value = useSubscription(sessionStorageValue({
22
+ * const value = useSubscription(() => createSessionStorageValue({
17
23
  * key: 'test',
18
24
  * defaultValue: 0,
19
25
  * schema: z.number(),
@@ -23,32 +29,30 @@ import type { Readable, Subscribable } from '../core/subscription';
23
29
  * }
24
30
  * ```
25
31
  *
26
- * @example
32
+ * @example Instance outside of component
27
33
  * ```tsx twoslash title="/app/page.tsx"
28
34
  * 'use client'
29
35
  *
30
- * import { sessionStorageValue } from 'seitu/web'
36
+ * import { createSessionStorage } from 'seitu/web'
31
37
  * import { useSubscription } from 'seitu/react'
32
38
  * import * as z from 'zod'
33
39
  *
34
- * const sessionStorage = sessionStorageValue({
35
- * key: 'test',
36
- * defaultValue: 0,
37
- * schema: z.number(),
40
+ * const sessionStorage = createSessionStorage({
41
+ * schemas: { count: z.number(), name: z.string() },
42
+ * defaultValues: { count: 0, name: '' },
38
43
  * })
39
44
  *
40
45
  * export default function Page() {
41
46
  * const value = useSubscription(sessionStorage)
42
- *
43
- * return <div>{value}</div>
47
+ * return <div>{value.count}</div>
44
48
  * }
45
49
  * ```
46
50
  *
47
- * @example
51
+ * @example Subscription with selector
48
52
  * ```tsx twoslash title="/app/page.tsx"
49
53
  * 'use client'
50
54
  *
51
- * import { createSessionStorage, sessionStorageValue } from 'seitu/web'
55
+ * import { createSessionStorage } from 'seitu/web'
52
56
  * import { useSubscription } from 'seitu/react'
53
57
  * import * as z from 'zod'
54
58
  *
@@ -60,12 +64,32 @@ import type { Readable, Subscribable } from '../core/subscription';
60
64
  * defaultValues: { count: 0, name: '' },
61
65
  * })
62
66
  *
63
- * // Usage with selector, re-renders only when count changes
64
67
  * export default function Page() {
65
- * const count = useSubscription(sessionStorage, value => value.count)
68
+ * // Usage with selector, re-renders only when count changes
69
+ * const count = useSubscription(sessionStorage, { selector: value => value.count })
66
70
  *
67
71
  * return <div>{count}</div>
68
72
  * }
69
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
+ * ```
70
94
  */
71
- export declare function useSubscription<S extends Subscribable<any> & Readable<any>, R = S['~types']['output']>(subscription: S, selector?: (value: S['~types']['output']) => R): R;
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;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom/vitest';
package/dist/react.js CHANGED
@@ -1778,11 +1778,17 @@ var t = Object.create, n = Object.defineProperty, r = Object.getOwnPropertyDescr
1778
1778
  };
1779
1779
  }))(), 1);
1780
1780
  function Ze(t, n) {
1781
- if (!t.get || !t.subscribe) throw Error("Subscription is not valid. It must have a get and subscribe method.");
1782
- let [r, i] = e.useState(() => n ? n(t.get()) : t.get()), a = e.useEffectEvent(() => r);
1783
- return e.useEffect(() => t.subscribe((e) => {
1784
- let t = n ? n(e) : e;
1785
- (0, Xe.default)(t, a()) || i(t);
1786
- }), [t, n]), r;
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;
1787
1793
  }
1788
1794
  export { Ze as useSubscription };
package/dist/utils.d.ts CHANGED
@@ -4,4 +4,4 @@ export type Simplify<T> = {
4
4
  } & {};
5
5
  export type Satisfies<T extends U, U> = T;
6
6
  export type PartialForKeys<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>;
7
- export declare function tryParseJson(value: string): unknown;
7
+ export declare function tryParseJson(value: unknown): unknown;
@@ -1,2 +1,6 @@
1
+ export * from './local-storage';
2
+ export * from './local-storage-value';
3
+ export * from './media-query';
4
+ export * from './scroll-state';
1
5
  export * from './session-storage';
2
6
  export * from './session-storage-value';
@@ -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>>;
@@ -0,0 +1,77 @@
1
+ import type { Readable, Subscribable } from '../core/index';
2
+ export interface MediaQuery extends Subscribable<boolean>, Readable<boolean> {
3
+ }
4
+ type MinMaxPrefix = 'min-' | 'max-' | '';
5
+ type CSSUnitSuffix = 'px' | 'em' | 'rem' | 'vw' | 'vh' | 'dvw' | 'dvh' | 'svw' | 'svh' | 'lvw' | 'lvh' | 'cqw' | 'cqh' | 'vmin' | 'vmax' | 'cm' | 'mm' | 'in' | 'pt' | 'pc';
6
+ type CSSUnit = `${number}${CSSUnitSuffix}`;
7
+ type CSSResolution = `${number}${'dpi' | 'dpcm' | 'dppx' | 'x'}`;
8
+ type Ratio = `${number}/${number}`;
9
+ type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
10
+ type ParseNum<S extends string, Acc extends string = ''> = S extends `${infer D extends Digit | '.'}${infer Rest}` ? ParseNum<Rest, `${Acc}${D}`> : Acc extends `${infer N extends number}` ? N : false;
11
+ type MQEnum<F extends string, V extends string> = `(${F}: ${V})`;
12
+ type MQRange<F extends string, V extends string = CSSUnit> = `(${MinMaxPrefix}${F}: ${V})`;
13
+ type MQOptNum<F extends string> = `(${MinMaxPrefix}${F}${'' | `: ${number}`})`;
14
+ export type MediaQueryType = `${'only ' | 'not ' | ''}${'screen' | 'print' | 'all'}` | MQEnum<'any-hover' | 'hover', 'hover' | 'none'> | MQEnum<'any-pointer' | 'pointer', 'none' | 'coarse' | 'fine'> | MQRange<'width' | 'height' | 'device-width' | 'device-height' | 'inline-size' | 'block-size'> | MQRange<'aspect-ratio' | 'device-aspect-ratio', Ratio> | MQOptNum<'color' | 'color-index' | 'monochrome'> | MQEnum<'color-gamut', 'srgb' | 'p3' | 'rec2020'> | MQEnum<'dynamic-range' | 'video-dynamic-range', 'standard' | 'high'> | MQEnum<'device-posture', 'continuous' | 'folded'> | MQEnum<'display-mode', 'browser' | 'fullscreen' | 'minimal-ui' | 'picture-in-picture' | 'standalone' | 'window-controls-overlay'> | MQEnum<'orientation', 'portrait' | 'landscape'> | MQEnum<'scan', 'interlace' | 'progressive'> | MQEnum<'grid', '0' | '1'> | MQEnum<'update', 'none' | 'slow' | 'fast'> | MQEnum<'overflow-block', 'none' | 'scroll' | 'optional-paged' | 'paged'> | MQEnum<'overflow-inline', 'none' | 'scroll'> | MQEnum<'environment-blending', 'opaque' | 'additive' | 'subtractive'> | MQRange<'resolution', 'infinite' | CSSResolution> | MQEnum<'prefers-color-scheme', 'light' | 'dark'> | MQEnum<'prefers-contrast', 'no-preference' | 'more' | 'less' | 'forced'> | MQEnum<'prefers-reduced-motion' | 'prefers-reduced-transparency' | 'prefers-reduced-data', 'no-preference' | 'reduce'> | MQEnum<'forced-colors', 'none' | 'active'> | MQEnum<'inverted-colors', 'none' | 'inverted'> | MQEnum<'prefers-online', 'online' | 'offline'> | MQEnum<'scripting', 'none' | 'initial-only' | 'enabled'>;
15
+ type Suggestion = MediaQueryType | `${MediaQueryType} and ` | `${MediaQueryType}, `;
16
+ type IsValid<T extends string> = string extends T ? true : T extends `${infer L}, ${infer R}` ? (IsValid<L> extends true ? IsValid<R> : false) : T extends `${infer L} and ${infer R}` ? (IsValid<L> extends true ? IsValid<R> : false) : T extends `not ${infer Rest}` ? IsValid<Rest> : T extends MediaQueryType ? true : false;
17
+ type ValuesOf<F extends string, MQ = MediaQueryType> = MQ extends `(${F}: ${infer V})` ? V : never;
18
+ type SuggestFeature<F extends string, V extends string> = ParseNum<V> extends infer N extends number ? `(${F}: ${N}${CSSUnitSuffix})` : [ValuesOf<F>] extends [never] ? MediaQueryType : `(${F}: ${ValuesOf<F>})`;
19
+ type Suggest<T extends string> = string extends T ? Suggestion : T extends `${infer L}, ${infer R}` ? (IsValid<L> extends true ? `${L}, ${Suggest<R>}` : Suggestion) : T extends `${infer L} and ${infer R}` ? (IsValid<L> extends true ? `${L} and ${Suggest<R>}` : Suggestion) : T extends `not ${infer Rest}` ? `not ${Suggest<Rest>}` : T extends `(${infer F}: ${infer Rest}` ? SuggestFeature<F, Rest extends `${infer V})` ? V : Rest> : MediaQueryType;
20
+ export interface MediaQueryOptions<T extends string> {
21
+ /**
22
+ * A media query string (e.g. `(min-width: 768px)` or `(prefers-color-scheme: dark)`).
23
+ */
24
+ query: IsValid<T> extends true ? T : Suggest<T>;
25
+ /**
26
+ * Value returned from `get()` during SSR.
27
+ * @default false
28
+ */
29
+ defaultMatches?: boolean;
30
+ }
31
+ /**
32
+ * Creates a handle for a media query.
33
+ *
34
+ * @example Vanilla
35
+ * ```ts twoslash title="media-query.ts"
36
+ * import { mediaQuery } from 'seitu/web'
37
+ * import { useSubscription } from 'seitu/react'
38
+ *
39
+ * const isDesktop = mediaQuery({ query: '(min-width: 768px)' })
40
+ *
41
+ * // Usage with subscribe
42
+ * isDesktop.subscribe(matches => {
43
+ * console.log(matches)
44
+ * })
45
+ *
46
+ * const state = isDesktop.get()
47
+ * console.log(state)
48
+ * ```
49
+ *
50
+ * @example React
51
+ * ```tsx twoslash title="page.tsx"
52
+ * import { mediaQuery } from 'seitu/web'
53
+ * import { useSubscription } from 'seitu/react'
54
+ *
55
+ * const isDesktop = mediaQuery({ query: '(min-width: 768px)' })
56
+ *
57
+ * // Usage with some function component
58
+ * function Layout() {
59
+ * const { value: matches } = useSubscription(isDesktop)
60
+ * return matches ? 'i am desktop' : 'i am mobile'
61
+ * }
62
+ * ```
63
+ *
64
+ * @example Errors
65
+ * ```tsx twoslash
66
+ * import { mediaQuery } from 'seitu/web'
67
+ * import { useSubscription } from 'seitu/react'
68
+ *
69
+ * // @errors: 2362 2322 1109
70
+ * mediaQuery({ query: '(min-width: ' })
71
+ *
72
+ * // @errors: 2362 2322 2820
73
+ * mediaQuery({ query: '(min-width: 768' })
74
+ * ```
75
+ */
76
+ export declare function mediaQuery<T extends string>(options: MediaQueryOptions<T>): MediaQuery;
77
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,87 @@
1
+ import type { Readable, Subscribable } from '../core/index';
2
+ export type ScrollDirection = 'vertical' | 'horizontal' | 'both';
3
+ export interface ScrollStateEdge {
4
+ value: boolean;
5
+ remaining: number;
6
+ }
7
+ export interface ScrollStateValue {
8
+ top: ScrollStateEdge;
9
+ bottom: ScrollStateEdge;
10
+ left: ScrollStateEdge;
11
+ right: ScrollStateEdge;
12
+ }
13
+ export interface ScrollState extends Subscribable<ScrollStateValue>, Readable<ScrollStateValue> {
14
+ }
15
+ export interface ScrollStateOptions {
16
+ /**
17
+ * The element to observe scroll position on.
18
+ */
19
+ element: Element | null;
20
+ /**
21
+ * Which scroll axis to track.
22
+ * @default 'both'
23
+ */
24
+ direction?: ScrollDirection;
25
+ /**
26
+ * Number of pixels from each edge before it counts as "scrolled".
27
+ * @default 0
28
+ */
29
+ threshold?: number;
30
+ }
31
+ /**
32
+ * Creates a reactive handle that tracks scroll position of an element relative to each edge.
33
+ *
34
+ * @example Vanilla
35
+ * ```ts twoslash
36
+ * import { scrollState } from 'seitu/web'
37
+ *
38
+ * const scroll = scrollState({
39
+ * element: document.querySelector('.container'),
40
+ * direction: 'vertical',
41
+ * threshold: 10,
42
+ * })
43
+ *
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)
49
+ * })
50
+ *
51
+ * const state = scroll.get()
52
+ * console.log(state)
53
+ * ```
54
+ *
55
+ * @example React
56
+ * ```tsx twoslash title="page.tsx"
57
+ * import { scrollState } from 'seitu/web'
58
+ * import { useSubscription } from 'seitu/react'
59
+ *
60
+ * const scroll = scrollState({
61
+ * element: document.querySelector('.container'),
62
+ * threshold: 10,
63
+ * })
64
+ *
65
+ * function Layout() {
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
+ * )
84
+ * }
85
+ * ```
86
+ */
87
+ export declare function scrollState(options: ScrollStateOptions): ScrollState;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,18 +1,7 @@
1
1
  import type { StandardSchemaV1 } from '@standard-schema/spec';
2
- import type { Readable, Removable, Subscribable, Writable } from '../core/index';
3
2
  import type { SessionStorage } from './session-storage';
4
- export interface SessionStorageValue<V> extends Subscribable<V>, Readable<V>, Writable<V>, Removable {
5
- }
6
- export interface SessionStorageValueOptionsWithStorage<Storage extends SessionStorage<any>, K extends keyof Storage['~types']['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 { sessionStorageValue } from 'seitu/web'
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 = sessionStorageValue({
19
+ * const value = createSessionStorageValue({
31
20
  * key: 'count',
32
21
  * defaultValue: 0,
33
22
  * schema: z.number(),
@@ -35,23 +24,45 @@ export type SessionStorageValueOptions = SessionStorageValueOptionsWithStorage<S
35
24
  * value.get() // 0
36
25
  * value.set(1)
37
26
  * value.set(v => v + 1)
38
- * value.remove()
39
27
  * value.subscribe(v => console.log(v))
40
28
  * ```
41
29
  *
42
- * @example
43
- * ```ts twoslash
44
- * import { createSessionStorage, sessionStorageValue } from 'seitu/web'
30
+ * @example Storage mode
31
+ * ```ts twoslash title="session-storage-value.ts"
32
+ * import { createSessionStorage, createSessionStorageValue } from 'seitu/web'
45
33
  * import * as z from 'zod'
46
34
  *
47
35
  * const storage = createSessionStorage({
48
36
  * schemas: { count: z.number(), name: z.string() },
49
37
  * defaultValues: { count: 0, name: '' },
50
38
  * })
51
- * const count = sessionStorageValue({ storage, key: 'count' })
39
+ * const count = createSessionStorageValue({ storage, key: 'count' })
52
40
  * count.set(5)
53
41
  * storage.get().count === 5 // true
54
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
+ * ```
55
66
  */
56
- export declare function sessionStorageValue<Storage extends SessionStorage<any>, K extends keyof Storage['~types']['output']>(options: SessionStorageValueOptionsWithStorage<Storage, K>): SessionStorageValue<Storage['~types']['output'][K]>;
57
- export declare function sessionStorageValue<S extends StandardSchemaV1<unknown>>(options: SessionStorageValueOptionsWithSchema<S>): SessionStorageValue<StandardSchemaV1.InferOutput<S>>;
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 +1,11 @@
1
- import type { StandardSchemaV1 } from '@standard-schema/spec';
2
- import type { Readable, Subscribable, Writable } from '../core/index';
3
- import type { Simplify } from '../utils';
4
- type Output<S extends Record<string, StandardSchemaV1>> = Simplify<{
5
- [K in keyof S]: StandardSchemaV1.InferOutput<S[K]>;
6
- }>;
7
- export interface SessionStorage<O extends Record<string, unknown>> extends Subscribable<O>, Readable<O>, Writable<Partial<O>, O> {
8
- clear: () => void;
9
- defaultValues: Readonly<O>;
10
- }
11
- export interface SessionStorageOptions<S extends Record<string, StandardSchemaV1>> {
12
- /**
13
- * Schemas for each session 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 sessionStorage = createSessionStorage({
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
- * })
25
- * ```
26
- */
27
- schemas: S;
28
- /**
29
- * The default values to use for the session storage.
30
- *
31
- * @example
32
- * ```ts
33
- * const sessionStorage = createSessionStorage({
34
- * defaultValues: {
35
- * token: null,
36
- * preferences: { theme: 'light' },
37
- * },
38
- * })
39
- * ```
40
- */
41
- defaultValues: Output<S>;
42
- }
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 };
43
4
  /**
44
5
  * Creates a reactive handle for a sessionStorage instance.
45
6
  *
46
- * @example
47
- * ```ts twoslash
7
+ * @example Vanilla
8
+ * ```ts twoslash title="session-storage.ts"
48
9
  * import { createSessionStorage } from 'seitu/web'
49
10
  * import * as z from 'zod'
50
11
  *
@@ -56,20 +17,34 @@ export interface SessionStorageOptions<S extends Record<string, StandardSchemaV1
56
17
  * defaultValues: { token: null, preferences: { theme: 'light' } },
57
18
  * })
58
19
  *
59
- * sessionStorage.get().token // null
60
- * sessionStorage.get().preferences // { theme: 'light' }
61
- * sessionStorage.set({ token: '123', preferences: { theme: 'dark' } })
62
- * sessionStorage.get().token // '123'
63
- * sessionStorage.get().preferences // { theme: 'dark' }
64
- * sessionStorage.clear()
65
- * sessionStorage.get().token // null
66
- * sessionStorage.get().preferences // { theme: 'light' }
67
- * sessionStorage.subscribe(value => console.log(value))
68
- * sessionStorage.set({ token: '456', preferences: { theme: 'light' } })
69
- * // { token: '456', preferences: { theme: 'light' } }
70
- * sessionStorage.clear()
71
- * // { token: null, preferences: { theme: 'light' } }
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
+ * }
72
48
  * ```
73
49
  */
74
- export declare function createSessionStorage<S extends Record<string, StandardSchemaV1>>(options: SessionStorageOptions<S>): SessionStorage<Output<S>>;
75
- export {};
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 @@
1
+ export {};
@@ -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>>;
@@ -0,0 +1 @@
1
+ export {};
package/dist/web.js CHANGED
@@ -1,87 +1,164 @@
1
- import { createSubscription as e } from "./core.js";
2
- function t(e) {
3
- try {
4
- return JSON.parse(e);
5
- } catch {
6
- return e;
7
- }
1
+ import { n as e, r as t, t as n } from "./core-CuCUF5Aj.js";
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
+ };
8
34
  }
9
- function n(n) {
10
- let { subscribe: r, notify: i } = e(), a = { ...n.defaultValues }, o = () => {
11
- let e = { ...a };
12
- for (let [r, i] of Object.entries(n.schemas)) {
13
- if (typeof window > "u") return a;
14
- let n = window.sessionStorage.getItem(r);
15
- if (n === null) continue;
16
- let o = i["~standard"].validate(t(n));
17
- if (o instanceof Promise) throw TypeError("[createSessionStorage] Validation schema should not return a Promise.");
18
- e[r] = o.issues ? a[r] : o.value;
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;
19
59
  }
20
- return e;
21
60
  };
22
61
  return {
23
- get: o,
24
- set: (e) => {
25
- let t = typeof e == "function" ? e(o()) : e;
26
- for (let [e, n] of Object.entries(t)) window.sessionStorage.setItem(e, typeof n == "string" ? n : JSON.stringify(n));
27
- i({
28
- ...o(),
29
- ...t
30
- });
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();
31
67
  },
32
- subscribe: (e) => {
33
- let t = r(() => {
34
- e(o());
35
- });
36
- return () => {
37
- t();
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);
38
74
  };
39
75
  },
40
- clear: () => {
41
- window.sessionStorage.clear(), i({ ...n.defaultValues });
42
- },
43
- defaultValues: a,
44
- "~types": { output: null }
76
+ "~": {
77
+ output: null,
78
+ notify: s
79
+ }
45
80
  };
46
81
  }
47
- function r(n) {
48
- if ("schema" in n && n.defaultValue === void 0) throw Error("[sessionStorageValue] Default value is required");
49
- if (n.key === void 0) throw Error("[sessionStorageValue] Key is required");
50
- if (!("schema" in n || "storage" in n)) throw Error("[sessionStorageValue] Either schema or storage must be provided");
51
- let r = ("schema" in n ? n.defaultValue : n.storage.defaultValues[n.key]) ?? null, { subscribe: i, notify: a } = e(), o = () => {
52
- if (typeof window > "u") return r;
53
- let e = window.sessionStorage.getItem(n.key);
54
- if (e === null) return r;
55
- let i = t(e);
82
+ function o(e) {
83
+ return "storage" in e ? a(e) : a({
84
+ ...e,
85
+ kind: "localStorage"
86
+ });
87
+ }
88
+ function s(e) {
89
+ let { subscribe: t, notify: r } = n(), i = () => {
90
+ if (typeof window > "u") return e.defaultMatches ?? !1;
56
91
  try {
57
- if ("schema" in n) {
58
- let e = n.schema["~standard"].validate(i);
59
- if (e instanceof Promise) throw TypeError("Validation schema should not return a Promise.");
60
- return e.issues ? (console.error(JSON.stringify(e.issues, null, 2), { cause: e.issues }), r) : e.value;
61
- } else return n.storage.get()[n.key];
92
+ return window.matchMedia(e.query).matches;
62
93
  } catch {
63
- return r !== void 0 && typeof r != "string" ? r : i;
94
+ return e.defaultMatches ?? !1;
64
95
  }
65
96
  };
66
97
  return {
67
- get: o,
68
- set: (e) => {
69
- if (typeof window > "u") return;
70
- let t = typeof e == "function" ? e(o()) : e;
71
- window.sessionStorage.setItem(n.key, typeof t == "string" ? t : JSON.stringify(t)), window.dispatchEvent(new Event("storage")), a(t);
72
- },
73
- remove: () => {
74
- typeof window > "u" || (window.sessionStorage.removeItem(n.key), window.dispatchEvent(new Event("storage")), a(o()));
75
- },
76
- subscribe: (e) => {
77
- let t = i(e), r = (t) => {
78
- t.key === n.key && e(o());
98
+ get: i,
99
+ subscribe: (n) => {
100
+ if (typeof window > "u") return n(i()), () => {};
101
+ let r = t(() => n(i())), a = window.matchMedia(e.query), o = () => n(i());
102
+ return a.addEventListener("change", o), () => {
103
+ r(), a.removeEventListener("change", o);
79
104
  };
80
- return typeof window < "u" && window.addEventListener("storage", r), () => {
81
- t(), typeof window < "u" && window.removeEventListener("storage", r);
105
+ },
106
+ "~": {
107
+ output: null,
108
+ notify: r
109
+ }
110
+ };
111
+ }
112
+ var c = {
113
+ value: !1,
114
+ remaining: 0
115
+ };
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) => ({
119
+ value: e,
120
+ remaining: Math.max(0, t)
121
+ });
122
+ if (!n) return {
123
+ top: c,
124
+ bottom: c,
125
+ left: c,
126
+ right: c
127
+ };
128
+ let a = n.scrollTop, o = n.scrollHeight - n.scrollTop - n.clientHeight, s = n.scrollLeft, l = n.scrollWidth - n.scrollLeft - n.clientWidth;
129
+ return {
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)
134
+ };
135
+ };
136
+ return {
137
+ get: o,
138
+ subscribe: (t) => {
139
+ let n = e.element;
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);
82
144
  };
83
145
  },
84
- "~types": { output: null }
146
+ "~": {
147
+ output: null,
148
+ notify: a
149
+ }
85
150
  };
86
151
  }
87
- export { n as createSessionStorage, r as sessionStorageValue };
152
+ function u(e) {
153
+ return r({
154
+ kind: "sessionStorage",
155
+ ...e
156
+ });
157
+ }
158
+ function d(e) {
159
+ return "storage" in e ? a(e) : a({
160
+ ...e,
161
+ kind: "sessionStorage"
162
+ });
163
+ }
164
+ export { i as createLocalStorage, o as createLocalStorageValue, u as createSessionStorage, d as createSessionStorageValue, s as mediaQuery, l as scrollState };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "seitu",
3
3
  "displayName": "Seitu",
4
4
  "type": "module",
5
- "version": "0.0.1",
5
+ "version": "0.2.0",
6
6
  "private": false,
7
7
  "author": "Valerii Strilets",
8
8
  "license": "MIT",