@esportsplus/reactivity 0.12.4 → 0.13.1
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 +5 -59
- package/build/reactive/array.js +183 -171
- package/build/reactive/index.d.ts +4 -3
- package/build/reactive/object.d.ts +4 -2
- package/build/reactive/object.js +6 -5
- package/build/types.d.ts +2 -3
- package/package.json +2 -2
- package/src/reactive/array.ts +214 -221
- package/src/reactive/index.ts +5 -8
- package/src/reactive/object.ts +9 -6
- package/src/types.ts +2 -6
|
@@ -1,62 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type Events<T> = {
|
|
6
|
-
pop: {
|
|
7
|
-
item: Item<T>;
|
|
8
|
-
};
|
|
9
|
-
push: {
|
|
10
|
-
items: Item<T>[];
|
|
11
|
-
};
|
|
12
|
-
reverse: undefined;
|
|
13
|
-
set: {
|
|
14
|
-
index: number;
|
|
15
|
-
item: Item<T>;
|
|
16
|
-
};
|
|
17
|
-
shift: {
|
|
18
|
-
item: Item<T>;
|
|
19
|
-
};
|
|
20
|
-
sort: undefined;
|
|
21
|
-
splice: {
|
|
22
|
-
deleteCount: number;
|
|
23
|
-
items: Item<T>[];
|
|
24
|
-
start: number;
|
|
25
|
-
};
|
|
26
|
-
unshift: {
|
|
27
|
-
items: Item<T>[];
|
|
28
|
-
};
|
|
1
|
+
import { Infer } from '../types.js';
|
|
2
|
+
type API<T> = Infer<T[]> & {
|
|
3
|
+
clear: () => void;
|
|
4
|
+
dispose: () => void;
|
|
29
5
|
};
|
|
30
|
-
|
|
31
|
-
type Listener<V> = {
|
|
32
|
-
once?: boolean;
|
|
33
|
-
(value: V): void;
|
|
34
|
-
};
|
|
35
|
-
type Value<T> = T extends Record<PropertyKey, unknown> ? ReactiveObject<T> : T extends Array<infer U> ? API<U> : T;
|
|
36
|
-
declare class ReactiveArray<T> {
|
|
37
|
-
[REACTIVE_ARRAY]: boolean;
|
|
38
|
-
disposables: number;
|
|
39
|
-
private data;
|
|
40
|
-
private listeners;
|
|
41
|
-
private proxy;
|
|
42
|
-
constructor(data: Item<T>[], proxy: API<T>);
|
|
43
|
-
get length(): number;
|
|
44
|
-
set length(n: number);
|
|
45
|
-
private cleanup;
|
|
46
|
-
at(i: number): T | API<T> | ReactiveObject<T extends Record<PropertyKey, unknown> ? T : never>;
|
|
47
|
-
dispatch<K extends keyof Events<T>, V>(event: K, value?: V): void;
|
|
48
|
-
dispose(): void;
|
|
49
|
-
map<R>(fn: (this: API<T>, value: Value<T>, i: number) => R, i?: number, n?: number): R[];
|
|
50
|
-
on<K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>): void;
|
|
51
|
-
once<K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>): void;
|
|
52
|
-
pop(): Item<T> | undefined;
|
|
53
|
-
push(...input: T[]): number;
|
|
54
|
-
reverse(): this;
|
|
55
|
-
shift(): Item<T> | undefined;
|
|
56
|
-
sort(fn: (a: Value<T>, b: Value<T>) => number): this;
|
|
57
|
-
splice(start: number, deleteCount?: number, ...input: T[]): Item<T>[];
|
|
58
|
-
unshift(...input: T[]): number;
|
|
59
|
-
}
|
|
60
|
-
declare const _default: <T>(input: T[]) => API<T>;
|
|
6
|
+
declare const _default: <T>(data: T[]) => API<T>;
|
|
61
7
|
export default _default;
|
|
62
8
|
export type { API as ReactiveArray };
|
package/build/reactive/array.js
CHANGED
|
@@ -1,205 +1,217 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isNumber } from '@esportsplus/utilities';
|
|
2
2
|
import { REACTIVE_ARRAY } from '../constants.js';
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
get length() {
|
|
16
|
-
return this.data.length;
|
|
17
|
-
}
|
|
18
|
-
set length(n) {
|
|
19
|
-
if (n > this.data.length) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
this.splice(n);
|
|
23
|
-
}
|
|
24
|
-
cleanup(item) {
|
|
25
|
-
if (isReactiveObject(item)) {
|
|
26
|
-
item.dispose();
|
|
27
|
-
}
|
|
28
|
-
else if (isComputed(item)) {
|
|
29
|
-
dispose(item);
|
|
30
|
-
}
|
|
3
|
+
import { dispose as d, isComputed, read } from '../system.js';
|
|
4
|
+
import { isReactiveObject } from './object.js';
|
|
5
|
+
function at(data, i) {
|
|
6
|
+
let value = data[i];
|
|
7
|
+
if (isComputed(value)) {
|
|
8
|
+
return read(value);
|
|
9
|
+
}
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
function cleanup(item) {
|
|
13
|
+
if (isReactiveObject(item)) {
|
|
14
|
+
item.dispose();
|
|
31
15
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (isComputed(value)) {
|
|
35
|
-
return read(value);
|
|
36
|
-
}
|
|
37
|
-
return value;
|
|
16
|
+
else if (isComputed(item)) {
|
|
17
|
+
d(item);
|
|
38
18
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
19
|
+
}
|
|
20
|
+
function clear(data, listeners) {
|
|
21
|
+
dispose(data);
|
|
22
|
+
dispatch(listeners, 'clear');
|
|
23
|
+
}
|
|
24
|
+
function dispatch(listeners, event, value) {
|
|
25
|
+
if (listeners === null || listeners[event] === undefined) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
let bucket = listeners[event];
|
|
29
|
+
for (let i = 0, n = bucket.length; i < n; i++) {
|
|
30
|
+
let listener = bucket[i];
|
|
31
|
+
if (listener === null) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
listener(value);
|
|
36
|
+
if (listener.once !== undefined) {
|
|
37
|
+
bucket[i] = null;
|
|
57
38
|
}
|
|
58
39
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
for (let i = 0, n = this.data.length; i < n; i++) {
|
|
62
|
-
this.cleanup(this.data[i]);
|
|
40
|
+
catch {
|
|
41
|
+
bucket[i] = null;
|
|
63
42
|
}
|
|
64
43
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (n === undefined) {
|
|
71
|
-
n = data.length;
|
|
72
|
-
}
|
|
73
|
-
n = Math.min(n, data.length);
|
|
74
|
-
let values = new Array(n - i);
|
|
75
|
-
for (; i < n; i++) {
|
|
76
|
-
let item = data[i];
|
|
77
|
-
values[i] = fn.call(proxy, (isComputed(item) ? item.value : item), i);
|
|
78
|
-
}
|
|
79
|
-
return values;
|
|
80
|
-
}
|
|
81
|
-
on(event, listener) {
|
|
82
|
-
if (this.listeners === null) {
|
|
83
|
-
this.listeners = { [event]: [listener] };
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
let listeners = this.listeners[event];
|
|
87
|
-
if (listeners === undefined) {
|
|
88
|
-
this.listeners[event] = [listener];
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
let hole = listeners.length;
|
|
92
|
-
for (let i = 0, n = hole; i < n; i++) {
|
|
93
|
-
let l = listeners[i];
|
|
94
|
-
if (l === listener) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
else if (l === null && hole === n) {
|
|
98
|
-
hole = i;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
listeners[hole] = listener;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
once(event, listener) {
|
|
106
|
-
listener.once = true;
|
|
107
|
-
this.on(event, listener);
|
|
108
|
-
}
|
|
109
|
-
pop() {
|
|
110
|
-
let item = this.data.pop();
|
|
111
|
-
if (item !== undefined) {
|
|
112
|
-
this.cleanup(item);
|
|
113
|
-
this.dispatch('pop', { item });
|
|
114
|
-
}
|
|
115
|
-
return item;
|
|
44
|
+
}
|
|
45
|
+
function dispose(data) {
|
|
46
|
+
let item;
|
|
47
|
+
while (item = data.pop()) {
|
|
48
|
+
cleanup(item);
|
|
116
49
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
50
|
+
}
|
|
51
|
+
function map(data, proxy, fn, i, n) {
|
|
52
|
+
if (i === undefined) {
|
|
53
|
+
i = 0;
|
|
121
54
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
this.dispatch('reverse');
|
|
125
|
-
return this;
|
|
55
|
+
if (n === undefined) {
|
|
56
|
+
n = data.length;
|
|
126
57
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
return item;
|
|
58
|
+
n = Math.min(n, data.length);
|
|
59
|
+
let values = new Array(n - i);
|
|
60
|
+
for (; i < n; i++) {
|
|
61
|
+
let item = data[i];
|
|
62
|
+
values[i] = fn.call(proxy, (isComputed(item) ? item.value : item), i);
|
|
134
63
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
64
|
+
return values;
|
|
65
|
+
}
|
|
66
|
+
function on(listeners, event, listener) {
|
|
67
|
+
let bucket = listeners[event];
|
|
68
|
+
if (bucket === undefined) {
|
|
69
|
+
listeners[event] = [listener];
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
let hole = bucket.length;
|
|
73
|
+
for (let i = 0, n = hole; i < n; i++) {
|
|
74
|
+
let l = bucket[i];
|
|
75
|
+
if (l === listener) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
else if (l === null && hole === n) {
|
|
79
|
+
hole = i;
|
|
145
80
|
}
|
|
146
|
-
this.dispatch('splice', {
|
|
147
|
-
deleteCount,
|
|
148
|
-
items,
|
|
149
|
-
start
|
|
150
|
-
});
|
|
151
81
|
}
|
|
152
|
-
|
|
82
|
+
bucket[hole] = listener;
|
|
153
83
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
84
|
+
}
|
|
85
|
+
function once(listeners, event, listener) {
|
|
86
|
+
listener.once = true;
|
|
87
|
+
on(listeners, event, listener);
|
|
88
|
+
}
|
|
89
|
+
function pop(data, listeners) {
|
|
90
|
+
let item = data.pop();
|
|
91
|
+
if (item !== undefined) {
|
|
92
|
+
cleanup(item);
|
|
93
|
+
dispatch(listeners, 'pop', { item });
|
|
158
94
|
}
|
|
95
|
+
return item;
|
|
159
96
|
}
|
|
160
|
-
function
|
|
161
|
-
let n =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
97
|
+
function push(data, listeners, items) {
|
|
98
|
+
let n = data.push(...items);
|
|
99
|
+
dispatch(listeners, 'push', { items });
|
|
100
|
+
return n;
|
|
101
|
+
}
|
|
102
|
+
function reverse(data, listeners) {
|
|
103
|
+
data.reverse();
|
|
104
|
+
dispatch(listeners, 'reverse');
|
|
105
|
+
}
|
|
106
|
+
function shift(data, listeners) {
|
|
107
|
+
let item = data.shift();
|
|
108
|
+
if (item !== undefined) {
|
|
109
|
+
cleanup(item);
|
|
110
|
+
dispatch(listeners, 'shift', { item });
|
|
173
111
|
}
|
|
174
|
-
return
|
|
112
|
+
return item;
|
|
113
|
+
}
|
|
114
|
+
function sort(data, listeners, fn) {
|
|
115
|
+
data.sort((a, b) => fn((isComputed(a) ? a.value : a), (isComputed(b) ? b.value : b)));
|
|
116
|
+
dispatch(listeners, 'sort');
|
|
117
|
+
}
|
|
118
|
+
function splice(data, listeners, start, deleteCount = data.length, items = []) {
|
|
119
|
+
let removed = data.splice(start, deleteCount, ...items);
|
|
120
|
+
if (items.length > 0 || removed.length > 0) {
|
|
121
|
+
for (let i = 0, n = removed.length; i < n; i++) {
|
|
122
|
+
cleanup(removed[i]);
|
|
123
|
+
}
|
|
124
|
+
dispatch(listeners, 'splice', {
|
|
125
|
+
deleteCount,
|
|
126
|
+
items,
|
|
127
|
+
start
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return removed;
|
|
175
131
|
}
|
|
176
|
-
|
|
177
|
-
let
|
|
132
|
+
function unshift(data, listeners, items) {
|
|
133
|
+
let length = data.unshift(...items);
|
|
134
|
+
dispatch(listeners, 'unshift', { items });
|
|
135
|
+
return length;
|
|
136
|
+
}
|
|
137
|
+
export default (data) => {
|
|
138
|
+
let listeners = {}, proxy = new Proxy({}, {
|
|
178
139
|
get(_, key) {
|
|
179
140
|
if (isNumber(key)) {
|
|
180
|
-
let value =
|
|
141
|
+
let value = data[key];
|
|
181
142
|
if (isComputed(value)) {
|
|
182
143
|
return read(value);
|
|
183
144
|
}
|
|
184
145
|
return value;
|
|
185
146
|
}
|
|
186
|
-
else if (key in
|
|
187
|
-
return
|
|
147
|
+
else if (key in wrapper) {
|
|
148
|
+
return wrapper[key];
|
|
149
|
+
}
|
|
150
|
+
else if (key === 'length') {
|
|
151
|
+
return data.length;
|
|
188
152
|
}
|
|
189
|
-
return
|
|
153
|
+
return data[key];
|
|
190
154
|
},
|
|
191
155
|
set(_, key, value) {
|
|
192
156
|
if (isNumber(key)) {
|
|
193
|
-
|
|
194
|
-
return true;
|
|
157
|
+
splice(data, listeners, key, 1, value);
|
|
195
158
|
}
|
|
196
159
|
else if (key === 'length') {
|
|
197
|
-
|
|
198
|
-
|
|
160
|
+
if (value >= data.length) {
|
|
161
|
+
}
|
|
162
|
+
else if (value === 0) {
|
|
163
|
+
clear(data, listeners);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
splice(data, listeners, value);
|
|
167
|
+
}
|
|
199
168
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
169
|
+
else {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
}), wrapper = {
|
|
175
|
+
[REACTIVE_ARRAY]: true,
|
|
176
|
+
at: (i) => at(data, i),
|
|
177
|
+
clear: () => {
|
|
178
|
+
clear(data, listeners);
|
|
179
|
+
return proxy;
|
|
180
|
+
},
|
|
181
|
+
dispatch: (event, value) => {
|
|
182
|
+
dispatch(listeners, event, value);
|
|
183
|
+
return proxy;
|
|
184
|
+
},
|
|
185
|
+
dispose: () => {
|
|
186
|
+
dispose(data);
|
|
187
|
+
return proxy;
|
|
188
|
+
},
|
|
189
|
+
map: (fn, i, n) => {
|
|
190
|
+
return map(data, proxy, fn, i, n);
|
|
191
|
+
},
|
|
192
|
+
on: (event, listener) => {
|
|
193
|
+
on(listeners, event, listener);
|
|
194
|
+
return proxy;
|
|
195
|
+
},
|
|
196
|
+
once: (event, listener) => {
|
|
197
|
+
once(listeners, event, listener);
|
|
198
|
+
return proxy;
|
|
199
|
+
},
|
|
200
|
+
pop: () => pop(data, listeners),
|
|
201
|
+
push: (...items) => push(data, listeners, items),
|
|
202
|
+
reverse: () => {
|
|
203
|
+
reverse(data, listeners);
|
|
204
|
+
return proxy;
|
|
205
|
+
},
|
|
206
|
+
shift: () => shift(data, listeners),
|
|
207
|
+
sort: (fn) => {
|
|
208
|
+
sort(data, listeners, fn);
|
|
209
|
+
return proxy;
|
|
210
|
+
},
|
|
211
|
+
splice: (start, deleteCount, ...items) => {
|
|
212
|
+
return splice(data, listeners, start, deleteCount, items);
|
|
213
|
+
},
|
|
214
|
+
unshift: (...items) => unshift(data, listeners, items),
|
|
215
|
+
};
|
|
204
216
|
return proxy;
|
|
205
217
|
};
|
|
@@ -3,7 +3,8 @@ import object from './object.js';
|
|
|
3
3
|
type API<T> = T extends Record<PropertyKey, unknown> ? ReturnType<typeof object<T>> : T extends unknown[] ? ReturnType<typeof array<T>> : never;
|
|
4
4
|
type Input<T> = T extends {
|
|
5
5
|
dispose: any;
|
|
6
|
-
} ?
|
|
7
|
-
|
|
6
|
+
} ? {
|
|
7
|
+
never: '[ dispose, signals ] are reserved keys';
|
|
8
|
+
} : T extends Record<PropertyKey, unknown> | unknown[] ? T : never;
|
|
9
|
+
declare const _default: <T>(input: Input<T>) => API<T>;
|
|
8
10
|
export default _default;
|
|
9
|
-
export type { Input };
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Prettify } from '@esportsplus/utilities';
|
|
2
2
|
import { Infer } from '../types.js';
|
|
3
3
|
import { REACTIVE_OBJECT } from '../constants.js';
|
|
4
|
-
type API<T
|
|
4
|
+
type API<T> = Prettify<{
|
|
5
5
|
[K in keyof T]: Infer<T[K]>;
|
|
6
|
-
}
|
|
6
|
+
} & {
|
|
7
|
+
dispose: VoidFunction;
|
|
8
|
+
}>;
|
|
7
9
|
declare class ReactiveObject<T extends Record<PropertyKey, unknown>> {
|
|
8
10
|
[REACTIVE_OBJECT]: boolean;
|
|
9
11
|
private disposers;
|
package/build/reactive/object.js
CHANGED
|
@@ -62,11 +62,12 @@ class ReactiveObject {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
dispose() {
|
|
65
|
-
let disposers = this.disposers;
|
|
66
|
-
if (disposers) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
let disposers = this.disposers, disposer;
|
|
66
|
+
if (!disposers) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
while (disposer = disposers.pop()) {
|
|
70
|
+
disposer();
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
}
|
package/build/types.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ interface Computed<T> {
|
|
|
15
15
|
subsTail: Link | null;
|
|
16
16
|
value: T;
|
|
17
17
|
}
|
|
18
|
-
type Infer<T> = T extends (...args: unknown[]) => Promise<infer R> ? R | undefined : T extends (...args: any[]) => infer R ? R : T extends (infer U)[] ?
|
|
18
|
+
type Infer<T> = T extends (...args: unknown[]) => Promise<infer R> ? R | undefined : T extends (...args: any[]) => infer R ? R : T extends (infer U)[] ? Infer<U>[] : T extends ReactiveObject<any> ? T : T extends Record<PropertyKey, unknown> ? {
|
|
19
19
|
[K in keyof T]: T[K];
|
|
20
20
|
} : T;
|
|
21
21
|
interface Link {
|
|
@@ -26,11 +26,10 @@ interface Link {
|
|
|
26
26
|
prevSub: Link | null;
|
|
27
27
|
version: number;
|
|
28
28
|
}
|
|
29
|
-
type Reactive<T> = T extends Record<PropertyKey, unknown> ? ReactiveObject<T> : ReactiveArray<T>;
|
|
30
29
|
type Signal<T> = {
|
|
31
30
|
[SIGNAL]: true;
|
|
32
31
|
subs: Link | null;
|
|
33
32
|
subsTail: Link | null;
|
|
34
33
|
value: T;
|
|
35
34
|
};
|
|
36
|
-
export type { Computed, Infer, Link, Signal,
|
|
35
|
+
export type { Computed, Infer, Link, Signal, ReactiveArray, ReactiveObject };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"author": "ICJR",
|
|
3
3
|
"dependencies": {
|
|
4
4
|
"@esportsplus/custom-function": "^0.0.13",
|
|
5
|
-
"@esportsplus/utilities": "^0.
|
|
5
|
+
"@esportsplus/utilities": "^0.22.1"
|
|
6
6
|
},
|
|
7
7
|
"devDependencies": {
|
|
8
8
|
"@esportsplus/typescript": "^0.9.2"
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"private": false,
|
|
13
13
|
"type": "module",
|
|
14
14
|
"types": "build/index.d.ts",
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.13.1",
|
|
16
16
|
"scripts": {
|
|
17
17
|
"build": "tsc && tsc-alias",
|
|
18
18
|
"-": "-"
|
package/src/reactive/array.ts
CHANGED
|
@@ -1,307 +1,246 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isNumber } from '@esportsplus/utilities';
|
|
2
2
|
import { REACTIVE_ARRAY } from '~/constants';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
3
|
+
import { dispose as d, isComputed, read } from '~/system';
|
|
4
|
+
import { Infer } from '~/types';
|
|
5
|
+
import { isReactiveObject } from './object';
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
type API<T> = Infer<T
|
|
8
|
+
type API<T> = Infer<T[]> & {
|
|
9
|
+
clear: () => void;
|
|
10
|
+
dispose: () => void;
|
|
11
|
+
};
|
|
9
12
|
|
|
10
13
|
type Events<T> = {
|
|
14
|
+
clear: undefined,
|
|
11
15
|
pop: {
|
|
12
|
-
item:
|
|
16
|
+
item: T;
|
|
13
17
|
};
|
|
14
18
|
push: {
|
|
15
|
-
items:
|
|
19
|
+
items: T[];
|
|
16
20
|
};
|
|
17
21
|
reverse: undefined;
|
|
18
22
|
set: {
|
|
19
23
|
index: number;
|
|
20
|
-
item:
|
|
24
|
+
item: T;
|
|
21
25
|
};
|
|
22
26
|
shift: {
|
|
23
|
-
item:
|
|
27
|
+
item: T;
|
|
24
28
|
};
|
|
25
29
|
sort: undefined;
|
|
26
30
|
splice: {
|
|
27
31
|
deleteCount: number;
|
|
28
|
-
items:
|
|
32
|
+
items: T[];
|
|
29
33
|
start: number;
|
|
30
34
|
};
|
|
31
35
|
unshift: {
|
|
32
|
-
items:
|
|
36
|
+
items: T[];
|
|
33
37
|
};
|
|
34
38
|
};
|
|
35
39
|
|
|
36
|
-
type Item<T> = T | Computed<T> | API<T> | ReactiveObject< T extends Record<PropertyKey, unknown> ? T : never >;
|
|
37
|
-
|
|
38
40
|
type Listener<V> = {
|
|
39
41
|
once?: boolean;
|
|
40
42
|
(value: V): void;
|
|
41
43
|
};
|
|
42
44
|
|
|
43
|
-
type
|
|
44
|
-
T extends Record<PropertyKey, unknown>
|
|
45
|
-
? ReactiveObject<T>
|
|
46
|
-
: T extends Array<infer U>
|
|
47
|
-
? API<U>
|
|
48
|
-
: T;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class ReactiveArray<T> {
|
|
52
|
-
[REACTIVE_ARRAY] = true;
|
|
53
|
-
disposables: number = 0;
|
|
54
|
-
|
|
55
|
-
private data: Item<T>[];
|
|
56
|
-
|
|
57
|
-
private listeners: Record<string, (Listener<any> | null)[]> | null = null;
|
|
45
|
+
type Listeners = Record<string, (Listener<any> | null)[]>;
|
|
58
46
|
|
|
59
|
-
private proxy: API<T>;
|
|
60
47
|
|
|
48
|
+
function at<T>(data: T[], i: number) {
|
|
49
|
+
let value = data[i];
|
|
61
50
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
this.proxy = proxy;
|
|
51
|
+
if (isComputed(value)) {
|
|
52
|
+
return read(value);
|
|
65
53
|
}
|
|
66
54
|
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
67
57
|
|
|
68
|
-
|
|
69
|
-
|
|
58
|
+
function cleanup<T>(item: T) {
|
|
59
|
+
if (isReactiveObject(item)) {
|
|
60
|
+
item.dispose();
|
|
70
61
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (n > this.data.length) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
this.splice(n);
|
|
62
|
+
else if (isComputed(item)) {
|
|
63
|
+
d(item);
|
|
78
64
|
}
|
|
65
|
+
}
|
|
79
66
|
|
|
67
|
+
function clear<T>(data: T[], listeners: Listeners) {
|
|
68
|
+
dispose(data);
|
|
69
|
+
dispatch(listeners, 'clear');
|
|
70
|
+
}
|
|
80
71
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
else if (isComputed(item)) {
|
|
86
|
-
dispose(item);
|
|
87
|
-
}
|
|
72
|
+
function dispatch<T, K extends keyof Events<T>, V>(listeners: Listeners, event: K, value?: V) {
|
|
73
|
+
if (listeners === null || listeners[event] === undefined) {
|
|
74
|
+
return;
|
|
88
75
|
}
|
|
89
76
|
|
|
77
|
+
let bucket = listeners[event];
|
|
90
78
|
|
|
91
|
-
|
|
92
|
-
let
|
|
93
|
-
|
|
94
|
-
if (isComputed(value)) {
|
|
95
|
-
return read(value);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return value;
|
|
99
|
-
}
|
|
79
|
+
for (let i = 0, n = bucket.length; i < n; i++) {
|
|
80
|
+
let listener = bucket[i];
|
|
100
81
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return;
|
|
82
|
+
if (listener === null) {
|
|
83
|
+
continue;
|
|
104
84
|
}
|
|
105
85
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
for (let i = 0, n = listeners.length; i < n; i++) {
|
|
109
|
-
let listener = listeners[i];
|
|
110
|
-
|
|
111
|
-
if (listener === null) {
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
try {
|
|
116
|
-
listener(value);
|
|
86
|
+
try {
|
|
87
|
+
listener(value);
|
|
117
88
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
catch {
|
|
123
|
-
listeners[i] = null;
|
|
89
|
+
if (listener.once !== undefined) {
|
|
90
|
+
bucket[i] = null;
|
|
124
91
|
}
|
|
125
92
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
dispose() {
|
|
129
|
-
for (let i = 0, n = this.data.length; i < n; i++) {
|
|
130
|
-
this.cleanup(this.data[i]);
|
|
93
|
+
catch {
|
|
94
|
+
bucket[i] = null;
|
|
131
95
|
}
|
|
132
96
|
}
|
|
97
|
+
}
|
|
133
98
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
i?: number,
|
|
137
|
-
n?: number
|
|
138
|
-
) {
|
|
139
|
-
let { data, proxy } = this;
|
|
99
|
+
function dispose<T>(data: T[]) {
|
|
100
|
+
let item;
|
|
140
101
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
102
|
+
while (item = data.pop()) {
|
|
103
|
+
cleanup(item);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
144
106
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
107
|
+
function map<T, R>(
|
|
108
|
+
data: T[],
|
|
109
|
+
proxy: API<T>,
|
|
110
|
+
fn: (this: API<T>, value: T, i: number) => R,
|
|
111
|
+
i?: number,
|
|
112
|
+
n?: number
|
|
113
|
+
) {
|
|
114
|
+
if (i === undefined) {
|
|
115
|
+
i = 0;
|
|
116
|
+
}
|
|
148
117
|
|
|
149
|
-
|
|
118
|
+
if (n === undefined) {
|
|
119
|
+
n = data.length;
|
|
120
|
+
}
|
|
150
121
|
|
|
151
|
-
|
|
122
|
+
n = Math.min(n, data.length);
|
|
152
123
|
|
|
153
|
-
|
|
154
|
-
let item = data[i];
|
|
124
|
+
let values: R[] = new Array(n - i);
|
|
155
125
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
(isComputed(item) ? item.value : item) as Value<T>,
|
|
159
|
-
i
|
|
160
|
-
);
|
|
161
|
-
}
|
|
126
|
+
for (; i < n; i++) {
|
|
127
|
+
let item = data[i];
|
|
162
128
|
|
|
163
|
-
|
|
129
|
+
values[i] = fn.call(
|
|
130
|
+
proxy,
|
|
131
|
+
(isComputed(item) ? item.value : item) as T,
|
|
132
|
+
i
|
|
133
|
+
);
|
|
164
134
|
}
|
|
165
135
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
this.listeners = { [event]: [listener] };
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
let listeners = this.listeners[event];
|
|
136
|
+
return values;
|
|
137
|
+
}
|
|
172
138
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
let hole = listeners.length;
|
|
139
|
+
function on<T, K extends keyof Events<T>>(listeners: Listeners, event: K, listener: Listener<Events<T>[K]>) {
|
|
140
|
+
let bucket = listeners[event];
|
|
178
141
|
|
|
179
|
-
|
|
180
|
-
|
|
142
|
+
if (bucket === undefined) {
|
|
143
|
+
listeners[event] = [listener];
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
let hole = bucket.length;
|
|
181
147
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
else if (l === null && hole === n) {
|
|
186
|
-
hole = i;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
148
|
+
for (let i = 0, n = hole; i < n; i++) {
|
|
149
|
+
let l = bucket[i];
|
|
189
150
|
|
|
190
|
-
|
|
151
|
+
if (l === listener) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
else if (l === null && hole === n) {
|
|
155
|
+
hole = i;
|
|
191
156
|
}
|
|
192
157
|
}
|
|
193
|
-
}
|
|
194
158
|
|
|
195
|
-
|
|
196
|
-
listener.once = true;
|
|
197
|
-
this.on(event, listener);
|
|
159
|
+
bucket[hole] = listener;
|
|
198
160
|
}
|
|
161
|
+
}
|
|
199
162
|
|
|
200
|
-
|
|
201
|
-
|
|
163
|
+
function once<T, K extends keyof Events<T>>(listeners: Listeners, event: K, listener: Listener<Events<T>[K]>) {
|
|
164
|
+
listener.once = true;
|
|
165
|
+
on(listeners, event, listener);
|
|
166
|
+
}
|
|
202
167
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
this.dispatch('pop', { item });
|
|
206
|
-
}
|
|
168
|
+
function pop<T>(data: T[], listeners: Listeners) {
|
|
169
|
+
let item = data.pop();
|
|
207
170
|
|
|
208
|
-
|
|
171
|
+
if (item !== undefined) {
|
|
172
|
+
cleanup(item);
|
|
173
|
+
dispatch(listeners, 'pop', { item });
|
|
209
174
|
}
|
|
210
175
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
n = this.data.push(...items);
|
|
176
|
+
return item;
|
|
177
|
+
}
|
|
214
178
|
|
|
215
|
-
|
|
179
|
+
function push<T>(data: T[], listeners: Listeners, items: T[]) {
|
|
180
|
+
let n = data.push(...items);
|
|
216
181
|
|
|
217
|
-
|
|
218
|
-
}
|
|
182
|
+
dispatch(listeners, 'push', { items });
|
|
219
183
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
this.dispatch('reverse');
|
|
223
|
-
|
|
224
|
-
return this;
|
|
225
|
-
}
|
|
184
|
+
return n;
|
|
185
|
+
}
|
|
226
186
|
|
|
227
|
-
|
|
228
|
-
|
|
187
|
+
function reverse<T>(data: T[], listeners: Listeners) {
|
|
188
|
+
data.reverse();
|
|
189
|
+
dispatch(listeners, 'reverse');
|
|
190
|
+
}
|
|
229
191
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
this.dispatch('shift', { item });
|
|
233
|
-
}
|
|
192
|
+
function shift<T>(data: T[], listeners: Listeners) {
|
|
193
|
+
let item = data.shift();
|
|
234
194
|
|
|
235
|
-
|
|
195
|
+
if (item !== undefined) {
|
|
196
|
+
cleanup(item);
|
|
197
|
+
dispatch(listeners, 'shift', { item });
|
|
236
198
|
}
|
|
237
199
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
(isComputed(a) ? a.value : a) as Value<T>,
|
|
241
|
-
(isComputed(b) ? b.value : b) as Value<T>
|
|
242
|
-
));
|
|
243
|
-
this.dispatch('sort');
|
|
244
|
-
|
|
245
|
-
return this;
|
|
246
|
-
}
|
|
200
|
+
return item;
|
|
201
|
+
}
|
|
247
202
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
203
|
+
function sort<T>(data: T[], listeners: Listeners, fn: (a: T, b: T) => number) {
|
|
204
|
+
data.sort((a, b) => fn(
|
|
205
|
+
(isComputed(a) ? a.value : a) as T,
|
|
206
|
+
(isComputed(b) ? b.value : b) as T
|
|
207
|
+
));
|
|
208
|
+
dispatch(listeners, 'sort');
|
|
209
|
+
}
|
|
251
210
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
this.cleanup(removed[i]);
|
|
255
|
-
}
|
|
211
|
+
function splice<T>(data: T[], listeners: Listeners, start: number, deleteCount: number = data.length, items: T[] = []) {
|
|
212
|
+
let removed = data.splice(start, deleteCount, ...items);
|
|
256
213
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
start
|
|
261
|
-
});
|
|
214
|
+
if (items.length > 0 || removed.length > 0) {
|
|
215
|
+
for (let i = 0, n = removed.length; i < n; i++) {
|
|
216
|
+
cleanup(removed[i]);
|
|
262
217
|
}
|
|
263
218
|
|
|
264
|
-
|
|
219
|
+
dispatch(listeners, 'splice', {
|
|
220
|
+
deleteCount,
|
|
221
|
+
items,
|
|
222
|
+
start
|
|
223
|
+
});
|
|
265
224
|
}
|
|
266
225
|
|
|
267
|
-
|
|
268
|
-
let items = factory(input),
|
|
269
|
-
length = this.data.unshift(...items);
|
|
270
|
-
|
|
271
|
-
this.dispatch('unshift', { items });
|
|
272
|
-
|
|
273
|
-
return length;
|
|
274
|
-
}
|
|
226
|
+
return removed;
|
|
275
227
|
}
|
|
276
228
|
|
|
229
|
+
function unshift<T>(data: T[], listeners: Listeners, items: T[]) {
|
|
230
|
+
let length = data.unshift(...items);
|
|
277
231
|
|
|
278
|
-
|
|
279
|
-
let n = input.length,
|
|
280
|
-
output: Item<T>[] = new Array(n);
|
|
232
|
+
dispatch(listeners, 'unshift', { items });
|
|
281
233
|
|
|
282
|
-
|
|
283
|
-
let value = input[i];
|
|
284
|
-
|
|
285
|
-
if (isFunction(value)) {
|
|
286
|
-
output[i] = computed(value as Computed<T>['fn']);
|
|
287
|
-
}
|
|
288
|
-
else if (isObject(value)) {
|
|
289
|
-
output[i] = object(value) as Item<T>;
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
output[i] = value;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
return output;
|
|
234
|
+
return length;
|
|
297
235
|
}
|
|
298
236
|
|
|
299
237
|
|
|
300
|
-
export default <T>(
|
|
301
|
-
let
|
|
302
|
-
|
|
238
|
+
export default <T>(data: T[]) => {
|
|
239
|
+
let listeners: Listeners = {},
|
|
240
|
+
proxy = new Proxy({}, {
|
|
241
|
+
get(_, key: any) {
|
|
303
242
|
if (isNumber(key)) {
|
|
304
|
-
let value =
|
|
243
|
+
let value = data[key];
|
|
305
244
|
|
|
306
245
|
if (isComputed(value)) {
|
|
307
246
|
return read(value);
|
|
@@ -309,29 +248,83 @@ export default <T>(input: T[]) => {
|
|
|
309
248
|
|
|
310
249
|
return value;
|
|
311
250
|
}
|
|
312
|
-
else if (key in
|
|
313
|
-
return
|
|
251
|
+
else if (key in wrapper) {
|
|
252
|
+
return wrapper[key as keyof typeof wrapper];
|
|
253
|
+
}
|
|
254
|
+
else if (key === 'length') {
|
|
255
|
+
return data.length;
|
|
314
256
|
}
|
|
315
257
|
|
|
316
|
-
return
|
|
258
|
+
return data[key];
|
|
317
259
|
},
|
|
318
|
-
set(_
|
|
260
|
+
set(_, key: any, value: any) {
|
|
319
261
|
if (isNumber(key)) {
|
|
320
|
-
|
|
321
|
-
return true;
|
|
262
|
+
splice(data, listeners, key, 1, value);
|
|
322
263
|
}
|
|
323
264
|
else if (key === 'length') {
|
|
324
|
-
|
|
325
|
-
|
|
265
|
+
if (value >= data.length) {
|
|
266
|
+
}
|
|
267
|
+
else if (value === 0) {
|
|
268
|
+
clear(data, listeners);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
splice(data, listeners, value);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
return false;
|
|
326
276
|
}
|
|
327
277
|
|
|
328
|
-
return
|
|
278
|
+
return true;
|
|
329
279
|
}
|
|
330
280
|
}) as API<T>,
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
281
|
+
wrapper = {
|
|
282
|
+
[REACTIVE_ARRAY]: true,
|
|
283
|
+
at: (i: number) => at(data, i),
|
|
284
|
+
clear: () => {
|
|
285
|
+
clear(data, listeners);
|
|
286
|
+
return proxy;
|
|
287
|
+
},
|
|
288
|
+
dispatch: <K extends keyof Events<T>, V>(event: K, value?: V) => {
|
|
289
|
+
dispatch(listeners, event, value);
|
|
290
|
+
return proxy;
|
|
291
|
+
},
|
|
292
|
+
dispose: () => {
|
|
293
|
+
dispose(data);
|
|
294
|
+
return proxy;
|
|
295
|
+
},
|
|
296
|
+
map: <R>(
|
|
297
|
+
fn: (this: API<T>, value: T, i: number) => R,
|
|
298
|
+
i?: number,
|
|
299
|
+
n?: number
|
|
300
|
+
) => {
|
|
301
|
+
return map(data, proxy, fn, i, n);
|
|
302
|
+
},
|
|
303
|
+
on: <K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>) => {
|
|
304
|
+
on(listeners, event, listener);
|
|
305
|
+
return proxy;
|
|
306
|
+
},
|
|
307
|
+
once: <K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>) => {
|
|
308
|
+
once(listeners, event, listener);
|
|
309
|
+
return proxy;
|
|
310
|
+
},
|
|
311
|
+
pop: () => pop(data, listeners),
|
|
312
|
+
push: (...items: T[]) => push(data, listeners, items),
|
|
313
|
+
reverse: () => {
|
|
314
|
+
reverse(data, listeners);
|
|
315
|
+
return proxy;
|
|
316
|
+
},
|
|
317
|
+
shift: () => shift(data, listeners),
|
|
318
|
+
sort: (fn: (a: T, b: T) => number) => {
|
|
319
|
+
sort(data, listeners, fn);
|
|
320
|
+
return proxy;
|
|
321
|
+
},
|
|
322
|
+
splice: (start: number, deleteCount?: number, ...items: T[]) => {
|
|
323
|
+
return splice(data, listeners, start, deleteCount, items);
|
|
324
|
+
},
|
|
325
|
+
unshift: (...items: T[]) => unshift(data, listeners, items),
|
|
326
|
+
};
|
|
334
327
|
|
|
335
328
|
return proxy;
|
|
336
329
|
};
|
|
337
|
-
export type { API as ReactiveArray };
|
|
330
|
+
export type { API as ReactiveArray };
|
package/src/reactive/index.ts
CHANGED
|
@@ -13,15 +13,13 @@ type API<T> =
|
|
|
13
13
|
|
|
14
14
|
type Input<T> =
|
|
15
15
|
T extends { dispose: any }
|
|
16
|
-
? never
|
|
17
|
-
: T extends Record<PropertyKey, unknown>
|
|
16
|
+
? { never: '[ dispose, signals ] are reserved keys' }
|
|
17
|
+
: T extends Record<PropertyKey, unknown> | unknown[]
|
|
18
18
|
? T
|
|
19
|
-
:
|
|
20
|
-
? Input<T[number]>[]
|
|
21
|
-
: never;
|
|
19
|
+
: never;
|
|
22
20
|
|
|
23
21
|
|
|
24
|
-
export default <T
|
|
22
|
+
export default <T>(input: Input<T>): API<T> => {
|
|
25
23
|
let value: API<T> | undefined;
|
|
26
24
|
|
|
27
25
|
return root(() => {
|
|
@@ -42,5 +40,4 @@ export default <T extends Record<PropertyKey, unknown> | unknown[]>(input: Input
|
|
|
42
40
|
|
|
43
41
|
throw new Error(`@esportsplus/reactivity: 'reactive' received invalid input - ${JSON.stringify(input)}`);
|
|
44
42
|
});
|
|
45
|
-
};
|
|
46
|
-
export type { Input };
|
|
43
|
+
};
|
package/src/reactive/object.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { REACTIVE_OBJECT } from '~/constants';
|
|
|
5
5
|
import array from './array';
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
type API<T
|
|
8
|
+
type API<T> = Prettify<{ [K in keyof T]: Infer<T[K]> } & { dispose: VoidFunction } >;
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class ReactiveObject<T extends Record<PropertyKey, unknown>> {
|
|
@@ -90,12 +90,15 @@ class ReactiveObject<T extends Record<PropertyKey, unknown>> {
|
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
dispose() {
|
|
93
|
-
let disposers = this.disposers
|
|
93
|
+
let disposers = this.disposers,
|
|
94
|
+
disposer;
|
|
94
95
|
|
|
95
|
-
if (disposers) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
if (!disposers) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
while (disposer = disposers.pop()) {
|
|
101
|
+
disposer();
|
|
99
102
|
}
|
|
100
103
|
}
|
|
101
104
|
}
|
package/src/types.ts
CHANGED
|
@@ -29,7 +29,7 @@ type Infer<T> =
|
|
|
29
29
|
: T extends (...args: any[]) => infer R
|
|
30
30
|
? R
|
|
31
31
|
: T extends (infer U)[]
|
|
32
|
-
?
|
|
32
|
+
? Infer<U>[]
|
|
33
33
|
: T extends ReactiveObject<any>
|
|
34
34
|
? T
|
|
35
35
|
: T extends Record<PropertyKey, unknown>
|
|
@@ -45,10 +45,6 @@ interface Link {
|
|
|
45
45
|
version: number;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
type Reactive<T> = T extends Record<PropertyKey, unknown>
|
|
49
|
-
? ReactiveObject<T>
|
|
50
|
-
: ReactiveArray<T>;
|
|
51
|
-
|
|
52
48
|
type Signal<T> = {
|
|
53
49
|
[SIGNAL]: true;
|
|
54
50
|
subs: Link | null;
|
|
@@ -62,5 +58,5 @@ export type {
|
|
|
62
58
|
Infer,
|
|
63
59
|
Link,
|
|
64
60
|
Signal,
|
|
65
|
-
|
|
61
|
+
ReactiveArray, ReactiveObject
|
|
66
62
|
};
|