@esportsplus/reactivity 0.0.30 → 0.1.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/bench.d.ts +1 -0
- package/build/bench.js +46 -0
- package/build/constants.d.ts +8 -0
- package/build/constants.js +8 -0
- package/build/context/node.d.ts +1 -1
- package/build/context/node.js +1 -1
- package/build/context/nodes.d.ts +1 -1
- package/build/context/nodes.js +1 -1
- package/build/effect.d.ts +2 -6
- package/build/effect.js +1 -2
- package/build/index.d.ts +2 -4
- package/build/index.js +2 -4
- package/build/macro.d.ts +10 -7
- package/build/macro.js +17 -5
- package/build/promise.d.ts +25 -5
- package/build/promise.js +37 -30
- package/build/reactive/array.d.ts +60 -0
- package/build/reactive/array.js +136 -0
- package/build/reactive/index.d.ts +11 -0
- package/build/reactive/index.js +4 -0
- package/build/reactive/object.d.ts +14 -0
- package/build/reactive/object.js +60 -0
- package/build/reactive/object2.d.ts +10 -0
- package/build/reactive/object2.js +65 -0
- package/build/reactive/types.d.ts +33 -0
- package/build/reactive/types.js +1 -0
- package/build/reactive-array.d.ts +1 -0
- package/build/reactive-array.js +106 -0
- package/build/reactive.js +2 -2
- package/build/resource.d.ts +16 -0
- package/build/resource.js +55 -0
- package/build/signal.d.ts +17 -12
- package/build/signal.js +71 -37
- package/build/testing/node.d.ts +13 -0
- package/build/testing/node.js +21 -0
- package/build/testing/nodes.d.ts +13 -0
- package/build/testing/nodes.js +33 -0
- package/build/testing/reactive.d.ts +0 -0
- package/build/testing/reactive.js +1 -0
- package/build/trigger.d.ts +15 -0
- package/build/trigger.js +30 -0
- package/build/types.d.ts +15 -17
- package/build/utilities.d.ts +3 -0
- package/build/utilities.js +3 -0
- package/package.json +5 -2
- package/src/constants.ts +17 -0
- package/src/index.ts +3 -5
- package/src/macro.ts +29 -9
- package/src/reactive/array.ts +219 -0
- package/src/reactive/index.ts +26 -0
- package/src/reactive/object.ts +93 -0
- package/src/resource.ts +79 -0
- package/src/signal.ts +91 -52
- package/src/types.ts +13 -19
- package/src/utilities.ts +6 -0
- package/src/context/index.ts +0 -5
- package/src/context/node.ts +0 -36
- package/src/context/nodes.ts +0 -52
- package/src/effect.ts +0 -5
- package/src/promise.ts +0 -48
- package/src/reactive.ts +0 -47
- package/src/symbols.ts +0 -29
package/build/bench.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/build/bench.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import object from './reactive';
|
|
2
|
+
import object2 from './reactive/object2';
|
|
3
|
+
console.time('original');
|
|
4
|
+
for (let i = 0, n = 10000; i < n; i++) {
|
|
5
|
+
let obj = object({
|
|
6
|
+
something: 'else',
|
|
7
|
+
what: 0,
|
|
8
|
+
does: 'sadsadsadsaasd',
|
|
9
|
+
elser: true,
|
|
10
|
+
hey: [
|
|
11
|
+
{
|
|
12
|
+
something: 'else',
|
|
13
|
+
what: 0,
|
|
14
|
+
does: 'sadsadsadsaasd',
|
|
15
|
+
elser: true,
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
});
|
|
19
|
+
obj.something;
|
|
20
|
+
obj.what;
|
|
21
|
+
obj.does;
|
|
22
|
+
obj.hey[0].something;
|
|
23
|
+
}
|
|
24
|
+
console.timeEnd('original');
|
|
25
|
+
console.time('lazy');
|
|
26
|
+
for (let i = 0, n = 10000; i < n; i++) {
|
|
27
|
+
let obj = object2({
|
|
28
|
+
something: 'else',
|
|
29
|
+
what: 0,
|
|
30
|
+
does: 'sadsadsadsaasd',
|
|
31
|
+
elser: true,
|
|
32
|
+
hey: [
|
|
33
|
+
{
|
|
34
|
+
something: 'else',
|
|
35
|
+
what: 0,
|
|
36
|
+
does: 'sadsadsadsaasd',
|
|
37
|
+
elser: true,
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
});
|
|
41
|
+
obj.something;
|
|
42
|
+
obj.what;
|
|
43
|
+
obj.does;
|
|
44
|
+
obj.hey[0].something;
|
|
45
|
+
}
|
|
46
|
+
console.timeEnd('lazy');
|
package/build/context/node.d.ts
CHANGED
package/build/context/node.js
CHANGED
package/build/context/nodes.d.ts
CHANGED
package/build/context/nodes.js
CHANGED
package/build/effect.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
on: (event: symbol, listener: import("./types").Listener) => void;
|
|
4
|
-
once: (event: symbol, listener: import("./types").Listener) => void;
|
|
5
|
-
reset: () => void;
|
|
6
|
-
};
|
|
1
|
+
import { API, Effect, Options, Prettify } from './types';
|
|
2
|
+
declare const _default: <T>(fn: (previous: T) => T, options: Options) => Omit<API<T>, "value"> extends infer T_1 ? { [K in keyof T_1]: Omit<API<T>, "value">[K]; } : never;
|
|
7
3
|
export default _default;
|
package/build/effect.js
CHANGED
package/build/index.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
export { default as effect } from './effect';
|
|
2
1
|
export { default as macro } from './macro';
|
|
3
|
-
export { default as
|
|
2
|
+
export { default as resource } from './resource';
|
|
4
3
|
export * as core from './signal';
|
|
5
|
-
export { root } from './signal';
|
|
4
|
+
export { effect, root } from './signal';
|
|
6
5
|
export { default as reactive } from './reactive';
|
|
7
|
-
export { DISPOSE, RESET, UPDATE } from './symbols';
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
export { default as effect } from './effect';
|
|
2
1
|
export { default as macro } from './macro';
|
|
3
|
-
export { default as
|
|
2
|
+
export { default as resource } from './resource';
|
|
4
3
|
export * as core from './signal';
|
|
5
|
-
export { root } from './signal';
|
|
4
|
+
export { effect, root } from './signal';
|
|
6
5
|
export { default as reactive } from './reactive';
|
|
7
|
-
export { DISPOSE, RESET, UPDATE } from './symbols';
|
package/build/macro.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import CustomFunction from '@esportsplus/custom-function';
|
|
1
2
|
import { computed } from './signal';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
type Fn<A extends unknown[], R> = Parameters<typeof computed<(...args: A) => R>>[0];
|
|
4
|
+
type Options = Parameters<typeof computed>[1];
|
|
5
|
+
declare class Macro<A extends unknown[], R> extends CustomFunction {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(fn: Fn<A, R>, options?: Options);
|
|
8
|
+
dispose(): void;
|
|
9
|
+
reset(): void;
|
|
10
|
+
}
|
|
11
|
+
declare const _default: <A extends unknown[], R>(fn: (previous: (...args: A) => R) => (...args: A) => R, options?: Options) => Macro<A, R>;
|
|
9
12
|
export default _default;
|
package/build/macro.js
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
import CustomFunction from '@esportsplus/custom-function';
|
|
1
2
|
import { computed, read } from './signal';
|
|
2
|
-
|
|
3
|
+
class Macro extends CustomFunction {
|
|
4
|
+
#factory;
|
|
5
|
+
constructor(fn, options = {}) {
|
|
6
|
+
super((...args) => {
|
|
7
|
+
return read(this.#factory)(...args);
|
|
8
|
+
});
|
|
9
|
+
this.#factory = computed(fn, options);
|
|
10
|
+
}
|
|
11
|
+
dispose() {
|
|
12
|
+
this.#factory.dispose();
|
|
13
|
+
}
|
|
14
|
+
reset() {
|
|
15
|
+
this.#factory.reset();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
3
18
|
export default (fn, options = {}) => {
|
|
4
|
-
|
|
5
|
-
return context.node((...args) => {
|
|
6
|
-
return read(node)(...args);
|
|
7
|
-
}, node);
|
|
19
|
+
return new Macro(fn, options);
|
|
8
20
|
};
|
package/build/promise.d.ts
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
|
+
import CustomFunction from '@esportsplus/custom-function';
|
|
1
2
|
import { computed } from './signal';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import { API, Signal } from './types';
|
|
4
|
+
type Fn = <A, R extends Promise<any>>(...args: A[]) => R;
|
|
5
|
+
type Options = Parameters<typeof computed>[1];
|
|
6
|
+
type R<T extends Fn> = Omit<ReactivePromise<T>, 'fn' | 'input' | 'nodes'> & {
|
|
7
|
+
readonly fn: T;
|
|
8
|
+
readonly input: Parameters<T> | null;
|
|
9
|
+
readonly nodes: {
|
|
10
|
+
data: API<ReturnType<T>>;
|
|
11
|
+
ok: API<boolean | null>;
|
|
12
|
+
};
|
|
7
13
|
};
|
|
14
|
+
declare class ReactivePromise<T extends Fn> extends CustomFunction {
|
|
15
|
+
fn: T;
|
|
16
|
+
input: Parameters<T> | null;
|
|
17
|
+
nodes: {
|
|
18
|
+
data: Signal<ReturnType<T>>;
|
|
19
|
+
ok: Signal<boolean | null>;
|
|
20
|
+
};
|
|
21
|
+
stop: boolean | null;
|
|
22
|
+
constructor(fn: T, options?: Options);
|
|
23
|
+
get data(): ReturnType<T> | ReturnType<ReturnType<T> extends infer T_1 ? T_1 extends ReturnType<T> ? T_1 extends Promise<unknown> ? never : (previous: T_1) => T_1 : never : never>;
|
|
24
|
+
get ok(): boolean | null;
|
|
25
|
+
invoke(...args: Parameters<T>): void;
|
|
26
|
+
}
|
|
27
|
+
declare const _default: <T extends Fn>(fn: T, options?: Options) => R<T>;
|
|
8
28
|
export default _default;
|
package/build/promise.js
CHANGED
|
@@ -1,38 +1,45 @@
|
|
|
1
|
+
import CustomFunction from '@esportsplus/custom-function';
|
|
1
2
|
import { read, root, signal, write } from './signal';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
class ReactivePromise extends CustomFunction {
|
|
4
|
+
fn;
|
|
5
|
+
input = null;
|
|
6
|
+
nodes;
|
|
7
|
+
stop = null;
|
|
8
|
+
constructor(fn, options = {}) {
|
|
9
|
+
super((...args) => this.invoke(...args));
|
|
10
|
+
this.fn = fn;
|
|
11
|
+
this.nodes = {
|
|
12
|
+
data: signal(options.value, options),
|
|
13
|
+
ok: signal(null, options)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
get data() {
|
|
17
|
+
return read(this.nodes.data);
|
|
18
|
+
}
|
|
19
|
+
get ok() {
|
|
20
|
+
return read(this.nodes.ok);
|
|
21
|
+
}
|
|
22
|
+
invoke(...args) {
|
|
23
|
+
this.input = args;
|
|
24
|
+
this.stop = null;
|
|
10
25
|
root(() => {
|
|
11
|
-
|
|
26
|
+
write(this.nodes.ok, null);
|
|
27
|
+
this.fn(...args)
|
|
12
28
|
.then((value) => {
|
|
13
|
-
|
|
29
|
+
if (this.stop === true) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
write(this.nodes.data, value);
|
|
33
|
+
write(this.nodes.ok, true);
|
|
14
34
|
})
|
|
15
35
|
.catch(() => {
|
|
16
|
-
|
|
36
|
+
if (this.stop === true) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
write(this.nodes.data, undefined);
|
|
40
|
+
write(this.nodes.ok, false);
|
|
17
41
|
});
|
|
18
42
|
});
|
|
19
43
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
get() {
|
|
23
|
-
return read(nodes.data);
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
input: {
|
|
27
|
-
get() {
|
|
28
|
-
return input;
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
status: {
|
|
32
|
-
get() {
|
|
33
|
-
return read(nodes.status);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
return context.nodes(host, nodes);
|
|
38
|
-
};
|
|
44
|
+
}
|
|
45
|
+
export default (fn, options = {}) => new ReactivePromise(fn, options);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Listener, Options } from '../types';
|
|
2
|
+
import { ReactiveObject } from './object';
|
|
3
|
+
type Events<T> = {
|
|
4
|
+
fill: {
|
|
5
|
+
value: T;
|
|
6
|
+
};
|
|
7
|
+
pop: {
|
|
8
|
+
item: T;
|
|
9
|
+
};
|
|
10
|
+
push: {
|
|
11
|
+
items: T[];
|
|
12
|
+
};
|
|
13
|
+
reverse: undefined;
|
|
14
|
+
shift: {
|
|
15
|
+
item: T;
|
|
16
|
+
};
|
|
17
|
+
sort: undefined;
|
|
18
|
+
splice: {
|
|
19
|
+
deleteCount: number;
|
|
20
|
+
items: T[];
|
|
21
|
+
start: number;
|
|
22
|
+
};
|
|
23
|
+
unshift: {
|
|
24
|
+
items: T[];
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
type Node<T extends Record<PropertyKey, unknown>> = ReactiveObject<T>;
|
|
28
|
+
declare class ReactiveArray<T> extends Array<T> {
|
|
29
|
+
#private;
|
|
30
|
+
constructor(data: T[]);
|
|
31
|
+
set length(n: number);
|
|
32
|
+
private trigger;
|
|
33
|
+
dispatch<E extends keyof Events<T>>(event: E, data?: Events<T>[E]): void;
|
|
34
|
+
dispose(): void;
|
|
35
|
+
fill(value: T, start?: number, end?: number): this;
|
|
36
|
+
on<E extends keyof Events<T>>(event: E, listener: Listener<Events<T>[E]>): void;
|
|
37
|
+
once<E extends keyof Events<T>>(event: E, listener: Listener<Events<T>[E]>): void;
|
|
38
|
+
pop(): T | undefined;
|
|
39
|
+
push(...items: T[]): number;
|
|
40
|
+
reset(): void;
|
|
41
|
+
reverse(): this;
|
|
42
|
+
shift(): T | undefined;
|
|
43
|
+
sort(): this;
|
|
44
|
+
splice(start: number, deleteCount?: number, ...items: T[]): T[];
|
|
45
|
+
track(): void;
|
|
46
|
+
unshift(...items: T[]): number;
|
|
47
|
+
}
|
|
48
|
+
declare class ReactiveObjectArray<T extends Record<PropertyKey, unknown>> extends ReactiveArray<Node<T>> {
|
|
49
|
+
#private;
|
|
50
|
+
constructor(data: T[], options?: Options);
|
|
51
|
+
fill(): never;
|
|
52
|
+
reverse(): never;
|
|
53
|
+
pop(): Node<T> | undefined;
|
|
54
|
+
push(...values: T[]): number;
|
|
55
|
+
shift(): Node<T> | undefined;
|
|
56
|
+
sort(): never;
|
|
57
|
+
splice(start: number, deleteCount?: number, ...values: T[]): Node<T> | Node<T>[] | undefined;
|
|
58
|
+
unshift(...values: T[]): number;
|
|
59
|
+
}
|
|
60
|
+
export { ReactiveArray, ReactiveObjectArray };
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { dispose, read, signal, write } from '../signal';
|
|
2
|
+
import { ReactiveObject } from './object';
|
|
3
|
+
function factory(data, options = {}) {
|
|
4
|
+
let signals = [];
|
|
5
|
+
for (let i = 0, n = data.length; i < n; i++) {
|
|
6
|
+
signals.push(new ReactiveObject(data[i], options));
|
|
7
|
+
}
|
|
8
|
+
return signals;
|
|
9
|
+
}
|
|
10
|
+
function unsupported(method) {
|
|
11
|
+
throw new Error(`Reactivity: '${method}' is not supported on reactive object array`);
|
|
12
|
+
}
|
|
13
|
+
class ReactiveArray extends Array {
|
|
14
|
+
#signal;
|
|
15
|
+
constructor(data) {
|
|
16
|
+
super(...data);
|
|
17
|
+
this.#signal = signal(false);
|
|
18
|
+
}
|
|
19
|
+
set length(n) {
|
|
20
|
+
if (n > this.length) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
this.splice(n);
|
|
24
|
+
}
|
|
25
|
+
trigger() {
|
|
26
|
+
write(this.#signal, !this.#signal.value);
|
|
27
|
+
}
|
|
28
|
+
dispatch(event, data) {
|
|
29
|
+
this.#signal.dispatch(event, data);
|
|
30
|
+
}
|
|
31
|
+
dispose() {
|
|
32
|
+
this.#signal.dispose();
|
|
33
|
+
}
|
|
34
|
+
fill(value, start, end) {
|
|
35
|
+
super.fill(value, start, end);
|
|
36
|
+
this.dispatch('fill', { value });
|
|
37
|
+
this.trigger();
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
on(event, listener) {
|
|
41
|
+
this.#signal.on(event, listener);
|
|
42
|
+
}
|
|
43
|
+
once(event, listener) {
|
|
44
|
+
this.#signal.once(event, listener);
|
|
45
|
+
}
|
|
46
|
+
pop() {
|
|
47
|
+
let item = super.pop();
|
|
48
|
+
if (item !== undefined) {
|
|
49
|
+
this.dispatch('pop', { item });
|
|
50
|
+
this.trigger();
|
|
51
|
+
}
|
|
52
|
+
return item;
|
|
53
|
+
}
|
|
54
|
+
push(...items) {
|
|
55
|
+
let n = super.push(...items);
|
|
56
|
+
this.dispatch('push', { items });
|
|
57
|
+
this.trigger();
|
|
58
|
+
return n;
|
|
59
|
+
}
|
|
60
|
+
reset() {
|
|
61
|
+
this.#signal.reset();
|
|
62
|
+
}
|
|
63
|
+
reverse() {
|
|
64
|
+
super.reverse();
|
|
65
|
+
this.dispatch('reverse');
|
|
66
|
+
this.trigger();
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
shift() {
|
|
70
|
+
let item = super.shift();
|
|
71
|
+
if (item !== undefined) {
|
|
72
|
+
this.dispatch('shift', { item });
|
|
73
|
+
this.trigger();
|
|
74
|
+
}
|
|
75
|
+
return item;
|
|
76
|
+
}
|
|
77
|
+
sort() {
|
|
78
|
+
super.sort();
|
|
79
|
+
this.dispatch('sort');
|
|
80
|
+
this.trigger();
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
splice(start, deleteCount = super.length, ...items) {
|
|
84
|
+
let removed = super.splice(start, deleteCount, ...items);
|
|
85
|
+
if (items.length > 0 || removed.length > 0) {
|
|
86
|
+
this.dispatch('splice', {
|
|
87
|
+
deleteCount,
|
|
88
|
+
items,
|
|
89
|
+
start
|
|
90
|
+
});
|
|
91
|
+
this.trigger();
|
|
92
|
+
}
|
|
93
|
+
return removed;
|
|
94
|
+
}
|
|
95
|
+
track() {
|
|
96
|
+
read(this.#signal);
|
|
97
|
+
}
|
|
98
|
+
unshift(...items) {
|
|
99
|
+
let length = super.unshift(...items);
|
|
100
|
+
this.dispatch('unshift', { items });
|
|
101
|
+
this.trigger();
|
|
102
|
+
return length;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
class ReactiveObjectArray extends ReactiveArray {
|
|
106
|
+
#options;
|
|
107
|
+
constructor(data, options = {}) {
|
|
108
|
+
super(factory(data, options));
|
|
109
|
+
this.#options = options;
|
|
110
|
+
}
|
|
111
|
+
fill() {
|
|
112
|
+
return unsupported('fill');
|
|
113
|
+
}
|
|
114
|
+
reverse() {
|
|
115
|
+
return unsupported('reverse');
|
|
116
|
+
}
|
|
117
|
+
pop() {
|
|
118
|
+
return dispose(super.pop());
|
|
119
|
+
}
|
|
120
|
+
push(...values) {
|
|
121
|
+
return super.push(...factory(values, this.#options));
|
|
122
|
+
}
|
|
123
|
+
shift() {
|
|
124
|
+
return dispose(super.shift());
|
|
125
|
+
}
|
|
126
|
+
sort() {
|
|
127
|
+
return unsupported('sort');
|
|
128
|
+
}
|
|
129
|
+
splice(start, deleteCount = super.length, ...values) {
|
|
130
|
+
return dispose(super.splice(start, deleteCount, ...factory(values, this.#options)));
|
|
131
|
+
}
|
|
132
|
+
unshift(...values) {
|
|
133
|
+
return super.unshift(...factory(values, this.#options));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export { ReactiveArray, ReactiveObjectArray };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Object, Options } from '../types';
|
|
2
|
+
import { ReactiveObject } from './object';
|
|
3
|
+
type Guard<T> = T extends Object ? {
|
|
4
|
+
[K in keyof T]: Never<K, Guard<T[K]>>;
|
|
5
|
+
} : T extends unknown[] ? Guard<T[number]>[] : T;
|
|
6
|
+
type Infer<T> = T extends (...args: unknown[]) => unknown ? ReturnType<T> : T extends unknown[] ? Infer<T[number]>[] : T extends Object ? {
|
|
7
|
+
[K in keyof T]: T[K];
|
|
8
|
+
} : T;
|
|
9
|
+
type Never<K, V> = K extends keyof ReactiveObject<Object> ? never : V;
|
|
10
|
+
declare const _default: <T extends Object>(data: Guard<T>, options?: Options) => { [K_1 in keyof T]: Infer<T[K_1]>; } & ReactiveObject<T> extends infer T_1 ? { [K in keyof T_1]: ({ [K_1 in keyof T]: Infer<T[K_1]>; } & ReactiveObject<T>)[K]; } : never;
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Computed, Options, Signal } from '../types';
|
|
2
|
+
import { ReactiveArray, ReactiveObjectArray } from './array';
|
|
3
|
+
type Node<T> = T extends (...args: unknown[]) => unknown ? Computed<T> : T extends unknown[] ? T extends Object[] ? ReactiveObjectArray<T[0]> : ReactiveArray<T> : Signal<T>;
|
|
4
|
+
type Nodes<T extends Object> = {
|
|
5
|
+
[K in keyof T]: Node<T[K]>;
|
|
6
|
+
};
|
|
7
|
+
type Object = Record<PropertyKey, unknown>;
|
|
8
|
+
declare class ReactiveObject<T extends Object> {
|
|
9
|
+
nodes: Nodes<T>;
|
|
10
|
+
constructor(data: T, options?: Options);
|
|
11
|
+
dispose(): void;
|
|
12
|
+
reset(): void;
|
|
13
|
+
}
|
|
14
|
+
export { ReactiveObject };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { computed, read, signal, write } from '../signal';
|
|
2
|
+
import { defineProperty, isArray } from '../utilities';
|
|
3
|
+
import { ReactiveArray, ReactiveObjectArray } from './array';
|
|
4
|
+
class ReactiveObject {
|
|
5
|
+
nodes;
|
|
6
|
+
constructor(data, options = {}) {
|
|
7
|
+
let nodes = {};
|
|
8
|
+
for (let key in data) {
|
|
9
|
+
let input = data[key];
|
|
10
|
+
if (typeof input === 'function') {
|
|
11
|
+
let node = nodes[key] = computed(input, options);
|
|
12
|
+
defineProperty(this, key, {
|
|
13
|
+
get() {
|
|
14
|
+
return read(node);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
else if (isArray(input)) {
|
|
19
|
+
let node, test = input[0];
|
|
20
|
+
if (typeof test === 'object' && test !== null && test.constructor.name === 'Object') {
|
|
21
|
+
node = nodes[key] = new ReactiveObjectArray(input, options);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
node = nodes[key] = new ReactiveArray(input);
|
|
25
|
+
}
|
|
26
|
+
defineProperty(this, key, {
|
|
27
|
+
get() {
|
|
28
|
+
node.track();
|
|
29
|
+
return node;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
let node = nodes[key] = signal(input, options);
|
|
35
|
+
defineProperty(this, key, {
|
|
36
|
+
get() {
|
|
37
|
+
return read(node);
|
|
38
|
+
},
|
|
39
|
+
set(value) {
|
|
40
|
+
write(node, value);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
this.nodes = nodes;
|
|
46
|
+
}
|
|
47
|
+
dispose() {
|
|
48
|
+
let nodes = this.nodes;
|
|
49
|
+
for (let key in nodes) {
|
|
50
|
+
nodes[key].dispose();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
reset() {
|
|
54
|
+
let nodes = this.nodes;
|
|
55
|
+
for (let key in nodes) {
|
|
56
|
+
nodes[key].reset();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export { ReactiveObject };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Infer, Key, Node, Options, Values } from './types';
|
|
2
|
+
declare class ReactiveObject<K extends Key, V> {
|
|
3
|
+
nodes: Record<K, Node<K, V>>;
|
|
4
|
+
constructor(data: Values<K, V>, options?: Options);
|
|
5
|
+
dispose(): void;
|
|
6
|
+
reset(): void;
|
|
7
|
+
}
|
|
8
|
+
declare const _default: <K extends Key, V>(data: Values<K, V>, options?: Options) => ReactiveObject<K, V> & Infer<Record<K, V>>;
|
|
9
|
+
export default _default;
|
|
10
|
+
export { ReactiveObject };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { computed, read, signal, write } from '../signal';
|
|
2
|
+
import { isArray } from '../utilities';
|
|
3
|
+
import ReactiveArray from './array';
|
|
4
|
+
class ReactiveObject {
|
|
5
|
+
nodes = {};
|
|
6
|
+
constructor(data, options = {}) {
|
|
7
|
+
let nodes = this.nodes;
|
|
8
|
+
for (let key in data) {
|
|
9
|
+
let node = nodes[key], value = data[key];
|
|
10
|
+
if (typeof value === 'function') {
|
|
11
|
+
Object.defineProperty(this, key, {
|
|
12
|
+
get() {
|
|
13
|
+
if (node === undefined) {
|
|
14
|
+
node = nodes[key] = computed(value, options);
|
|
15
|
+
}
|
|
16
|
+
return read(node);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
else if (isArray(value) && value[0]?.constructor?.name === 'Object') {
|
|
21
|
+
Object.defineProperty(this, key, {
|
|
22
|
+
get() {
|
|
23
|
+
if (node === undefined) {
|
|
24
|
+
node = nodes[key] = new ReactiveArray(value, options);
|
|
25
|
+
}
|
|
26
|
+
node.track();
|
|
27
|
+
return node;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
Object.defineProperty(this, key, {
|
|
33
|
+
get() {
|
|
34
|
+
if (node === undefined) {
|
|
35
|
+
node = nodes[key] = signal(value, options);
|
|
36
|
+
}
|
|
37
|
+
return read(node);
|
|
38
|
+
},
|
|
39
|
+
set(value) {
|
|
40
|
+
if (node === undefined) {
|
|
41
|
+
node = nodes[key] = signal(value, options);
|
|
42
|
+
}
|
|
43
|
+
write(node, value);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
dispose() {
|
|
50
|
+
let nodes = this.nodes;
|
|
51
|
+
for (let key in nodes) {
|
|
52
|
+
nodes[key].dispose();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
reset() {
|
|
56
|
+
let nodes = this.nodes;
|
|
57
|
+
for (let key in nodes) {
|
|
58
|
+
nodes[key].reset();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export default (data, options = {}) => {
|
|
63
|
+
return new ReactiveObject(data, options);
|
|
64
|
+
};
|
|
65
|
+
export { ReactiveObject };
|