@esportsplus/reactivity 0.1.2 → 0.1.5

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/index.d.ts CHANGED
@@ -3,3 +3,4 @@ export { default as resource } from './resource';
3
3
  export * as core from './signal';
4
4
  export { effect, root } from './signal';
5
5
  export { default as reactive } from './reactive';
6
+ export * from './types';
package/build/index.js CHANGED
@@ -3,3 +3,4 @@ export { default as resource } from './resource';
3
3
  export * as core from './signal';
4
4
  export { effect, root } from './signal';
5
5
  export { default as reactive } from './reactive';
6
+ export * from './types';
package/build/macro.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import CustomFunction from '@esportsplus/custom-function';
2
2
  import { computed } from './signal';
3
- type Fn<A extends unknown[], R> = Parameters<typeof computed<(...args: A) => R>>[0];
3
+ import { Computed } from './types';
4
+ type Fn<A extends unknown[], R> = Computed<(...args: A) => R>['fn'];
4
5
  type Options = Parameters<typeof computed>[1];
5
6
  declare class Macro<A extends unknown[], R> extends CustomFunction {
6
7
  #private;
@@ -1,7 +1,8 @@
1
1
  import { Computed, Object, Options, Signal } from '../types';
2
2
  import { ReactiveArray, ReactiveObjectArray } from './array';
3
+ type Node = Computed<unknown> | ReactiveArray<unknown> | ReactiveObjectArray<Object> | Signal<unknown>;
3
4
  declare class ReactiveObject<T extends Object> {
4
- nodes: Record<PropertyKey, Computed<unknown> | ReactiveObjectArray<Object> | ReactiveArray<unknown> | Signal<unknown>>;
5
+ nodes: Record<PropertyKey, Node>;
5
6
  constructor(data: T, options?: Options);
6
7
  dispose(): void;
7
8
  reset(): void;
@@ -10,6 +10,7 @@ class ReactiveObject {
10
10
  if (typeof input === 'function') {
11
11
  let node = nodes[key] = computed(input, options);
12
12
  defineProperty(this, key, {
13
+ enumerable: true,
13
14
  get() {
14
15
  return read(node);
15
16
  }
@@ -17,13 +18,14 @@ class ReactiveObject {
17
18
  }
18
19
  else if (isArray(input)) {
19
20
  let node, test = input[0];
20
- if (typeof test === 'object' && test !== null && test.constructor.name === 'Object') {
21
+ if (typeof test === 'object' && test !== null && test?.constructor?.name === 'Object') {
21
22
  node = nodes[key] = new ReactiveObjectArray(input, options);
22
23
  }
23
24
  else {
24
25
  node = nodes[key] = new ReactiveArray(input);
25
26
  }
26
27
  defineProperty(this, key, {
28
+ enumerable: true,
27
29
  get() {
28
30
  node.track();
29
31
  return node;
@@ -33,6 +35,7 @@ class ReactiveObject {
33
35
  else {
34
36
  let node = nodes[key] = signal(input, options);
35
37
  defineProperty(this, key, {
38
+ enumerable: true,
36
39
  get() {
37
40
  return read(node);
38
41
  },
@@ -6,9 +6,9 @@ declare class Resource<A extends unknown[], R extends Promise<unknown>> extends
6
6
  #private;
7
7
  stop: boolean | null;
8
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>;
9
+ get data(): Awaited<R> | ReturnType<import("./types").PreventPromise<Awaited<R>, (previous: Awaited<R>) => Awaited<R>>>;
10
10
  get ok(): boolean | null;
11
- get input(): A | ReturnType<A extends Promise<unknown> ? never : (previous: A) => A> | null;
11
+ get input(): A | ReturnType<import("./types").PreventPromise<A, (previous: A | null) => A | null>> | null;
12
12
  dispose(): void;
13
13
  reset(): void;
14
14
  }
package/build/signal.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Changed, Computed, Effect, Event, Listener, Options, Root, Scheduler, State, Type } from './types';
1
+ import { Changed, Computed, Effect, Event, Listener, PreventPromise, 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;
@@ -18,19 +18,19 @@ declare class Signal<T> {
18
18
  once(event: Event, listener: Listener<any>): void;
19
19
  reset(): void;
20
20
  }
21
- declare const computed: <T>(fn: T extends Promise<unknown> ? never : (previous: T) => T, options?: Options) => Computed<T>;
21
+ declare const computed: <T>(fn: PreventPromise<T, (previous: T) => T>, options?: Options) => Computed<T>;
22
22
  declare const dispose: <T extends {
23
23
  dispose: () => void;
24
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>;
25
+ declare const effect: <T>(fn: PreventPromise<T, (node: Effect<T>) => void>, options?: Omit<Options, 'value'>) => Effect<void>;
26
+ declare const read: <T>(node: Signal<T>) => T | ReturnType<PreventPromise<T, (previous: T) => T>>;
27
27
  declare const reset: <T extends {
28
28
  reset: () => void;
29
29
  }>(reset?: T | T[] | undefined) => T | T[] | undefined;
30
- declare const root: <T>(fn: () => T, properties?: {
30
+ declare const root: <T>(fn: PreventPromise<T, () => T>, properties?: {
31
31
  scheduler?: Scheduler;
32
32
  }) => T;
33
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>;
34
+ declare const write: <T>(node: Signal<T>, value: unknown) => T | ReturnType<PreventPromise<T, (previous: T) => T>>;
35
35
  export default Signal;
36
36
  export { computed, dispose, effect, read, reset, root, signal, write };
package/build/signal.js CHANGED
@@ -216,22 +216,27 @@ const dispose = (dispose) => {
216
216
  return dispose;
217
217
  };
218
218
  const effect = (fn, options = {}) => {
219
- if (!scope) {
219
+ let node = new Signal(undefined, DIRTY, EFFECT, options);
220
+ if (scope !== null) {
221
+ node.root = scope;
222
+ }
223
+ else if (observer !== null && observer.type === EFFECT) {
224
+ node.root = observer.root;
225
+ }
226
+ else {
220
227
  throw new Error('Reactivity: `effects` cannot be created without a reactive root');
221
228
  }
222
- let node = new Signal(undefined, DIRTY, EFFECT, options);
223
229
  node.fn = fn;
224
- node.root = scope;
225
230
  node.task = () => read(node);
226
- node.root.scheduler(node.task);
231
+ read(node);
227
232
  return node;
228
233
  };
229
234
  const read = (node) => {
230
235
  if (node.state === DISPOSED) {
231
236
  return node.value;
232
237
  }
233
- if (observer) {
234
- if (!observers) {
238
+ if (observer !== null) {
239
+ if (observers === null) {
235
240
  if (observer.sources !== null && observer.sources[index] == node) {
236
241
  index++;
237
242
  }
@@ -243,7 +248,7 @@ const read = (node) => {
243
248
  observers.push(node);
244
249
  }
245
250
  }
246
- if (node.fn) {
251
+ if (node.fn !== null) {
247
252
  sync(node);
248
253
  }
249
254
  return node.value;
@@ -264,10 +269,10 @@ const reset = (reset) => {
264
269
  const root = (fn, properties = {}) => {
265
270
  let o = observer, s = scope;
266
271
  if (properties.scheduler === undefined) {
267
- properties.scheduler = scope?.scheduler;
268
- if (properties.scheduler === undefined) {
272
+ if (scope === null) {
269
273
  throw new Error('Reactivity: `root` cannot be created without a task scheduler');
270
274
  }
275
+ properties.scheduler = scope.scheduler;
271
276
  }
272
277
  observer = null;
273
278
  scope = properties;
package/build/types.d.ts CHANGED
@@ -3,11 +3,11 @@ import { CHECK, CLEAN, COMPUTED, DIRTY, DISPOSED, EFFECT, SIGNAL } from './const
3
3
  import Signal from './signal';
4
4
  type Changed = (a: unknown, b: unknown) => boolean;
5
5
  type Computed<T> = {
6
- fn: T extends Promise<unknown> ? never : ((previous: T) => T);
6
+ fn: PreventPromise<T, (previous: T) => T>;
7
7
  value: ReturnType<Computed<T>['fn']>;
8
8
  } & Omit<Signal<T>, 'fn' | 'value'>;
9
9
  type Effect<T> = {
10
- fn: (node: Effect<T>) => void;
10
+ fn: PreventPromise<T, (node: Effect<T>) => void>;
11
11
  root: NonNullable<Signal<T>['root']>;
12
12
  task: NonNullable<Signal<T>['task']>;
13
13
  value: void;
@@ -25,10 +25,11 @@ type Options = {
25
25
  changed?: Changed;
26
26
  value?: unknown;
27
27
  };
28
+ type PreventPromise<T, R> = T extends Promise<unknown> ? never : R;
28
29
  type Root = {
29
30
  scheduler: Scheduler;
30
31
  };
31
32
  type Scheduler = (fn: (...args: unknown[]) => Promise<unknown> | unknown) => unknown;
32
33
  type State = typeof CHECK | typeof CLEAN | typeof DIRTY | typeof DISPOSED;
33
34
  type Type = typeof COMPUTED | typeof EFFECT | typeof SIGNAL;
34
- export { Changed, Computed, Effect, Event, Listener, Object, Options, Prettify, Root, Scheduler, Signal, State, Type };
35
+ export { Changed, Computed, Effect, Event, Listener, Object, Options, Prettify, PreventPromise, Root, Scheduler, Signal, State, Type };
package/package.json CHANGED
@@ -16,5 +16,5 @@
16
16
  "prepublishOnly": "npm run build"
17
17
  },
18
18
  "types": "build/index.d.ts",
19
- "version": "0.1.2"
19
+ "version": "0.1.5"
20
20
  }
package/src/index.ts CHANGED
@@ -2,4 +2,5 @@ export { default as macro } from './macro';
2
2
  export { default as resource } from './resource';
3
3
  export * as core from './signal';
4
4
  export { effect, root } from './signal';
5
- export { default as reactive } from './reactive';
5
+ export { default as reactive } from './reactive';
6
+ export * from './types';
package/src/macro.ts CHANGED
@@ -3,7 +3,7 @@ import { computed, read } from './signal';
3
3
  import { Computed } from './types';
4
4
 
5
5
 
6
- type Fn<A extends unknown[], R> = Parameters<typeof computed<(...args: A) => R>>[0];
6
+ type Fn<A extends unknown[], R> = Computed<(...args: A) => R>['fn'];
7
7
 
8
8
  type Options = Parameters<typeof computed>[1];
9
9
 
@@ -4,8 +4,11 @@ import { defineProperty, isArray } from '~/utilities';
4
4
  import { ReactiveArray, ReactiveObjectArray } from './array';
5
5
 
6
6
 
7
+ type Node = Computed<unknown> | ReactiveArray<unknown> | ReactiveObjectArray<Object> | Signal<unknown>;
8
+
9
+
7
10
  class ReactiveObject<T extends Object> {
8
- nodes: Record<PropertyKey, Computed<unknown> | ReactiveObjectArray<Object> | ReactiveArray<unknown> | Signal<unknown>> = {};
11
+ nodes: Record<PropertyKey, Node> = {};
9
12
 
10
13
 
11
14
  constructor(data: T, options: Options = {}) {
@@ -18,6 +21,7 @@ class ReactiveObject<T extends Object> {
18
21
  let node = nodes[key] = computed(input as Computed<unknown>['fn'], options);
19
22
 
20
23
  defineProperty(this, key, {
24
+ enumerable: true,
21
25
  get() {
22
26
  return read(node);
23
27
  }
@@ -27,7 +31,7 @@ class ReactiveObject<T extends Object> {
27
31
  let node: ReactiveArray<unknown> | ReactiveObjectArray<Object>,
28
32
  test = input[0];
29
33
 
30
- if (typeof test === 'object' && test !== null && test.constructor.name === 'Object') {
34
+ if (typeof test === 'object' && test !== null && test?.constructor?.name === 'Object') {
31
35
  node = nodes[key] = new ReactiveObjectArray(input, options);
32
36
  }
33
37
  else {
@@ -35,6 +39,7 @@ class ReactiveObject<T extends Object> {
35
39
  }
36
40
 
37
41
  defineProperty(this, key, {
42
+ enumerable: true,
38
43
  get() {
39
44
  node.track();
40
45
 
@@ -43,9 +48,10 @@ class ReactiveObject<T extends Object> {
43
48
  });
44
49
  }
45
50
  else {
46
- let node = nodes[key] = signal(input, options);
51
+ let node = nodes[key] = signal<unknown>(input, options);
47
52
 
48
53
  defineProperty(this, key, {
54
+ enumerable: true,
49
55
  get() {
50
56
  return read(node);
51
57
  },
package/src/resource.ts CHANGED
@@ -42,8 +42,8 @@ class Resource<A extends unknown[], R extends Promise<unknown>> extends CustomFu
42
42
  });
43
43
  });
44
44
  this.#data = signal(options.value as Awaited<R>, options),
45
- this.#input = signal(null, options),
46
- this.#ok = signal(null, options)
45
+ this.#input = signal<A | null>(null, options),
46
+ this.#ok = signal<boolean | null>(null, options)
47
47
  }
48
48
 
49
49
 
package/src/signal.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CHECK, CLEAN, COMPUTED, DIRTY, DISPOSED, EFFECT, SIGNAL } from './constants';
2
- import { Changed, Computed, Effect, Event, Listener, Options, Root, Scheduler, State, Type } from './types';
2
+ import { Changed, Computed, Effect, Event, Listener, PreventPromise, Options, Root, Scheduler, State, Type } from './types';
3
3
  import { isArray } from './utilities';
4
4
 
5
5
 
@@ -286,17 +286,22 @@ const dispose = <T extends { dispose: () => void }>(dispose?: T[] | T) => {
286
286
  };
287
287
 
288
288
  const effect = <T>(fn: Effect<T>['fn'], options: Omit<Options, 'value'> = {}) => {
289
- if (!scope) {
289
+ let node = new Signal(undefined as any, DIRTY, EFFECT, options);
290
+
291
+ if (scope !== null) {
292
+ node.root = scope;
293
+ }
294
+ else if (observer !== null && observer.type === EFFECT) {
295
+ node.root = observer.root;
296
+ }
297
+ else {
290
298
  throw new Error('Reactivity: `effects` cannot be created without a reactive root');
291
299
  }
292
300
 
293
- let node = new Signal(undefined as any, DIRTY, EFFECT, options);
294
-
295
301
  node.fn = fn;
296
- node.root = scope;
297
302
  node.task = () => read(node);
298
303
 
299
- node.root.scheduler(node.task);
304
+ read(node);
300
305
 
301
306
  return node as Effect<void>;
302
307
  };
@@ -306,8 +311,8 @@ const read = <T>(node: Signal<T>): typeof node['value'] => {
306
311
  return node.value;
307
312
  }
308
313
 
309
- if (observer) {
310
- if (!observers) {
314
+ if (observer !== null) {
315
+ if (observers === null) {
311
316
  if (observer.sources !== null && observer.sources[index] == node) {
312
317
  index++;
313
318
  }
@@ -320,7 +325,7 @@ const read = <T>(node: Signal<T>): typeof node['value'] => {
320
325
  }
321
326
  }
322
327
 
323
- if (node.fn) {
328
+ if (node.fn !== null) {
324
329
  sync(node);
325
330
  }
326
331
 
@@ -342,16 +347,16 @@ const reset = <T extends { reset: () => void }>(reset?: T[] | T) => {
342
347
  return reset;
343
348
  };
344
349
 
345
- const root = <T>(fn: () => T, properties: { scheduler?: Scheduler } = {}) => {
350
+ const root = <T>(fn: PreventPromise<T, () => T>, properties: { scheduler?: Scheduler } = {}) => {
346
351
  let o = observer,
347
352
  s = scope;
348
353
 
349
354
  if (properties.scheduler === undefined) {
350
- properties.scheduler = scope?.scheduler;
351
-
352
- if (properties.scheduler === undefined) {
355
+ if (scope === null) {
353
356
  throw new Error('Reactivity: `root` cannot be created without a task scheduler');
354
357
  }
358
+
359
+ properties.scheduler = scope.scheduler;
355
360
  }
356
361
 
357
362
  observer = null;
package/src/types.ts CHANGED
@@ -6,12 +6,12 @@ import Signal from './signal';
6
6
  type Changed = (a: unknown, b: unknown) => boolean;
7
7
 
8
8
  type Computed<T> = {
9
- fn: T extends Promise<unknown> ? never : ((previous: T) => T);
9
+ fn: PreventPromise<T, (previous: T) => T>;
10
10
  value: ReturnType<Computed<T>['fn']>;
11
11
  } & Omit<Signal<T>, 'fn' | 'value'>;
12
12
 
13
13
  type Effect<T> = {
14
- fn: (node: Effect<T>) => void;
14
+ fn: PreventPromise<T, (node: Effect<T>) => void>;
15
15
  root: NonNullable<Signal<T>['root']>;
16
16
  task: NonNullable<Signal<T>['task']>
17
17
  value: void;
@@ -32,6 +32,8 @@ type Options = {
32
32
  value?: unknown;
33
33
  };
34
34
 
35
+ type PreventPromise<T, R> = T extends Promise<unknown> ? never : R;
36
+
35
37
  type Root = {
36
38
  scheduler: Scheduler
37
39
  };
@@ -43,4 +45,4 @@ type State = typeof CHECK | typeof CLEAN | typeof DIRTY | typeof DISPOSED;
43
45
  type Type = typeof COMPUTED | typeof EFFECT | typeof SIGNAL;
44
46
 
45
47
 
46
- export { Changed, Computed, Effect, Event, Listener, Object, Options, Prettify, Root, Scheduler, Signal, State, Type };
48
+ export { Changed, Computed, Effect, Event, Listener, Object, Options, Prettify, PreventPromise, Root, Scheduler, Signal, State, Type };