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 +29 -29
- package/build/atomaric.js +154 -130
- package/build/atomaric.umd.cjs +1 -1
- package/package.json +44 -44
- package/types/model.d.ts +151 -149
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
|
|
2
|
-
let
|
|
3
|
-
typeof
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
10
|
-
|
|
9
|
+
})
|
|
10
|
+
) : typeof e == "boolean" ? f = T(
|
|
11
|
+
n,
|
|
12
|
+
(s) => ({
|
|
11
13
|
toggle: () => {
|
|
12
|
-
|
|
14
|
+
s.set(!s.get());
|
|
13
15
|
}
|
|
14
|
-
}
|
|
15
|
-
) : Array.isArray(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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: (...
|
|
21
|
-
|
|
23
|
+
unshift: (...r) => {
|
|
24
|
+
s.set(r.concat(s.get()));
|
|
22
25
|
},
|
|
23
|
-
update: (
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
+
update: (r) => {
|
|
27
|
+
const c = s.get().slice();
|
|
28
|
+
r(c), s.set(c);
|
|
26
29
|
},
|
|
27
|
-
filter: (
|
|
28
|
-
|
|
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
|
-
) :
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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: (
|
|
37
|
-
const
|
|
38
|
-
|
|
44
|
+
delete: (r) => {
|
|
45
|
+
const c = new Set(s.get());
|
|
46
|
+
c.delete(r), s.set(c);
|
|
39
47
|
},
|
|
40
|
-
toggle: (
|
|
41
|
-
const
|
|
42
|
-
|
|
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
|
-
|
|
53
|
+
s.set(/* @__PURE__ */ new Set());
|
|
46
54
|
},
|
|
47
|
-
update: (
|
|
48
|
-
const
|
|
49
|
-
|
|
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
|
|
61
|
-
(s, r) =>
|
|
62
|
-
() =>
|
|
63
|
-
|
|
64
|
-
(s, r,
|
|
65
|
-
) : null,
|
|
66
|
-
return
|
|
67
|
-
(s) => Object.defineProperty(
|
|
68
|
-
),
|
|
69
|
-
},
|
|
70
|
-
class
|
|
71
|
-
constructor(
|
|
72
|
-
const
|
|
73
|
-
let r =
|
|
74
|
-
},
|
|
75
|
-
const t =
|
|
76
|
-
return
|
|
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
|
|
79
|
-
get: (t,
|
|
80
|
-
set:
|
|
81
|
-
}),
|
|
82
|
-
const
|
|
83
|
-
if (!(
|
|
84
|
-
|
|
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:
|
|
99
|
+
C.postMessage({ key: i, value: a() });
|
|
87
100
|
} catch {
|
|
88
101
|
}
|
|
89
|
-
|
|
102
|
+
u !== !0 && w(g);
|
|
90
103
|
}
|
|
91
104
|
};
|
|
92
|
-
this.set = (t,
|
|
93
|
-
|
|
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
|
-
|
|
108
|
+
A(n, !0), h.forEach(s, this);
|
|
96
109
|
};
|
|
97
|
-
const
|
|
98
|
-
|
|
110
|
+
const M = (t, u) => {
|
|
111
|
+
A(t, u), c = void 0;
|
|
99
112
|
};
|
|
100
|
-
if (this.setDeferred = (t,
|
|
101
|
-
|
|
102
|
-
},
|
|
103
|
-
let
|
|
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
|
|
108
|
-
|
|
109
|
-
else if ("storeKey" in
|
|
110
|
-
|
|
111
|
-
else return
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
return
|
|
115
|
-
}
|
|
116
|
-
let
|
|
117
|
-
if (o[`atom/${
|
|
118
|
-
if (
|
|
119
|
-
|
|
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
|
-
|
|
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
|
|
127
|
-
},
|
|
128
|
-
if (t ===
|
|
139
|
+
return a();
|
|
140
|
+
}, w = (t) => {
|
|
141
|
+
if (t === n) {
|
|
129
142
|
this.reset();
|
|
130
143
|
return;
|
|
131
144
|
}
|
|
132
|
-
o[i] =
|
|
145
|
+
o[i] = V(t);
|
|
133
146
|
}, this.reset = () => {
|
|
134
|
-
delete o[i],
|
|
135
|
-
},
|
|
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,
|
|
138
|
-
|
|
139
|
-
clearTimeout(
|
|
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
|
-
|
|
155
|
+
m[i] = (t) => {
|
|
143
156
|
if (t.newValue === null) {
|
|
144
157
|
this.reset();
|
|
145
158
|
return;
|
|
146
159
|
}
|
|
147
160
|
try {
|
|
148
|
-
|
|
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", (
|
|
159
|
-
var
|
|
160
|
-
(
|
|
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,
|
|
165
|
-
throw `${
|
|
177
|
+
const o = window.localStorage, m = {}, y = {}, U = (e, n) => {
|
|
178
|
+
throw `${n} is readonly property`;
|
|
166
179
|
};
|
|
167
|
-
window.addEventListener("storage", (
|
|
168
|
-
var
|
|
169
|
-
|
|
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
|
|
172
|
-
o.setItem = (
|
|
173
|
-
|
|
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 = (
|
|
176
|
-
|
|
188
|
+
o.removeItem = (e) => {
|
|
189
|
+
y[e] === void 0 && q.call(o, e);
|
|
177
190
|
};
|
|
178
|
-
|
|
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
|
|
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
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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
|
};
|
package/build/atomaric.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
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.
|
|
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
|
-
"
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
?
|
|
96
|
-
: Value extends
|
|
97
|
-
?
|
|
98
|
-
: Value extends
|
|
99
|
-
?
|
|
100
|
-
: Value extends
|
|
101
|
-
?
|
|
102
|
-
:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
readonly
|
|
111
|
-
/**
|
|
112
|
-
readonly
|
|
113
|
-
/** set current value
|
|
114
|
-
readonly
|
|
115
|
-
/** set current value
|
|
116
|
-
readonly
|
|
117
|
-
/**
|
|
118
|
-
readonly
|
|
119
|
-
/**
|
|
120
|
-
readonly
|
|
121
|
-
/**
|
|
122
|
-
readonly
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
export function
|
|
131
|
-
|
|
132
|
-
export function
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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;
|