atomaric 0.0.76 → 0.0.78
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 +87 -86
- package/build/atomaric.umd.cjs +1 -1
- package/package.json +2 -4
- package/types/do.classes.model/IArray.ts +24 -0
- package/types/do.classes.model/IBoolean.ts +4 -0
- package/types/do.classes.model/IMap.ts +22 -0
- package/types/do.classes.model/INumber.ts +6 -0
- package/types/do.classes.model/IObject.ts +12 -0
- package/types/do.classes.model/ISet.ts +13 -0
- package/types/index.d.ts +12 -12
- package/src/do.classes/Array.test.ts +0 -103
- package/src/do.classes/Array.ts +0 -66
- package/src/do.classes/Boolean.test.ts +0 -27
- package/src/do.classes/Boolean.ts +0 -13
- package/src/do.classes/Map.test.ts +0 -77
- package/src/do.classes/Map.ts +0 -59
- package/src/do.classes/Number.test.ts +0 -25
- package/src/do.classes/Number.ts +0 -15
- package/src/do.classes/Object.test.ts +0 -67
- package/src/do.classes/Object.ts +0 -75
- package/src/do.classes/Set.test.ts +0 -46
- package/src/do.classes/Set.ts +0 -40
- package/src/do.classes/_Basic.ts +0 -11
- package/src/do.classes/_Update.ts +0 -37
package/build/atomaric.js
CHANGED
|
@@ -14,15 +14,15 @@ class V {
|
|
|
14
14
|
}
|
|
15
15
|
const ce = (t, e) => {
|
|
16
16
|
const i = (s, n, c) => new Proxy(s, {
|
|
17
|
-
get: (
|
|
18
|
-
const
|
|
19
|
-
return typeof
|
|
20
|
-
Array.isArray(
|
|
21
|
-
n.concat(Array.isArray(
|
|
17
|
+
get: (a, d, p) => {
|
|
18
|
+
const w = c === 0 && e.get != null ? e.get(a, d, p) : a[d], f = w ?? (Array.isArray(a) ? [] : {});
|
|
19
|
+
return typeof f == "object" && f !== null ? i(
|
|
20
|
+
Array.isArray(f) ? f.slice(0) : { ...f },
|
|
21
|
+
n.concat(Array.isArray(a) ? +d : d),
|
|
22
22
|
c + 1
|
|
23
|
-
) :
|
|
23
|
+
) : f;
|
|
24
24
|
},
|
|
25
|
-
set: (
|
|
25
|
+
set: (a, d, p) => (e.onSet(a, n, d, p, a[d]) && (a[d] = p), !0)
|
|
26
26
|
});
|
|
27
27
|
return i(t, [], 0);
|
|
28
28
|
};
|
|
@@ -31,19 +31,20 @@ class O extends V {
|
|
|
31
31
|
super(...arguments), this.updateValue = (e, i) => {
|
|
32
32
|
const s = Array.isArray(e) ? e.slice(0) : { ...e };
|
|
33
33
|
let n = !1;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
34
|
+
return i(
|
|
35
|
+
ce(s, {
|
|
36
|
+
onSet: (c, a, d, p, w) => {
|
|
37
|
+
if (p === w) return !0;
|
|
38
|
+
let f = s;
|
|
39
|
+
n = !0;
|
|
40
|
+
for (const b of a) {
|
|
41
|
+
const h = f[b];
|
|
42
|
+
f = f[b] = Array.isArray(h) ? h.slice() : { ...h };
|
|
43
|
+
}
|
|
44
|
+
return f[d] = p, !0;
|
|
42
45
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
});
|
|
46
|
-
return i(c), n ? s : e;
|
|
46
|
+
})
|
|
47
|
+
), n ? s : e;
|
|
47
48
|
};
|
|
48
49
|
}
|
|
49
50
|
}
|
|
@@ -67,8 +68,8 @@ class oe extends O {
|
|
|
67
68
|
const c = this.a.get().slice(0);
|
|
68
69
|
c.splice(n, 1), this.a.set(c);
|
|
69
70
|
}, this.toggle = (s, n) => {
|
|
70
|
-
const c = this.a.get().slice(),
|
|
71
|
-
|
|
71
|
+
const c = this.a.get().slice(), a = c.indexOf(s);
|
|
72
|
+
a < 0 ? n ? c.unshift(s) : c.push(s) : c.splice(a, 1), this.a.set(c);
|
|
72
73
|
};
|
|
73
74
|
}
|
|
74
75
|
}
|
|
@@ -117,31 +118,31 @@ class he extends O {
|
|
|
117
118
|
})), this.update = (s) => {
|
|
118
119
|
const n = this.a.get(), c = this.updateValue(n, s);
|
|
119
120
|
c !== n && this.a.set(c);
|
|
120
|
-
}, this.setDeepPartial = (s, n, c,
|
|
121
|
-
if (!
|
|
122
|
-
if (s.includes(
|
|
123
|
-
let
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
let
|
|
128
|
-
for (const y of
|
|
129
|
-
|
|
130
|
-
const D =
|
|
121
|
+
}, this.setDeepPartial = (s, n, c, a = _.keyPathSeparator || ".") => {
|
|
122
|
+
if (!a) return;
|
|
123
|
+
if (s.includes(a)) {
|
|
124
|
+
let w = s.split(a);
|
|
125
|
+
const f = w[w.length - 1];
|
|
126
|
+
w = w.slice(0, -1);
|
|
127
|
+
const b = { ...this.a.get() };
|
|
128
|
+
let h = b, g = c;
|
|
129
|
+
for (const y of w) {
|
|
130
|
+
g = g == null ? void 0 : g[Array.isArray(g) ? "0" : y];
|
|
131
|
+
const D = h[v(h, y)] ?? (Array.isArray(g) ? [] : {});
|
|
131
132
|
if (D == null || typeof D != "object") {
|
|
132
133
|
if (c == null) throw "Incorrect path for setDeepPartial";
|
|
133
|
-
const
|
|
134
|
-
this.a.get()[s] !==
|
|
134
|
+
const m = typeof n == "function" ? n(void 0) : n;
|
|
135
|
+
this.a.get()[s] !== m && this.setPartial({ [s]: m });
|
|
135
136
|
return;
|
|
136
137
|
}
|
|
137
|
-
|
|
138
|
+
h = h[v(h, y)] = Array.isArray(D) ? [...D] : { ...D };
|
|
138
139
|
}
|
|
139
|
-
const E = f
|
|
140
|
-
f
|
|
140
|
+
const E = h[f];
|
|
141
|
+
h[f] = typeof n == "function" ? n(h[f]) : n, E !== h[f] && this.a.set(b);
|
|
141
142
|
return;
|
|
142
143
|
}
|
|
143
|
-
const
|
|
144
|
-
p !==
|
|
144
|
+
const d = this.a.get()[s], p = typeof n == "function" ? n(d) : n;
|
|
145
|
+
p !== d && this.setPartial({ [s]: p });
|
|
145
146
|
};
|
|
146
147
|
}
|
|
147
148
|
}
|
|
@@ -164,53 +165,53 @@ class de extends V {
|
|
|
164
165
|
}
|
|
165
166
|
const ge = (t, e, i) => {
|
|
166
167
|
const s = typeof i == "object" && i != null && "do" in i ? i.do(
|
|
167
|
-
(c,
|
|
168
|
+
(c, a) => e.set(c, a),
|
|
168
169
|
() => e.get(),
|
|
169
170
|
e,
|
|
170
|
-
(c,
|
|
171
|
+
(c, a, d) => e.setDeferred(c, a, d)
|
|
171
172
|
) : null, n = {};
|
|
172
173
|
return s && Object.keys(s).forEach((c) => Object.defineProperty(n, c, { get: () => s[c] })), typeof t == "number" ? new fe(e, s) : typeof t == "boolean" ? new ue(e, s) : Array.isArray(t) ? new oe(e, s) : t instanceof Set ? new de(e, s) : t instanceof Map ? new le(e, s) : t instanceof Object ? new he(e, s) : new V(s);
|
|
173
174
|
};
|
|
174
175
|
class pe {
|
|
175
176
|
constructor(e, i) {
|
|
176
177
|
e = typeof e == "function" ? e() : e;
|
|
177
|
-
const s = (r) =>
|
|
178
|
-
let
|
|
179
|
-
},
|
|
178
|
+
const s = (r) => w = r, n = () => w, c = /* @__PURE__ */ new Set(), a = (r) => r(h());
|
|
179
|
+
let d = !0, p = !1, w = e, f, b = () => {
|
|
180
|
+
}, h = () => n(), g = null, E = () => {
|
|
180
181
|
const r = ge(e, y, i);
|
|
181
182
|
return E = () => r, r;
|
|
182
183
|
};
|
|
183
184
|
const y = new Proxy(this, {
|
|
184
|
-
get: (r,
|
|
185
|
+
get: (r, l) => l === "do" ? E() : r[l],
|
|
185
186
|
set: we
|
|
186
187
|
}), D = () => {
|
|
187
|
-
|
|
188
|
+
d = !0, p !== !0 && b(h()), p = !1;
|
|
188
189
|
try {
|
|
189
|
-
H.postMessage({ key:
|
|
190
|
+
H.postMessage({ key: u, value: n() });
|
|
190
191
|
} catch {
|
|
191
192
|
}
|
|
192
|
-
},
|
|
193
|
-
const
|
|
194
|
-
|
|
193
|
+
}, m = (r, l) => {
|
|
194
|
+
const S = typeof r == "function" ? r(h()) : r;
|
|
195
|
+
S !== h() && (s(S), p = l, d && (d = !1, c.forEach(a), queueMicrotask(D)));
|
|
195
196
|
};
|
|
196
|
-
this.set = (r,
|
|
197
|
+
this.set = (r, l) => m(r, l), this.get = () => h(), this.initialValue = e, this.isInitialValue = () => e === n(), this.subscribe = (r) => (c.add(r), () => {
|
|
197
198
|
c.delete(r);
|
|
198
199
|
}), this.reset = () => {
|
|
199
|
-
|
|
200
|
+
m(e, !0);
|
|
200
201
|
};
|
|
201
|
-
const re = (r,
|
|
202
|
-
|
|
202
|
+
const re = (r, l) => {
|
|
203
|
+
m(r, l), f = void 0;
|
|
203
204
|
};
|
|
204
|
-
if (this.setDeferred = (r,
|
|
205
|
-
|
|
205
|
+
if (this.setDeferred = (r, l = 500, S, x = !0) => {
|
|
206
|
+
x && f === void 0 && m(r, S), clearTimeout(f), f = setTimeout(re, l, r, S);
|
|
206
207
|
}, i == null) return y;
|
|
207
208
|
let A = null, j = null, q = !0, F = !0, N = !1, $ = 0, M = 0, K = -1, T = e instanceof Set ? (r) => new Set(r) : e instanceof Map ? (r) => new Map(r) : (r) => r, I = e instanceof Set ? (r) => {
|
|
208
209
|
if (r instanceof Set) return Array.from(r);
|
|
209
210
|
throw console.error(r), "The value is not Set instance";
|
|
210
211
|
} : e instanceof Map ? (r) => {
|
|
211
212
|
if (r instanceof Map) {
|
|
212
|
-
const
|
|
213
|
-
return r.forEach((
|
|
213
|
+
const l = [];
|
|
214
|
+
return r.forEach((S, x) => l.push([x, S])), l;
|
|
214
215
|
}
|
|
215
216
|
throw console.error(r), "The value is not Set instance";
|
|
216
217
|
} : (r) => r;
|
|
@@ -219,75 +220,75 @@ class pe {
|
|
|
219
220
|
else if ("storeKey" in i)
|
|
220
221
|
q = i.warnOnDuplicateStoreKey ?? q, F = i.listenStorageChanges ?? F, A = i.storeKey, T = i.unzipValue ?? T, I = i.zipValue ?? I, N = i.unchangable ?? N, $ = i.securifyKeyLevel ?? _.securifyKeyLevel ?? $, M = i.securifyValueLevel ?? _.securifyValueLevel ?? M, j = i.exp ?? j;
|
|
221
222
|
else return y;
|
|
222
|
-
const B = $ ? L(A, $) : A,
|
|
223
|
+
const B = $ ? L(A, $) : A, u = `${M ? J : C}${B}`;
|
|
223
224
|
if ($) {
|
|
224
225
|
const r = `${C}${A}`;
|
|
225
|
-
r in o && (o[
|
|
226
|
+
r in o && (o[u] = o[r], delete o[r]);
|
|
226
227
|
} else {
|
|
227
228
|
const r = `${C}${L(A, $)}`;
|
|
228
|
-
r in o && (o[
|
|
229
|
+
r in o && (o[u] = o[r], delete o[r]);
|
|
229
230
|
}
|
|
230
|
-
const W = j === null || !(j(y,
|
|
231
|
+
const W = j === null || !(j(y, u in o) instanceof Date) ? (r) => L([I(r)], 0) : (r) => (g ?? (g = {}), g.exp = j(y, u in o).getTime(), g.exp - Date.now() < 24 * 60 * 60 * 1e3 && (clearTimeout(K), clearTimeout(ee[u]), K = setTimeout(() => this.reset(), g.exp - Date.now())), g.exp = Math.trunc(g.exp / 1e3), L([I(r), g], 0));
|
|
231
232
|
if (M) {
|
|
232
|
-
const r = `${C}${B}`,
|
|
233
|
-
if (I = (
|
|
233
|
+
const r = `${C}${B}`, l = I, S = T;
|
|
234
|
+
if (I = (x) => {
|
|
234
235
|
try {
|
|
235
|
-
return L([
|
|
236
|
+
return L([l(x)], M);
|
|
236
237
|
} catch {
|
|
237
|
-
return delete o[
|
|
238
|
+
return delete o[u], "";
|
|
238
239
|
}
|
|
239
240
|
}, r in o) {
|
|
240
|
-
const
|
|
241
|
+
const x = `${C}${L(A, $)}`;
|
|
241
242
|
try {
|
|
242
|
-
o[
|
|
243
|
+
o[x] = W(T(z(o[r], 0)[0])), delete o[r];
|
|
243
244
|
} catch {
|
|
244
245
|
}
|
|
245
246
|
}
|
|
246
|
-
T = (
|
|
247
|
+
T = (x) => {
|
|
247
248
|
try {
|
|
248
|
-
return
|
|
249
|
+
return S(z(x, M)[0]);
|
|
249
250
|
} catch {
|
|
250
|
-
return delete o[
|
|
251
|
+
return delete o[u], "";
|
|
251
252
|
}
|
|
252
253
|
};
|
|
253
254
|
} else delete o[`${J}${B}`];
|
|
254
255
|
const X = (r) => {
|
|
255
|
-
const
|
|
256
|
-
return
|
|
256
|
+
const l = z(r, 0);
|
|
257
|
+
return g = l[1], T(l[0]);
|
|
257
258
|
};
|
|
258
259
|
let Y = !0;
|
|
259
|
-
if (G[
|
|
260
|
-
if (
|
|
260
|
+
if (G[u] = y, o[`atom/${A}`] && (o[u] || (o[u] = `[${o[`atom/${A}`]}]`), delete o[`atom/${A}`]), h = () => {
|
|
261
|
+
if (h = n, Y) {
|
|
261
262
|
Y = !1;
|
|
262
263
|
try {
|
|
263
|
-
s(
|
|
264
|
+
s(u in o ? X(o[u]) : e);
|
|
264
265
|
} catch {
|
|
265
|
-
console.warn("Invalid json value", o[
|
|
266
|
+
console.warn("Invalid json value", o[u]);
|
|
266
267
|
}
|
|
267
268
|
}
|
|
268
269
|
return n();
|
|
269
|
-
},
|
|
270
|
+
}, b = (r) => {
|
|
270
271
|
if (r === e) {
|
|
271
272
|
this.reset();
|
|
272
273
|
return;
|
|
273
274
|
}
|
|
274
|
-
o[
|
|
275
|
+
o[u] = W(r);
|
|
275
276
|
}, this.reset = () => {
|
|
276
|
-
delete o[
|
|
277
|
-
}, q && P[
|
|
277
|
+
delete o[u], m(e, !0);
|
|
278
|
+
}, q && P[u] !== void 0 && console.warn("Duplicate Atom key", A), F)
|
|
278
279
|
if (N) {
|
|
279
|
-
let r = !1,
|
|
280
|
-
U[
|
|
281
|
-
clearTimeout(
|
|
280
|
+
let r = !1, l;
|
|
281
|
+
U[u] = this, P[u] = () => {
|
|
282
|
+
clearTimeout(l), l = setTimeout(() => r = !1, 10), !r && (r = !0, o[u] = W(n()));
|
|
282
283
|
};
|
|
283
284
|
} else
|
|
284
|
-
P[
|
|
285
|
+
P[u] = (r) => {
|
|
285
286
|
if (r.newValue === null) {
|
|
286
287
|
this.reset();
|
|
287
288
|
return;
|
|
288
289
|
}
|
|
289
290
|
try {
|
|
290
|
-
|
|
291
|
+
m(X(r.newValue));
|
|
291
292
|
} catch {
|
|
292
293
|
console.warn("Invalid json value", r.newValue);
|
|
293
294
|
}
|
package/build/atomaric.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(f,_){typeof exports=="object"&&typeof module<"u"?_(exports):typeof define=="function"&&define.amd?define(["exports"],_):(f=typeof globalThis<"u"?globalThis:f||self,_(f.atomaric={}))})(this,function(f){"use strict";let _=()=>{throw"call configureAtomaric() before all!"};const
|
|
1
|
+
(function(f,_){typeof exports=="object"&&typeof module<"u"?_(exports):typeof define=="function"&&define.amd?define(["exports"],_):(f=typeof globalThis<"u"?globalThis:f||self,_(f.atomaric={}))})(this,function(f){"use strict";let _=()=>{throw"call configureAtomaric() before all!"};const x={},de=t=>{x.useSyncExternalStore=_=t.useSyncExternalStore,x.keyPathSeparator=t.keyPathSeparator,x.securifyKeyLevel=t.securifyKeyLevel,x.securifyValueLevel=t.securifyValueLevel},Y=t=>_(t.subscribe,t.get),Z=t=>t.set,ge=t=>t.setDeferred,Ae=t=>t.get,me=t=>t.do,ye=t=>[Y(t),Z(t)],we=(t,e)=>new ie(t,e);class j{constructor(e){if(e)return new Proxy(this,{get:(i,s)=>s in this?i[s]:e[s]})}}const pe=(t,e)=>{const i=(s,r,o)=>new Proxy(s,{get:(a,g,m)=>{const y=o===0&&e.get!=null?e.get(a,g,m):a[g],h=y??(Array.isArray(a)?[]:{});return typeof h=="object"&&h!==null?i(Array.isArray(h)?h.slice(0):{...h},r.concat(Array.isArray(a)?+g:g),o+1):h},set:(a,g,m)=>(e.onSet(a,r,g,m,a[g])&&(a[g]=m),!0)});return i(t,[],0)};class v extends j{constructor(){super(...arguments),this.updateValue=(e,i)=>{const s=Array.isArray(e)?e.slice(0):{...e};let r=!1;return i(pe(s,{onSet:(o,a,g,m,y)=>{if(m===y)return!0;let h=s;r=!0;for(const $ of a){const d=h[$];h=h[$]=Array.isArray(d)?d.slice():{...d}}return h[g]=m,!0}})),r?s:e}}}class k extends v{constructor(e,i){super(i),this.a=e,this.push=(...s)=>{s.length!==0&&this.a.set(this.a.get().concat(s))},this.unshift=(...s)=>{s.length!==0&&this.a.set(s.concat(this.a.get()))},this.update=s=>{const r=this.a.get(),o=this.updateValue(r,s);o!==r&&this.a.set(o)},this.filter=s=>{const r=this.a.get().filter(s??Se);r.length!==this.a.get().length&&this.a.set(r)},this.add=s=>{this.a.get().includes(s)||this.a.set(this.a.get().concat([s]))},this.removeFirst=s=>{const r=this.a.get().indexOf(s);if(r<0)return;const o=this.a.get().slice(0);o.splice(r,1),this.a.set(o)},this.toggle=(s,r)=>{const o=this.a.get().slice(),a=o.indexOf(s);a<0?r?o.unshift(s):o.push(s):o.splice(a,1),this.a.set(o)}}}const Se=t=>t;class O extends j{constructor(e,i){super(i),this.a=e,this.toggle=()=>{this.a.set(!this.a.get())}}}class ee extends j{constructor(e,i){super(i),this.a=e,this.setValue=(s,r)=>{if(this.a.get().get(s)===r)return;const o=new Map(this.a.get());o.set(s,r),this.a.set(o)},this.setIfNo=(s,r)=>{if(this.a.get().has(s))return;const o=new Map(this.a.get());o.set(s,r),this.a.set(o)},this.delete=s=>{if(!this.a.get().has(s))return;const r=new Map(this.a.get());r.delete(s),this.a.set(r)},this.toggle=(s,r)=>{const o=new Map(this.a.get());o.has(s)?o.delete(s):o.set(s,r),this.a.set(o)},this.clear=()=>{this.a.set(new Map)},this.a=e}}class te extends j{constructor(e,i){super(i),this.a=e,this.increment=s=>{this.a.set(+this.a.get()+(s??1))}}}class se extends v{constructor(e,i){super(i),this.a=e,this.setPartial=s=>this.a.set(r=>({...r,...typeof s=="function"?s(this.a.get()):s})),this.update=s=>{const r=this.a.get(),o=this.updateValue(r,s);o!==r&&this.a.set(o)},this.setDeepPartial=(s,r,o,a=x.keyPathSeparator||".")=>{if(!a)return;if(s.includes(a)){let y=s.split(a);const h=y[y.length-1];y=y.slice(0,-1);const $={...this.a.get()};let d=$,A=o;for(const w of y){A=A==null?void 0:A[Array.isArray(A)?"0":w];const M=d[ne(d,w)]??(Array.isArray(A)?[]:{});if(M==null||typeof M!="object"){if(o==null)throw"Incorrect path for setDeepPartial";const S=typeof r=="function"?r(void 0):r;this.a.get()[s]!==S&&this.setPartial({[s]:S});return}d=d[ne(d,w)]=Array.isArray(M)?[...M]:{...M}}const q=d[h];d[h]=typeof r=="function"?r(d[h]):r,q!==d[h]&&this.a.set($);return}const g=this.a.get()[s],m=typeof r=="function"?r(g):r;m!==g&&this.setPartial({[s]:m})}}}const ne=(t,e)=>Array.isArray(t)?`${+e}`:e;class re extends j{constructor(e,i){super(i),this.a=e,this.add=s=>{this.a.get().has(s)||this.a.set(new Set(this.a.get()).add(s))},this.delete=s=>{if(!this.a.get().has(s))return;const r=new Set(this.a.get());r.delete(s),this.a.set(r)},this.toggle=s=>{const r=new Set(this.a.get());r.has(s)?r.delete(s):r.add(s),this.a.set(r)},this.clear=()=>{this.a.set(new Set)},this.a=e}}const be=(t,e,i)=>{const s=typeof i=="object"&&i!=null&&"do"in i?i.do((o,a)=>e.set(o,a),()=>e.get(),e,(o,a,g)=>e.setDeferred(o,a,g)):null,r={};return s&&Object.keys(s).forEach(o=>Object.defineProperty(r,o,{get:()=>s[o]})),typeof t=="number"?new te(e,s):typeof t=="boolean"?new O(e,s):Array.isArray(t)?new k(e,s):t instanceof Set?new re(e,s):t instanceof Map?new ee(e,s):t instanceof Object?new se(e,s):new j(s)};class ie{constructor(e,i){e=typeof e=="function"?e():e;const s=n=>y=n,r=()=>y,o=new Set,a=n=>n(d());let g=!0,m=!1,y=e,h,$=()=>{},d=()=>r(),A=null,q=()=>{const n=be(e,w,i);return q=()=>n,n};const w=new Proxy(this,{get:(n,l)=>l==="do"?q():n[l],set:De}),M=()=>{g=!0,m!==!0&&$(d()),m=!1;try{B.postMessage({key:u,value:r()})}catch{}},S=(n,l)=>{const b=typeof n=="function"?n(d()):n;b!==d()&&(s(b),m=l,g&&(g=!1,o.forEach(a),queueMicrotask(M)))};this.set=(n,l)=>S(n,l),this.get=()=>d(),this.initialValue=e,this.isInitialValue=()=>e===r(),this.subscribe=n=>(o.add(n),()=>{o.delete(n)}),this.reset=()=>{S(e,!0)};const Te=(n,l)=>{S(n,l),h=void 0};if(this.setDeferred=(n,l=500,b,D=!0)=>{D&&h===void 0&&S(n,b),clearTimeout(h),h=setTimeout(Te,l,n,b)},i==null)return w;let p=null,z=null,H=!0,J=!0,Q=!1,T=0,V=0,ue=-1,C=e instanceof Set?n=>new Set(n):e instanceof Map?n=>new Map(n):n=>n,E=e instanceof Set?n=>{if(n instanceof Set)return Array.from(n);throw console.error(n),"The value is not Set instance"}:e instanceof Map?n=>{if(n instanceof Map){const l=[];return n.forEach((b,D)=>l.push([D,b])),l}throw console.error(n),"The value is not Set instance"}:n=>n;if(typeof i=="string")p=i;else if("storeKey"in i)H=i.warnOnDuplicateStoreKey??H,J=i.listenStorageChanges??J,p=i.storeKey,C=i.unzipValue??C,E=i.zipValue??E,Q=i.unchangable??Q,T=i.securifyKeyLevel??x.securifyKeyLevel??T,V=i.securifyValueLevel??x.securifyValueLevel??V,z=i.exp??z;else return w;const K=T?P(p,T):p,u=`${V?F:L}${K}`;if(T){const n=`${L}${p}`;n in c&&(c[u]=c[n],delete c[n])}else{const n=`${L}${P(p,T)}`;n in c&&(c[u]=c[n],delete c[n])}const X=z===null||!(z(w,u in c)instanceof Date)?n=>P([E(n)],0):n=>(A??(A={}),A.exp=z(w,u in c).getTime(),A.exp-Date.now()<24*60*60*1e3&&(clearTimeout(ue),clearTimeout(oe[u]),ue=setTimeout(()=>this.reset(),A.exp-Date.now())),A.exp=Math.trunc(A.exp/1e3),P([E(n),A],0));if(V){const n=`${L}${K}`,l=E,b=C;if(E=D=>{try{return P([l(D)],V)}catch{return delete c[u],""}},n in c){const D=`${L}${P(p,T)}`;try{c[D]=X(C(U(c[n],0)[0])),delete c[n]}catch{}}C=D=>{try{return b(U(D,V)[0])}catch{return delete c[u],""}}}else delete c[`${F}${K}`];const le=n=>{const l=U(n,0);return A=l[1],C(l[0])};let fe=!0;if(W[u]=w,c[`atom/${p}`]&&(c[u]||(c[u]=`[${c[`atom/${p}`]}]`),delete c[`atom/${p}`]),d=()=>{if(d=r,fe){fe=!1;try{s(u in c?le(c[u]):e)}catch{console.warn("Invalid json value",c[u])}}return r()},$=n=>{if(n===e){this.reset();return}c[u]=X(n)},this.reset=()=>{delete c[u],S(e,!0)},H&&I[u]!==void 0&&console.warn("Duplicate Atom key",p),J)if(Q){let n=!1,l;R[u]=this,I[u]=()=>{clearTimeout(l),l=setTimeout(()=>n=!1,10),!n&&(n=!0,c[u]=X(r()))}}else I[u]=n=>{if(n.newValue===null){this.reset();return}try{S(le(n.newValue))}catch{console.warn("Invalid json value",n.newValue)}};return w}}let B;try{B=new BroadcastChannel("updateHere"),B.addEventListener("message",t=>{var e;(e=R[t.data.key])==null||e.set(t.data.value,!0)})}catch{}const c=localStorage,I={},R={},De=(t,e)=>{throw`${e} is readonly property`};window.addEventListener("storage",t=>{var e;t.key===null||t.newValue===t.oldValue||(e=I[t.key])==null||e.call(I,t)});const xe=c.setItem.bind(c),$e=c.removeItem.bind(c);c.setItem=(t,e)=>{R[t]===void 0&&xe.call(c,t,e)},c.removeItem=t=>{R[t]===void 0&&$e.call(c,t)};const Me=/"exp":\s*(\d+)/,L="atom\\",F="atom`s\\",W={},oe={},ce=/[a-z]/gi,N=5,G={};for(let t=54;t<80;t++){if(t===68||t===72||t===55)continue;const e=String.fromCharCode(t+43).toUpperCase(),i=String.fromCharCode(t+43).toLowerCase();G[e]=i,G[i]=e}const ae=t=>G[t]??t,P=(()=>{const t=[e=>JSON.stringify(e),e=>btoa(encodeURI(t[0](e))),e=>{const i=t[1](e);return`${i.slice(0,N)}${i.slice(N).replace(ce,ae)}`},e=>btoa(t[2](e))];return(e,i)=>{try{return t[i](e)}catch(s){if(i===0)throw s;return t[0](e)}}})(),U=(()=>{const t=[e=>JSON.parse(e),e=>t[0](decodeURI(atob(e))),e=>t[1](`${e.slice(0,N)}${e.slice(N).replace(ce,ae)}`),e=>t[2](atob(e))];return(e,i)=>{try{return t[i](e)}catch(s){if(i===0)throw s;return t[0](e)}}})();setTimeout(()=>{Object.keys(c).forEach(t=>{var s;if(typeof c[t]!="string"||!t.startsWith(L)&&!t.startsWith(F))return;const e=(s=c[t].match(Me))==null?void 0:s[1];if(!e||+e*1e3-Date.now()>24*60*60*1e3)return;const i=U(c[t],0);!Array.isArray(i)||i[1]==null||!("exp"in i[1])||i[1].exp!==e||(oe[t]=setTimeout(()=>{W[t]?W[t].reset():delete c[t]},+e*1e3-Date.now()))})},1e3),f.Atom=ie,f.AtomArrayDoActions=k,f.AtomBooleanDoActions=O,f.AtomMapDoActions=ee,f.AtomNumberDoActions=te,f.AtomObjectDoActions=se,f.AtomSetDoActions=re,f.atom=we,f.configureAtomaric=de,f.configuredOptions=x,f.useAtom=ye,f.useAtomDo=me,f.useAtomGet=Ae,f.useAtomSet=Z,f.useAtomSetDeferred=ge,f.useAtomValue=Y,Object.defineProperty(f,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.
|
|
4
|
+
"version": "0.0.78",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./build/atomaric.umd.cjs",
|
|
7
7
|
"module": "./build/atomaric.js",
|
|
@@ -15,9 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
"build",
|
|
18
|
-
"types"
|
|
19
|
-
"src/do.classes",
|
|
20
|
-
"src/makeDeepProxyObject"
|
|
18
|
+
"types"
|
|
21
19
|
],
|
|
22
20
|
"keywords": [
|
|
23
21
|
"react",
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
|
|
3
|
+
export interface IAtomArrayDoActions<Value> {
|
|
4
|
+
/** like the Array.prototype.push() method */
|
|
5
|
+
push: (...values: Value[]) => void;
|
|
6
|
+
|
|
7
|
+
/** like the Array.prototype.unshift() method */
|
|
8
|
+
unshift: (...values: Value[]) => void;
|
|
9
|
+
|
|
10
|
+
/** transform current taken value */
|
|
11
|
+
update: (updater: (value: Value[]) => void) => void;
|
|
12
|
+
|
|
13
|
+
/** like the Array.prototype.filter() method, but callback is optional - (it) => !!it */
|
|
14
|
+
filter: (filter?: (value: Value, index: number, Array: Value[]) => any) => void;
|
|
15
|
+
|
|
16
|
+
/** will add value if not exists */
|
|
17
|
+
add: (value: Value) => void;
|
|
18
|
+
|
|
19
|
+
/** will delete first found value from array */
|
|
20
|
+
removeFirst: (value: Value) => void;
|
|
21
|
+
|
|
22
|
+
/** will add value if it doesn't exist, otherwise delete */
|
|
23
|
+
toggle: (value: Value, isAddToStart?: boolean) => void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
|
|
3
|
+
export interface IAtomMapDoActions<
|
|
4
|
+
MapValue extends Map<any, any>,
|
|
5
|
+
Key extends MapValue extends Map<infer K, any> ? K : never,
|
|
6
|
+
Value extends MapValue extends Map<any, infer V> ? V : never,
|
|
7
|
+
> {
|
|
8
|
+
/** like the Map.prototype.set() method, when value is new for key in current atom value */
|
|
9
|
+
setValue: (key: Key, value: Value) => void;
|
|
10
|
+
|
|
11
|
+
/** like the Map.prototype.set() method, when key is not exists */
|
|
12
|
+
setIfNo: (key: Key, value: Value) => void;
|
|
13
|
+
|
|
14
|
+
/** like the Map.prototype.delete() method */
|
|
15
|
+
delete: (key: Key) => void;
|
|
16
|
+
|
|
17
|
+
/** will add value if it doesn't exist, otherwise delete */
|
|
18
|
+
toggle: (key: Key, value: Value) => void;
|
|
19
|
+
|
|
20
|
+
/** like the Map.prototype.clear() method */
|
|
21
|
+
clear: () => void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ObjectActionsSetDeepPartialDoAction } from '..';
|
|
2
|
+
|
|
3
|
+
export interface IAtomObjectDoActions<Value extends object> {
|
|
4
|
+
/** pass partial object to update some field values */
|
|
5
|
+
setPartial: (value: Partial<Value> | ((value: Value) => Partial<Value>)) => void;
|
|
6
|
+
|
|
7
|
+
/** transform current taken value */
|
|
8
|
+
update: (updater: (value: Value) => void) => void;
|
|
9
|
+
|
|
10
|
+
/** pass partial value to update some deep values by flat path */
|
|
11
|
+
setDeepPartial: ObjectActionsSetDeepPartialDoAction<Value>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface IAtomSetDoActions<Value> {
|
|
2
|
+
/** like the Set.prototype.add() method */
|
|
3
|
+
add: (value: Value) => void;
|
|
4
|
+
|
|
5
|
+
/** like the Set.prototype.delete() method */
|
|
6
|
+
delete: (value: Value) => void;
|
|
7
|
+
|
|
8
|
+
/** will add value if it doesn't exist, otherwise delete */
|
|
9
|
+
toggle: (value: Value) => void;
|
|
10
|
+
|
|
11
|
+
/** like the Set.prototype.clear() method */
|
|
12
|
+
clear: () => void;
|
|
13
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { useSyncExternalStore } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { IAtomArrayDoActions } from './do.classes.model/IArray';
|
|
4
|
+
import { IAtomBooleanDoActions } from './do.classes.model/IBoolean';
|
|
5
|
+
import { IAtomMapDoActions } from './do.classes.model/IMap';
|
|
6
|
+
import { IAtomNumberDoActions } from './do.classes.model/INumber';
|
|
7
|
+
import { IAtomObjectDoActions } from './do.classes.model/IObject';
|
|
8
|
+
import { IAtomSetDoActions } from './do.classes.model/ISet';
|
|
9
9
|
import { Path, PathValue, PathValueDonor } from './paths';
|
|
10
10
|
|
|
11
11
|
export type AtomSecureLevel = 0 | 1 | 2 | 3;
|
|
@@ -80,17 +80,17 @@ export type ObjectActionsSetDeepPartialDoAction<Value> = <
|
|
|
80
80
|
) => void;
|
|
81
81
|
|
|
82
82
|
export type DefaultActions<Value> = Value extends Set<infer Val>
|
|
83
|
-
?
|
|
83
|
+
? IAtomSetDoActions<Val>
|
|
84
84
|
: Value extends Map<infer Key, infer Val>
|
|
85
|
-
?
|
|
85
|
+
? IAtomMapDoActions<Value, Key, Val>
|
|
86
86
|
: Value extends boolean
|
|
87
|
-
?
|
|
87
|
+
? IAtomBooleanDoActions
|
|
88
88
|
: Value extends (infer Val)[]
|
|
89
|
-
?
|
|
89
|
+
? IAtomArrayDoActions<Val>
|
|
90
90
|
: Value extends number
|
|
91
|
-
?
|
|
91
|
+
? IAtomNumberDoActions
|
|
92
92
|
: Value extends object
|
|
93
|
-
?
|
|
93
|
+
? IAtomObjectDoActions<Value>
|
|
94
94
|
: object;
|
|
95
95
|
|
|
96
96
|
declare class Atom<Value, Actions extends Record<string, AnyFunc> = Record<string, AnyFunc>> {
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { useSyncExternalStore } from 'react';
|
|
2
|
-
import { atom, configureAtomaric } from '../lib';
|
|
3
|
-
import { wait } from '../utils';
|
|
4
|
-
|
|
5
|
-
configureAtomaric({
|
|
6
|
-
useSyncExternalStore,
|
|
7
|
-
keyPathSeparator: '.',
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
describe('Array', () => {
|
|
11
|
-
test('simple init', async () => {
|
|
12
|
-
const initArray: number[] = [];
|
|
13
|
-
const testAtom = atom(initArray);
|
|
14
|
-
testAtom.set([]);
|
|
15
|
-
|
|
16
|
-
expect(testAtom.get() !== initArray).toBeTruthy();
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
test('do actions', async () => {
|
|
20
|
-
const testAtom = atom((): (number | nil | string | { nums: number[] })[] => [], {
|
|
21
|
-
do: (_set, _get, self) => ({
|
|
22
|
-
switch30(toggleValue: string) {
|
|
23
|
-
self.do.toggle(30);
|
|
24
|
-
self.do.toggle(toggleValue);
|
|
25
|
-
},
|
|
26
|
-
}),
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
testAtom.do.push(1, 2, 5, 2, 5, 5, 5, 5, 1, null, '', '#');
|
|
30
|
-
await wait();
|
|
31
|
-
|
|
32
|
-
expect(testAtom.get()).toEqual([1, 2, 5, 2, 5, 5, 5, 5, 1, null, '', '#']);
|
|
33
|
-
|
|
34
|
-
testAtom.do.add(0);
|
|
35
|
-
testAtom.do.add(5);
|
|
36
|
-
testAtom.do.add(8);
|
|
37
|
-
await wait();
|
|
38
|
-
|
|
39
|
-
expect(testAtom.get()).toEqual([1, 2, 5, 2, 5, 5, 5, 5, 1, null, '', '#', 0, 8]);
|
|
40
|
-
|
|
41
|
-
testAtom.do.removeFirst(5);
|
|
42
|
-
await wait();
|
|
43
|
-
|
|
44
|
-
expect(testAtom.get()).toEqual([1, 2, 2, 5, 5, 5, 5, 1, null, '', '#', 0, 8]);
|
|
45
|
-
|
|
46
|
-
testAtom.do.toggle('+');
|
|
47
|
-
await wait();
|
|
48
|
-
|
|
49
|
-
expect(testAtom.get()).toEqual([1, 2, 2, 5, 5, 5, 5, 1, null, '', '#', 0, 8, '+']);
|
|
50
|
-
|
|
51
|
-
testAtom.do.toggle('+');
|
|
52
|
-
await wait();
|
|
53
|
-
|
|
54
|
-
expect(testAtom.get()).toEqual([1, 2, 2, 5, 5, 5, 5, 1, null, '', '#', 0, 8]);
|
|
55
|
-
|
|
56
|
-
testAtom.do.switch30('@');
|
|
57
|
-
await wait();
|
|
58
|
-
|
|
59
|
-
expect(testAtom.get()).toEqual([1, 2, 2, 5, 5, 5, 5, 1, null, '', '#', 0, 8, 30, '@']);
|
|
60
|
-
|
|
61
|
-
testAtom.do.unshift('**');
|
|
62
|
-
await wait();
|
|
63
|
-
|
|
64
|
-
expect(testAtom.get()).toEqual(['**', 1, 2, 2, 5, 5, 5, 5, 1, null, '', '#', 0, 8, 30, '@']);
|
|
65
|
-
|
|
66
|
-
testAtom.do.filter();
|
|
67
|
-
await wait();
|
|
68
|
-
|
|
69
|
-
expect(testAtom.get()).toEqual(['**', 1, 2, 2, 5, 5, 5, 5, 1, '#', 8, 30, '@']);
|
|
70
|
-
|
|
71
|
-
testAtom.do.filter(val => typeof val === 'string');
|
|
72
|
-
await wait();
|
|
73
|
-
|
|
74
|
-
expect(testAtom.get()).toEqual(['**', '#', '@']);
|
|
75
|
-
|
|
76
|
-
testAtom.do.update(val => val.reverse());
|
|
77
|
-
await wait();
|
|
78
|
-
|
|
79
|
-
expect(testAtom.get()).toEqual(['@', '#', '**']);
|
|
80
|
-
|
|
81
|
-
const nums555 = { nums: [5, 5, 5] };
|
|
82
|
-
const nums123 = { nums: [1, 2, 3] };
|
|
83
|
-
|
|
84
|
-
testAtom.do.add(nums123);
|
|
85
|
-
testAtom.do.add(nums555);
|
|
86
|
-
await wait();
|
|
87
|
-
|
|
88
|
-
expect(testAtom.get()).toEqual(['@', '#', '**', nums123, nums555]);
|
|
89
|
-
|
|
90
|
-
testAtom.do.update(val => {
|
|
91
|
-
if (val[3] && typeof val[3] === 'object' && 'nums' in val[3]) val[3].nums.reverse();
|
|
92
|
-
});
|
|
93
|
-
await wait();
|
|
94
|
-
|
|
95
|
-
expect(testAtom.get()).toEqual(['@', '#', '**', { nums: [3, 2, 1] }, nums555]);
|
|
96
|
-
|
|
97
|
-
expect(testAtom.get()[4] === nums555).toBeTruthy();
|
|
98
|
-
expect(testAtom.get()[3] !== nums123).toBeTruthy();
|
|
99
|
-
|
|
100
|
-
const value = testAtom.get();
|
|
101
|
-
expect(value[3] && typeof value[3] === 'object' && value[3].nums !== nums123.nums).toBeTruthy();
|
|
102
|
-
});
|
|
103
|
-
});
|
package/src/do.classes/Array.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { Atom } from '../../types';
|
|
3
|
-
import { AtomUpdateDoAction } from './_Update';
|
|
4
|
-
|
|
5
|
-
export class AtomArrayDoActions<Value> extends AtomUpdateDoAction {
|
|
6
|
-
constructor(private a: Atom<Value[]>, actions: Record<string, AnyFunc> | nil) {
|
|
7
|
-
super(actions);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/** like the Array.prototype.push() method */
|
|
11
|
-
push = (...values: Value[]) => {
|
|
12
|
-
if (values.length === 0) return;
|
|
13
|
-
this.a.set(this.a.get().concat(values));
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
/** like the Array.prototype.unshift() method */
|
|
17
|
-
unshift = (...values: Value[]) => {
|
|
18
|
-
if (values.length === 0) return;
|
|
19
|
-
this.a.set(values.concat(this.a.get()));
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/** transform current taken value */
|
|
23
|
-
update = (updater: (value: Value[]) => void) => {
|
|
24
|
-
const prev = this.a.get();
|
|
25
|
-
const newValue = this.updateValue(prev, updater);
|
|
26
|
-
if (newValue === prev) return;
|
|
27
|
-
this.a.set(newValue);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/** like the Array.prototype.filter() method, but callback is optional - (it) => !!it */
|
|
31
|
-
filter = (filter?: (value: Value, index: number, Array: Value[]) => any) => {
|
|
32
|
-
const filtered = this.a.get().filter(filter ?? itIt);
|
|
33
|
-
if (filtered.length === this.a.get().length) return;
|
|
34
|
-
this.a.set(filtered);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/** will add value if not exists */
|
|
38
|
-
add = (value: Value) => {
|
|
39
|
-
if (this.a.get().includes(value)) return;
|
|
40
|
-
this.a.set(this.a.get().concat([value]));
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/** will delete value from array */
|
|
44
|
-
removeFirst = (value: Value) => {
|
|
45
|
-
const index = this.a.get().indexOf(value);
|
|
46
|
-
if (index < 0) return;
|
|
47
|
-
const newArray = this.a.get().slice(0);
|
|
48
|
-
newArray.splice(index, 1);
|
|
49
|
-
this.a.set(newArray);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
/** will add value if it doesn't exist, otherwise delete */
|
|
53
|
-
toggle = (value: Value, isAddToStart?: boolean) => {
|
|
54
|
-
const newArray = this.a.get().slice();
|
|
55
|
-
const index = newArray.indexOf(value);
|
|
56
|
-
|
|
57
|
-
if (index < 0) {
|
|
58
|
-
if (isAddToStart) newArray.unshift(value);
|
|
59
|
-
else newArray.push(value);
|
|
60
|
-
} else newArray.splice(index, 1);
|
|
61
|
-
|
|
62
|
-
this.a.set(newArray);
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const itIt = <It>(it: It) => it;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { useSyncExternalStore } from 'react';
|
|
2
|
-
import { atom, configureAtomaric } from '../lib';
|
|
3
|
-
import { wait } from '../utils';
|
|
4
|
-
|
|
5
|
-
configureAtomaric({
|
|
6
|
-
useSyncExternalStore,
|
|
7
|
-
keyPathSeparator: '.',
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
describe('Boolean', () => {
|
|
11
|
-
test('do actions', async () => {
|
|
12
|
-
const testAtom = atom(false, {
|
|
13
|
-
do: (set, get) => ({
|
|
14
|
-
switch(news?: boolean) {
|
|
15
|
-
set(news ?? !get());
|
|
16
|
-
},
|
|
17
|
-
}),
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
testAtom.do.switch(true);
|
|
21
|
-
testAtom.do.switch();
|
|
22
|
-
testAtom.do.toggle();
|
|
23
|
-
await wait();
|
|
24
|
-
|
|
25
|
-
expect(testAtom.get() === true).toBeTruthy();
|
|
26
|
-
});
|
|
27
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Atom } from '../../types';
|
|
2
|
-
import { AtomDoActionsBasic } from './_Basic';
|
|
3
|
-
|
|
4
|
-
export class AtomBooleanDoActions extends AtomDoActionsBasic {
|
|
5
|
-
constructor(private a: Atom<boolean>, actions: Record<string, AnyFunc> | nil) {
|
|
6
|
-
super(actions);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/** toggle current value between true/false */
|
|
10
|
-
toggle = () => {
|
|
11
|
-
this.a.set(!this.a.get());
|
|
12
|
-
};
|
|
13
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { useSyncExternalStore } from 'react';
|
|
2
|
-
import { atom, configureAtomaric } from '../lib';
|
|
3
|
-
import { makeFullKey, wait } from '../utils';
|
|
4
|
-
|
|
5
|
-
configureAtomaric({
|
|
6
|
-
useSyncExternalStore,
|
|
7
|
-
keyPathSeparator: '.',
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
describe('Map', () => {
|
|
11
|
-
type Value = number | { asasa: '' };
|
|
12
|
-
const testAtom = atom(new Map<string, Value>(), {
|
|
13
|
-
storeKey: 'map:test',
|
|
14
|
-
do: (set, get) => ({
|
|
15
|
-
filterKeyValues: () => {
|
|
16
|
-
const newMap = new Map();
|
|
17
|
-
get().forEach((value, key) => {
|
|
18
|
-
if (value) newMap.set(key, value);
|
|
19
|
-
});
|
|
20
|
-
set(newMap);
|
|
21
|
-
},
|
|
22
|
-
}),
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test('do.setValue()', async () => {
|
|
26
|
-
testAtom.do.setValue('!', 1);
|
|
27
|
-
testAtom.do.setValue('@', 0);
|
|
28
|
-
testAtom.do.setValue('#', { asasa: '' });
|
|
29
|
-
testAtom.do.setValue('', 123);
|
|
30
|
-
await wait();
|
|
31
|
-
|
|
32
|
-
expect(localStorage[makeFullKey('map:test')]).toEqual('[[["!",1],["@",0],["#",{"asasa":""}],["",123]]]');
|
|
33
|
-
|
|
34
|
-
expect(testAtom.get()).toEqual(
|
|
35
|
-
new Map<string, Value>([
|
|
36
|
-
['!', 1],
|
|
37
|
-
['@', 0],
|
|
38
|
-
['#', { asasa: '' }],
|
|
39
|
-
['', 123],
|
|
40
|
-
]),
|
|
41
|
-
);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test('do.<filterKeyValues>()', async () => {
|
|
45
|
-
testAtom.do.filterKeyValues();
|
|
46
|
-
await wait();
|
|
47
|
-
|
|
48
|
-
expect(localStorage[makeFullKey('map:test')]).toEqual('[[["!",1],["#",{"asasa":""}],["",123]]]');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test('do.delete()', async () => {
|
|
52
|
-
testAtom.do.delete('#');
|
|
53
|
-
await wait();
|
|
54
|
-
|
|
55
|
-
expect(localStorage[makeFullKey('map:test')]).toEqual('[[["!",1],["",123]]]');
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
test('do.toggle()', async () => {
|
|
59
|
-
testAtom.do.toggle('#', 555);
|
|
60
|
-
await wait();
|
|
61
|
-
|
|
62
|
-
expect(localStorage[makeFullKey('map:test')]).toEqual('[[["!",1],["",123],["#",555]]]');
|
|
63
|
-
|
|
64
|
-
testAtom.do.toggle('', 999);
|
|
65
|
-
testAtom.do.toggle('!', 1234567890);
|
|
66
|
-
await wait();
|
|
67
|
-
|
|
68
|
-
expect(localStorage[makeFullKey('map:test')]).toEqual('[[["#",555]]]');
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
test('do.clear()', async () => {
|
|
72
|
-
testAtom.do.clear();
|
|
73
|
-
await wait();
|
|
74
|
-
|
|
75
|
-
expect(localStorage[makeFullKey('map:test')]).toEqual('[[]]');
|
|
76
|
-
});
|
|
77
|
-
});
|
package/src/do.classes/Map.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { Atom } from '../../types';
|
|
3
|
-
import { AtomDoActionsBasic } from './_Basic';
|
|
4
|
-
|
|
5
|
-
export class AtomMapDoActions<
|
|
6
|
-
MapValue extends Map<any, any>,
|
|
7
|
-
Key extends MapValue extends Map<infer K, any> ? K : never,
|
|
8
|
-
Value extends MapValue extends Map<any, infer V> ? V : never,
|
|
9
|
-
> extends AtomDoActionsBasic {
|
|
10
|
-
constructor(private a: Atom<MapValue>, actions: Record<string, AnyFunc> | nil) {
|
|
11
|
-
super(actions);
|
|
12
|
-
this.a = a;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** like the Map.prototype.set() method, when value is new for key in current atom value */
|
|
16
|
-
setValue = (key: Key, value: Value) => {
|
|
17
|
-
if (this.a.get().get(key) === value) return;
|
|
18
|
-
|
|
19
|
-
const newMap = new Map(this.a.get());
|
|
20
|
-
newMap.set(key, value);
|
|
21
|
-
|
|
22
|
-
this.a.set(newMap as never);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/** like the Map.prototype.set() method, when key is not exists */
|
|
26
|
-
setIfNo = (key: Key, value: Value) => {
|
|
27
|
-
if (this.a.get().has(key)) return;
|
|
28
|
-
|
|
29
|
-
const newMap = new Map(this.a.get());
|
|
30
|
-
newMap.set(key, value);
|
|
31
|
-
|
|
32
|
-
this.a.set(newMap as never);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/** like the Map.prototype.delete() method */
|
|
36
|
-
delete = (key: Key) => {
|
|
37
|
-
if (!this.a.get().has(key)) return;
|
|
38
|
-
|
|
39
|
-
const newMap = new Map(this.a.get());
|
|
40
|
-
newMap.delete(key);
|
|
41
|
-
|
|
42
|
-
this.a.set(newMap as never);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
/** will add value if it doesn't exist, otherwise delete */
|
|
46
|
-
toggle = (key: Key, value: Value) => {
|
|
47
|
-
const newMap = new Map(this.a.get());
|
|
48
|
-
|
|
49
|
-
if (newMap.has(key)) newMap.delete(key);
|
|
50
|
-
else newMap.set(key, value);
|
|
51
|
-
|
|
52
|
-
this.a.set(newMap as never);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
/** like the Map.prototype.clear() method */
|
|
56
|
-
clear = () => {
|
|
57
|
-
this.a.set(new Map() as never);
|
|
58
|
-
};
|
|
59
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { useSyncExternalStore } from 'react';
|
|
2
|
-
import { atom, configureAtomaric } from '../lib';
|
|
3
|
-
import { wait } from '../utils';
|
|
4
|
-
|
|
5
|
-
configureAtomaric({
|
|
6
|
-
useSyncExternalStore,
|
|
7
|
-
keyPathSeparator: '.',
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
describe('Number', () => {
|
|
11
|
-
test('do actions', async () => {
|
|
12
|
-
const testAtom = atom(100, { do: (set, get) => ({ switchSign: () => set(-get()) }) });
|
|
13
|
-
const testFuncAtom = atom(() => 200, { do: (set, get) => ({ switchSign: () => set(-get()) }) });
|
|
14
|
-
|
|
15
|
-
testAtom.do.increment();
|
|
16
|
-
testAtom.do.switchSign();
|
|
17
|
-
|
|
18
|
-
testFuncAtom.do.increment(-3);
|
|
19
|
-
testFuncAtom.do.switchSign();
|
|
20
|
-
await wait();
|
|
21
|
-
|
|
22
|
-
expect(testAtom.get()).toEqual(-101);
|
|
23
|
-
expect(testFuncAtom.get()).toEqual(-197);
|
|
24
|
-
});
|
|
25
|
-
});
|
package/src/do.classes/Number.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { Atom } from '../../types';
|
|
2
|
-
import { AtomDoActionsBasic } from './_Basic';
|
|
3
|
-
|
|
4
|
-
export class AtomNumberDoActions extends AtomDoActionsBasic {
|
|
5
|
-
constructor(private a: Atom<number>, actions: Record<string, AnyFunc> | nil) {
|
|
6
|
-
super(actions);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/** pass the 2 to increment on 2, pass the -2 to decrement on 2
|
|
10
|
-
* **default: 1**
|
|
11
|
-
*/
|
|
12
|
-
increment = (delta?: number) => {
|
|
13
|
-
this.a.set(+this.a.get() + (delta ?? 1));
|
|
14
|
-
};
|
|
15
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { useSyncExternalStore } from 'react';
|
|
2
|
-
import { atom, configureAtomaric } from '../lib';
|
|
3
|
-
import { wait } from '../utils';
|
|
4
|
-
|
|
5
|
-
configureAtomaric({
|
|
6
|
-
useSyncExternalStore,
|
|
7
|
-
keyPathSeparator: '.',
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
describe('Object', () => {
|
|
11
|
-
test('do.setDeepPartial()', async () => {
|
|
12
|
-
const b = { c: [{ d: 8, e: 'e', f: 'F', g: { h: 'HHH' } }] };
|
|
13
|
-
const a = { f: { g: '' }, b };
|
|
14
|
-
const testAtom = atom({ a, b });
|
|
15
|
-
|
|
16
|
-
testAtom.do.setDeepPartial('b.c.0.d', 123, { b: { c: [{}] } });
|
|
17
|
-
|
|
18
|
-
await wait();
|
|
19
|
-
|
|
20
|
-
expect(testAtom.get().b).not.toEqual(b);
|
|
21
|
-
expect(testAtom.get().b.c[0].d).toEqual(123);
|
|
22
|
-
expect(testAtom.get().b.c).not.toEqual(b.c);
|
|
23
|
-
expect(testAtom.get().a).toEqual(a);
|
|
24
|
-
|
|
25
|
-
testAtom.do.setDeepPartial('b+c+8+e', 'EE', null, '+');
|
|
26
|
-
|
|
27
|
-
await wait();
|
|
28
|
-
|
|
29
|
-
expect(testAtom.get().b.c[8].e).toEqual('EE');
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
test('do.setDeepPartial() with first numeric prop', async () => {
|
|
33
|
-
enum Num {
|
|
34
|
-
num = 123,
|
|
35
|
-
}
|
|
36
|
-
const testAtom = atom({ [Num.num]: { a: 'A' } });
|
|
37
|
-
|
|
38
|
-
testAtom.do.setDeepPartial(`${Num.num}.a`, 'AA', { [Num.num]: {} });
|
|
39
|
-
|
|
40
|
-
await wait();
|
|
41
|
-
|
|
42
|
-
expect(testAtom.get()[Num.num].a).toEqual('AA');
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
test('do.setPartial()', async () => {
|
|
46
|
-
const testAtom = atom((): Record<number, unknown> => ({ 2: { a: 'A' } }));
|
|
47
|
-
|
|
48
|
-
testAtom.do.setPartial({ 3: { b: 'B' } });
|
|
49
|
-
testAtom.do.setPartial({ 4: [] });
|
|
50
|
-
await wait();
|
|
51
|
-
|
|
52
|
-
expect(testAtom.get()).toEqual({ 2: { a: 'A' }, 3: { b: 'B' }, 4: [] });
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test('do.update()', async () => {
|
|
56
|
-
const init = { a: { b: { c: { d: { e: 'E' } }, f: { g: {} } }, h: { i: { j: {} } } } };
|
|
57
|
-
const testAtom = atom(init);
|
|
58
|
-
|
|
59
|
-
testAtom.do.update(obj => (obj.a.b.c.d.e = 'eE'));
|
|
60
|
-
|
|
61
|
-
await wait();
|
|
62
|
-
|
|
63
|
-
expect(testAtom.get().a.b.c.d.e).toEqual('eE');
|
|
64
|
-
expect(testAtom.get().a.b.c).not.toEqual(init.a.b.c);
|
|
65
|
-
expect(testAtom.get().a.h.i).toEqual(init.a.h.i);
|
|
66
|
-
});
|
|
67
|
-
});
|
package/src/do.classes/Object.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { Atom, ObjectActionsSetDeepPartialDoAction } from '../../types';
|
|
2
|
-
import { configuredOptions } from '../lib';
|
|
3
|
-
import { AtomUpdateDoAction } from './_Update';
|
|
4
|
-
|
|
5
|
-
export class AtomObjectDoActions<Value extends object> extends AtomUpdateDoAction {
|
|
6
|
-
constructor(private a: Atom<Value>, actions: Record<string, AnyFunc> | nil) {
|
|
7
|
-
super(actions);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/** pass partial object to update some field values */
|
|
11
|
-
setPartial = (value: Partial<Value> | ((value: Value) => Partial<Value>)) =>
|
|
12
|
-
this.a.set(prev => ({
|
|
13
|
-
...prev,
|
|
14
|
-
...(typeof value === 'function' ? value(this.a.get()) : value),
|
|
15
|
-
}));
|
|
16
|
-
|
|
17
|
-
/** transform current taken value */
|
|
18
|
-
update = (updater: (value: Value) => void) => {
|
|
19
|
-
const prev = this.a.get();
|
|
20
|
-
const newValue = this.updateValue(prev, updater);
|
|
21
|
-
if (newValue === prev) return;
|
|
22
|
-
this.a.set(newValue);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/** pass partial value to update some deep values by flat path */
|
|
26
|
-
setDeepPartial: ObjectActionsSetDeepPartialDoAction<Value> = (
|
|
27
|
-
path,
|
|
28
|
-
value,
|
|
29
|
-
donor,
|
|
30
|
-
separator = (configuredOptions.keyPathSeparator || '.') as never,
|
|
31
|
-
) => {
|
|
32
|
-
if (!separator) return;
|
|
33
|
-
|
|
34
|
-
if (path.includes(separator)) {
|
|
35
|
-
let keys = path.split(separator);
|
|
36
|
-
const lastKey = keys[keys.length - 1];
|
|
37
|
-
keys = keys.slice(0, -1);
|
|
38
|
-
const newObject = { ...this.a.get() };
|
|
39
|
-
let lastObject = newObject as Record<string, unknown>;
|
|
40
|
-
let lastDonorObject = donor as Record<string, unknown> | nil;
|
|
41
|
-
|
|
42
|
-
for (const key of keys) {
|
|
43
|
-
lastDonorObject = lastDonorObject?.[Array.isArray(lastDonorObject) ? '0' : key] as never;
|
|
44
|
-
const currentObject = lastObject[makeKey(lastObject, key)] ?? (Array.isArray(lastDonorObject) ? [] : {});
|
|
45
|
-
|
|
46
|
-
if (currentObject == null || typeof currentObject !== 'object') {
|
|
47
|
-
if (donor == null) throw 'Incorrect path for setDeepPartial';
|
|
48
|
-
|
|
49
|
-
const newValue = typeof value === 'function' ? (value as (val: undefined) => Value)(undefined) : value;
|
|
50
|
-
|
|
51
|
-
if (this.a.get()[path as never] !== newValue) this.setPartial({ [path]: newValue } as never);
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
lastObject = lastObject[makeKey(lastObject, key)] = (
|
|
56
|
-
Array.isArray(currentObject) ? [...currentObject] : { ...currentObject }
|
|
57
|
-
) as never;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const prev = lastObject[lastKey];
|
|
61
|
-
lastObject[lastKey] =
|
|
62
|
-
typeof value === 'function' ? (value as (val: unknown) => Value)(lastObject[lastKey]) : value;
|
|
63
|
-
|
|
64
|
-
if (prev !== lastObject[lastKey]) this.a.set(newObject);
|
|
65
|
-
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const prevValue = this.a.get()[path as never];
|
|
70
|
-
const newValue = typeof value === 'function' ? (value as (val: Value) => Value)(prevValue) : value;
|
|
71
|
-
if (newValue !== prevValue) this.setPartial({ [path]: newValue } as never);
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const makeKey = (obj: object, key: string) => (Array.isArray(obj) ? `${+key}` : key);
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { useSyncExternalStore } from 'react';
|
|
2
|
-
import { atom, configureAtomaric } from '../lib';
|
|
3
|
-
import { makeFullKey, wait } from '../utils';
|
|
4
|
-
|
|
5
|
-
configureAtomaric({
|
|
6
|
-
useSyncExternalStore,
|
|
7
|
-
keyPathSeparator: '.',
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
describe('Set', () => {
|
|
11
|
-
test('do actions', async () => {
|
|
12
|
-
const testAtom = atom(new Set<string>(), {
|
|
13
|
-
storeKey: 'set:test',
|
|
14
|
-
do: (set, get) => ({
|
|
15
|
-
filterValues: () => {
|
|
16
|
-
const array = Array.from(get());
|
|
17
|
-
set(new Set(array.filter(it => it)));
|
|
18
|
-
},
|
|
19
|
-
}),
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
testAtom.do.add('!');
|
|
23
|
-
testAtom.do.add('@');
|
|
24
|
-
testAtom.do.add('#');
|
|
25
|
-
testAtom.do.add('');
|
|
26
|
-
await wait();
|
|
27
|
-
|
|
28
|
-
expect(localStorage[makeFullKey('set:test')]).toEqual('[["!","@","#",""]]');
|
|
29
|
-
|
|
30
|
-
testAtom.do.filterValues();
|
|
31
|
-
await wait();
|
|
32
|
-
|
|
33
|
-
expect(localStorage[makeFullKey('set:test')]).toEqual('[["!","@","#"]]');
|
|
34
|
-
|
|
35
|
-
testAtom.do.toggle('@');
|
|
36
|
-
await wait();
|
|
37
|
-
|
|
38
|
-
expect(localStorage[makeFullKey('set:test')]).toEqual('[["!","#"]]');
|
|
39
|
-
|
|
40
|
-
testAtom.do.toggle('@');
|
|
41
|
-
testAtom.do.delete('!');
|
|
42
|
-
await wait();
|
|
43
|
-
|
|
44
|
-
expect(localStorage[makeFullKey('set:test')]).toEqual('[["#","@"]]');
|
|
45
|
-
});
|
|
46
|
-
});
|
package/src/do.classes/Set.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { Atom } from '../../types';
|
|
2
|
-
import { AtomDoActionsBasic } from './_Basic';
|
|
3
|
-
|
|
4
|
-
export class AtomSetDoActions<Value> extends AtomDoActionsBasic {
|
|
5
|
-
constructor(private a: Atom<Set<Value>>, actions: Record<string, AnyFunc> | nil) {
|
|
6
|
-
super(actions);
|
|
7
|
-
this.a = a;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/** like the Set.prototype.add() method */
|
|
11
|
-
add = (value: Value) => {
|
|
12
|
-
if (this.a.get().has(value)) return;
|
|
13
|
-
|
|
14
|
-
this.a.set(new Set(this.a.get()).add(value));
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/** like the Set.prototype.delete() method */
|
|
18
|
-
delete = (value: Value) => {
|
|
19
|
-
if (!this.a.get().has(value)) return;
|
|
20
|
-
|
|
21
|
-
const newSet = new Set(this.a.get());
|
|
22
|
-
newSet.delete(value);
|
|
23
|
-
this.a.set(newSet);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/** will add value if it doesn't exist, otherwise delete */
|
|
27
|
-
toggle = (value: Value) => {
|
|
28
|
-
const newSet = new Set(this.a.get());
|
|
29
|
-
|
|
30
|
-
if (newSet.has(value)) newSet.delete(value);
|
|
31
|
-
else newSet.add(value);
|
|
32
|
-
|
|
33
|
-
this.a.set(newSet);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/** like the Set.prototype.clear() method */
|
|
37
|
-
clear = () => {
|
|
38
|
-
this.a.set(new Set());
|
|
39
|
-
};
|
|
40
|
-
}
|
package/src/do.classes/_Basic.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { makeDeepProxyObject } from '../makeDeepProxyObject';
|
|
2
|
-
import { AtomDoActionsBasic } from './_Basic';
|
|
3
|
-
|
|
4
|
-
export class AtomUpdateDoAction extends AtomDoActionsBasic {
|
|
5
|
-
protected updateValue = <Object extends object | unknown[]>(
|
|
6
|
-
object: Object,
|
|
7
|
-
updater: (object: Object) => void,
|
|
8
|
-
): Object => {
|
|
9
|
-
const newObject = Array.isArray(object) ? object.slice(0) : { ...object };
|
|
10
|
-
let isSomeSetted = false;
|
|
11
|
-
|
|
12
|
-
const pro = makeDeepProxyObject(object, {
|
|
13
|
-
onSet: (_, keys, setKey, value, prevValue) => {
|
|
14
|
-
if (value === prevValue) return true;
|
|
15
|
-
let currentObject = newObject as Record<string, unknown> | unknown[];
|
|
16
|
-
|
|
17
|
-
isSomeSetted = true;
|
|
18
|
-
|
|
19
|
-
for (const key of keys) {
|
|
20
|
-
const nextObject = currentObject[key as never] as object;
|
|
21
|
-
|
|
22
|
-
currentObject = currentObject[key as never] = (
|
|
23
|
-
Array.isArray(nextObject) ? nextObject.slice() : { ...nextObject }
|
|
24
|
-
) as never;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
currentObject[setKey as never] = value as never;
|
|
28
|
-
|
|
29
|
-
return true;
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
updater(pro);
|
|
34
|
-
|
|
35
|
-
return isSomeSetted ? (newObject as never) : object;
|
|
36
|
-
};
|
|
37
|
-
}
|