atomaric 0.0.28 → 0.0.31

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,216 @@
1
- const P = (n, e, c) => {
2
- let u = null;
3
- typeof n == "number" ? u = p(
4
- {
5
- increment: (s) => {
6
- e.set(+e.get() + (s ?? 0));
1
+ const R = (e, n, l) => {
2
+ let f = null;
3
+ typeof e == "number" ? f = T(
4
+ n,
5
+ (s) => ({
6
+ increment: (r) => {
7
+ s.set(+s.get() + (r ?? 0));
7
8
  }
8
- }
9
- ) : typeof n == "boolean" ? u = p(
10
- {
9
+ })
10
+ ) : typeof e == "boolean" ? f = T(
11
+ n,
12
+ (s) => ({
11
13
  toggle: () => {
12
- e.set(!e.get());
14
+ s.set(!s.get());
13
15
  }
14
- }
15
- ) : Array.isArray(n) ? u = p(
16
- {
17
- push: (...s) => {
18
- e.set(e.get().concat(s));
16
+ })
17
+ ) : Array.isArray(e) ? f = T(
18
+ n,
19
+ (s) => ({
20
+ push: (...r) => {
21
+ s.set(s.get().concat(r));
19
22
  },
20
- unshift: (...s) => {
21
- e.set(s.concat(e.get()));
23
+ unshift: (...r) => {
24
+ s.set(r.concat(s.get()));
22
25
  },
23
- update: (s) => {
24
- const r = e.get().slice();
25
- s(r), e.set(r);
26
+ update: (r) => {
27
+ const c = s.get().slice();
28
+ r(c), s.set(c);
26
29
  },
27
- filter: (s) => {
28
- e.set(e.get().filter(s ?? V));
30
+ filter: (r) => {
31
+ s.set(s.get().filter(r ?? B));
32
+ },
33
+ toggle: (r, c) => {
34
+ const w = s.get().slice(), d = w.indexOf(r);
35
+ d < 0 ? c ? w.unshift(r) : w.push(r) : w.splice(d, 1), s.set(w);
29
36
  }
30
- }
31
- ) : n instanceof Set ? u = p(
32
- {
33
- add: (s) => {
34
- e.set(new Set(e.get()).add(s));
37
+ })
38
+ ) : e instanceof Set ? f = T(
39
+ n,
40
+ (s) => ({
41
+ add: (r) => {
42
+ s.set(new Set(s.get()).add(r));
35
43
  },
36
- delete: (s) => {
37
- const r = new Set(e.get());
38
- r.delete(s), e.set(r);
44
+ delete: (r) => {
45
+ const c = new Set(s.get());
46
+ c.delete(r), 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: (r) => {
49
+ const c = new Set(s.get());
50
+ c.has(r) ? c.delete(r) : c.add(r), s.set(c);
43
51
  },
44
52
  clear: () => {
45
- e.set(/* @__PURE__ */ new Set());
53
+ s.set(/* @__PURE__ */ new Set());
46
54
  },
47
- update: (s) => {
48
- const r = new Set(e.get());
49
- s(r), e.set(r);
55
+ update: (r) => {
56
+ const c = new Set(s.get());
57
+ r(c), s.set(c);
58
+ }
59
+ })
60
+ ) : e instanceof Object && (f = T(
61
+ n,
62
+ (s) => ({
63
+ setPartial: (r) => s.set((c) => ({
64
+ ...c,
65
+ ...typeof r == "function" ? r(s.get()) : r
66
+ })),
67
+ update: (r) => {
68
+ const c = { ...s.get() };
69
+ r(c), s.set(c);
50
70
  }
51
- }
52
- ) : n instanceof Object && (u = p(
53
- {
54
- setPartial: (s) => e.set((r) => ({
55
- ...r,
56
- ...typeof s == "function" ? s(e.get()) : s
57
- }))
58
- }
71
+ })
59
72
  ));
60
- const f = typeof c == "object" && c != null && "do" in c ? c.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] })), u && Object.keys(u).forEach(
67
- (s) => Object.defineProperty(d, s, { get: () => u[s] })
68
- ), d;
69
- }, V = (n) => n, p = (n, e) => n;
70
- class H {
71
- constructor(e, c) {
72
- const u = (t) => r = t, f = () => r, d = /* @__PURE__ */ new Set(), s = (t) => t(S());
73
- let r = e, w, $ = () => {
74
- }, S = () => f(), g = null, k = () => {
75
- const t = P(e, _, c);
76
- return k = () => t, t;
73
+ const a = typeof l == "object" && l != null && "do" in l ? l.do(
74
+ (s, r) => n.set(s, r),
75
+ () => n.get(),
76
+ n,
77
+ (s, r, c) => n.setDeferred(s, r, c)
78
+ ) : null, h = {};
79
+ return a && Object.keys(a).forEach((s) => Object.defineProperty(h, s, { get: () => a[s] })), f && Object.keys(f).forEach(
80
+ (s) => Object.defineProperty(h, s, { get: () => f[s] })
81
+ ), h;
82
+ }, B = (e) => e, T = (e, n, l) => n(e);
83
+ class G {
84
+ constructor(n, l) {
85
+ const f = (t) => r = t, a = () => r, h = /* @__PURE__ */ new Set(), s = (t) => t(d());
86
+ let r = n, c, w = () => {
87
+ }, d = () => a(), b = null, N = () => {
88
+ const t = R(n, S, l);
89
+ return N = () => t, t;
77
90
  };
78
- const _ = new Proxy(this, {
79
- get: (t, l) => l === "do" ? k() : t[l],
80
- set: L
81
- }), b = (t, l) => {
82
- const a = typeof t == "function" ? t(S()) : t;
83
- if (!(a === S() || a === void 0 || typeof a == "number" && isNaN(a))) {
84
- u(a), d.forEach(s, this);
91
+ const S = new Proxy(this, {
92
+ get: (t, u) => u === "do" ? N() : t[u],
93
+ set: U
94
+ }), A = (t, u) => {
95
+ const g = typeof t == "function" ? t(d()) : t;
96
+ if (!(g === d() || g === void 0 || typeof g == "number" && isNaN(g))) {
97
+ f(g), h.forEach(s, this);
85
98
  try {
86
- C.postMessage({ key: i, value: f() });
99
+ C.postMessage({ key: i, value: a() });
87
100
  } catch {
88
101
  }
89
- l !== !0 && $(a);
102
+ u !== !0 && w(g);
90
103
  }
91
104
  };
92
- this.set = (t, l) => b(t, l), this.get = () => S(), this.initialValue = e, this.isInitialValue = () => e === f(), this.subscribe = (t) => (d.add(t), () => {
93
- d.delete(t);
105
+ this.set = (t, u) => A(t, u), this.get = () => d(), this.initialValue = n, this.isInitialValue = () => n === a(), this.subscribe = (t) => (h.add(t), () => {
106
+ h.delete(t);
94
107
  }), this.reset = () => {
95
- b(e, !0), d.forEach(s, this);
108
+ A(n, !0), h.forEach(s, this);
96
109
  };
97
- const J = (t, l) => {
98
- b(t, l), w = void 0;
110
+ const M = (t, u) => {
111
+ A(t, u), c = void 0;
99
112
  };
100
- if (this.setDeferred = (t, l = 500, a, z = !0) => {
101
- z && w === void 0 && b(t, a), clearTimeout(w), w = setTimeout(J, l, t, a);
102
- }, c == null) return _;
103
- let h = null, y = null, I = !0, x = !0, j = !1, E = e instanceof Set ? (t) => new Set(t) : (t) => t, m = e instanceof Set ? (t) => {
113
+ if (this.setDeferred = (t, u = 500, g, J = !0) => {
114
+ J && c === void 0 && A(t, g), clearTimeout(c), c = setTimeout(M, u, t, g);
115
+ }, l == null) return S;
116
+ let p = null, x = null, D = !0, I = !0, j = !1, z = -1, E = n instanceof Set ? (t) => new Set(t) : (t) => t, _ = n instanceof Set ? (t) => {
104
117
  if (t instanceof Set) return Array.from(t);
105
118
  throw console.error(t), "The value is not Set instance";
106
119
  } : (t) => t;
107
- if (typeof c == "string")
108
- h = c;
109
- else if ("storeKey" in c)
110
- I = c.warnOnDuplicateStoreKey ?? I, x = c.listenStorageChanges ?? x, h = c.storeKey, E = c.unzipValue ?? E, m = c.zipValue ?? m, j = c.unchangable ?? j, y = c.exp ?? y;
111
- else return _;
112
- const v = y === null || !(y() instanceof Date) ? (t) => JSON.stringify([m(t)]) : (t) => (g ?? (g = {}), g.exp = y().getTime(), JSON.stringify([m(t), g])), T = (t) => {
113
- const l = JSON.parse(t);
114
- return g = l[1], g != null && g.exp != null && g.exp < Date.now() ? (this.reset(), e) : E(l[0]);
115
- }, i = `atom\\${h}`;
116
- let N = !0;
117
- if (o[`atom/${h}`] && (this.set(T(`[${o[`atom/${h}`]}]`)), delete o[`atom/${h}`]), S = () => {
118
- if (S = f, N) {
119
- N = !1;
120
+ if (typeof l == "string")
121
+ p = l;
122
+ else if ("storeKey" in l)
123
+ D = l.warnOnDuplicateStoreKey ?? D, I = l.listenStorageChanges ?? I, p = l.storeKey, E = l.unzipValue ?? E, _ = l.zipValue ?? _, j = l.unchangable ?? j, x = l.exp ?? x;
124
+ else return S;
125
+ const i = `${P}${p}`, V = x === null || !(x(S, i in o) instanceof Date) ? (t) => JSON.stringify([_(t)]) : (t) => (b ?? (b = {}), b.exp = x(S, i in o).getTime() + 0.2866, b.exp - Date.now() < 24 * 60 * 60 * 1e3 && (clearTimeout(z), clearTimeout(H[i]), z = setTimeout(() => this.reset(), b.exp - Date.now())), JSON.stringify([_(t), b])), v = (t) => {
126
+ const u = JSON.parse(t);
127
+ return b = u[1], E(u[0]);
128
+ };
129
+ let F = !0;
130
+ if ($[i] = S, o[`atom/${p}`] && (o[i] || (o[i] = `[${o[`atom/${p}`]}]`), delete o[`atom/${p}`]), d = () => {
131
+ if (d = a, F) {
132
+ F = !1;
120
133
  try {
121
- u(i in o ? T(o[i]) : e);
134
+ f(i in o ? v(o[i]) : n);
122
135
  } catch {
123
136
  console.warn("Invalid json value", o[i]);
124
137
  }
125
138
  }
126
- return f();
127
- }, $ = (t) => {
128
- if (t === e) {
139
+ return a();
140
+ }, w = (t) => {
141
+ if (t === n) {
129
142
  this.reset();
130
143
  return;
131
144
  }
132
- o[i] = v(t);
145
+ o[i] = V(t);
133
146
  }, this.reset = () => {
134
- delete o[i], b(e, !0);
135
- }, I && A[i] !== void 0 && console.warn("Duplicate Atom key", h), x)
147
+ delete o[i], A(n, !0);
148
+ }, D && m[i] !== void 0 && console.warn("Duplicate Atom key", p), I)
136
149
  if (j) {
137
- let t = !1, l;
138
- D[i] = this, A[i] = () => {
139
- clearTimeout(l), l = setTimeout(() => t = !1, 10), !t && (t = !0, o[i] = v(f()));
150
+ let t = !1, u;
151
+ y[i] = this, m[i] = () => {
152
+ clearTimeout(u), u = setTimeout(() => t = !1, 10), !t && (t = !0, o[i] = V(a()));
140
153
  };
141
154
  } else
142
- A[i] = (t) => {
155
+ m[i] = (t) => {
143
156
  if (t.newValue === null) {
144
157
  this.reset();
145
158
  return;
146
159
  }
147
160
  try {
148
- b(T(t.newValue));
161
+ A(v(t.newValue));
149
162
  } catch {
150
163
  console.warn("Invalid json value", t.newValue);
151
164
  }
152
165
  };
153
- return _;
166
+ return S;
154
167
  }
155
168
  }
156
169
  let C;
157
170
  try {
158
- C = new BroadcastChannel("updateHere"), C.addEventListener("message", (n) => {
159
- var e;
160
- (e = D[n.data.key]) == null || e.set(n.data.value, !0);
171
+ C = new BroadcastChannel("updateHere"), C.addEventListener("message", (e) => {
172
+ var n;
173
+ (n = y[e.data.key]) == null || n.set(e.data.value, !0);
161
174
  });
162
175
  } catch {
163
176
  }
164
- const o = window.localStorage, A = {}, D = {}, L = (n, e) => {
165
- throw `${e} is readonly property`;
177
+ const o = window.localStorage, m = {}, y = {}, U = (e, n) => {
178
+ throw `${n} is readonly property`;
166
179
  };
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);
180
+ window.addEventListener("storage", (e) => {
181
+ var n;
182
+ e.key === null || e.newValue === e.oldValue || (n = m[e.key]) == null || n.call(m, e);
170
183
  });
171
- const B = o.setItem.bind(o), G = o.removeItem.bind(o);
172
- o.setItem = (n, e) => {
173
- D[n] === void 0 && B.call(o, n, e);
184
+ const W = o.setItem.bind(o), q = o.removeItem.bind(o);
185
+ o.setItem = (e, n) => {
186
+ y[e] === void 0 && W.call(o, e, n);
174
187
  };
175
- o.removeItem = (n) => {
176
- D[n] === void 0 && G.call(o, n);
188
+ o.removeItem = (e) => {
189
+ y[e] === void 0 && q.call(o, e);
177
190
  };
178
- let F = () => {
191
+ const Q = /"exp":(\d+)\.2866/, P = "atom\\", $ = {}, H = {};
192
+ setTimeout(() => {
193
+ Object.keys(o).forEach((e) => {
194
+ var l;
195
+ if (!e.startsWith(P) || typeof o[e] != "string") return;
196
+ const n = +((l = o[e].match(Q)) == null ? void 0 : l[1]);
197
+ n && n - Date.now() < 24 * 60 * 60 * 1e3 && (H[e] = setTimeout(() => {
198
+ $[e] ? $[e].reset() : delete o[e];
199
+ }, n - Date.now()));
200
+ });
201
+ }, 1e3);
202
+ let L = () => {
179
203
  throw "call configureAtomaric() before all!";
180
204
  };
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);
205
+ const Z = (e) => L = e.useSyncExternalStore, X = (e) => L(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, n) => new G(e, n);
182
206
  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
207
+ G as Atom,
208
+ te as atom,
209
+ Z as configureAtomaric,
210
+ ee as useAtom,
211
+ O as useAtomDo,
212
+ K as useAtomGet,
213
+ Y as useAtomSet,
214
+ k as useAtomSetDeferred,
215
+ X as useAtomValue
192
216
  };
@@ -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,c)=>{let i=null;typeof n=="number"?i=p({increment:s=>{e.set(+e.get()+(s??0))}}):typeof n=="boolean"?i=p({toggle:()=>{e.set(!e.get())}}):Array.isArray(n)?i=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?i=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&&(i=p({setPartial:s=>e.set(r=>({...r,...typeof s=="function"?s(e.get()):s}))}));const a=typeof c=="object"&&c!=null&&"do"in c?c.do((s,r)=>e.set(s,r),()=>e.get(),e,(s,r,A)=>e.setDeferred(s,r,A)):null,g={};return a&&Object.keys(a).forEach(s=>Object.defineProperty(g,s,{get:()=>a[s]})),i&&Object.keys(i).forEach(s=>Object.defineProperty(g,s,{get:()=>i[s]})),g},L=n=>n,p=(n,e)=>n;class N{constructor(e,c){const i=t=>r=t,a=()=>r,g=new Set,s=t=>t(b());let r=e,A,x=()=>{},b=()=>a(),h=null,F=()=>{const t=y(e,I,c);return F=()=>t,t};const I=new Proxy(this,{get:(t,l)=>l==="do"?F():t[l],set:M}),m=(t,l)=>{const d=typeof t=="function"?t(b()):t;if(!(d===b()||d===void 0||typeof d=="number"&&isNaN(d))){i(d),g.forEach(s,this);try{j.postMessage({key:f,value:a()})}catch{}l!==!0&&x(d)}};this.set=(t,l)=>m(t,l),this.get=()=>b(),this.initialValue=e,this.isInitialValue=()=>e===a(),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,d,H=!0)=>{H&&A===void 0&&m(t,d),clearTimeout(A),A=setTimeout(Z,l,t,d)},c==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 c=="string")S=c;else if("storeKey"in c)E=c.warnOnDuplicateStoreKey??E,C=c.listenStorageChanges??C,S=c.storeKey,$=c.unzipValue??$,T=c.zipValue??T,v=c.unchangable??v,_=c.exp??_;else return I;const J=_===null||!(_()instanceof Date)?t=>JSON.stringify([T(t)]):t=>(h??(h={}),h.exp=_().getTime(),JSON.stringify([T(t),h])),k=t=>{const l=JSON.parse(t);return h=l[1],h!=null&&h.exp!=null&&h.exp<Date.now()?(this.reset(),e):$(l[0])},f=`atom\\${S}`;let G=!0;if(o[`atom/${S}`]&&(this.set(k(`[${o[`atom/${S}`]}]`)),delete o[`atom/${S}`]),b=()=>{if(b=a,G){G=!1;try{i(f in o?k(o[f]):e)}catch{console.warn("Invalid json value",o[f])}}return a()},x=t=>{if(t===e){this.reset();return}o[f]=J(t)},this.reset=()=>{delete o[f],m(e,!0)},E&&w[f]!==void 0&&console.warn("Duplicate Atom key",S),C)if(v){let t=!1,l;D[f]=this,w[f]=()=>{clearTimeout(l),l=setTimeout(()=>t=!1,10),!t&&(t=!0,o[f]=J(a()))}}else w[f]=t=>{if(t.newValue===null){this.reset();return}try{m(k(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 o=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=o.setItem.bind(o),U=o.removeItem.bind(o);o.setItem=(n,e)=>{D[n]===void 0&&B.call(o,n,e)},o.removeItem=n=>{D[n]===void 0&&U.call(o,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(f,T){typeof exports=="object"&&typeof module<"u"?T(exports):typeof define=="function"&&define.amd?define(["exports"],T):(f=typeof globalThis<"u"?globalThis:f||self,T(f.atomaric={}))})(this,function(f){"use strict";const T=(e,s,i)=>{let d=null;typeof e=="number"?d=D(s,n=>({increment:r=>{n.set(+n.get()+(r??0))}})):typeof e=="boolean"?d=D(s,n=>({toggle:()=>{n.set(!n.get())}})):Array.isArray(e)?d=D(s,n=>({push:(...r)=>{n.set(n.get().concat(r))},unshift:(...r)=>{n.set(r.concat(n.get()))},update:r=>{const o=n.get().slice();r(o),n.set(o)},filter:r=>{n.set(n.get().filter(r??W))},toggle:(r,o)=>{const S=n.get().slice(),g=S.indexOf(r);g<0?o?S.unshift(r):S.push(r):S.splice(g,1),n.set(S)}})):e instanceof Set?d=D(s,n=>({add:r=>{n.set(new Set(n.get()).add(r))},delete:r=>{const o=new Set(n.get());o.delete(r),n.set(o)},toggle:r=>{const o=new Set(n.get());o.has(r)?o.delete(r):o.add(r),n.set(o)},clear:()=>{n.set(new Set)},update:r=>{const o=new Set(n.get());r(o),n.set(o)}})):e instanceof Object&&(d=D(s,n=>({setPartial:r=>n.set(o=>({...o,...typeof r=="function"?r(n.get()):r})),update:r=>{const o={...n.get()};r(o),n.set(o)}})));const a=typeof i=="object"&&i!=null&&"do"in i?i.do((n,r)=>s.set(n,r),()=>s.get(),s,(n,r,o)=>s.setDeferred(n,r,o)):null,w={};return a&&Object.keys(a).forEach(n=>Object.defineProperty(w,n,{get:()=>a[n]})),d&&Object.keys(d).forEach(n=>Object.defineProperty(w,n,{get:()=>d[n]})),w},W=e=>e,D=(e,s,i)=>s(e);class v{constructor(s,i){const d=t=>r=t,a=()=>r,w=new Set,n=t=>t(g());let r=s,o,S=()=>{},g=()=>a(),p=null,G=()=>{const t=T(s,A,i);return G=()=>t,t};const A=new Proxy(this,{get:(t,u)=>u==="do"?G():t[u],set:q}),y=(t,u)=>{const h=typeof t=="function"?t(g()):t;if(!(h===g()||h===void 0||typeof h=="number"&&isNaN(h))){d(h),w.forEach(n,this);try{x.postMessage({key:l,value:a()})}catch{}u!==!0&&S(h)}};this.set=(t,u)=>y(t,u),this.get=()=>g(),this.initialValue=s,this.isInitialValue=()=>s===a(),this.subscribe=t=>(w.add(t),()=>{w.delete(t)}),this.reset=()=>{y(s,!0),w.forEach(n,this)};const ne=(t,u)=>{y(t,u),o=void 0};if(this.setDeferred=(t,u=500,h,U=!0)=>{U&&o===void 0&&y(t,h),clearTimeout(o),o=setTimeout(ne,u,t,h)},i==null)return A;let m=null,_=null,C=!0,$=!0,N=!1,H=-1,V=s instanceof Set?t=>new Set(t):t=>t,I=s 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")m=i;else if("storeKey"in i)C=i.warnOnDuplicateStoreKey??C,$=i.listenStorageChanges??$,m=i.storeKey,V=i.unzipValue??V,I=i.zipValue??I,N=i.unchangable??N,_=i.exp??_;else return A;const l=`${z}${m}`,L=_===null||!(_(A,l in c)instanceof Date)?t=>JSON.stringify([I(t)]):t=>(p??(p={}),p.exp=_(A,l in c).getTime()+.2866,p.exp-Date.now()<24*60*60*1e3&&(clearTimeout(H),clearTimeout(P[l]),H=setTimeout(()=>this.reset(),p.exp-Date.now())),JSON.stringify([I(t),p])),R=t=>{const u=JSON.parse(t);return p=u[1],V(u[0])};let B=!0;if(E[l]=A,c[`atom/${m}`]&&(c[l]||(c[l]=`[${c[`atom/${m}`]}]`),delete c[`atom/${m}`]),g=()=>{if(g=a,B){B=!1;try{d(l in c?R(c[l]):s)}catch{console.warn("Invalid json value",c[l])}}return a()},S=t=>{if(t===s){this.reset();return}c[l]=L(t)},this.reset=()=>{delete c[l],y(s,!0)},C&&b[l]!==void 0&&console.warn("Duplicate Atom key",m),$)if(N){let t=!1,u;j[l]=this,b[l]=()=>{clearTimeout(u),u=setTimeout(()=>t=!1,10),!t&&(t=!0,c[l]=L(a()))}}else b[l]=t=>{if(t.newValue===null){this.reset();return}try{y(R(t.newValue))}catch{console.warn("Invalid json value",t.newValue)}};return A}}let x;try{x=new BroadcastChannel("updateHere"),x.addEventListener("message",e=>{var s;(s=j[e.data.key])==null||s.set(e.data.value,!0)})}catch{}const c=window.localStorage,b={},j={},q=(e,s)=>{throw`${s} is readonly property`};window.addEventListener("storage",e=>{var s;e.key===null||e.newValue===e.oldValue||(s=b[e.key])==null||s.call(b,e)});const Q=c.setItem.bind(c),X=c.removeItem.bind(c);c.setItem=(e,s)=>{j[e]===void 0&&Q.call(c,e,s)},c.removeItem=e=>{j[e]===void 0&&X.call(c,e)};const Y=/"exp":(\d+)\.2866/,z="atom\\",E={},P={};setTimeout(()=>{Object.keys(c).forEach(e=>{var i;if(!e.startsWith(z)||typeof c[e]!="string")return;const s=+((i=c[e].match(Y))==null?void 0:i[1]);s&&s-Date.now()<24*60*60*1e3&&(P[e]=setTimeout(()=>{E[e]?E[e].reset():delete c[e]},s-Date.now()))})},1e3);let F=()=>{throw"call configureAtomaric() before all!"};const Z=e=>F=e.useSyncExternalStore,J=e=>F(e.subscribe,e.get),M=e=>e.set,k=e=>e.setDeferred,K=e=>e.get,O=e=>e.do,ee=e=>[J(e),M(e)],te=(e,s)=>new v(e,s);f.Atom=v,f.atom=te,f.configureAtomaric=Z,f.useAtom=ee,f.useAtomDo=O,f.useAtomGet=K,f.useAtomSet=M,f.useAtomSetDeferred=k,f.useAtomValue=J,Object.defineProperty(f,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.28",
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
- "dev": "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.31",
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,151 @@
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
+
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?: (self: Atom<Value>, isValueWasStoraged: boolean) => 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> = UpdateAction<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
+ /** will add value if it doesn't exist, otherwise delete */
91
+ toggle: (value: Value, isAddInStart?: boolean) => void;
92
+ };
93
+
94
+ export type DefaultActions<Value> = Value extends Set<infer Val>
95
+ ? SetActions<Val>
96
+ : Value extends boolean
97
+ ? BooleanActions
98
+ : Value extends (infer Val)[]
99
+ ? ArrayActions<Val>
100
+ : Value extends number
101
+ ? NumberActions<Value>
102
+ : Value extends object
103
+ ? ObjectActions<Value>
104
+ : {};
105
+
106
+ declare class Atom<Value, Actions extends Record<string, Function> = {}> {
107
+ constructor(initialValue: Value, storeKeyOrOptions: StoreKeyOrOptions<Value, Actions> | undefined);
108
+
109
+ /** initial value */
110
+ readonly initialValue: Value;
111
+ /** get current value */
112
+ readonly get: () => Value;
113
+ /** set current value */
114
+ readonly set: AtomSetMethod<Value>;
115
+ /** set current value with debounce */
116
+ readonly setDeferred: AtomSetDeferredMethod<Value>;
117
+ /** set current value as default (initial) */
118
+ readonly reset: () => void;
119
+ /** subscribe on value changes */
120
+ readonly subscribe: AtomSubscribeMethod<Value>;
121
+ /** your custom actions */
122
+ readonly do: Actions & DefaultActions<Value>;
123
+ /** check is current value not changed */
124
+ readonly isInitialValue: () => boolean;
125
+ }
126
+
127
+ export function useAtom<Value>(atom: Atom<Value>): [Value, AtomSetMethod<Value>];
128
+
129
+ /** observable atom value */
130
+ export function useAtomValue<Value>(atom: Atom<Value>): Value;
131
+
132
+ export function useAtomSet<Value>(atom: Atom<Value>): AtomSetMethod<Value>;
133
+ export function useAtomSetDeferred<Value>(atom: Atom<Value>): AtomSetDeferredMethod<Value>;
134
+ export function useAtomGet<Value>(atom: Atom<Value>): () => Value;
135
+
136
+ /** get your custom actions */
137
+ export function useAtomDo<Value, Actions extends Record<string, Function> = {}>(
138
+ atom: Atom<Value, Actions>,
139
+ ): Actions & DefaultActions<Value>;
140
+
141
+ export type StoreKeyOrOptions<Value, Actions extends Record<string, Function> = {}> =
142
+ | AtomStoreKey
143
+ | AtomOptions<Value, Actions>;
144
+
145
+ export function atom<Value, Actions extends Record<string, Function> = {}>(
146
+ value: Value,
147
+ storeKeyOrOptions?: StoreKeyOrOptions<Value, Actions>,
148
+ ): Atom<Value, Actions>;
149
+
150
+ /** invoke this function before all atom usages */
151
+ export function configureAtomaric(options: { useSyncExternalStore: typeof useSyncExternalStore }): void;