atomaric 0.0.45 → 0.0.60
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 +181 -179
- package/build/atomaric.umd.cjs +1 -1
- package/package.json +10 -8
- package/src/class.ts +295 -0
- package/src/globals.d.ts +52 -0
- package/src/index.ts +2 -0
- package/src/lib.ts +36 -0
- package/src/makeDeepProxyObject.ts +35 -0
- package/src/makeDoFillerActions.ts +225 -0
- package/src/test.tsx +207 -0
- package/types/index.d.ts +6 -6
- package/types/paths.ts +3 -3
package/src/test.tsx
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import React, { useEffect, useSyncExternalStore } from 'react';
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import { atom, configureAtomaric, useAtomDo, useAtomValue } from './lib';
|
|
4
|
+
|
|
5
|
+
configureAtomaric({ useSyncExternalStore, keyPathSeparator: '.' });
|
|
6
|
+
|
|
7
|
+
createRoot(document.getElementById('root')!).render(
|
|
8
|
+
<React.StrictMode>
|
|
9
|
+
<App />
|
|
10
|
+
</React.StrictMode>,
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const testAtom = atom(new Set<number>(), {
|
|
14
|
+
storeKey: 'test:set',
|
|
15
|
+
do: set => ({
|
|
16
|
+
update12: () => set(prev => new Set(prev).add(12)),
|
|
17
|
+
}),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const testTextAtom = atom('', {
|
|
21
|
+
storeKey: 'test:text',
|
|
22
|
+
unchangable: true,
|
|
23
|
+
exp: () => new Date(Date.now() + 3 * 1000),
|
|
24
|
+
|
|
25
|
+
zipValue: value => ({ value }),
|
|
26
|
+
unzipValue: val => val.value,
|
|
27
|
+
|
|
28
|
+
do: set => ({
|
|
29
|
+
addText: (text: string) => {
|
|
30
|
+
set(prev => prev + text);
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const array: (number | '')[] = [3, 1, 7, 4, 8, 9, 5];
|
|
36
|
+
const arrayAtom = atom(array, {
|
|
37
|
+
do: () => ({
|
|
38
|
+
nothing: () => {},
|
|
39
|
+
}),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
console.info(Object.keys(arrayAtom));
|
|
43
|
+
// arrayAtom.do.filter = {};
|
|
44
|
+
|
|
45
|
+
console.info(arrayAtom);
|
|
46
|
+
arrayAtom.do.push(0);
|
|
47
|
+
arrayAtom.do.nothing();
|
|
48
|
+
console.info(arrayAtom.get());
|
|
49
|
+
arrayAtom.do.unshift(-1);
|
|
50
|
+
console.info(arrayAtom.get());
|
|
51
|
+
arrayAtom.do.update(arr => arr.sort());
|
|
52
|
+
console.info(arrayAtom.get());
|
|
53
|
+
arrayAtom.do.filter();
|
|
54
|
+
console.info(arrayAtom.get());
|
|
55
|
+
|
|
56
|
+
atom(0, 'a:a');
|
|
57
|
+
atom(0, { storeKey: 'a:a' });
|
|
58
|
+
atom(0, { storeKey: 'a:a', warnOnDuplicateStoreKey: false });
|
|
59
|
+
|
|
60
|
+
(function testDeepPartialChanges() {
|
|
61
|
+
const b = { c: [{ d: 8, e: 'e', f: 'F' }] };
|
|
62
|
+
const a = { f: { g: '' }, b };
|
|
63
|
+
const deepTest = atom({ a, b });
|
|
64
|
+
|
|
65
|
+
deepTest.do.setDeepPartial('b.c.0.d', 123, { b: { c: [{}] } });
|
|
66
|
+
deepTest.do.setDeepPartial('b+c+8+e', 'EE', null, '+');
|
|
67
|
+
|
|
68
|
+
console.info(deepTest.get(), deepTest.get().a.f === a.f, deepTest.get().b.c === b.c);
|
|
69
|
+
})();
|
|
70
|
+
|
|
71
|
+
(function testDeepPartialChanges() {
|
|
72
|
+
const enum Id {
|
|
73
|
+
def = 0,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const deepTest = atom(
|
|
77
|
+
{} as Record<
|
|
78
|
+
Id,
|
|
79
|
+
{
|
|
80
|
+
in: { inin: [{ ininin: number }] }[];
|
|
81
|
+
out: { some: { req: 0 } };
|
|
82
|
+
else: { if: {} };
|
|
83
|
+
}
|
|
84
|
+
>,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
deepTest.do.setDeepPartial(`${Id.def}.in.${9}.inin.0`, { ininin: 9 }, { [Id.def]: { in: [{ inin: [] }] } });
|
|
88
|
+
console.info('Id.def', deepTest.get());
|
|
89
|
+
|
|
90
|
+
deepTest.do.setDeepPartial(`${Id.def}+in+ 4 +inin+0+ininin`, () => 7, { [Id.def]: { in: [{ inin: [{}] }] } }, '+');
|
|
91
|
+
console.info('Id.def', deepTest.get());
|
|
92
|
+
|
|
93
|
+
// will throw
|
|
94
|
+
// console.error(deepTest.get()[Id.def]?.out.some.req);
|
|
95
|
+
})();
|
|
96
|
+
|
|
97
|
+
(function testDeepPartialSetWithDonor() {
|
|
98
|
+
const a: {
|
|
99
|
+
val: {
|
|
100
|
+
b?: { c?: { f: { g?: { e: string } }[] }[] };
|
|
101
|
+
f: { l: number; g?: number };
|
|
102
|
+
};
|
|
103
|
+
} = { val: { f: { l: 9 } } };
|
|
104
|
+
|
|
105
|
+
const deepTest = atom(a);
|
|
106
|
+
|
|
107
|
+
deepTest.do.setDeepPartial('val.b.c.4.f', [{ g: { e: '^' } }], { val: { b: { c: [{}] } } });
|
|
108
|
+
deepTest.do.setDeepPartial('val.b.c.4.f.5.g', { e: '!!@' }, { val: { b: { c: [{ f: [{}] }] } } });
|
|
109
|
+
deepTest.do.setDeepPartial('val.b.c.4.f.2', { g: { e: '2' } }, { val: { b: { c: [{ f: [] }] } } });
|
|
110
|
+
deepTest.do.setDeepPartial('val.b.c.4.f.5.g.e', 'FIVE', { val: { b: { c: [{ f: [{ g: {} }] }] } } });
|
|
111
|
+
deepTest.do.setDeepPartial('val.f.l', 123, { val: { f: {} } });
|
|
112
|
+
|
|
113
|
+
deepTest.do.setDeepPartial('val***f***g', 777, { val: { f: {} } }, '***');
|
|
114
|
+
|
|
115
|
+
console.info(deepTest.get());
|
|
116
|
+
})();
|
|
117
|
+
|
|
118
|
+
(function testUpdate() {
|
|
119
|
+
const a: {
|
|
120
|
+
val: {
|
|
121
|
+
b: { c: { f: { g: { e: string } }[] }[] };
|
|
122
|
+
};
|
|
123
|
+
f: { l: { v: { r: number } }; g?: number };
|
|
124
|
+
num: number;
|
|
125
|
+
} = {
|
|
126
|
+
val: { b: { c: [{ f: [{ g: { e: '1' } }] }] } },
|
|
127
|
+
f: { l: { v: { r: 8 } } },
|
|
128
|
+
num: 8,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const updateTest = atom(a);
|
|
132
|
+
|
|
133
|
+
const prevF = a.val.b.c[0].f;
|
|
134
|
+
const prevV = a.f.l.v;
|
|
135
|
+
|
|
136
|
+
console.info(updateTest.get() === a);
|
|
137
|
+
|
|
138
|
+
updateTest.do.update(a => {
|
|
139
|
+
a.val.b.c[0].f[0].g.e = '2';
|
|
140
|
+
// a.num = 0;
|
|
141
|
+
});
|
|
142
|
+
console.info(
|
|
143
|
+
updateTest.get() === a,
|
|
144
|
+
prevF === a.val.b.c[0].f,
|
|
145
|
+
prevV === updateTest.get().f.l.v,
|
|
146
|
+
updateTest.get().val.b.c[0].f === a.val.b.c[0].f,
|
|
147
|
+
a.val.b.c[0].f[0].g,
|
|
148
|
+
updateTest.get().val.b.c[0].f[0].g,
|
|
149
|
+
);
|
|
150
|
+
})();
|
|
151
|
+
|
|
152
|
+
const numAtom = atom(0);
|
|
153
|
+
|
|
154
|
+
const inputValueAtom = atom('');
|
|
155
|
+
|
|
156
|
+
function App() {
|
|
157
|
+
const test = useAtomValue(testAtom);
|
|
158
|
+
const testText = useAtomValue(testTextAtom);
|
|
159
|
+
const testDo = useAtomDo(testAtom);
|
|
160
|
+
const value = useAtomValue(inputValueAtom);
|
|
161
|
+
console.log({ num: useAtomValue(numAtom) });
|
|
162
|
+
|
|
163
|
+
console.info(test);
|
|
164
|
+
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
const onClick = () => {
|
|
167
|
+
testDo.add(Date.now());
|
|
168
|
+
testDo.update12();
|
|
169
|
+
testTextAtom.do.addText('1');
|
|
170
|
+
|
|
171
|
+
numAtom.set(num => {
|
|
172
|
+
console.log(num);
|
|
173
|
+
return 1;
|
|
174
|
+
});
|
|
175
|
+
numAtom.set(3);
|
|
176
|
+
numAtom.set(num => {
|
|
177
|
+
console.log(num);
|
|
178
|
+
return 4;
|
|
179
|
+
});
|
|
180
|
+
numAtom.set(num => {
|
|
181
|
+
console.log(num);
|
|
182
|
+
return 5;
|
|
183
|
+
});
|
|
184
|
+
numAtom.set(6);
|
|
185
|
+
numAtom.set(num => {
|
|
186
|
+
console.log(num);
|
|
187
|
+
return 7;
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
window.addEventListener('click', onClick);
|
|
192
|
+
return () => window.removeEventListener('click', onClick);
|
|
193
|
+
}, []);
|
|
194
|
+
|
|
195
|
+
return (
|
|
196
|
+
<>
|
|
197
|
+
{testText}
|
|
198
|
+
<input
|
|
199
|
+
value={value}
|
|
200
|
+
onChange={event => {
|
|
201
|
+
inputValueAtom.set(event.currentTarget.value + '*');
|
|
202
|
+
inputValueAtom.set(event.currentTarget.value);
|
|
203
|
+
}}
|
|
204
|
+
/>
|
|
205
|
+
</>
|
|
206
|
+
);
|
|
207
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -3,6 +3,12 @@ import { Path, PathValue, PathValueDonor } from './paths';
|
|
|
3
3
|
|
|
4
4
|
export interface Register {}
|
|
5
5
|
|
|
6
|
+
export type ObjectActionsSetDeepPartial = Register extends {
|
|
7
|
+
keyPathSeparator: infer Separator extends string;
|
|
8
|
+
}
|
|
9
|
+
? Separator
|
|
10
|
+
: '.';
|
|
11
|
+
|
|
6
12
|
type Sunscriber<Value> = (value: Value) => void;
|
|
7
13
|
|
|
8
14
|
export type AtomStoreKey = `${string}${string}:${string}${string}`;
|
|
@@ -78,12 +84,6 @@ export type ObjectActions<Value> = UpdateAction<Value> & {
|
|
|
78
84
|
) => void;
|
|
79
85
|
};
|
|
80
86
|
|
|
81
|
-
export type ObjectActionsSetDeepPartial = Register extends {
|
|
82
|
-
keyPathSeparator: infer Separator extends string;
|
|
83
|
-
}
|
|
84
|
-
? Separator
|
|
85
|
-
: '.';
|
|
86
|
-
|
|
87
87
|
export type BooleanActions = {
|
|
88
88
|
/** toggle current value between true/false */
|
|
89
89
|
toggle: () => void;
|
package/types/paths.ts
CHANGED
|
@@ -85,9 +85,9 @@ export type PathValueDonor<
|
|
|
85
85
|
? Required<Record<Key, PathValueDonor<Value[Key], Sep, KeyRest>>>
|
|
86
86
|
: never
|
|
87
87
|
: Value extends ReadonlyArray<infer V>
|
|
88
|
-
? [PathValueDonor<V, Sep, KeyRest & Path<V, Sep>>
|
|
88
|
+
? [PathValueDonor<V, Sep, KeyRest & Path<V, Sep>>]
|
|
89
89
|
: Value extends Partial<Record<infer K, infer V>> | Record<infer K, infer V>
|
|
90
|
-
? Record<K, PathValueDonor<V, Sep, KeyRest & Path<V, Sep>>>
|
|
90
|
+
? Record<K, PathValueDonor<V, Sep, KeyRest & Path<V, Sep>>>
|
|
91
91
|
: never
|
|
92
92
|
: FullPath extends keyof Value
|
|
93
93
|
? FullPath extends `${string}${Sep}${string}${string}`
|
|
@@ -100,7 +100,7 @@ export type PathValueDonor<
|
|
|
100
100
|
? [V]
|
|
101
101
|
: []
|
|
102
102
|
: Value extends Partial<Record<infer K, infer V>> | Record<infer K, infer V>
|
|
103
|
-
? Record<K, V>
|
|
103
|
+
? Record<K, V>
|
|
104
104
|
: never
|
|
105
105
|
: never;
|
|
106
106
|
|