@esportsplus/reactivity 0.16.6 → 0.17.0
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/reactive/array.d.ts +20 -156
- package/build/reactive/array.js +98 -173
- package/build/reactive/index.d.ts +13 -4
- package/build/reactive/index.js +6 -6
- package/build/reactive/object.d.ts +1 -14
- package/build/reactive/object.js +23 -23
- package/build/system.js +27 -24
- package/package.json +1 -1
- package/src/reactive/array.ts +106 -200
- package/src/reactive/index.ts +24 -11
- package/src/reactive/object.ts +30 -41
- package/src/system.ts +28 -24
package/build/system.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isObject } from '@esportsplus/utilities';
|
|
2
2
|
import { COMPUTED, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING } from './constants.js';
|
|
3
3
|
let depth = 0, heap = new Array(64), heap_i = 0, heap_n = 0, microtask = queueMicrotask, notified = false, observer = null, scope = null, stabilizer = STABILIZER_IDLE, version = 0;
|
|
4
4
|
function cleanup(computed) {
|
|
@@ -6,14 +6,14 @@ function cleanup(computed) {
|
|
|
6
6
|
return;
|
|
7
7
|
}
|
|
8
8
|
let value = computed.cleanup;
|
|
9
|
-
if (
|
|
9
|
+
if (typeof value === 'function') {
|
|
10
|
+
value();
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
10
13
|
for (let i = 0, n = value.length; i < n; i++) {
|
|
11
14
|
value[i]();
|
|
12
15
|
}
|
|
13
16
|
}
|
|
14
|
-
else {
|
|
15
|
-
value();
|
|
16
|
-
}
|
|
17
17
|
computed.cleanup = null;
|
|
18
18
|
}
|
|
19
19
|
function deleteFromHeap(computed) {
|
|
@@ -64,20 +64,20 @@ function insertIntoHeap(computed) {
|
|
|
64
64
|
}
|
|
65
65
|
function link(dep, sub) {
|
|
66
66
|
let prevDep = sub.depsTail;
|
|
67
|
-
if (prevDep
|
|
67
|
+
if (prevDep && prevDep.dep === dep) {
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
70
|
let nextDep = null;
|
|
71
71
|
if (sub.state & STATE_RECOMPUTING) {
|
|
72
|
-
nextDep = prevDep
|
|
73
|
-
if (nextDep
|
|
72
|
+
nextDep = prevDep ? prevDep.nextDep : sub.deps;
|
|
73
|
+
if (nextDep && nextDep.dep === dep) {
|
|
74
74
|
nextDep.version = version;
|
|
75
75
|
sub.depsTail = nextDep;
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
let prevSub = dep.subsTail;
|
|
80
|
-
if (prevSub
|
|
80
|
+
if (prevSub &&
|
|
81
81
|
prevSub.version === version &&
|
|
82
82
|
prevSub.sub === sub) {
|
|
83
83
|
return;
|
|
@@ -91,13 +91,13 @@ function link(dep, sub) {
|
|
|
91
91
|
nextSub: null,
|
|
92
92
|
version
|
|
93
93
|
};
|
|
94
|
-
if (prevDep
|
|
94
|
+
if (prevDep) {
|
|
95
95
|
prevDep.nextDep = newLink;
|
|
96
96
|
}
|
|
97
97
|
else {
|
|
98
98
|
sub.deps = newLink;
|
|
99
99
|
}
|
|
100
|
-
if (prevSub
|
|
100
|
+
if (prevSub) {
|
|
101
101
|
prevSub.nextSub = newLink;
|
|
102
102
|
}
|
|
103
103
|
else {
|
|
@@ -110,7 +110,7 @@ function notify(computed, newState = STATE_DIRTY) {
|
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
112
|
computed.state = state | newState;
|
|
113
|
-
for (let link = computed.subs; link
|
|
113
|
+
for (let link = computed.subs; link; link = link.nextSub) {
|
|
114
114
|
notify(link.sub, STATE_CHECK);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
@@ -140,12 +140,12 @@ function recompute(computed, del) {
|
|
|
140
140
|
depth--;
|
|
141
141
|
observer = o;
|
|
142
142
|
computed.state = STATE_NONE;
|
|
143
|
-
let depsTail = computed.depsTail, remove = depsTail
|
|
144
|
-
if (remove
|
|
143
|
+
let depsTail = computed.depsTail, remove = depsTail ? depsTail.nextDep : computed.deps;
|
|
144
|
+
if (remove) {
|
|
145
145
|
do {
|
|
146
146
|
remove = unlink(remove);
|
|
147
|
-
} while (remove
|
|
148
|
-
if (depsTail
|
|
147
|
+
} while (remove);
|
|
148
|
+
if (depsTail) {
|
|
149
149
|
depsTail.nextDep = null;
|
|
150
150
|
}
|
|
151
151
|
else {
|
|
@@ -154,7 +154,7 @@ function recompute(computed, del) {
|
|
|
154
154
|
}
|
|
155
155
|
if (ok && value !== computed.value) {
|
|
156
156
|
computed.value = value;
|
|
157
|
-
for (let c = computed.subs; c
|
|
157
|
+
for (let c = computed.subs; c; c = c.nextSub) {
|
|
158
158
|
let s = c.sub, state = s.state;
|
|
159
159
|
if (state & STATE_CHECK) {
|
|
160
160
|
s.state = state | STATE_DIRTY;
|
|
@@ -165,6 +165,9 @@ function recompute(computed, del) {
|
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
function schedule() {
|
|
168
|
+
if (stabilizer === STABILIZER_SCHEDULED) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
168
171
|
if (stabilizer === STABILIZER_IDLE && !depth) {
|
|
169
172
|
stabilizer = STABILIZER_SCHEDULED;
|
|
170
173
|
microtask(stabilize);
|
|
@@ -199,13 +202,13 @@ function stabilize() {
|
|
|
199
202
|
}
|
|
200
203
|
function unlink(link) {
|
|
201
204
|
let dep = link.dep, nextDep = link.nextDep, nextSub = link.nextSub, prevSub = link.prevSub;
|
|
202
|
-
if (nextSub
|
|
205
|
+
if (nextSub) {
|
|
203
206
|
nextSub.prevSub = prevSub;
|
|
204
207
|
}
|
|
205
208
|
else {
|
|
206
209
|
dep.subsTail = prevSub;
|
|
207
210
|
}
|
|
208
|
-
if (prevSub
|
|
211
|
+
if (prevSub) {
|
|
209
212
|
prevSub.nextSub = nextSub;
|
|
210
213
|
}
|
|
211
214
|
else if ((dep.subs = nextSub) === null && 'fn' in dep) {
|
|
@@ -271,7 +274,7 @@ const computed = (fn) => {
|
|
|
271
274
|
const dispose = (computed) => {
|
|
272
275
|
deleteFromHeap(computed);
|
|
273
276
|
let dep = computed.deps;
|
|
274
|
-
while (dep
|
|
277
|
+
while (dep) {
|
|
275
278
|
dep = unlink(dep);
|
|
276
279
|
}
|
|
277
280
|
computed.deps = null;
|
|
@@ -300,11 +303,11 @@ const onCleanup = (fn) => {
|
|
|
300
303
|
if (!cleanup) {
|
|
301
304
|
parent.cleanup = fn;
|
|
302
305
|
}
|
|
303
|
-
else if (
|
|
304
|
-
cleanup
|
|
306
|
+
else if (typeof cleanup === 'function') {
|
|
307
|
+
parent.cleanup = [cleanup, fn];
|
|
305
308
|
}
|
|
306
309
|
else {
|
|
307
|
-
|
|
310
|
+
cleanup.push(fn);
|
|
308
311
|
}
|
|
309
312
|
return fn;
|
|
310
313
|
};
|
|
@@ -361,7 +364,7 @@ const set = (signal, value) => {
|
|
|
361
364
|
if (signal.subs === null) {
|
|
362
365
|
return;
|
|
363
366
|
}
|
|
364
|
-
for (let link = signal.subs; link
|
|
367
|
+
for (let link = signal.subs; link; link = link.nextSub) {
|
|
365
368
|
insertIntoHeap(link.sub);
|
|
366
369
|
}
|
|
367
370
|
schedule();
|
package/package.json
CHANGED
package/src/reactive/array.ts
CHANGED
|
@@ -1,19 +1,7 @@
|
|
|
1
|
-
import { isNumber, Prettify } from '@esportsplus/utilities';
|
|
2
1
|
import { REACTIVE_ARRAY } from '~/constants';
|
|
3
2
|
import { isReactiveObject } from './object';
|
|
4
3
|
|
|
5
4
|
|
|
6
|
-
type ReactiveArray<T> = Prettify<
|
|
7
|
-
T[] & {
|
|
8
|
-
clear: () => void;
|
|
9
|
-
dispose: () => void;
|
|
10
|
-
dispatch: <K extends keyof Events<T>, V>(event: K, value?: V) => void;
|
|
11
|
-
map: <R>(fn: (this: ReactiveArray<T>, value: T, i: number) => R) => R[];
|
|
12
|
-
on: <K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>) => void;
|
|
13
|
-
once: <K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>) => void;
|
|
14
|
-
}
|
|
15
|
-
>;
|
|
16
|
-
|
|
17
5
|
type Events<T> = {
|
|
18
6
|
clear: undefined,
|
|
19
7
|
pop: {
|
|
@@ -49,243 +37,161 @@ type Listener<V> = {
|
|
|
49
37
|
type Listeners = Record<string, (Listener<any> | null)[]>;
|
|
50
38
|
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
}
|
|
40
|
+
class ReactiveArray<T> extends Array<T> {
|
|
41
|
+
[REACTIVE_ARRAY] = true;
|
|
42
|
+
listeners: Listeners = {};
|
|
57
43
|
|
|
58
|
-
function clear<T>(data: T[], listeners: Listeners) {
|
|
59
|
-
dispose(data);
|
|
60
|
-
dispatch(listeners, 'clear');
|
|
61
|
-
}
|
|
62
44
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return;
|
|
45
|
+
constructor(...items: T[]) {
|
|
46
|
+
super(...items);
|
|
66
47
|
}
|
|
67
48
|
|
|
68
|
-
let bucket = listeners[event];
|
|
69
49
|
|
|
70
|
-
|
|
71
|
-
|
|
50
|
+
clear() {
|
|
51
|
+
this.dispose();
|
|
52
|
+
this.dispatch('clear');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
dispatch<K extends keyof Events<T>, V>(event: K, value?: V) {
|
|
56
|
+
let listeners = this.listeners[event];
|
|
72
57
|
|
|
73
|
-
if (
|
|
74
|
-
|
|
58
|
+
if (!listeners) {
|
|
59
|
+
return;
|
|
75
60
|
}
|
|
76
61
|
|
|
77
|
-
|
|
78
|
-
listener
|
|
62
|
+
for (let i = 0, n = listeners.length; i < n; i++) {
|
|
63
|
+
let listener = listeners[i];
|
|
79
64
|
|
|
80
|
-
if (listener
|
|
81
|
-
|
|
65
|
+
if (listener === null) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
listener(value);
|
|
71
|
+
|
|
72
|
+
if (listener.once !== undefined) {
|
|
73
|
+
listeners[i] = null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
listeners[i] = null;
|
|
82
78
|
}
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
bucket[i] = null;
|
|
86
79
|
}
|
|
87
80
|
}
|
|
88
|
-
}
|
|
89
81
|
|
|
90
|
-
|
|
91
|
-
|
|
82
|
+
dispose() {
|
|
83
|
+
let item;
|
|
92
84
|
|
|
93
|
-
|
|
94
|
-
|
|
85
|
+
while (item = super.pop()) {
|
|
86
|
+
if (isReactiveObject(item)) {
|
|
87
|
+
item.dispose();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
95
90
|
}
|
|
96
|
-
}
|
|
97
91
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
proxy: ReactiveArray<T>,
|
|
101
|
-
fn: (this: ReactiveArray<T>, value: T, i: number) => R
|
|
102
|
-
) {
|
|
103
|
-
let n = data.length,
|
|
104
|
-
values: R[] = new Array(n);
|
|
92
|
+
on<K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>) {
|
|
93
|
+
let listeners = this.listeners[event];
|
|
105
94
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
95
|
+
if (listeners === undefined) {
|
|
96
|
+
this.listeners[event] = [listener];
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
let hole = listeners.length;
|
|
109
100
|
|
|
110
|
-
|
|
111
|
-
|
|
101
|
+
for (let i = 0, n = hole; i < n; i++) {
|
|
102
|
+
let l = listeners[i];
|
|
112
103
|
|
|
113
|
-
|
|
114
|
-
|
|
104
|
+
if (l === listener) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
else if (l === null && hole === n) {
|
|
108
|
+
hole = i;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
listeners[hole] = listener;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
once<K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>) {
|
|
117
|
+
listener.once = true;
|
|
118
|
+
this.on(event, listener);
|
|
118
119
|
}
|
|
119
|
-
else {
|
|
120
|
-
let hole = bucket.length;
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
pop() {
|
|
122
|
+
let item = super.pop();
|
|
124
123
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
else if (l === null && hole === n) {
|
|
129
|
-
hole = i;
|
|
124
|
+
if (item !== undefined) {
|
|
125
|
+
if (isReactiveObject(item)) {
|
|
126
|
+
item.dispose();
|
|
130
127
|
}
|
|
128
|
+
this.dispatch('pop', { item });
|
|
131
129
|
}
|
|
132
130
|
|
|
133
|
-
|
|
131
|
+
return item;
|
|
134
132
|
}
|
|
135
|
-
}
|
|
136
133
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
on(listeners, event, listener);
|
|
140
|
-
}
|
|
134
|
+
push(...items: T[]) {
|
|
135
|
+
let length = super.push(...items);
|
|
141
136
|
|
|
142
|
-
|
|
143
|
-
let item = data.pop();
|
|
137
|
+
this.dispatch('push', { items });
|
|
144
138
|
|
|
145
|
-
|
|
146
|
-
cleanup(item);
|
|
147
|
-
dispatch(listeners, 'pop', { item });
|
|
139
|
+
return length;
|
|
148
140
|
}
|
|
149
141
|
|
|
150
|
-
|
|
151
|
-
|
|
142
|
+
reverse() {
|
|
143
|
+
super.reverse();
|
|
144
|
+
this.dispatch('reverse');
|
|
152
145
|
|
|
153
|
-
|
|
154
|
-
|
|
146
|
+
return this;
|
|
147
|
+
}
|
|
155
148
|
|
|
156
|
-
|
|
149
|
+
shift() {
|
|
150
|
+
let item = super.shift();
|
|
157
151
|
|
|
158
|
-
|
|
159
|
-
|
|
152
|
+
if (item !== undefined) {
|
|
153
|
+
if (isReactiveObject(item)) {
|
|
154
|
+
item.dispose();
|
|
155
|
+
}
|
|
156
|
+
this.dispatch('shift', { item });
|
|
157
|
+
}
|
|
160
158
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
dispatch(listeners, 'reverse');
|
|
164
|
-
}
|
|
159
|
+
return item;
|
|
160
|
+
}
|
|
165
161
|
|
|
166
|
-
|
|
167
|
-
|
|
162
|
+
sort(fn: (a: T, b: T) => number) {
|
|
163
|
+
super.sort(fn);
|
|
164
|
+
this.dispatch('sort');
|
|
168
165
|
|
|
169
|
-
|
|
170
|
-
cleanup(item);
|
|
171
|
-
dispatch(listeners, 'shift', { item });
|
|
166
|
+
return this;
|
|
172
167
|
}
|
|
173
168
|
|
|
174
|
-
|
|
175
|
-
|
|
169
|
+
splice(start: number, deleteCount: number = this.length, ...items: T[]) {
|
|
170
|
+
let removed = super.splice(start, deleteCount, ...items);
|
|
176
171
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
172
|
+
if (items.length > 0 || removed.length > 0) {
|
|
173
|
+
for (let i = 0, n = removed.length; i < n; i++) {
|
|
174
|
+
let item = removed[i];
|
|
181
175
|
|
|
182
|
-
|
|
183
|
-
|
|
176
|
+
if (isReactiveObject(item)) {
|
|
177
|
+
item.dispose();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
184
180
|
|
|
185
|
-
|
|
186
|
-
for (let i = 0, n = removed.length; i < n; i++) {
|
|
187
|
-
cleanup(removed[i]);
|
|
181
|
+
this.dispatch('splice', { deleteCount, items, start });
|
|
188
182
|
}
|
|
189
183
|
|
|
190
|
-
|
|
191
|
-
deleteCount,
|
|
192
|
-
items,
|
|
193
|
-
start
|
|
194
|
-
});
|
|
184
|
+
return removed;
|
|
195
185
|
}
|
|
196
186
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
function unshift<T>(data: T[], listeners: Listeners, items: T[]) {
|
|
201
|
-
let length = data.unshift(...items);
|
|
187
|
+
unshift(...items: T[]) {
|
|
188
|
+
let length = super.unshift(...items);
|
|
202
189
|
|
|
203
|
-
|
|
190
|
+
this.dispatch('unshift', { items });
|
|
204
191
|
|
|
205
|
-
|
|
192
|
+
return length;
|
|
193
|
+
}
|
|
206
194
|
}
|
|
207
195
|
|
|
208
196
|
|
|
209
|
-
export
|
|
210
|
-
let listeners: Listeners = {},
|
|
211
|
-
proxy = new Proxy({}, {
|
|
212
|
-
get(_, key: any) {
|
|
213
|
-
if (isNumber(key)) {
|
|
214
|
-
return data[key];
|
|
215
|
-
}
|
|
216
|
-
else if (key in wrapper) {
|
|
217
|
-
return wrapper[key as keyof typeof wrapper];
|
|
218
|
-
}
|
|
219
|
-
else if (key === 'length') {
|
|
220
|
-
return data.length;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
return data[key];
|
|
224
|
-
},
|
|
225
|
-
set(_, key: any, value: any) {
|
|
226
|
-
if (isNumber(key)) {
|
|
227
|
-
splice(data, listeners, key, 1, value);
|
|
228
|
-
}
|
|
229
|
-
else if (key === 'length') {
|
|
230
|
-
if (value >= data.length) {
|
|
231
|
-
}
|
|
232
|
-
else if (value === 0) {
|
|
233
|
-
clear(data, listeners);
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
splice(data, listeners, value);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
else {
|
|
240
|
-
return false;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
return true;
|
|
244
|
-
}
|
|
245
|
-
}) as ReactiveArray<T>,
|
|
246
|
-
wrapper = {
|
|
247
|
-
[REACTIVE_ARRAY]: true,
|
|
248
|
-
at: (i: number) => data[i],
|
|
249
|
-
clear: () => {
|
|
250
|
-
clear(data, listeners);
|
|
251
|
-
return proxy;
|
|
252
|
-
},
|
|
253
|
-
dispatch: <K extends keyof Events<T>, V>(event: K, value?: V) => {
|
|
254
|
-
dispatch(listeners, event, value);
|
|
255
|
-
return proxy;
|
|
256
|
-
},
|
|
257
|
-
dispose: () => {
|
|
258
|
-
dispose(data);
|
|
259
|
-
return proxy;
|
|
260
|
-
},
|
|
261
|
-
map: <R>(fn: (this: ReactiveArray<T>, value: T, i: number) => R) => {
|
|
262
|
-
return map(data, proxy, fn);
|
|
263
|
-
},
|
|
264
|
-
on: <K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>) => {
|
|
265
|
-
on(listeners, event, listener);
|
|
266
|
-
return proxy;
|
|
267
|
-
},
|
|
268
|
-
once: <K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>) => {
|
|
269
|
-
once(listeners, event, listener);
|
|
270
|
-
return proxy;
|
|
271
|
-
},
|
|
272
|
-
pop: () => pop(data, listeners),
|
|
273
|
-
push: (...items: T[]) => push(data, listeners, items),
|
|
274
|
-
reverse: () => {
|
|
275
|
-
reverse(data, listeners);
|
|
276
|
-
return proxy;
|
|
277
|
-
},
|
|
278
|
-
shift: () => shift(data, listeners),
|
|
279
|
-
sort: (fn: (a: T, b: T) => number) => {
|
|
280
|
-
sort(data, listeners, fn);
|
|
281
|
-
return proxy;
|
|
282
|
-
},
|
|
283
|
-
splice: (start: number, deleteCount?: number, ...items: T[]) => {
|
|
284
|
-
return splice(data, listeners, start, deleteCount, items);
|
|
285
|
-
},
|
|
286
|
-
unshift: (...items: T[]) => unshift(data, listeners, items),
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
return proxy;
|
|
290
|
-
};
|
|
291
|
-
export type { ReactiveArray };
|
|
197
|
+
export { ReactiveArray };
|
package/src/reactive/index.ts
CHANGED
|
@@ -1,29 +1,42 @@
|
|
|
1
|
-
import { isArray, isObject } from '@esportsplus/utilities';
|
|
1
|
+
import { isArray, isObject, Prettify } from '@esportsplus/utilities';
|
|
2
2
|
import { onCleanup, root } from '~/system';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import { ReactiveArray } from './array';
|
|
4
|
+
import { ReactiveObject } from './object';
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
type API<T> =
|
|
8
8
|
T extends Record<PropertyKey, unknown>
|
|
9
|
-
?
|
|
9
|
+
? Prettify<{ [K in keyof T]: Infer<T[K]> } & { dispose: VoidFunction } >
|
|
10
10
|
: T extends (infer U)[]
|
|
11
11
|
? ReactiveArray<U>
|
|
12
12
|
: never;
|
|
13
13
|
|
|
14
|
+
type Guard<T> = T extends { dispose: any } ? { never: '[ dispose ] are reserved keys' } : T;
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
type Infer<T> =
|
|
17
|
+
T extends (...args: unknown[]) => Promise<infer R>
|
|
18
|
+
? R | undefined
|
|
19
|
+
: T extends (...args: any[]) => infer R
|
|
20
|
+
? R
|
|
21
|
+
: T extends (infer U)[]
|
|
22
|
+
? ReactiveArray<U>
|
|
23
|
+
: T extends ReactiveObject<any>
|
|
24
|
+
? T
|
|
25
|
+
: T extends Record<PropertyKey, unknown>
|
|
26
|
+
? { [K in keyof T]: T[K] }
|
|
27
|
+
: T;
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
export default <T extends Record<PropertyKey, any> | unknown[]>(input: Guard<T>): API<T> => {
|
|
18
31
|
let dispose = false,
|
|
19
32
|
value = root(() => {
|
|
20
33
|
let response: API<T> | undefined;
|
|
21
34
|
|
|
22
|
-
if (
|
|
23
|
-
response =
|
|
35
|
+
if (isObject(input)) {
|
|
36
|
+
response = new ReactiveObject(input) as any as API<T>;
|
|
24
37
|
}
|
|
25
|
-
else if (
|
|
26
|
-
response =
|
|
38
|
+
else if (isArray(input)) {
|
|
39
|
+
response = new ReactiveArray(...input) as API<T>;
|
|
27
40
|
}
|
|
28
41
|
|
|
29
42
|
if (response) {
|