atomaric 0.0.60 → 0.0.62
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 +314 -198
- package/build/atomaric.umd.cjs +1 -1
- package/package.json +8 -10
- package/types/index.d.ts +6 -2
- package/src/class.ts +0 -295
- package/src/globals.d.ts +0 -52
- package/src/index.ts +0 -2
- package/src/lib.ts +0 -36
- package/src/makeDeepProxyObject.ts +0 -35
- package/src/makeDoFillerActions.ts +0 -225
- package/src/test.tsx +0 -207
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import { AtomOptions, AtomStoreKey, DefaultActions } from '../types';
|
|
2
|
-
import { Atom } from './class';
|
|
3
|
-
import { configuredOptions } from './lib';
|
|
4
|
-
import { makeDeepProxyObject } from './makeDeepProxyObject';
|
|
5
|
-
|
|
6
|
-
type nil = null | undefined;
|
|
7
|
-
|
|
8
|
-
export const makeDoFillerActions = <Value, Actions extends Record<string, Function>>(
|
|
9
|
-
initialValue: Value,
|
|
10
|
-
atom: Atom<Value, Actions>,
|
|
11
|
-
storeKeyOrOptions: AtomStoreKey | AtomOptions<Value, Actions> | undefined,
|
|
12
|
-
) => {
|
|
13
|
-
let defaultActions: DefaultActions<any> | null = null;
|
|
14
|
-
|
|
15
|
-
if (typeof initialValue === 'number') {
|
|
16
|
-
defaultActions = fillActions<number>(
|
|
17
|
-
atom as never,
|
|
18
|
-
atom => ({
|
|
19
|
-
increment: delta => {
|
|
20
|
-
atom.set(+atom.get() + (delta ?? 0));
|
|
21
|
-
},
|
|
22
|
-
}),
|
|
23
|
-
initialValue,
|
|
24
|
-
);
|
|
25
|
-
} else if (typeof initialValue === 'boolean') {
|
|
26
|
-
defaultActions = fillActions<boolean>(
|
|
27
|
-
atom as never,
|
|
28
|
-
atom => ({
|
|
29
|
-
toggle: () => {
|
|
30
|
-
atom.set(!atom.get());
|
|
31
|
-
},
|
|
32
|
-
}),
|
|
33
|
-
initialValue,
|
|
34
|
-
);
|
|
35
|
-
} else if (Array.isArray(initialValue)) {
|
|
36
|
-
defaultActions = fillActions<any[]>(
|
|
37
|
-
atom as never,
|
|
38
|
-
atom => ({
|
|
39
|
-
push: (...values) => {
|
|
40
|
-
atom.set(atom.get().concat(values));
|
|
41
|
-
},
|
|
42
|
-
unshift: (...values) => {
|
|
43
|
-
atom.set(values.concat(atom.get()));
|
|
44
|
-
},
|
|
45
|
-
update: updater => {
|
|
46
|
-
const prev = atom.get();
|
|
47
|
-
const newValue = updateValue(prev, updater);
|
|
48
|
-
if (newValue === prev) return;
|
|
49
|
-
atom.set(newValue);
|
|
50
|
-
},
|
|
51
|
-
filter: filter => {
|
|
52
|
-
atom.set(atom.get().filter(filter ?? itIt));
|
|
53
|
-
},
|
|
54
|
-
add: value => {
|
|
55
|
-
if (atom.get().includes(value)) return;
|
|
56
|
-
atom.set(atom.get().concat([value]));
|
|
57
|
-
},
|
|
58
|
-
remove: value => {
|
|
59
|
-
const index = atom.get().indexOf(value);
|
|
60
|
-
if (index < 0) return;
|
|
61
|
-
const newArray = atom.get().slice(0);
|
|
62
|
-
newArray.splice(index, 1);
|
|
63
|
-
atom.set(newArray);
|
|
64
|
-
},
|
|
65
|
-
toggle: (value, isAddInStart) => {
|
|
66
|
-
const newArray = atom.get().slice();
|
|
67
|
-
const index = newArray.indexOf(value);
|
|
68
|
-
if (index < 0) {
|
|
69
|
-
if (isAddInStart) newArray.unshift(value);
|
|
70
|
-
else newArray.push(value);
|
|
71
|
-
} else newArray.splice(index, 1);
|
|
72
|
-
atom.set(newArray);
|
|
73
|
-
},
|
|
74
|
-
}),
|
|
75
|
-
initialValue,
|
|
76
|
-
);
|
|
77
|
-
} else if (initialValue instanceof Set) {
|
|
78
|
-
defaultActions = fillActions<Set<any>>(
|
|
79
|
-
atom as never,
|
|
80
|
-
atom => ({
|
|
81
|
-
add: value => {
|
|
82
|
-
atom.set(new Set(atom.get()).add(value));
|
|
83
|
-
},
|
|
84
|
-
delete: value => {
|
|
85
|
-
const newSet = new Set(atom.get());
|
|
86
|
-
newSet.delete(value);
|
|
87
|
-
atom.set(newSet);
|
|
88
|
-
},
|
|
89
|
-
toggle: value => {
|
|
90
|
-
const newSet = new Set(atom.get());
|
|
91
|
-
|
|
92
|
-
if (newSet.has(value)) newSet.delete(value);
|
|
93
|
-
else newSet.add(value);
|
|
94
|
-
|
|
95
|
-
atom.set(newSet);
|
|
96
|
-
},
|
|
97
|
-
clear: () => {
|
|
98
|
-
atom.set(new Set());
|
|
99
|
-
},
|
|
100
|
-
}),
|
|
101
|
-
initialValue,
|
|
102
|
-
);
|
|
103
|
-
} else if (initialValue instanceof Object) {
|
|
104
|
-
const keyPathSeparator = configuredOptions.keyPathSeparator || '.';
|
|
105
|
-
|
|
106
|
-
defaultActions = fillActions<object>(
|
|
107
|
-
atom as never,
|
|
108
|
-
atom => ({
|
|
109
|
-
setPartial: value =>
|
|
110
|
-
atom.set(prev => ({
|
|
111
|
-
...prev,
|
|
112
|
-
...(typeof value === 'function' ? value(atom.get()) : value),
|
|
113
|
-
})),
|
|
114
|
-
update: updater => {
|
|
115
|
-
const prev = atom.get();
|
|
116
|
-
const newValue = updateValue(prev, updater);
|
|
117
|
-
if (newValue === prev) return;
|
|
118
|
-
atom.set(newValue);
|
|
119
|
-
},
|
|
120
|
-
setDeepPartial: (path: string, value: any, donor, separator = keyPathSeparator as never) => {
|
|
121
|
-
if (!separator) return;
|
|
122
|
-
|
|
123
|
-
if (path.includes(separator)) {
|
|
124
|
-
let keys = path.split(separator);
|
|
125
|
-
const lastKey = keys[keys.length - 1];
|
|
126
|
-
keys = keys.slice(0, -1);
|
|
127
|
-
const newObject = { ...atom.get() };
|
|
128
|
-
let lastObject: Record<string, unknown> = newObject;
|
|
129
|
-
let lastDonorObject = donor as Record<string, unknown> | nil;
|
|
130
|
-
|
|
131
|
-
for (const key of keys) {
|
|
132
|
-
lastDonorObject = lastDonorObject?.[Array.isArray(lastDonorObject) ? '0' : key] as never;
|
|
133
|
-
const currentObject = lastObject[makeKey(lastObject, key)] ?? (Array.isArray(lastDonorObject) ? [] : {});
|
|
134
|
-
|
|
135
|
-
if (currentObject == null || typeof currentObject !== 'object') {
|
|
136
|
-
if (donor == null) throw 'Incorrect path for setDeepPartial';
|
|
137
|
-
|
|
138
|
-
const newValue = typeof value === 'function' ? value(undefined) : value;
|
|
139
|
-
|
|
140
|
-
if (atom.get()[path as never] !== newValue) atom.do.setPartial({ [path]: newValue });
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
lastObject = lastObject[makeKey(lastObject, key)] = (
|
|
145
|
-
Array.isArray(currentObject) ? [...currentObject] : { ...currentObject }
|
|
146
|
-
) as never;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const prev = lastObject[lastKey];
|
|
150
|
-
lastObject[lastKey] = typeof value === 'function' ? value(lastObject[lastKey]) : value;
|
|
151
|
-
|
|
152
|
-
if (prev !== lastObject[lastKey]) atom.set(newObject);
|
|
153
|
-
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const prevValue = atom.get()[path as never];
|
|
158
|
-
const newValue = typeof value === 'function' ? value(prevValue) : value;
|
|
159
|
-
if (newValue !== prevValue) atom.do.setPartial({ [path]: newValue });
|
|
160
|
-
},
|
|
161
|
-
}),
|
|
162
|
-
initialValue,
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const actions =
|
|
167
|
-
typeof storeKeyOrOptions === 'object' && storeKeyOrOptions != null && 'do' in storeKeyOrOptions
|
|
168
|
-
? storeKeyOrOptions.do(
|
|
169
|
-
(value, isPreventSave) => atom.set(value, isPreventSave),
|
|
170
|
-
() => atom.get(),
|
|
171
|
-
atom,
|
|
172
|
-
(value, debounceMs, isPreventSave) => atom.setDeferred(value, debounceMs, isPreventSave),
|
|
173
|
-
)
|
|
174
|
-
: null;
|
|
175
|
-
|
|
176
|
-
const doActions = {};
|
|
177
|
-
|
|
178
|
-
if (actions) Object.keys(actions).forEach(key => Object.defineProperty(doActions, key, { get: () => actions[key] }));
|
|
179
|
-
|
|
180
|
-
if (defaultActions)
|
|
181
|
-
Object.keys(defaultActions).forEach(key =>
|
|
182
|
-
Object.defineProperty(doActions, key, { get: () => defaultActions[key as never] }),
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
return doActions;
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
const itIt = <It>(it: It) => it;
|
|
189
|
-
const fillActions = <Value, ValAtom extends Atom<Value> = Atom<Value>>(
|
|
190
|
-
atom: ValAtom,
|
|
191
|
-
actions: (atom: ValAtom) => DefaultActions<Value>,
|
|
192
|
-
_value: Value,
|
|
193
|
-
) => actions(atom);
|
|
194
|
-
|
|
195
|
-
const updateValue = <Object extends object | unknown[]>(object: Object, updater: (object: Object) => void): Object => {
|
|
196
|
-
const newObject = Array.isArray(object) ? object.slice(0) : { ...object };
|
|
197
|
-
let isSomeSetted = false;
|
|
198
|
-
|
|
199
|
-
const pro = makeDeepProxyObject(object, {
|
|
200
|
-
onSet: (_, keys, setKey, value, prevValue) => {
|
|
201
|
-
if (value === prevValue) return true;
|
|
202
|
-
let currentObject = newObject as Record<string, unknown> | unknown[];
|
|
203
|
-
|
|
204
|
-
isSomeSetted = true;
|
|
205
|
-
|
|
206
|
-
for (const key of keys) {
|
|
207
|
-
const nextObject = currentObject[key as never] as object;
|
|
208
|
-
|
|
209
|
-
currentObject = currentObject[key as never] = (
|
|
210
|
-
Array.isArray(nextObject) ? nextObject.slice(0) : { ...nextObject }
|
|
211
|
-
) as never;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
currentObject[setKey as never] = value as never;
|
|
215
|
-
|
|
216
|
-
return true;
|
|
217
|
-
},
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
updater(pro);
|
|
221
|
-
|
|
222
|
-
return isSomeSetted ? (newObject as never) : object;
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
const makeKey = (obj: object, key: string) => (Array.isArray(obj) ? `${+key}` : key);
|
package/src/test.tsx
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
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
|
-
}
|