@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.
Files changed (62) hide show
  1. package/build/bench.d.ts +1 -0
  2. package/build/bench.js +46 -0
  3. package/build/constants.d.ts +8 -0
  4. package/build/constants.js +8 -0
  5. package/build/context/node.d.ts +1 -1
  6. package/build/context/node.js +1 -1
  7. package/build/context/nodes.d.ts +1 -1
  8. package/build/context/nodes.js +1 -1
  9. package/build/effect.d.ts +2 -6
  10. package/build/effect.js +1 -2
  11. package/build/index.d.ts +2 -4
  12. package/build/index.js +2 -4
  13. package/build/macro.d.ts +10 -7
  14. package/build/macro.js +17 -5
  15. package/build/promise.d.ts +25 -5
  16. package/build/promise.js +37 -30
  17. package/build/reactive/array.d.ts +60 -0
  18. package/build/reactive/array.js +136 -0
  19. package/build/reactive/index.d.ts +11 -0
  20. package/build/reactive/index.js +4 -0
  21. package/build/reactive/object.d.ts +14 -0
  22. package/build/reactive/object.js +60 -0
  23. package/build/reactive/object2.d.ts +10 -0
  24. package/build/reactive/object2.js +65 -0
  25. package/build/reactive/types.d.ts +33 -0
  26. package/build/reactive/types.js +1 -0
  27. package/build/reactive-array.d.ts +1 -0
  28. package/build/reactive-array.js +106 -0
  29. package/build/reactive.js +2 -2
  30. package/build/resource.d.ts +16 -0
  31. package/build/resource.js +55 -0
  32. package/build/signal.d.ts +17 -12
  33. package/build/signal.js +71 -37
  34. package/build/testing/node.d.ts +13 -0
  35. package/build/testing/node.js +21 -0
  36. package/build/testing/nodes.d.ts +13 -0
  37. package/build/testing/nodes.js +33 -0
  38. package/build/testing/reactive.d.ts +0 -0
  39. package/build/testing/reactive.js +1 -0
  40. package/build/trigger.d.ts +15 -0
  41. package/build/trigger.js +30 -0
  42. package/build/types.d.ts +15 -17
  43. package/build/utilities.d.ts +3 -0
  44. package/build/utilities.js +3 -0
  45. package/package.json +5 -2
  46. package/src/constants.ts +17 -0
  47. package/src/index.ts +3 -5
  48. package/src/macro.ts +29 -9
  49. package/src/reactive/array.ts +219 -0
  50. package/src/reactive/index.ts +26 -0
  51. package/src/reactive/object.ts +93 -0
  52. package/src/resource.ts +79 -0
  53. package/src/signal.ts +91 -52
  54. package/src/types.ts +13 -19
  55. package/src/utilities.ts +6 -0
  56. package/src/context/index.ts +0 -5
  57. package/src/context/node.ts +0 -36
  58. package/src/context/nodes.ts +0 -52
  59. package/src/effect.ts +0 -5
  60. package/src/promise.ts +0 -48
  61. package/src/reactive.ts +0 -47
  62. package/src/symbols.ts +0 -29
@@ -0,0 +1,33 @@
1
+ import { computed, signal } from '../signal';
2
+ import { Computed, Signal } from '../types';
3
+ import { ReactiveObject } from './object';
4
+ import ReactiveArray from './array';
5
+ type Events<T> = {
6
+ pop: {
7
+ item: T;
8
+ };
9
+ push: {
10
+ items: T[];
11
+ };
12
+ shift: {
13
+ item: T;
14
+ };
15
+ splice: {
16
+ deleteCount: number;
17
+ items: T[];
18
+ start: number;
19
+ };
20
+ unshift: {
21
+ items: T[];
22
+ };
23
+ };
24
+ type Infer<T> = T extends (...args: unknown[]) => unknown ? ReturnType<T> : T extends unknown[] ? Infer<T> : T extends Record<Key, unknown> ? {
25
+ [K in keyof T]: T[K];
26
+ } : T;
27
+ type Key = string | symbol;
28
+ type Node<K extends Key, V> = Computed<V> | ReactiveArray<K, V> | Signal<V>;
29
+ type Options = Parameters<typeof computed>[1] | Parameters<typeof signal>[1];
30
+ type Values<K extends Key, V> = Record<K, V> & {
31
+ [K in keyof ReactiveObject<Key, unknown>]?: never;
32
+ };
33
+ export { Events, Infer, Key, Node, Options, Values };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,106 @@
1
+ import { read, signal } from './signal';
2
+ import { Trigger } from './trigger';
3
+ let { isArray } = Array;
4
+ function dispose(dispose) {
5
+ if (dispose === undefined) {
6
+ }
7
+ else if (isArray(dispose)) {
8
+ for (let i = 0, n = dispose.length; i < n; i++) {
9
+ dispose[i].dispose();
10
+ }
11
+ }
12
+ else {
13
+ dispose.dispose();
14
+ }
15
+ return dispose;
16
+ }
17
+ class Reactive extends Trigger {
18
+ nodes;
19
+ constructor(nodes) {
20
+ super();
21
+ this.nodes = nodes;
22
+ }
23
+ [Symbol.iterator]() {
24
+ let i = 0;
25
+ return {
26
+ next: () => {
27
+ if (i < this.nodes.length) {
28
+ return {
29
+ done: false,
30
+ value: read(this.nodes[i++])
31
+ };
32
+ }
33
+ return { done: true };
34
+ }
35
+ };
36
+ }
37
+ get length() {
38
+ return this.nodes.length;
39
+ }
40
+ set length(n) {
41
+ this.splice(n);
42
+ }
43
+ get(index) {
44
+ if (index in this.nodes) {
45
+ return read(this.nodes[index]);
46
+ }
47
+ return undefined;
48
+ }
49
+ pop() {
50
+ let signal = dispose(this.nodes.pop());
51
+ if (signal !== undefined) {
52
+ this.dispatch('action', {
53
+ signal,
54
+ type: 'pop'
55
+ });
56
+ }
57
+ return signal;
58
+ }
59
+ push(...values) {
60
+ let signals = [];
61
+ for (let i = 0, n = values.length; i < n; i++) {
62
+ signals.push(signal(values[i]));
63
+ }
64
+ this.nodes.push(...signals);
65
+ this.dispatch('action', {
66
+ signals,
67
+ type: 'push'
68
+ });
69
+ return this.nodes.length;
70
+ }
71
+ shift() {
72
+ let signal = dispose(this.nodes.shift());
73
+ if (signal !== undefined) {
74
+ this.dispatch('action', {
75
+ signal,
76
+ type: 'shift'
77
+ });
78
+ }
79
+ return signal;
80
+ }
81
+ splice(start, deleteCount = this.nodes.length, ...values) {
82
+ let signals = [];
83
+ for (let i = 0, n = values.length; i < n; i++) {
84
+ signals.push(signal(values[i]));
85
+ }
86
+ let disposed = dispose(this.nodes.splice(start, deleteCount, ...signals));
87
+ this.dispatch('action', {
88
+ deleteCount,
89
+ signals,
90
+ start,
91
+ type: 'splice'
92
+ });
93
+ return disposed;
94
+ }
95
+ unshift(...values) {
96
+ let signals = [];
97
+ for (let i = 0, n = values.length; i < n; i++) {
98
+ signals.push(signal(values[i]));
99
+ }
100
+ this.dispatch('action', {
101
+ signals,
102
+ type: 'unshift'
103
+ });
104
+ return this.nodes.unshift(...signals);
105
+ }
106
+ }
package/build/reactive.js CHANGED
@@ -17,8 +17,8 @@ export default (data, options = {}) => {
17
17
  get() {
18
18
  return read(nodes[key]);
19
19
  },
20
- set(data) {
21
- write(nodes[key], data);
20
+ set(value) {
21
+ write(nodes[key], value);
22
22
  }
23
23
  });
24
24
  }
@@ -0,0 +1,16 @@
1
+ import CustomFunction from '@esportsplus/custom-function';
2
+ import { computed } from './signal';
3
+ type Fn<A extends unknown[], R extends Promise<unknown>> = (...args: A) => R;
4
+ type Options = Parameters<typeof computed>[1];
5
+ declare class Resource<A extends unknown[], R extends Promise<unknown>> extends CustomFunction {
6
+ #private;
7
+ stop: boolean | null;
8
+ constructor(fn: Fn<A, R>, options?: Options);
9
+ get data(): Awaited<R> | ReturnType<Awaited<R> extends infer T ? T extends Awaited<R> ? T extends Promise<unknown> ? never : (previous: T) => T : never : never>;
10
+ get ok(): boolean | null;
11
+ get input(): A | ReturnType<A extends Promise<unknown> ? never : (previous: A) => A> | null;
12
+ dispose(): void;
13
+ reset(): void;
14
+ }
15
+ declare const _default: <A extends unknown[], R extends Promise<unknown>>(fn: Fn<A, R>, options?: Options) => Resource<A, R>;
16
+ export default _default;
@@ -0,0 +1,55 @@
1
+ import CustomFunction from '@esportsplus/custom-function';
2
+ import { read, signal, write } from './signal';
3
+ class Resource extends CustomFunction {
4
+ #data;
5
+ #input;
6
+ #ok;
7
+ stop = null;
8
+ constructor(fn, options = {}) {
9
+ super((...args) => {
10
+ this.stop = null;
11
+ write(this.#input, args);
12
+ write(this.#ok, null);
13
+ fn(...args)
14
+ .then((value) => {
15
+ if (this.stop === true) {
16
+ return;
17
+ }
18
+ write(this.#data, value);
19
+ write(this.#ok, true);
20
+ })
21
+ .catch(() => {
22
+ if (this.stop === true) {
23
+ return;
24
+ }
25
+ write(this.#data, undefined);
26
+ write(this.#ok, false);
27
+ });
28
+ });
29
+ this.#data = signal(options.value, options),
30
+ this.#input = signal(null, options),
31
+ this.#ok = signal(null, options);
32
+ }
33
+ get data() {
34
+ return read(this.#data);
35
+ }
36
+ get ok() {
37
+ return read(this.#ok);
38
+ }
39
+ get input() {
40
+ return read(this.#input);
41
+ }
42
+ dispose() {
43
+ this.#data.dispose();
44
+ this.#input.dispose();
45
+ this.#ok.dispose();
46
+ }
47
+ reset() {
48
+ this.#data.reset();
49
+ this.#input.reset();
50
+ this.#ok.reset();
51
+ }
52
+ }
53
+ export default (fn, options = {}) => {
54
+ return new Resource(fn, options);
55
+ };
package/build/signal.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { Changed, Computed, Context, Effect, Event, Listener, Options, Root, Scheduler, State, Type } from './types';
1
+ import { Changed, Computed, Effect, Event, Listener, Options, Root, Scheduler, State, Type } from './types';
2
2
  declare class Signal<T> {
3
3
  changed: Changed | null;
4
4
  fn: Computed<T>['fn'] | null;
5
- listeners: Record<symbol, (Listener | null)[]> | null;
5
+ listeners: Record<Event, (Listener<any> | null)[]> | null;
6
6
  observers: Signal<T>[] | null;
7
7
  root: Root | null;
8
8
  sources: Signal<T>[] | null;
@@ -12,20 +12,25 @@ declare class Signal<T> {
12
12
  updating: boolean | null;
13
13
  value: Computed<T>['value'] | T;
14
14
  constructor(data: T, state: Signal<T>['state'], type: Signal<T>['type'], options?: Options);
15
+ dispatch<D>(event: Event, data?: D): void;
15
16
  dispose(): void;
16
- on(event: Event, listener: Listener): void;
17
- once(event: Event, listener: Listener): void;
17
+ on(event: Event, listener: Listener<any>): void;
18
+ once(event: Event, listener: Listener<any>): void;
18
19
  reset(): void;
19
20
  }
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>;
21
+ declare const computed: <T>(fn: T extends Promise<unknown> ? never : (previous: T) => T, options?: Options) => Computed<T>;
22
+ declare const dispose: <T extends {
23
+ dispose: () => void;
24
+ }>(dispose?: T | T[] | undefined) => T | T[] | undefined;
25
+ declare const effect: <T>(fn: (node: Effect<T>) => void, options?: Omit<Options, 'value'>) => Effect<void>;
26
+ declare const read: <T>(node: Signal<T>) => T | ReturnType<T extends Promise<unknown> ? never : (previous: T) => T>;
27
+ declare const reset: <T extends {
28
+ reset: () => void;
29
+ }>(reset?: T | T[] | undefined) => T | T[] | undefined;
25
30
  declare const root: <T>(fn: () => T, properties?: {
26
31
  scheduler?: Scheduler;
27
32
  }) => 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>;
33
+ declare const signal: <T>(data: T, options?: Omit<Options, 'value'>) => Signal<T>;
34
+ declare const write: <T>(node: Signal<T>, value: unknown) => T | ReturnType<T extends Promise<unknown> ? never : (previous: T) => T>;
30
35
  export default Signal;
31
- export { computed, effect, read, root, signal, write };
36
+ export { computed, dispose, effect, read, reset, root, signal, write };
package/build/signal.js CHANGED
@@ -1,4 +1,5 @@
1
- import { CHECK, CLEAN, COMPUTED, DIRTY, DISPOSED, DISPOSE, EFFECT, RESET, SIGNAL, UPDATE } from './symbols';
1
+ import { CHECK, CLEAN, COMPUTED, DIRTY, DISPOSED, EFFECT, SIGNAL } from './constants';
2
+ import { isArray } from './utilities';
2
3
  let index = 0, observer = null, observers = null, scope = null;
3
4
  class Signal {
4
5
  changed = null;
@@ -13,26 +14,47 @@ class Signal {
13
14
  updating = null;
14
15
  value;
15
16
  constructor(data, state, type, options = {}) {
16
- if (options?.changed) {
17
+ if (options.changed !== undefined) {
17
18
  this.changed = options.changed;
18
19
  }
19
20
  this.state = state;
20
21
  this.type = type;
21
22
  this.value = data;
22
23
  }
24
+ dispatch(event, data) {
25
+ if (this.listeners === null || !(event in this.listeners)) {
26
+ return;
27
+ }
28
+ let listeners = this.listeners[event], value = this.value;
29
+ for (let i = 0, n = listeners.length; i < n; i++) {
30
+ let listener = listeners[i];
31
+ if (listener === null) {
32
+ continue;
33
+ }
34
+ try {
35
+ listener(listener.length === 0 ? null : { data, value });
36
+ }
37
+ catch {
38
+ listeners[i] = null;
39
+ }
40
+ if (listener.once !== undefined) {
41
+ listeners[i] = null;
42
+ }
43
+ }
44
+ }
23
45
  dispose() {
24
46
  if (this.state === DISPOSED) {
25
47
  return;
26
48
  }
27
49
  this.state = DISPOSED;
28
- dispatch(DISPOSE, this);
50
+ this.dispatch('dispose', this);
29
51
  flush(this);
30
52
  }
31
53
  on(event, listener) {
32
54
  if (this.updating) {
33
55
  listener.once = true;
34
56
  }
35
- if (!this.listeners?.[event]) {
57
+ if (this.listeners === null || !(event in this.listeners)) {
36
58
  this.listeners ??= {};
37
59
  this.listeners[event] = [listener];
38
60
  }
@@ -54,7 +76,7 @@ class Signal {
54
76
  this.on(event, listener);
55
77
  }
56
78
  reset() {
57
- dispatch(RESET, this);
79
+ this.dispatch('reset', this);
58
80
  flush(this);
59
81
  if (this.type === COMPUTED) {
60
82
  this.state = DIRTY;
@@ -72,24 +94,8 @@ class Signal {
72
94
  function changed(a, b) {
73
95
  return a !== b;
74
96
  }
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
97
  function flush(node) {
92
- if (node.sources) {
98
+ if (node.sources !== null) {
93
99
  removeSourceObservers(node, 0);
94
100
  }
95
101
  node.listeners = null;
@@ -97,7 +103,7 @@ function flush(node) {
97
103
  node.sources = null;
98
104
  }
99
105
  function notify(nodes, state) {
100
- if (!nodes) {
106
+ if (nodes === null) {
101
107
  return;
102
108
  }
103
109
  for (let i = 0, n = nodes.length; i < n; i++) {
@@ -112,12 +118,12 @@ function notify(nodes, state) {
112
118
  }
113
119
  }
114
120
  function removeSourceObservers(node, start) {
115
- if (!node.sources) {
121
+ if (node.sources === null) {
116
122
  return;
117
123
  }
118
124
  for (let i = start, n = node.sources.length; i < n; i++) {
119
125
  let source = node.sources[i];
120
- if (!source?.observers) {
126
+ if (source.observers === null) {
121
127
  continue;
122
128
  }
123
129
  source.observers[source.observers.indexOf(node)] = source.observers[source.observers.length - 1];
@@ -125,7 +131,7 @@ function removeSourceObservers(node, start) {
125
131
  }
126
132
  }
127
133
  function sync(node) {
128
- if (node.state === CHECK && node.sources) {
134
+ if (node.state === CHECK && node.sources !== null) {
129
135
  for (let i = 0, n = node.sources.length; i < n; i++) {
130
136
  sync(node.sources[i]);
131
137
  if (node.state === DIRTY) {
@@ -146,13 +152,13 @@ function update(node) {
146
152
  observer = node;
147
153
  observers = null;
148
154
  try {
149
- dispatch(UPDATE, node);
155
+ node.dispatch('update');
150
156
  node.updating = true;
151
- let value = node.fn.call(node, node?.value);
157
+ let value = node.fn.call(node, node.value);
152
158
  node.updating = null;
153
159
  if (observers) {
154
160
  removeSourceObservers(node, index);
155
- if (node.sources && index > 0) {
161
+ if (node.sources !== null && index > 0) {
156
162
  node.sources.length = index + observers.length;
157
163
  for (let i = 0, n = observers.length; i < n; i++) {
158
164
  node.sources[index + i] = observers[i];
@@ -171,7 +177,7 @@ function update(node) {
171
177
  }
172
178
  }
173
179
  }
174
- else if (node.sources && index < node.sources.length) {
180
+ else if (node.sources !== null && index < node.sources.length) {
175
181
  removeSourceObservers(node, index);
176
182
  node.sources.length = index;
177
183
  }
@@ -192,10 +198,23 @@ function update(node) {
192
198
  node.state = CLEAN;
193
199
  }
194
200
  const computed = (fn, options = {}) => {
195
- let node = new Signal(options?.value, DIRTY, COMPUTED, options);
201
+ let node = new Signal(options.value, DIRTY, COMPUTED, options);
196
202
  node.fn = fn;
197
203
  return node;
198
204
  };
205
+ const dispose = (dispose) => {
206
+ if (dispose === undefined) {
207
+ }
208
+ else if (isArray(dispose)) {
209
+ for (let i = 0, n = dispose.length; i < n; i++) {
210
+ dispose[i].dispose();
211
+ }
212
+ }
213
+ else {
214
+ dispose.dispose();
215
+ }
216
+ return dispose;
217
+ };
199
218
  const effect = (fn, options = {}) => {
200
219
  if (!scope) {
201
220
  throw new Error('Reactivity: `effects` cannot be created without a reactive root');
@@ -213,7 +232,7 @@ const read = (node) => {
213
232
  }
214
233
  if (observer) {
215
234
  if (!observers) {
216
- if (observer?.sources?.[index] == node) {
235
+ if (observer.sources !== null && observer.sources[index] == node) {
217
236
  index++;
218
237
  }
219
238
  else {
@@ -229,11 +248,26 @@ const read = (node) => {
229
248
  }
230
249
  return node.value;
231
250
  };
251
+ const reset = (reset) => {
252
+ if (reset === undefined) {
253
+ }
254
+ else if (isArray(reset)) {
255
+ for (let i = 0, n = reset.length; i < n; i++) {
256
+ reset[i].reset();
257
+ }
258
+ }
259
+ else {
260
+ reset.reset();
261
+ }
262
+ return reset;
263
+ };
232
264
  const root = (fn, properties = {}) => {
233
265
  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');
266
+ if (properties.scheduler === undefined) {
267
+ properties.scheduler = scope?.scheduler;
268
+ if (properties.scheduler === undefined) {
269
+ throw new Error('Reactivity: `root` cannot be created without a task scheduler');
270
+ }
237
271
  }
238
272
  observer = null;
239
273
  scope = properties;
@@ -246,11 +280,11 @@ const signal = (data, options = {}) => {
246
280
  return new Signal(data, CLEAN, SIGNAL, options);
247
281
  };
248
282
  const write = (node, value) => {
249
- if ((node?.changed || changed)(node.value, value)) {
283
+ if ((node.changed === null ? changed : node.changed)(node.value, value)) {
250
284
  node.value = value;
251
285
  notify(node.observers, DIRTY);
252
286
  }
253
287
  return node.value;
254
288
  };
255
289
  export default Signal;
256
- export { computed, effect, read, root, signal, write };
290
+ export { computed, dispose, effect, read, reset, root, signal, write };
@@ -0,0 +1,13 @@
1
+ import { Event, Listener, Signal } from '../types';
2
+ import CustomFunction from '@esportsplus/custom-function';
3
+ type Node = Signal<any>;
4
+ declare class Context<T extends Function> extends CustomFunction {
5
+ signal: Signal<any>;
6
+ constructor(host: T, node: Node);
7
+ dispose(): void;
8
+ on(event: Event, listener: Listener): void;
9
+ once(event: Event, listener: Listener): void;
10
+ reset(): void;
11
+ }
12
+ declare const _default: <T extends Function>(fn: T, node: Node) => Context<T>;
13
+ export default _default;
@@ -0,0 +1,21 @@
1
+ import CustomFunction from '@esportsplus/custom-function';
2
+ class Context extends CustomFunction {
3
+ signal;
4
+ constructor(host, node) {
5
+ super(host);
6
+ this.signal = node;
7
+ }
8
+ dispose() {
9
+ this.signal.dispose();
10
+ }
11
+ on(event, listener) {
12
+ this.signal.on(event, listener);
13
+ }
14
+ once(event, listener) {
15
+ this.signal.once(event, listener);
16
+ }
17
+ reset() {
18
+ this.signal.reset();
19
+ }
20
+ }
21
+ export default (fn, node) => new Context(fn, node);
@@ -0,0 +1,13 @@
1
+ import { Event, Listener, Signal } from '../types';
2
+ import CustomFunction from '@esportsplus/custom-function';
3
+ type Nodes = Record<PropertyKey, Signal<any>>;
4
+ declare class Context<T extends Function> extends CustomFunction {
5
+ #private;
6
+ constructor(host: T, nodes: Nodes);
7
+ dispose(): void;
8
+ on(event: Event, listener: Listener): void;
9
+ once(event: Event, listener: Listener): void;
10
+ reset(): void;
11
+ }
12
+ declare const _default: <T extends Function>(fn: T, nodes?: Nodes) => Context<T>;
13
+ export default _default;
@@ -0,0 +1,33 @@
1
+ import CustomFunction from '@esportsplus/custom-function';
2
+ class Context extends CustomFunction {
3
+ #nodes;
4
+ constructor(host, nodes) {
5
+ super(host);
6
+ this.#nodes = nodes;
7
+ }
8
+ dispose() {
9
+ let nodes = this.#nodes;
10
+ for (let key in nodes) {
11
+ nodes[key].dispose();
12
+ }
13
+ }
14
+ on(event, listener) {
15
+ let nodes = this.#nodes;
16
+ for (let key in nodes) {
17
+ nodes[key].on(event, listener);
18
+ }
19
+ }
20
+ once(event, listener) {
21
+ let nodes = this.#nodes;
22
+ for (let key in nodes) {
23
+ nodes[key].once(event, listener);
24
+ }
25
+ }
26
+ reset() {
27
+ let nodes = this.#nodes;
28
+ for (let key in nodes) {
29
+ nodes[key].reset();
30
+ }
31
+ }
32
+ }
33
+ export default (fn, nodes = {}) => new Context(fn, nodes);
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,15 @@
1
+ import { Event, Listener, Signal } from './types';
2
+ declare class Trigger {
3
+ signal: Signal<boolean>;
4
+ constructor();
5
+ dispatch<T>(event: Event, data?: T): void;
6
+ dispose(): void;
7
+ on(event: Event, listener: Listener): void;
8
+ once(event: Event, listener: Listener): void;
9
+ reset(): void;
10
+ track(): void;
11
+ trigger(): void;
12
+ }
13
+ declare const _default: () => Trigger;
14
+ export default _default;
15
+ export { Trigger };
@@ -0,0 +1,30 @@
1
+ import { read, signal, write } from './signal';
2
+ class Trigger {
3
+ signal;
4
+ constructor() {
5
+ this.signal = signal(false);
6
+ }
7
+ dispatch(event, data) {
8
+ this.signal.dispatch(event, data);
9
+ }
10
+ dispose() {
11
+ this.signal.dispose();
12
+ }
13
+ on(event, listener) {
14
+ this.signal.on(event, listener);
15
+ }
16
+ once(event, listener) {
17
+ this.signal.once(event, listener);
18
+ }
19
+ reset() {
20
+ this.signal.reset();
21
+ }
22
+ track() {
23
+ read(this.signal);
24
+ }
25
+ trigger() {
26
+ write(this.signal, !this.signal.value);
27
+ }
28
+ }
29
+ export default () => new Trigger();
30
+ export { Trigger };