atomaric 0.0.31 → 0.0.33

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/build/atomaric.js CHANGED
@@ -1,208 +1,226 @@
1
- const R = (e, n, l) => {
2
- let f = null;
3
- typeof e == "number" ? f = T(
4
- n,
1
+ const v = (e, r, l) => {
2
+ let d = null;
3
+ typeof e == "number" ? d = _(
4
+ r,
5
5
  (s) => ({
6
- increment: (r) => {
7
- s.set(+s.get() + (r ?? 0));
6
+ increment: (n) => {
7
+ s.set(+s.get() + (n ?? 0));
8
8
  }
9
9
  })
10
- ) : typeof e == "boolean" ? f = T(
11
- n,
10
+ ) : typeof e == "boolean" ? d = _(
11
+ r,
12
12
  (s) => ({
13
13
  toggle: () => {
14
14
  s.set(!s.get());
15
15
  }
16
16
  })
17
- ) : Array.isArray(e) ? f = T(
18
- n,
17
+ ) : Array.isArray(e) ? d = _(
18
+ r,
19
19
  (s) => ({
20
- push: (...r) => {
21
- s.set(s.get().concat(r));
20
+ push: (...n) => {
21
+ s.set(s.get().concat(n));
22
22
  },
23
- unshift: (...r) => {
24
- s.set(r.concat(s.get()));
23
+ unshift: (...n) => {
24
+ s.set(n.concat(s.get()));
25
25
  },
26
- update: (r) => {
26
+ update: (n) => {
27
27
  const c = s.get().slice();
28
- r(c), s.set(c);
28
+ n(c), s.set(c);
29
29
  },
30
- filter: (r) => {
31
- s.set(s.get().filter(r ?? B));
30
+ filter: (n) => {
31
+ s.set(s.get().filter(n ?? B));
32
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);
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);
36
36
  }
37
37
  })
38
- ) : e instanceof Set ? f = T(
39
- n,
38
+ ) : e instanceof Set ? d = _(
39
+ r,
40
40
  (s) => ({
41
- add: (r) => {
42
- s.set(new Set(s.get()).add(r));
41
+ add: (n) => {
42
+ s.set(new Set(s.get()).add(n));
43
43
  },
44
- delete: (r) => {
44
+ delete: (n) => {
45
45
  const c = new Set(s.get());
46
- c.delete(r), s.set(c);
46
+ c.delete(n), s.set(c);
47
47
  },
48
- toggle: (r) => {
48
+ toggle: (n) => {
49
49
  const c = new Set(s.get());
50
- c.has(r) ? c.delete(r) : c.add(r), s.set(c);
50
+ c.has(n) ? c.delete(n) : c.add(n), s.set(c);
51
51
  },
52
52
  clear: () => {
53
53
  s.set(/* @__PURE__ */ new Set());
54
54
  },
55
- update: (r) => {
55
+ update: (n) => {
56
56
  const c = new Set(s.get());
57
- r(c), s.set(c);
57
+ n(c), s.set(c);
58
58
  }
59
59
  })
60
- ) : e instanceof Object && (f = T(
61
- n,
60
+ ) : e instanceof Object && (d = _(
61
+ r,
62
62
  (s) => ({
63
- setPartial: (r) => s.set((c) => ({
63
+ setPartial: (n) => s.set((c) => ({
64
64
  ...c,
65
- ...typeof r == "function" ? r(s.get()) : r
65
+ ...typeof n == "function" ? n(s.get()) : n
66
66
  })),
67
- update: (r) => {
67
+ update: (n) => {
68
68
  const c = { ...s.get() };
69
- r(c), s.set(c);
69
+ n(c), s.set(c);
70
+ },
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 });
70
88
  }
71
89
  })
72
90
  ));
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);
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);
83
101
  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;
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;
90
108
  };
91
- const S = new Proxy(this, {
92
- get: (t, u) => u === "do" ? N() : t[u],
109
+ const a = new Proxy(this, {
110
+ get: (t, u) => u === "do" ? D() : t[u],
93
111
  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);
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);
98
116
  try {
99
- C.postMessage({ key: i, value: a() });
117
+ P.postMessage({ key: i, value: h() });
100
118
  } catch {
101
119
  }
102
- u !== !0 && w(g);
120
+ u !== !0 && g(S);
103
121
  }
104
122
  };
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);
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);
107
125
  }), this.reset = () => {
108
- A(n, !0), h.forEach(s, this);
126
+ w(r, !0), b.forEach(s, this);
109
127
  };
110
- const M = (t, u) => {
111
- A(t, u), c = void 0;
128
+ const A = (t, u) => {
129
+ w(t, u), c = void 0;
112
130
  };
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) => {
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) => {
117
135
  if (t instanceof Set) return Array.from(t);
118
136
  throw console.error(t), "The value is not Set instance";
119
137
  } : (t) => t;
120
138
  if (typeof l == "string")
121
- p = l;
139
+ y = l;
122
140
  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) => {
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) => {
126
144
  const u = JSON.parse(t);
127
- return b = u[1], E(u[0]);
145
+ return p = u[1], $(u[0]);
128
146
  };
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;
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;
133
151
  try {
134
- f(i in o ? v(o[i]) : n);
152
+ d(i in o ? F(o[i]) : r);
135
153
  } catch {
136
154
  console.warn("Invalid json value", o[i]);
137
155
  }
138
156
  }
139
- return a();
140
- }, w = (t) => {
141
- if (t === n) {
157
+ return h();
158
+ }, g = (t) => {
159
+ if (t === r) {
142
160
  this.reset();
143
161
  return;
144
162
  }
145
163
  o[i] = V(t);
146
164
  }, this.reset = () => {
147
- delete o[i], A(n, !0);
148
- }, D && m[i] !== void 0 && console.warn("Duplicate Atom key", p), I)
149
- if (j) {
165
+ delete o[i], w(r, !0);
166
+ }, I && x[i] !== void 0 && console.warn("Duplicate Atom key", y), E)
167
+ if (C) {
150
168
  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()));
169
+ m[i] = this, x[i] = () => {
170
+ clearTimeout(u), u = setTimeout(() => t = !1, 10), !t && (t = !0, o[i] = V(h()));
153
171
  };
154
172
  } else
155
- m[i] = (t) => {
173
+ x[i] = (t) => {
156
174
  if (t.newValue === null) {
157
175
  this.reset();
158
176
  return;
159
177
  }
160
178
  try {
161
- A(v(t.newValue));
179
+ w(F(t.newValue));
162
180
  } catch {
163
181
  console.warn("Invalid json value", t.newValue);
164
182
  }
165
183
  };
166
- return S;
184
+ return a;
167
185
  }
168
186
  }
169
- let C;
187
+ let P;
170
188
  try {
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);
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);
174
192
  });
175
193
  } catch {
176
194
  }
177
- const o = window.localStorage, m = {}, y = {}, U = (e, n) => {
178
- throw `${n} is readonly property`;
195
+ const o = window.localStorage, x = {}, m = {}, U = (e, r) => {
196
+ throw `${r} is readonly property`;
179
197
  };
180
198
  window.addEventListener("storage", (e) => {
181
- var n;
182
- e.key === null || e.newValue === e.oldValue || (n = m[e.key]) == null || n.call(m, e);
199
+ var r;
200
+ e.key === null || e.newValue === e.oldValue || (r = x[e.key]) == null || r.call(x, e);
183
201
  });
184
202
  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);
203
+ o.setItem = (e, r) => {
204
+ m[e] === void 0 && W.call(o, e, r);
187
205
  };
188
206
  o.removeItem = (e) => {
189
- y[e] === void 0 && q.call(o, e);
207
+ m[e] === void 0 && q.call(o, e);
190
208
  };
191
- const Q = /"exp":(\d+)\.2866/, P = "atom\\", $ = {}, H = {};
209
+ const Q = /"exp":(\d+)\.2866/, L = "atom\\", N = {}, M = {};
192
210
  setTimeout(() => {
193
211
  Object.keys(o).forEach((e) => {
194
212
  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()));
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()));
200
218
  });
201
219
  }, 1e3);
202
- let L = () => {
220
+ let R = () => {
203
221
  throw "call configureAtomaric() before all!";
204
222
  };
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);
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);
206
224
  export {
207
225
  G as Atom,
208
226
  te as atom,
@@ -1 +1 @@
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"})});
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,7 +1,7 @@
1
1
  {
2
2
  "name": "atomaric",
3
3
  "description": "Manage your project state",
4
- "version": "0.0.31",
4
+ "version": "0.0.33",
5
5
  "type": "module",
6
6
  "main": "./build/atomaric.umd.cjs",
7
7
  "module": "./build/atomaric.js",
package/types/model.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { useSyncExternalStore } from 'react';
2
+ import { Path, PathValue } from './paths';
2
3
 
3
4
  type Sunscriber<Value> = (value: Value) => void;
4
5
 
@@ -60,8 +61,18 @@ export type NumberActions<Value> = {
60
61
  };
61
62
 
62
63
  export type ObjectActions<Value> = UpdateAction<Value> & {
63
- /** pass partial object to update some fields */
64
+ /** pass partial object to update some field values */
64
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;
65
76
  };
66
77
 
67
78
  export type BooleanActions = {
package/types/paths.ts ADDED
@@ -0,0 +1,109 @@
1
+ export type Path<T, Sep extends string> = T extends any ? PathInternal<T, Sep> : never;
2
+ // export type PathValue<T, Sep extends string, ValuePath extends Path<T, Sep>> = TPathValue<T, Sep, ValuePath>;
3
+
4
+ /////////////////////////////////////////////////////////////////////////
5
+ /////////////////////////////////////////////////////////////////////////
6
+ /////////////////////////////////////////////////////////////////////////
7
+ /////////////////////////////////////////////////////////////////////////
8
+ /////////////////////////////////////////////////////////////////////////
9
+ /////////////////////////////////////////////////////////////////////////
10
+ /////////////////////////////////////////////////////////////////////////
11
+ /////////////////////////////////////////////////////////////////////////
12
+
13
+ type PathInternal<T, Sep extends string, TraversedTypes = T> = T extends ReadonlyArray<infer V>
14
+ ? IsTuple<T> extends true
15
+ ? {
16
+ [K in TupleKeys<T>]-?: PathImpl<K & string, Sep, T[K], TraversedTypes>;
17
+ }[TupleKeys<T>]
18
+ : PathImpl<ArrayKey, Sep, V, TraversedTypes>
19
+ : {
20
+ [K in keyof T]-?: PathImpl<K & string, Sep, T[K], TraversedTypes>;
21
+ }[keyof T];
22
+
23
+ export type TupleKeys<T extends ReadonlyArray<any>> = Exclude<keyof T, keyof any[]>;
24
+
25
+ type PathImpl<K extends string | number, Sep extends string, V, TraversedTypes> = V extends
26
+ | Primitive
27
+ | BrowserNativeObject
28
+ ? `${K}`
29
+ : true extends AnyIsEqual<TraversedTypes, V>
30
+ ? `${K}`
31
+ : `${K}` | `${K}${Sep}${PathInternal<V, Sep, TraversedTypes | V>}`;
32
+
33
+ export type ArrayKey = number;
34
+ export type Primitive = null | undefined | string | number | boolean | symbol | bigint;
35
+ export type IsTuple<T extends ReadonlyArray<any>> = number extends T['length'] ? false : true;
36
+ export type BrowserNativeObject = Date | FileList | File;
37
+
38
+ type AnyIsEqual<T1, T2> = T1 extends T2 ? (IsEqual<T1, T2> extends true ? true : never) : never;
39
+ export type IsEqual<T1, T2> = T1 extends T2
40
+ ? (<G>() => G extends T1 ? 1 : 2) extends <G>() => G extends T2 ? 1 : 2
41
+ ? true
42
+ : false
43
+ : false;
44
+
45
+ ////////////////////////////////////////////////////////////////////////////
46
+ ////////////////////////////////////////////////////////////////////////////
47
+ ////////////////////////////////////////////////////////////////////////////
48
+ ////////////////////////////////////////////////////////////////////////////
49
+ ////////////////////////////////////////////////////////////////////////////
50
+ ////////////////////////////////////////////////////////////////////////////
51
+ ////////////////////////////////////////////////////////////////////////////
52
+ ////////////////////////////////////////////////////////////////////////////
53
+ ////////////////////////////////////////////////////////////////////////////
54
+ ////////////////////////////////////////////////////////////////////////////
55
+ ////////////////////////////////////////////////////////////////////////////
56
+ ////////////////////////////////////////////////////////////////////////////
57
+ ////////////////////////////////////////////////////////////////////////////
58
+
59
+ export type PathValue<T, Sep extends string, P extends Path<T, Sep> | ArrayPath<T, Sep>> = T extends any
60
+ ? P extends `${infer K}${Sep}${infer R}`
61
+ ? K extends keyof T
62
+ ? R extends Path<T[K], Sep>
63
+ ? PathValue<T[K], Sep, R>
64
+ : never
65
+ : K extends `${ArrayKey}`
66
+ ? T extends ReadonlyArray<infer V>
67
+ ? PathValue<V, Sep, R & Path<V, Sep>>
68
+ : never
69
+ : never
70
+ : P extends keyof T
71
+ ? T[P]
72
+ : P extends `${ArrayKey}`
73
+ ? T extends ReadonlyArray<infer V>
74
+ ? V
75
+ : never
76
+ : never
77
+ : never;
78
+
79
+ export type ArrayPath<T, Sep extends string> = T extends any ? ArrayPathInternal<T, Sep> : never;
80
+
81
+ type ArrayPathInternal<T, Sep extends string, TraversedTypes = T> = T extends ReadonlyArray<infer V>
82
+ ? IsTuple<T> extends true
83
+ ? {
84
+ [K in TupleKeys<T>]-?: ArrayPathImpl<K & string, Sep, T[K], TraversedTypes>;
85
+ }[TupleKeys<T>]
86
+ : ArrayPathImpl<ArrayKey, Sep, V, TraversedTypes>
87
+ : {
88
+ [K in keyof T]-?: ArrayPathImpl<K & string, Sep, T[K], TraversedTypes>;
89
+ }[keyof T];
90
+
91
+ type ArrayPathImpl<K extends string | number, Sep extends string, V, TraversedTypes> = V extends
92
+ | Primitive
93
+ | BrowserNativeObject
94
+ ? IsAny<V> extends true
95
+ ? string
96
+ : never
97
+ : V extends ReadonlyArray<infer U>
98
+ ? U extends Primitive | BrowserNativeObject
99
+ ? IsAny<V> extends true
100
+ ? string
101
+ : never
102
+ : true extends AnyIsEqual<TraversedTypes, V>
103
+ ? never
104
+ : `${K}` | `${K}${Sep}${ArrayPathInternal<V, Sep, TraversedTypes | V>}`
105
+ : true extends AnyIsEqual<TraversedTypes, V>
106
+ ? never
107
+ : `${K}${Sep}${ArrayPathInternal<V, Sep, TraversedTypes | V>}`;
108
+
109
+ export type IsAny<T> = 0 extends 1 & T ? true : false;