seitu 0.4.6 → 0.5.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.
@@ -8,8 +8,13 @@ export interface Store<T> extends Readable<T>, Writable<T, T>, Subscribable<T> {
8
8
  * - **With schema-store**: use as the state backing for a memory provider.
9
9
  *
10
10
  * @example
11
+ * ```ts twoslash
12
+ * import { createStore } from 'seitu'
13
+ *
11
14
  * const store = createStore({ count: 0 })
12
15
  * store.set(prev => ({ ...prev, count: prev.count + 1 }))
13
16
  * store.subscribe(state => console.log(state))
17
+ * store.get() // { count: 0 }
18
+ * ```
14
19
  */
15
20
  export declare function createStore<T>(initial: T): Store<T>;
@@ -17,6 +17,9 @@ export interface Readable<T> {
17
17
  export interface Writable<T, P = T> {
18
18
  set: (value: T | ((prev: P) => T)) => any;
19
19
  }
20
+ export interface Removable {
21
+ remove: () => void;
22
+ }
20
23
  export interface Destroyable {
21
24
  destroy: () => void;
22
25
  }
@@ -1,3 +1,4 @@
1
+ export * from './is-online';
1
2
  export * from './local-storage';
2
3
  export * from './local-storage-value';
3
4
  export * from './media-query';
@@ -0,0 +1,33 @@
1
+ import type { Destroyable, Readable, Subscribable } from '../core/index';
2
+ export interface IsOnline extends Subscribable<boolean>, Readable<boolean>, Destroyable {
3
+ }
4
+ /**
5
+ * Creates a reactive handle for browser online status.
6
+ *
7
+ * @example Vanilla
8
+ * ```ts twoslash
9
+ * import { createIsOnline } from 'seitu/web'
10
+ *
11
+ * const isOnline = createIsOnline()
12
+ *
13
+ * isOnline.subscribe(value => {
14
+ * console.log(value ? 'online' : 'offline')
15
+ * })
16
+ *
17
+ * console.log(isOnline.get())
18
+ * ```
19
+ *
20
+ * @example React
21
+ * ```tsx twoslash title="page.tsx"
22
+ * import { createIsOnline } from 'seitu/web'
23
+ * import { useSubscription } from 'seitu/react'
24
+ *
25
+ * const isOnline = createIsOnline()
26
+ *
27
+ * function Status() {
28
+ * const online = useSubscription(isOnline)
29
+ * return online ? 'Connected' : 'Disconnected'
30
+ * }
31
+ * ```
32
+ */
33
+ export declare function createIsOnline(): IsOnline;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,7 +1,7 @@
1
1
  import type { StandardSchemaV1 } from '@standard-schema/spec';
2
- import type { Destroyable, Readable, Subscribable, Writable } from '../core/index';
2
+ import type { Destroyable, Readable, Removable, Subscribable, Writable } from '../core/index';
3
3
  import type { WebStorage } from './web-storage';
4
- export interface WebStorageValue<V> extends Subscribable<V>, Readable<V>, Writable<V>, Destroyable {
4
+ export interface WebStorageValue<V> extends Subscribable<V>, Readable<V>, Writable<V>, Destroyable, Removable {
5
5
  }
6
6
  export interface WebStorageValueOptionsWithStorage<Storage extends WebStorage<any>, K extends keyof Storage['~']['output']> {
7
7
  storage: Storage;
package/dist/web.js CHANGED
@@ -1,6 +1,22 @@
1
1
  import { i as e, n as t, o as n } from "./core-3fd1NXIt.js";
2
+ //#region src/web/is-online.ts
3
+ function r() {
4
+ let { subscribe: e, notify: t } = n(), r = () => typeof navigator > "u" ? !0 : navigator.onLine, i = () => t();
5
+ return typeof window < "u" && (window.addEventListener("online", i), window.addEventListener("offline", i)), {
6
+ get: r,
7
+ subscribe: (t) => e(() => t(r())),
8
+ destroy: () => {
9
+ typeof window < "u" && (window.removeEventListener("online", i), window.removeEventListener("offline", i));
10
+ },
11
+ "~": {
12
+ output: null,
13
+ notify: t
14
+ }
15
+ };
16
+ }
17
+ //#endregion
2
18
  //#region src/web/web-storage.ts
3
- function r(n) {
19
+ function i(n) {
4
20
  let { kind: r, keyTransform: i, defaultValues: a, schemas: o } = n, s = !1, c = t({
5
21
  defaultValues: a,
6
22
  schemas: o,
@@ -45,15 +61,15 @@ function r(n) {
45
61
  }
46
62
  //#endregion
47
63
  //#region src/web/local-storage.ts
48
- function i(e) {
49
- return r({
64
+ function a(e) {
65
+ return i({
50
66
  kind: "localStorage",
51
67
  ...e
52
68
  });
53
69
  }
54
70
  //#endregion
55
71
  //#region src/web/web-storage-value.ts
56
- function a(t) {
72
+ function o(t) {
57
73
  let r = "storage" in t ? t.storage["~"].kind : t.kind, i = !1, a = `${r}Value`;
58
74
  if ("schema" in t && t.defaultValue === void 0) throw Error(`[${a}] Default value is required`);
59
75
  if (t.key === void 0) throw Error(`[${a}] Key is required`);
@@ -83,6 +99,9 @@ function a(t) {
83
99
  i = !0, n.setItem(t.key, typeof a == "string" ? a : JSON.stringify(a)), window.dispatchEvent(new Event("storage")), i = !1, c();
84
100
  },
85
101
  subscribe: (e) => s(() => e(l())),
102
+ remove: () => {
103
+ typeof window > "u" || window[r].removeItem(t.key);
104
+ },
86
105
  destroy: () => {
87
106
  typeof window < "u" && window.removeEventListener("storage", u);
88
107
  },
@@ -94,15 +113,15 @@ function a(t) {
94
113
  }
95
114
  //#endregion
96
115
  //#region src/web/local-storage-value.ts
97
- function o(e) {
98
- return "storage" in e ? a(e) : a({
116
+ function s(e) {
117
+ return "storage" in e ? o(e) : o({
99
118
  ...e,
100
119
  kind: "localStorage"
101
120
  });
102
121
  }
103
122
  //#endregion
104
123
  //#region src/web/media-query.ts
105
- function s(e) {
124
+ function c(e) {
106
125
  let { subscribe: t, notify: r } = n(), i = typeof window > "u" ? null : window.matchMedia(e.query), a = () => i?.matches ?? e.defaultMatches ?? !1, o = () => r();
107
126
  return i?.addEventListener("change", o), {
108
127
  get: a,
@@ -118,11 +137,11 @@ function s(e) {
118
137
  }
119
138
  //#endregion
120
139
  //#region src/web/scroll-state.ts
121
- var c = {
140
+ var l = {
122
141
  reached: !1,
123
142
  remaining: 0
124
143
  };
125
- function l(e) {
144
+ function u(e) {
126
145
  let { direction: t = "both", threshold: r = 0 } = e, { subscribe: i, notify: a } = n(), o = typeof r == "number" ? {
127
146
  top: r,
128
147
  bottom: r,
@@ -133,31 +152,31 @@ function l(e) {
133
152
  bottom: r.bottom ?? 0,
134
153
  left: r.left ?? 0,
135
154
  right: r.right ?? 0
136
- }, s = () => typeof e.element == "function" ? e.element() : e.element, l = () => {
155
+ }, s = () => typeof e.element == "function" ? e.element() : e.element, c = () => {
137
156
  let e = s(), n = (e, t) => ({
138
157
  reached: e,
139
158
  remaining: Math.max(0, t)
140
159
  });
141
160
  if (!e) return {
142
- top: c,
143
- bottom: c,
144
- left: c,
145
- right: c
161
+ top: l,
162
+ bottom: l,
163
+ left: l,
164
+ right: l
146
165
  };
147
- let r = e.scrollTop, i = e.scrollHeight - e.scrollTop - e.clientHeight, a = e.scrollLeft, l = e.scrollWidth - e.scrollLeft - e.clientWidth;
166
+ let r = e.scrollTop, i = e.scrollHeight - e.scrollTop - e.clientHeight, a = e.scrollLeft, c = e.scrollWidth - e.scrollLeft - e.clientWidth;
148
167
  return {
149
- top: t === "horizontal" ? c : n(r <= o.top, r),
150
- bottom: t === "horizontal" ? c : n(i <= o.bottom, i),
151
- left: t === "vertical" ? c : n(a <= o.left, a),
152
- right: t === "vertical" ? c : n(l <= o.right, l)
168
+ top: t === "horizontal" ? l : n(r <= o.top, r),
169
+ bottom: t === "horizontal" ? l : n(i <= o.bottom, i),
170
+ left: t === "vertical" ? l : n(a <= o.left, a),
171
+ right: t === "vertical" ? l : n(c <= o.right, c)
153
172
  };
154
173
  };
155
174
  return {
156
- get: l,
175
+ get: c,
157
176
  subscribe: (e) => {
158
177
  let t = s();
159
- if (!t) return e(l()), () => {};
160
- let n = i(() => e(l())), r = () => e(l());
178
+ if (!t) return e(c()), () => {};
179
+ let n = i(() => e(c())), r = () => e(c());
161
180
  return t.addEventListener("scroll", r, { passive: !0 }), () => {
162
181
  n(), t.removeEventListener("scroll", r);
163
182
  };
@@ -170,19 +189,19 @@ function l(e) {
170
189
  }
171
190
  //#endregion
172
191
  //#region src/web/session-storage.ts
173
- function u(e) {
174
- return r({
192
+ function d(e) {
193
+ return i({
175
194
  kind: "sessionStorage",
176
195
  ...e
177
196
  });
178
197
  }
179
198
  //#endregion
180
199
  //#region src/web/session-storage-value.ts
181
- function d(e) {
182
- return "storage" in e ? a(e) : a({
200
+ function f(e) {
201
+ return "storage" in e ? o(e) : o({
183
202
  ...e,
184
203
  kind: "sessionStorage"
185
204
  });
186
205
  }
187
206
  //#endregion
188
- export { i as createLocalStorage, o as createLocalStorageValue, s as createMediaQuery, l as createScrollState, u as createSessionStorage, d as createSessionStorageValue };
207
+ export { r as createIsOnline, a as createLocalStorage, s as createLocalStorageValue, c as createMediaQuery, u as createScrollState, d as createSessionStorage, f as createSessionStorageValue };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "seitu",
3
3
  "displayName": "Seitu",
4
4
  "type": "module",
5
- "version": "0.4.6",
5
+ "version": "0.5.0",
6
6
  "private": false,
7
7
  "author": "Valerii Strilets",
8
8
  "license": "MIT",
@@ -64,14 +64,14 @@
64
64
  "@testing-library/jest-dom": "^6.9.1",
65
65
  "@testing-library/react": "^16.3.2",
66
66
  "@types/react": "^19.2.14",
67
- "@vitejs/plugin-react": "^6.0.1",
68
- "happy-dom": "^20.8.4",
67
+ "@vitejs/plugin-react": "^5.1.4",
68
+ "happy-dom": "^20.8.3",
69
69
  "react-dom": "^19.2.4",
70
70
  "type-fest": "^5.4.4",
71
71
  "typescript": "^5.9.3",
72
- "vite": "^8.0.0",
72
+ "vite": "^8.0.0-beta.16",
73
73
  "vite-plugin-dts": "^4.5.4",
74
- "vitest": "^4.1.0",
74
+ "vitest": "^4.0.18",
75
75
  "zod": "^4.3.6"
76
76
  },
77
77
  "scripts": {