@esportsplus/reactivity 0.0.22 → 0.0.24
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/api/effect.d.ts +2 -0
- package/build/api/effect.js +3 -0
- package/build/api/index.d.ts +4 -0
- package/build/api/index.js +4 -0
- package/build/api/macro.d.ts +4 -0
- package/build/api/macro.js +8 -0
- package/build/api/promise.d.ts +3 -0
- package/build/api/promise.js +38 -0
- package/build/api/reactive.d.ts +16 -0
- package/build/api/reactive.js +27 -0
- package/build/context/index.d.ts +5 -0
- package/build/context/index.js +3 -0
- package/build/context/node.d.ts +7 -0
- package/build/context/node.js +21 -0
- package/build/context/nodes.d.ts +7 -0
- package/build/context/nodes.js +33 -0
- package/build/index.d.ts +3 -12
- package/build/index.js +3 -4
- package/build/signal.d.ts +31 -0
- package/build/signal.js +256 -0
- package/build/symbols.d.ts +10 -1
- package/build/symbols.js +10 -1
- package/build/types.d.ts +33 -13
- package/build/types.js +2 -1
- package/package.json +2 -2
- package/readme.md +2 -0
- package/src/api/effect.ts +5 -0
- package/src/api/index.ts +4 -0
- package/src/api/macro.ts +15 -0
- package/src/api/promise.ts +45 -0
- package/src/api/reactive.ts +42 -0
- package/src/context/index.ts +5 -0
- package/src/context/node.ts +36 -0
- package/src/context/nodes.ts +52 -0
- package/src/index.ts +3 -6
- package/src/signal.ts +344 -0
- package/src/symbols.ts +22 -1
- package/src/types.ts +40 -13
- package/tsconfig.json +1 -1
- package/build/index.browser.js +0 -277
- package/build/methods/effect.d.ts +0 -2
- package/build/methods/effect.js +0 -4
- package/build/methods/index.d.ts +0 -3
- package/build/methods/index.js +0 -3
- package/build/methods/reactive.d.ts +0 -3
- package/build/methods/reactive.js +0 -52
- package/build/reactive.d.ts +0 -22
- package/build/reactive.js +0 -190
- package/src/methods/effect.ts +0 -6
- package/src/methods/index.ts +0 -5
- package/src/methods/reactive.ts +0 -71
- package/src/reactive.ts +0 -266
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { computed } from '../signal';
|
|
2
|
+
import { Computed } from '../types';
|
|
3
|
+
declare const _default: <T extends <A, R>(...args: A[]) => R>(fn: T extends Promise<unknown> ? never : (this: import("../types").Context, previous: T) => T, options?: Parameters<typeof computed>[1]) => Required<((...args: Parameters<ReturnType<T extends Promise<unknown> ? never : (this: import("../types").Context, previous: T) => T>>) => unknown) & Partial<import("../types").Context>>;
|
|
4
|
+
export default _default;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { computed } from '../signal';
|
|
2
|
+
declare const _default: (fn: <A, R extends Promise<any>>(...args: A[]) => R, options?: Parameters<typeof computed>[1]) => Required<((this: any, ...args: unknown[]) => void) & Partial<import("../types").Context>>;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { read, root, signal, write } from '../signal';
|
|
2
|
+
import context from '../context';
|
|
3
|
+
export default (fn, options = {}) => {
|
|
4
|
+
let input, nodes = {
|
|
5
|
+
data: signal(options?.value, options),
|
|
6
|
+
status: signal(undefined, options)
|
|
7
|
+
};
|
|
8
|
+
function host(...args) {
|
|
9
|
+
input = args;
|
|
10
|
+
root(() => {
|
|
11
|
+
fn(...args)
|
|
12
|
+
.then((value) => {
|
|
13
|
+
write(nodes.data, value);
|
|
14
|
+
})
|
|
15
|
+
.catch(() => {
|
|
16
|
+
write(nodes.data, undefined);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperties(host, {
|
|
21
|
+
data: {
|
|
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
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { computed, signal } from '../signal';
|
|
2
|
+
import { Context } from '../types';
|
|
3
|
+
type Data = {
|
|
4
|
+
[key in keyof Context]: never;
|
|
5
|
+
} & Record<PropertyKey, Parameters<typeof computed>[0] | Parameters<typeof signal>[0]>;
|
|
6
|
+
type Options = Parameters<typeof computed>[1] | Parameters<typeof signal>[1];
|
|
7
|
+
declare const _default: <T>(data: Data, options?: Options) => Required<{
|
|
8
|
+
[x: string]: unknown;
|
|
9
|
+
[x: number]: unknown;
|
|
10
|
+
[x: symbol]: unknown;
|
|
11
|
+
dispose: never;
|
|
12
|
+
on: never;
|
|
13
|
+
once: never;
|
|
14
|
+
reset: never;
|
|
15
|
+
} & Partial<Context>>;
|
|
16
|
+
export default _default;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { computed, read, signal, write } from '../signal';
|
|
2
|
+
import context from '../context';
|
|
3
|
+
export default (data, options = {}) => {
|
|
4
|
+
let host = {}, nodes = {};
|
|
5
|
+
for (let key in data) {
|
|
6
|
+
if (typeof data[key] === 'function') {
|
|
7
|
+
nodes[key] = computed(data[key], options);
|
|
8
|
+
Object.defineProperty(host, key, {
|
|
9
|
+
get() {
|
|
10
|
+
return read(nodes[key]);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
nodes[key] = signal(data[key], options);
|
|
16
|
+
Object.defineProperty(host, key, {
|
|
17
|
+
get() {
|
|
18
|
+
return read(nodes[key]);
|
|
19
|
+
},
|
|
20
|
+
set(data) {
|
|
21
|
+
write(nodes[key], data);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return context.nodes(host, nodes);
|
|
27
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
node: <T>(host: T & Partial<import("../types").Context>, node: import("../signal").default<any>) => Required<T & Partial<import("../types").Context>>;
|
|
3
|
+
nodes: <T_1>(host: T_1 & Partial<import("../types").Context>, nodes: Record<PropertyKey, import("../signal").default<any>>) => Required<T_1 & Partial<import("../types").Context>>;
|
|
4
|
+
};
|
|
5
|
+
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NODE } from '../symbols';
|
|
2
|
+
import { Context, Signal } from '../types';
|
|
3
|
+
type Internals = {
|
|
4
|
+
[NODE]: Signal<any>;
|
|
5
|
+
};
|
|
6
|
+
declare const _default: <T>(host: T & Partial<Context>, node: Internals[typeof NODE]) => Required<T & Partial<Context>>;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { NODE } from '../symbols';
|
|
2
|
+
function dispose() {
|
|
3
|
+
this[NODE].dispose();
|
|
4
|
+
}
|
|
5
|
+
function on(event, listener) {
|
|
6
|
+
this[NODE].on(event, listener);
|
|
7
|
+
}
|
|
8
|
+
function once(event, listener) {
|
|
9
|
+
this[NODE].once(event, listener);
|
|
10
|
+
}
|
|
11
|
+
function reset() {
|
|
12
|
+
this[NODE].reset();
|
|
13
|
+
}
|
|
14
|
+
export default (host, node) => {
|
|
15
|
+
host[NODE] = node;
|
|
16
|
+
host.dispose = dispose;
|
|
17
|
+
host.on = on;
|
|
18
|
+
host.once = once;
|
|
19
|
+
host.reset = reset;
|
|
20
|
+
return host;
|
|
21
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NODES } from '../symbols';
|
|
2
|
+
import { Context, Signal } from '../types';
|
|
3
|
+
type Internals = {
|
|
4
|
+
[NODES]: Record<PropertyKey, Signal<any>>;
|
|
5
|
+
};
|
|
6
|
+
declare const _default: <T>(host: T & Partial<Context>, nodes: Internals[typeof NODES]) => Required<T & Partial<Context>>;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { NODES } from '../symbols';
|
|
2
|
+
function dispose() {
|
|
3
|
+
let nodes = this[NODES];
|
|
4
|
+
for (let key in nodes) {
|
|
5
|
+
nodes[key].dispose();
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
function on(event, listener) {
|
|
9
|
+
let nodes = this[NODES];
|
|
10
|
+
for (let key in nodes) {
|
|
11
|
+
nodes[key].on(event, listener);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function once(event, listener) {
|
|
15
|
+
let nodes = this[NODES];
|
|
16
|
+
for (let key in nodes) {
|
|
17
|
+
nodes[key].once(event, listener);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function reset() {
|
|
21
|
+
let nodes = this[NODES];
|
|
22
|
+
for (let key in nodes) {
|
|
23
|
+
nodes[key].reset();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export default (host, nodes) => {
|
|
27
|
+
host[NODES] = nodes;
|
|
28
|
+
host.dispose = dispose;
|
|
29
|
+
host.on = on;
|
|
30
|
+
host.once = once;
|
|
31
|
+
host.reset = reset;
|
|
32
|
+
return host;
|
|
33
|
+
};
|
package/build/index.d.ts
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
effect: <T>(fn: () => T) => void;
|
|
5
|
-
reactive: <T_1>(value: T_1) => import("./types").Infer<T_1>;
|
|
6
|
-
scheduler: {
|
|
7
|
-
add: (scheduler: import("./types").Scheduler) => void;
|
|
8
|
-
delete: (scheduler: import("./types").Scheduler) => void;
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
export default _default;
|
|
12
|
-
export { effect, reactive, scheduler };
|
|
1
|
+
export * from './api';
|
|
2
|
+
export * as core from './signal';
|
|
3
|
+
export { DISPOSE, RESET, UPDATE } from './symbols';
|
package/build/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
export { effect, reactive, scheduler };
|
|
1
|
+
export * from './api';
|
|
2
|
+
export * as core from './signal';
|
|
3
|
+
export { DISPOSE, RESET, UPDATE } from './symbols';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Changed, Computed, Context, Effect, Event, Listener, Options, Root, Scheduler, State, Type } from './types';
|
|
2
|
+
declare class Signal<T> {
|
|
3
|
+
changed: Changed | null;
|
|
4
|
+
fn: Computed<T>['fn'] | null;
|
|
5
|
+
listeners: Record<symbol, (Listener | null)[]> | null;
|
|
6
|
+
observers: Signal<T>[] | null;
|
|
7
|
+
root: Root | null;
|
|
8
|
+
sources: Signal<T>[] | null;
|
|
9
|
+
state: State;
|
|
10
|
+
task: Parameters<Scheduler>[0] | null;
|
|
11
|
+
type: Type;
|
|
12
|
+
updating: boolean | null;
|
|
13
|
+
value: Computed<T>['value'] | T;
|
|
14
|
+
constructor(data: T, state: Signal<T>['state'], type: Signal<T>['type'], options?: Options);
|
|
15
|
+
dispose(): void;
|
|
16
|
+
on(event: Event, listener: Listener): void;
|
|
17
|
+
once(event: Event, listener: Listener): void;
|
|
18
|
+
reset(): void;
|
|
19
|
+
}
|
|
20
|
+
declare const computed: <T>(fn: T extends Promise<unknown> ? never : (this: Context, previous: T) => T, options?: Options & {
|
|
21
|
+
value?: unknown;
|
|
22
|
+
}) => Computed<T>;
|
|
23
|
+
declare const effect: <T>(fn: (this: Context, previous: T) => T, options?: Options) => Effect<void>;
|
|
24
|
+
declare const read: <T>(node: Signal<T>) => T | ReturnType<T extends Promise<unknown> ? never : (this: Context, previous: T) => T>;
|
|
25
|
+
declare const root: <T>(fn: () => T, properties?: {
|
|
26
|
+
scheduler?: Scheduler;
|
|
27
|
+
}) => T;
|
|
28
|
+
declare const signal: <T>(data: T, options?: Options) => Signal<T>;
|
|
29
|
+
declare const write: <T>(node: Signal<T>, value: unknown) => T | ReturnType<T extends Promise<unknown> ? never : (this: Context, previous: T) => T>;
|
|
30
|
+
export default Signal;
|
|
31
|
+
export { computed, effect, read, root, signal, write };
|
package/build/signal.js
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { CHECK, CLEAN, COMPUTED, DIRTY, DISPOSED, DISPOSE, EFFECT, RESET, SIGNAL, UPDATE } from './symbols';
|
|
2
|
+
let index = 0, observer = null, observers = null, scope = null;
|
|
3
|
+
class Signal {
|
|
4
|
+
changed = null;
|
|
5
|
+
fn = null;
|
|
6
|
+
listeners = null;
|
|
7
|
+
observers = null;
|
|
8
|
+
root = null;
|
|
9
|
+
sources = null;
|
|
10
|
+
state;
|
|
11
|
+
task = null;
|
|
12
|
+
type;
|
|
13
|
+
updating = null;
|
|
14
|
+
value;
|
|
15
|
+
constructor(data, state, type, options = {}) {
|
|
16
|
+
if (options?.changed) {
|
|
17
|
+
this.changed = options.changed;
|
|
18
|
+
}
|
|
19
|
+
this.state = state;
|
|
20
|
+
this.type = type;
|
|
21
|
+
this.value = data;
|
|
22
|
+
}
|
|
23
|
+
dispose() {
|
|
24
|
+
if (this.state === DISPOSED) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
this.state = DISPOSED;
|
|
28
|
+
dispatch(DISPOSE, this);
|
|
29
|
+
flush(this);
|
|
30
|
+
}
|
|
31
|
+
on(event, listener) {
|
|
32
|
+
if (this.updating) {
|
|
33
|
+
listener.once = true;
|
|
34
|
+
}
|
|
35
|
+
if (!this.listeners?.[event]) {
|
|
36
|
+
this.listeners ??= {};
|
|
37
|
+
this.listeners[event] = [listener];
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
let listeners = this.listeners[event];
|
|
41
|
+
if (listeners.indexOf(listener) === -1) {
|
|
42
|
+
let i = listeners.indexOf(null);
|
|
43
|
+
if (i === -1) {
|
|
44
|
+
listeners.push(listener);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
listeners[i] = listener;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
once(event, listener) {
|
|
53
|
+
listener.once = true;
|
|
54
|
+
this.on(event, listener);
|
|
55
|
+
}
|
|
56
|
+
reset() {
|
|
57
|
+
dispatch(RESET, this);
|
|
58
|
+
flush(this);
|
|
59
|
+
if (this.type === COMPUTED) {
|
|
60
|
+
this.state = DIRTY;
|
|
61
|
+
this.value = undefined;
|
|
62
|
+
}
|
|
63
|
+
else if (this.type === EFFECT) {
|
|
64
|
+
this.state = DIRTY;
|
|
65
|
+
update(this);
|
|
66
|
+
}
|
|
67
|
+
else if (this.type === SIGNAL) {
|
|
68
|
+
this.state = CLEAN;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function changed(a, b) {
|
|
73
|
+
return a !== b;
|
|
74
|
+
}
|
|
75
|
+
function dispatch(event, node) {
|
|
76
|
+
if (!node.listeners?.[event]) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
let listeners = node.listeners[event], value = node.value;
|
|
80
|
+
for (let i = 0, n = listeners.length; i < n; i++) {
|
|
81
|
+
let listener = listeners[i];
|
|
82
|
+
if (!listener) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
listener(value);
|
|
86
|
+
if (listener?.once) {
|
|
87
|
+
listeners[i] = null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function flush(node) {
|
|
92
|
+
if (node.sources) {
|
|
93
|
+
removeSourceObservers(node, 0);
|
|
94
|
+
}
|
|
95
|
+
node.listeners = null;
|
|
96
|
+
node.observers = null;
|
|
97
|
+
node.sources = null;
|
|
98
|
+
}
|
|
99
|
+
function notify(nodes, state) {
|
|
100
|
+
if (!nodes) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
for (let i = 0, n = nodes.length; i < n; i++) {
|
|
104
|
+
let node = nodes[i];
|
|
105
|
+
if (node.state < state) {
|
|
106
|
+
if (node.type === EFFECT && node.state === CLEAN) {
|
|
107
|
+
node.root.scheduler(node.task);
|
|
108
|
+
}
|
|
109
|
+
node.state = state;
|
|
110
|
+
notify(node.observers, CHECK);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function removeSourceObservers(node, start) {
|
|
115
|
+
if (!node.sources) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
for (let i = start, n = node.sources.length; i < n; i++) {
|
|
119
|
+
let source = node.sources[i];
|
|
120
|
+
if (!source?.observers) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
source.observers[source.observers.indexOf(node)] = source.observers[source.observers.length - 1];
|
|
124
|
+
source.observers.pop();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function sync(node) {
|
|
128
|
+
if (node.state === CHECK && node.sources) {
|
|
129
|
+
for (let i = 0, n = node.sources.length; i < n; i++) {
|
|
130
|
+
sync(node.sources[i]);
|
|
131
|
+
if (node.state === DIRTY) {
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (node.state === DIRTY) {
|
|
137
|
+
update(node);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
node.state = CLEAN;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function update(node) {
|
|
144
|
+
let i = index, o = observer, os = observers;
|
|
145
|
+
index = 0;
|
|
146
|
+
observer = node;
|
|
147
|
+
observers = null;
|
|
148
|
+
try {
|
|
149
|
+
dispatch(UPDATE, node);
|
|
150
|
+
node.updating = true;
|
|
151
|
+
let value = node.fn.call(node, node?.value);
|
|
152
|
+
node.updating = null;
|
|
153
|
+
if (observers) {
|
|
154
|
+
removeSourceObservers(node, index);
|
|
155
|
+
if (node.sources && index > 0) {
|
|
156
|
+
node.sources.length = index + observers.length;
|
|
157
|
+
for (let i = 0, n = observers.length; i < n; i++) {
|
|
158
|
+
node.sources[index + i] = observers[i];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
node.sources = observers;
|
|
163
|
+
}
|
|
164
|
+
for (let i = index, n = node.sources.length; i < n; i++) {
|
|
165
|
+
let source = node.sources[i];
|
|
166
|
+
if (!source.observers) {
|
|
167
|
+
source.observers = [node];
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
source.observers.push(node);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else if (node.sources && index < node.sources.length) {
|
|
175
|
+
removeSourceObservers(node, index);
|
|
176
|
+
node.sources.length = index;
|
|
177
|
+
}
|
|
178
|
+
if (node.type === COMPUTED) {
|
|
179
|
+
write(node, value);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
if (node.state === DIRTY) {
|
|
184
|
+
removeSourceObservers(node, 0);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
index = i;
|
|
189
|
+
observer = o;
|
|
190
|
+
observers = os;
|
|
191
|
+
}
|
|
192
|
+
node.state = CLEAN;
|
|
193
|
+
}
|
|
194
|
+
const computed = (fn, options = {}) => {
|
|
195
|
+
let node = new Signal(options?.value, DIRTY, COMPUTED, options);
|
|
196
|
+
node.fn = fn;
|
|
197
|
+
return node;
|
|
198
|
+
};
|
|
199
|
+
const effect = (fn, options = {}) => {
|
|
200
|
+
if (!scope) {
|
|
201
|
+
throw new Error('Reactivity: `effects` cannot be created without a reactive root');
|
|
202
|
+
}
|
|
203
|
+
let node = new Signal(undefined, DIRTY, EFFECT, options);
|
|
204
|
+
node.fn = fn;
|
|
205
|
+
node.root = scope;
|
|
206
|
+
node.task = () => read(node);
|
|
207
|
+
update(node);
|
|
208
|
+
return node;
|
|
209
|
+
};
|
|
210
|
+
const read = (node) => {
|
|
211
|
+
if (node.state === DISPOSED) {
|
|
212
|
+
return node.value;
|
|
213
|
+
}
|
|
214
|
+
if (observer) {
|
|
215
|
+
if (!observers) {
|
|
216
|
+
if (observer?.sources?.[index] == node) {
|
|
217
|
+
index++;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
observers = [node];
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
observers.push(node);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (node.fn) {
|
|
228
|
+
sync(node);
|
|
229
|
+
}
|
|
230
|
+
return node.value;
|
|
231
|
+
};
|
|
232
|
+
const root = (fn, properties = {}) => {
|
|
233
|
+
let o = observer, s = scope;
|
|
234
|
+
properties.scheduler = properties?.scheduler || scope?.scheduler;
|
|
235
|
+
if (!properties.scheduler) {
|
|
236
|
+
throw new Error('Reactivity: `root` cannot be created without a task scheduler');
|
|
237
|
+
}
|
|
238
|
+
observer = null;
|
|
239
|
+
scope = properties;
|
|
240
|
+
let result = fn();
|
|
241
|
+
observer = o;
|
|
242
|
+
scope = s;
|
|
243
|
+
return result;
|
|
244
|
+
};
|
|
245
|
+
const signal = (data, options = {}) => {
|
|
246
|
+
return new Signal(data, CLEAN, SIGNAL, options);
|
|
247
|
+
};
|
|
248
|
+
const write = (node, value) => {
|
|
249
|
+
if ((node?.changed || changed)(node.value, value)) {
|
|
250
|
+
node.value = value;
|
|
251
|
+
notify(node.observers, DIRTY);
|
|
252
|
+
}
|
|
253
|
+
return node.value;
|
|
254
|
+
};
|
|
255
|
+
export default Signal;
|
|
256
|
+
export { computed, effect, read, root, signal, write };
|
package/build/symbols.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
declare const CLEAN = 0;
|
|
2
2
|
declare const CHECK = 1;
|
|
3
3
|
declare const DIRTY = 2;
|
|
4
|
-
|
|
4
|
+
declare const DISPOSED = 3;
|
|
5
|
+
declare const COMPUTED = 0;
|
|
6
|
+
declare const EFFECT = 1;
|
|
7
|
+
declare const SIGNAL = 2;
|
|
8
|
+
declare const DISPOSE: unique symbol;
|
|
9
|
+
declare const RESET: unique symbol;
|
|
10
|
+
declare const UPDATE: unique symbol;
|
|
11
|
+
declare const NODE: unique symbol;
|
|
12
|
+
declare const NODES: unique symbol;
|
|
13
|
+
export { CHECK, CLEAN, COMPUTED, DIRTY, DISPOSED, DISPOSE, EFFECT, NODE, NODES, RESET, SIGNAL, UPDATE };
|
package/build/symbols.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
const CLEAN = 0;
|
|
2
2
|
const CHECK = 1;
|
|
3
3
|
const DIRTY = 2;
|
|
4
|
-
|
|
4
|
+
const DISPOSED = 3;
|
|
5
|
+
const COMPUTED = 0;
|
|
6
|
+
const EFFECT = 1;
|
|
7
|
+
const SIGNAL = 2;
|
|
8
|
+
const DISPOSE = Symbol();
|
|
9
|
+
const RESET = Symbol();
|
|
10
|
+
const UPDATE = Symbol();
|
|
11
|
+
const NODE = Symbol();
|
|
12
|
+
const NODES = Symbol();
|
|
13
|
+
export { CHECK, CLEAN, COMPUTED, DIRTY, DISPOSED, DISPOSE, EFFECT, NODE, NODES, RESET, SIGNAL, UPDATE };
|
package/build/types.d.ts
CHANGED
|
@@ -1,16 +1,36 @@
|
|
|
1
|
-
import { CLEAN,
|
|
2
|
-
|
|
3
|
-
type
|
|
1
|
+
import { CHECK, CLEAN, COMPUTED, DIRTY, DISPOSED, EFFECT, SIGNAL } from './symbols';
|
|
2
|
+
import Signal from './signal';
|
|
3
|
+
type Changed = (a: unknown, b: unknown) => boolean;
|
|
4
|
+
type Computed<T> = {
|
|
5
|
+
fn: T extends Promise<unknown> ? never : ((this: Context, previous: T) => T);
|
|
6
|
+
value: ReturnType<Computed<T>['fn']>;
|
|
7
|
+
} & Omit<Signal<T>, 'fn' | 'value'>;
|
|
8
|
+
type Context = {
|
|
9
|
+
dispose(): void;
|
|
10
|
+
on(event: Event, listener: Listener): void;
|
|
11
|
+
once(event: Event, listener: Listener): void;
|
|
12
|
+
reset(): void;
|
|
13
|
+
};
|
|
14
|
+
type Effect<T> = {
|
|
15
|
+
fn: (this: Context, previous: T) => T;
|
|
16
|
+
root: NonNullable<Signal<T>['root']>;
|
|
17
|
+
task: NonNullable<Signal<T>['task']>;
|
|
18
|
+
} & Omit<Computed<T>, 'fn' | 'root' | 'task'>;
|
|
19
|
+
type Event = symbol;
|
|
20
|
+
type Infer<T> = T extends (...args: any[]) => any ? ReturnType<T> : T extends Record<PropertyKey, unknown> ? {
|
|
4
21
|
[K in keyof T]: Infer<T[K]>;
|
|
5
22
|
} : T;
|
|
6
|
-
type
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
23
|
+
type Listener = {
|
|
24
|
+
once?: boolean;
|
|
25
|
+
<T>(value: T): void;
|
|
26
|
+
};
|
|
27
|
+
type Options = {
|
|
28
|
+
changed?: Changed;
|
|
29
|
+
};
|
|
30
|
+
type Root = {
|
|
31
|
+
scheduler: Scheduler;
|
|
14
32
|
};
|
|
15
|
-
type
|
|
16
|
-
|
|
33
|
+
type Scheduler = (fn: (...args: unknown[]) => Promise<unknown> | unknown) => unknown;
|
|
34
|
+
type State = typeof CHECK | typeof CLEAN | typeof DIRTY | typeof DISPOSED;
|
|
35
|
+
type Type = typeof COMPUTED | typeof EFFECT | typeof SIGNAL;
|
|
36
|
+
export { Changed, Computed, Context, Effect, Event, Infer, Listener, Options, Root, Scheduler, Signal, State, Type };
|
package/build/types.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import Signal from './signal';
|
|
2
|
+
export { Signal };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"author": "ICJR",
|
|
3
3
|
"description": "Reactivity",
|
|
4
4
|
"devDependencies": {
|
|
5
|
-
"@esportsplus/
|
|
5
|
+
"@esportsplus/rspack": "^0.0.1"
|
|
6
6
|
},
|
|
7
7
|
"main": "build/index.js",
|
|
8
8
|
"name": "@esportsplus/reactivity",
|
|
@@ -14,5 +14,5 @@
|
|
|
14
14
|
"prepublishOnly": "npm run build"
|
|
15
15
|
},
|
|
16
16
|
"types": "build/index.d.ts",
|
|
17
|
-
"version": "0.0.
|
|
17
|
+
"version": "0.0.24"
|
|
18
18
|
}
|
package/readme.md
ADDED
package/src/api/index.ts
ADDED
package/src/api/macro.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { computed, read } from '~/signal';
|
|
2
|
+
import { Computed } from '~/types';
|
|
3
|
+
import context from '~/context';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export default <T extends <A, R>(...args: A[]) => R>(fn: Computed<T>['fn'], options: Parameters<typeof computed>[1] = {}) => {
|
|
7
|
+
let node = computed(fn, options);
|
|
8
|
+
|
|
9
|
+
return context.node(
|
|
10
|
+
(...args: Parameters<ReturnType<typeof fn>>) => {
|
|
11
|
+
return (read(node) as ReturnType<typeof fn>)(...args);
|
|
12
|
+
},
|
|
13
|
+
node
|
|
14
|
+
);
|
|
15
|
+
};
|