atomaric 0.0.29 → 0.0.32

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
@@ -1,29 +1,29 @@
1
- ## 🕹️Installation
2
-
3
- ```sh
4
- npm install atomaric
5
- ```
6
-
7
- ## usage
8
-
9
- ```tsx
10
- import { atom, useAtom, configureAtomaric } from 'atomaric';
11
- import { useSyncExternalStore } from 'react';
12
-
13
- configureAtomaric({ useSyncExternalStore }); // do this before all
14
-
15
- const nameAtom = atom(
16
- 'World',
17
- 'greats:name', // optional localStorage key
18
- );
19
-
20
- function App() {
21
- const [name, setIsOpen] = useAtom(nameAtom);
22
-
23
- return (
24
- <div onClick={() => setIsOpen(isOpen => (name === 'World' ? 'Man' : 'World'))}>
25
- Hello <span className="color-accent">{name}</span>
26
- </div>
27
- );
28
- }
29
- ```
1
+ ## 🕹️Installation
2
+
3
+ ```sh
4
+ npm install atomaric
5
+ ```
6
+
7
+ ## usage
8
+
9
+ ```tsx
10
+ import { atom, useAtom, configureAtomaric } from 'atomaric';
11
+ import { useSyncExternalStore } from 'react';
12
+
13
+ configureAtomaric({ useSyncExternalStore }); // do this before all
14
+
15
+ const nameAtom = atom(
16
+ 'World',
17
+ 'greats:name', // optional localStorage key
18
+ );
19
+
20
+ function App() {
21
+ const [name, setIsOpen] = useAtom(nameAtom);
22
+
23
+ return (
24
+ <div onClick={() => setIsOpen(isOpen => (name === 'World' ? 'Man' : 'World'))}>
25
+ Hello <span className="color-accent">{name}</span>
26
+ </div>
27
+ );
28
+ }
29
+ ```
package/build/atomaric.js CHANGED
@@ -1,192 +1,234 @@
1
- const P = (n, e, l) => {
2
- let i = null;
3
- typeof n == "number" ? i = y(
4
- {
5
- increment: (s) => {
6
- e.set(+e.get() + (s ?? 0));
1
+ const v = (e, r, l) => {
2
+ let d = null;
3
+ typeof e == "number" ? d = _(
4
+ r,
5
+ (s) => ({
6
+ increment: (n) => {
7
+ s.set(+s.get() + (n ?? 0));
7
8
  }
8
- }
9
- ) : typeof n == "boolean" ? i = y(
10
- {
9
+ })
10
+ ) : typeof e == "boolean" ? d = _(
11
+ r,
12
+ (s) => ({
11
13
  toggle: () => {
12
- e.set(!e.get());
14
+ s.set(!s.get());
13
15
  }
14
- }
15
- ) : Array.isArray(n) ? i = y(
16
- {
17
- push: (...s) => {
18
- e.set(e.get().concat(s));
16
+ })
17
+ ) : Array.isArray(e) ? d = _(
18
+ r,
19
+ (s) => ({
20
+ push: (...n) => {
21
+ s.set(s.get().concat(n));
19
22
  },
20
- unshift: (...s) => {
21
- e.set(s.concat(e.get()));
23
+ unshift: (...n) => {
24
+ s.set(n.concat(s.get()));
22
25
  },
23
- update: (s) => {
24
- const r = e.get().slice();
25
- s(r), e.set(r);
26
+ update: (n) => {
27
+ const c = s.get().slice();
28
+ n(c), s.set(c);
26
29
  },
27
- filter: (s) => {
28
- e.set(e.get().filter(s ?? V));
30
+ filter: (n) => {
31
+ s.set(s.get().filter(n ?? B));
32
+ },
33
+ toggle: (n, c) => {
34
+ const g = s.get().slice(), f = g.indexOf(n);
35
+ f < 0 ? c ? g.unshift(n) : g.push(n) : g.splice(f, 1), s.set(g);
29
36
  }
30
- }
31
- ) : n instanceof Set ? i = y(
32
- {
33
- add: (s) => {
34
- e.set(new Set(e.get()).add(s));
37
+ })
38
+ ) : e instanceof Set ? d = _(
39
+ r,
40
+ (s) => ({
41
+ add: (n) => {
42
+ s.set(new Set(s.get()).add(n));
35
43
  },
36
- delete: (s) => {
37
- const r = new Set(e.get());
38
- r.delete(s), e.set(r);
44
+ delete: (n) => {
45
+ const c = new Set(s.get());
46
+ c.delete(n), s.set(c);
39
47
  },
40
- toggle: (s) => {
41
- const r = new Set(e.get());
42
- r.has(s) ? r.delete(s) : r.add(s), e.set(r);
48
+ toggle: (n) => {
49
+ const c = new Set(s.get());
50
+ c.has(n) ? c.delete(n) : c.add(n), s.set(c);
43
51
  },
44
52
  clear: () => {
45
- e.set(/* @__PURE__ */ new Set());
53
+ s.set(/* @__PURE__ */ new Set());
54
+ },
55
+ update: (n) => {
56
+ const c = new Set(s.get());
57
+ n(c), s.set(c);
58
+ }
59
+ })
60
+ ) : e instanceof Object && (d = _(
61
+ r,
62
+ (s) => ({
63
+ setPartial: (n) => s.set((c) => ({
64
+ ...c,
65
+ ...typeof n == "function" ? n(s.get()) : n
66
+ })),
67
+ update: (n) => {
68
+ const c = { ...s.get() };
69
+ n(c), s.set(c);
46
70
  },
47
- update: (s) => {
48
- const r = new Set(e.get());
49
- s(r), e.set(r);
71
+ setDeepPartial: (n, c, g = ".") => {
72
+ if (n.includes(g)) {
73
+ let f = n.split(g);
74
+ const p = f[f.length - 1];
75
+ f = f.slice(0, -1);
76
+ const D = { ...s.get() };
77
+ let a = D;
78
+ for (const w of f) {
79
+ const A = a[w];
80
+ if (A == null || typeof A != "object") {
81
+ s.do.setPartial({ [n]: c });
82
+ return;
83
+ }
84
+ a = a[w] = Array.isArray(A) ? [...A] : { ...A };
85
+ }
86
+ a[p] = c, s.set(D);
87
+ } else s.do.setPartial({ [n]: c });
50
88
  }
51
- }
52
- ) : n instanceof Object && (i = y(
53
- {
54
- setPartial: (s) => e.set((r) => ({
55
- ...r,
56
- ...typeof s == "function" ? s(e.get()) : s
57
- }))
58
- }
89
+ })
59
90
  ));
60
- const f = typeof l == "object" && l != null && "do" in l ? l.do(
61
- (s, r) => e.set(s, r),
62
- () => e.get(),
63
- e,
64
- (s, r, w) => e.setDeferred(s, r, w)
65
- ) : null, d = {};
66
- return f && Object.keys(f).forEach((s) => Object.defineProperty(d, s, { get: () => f[s] })), i && Object.keys(i).forEach(
67
- (s) => Object.defineProperty(d, s, { get: () => i[s] })
68
- ), d;
69
- }, V = (n) => n, y = (n, e) => n;
70
- class H {
71
- constructor(e, l) {
72
- const i = (t) => r = t, f = () => r, d = /* @__PURE__ */ new Set(), s = (t) => t(S());
73
- let r = e, w, C = () => {
74
- }, S = () => f(), g = null, $ = () => {
75
- const t = P(e, _, l);
76
- return $ = () => t, t;
91
+ const h = typeof l == "object" && l != null && "do" in l ? l.do(
92
+ (s, n) => r.set(s, n),
93
+ () => r.get(),
94
+ r,
95
+ (s, n, c) => r.setDeferred(s, n, c)
96
+ ) : null, b = {};
97
+ return h && Object.keys(h).forEach((s) => Object.defineProperty(b, s, { get: () => h[s] })), d && Object.keys(d).forEach(
98
+ (s) => Object.defineProperty(b, s, { get: () => d[s] })
99
+ ), b;
100
+ }, B = (e) => e, _ = (e, r, l) => r(e);
101
+ class G {
102
+ constructor(r, l) {
103
+ const d = (t) => n = t, h = () => n, b = /* @__PURE__ */ new Set(), s = (t) => t(f());
104
+ let n = r, c, g = () => {
105
+ }, f = () => h(), p = null, D = () => {
106
+ const t = v(r, a, l);
107
+ return D = () => t, t;
77
108
  };
78
- const _ = new Proxy(this, {
79
- get: (t, o) => o === "do" ? $() : t[o],
80
- set: L
81
- }), b = (t, o) => {
82
- const a = typeof t == "function" ? t(S()) : t;
83
- if (!(a === S() || a === void 0 || typeof a == "number" && isNaN(a))) {
84
- i(a), d.forEach(s, this);
109
+ const a = new Proxy(this, {
110
+ get: (t, u) => u === "do" ? D() : t[u],
111
+ set: U
112
+ }), w = (t, u) => {
113
+ const S = typeof t == "function" ? t(f()) : t;
114
+ if (!(S === f() || S === void 0 || typeof S == "number" && isNaN(S))) {
115
+ d(S), b.forEach(s, this);
85
116
  try {
86
- T.postMessage({ key: u, value: f() });
117
+ P.postMessage({ key: i, value: h() });
87
118
  } catch {
88
119
  }
89
- o !== !0 && C(a);
120
+ u !== !0 && g(S);
90
121
  }
91
122
  };
92
- this.set = (t, o) => b(t, o), this.get = () => S(), this.initialValue = e, this.isInitialValue = () => e === f(), this.subscribe = (t) => (d.add(t), () => {
93
- d.delete(t);
123
+ this.set = (t, u) => w(t, u), this.get = () => f(), this.initialValue = r, this.isInitialValue = () => r === h(), this.subscribe = (t) => (b.add(t), () => {
124
+ b.delete(t);
94
125
  }), this.reset = () => {
95
- b(e, !0), d.forEach(s, this);
126
+ w(r, !0), b.forEach(s, this);
96
127
  };
97
- const J = (t, o) => {
98
- b(t, o), w = void 0;
128
+ const A = (t, u) => {
129
+ w(t, u), c = void 0;
99
130
  };
100
- if (this.setDeferred = (t, o = 500, a, k = !0) => {
101
- k && w === void 0 && b(t, a), clearTimeout(w), w = setTimeout(J, o, t, a);
102
- }, l == null) return _;
103
- let h = null, p = null, I = !0, x = !0, j = !1, E = e instanceof Set ? (t) => new Set(t) : (t) => t, m = e instanceof Set ? (t) => {
131
+ if (this.setDeferred = (t, u = 500, S, H = !0) => {
132
+ H && c === void 0 && w(t, S), clearTimeout(c), c = setTimeout(A, u, t, S);
133
+ }, l == null) return a;
134
+ let y = null, T = null, I = !0, E = !0, C = !1, z = -1, $ = r instanceof Set ? (t) => new Set(t) : (t) => t, j = r instanceof Set ? (t) => {
104
135
  if (t instanceof Set) return Array.from(t);
105
136
  throw console.error(t), "The value is not Set instance";
106
137
  } : (t) => t;
107
138
  if (typeof l == "string")
108
- h = l;
139
+ y = l;
109
140
  else if ("storeKey" in l)
110
- I = l.warnOnDuplicateStoreKey ?? I, x = l.listenStorageChanges ?? x, h = l.storeKey, E = l.unzipValue ?? E, m = l.zipValue ?? m, j = l.unchangable ?? j, p = l.exp ?? p;
111
- else return _;
112
- const v = p === null || !(p() instanceof Date) ? (t) => JSON.stringify([m(t)]) : (t) => (g ?? (g = {}), g.exp = p().getTime(), JSON.stringify([m(t), g])), N = (t) => {
113
- const o = JSON.parse(t);
114
- return g = o[1], g != null && g.exp != null && g.exp < Date.now() ? (this.reset(), e) : E(o[0]);
115
- }, u = `atom\\${h}`;
116
- let z = !0;
117
- if (c[`atom/${h}`] && (c[u] || (c[u] = `[${c[`atom/${h}`]}]`), delete c[`atom/${h}`]), S = () => {
118
- if (S = f, z) {
119
- z = !1;
141
+ I = l.warnOnDuplicateStoreKey ?? I, E = l.listenStorageChanges ?? E, y = l.storeKey, $ = l.unzipValue ?? $, j = l.zipValue ?? j, C = l.unchangable ?? C, T = l.exp ?? T;
142
+ else return a;
143
+ const i = `${L}${y}`, V = T === null || !(T(a, i in o) instanceof Date) ? (t) => JSON.stringify([j(t)]) : (t) => (p ?? (p = {}), p.exp = T(a, i in o).getTime() + 0.2866, p.exp - Date.now() < 24 * 60 * 60 * 1e3 && (clearTimeout(z), clearTimeout(M[i]), z = setTimeout(() => this.reset(), p.exp - Date.now())), JSON.stringify([j(t), p])), F = (t) => {
144
+ const u = JSON.parse(t);
145
+ return p = u[1], $(u[0]);
146
+ };
147
+ let J = !0;
148
+ if (N[i] = a, o[`atom/${y}`] && (o[i] || (o[i] = `[${o[`atom/${y}`]}]`), delete o[`atom/${y}`]), f = () => {
149
+ if (f = h, J) {
150
+ J = !1;
120
151
  try {
121
- i(u in c ? N(c[u]) : e);
152
+ d(i in o ? F(o[i]) : r);
122
153
  } catch {
123
- console.warn("Invalid json value", c[u]);
154
+ console.warn("Invalid json value", o[i]);
124
155
  }
125
156
  }
126
- return f();
127
- }, C = (t) => {
128
- if (t === e) {
157
+ return h();
158
+ }, g = (t) => {
159
+ if (t === r) {
129
160
  this.reset();
130
161
  return;
131
162
  }
132
- c[u] = v(t);
163
+ o[i] = V(t);
133
164
  }, this.reset = () => {
134
- delete c[u], b(e, !0);
135
- }, I && A[u] !== void 0 && console.warn("Duplicate Atom key", h), x)
136
- if (j) {
137
- let t = !1, o;
138
- D[u] = this, A[u] = () => {
139
- clearTimeout(o), o = setTimeout(() => t = !1, 10), !t && (t = !0, c[u] = v(f()));
165
+ delete o[i], w(r, !0);
166
+ }, I && x[i] !== void 0 && console.warn("Duplicate Atom key", y), E)
167
+ if (C) {
168
+ let t = !1, u;
169
+ m[i] = this, x[i] = () => {
170
+ clearTimeout(u), u = setTimeout(() => t = !1, 10), !t && (t = !0, o[i] = V(h()));
140
171
  };
141
172
  } else
142
- A[u] = (t) => {
173
+ x[i] = (t) => {
143
174
  if (t.newValue === null) {
144
175
  this.reset();
145
176
  return;
146
177
  }
147
178
  try {
148
- b(N(t.newValue));
179
+ w(F(t.newValue));
149
180
  } catch {
150
181
  console.warn("Invalid json value", t.newValue);
151
182
  }
152
183
  };
153
- return _;
184
+ return a;
154
185
  }
155
186
  }
156
- let T;
187
+ let P;
157
188
  try {
158
- T = new BroadcastChannel("updateHere"), T.addEventListener("message", (n) => {
159
- var e;
160
- (e = D[n.data.key]) == null || e.set(n.data.value, !0);
189
+ P = new BroadcastChannel("updateHere"), P.addEventListener("message", (e) => {
190
+ var r;
191
+ (r = m[e.data.key]) == null || r.set(e.data.value, !0);
161
192
  });
162
193
  } catch {
163
194
  }
164
- const c = window.localStorage, A = {}, D = {}, L = (n, e) => {
165
- throw `${e} is readonly property`;
195
+ const o = window.localStorage, x = {}, m = {}, U = (e, r) => {
196
+ throw `${r} is readonly property`;
166
197
  };
167
- window.addEventListener("storage", (n) => {
168
- var e;
169
- n.key === null || n.newValue === n.oldValue || (e = A[n.key]) == null || e.call(A, n);
198
+ window.addEventListener("storage", (e) => {
199
+ var r;
200
+ e.key === null || e.newValue === e.oldValue || (r = x[e.key]) == null || r.call(x, e);
170
201
  });
171
- const B = c.setItem.bind(c), G = c.removeItem.bind(c);
172
- c.setItem = (n, e) => {
173
- D[n] === void 0 && B.call(c, n, e);
202
+ const W = o.setItem.bind(o), q = o.removeItem.bind(o);
203
+ o.setItem = (e, r) => {
204
+ m[e] === void 0 && W.call(o, e, r);
174
205
  };
175
- c.removeItem = (n) => {
176
- D[n] === void 0 && G.call(c, n);
206
+ o.removeItem = (e) => {
207
+ m[e] === void 0 && q.call(o, e);
177
208
  };
178
- let F = () => {
209
+ const Q = /"exp":(\d+)\.2866/, L = "atom\\", N = {}, M = {};
210
+ setTimeout(() => {
211
+ Object.keys(o).forEach((e) => {
212
+ var l;
213
+ if (!e.startsWith(L) || typeof o[e] != "string") return;
214
+ const r = +((l = o[e].match(Q)) == null ? void 0 : l[1]);
215
+ r && r - Date.now() < 24 * 60 * 60 * 1e3 && (M[e] = setTimeout(() => {
216
+ N[e] ? N[e].reset() : delete o[e];
217
+ }, r - Date.now()));
218
+ });
219
+ }, 1e3);
220
+ let R = () => {
179
221
  throw "call configureAtomaric() before all!";
180
222
  };
181
- const q = (n) => F = n.useSyncExternalStore, M = (n) => F(n.subscribe, n.get), U = (n) => n.set, Q = (n) => n.setDeferred, R = (n) => n.get, W = (n) => n.do, X = (n) => [M(n), U(n)], Y = (n, e) => new H(n, e);
223
+ const Z = (e) => R = e.useSyncExternalStore, X = (e) => R(e.subscribe, e.get), Y = (e) => e.set, k = (e) => e.setDeferred, K = (e) => e.get, O = (e) => e.do, ee = (e) => [X(e), Y(e)], te = (e, r) => new G(e, r);
182
224
  export {
183
- H as Atom,
184
- Y as atom,
185
- q as configureAtomaric,
186
- X as useAtom,
187
- W as useAtomDo,
188
- R as useAtomGet,
189
- U as useAtomSet,
190
- Q as useAtomSetDeferred,
191
- M as useAtomValue
225
+ G as Atom,
226
+ te as atom,
227
+ Z as configureAtomaric,
228
+ ee as useAtom,
229
+ O as useAtomDo,
230
+ K as useAtomGet,
231
+ Y as useAtomSet,
232
+ k as useAtomSetDeferred,
233
+ X as useAtomValue
192
234
  };
@@ -1 +1 @@
1
- (function(u,y){typeof exports=="object"&&typeof module<"u"?y(exports):typeof define=="function"&&define.amd?define(["exports"],y):(u=typeof globalThis<"u"?globalThis:u||self,y(u.atomaric={}))})(this,function(u){"use strict";const y=(n,e,o)=>{let f=null;typeof n=="number"?f=p({increment:s=>{e.set(+e.get()+(s??0))}}):typeof n=="boolean"?f=p({toggle:()=>{e.set(!e.get())}}):Array.isArray(n)?f=p({push:(...s)=>{e.set(e.get().concat(s))},unshift:(...s)=>{e.set(s.concat(e.get()))},update:s=>{const r=e.get().slice();s(r),e.set(r)},filter:s=>{e.set(e.get().filter(s??L))}}):n instanceof Set?f=p({add:s=>{e.set(new Set(e.get()).add(s))},delete:s=>{const r=new Set(e.get());r.delete(s),e.set(r)},toggle:s=>{const r=new Set(e.get());r.has(s)?r.delete(s):r.add(s),e.set(r)},clear:()=>{e.set(new Set)},update:s=>{const r=new Set(e.get());s(r),e.set(r)}}):n instanceof Object&&(f=p({setPartial:s=>e.set(r=>({...r,...typeof s=="function"?s(e.get()):s}))}));const d=typeof o=="object"&&o!=null&&"do"in o?o.do((s,r)=>e.set(s,r),()=>e.get(),e,(s,r,A)=>e.setDeferred(s,r,A)):null,g={};return d&&Object.keys(d).forEach(s=>Object.defineProperty(g,s,{get:()=>d[s]})),f&&Object.keys(f).forEach(s=>Object.defineProperty(g,s,{get:()=>f[s]})),g},L=n=>n,p=(n,e)=>n;class N{constructor(e,o){const f=t=>r=t,d=()=>r,g=new Set,s=t=>t(b());let r=e,A,k=()=>{},b=()=>d(),h=null,x=()=>{const t=y(e,I,o);return x=()=>t,t};const I=new Proxy(this,{get:(t,l)=>l==="do"?x():t[l],set:M}),m=(t,l)=>{const a=typeof t=="function"?t(b()):t;if(!(a===b()||a===void 0||typeof a=="number"&&isNaN(a))){f(a),g.forEach(s,this);try{j.postMessage({key:i,value:d()})}catch{}l!==!0&&k(a)}};this.set=(t,l)=>m(t,l),this.get=()=>b(),this.initialValue=e,this.isInitialValue=()=>e===d(),this.subscribe=t=>(g.add(t),()=>{g.delete(t)}),this.reset=()=>{m(e,!0),g.forEach(s,this)};const Z=(t,l)=>{m(t,l),A=void 0};if(this.setDeferred=(t,l=500,a,H=!0)=>{H&&A===void 0&&m(t,a),clearTimeout(A),A=setTimeout(Z,l,t,a)},o==null)return I;let S=null,_=null,E=!0,C=!0,v=!1,$=e instanceof Set?t=>new Set(t):t=>t,T=e instanceof Set?t=>{if(t instanceof Set)return Array.from(t);throw console.error(t),"The value is not Set instance"}:t=>t;if(typeof o=="string")S=o;else if("storeKey"in o)E=o.warnOnDuplicateStoreKey??E,C=o.listenStorageChanges??C,S=o.storeKey,$=o.unzipValue??$,T=o.zipValue??T,v=o.unchangable??v,_=o.exp??_;else return I;const F=_===null||!(_()instanceof Date)?t=>JSON.stringify([T(t)]):t=>(h??(h={}),h.exp=_().getTime(),JSON.stringify([T(t),h])),J=t=>{const l=JSON.parse(t);return h=l[1],h!=null&&h.exp!=null&&h.exp<Date.now()?(this.reset(),e):$(l[0])},i=`atom\\${S}`;let G=!0;if(c[`atom/${S}`]&&(c[i]||(c[i]=`[${c[`atom/${S}`]}]`),delete c[`atom/${S}`]),b=()=>{if(b=d,G){G=!1;try{f(i in c?J(c[i]):e)}catch{console.warn("Invalid json value",c[i])}}return d()},k=t=>{if(t===e){this.reset();return}c[i]=F(t)},this.reset=()=>{delete c[i],m(e,!0)},E&&w[i]!==void 0&&console.warn("Duplicate Atom key",S),C)if(v){let t=!1,l;D[i]=this,w[i]=()=>{clearTimeout(l),l=setTimeout(()=>t=!1,10),!t&&(t=!0,c[i]=F(d()))}}else w[i]=t=>{if(t.newValue===null){this.reset();return}try{m(J(t.newValue))}catch{console.warn("Invalid json value",t.newValue)}};return I}}let j;try{j=new BroadcastChannel("updateHere"),j.addEventListener("message",n=>{var e;(e=D[n.data.key])==null||e.set(n.data.value,!0)})}catch{}const c=window.localStorage,w={},D={},M=(n,e)=>{throw`${e} is readonly property`};window.addEventListener("storage",n=>{var e;n.key===null||n.newValue===n.oldValue||(e=w[n.key])==null||e.call(w,n)});const B=c.setItem.bind(c),U=c.removeItem.bind(c);c.setItem=(n,e)=>{D[n]===void 0&&B.call(c,n,e)},c.removeItem=n=>{D[n]===void 0&&U.call(c,n)};let z=()=>{throw"call configureAtomaric() before all!"};const q=n=>z=n.useSyncExternalStore,P=n=>z(n.subscribe,n.get),V=n=>n.set,Q=n=>n.setDeferred,R=n=>n.get,W=n=>n.do,X=n=>[P(n),V(n)],Y=(n,e)=>new N(n,e);u.Atom=N,u.atom=Y,u.configureAtomaric=q,u.useAtom=X,u.useAtomDo=W,u.useAtomGet=R,u.useAtomSet=V,u.useAtomSetDeferred=Q,u.useAtomValue=P,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
1
+ (function(d,D){typeof exports=="object"&&typeof module<"u"?D(exports):typeof define=="function"&&define.amd?define(["exports"],D):(d=typeof globalThis<"u"?globalThis:d||self,D(d.atomaric={}))})(this,function(d){"use strict";const D=(e,r,i)=>{let g=null;typeof e=="number"?g=j(r,s=>({increment:n=>{s.set(+s.get()+(n??0))}})):typeof e=="boolean"?g=j(r,s=>({toggle:()=>{s.set(!s.get())}})):Array.isArray(e)?g=j(r,s=>({push:(...n)=>{s.set(s.get().concat(n))},unshift:(...n)=>{s.set(n.concat(s.get()))},update:n=>{const c=s.get().slice();n(c),s.set(c)},filter:n=>{s.set(s.get().filter(n??q))},toggle:(n,c)=>{const h=s.get().slice(),f=h.indexOf(n);f<0?c?h.unshift(n):h.push(n):h.splice(f,1),s.set(h)}})):e instanceof Set?g=j(r,s=>({add:n=>{s.set(new Set(s.get()).add(n))},delete:n=>{const c=new Set(s.get());c.delete(n),s.set(c)},toggle:n=>{const c=new Set(s.get());c.has(n)?c.delete(n):c.add(n),s.set(c)},clear:()=>{s.set(new Set)},update:n=>{const c=new Set(s.get());n(c),s.set(c)}})):e instanceof Object&&(g=j(r,s=>({setPartial:n=>s.set(c=>({...c,...typeof n=="function"?n(s.get()):n})),update:n=>{const c={...s.get()};n(c),s.set(c)},setDeepPartial:(n,c,h=".")=>{if(n.includes(h)){let f=n.split(h);const m=f[f.length-1];f=f.slice(0,-1);const _={...s.get()};let a=_;for(const S of f){const p=a[S];if(p==null||typeof p!="object"){s.do.setPartial({[n]:c});return}a=a[S]=Array.isArray(p)?[...p]:{...p}}a[m]=c,s.set(_)}else s.do.setPartial({[n]:c})}})));const w=typeof i=="object"&&i!=null&&"do"in i?i.do((s,n)=>r.set(s,n),()=>r.get(),r,(s,n,c)=>r.setDeferred(s,n,c)):null,b={};return w&&Object.keys(w).forEach(s=>Object.defineProperty(b,s,{get:()=>w[s]})),g&&Object.keys(g).forEach(s=>Object.defineProperty(b,s,{get:()=>g[s]})),b},q=e=>e,j=(e,r,i)=>r(e);class F{constructor(r,i){const g=t=>n=t,w=()=>n,b=new Set,s=t=>t(f());let n=r,c,h=()=>{},f=()=>w(),m=null,_=()=>{const t=D(r,a,i);return _=()=>t,t};const a=new Proxy(this,{get:(t,u)=>u==="do"?_():t[u],set:Q}),S=(t,u)=>{const A=typeof t=="function"?t(f()):t;if(!(A===f()||A===void 0||typeof A=="number"&&isNaN(A))){g(A),b.forEach(s,this);try{C.postMessage({key:l,value:w()})}catch{}u!==!0&&h(A)}};this.set=(t,u)=>S(t,u),this.get=()=>f(),this.initialValue=r,this.isInitialValue=()=>r===w(),this.subscribe=t=>(b.add(t),()=>{b.delete(t)}),this.reset=()=>{S(r,!0),b.forEach(s,this)};const p=(t,u)=>{S(t,u),c=void 0};if(this.setDeferred=(t,u=500,A,W=!0)=>{W&&c===void 0&&S(t,A),clearTimeout(c),c=setTimeout(p,u,t,A)},i==null)return a;let y=null,I=null,$=!0,N=!0,V=!1,L=-1,z=r instanceof Set?t=>new Set(t):t=>t,E=r instanceof Set?t=>{if(t instanceof Set)return Array.from(t);throw console.error(t),"The value is not Set instance"}:t=>t;if(typeof i=="string")y=i;else if("storeKey"in i)$=i.warnOnDuplicateStoreKey??$,N=i.listenStorageChanges??N,y=i.storeKey,z=i.unzipValue??z,E=i.zipValue??E,V=i.unchangable??V,I=i.exp??I;else return a;const l=`${J}${y}`,R=I===null||!(I(a,l in o)instanceof Date)?t=>JSON.stringify([E(t)]):t=>(m??(m={}),m.exp=I(a,l in o).getTime()+.2866,m.exp-Date.now()<24*60*60*1e3&&(clearTimeout(L),clearTimeout(M[l]),L=setTimeout(()=>this.reset(),m.exp-Date.now())),JSON.stringify([E(t),m])),B=t=>{const u=JSON.parse(t);return m=u[1],z(u[0])};let U=!0;if(P[l]=a,o[`atom/${y}`]&&(o[l]||(o[l]=`[${o[`atom/${y}`]}]`),delete o[`atom/${y}`]),f=()=>{if(f=w,U){U=!1;try{g(l in o?B(o[l]):r)}catch{console.warn("Invalid json value",o[l])}}return w()},h=t=>{if(t===r){this.reset();return}o[l]=R(t)},this.reset=()=>{delete o[l],S(r,!0)},$&&T[l]!==void 0&&console.warn("Duplicate Atom key",y),N)if(V){let t=!1,u;x[l]=this,T[l]=()=>{clearTimeout(u),u=setTimeout(()=>t=!1,10),!t&&(t=!0,o[l]=R(w()))}}else T[l]=t=>{if(t.newValue===null){this.reset();return}try{S(B(t.newValue))}catch{console.warn("Invalid json value",t.newValue)}};return a}}let C;try{C=new BroadcastChannel("updateHere"),C.addEventListener("message",e=>{var r;(r=x[e.data.key])==null||r.set(e.data.value,!0)})}catch{}const o=window.localStorage,T={},x={},Q=(e,r)=>{throw`${r} is readonly property`};window.addEventListener("storage",e=>{var r;e.key===null||e.newValue===e.oldValue||(r=T[e.key])==null||r.call(T,e)});const X=o.setItem.bind(o),Y=o.removeItem.bind(o);o.setItem=(e,r)=>{x[e]===void 0&&X.call(o,e,r)},o.removeItem=e=>{x[e]===void 0&&Y.call(o,e)};const Z=/"exp":(\d+)\.2866/,J="atom\\",P={},M={};setTimeout(()=>{Object.keys(o).forEach(e=>{var i;if(!e.startsWith(J)||typeof o[e]!="string")return;const r=+((i=o[e].match(Z))==null?void 0:i[1]);r&&r-Date.now()<24*60*60*1e3&&(M[e]=setTimeout(()=>{P[e]?P[e].reset():delete o[e]},r-Date.now()))})},1e3);let v=()=>{throw"call configureAtomaric() before all!"};const k=e=>v=e.useSyncExternalStore,G=e=>v(e.subscribe,e.get),H=e=>e.set,K=e=>e.setDeferred,O=e=>e.get,ee=e=>e.do,te=e=>[G(e),H(e)],se=(e,r)=>new F(e,r);d.Atom=F,d.atom=se,d.configureAtomaric=k,d.useAtom=te,d.useAtomDo=ee,d.useAtomGet=O,d.useAtomSet=H,d.useAtomSetDeferred=K,d.useAtomValue=G,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,44 +1,44 @@
1
- {
2
- "name": "atomaric",
3
- "description": "Manage your project state",
4
- "version": "0.0.29",
5
- "type": "module",
6
- "main": "./build/atomaric.umd.cjs",
7
- "module": "./build/atomaric.js",
8
- "types": "./types/model.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./types/model.d.ts",
12
- "require": "./build/atomaric.umd.cjs",
13
- "import": "./build/atomaric.js"
14
- }
15
- },
16
- "files": [
17
- "build",
18
- "types"
19
- ],
20
- "keywords": [
21
- "react",
22
- "state",
23
- "manager"
24
- ],
25
- "scripts": {
26
- "start": "vite --port 8378 --host",
27
- "build": "tsc && vite build",
28
- "preview": "vite preview"
29
- },
30
- "devDependencies": {
31
- "@types/md5": "^2.3.5",
32
- "@types/node": "^22.15.1",
33
- "@types/react": "^19.1.2",
34
- "@types/react-dom": "^19.1.8",
35
- "@vitejs/plugin-react": "^4.7.0",
36
- "react": "^19.1.0",
37
- "react-dom": "^19.1.1",
38
- "vite": "^6.3.1",
39
- "vite-plugin-eslint": "^1.8.1"
40
- },
41
- "dependencies": {
42
- "typescript": "~5.7.2"
43
- }
44
- }
1
+ {
2
+ "name": "atomaric",
3
+ "description": "Manage your project state",
4
+ "version": "0.0.32",
5
+ "type": "module",
6
+ "main": "./build/atomaric.umd.cjs",
7
+ "module": "./build/atomaric.js",
8
+ "types": "./types/model.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./types/model.d.ts",
12
+ "require": "./build/atomaric.umd.cjs",
13
+ "import": "./build/atomaric.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "build",
18
+ "types"
19
+ ],
20
+ "keywords": [
21
+ "react",
22
+ "state",
23
+ "manager"
24
+ ],
25
+ "scripts": {
26
+ "start": "vite --port 8378 --host",
27
+ "build": "tsc && vite build",
28
+ "preview": "vite preview"
29
+ },
30
+ "devDependencies": {
31
+ "@types/md5": "^2.3.5",
32
+ "@types/node": "^22.15.1",
33
+ "@types/react": "^19.1.2",
34
+ "@types/react-dom": "^19.1.8",
35
+ "@vitejs/plugin-react": "^4.7.0",
36
+ "react": "^19.1.0",
37
+ "react-dom": "^19.1.1",
38
+ "vite": "^6.3.1",
39
+ "vite-plugin-eslint": "^1.8.1"
40
+ },
41
+ "dependencies": {
42
+ "typescript": "~5.7.2"
43
+ }
44
+ }
package/types/model.d.ts CHANGED
@@ -1,149 +1,162 @@
1
- import { useSyncExternalStore } from 'react';
2
-
3
- type Sunscriber<Value> = (value: Value) => void;
4
-
5
- export type AtomStoreKey = `${string}${string}:${string}${string}`;
6
-
7
- export type AtomOptions<Value, Actions extends Record<string, Function> = {}> = {
8
- /** **default: true** */
9
- warnOnDuplicateStoreKey?: boolean;
10
- /** will update value if localStorage value is changed
11
- * **default: true**
12
- */
13
- listenStorageChanges?: boolean;
14
-
15
- /** zip Value to stringifiable value */
16
- zipValue?: (value: Value) => any;
17
- /** unzip stringifiable value to Value */
18
- unzipValue?: (packedValue: any) => Value;
19
-
20
- /** make your localStorage value unchangable */
21
- unchangable?: true;
22
- /** return value expire Date */
23
- exp?: () => Date;
24
- } & (
25
- | {
26
- /** save in localStorage by this key */
27
- storeKey: AtomStoreKey;
28
- }
29
- | {
30
- /** declare your custom actions */
31
- do: (
32
- set: (value: Value | ((value: Value) => Value), isPreventSave?: boolean) => void,
33
- get: () => Value,
34
- self: Atom<Value>,
35
- setDeferred: (value: Value | ((value: Value) => Value), debounceMs?: number, isPreventSave?: boolean) => void,
36
- ) => Actions;
37
- }
38
- );
39
-
40
- export type AtomSetMethod<Value> = (value: Value | ((prev: Value) => Value), isPreventSave?: boolean) => void;
41
- export type AtomSetDeferredMethod<Value> = (
42
- value: Value | ((prev: Value) => Value),
43
- debounceMs?: number,
44
- isPreventSave?: boolean,
45
- isInitInvoke?: boolean,
46
- ) => void;
47
-
48
- export type AtomSubscribeMethod<Value> = (subscriber: Sunscriber<Value>) => () => void;
49
-
50
- export type UpdateAction<Value> = {
51
- /** transform current taken value */
52
- update: (updater: (value: Value) => void) => void;
53
- };
54
-
55
- export type NumberActions<Value> = {
56
- /** pass the 2 to increment on 2, pass the -2 to decrement on 2
57
- * **default: 1**
58
- */
59
- increment: (delta?: number) => void;
60
- };
61
-
62
- export type ObjectActions<Value> = {
63
- /** pass partial object to update some fields */
64
- setPartial: (value: Partial<Value> | ((value: Value) => Partial<Value>)) => void;
65
- };
66
-
67
- export type BooleanActions = {
68
- /** toggle current value between true/false */
69
- toggle: () => void;
70
- };
71
-
72
- export type SetActions<Value> = UpdateAction<Value> & {
73
- /** like the Set.prototype.add() method */
74
- add: (value: Value) => void;
75
- /** like the Set.prototype.delete() method */
76
- delete: (value: Value) => void;
77
- /** will add value if it doesn't exist, otherwise delete */
78
- toggle: (value: Value) => void;
79
- /** like the Set.prototype.clear() method */
80
- clear: () => void;
81
- };
82
-
83
- export type ArrayActions<Value> = UpdateAction<Value[]> & {
84
- /** like the Array.prototype.push() method */
85
- push: (...values: Value[]) => void;
86
- /** like the Array.prototype.unshift() method */
87
- unshift: (...values: Value[]) => void;
88
- /** like the Array.prototype.filter() method, but callback is optional - (it) => !!it */
89
- filter: (filter?: (value: Value, index: number, array: Value[]) => any) => void;
90
- };
91
-
92
- export type DefaultActions<Value> = Value extends Set<infer Val>
93
- ? SetActions<Val>
94
- : Value extends boolean
95
- ? BooleanActions
96
- : Value extends (infer Val)[]
97
- ? ArrayActions<Val>
98
- : Value extends number
99
- ? NumberActions<Value>
100
- : Value extends object
101
- ? ObjectActions<Value>
102
- : {};
103
-
104
- declare class Atom<Value, Actions extends Record<string, Function> = {}> {
105
- constructor(initialValue: Value, storeKeyOrOptions: StoreKeyOrOptions<Value, Actions> | undefined);
106
-
107
- /** initial value */
108
- readonly initialValue: Value;
109
- /** get current value */
110
- readonly get: () => Value;
111
- /** set current value */
112
- readonly set: AtomSetMethod<Value>;
113
- /** set current value with debounce */
114
- readonly setDeferred: AtomSetDeferredMethod<Value>;
115
- /** set current value as default (initial) */
116
- readonly reset: () => void;
117
- /** subscribe on value changes */
118
- readonly subscribe: AtomSubscribeMethod<Value>;
119
- /** your custom actions */
120
- readonly do: Actions & DefaultActions<Value>;
121
- /** check is current value not changed */
122
- readonly isInitialValue: () => boolean;
123
- }
124
-
125
- export function useAtom<Value>(atom: Atom<Value>): [Value, AtomSetMethod<Value>];
126
-
127
- /** observable atom value */
128
- export function useAtomValue<Value>(atom: Atom<Value>): Value;
129
-
130
- export function useAtomSet<Value>(atom: Atom<Value>): AtomSetMethod<Value>;
131
- export function useAtomSetDeferred<Value>(atom: Atom<Value>): AtomSetDeferredMethod<Value>;
132
- export function useAtomGet<Value>(atom: Atom<Value>): () => Value;
133
-
134
- /** get your custom actions */
135
- export function useAtomDo<Value, Actions extends Record<string, Function> = {}>(
136
- atom: Atom<Value, Actions>,
137
- ): Actions & DefaultActions<Value>;
138
-
139
- export type StoreKeyOrOptions<Value, Actions extends Record<string, Function> = {}> =
140
- | AtomStoreKey
141
- | AtomOptions<Value, Actions>;
142
-
143
- export function atom<Value, Actions extends Record<string, Function> = {}>(
144
- value: Value,
145
- storeKeyOrOptions?: StoreKeyOrOptions<Value, Actions>,
146
- ): Atom<Value, Actions>;
147
-
148
- /** invoke this function before all atom usages */
149
- export function configureAtomaric(options: { useSyncExternalStore: typeof useSyncExternalStore }): void;
1
+ import { useSyncExternalStore } from 'react';
2
+ import { Path, PathValue } from '../src/model';
3
+
4
+ type Sunscriber<Value> = (value: Value) => void;
5
+
6
+ export type AtomStoreKey = `${string}${string}:${string}${string}`;
7
+
8
+ export type AtomOptions<Value, Actions extends Record<string, Function> = {}> = {
9
+ /** **default: true** */
10
+ warnOnDuplicateStoreKey?: boolean;
11
+ /** will update value if localStorage value is changed
12
+ * **default: true**
13
+ */
14
+ listenStorageChanges?: boolean;
15
+
16
+ /** zip Value to stringifiable value */
17
+ zipValue?: (value: Value) => any;
18
+ /** unzip stringifiable value to Value */
19
+ unzipValue?: (packedValue: any) => Value;
20
+
21
+ /** make your localStorage value unchangable */
22
+ unchangable?: true;
23
+ /** return value expire Date */
24
+ exp?: (self: Atom<Value>, isValueWasStoraged: boolean) => Date;
25
+ } & (
26
+ | {
27
+ /** save in localStorage by this key */
28
+ storeKey: AtomStoreKey;
29
+ }
30
+ | {
31
+ /** declare your custom actions */
32
+ do: (
33
+ set: (value: Value | ((value: Value) => Value), isPreventSave?: boolean) => void,
34
+ get: () => Value,
35
+ self: Atom<Value>,
36
+ setDeferred: (value: Value | ((value: Value) => Value), debounceMs?: number, isPreventSave?: boolean) => void,
37
+ ) => Actions;
38
+ }
39
+ );
40
+
41
+ export type AtomSetMethod<Value> = (value: Value | ((prev: Value) => Value), isPreventSave?: boolean) => void;
42
+ export type AtomSetDeferredMethod<Value> = (
43
+ value: Value | ((prev: Value) => Value),
44
+ debounceMs?: number,
45
+ isPreventSave?: boolean,
46
+ isInitInvoke?: boolean,
47
+ ) => void;
48
+
49
+ export type AtomSubscribeMethod<Value> = (subscriber: Sunscriber<Value>) => () => void;
50
+
51
+ export type UpdateAction<Value> = {
52
+ /** transform current taken value */
53
+ update: (updater: (value: Value) => void) => void;
54
+ };
55
+
56
+ export type NumberActions<Value> = {
57
+ /** pass the 2 to increment on 2, pass the -2 to decrement on 2
58
+ * **default: 1**
59
+ */
60
+ increment: (delta?: number) => void;
61
+ };
62
+
63
+ export type ObjectActions<Value> = UpdateAction<Value> & {
64
+ /** pass partial object to update some field values */
65
+ setPartial: (value: Partial<Value> | ((value: Value) => Partial<Value>)) => void;
66
+ /** pass partial value to update some deep values by flat path */
67
+ setDeepPartial: <
68
+ ValuePath extends Path<Value, Sep>,
69
+ Val extends PathValue<Value, Sep, ValuePath>,
70
+ Sep extends string = '.',
71
+ >(
72
+ path: ValuePath,
73
+ value: Partial<Val> | ((value: Val) => Partial<Val>),
74
+ separator?: Sep,
75
+ ) => void;
76
+ };
77
+
78
+ export type BooleanActions = {
79
+ /** toggle current value between true/false */
80
+ toggle: () => void;
81
+ };
82
+
83
+ export type SetActions<Value> = UpdateAction<Value> & {
84
+ /** like the Set.prototype.add() method */
85
+ add: (value: Value) => void;
86
+ /** like the Set.prototype.delete() method */
87
+ delete: (value: Value) => void;
88
+ /** will add value if it doesn't exist, otherwise delete */
89
+ toggle: (value: Value) => void;
90
+ /** like the Set.prototype.clear() method */
91
+ clear: () => void;
92
+ };
93
+
94
+ export type ArrayActions<Value> = UpdateAction<Value[]> & {
95
+ /** like the Array.prototype.push() method */
96
+ push: (...values: Value[]) => void;
97
+ /** like the Array.prototype.unshift() method */
98
+ unshift: (...values: Value[]) => void;
99
+ /** like the Array.prototype.filter() method, but callback is optional - (it) => !!it */
100
+ filter: (filter?: (value: Value, index: number, array: Value[]) => any) => void;
101
+ /** will add value if it doesn't exist, otherwise delete */
102
+ toggle: (value: Value, isAddInStart?: boolean) => void;
103
+ };
104
+
105
+ export type DefaultActions<Value> = Value extends Set<infer Val>
106
+ ? SetActions<Val>
107
+ : Value extends boolean
108
+ ? BooleanActions
109
+ : Value extends (infer Val)[]
110
+ ? ArrayActions<Val>
111
+ : Value extends number
112
+ ? NumberActions<Value>
113
+ : Value extends object
114
+ ? ObjectActions<Value>
115
+ : {};
116
+
117
+ declare class Atom<Value, Actions extends Record<string, Function> = {}> {
118
+ constructor(initialValue: Value, storeKeyOrOptions: StoreKeyOrOptions<Value, Actions> | undefined);
119
+
120
+ /** initial value */
121
+ readonly initialValue: Value;
122
+ /** get current value */
123
+ readonly get: () => Value;
124
+ /** set current value */
125
+ readonly set: AtomSetMethod<Value>;
126
+ /** set current value with debounce */
127
+ readonly setDeferred: AtomSetDeferredMethod<Value>;
128
+ /** set current value as default (initial) */
129
+ readonly reset: () => void;
130
+ /** subscribe on value changes */
131
+ readonly subscribe: AtomSubscribeMethod<Value>;
132
+ /** your custom actions */
133
+ readonly do: Actions & DefaultActions<Value>;
134
+ /** check is current value not changed */
135
+ readonly isInitialValue: () => boolean;
136
+ }
137
+
138
+ export function useAtom<Value>(atom: Atom<Value>): [Value, AtomSetMethod<Value>];
139
+
140
+ /** observable atom value */
141
+ export function useAtomValue<Value>(atom: Atom<Value>): Value;
142
+
143
+ export function useAtomSet<Value>(atom: Atom<Value>): AtomSetMethod<Value>;
144
+ export function useAtomSetDeferred<Value>(atom: Atom<Value>): AtomSetDeferredMethod<Value>;
145
+ export function useAtomGet<Value>(atom: Atom<Value>): () => Value;
146
+
147
+ /** get your custom actions */
148
+ export function useAtomDo<Value, Actions extends Record<string, Function> = {}>(
149
+ atom: Atom<Value, Actions>,
150
+ ): Actions & DefaultActions<Value>;
151
+
152
+ export type StoreKeyOrOptions<Value, Actions extends Record<string, Function> = {}> =
153
+ | AtomStoreKey
154
+ | AtomOptions<Value, Actions>;
155
+
156
+ export function atom<Value, Actions extends Record<string, Function> = {}>(
157
+ value: Value,
158
+ storeKeyOrOptions?: StoreKeyOrOptions<Value, Actions>,
159
+ ): Atom<Value, Actions>;
160
+
161
+ /** invoke this function before all atom usages */
162
+ export function configureAtomaric(options: { useSyncExternalStore: typeof useSyncExternalStore }): void;