@oscarpalmer/mora 0.16.0 → 0.17.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.
@@ -1,7 +1,7 @@
1
1
  import {batchDepth, batchedHandlers} from '../batch';
2
2
  import {type Effect, activeEffect, effect, runEffect} from '../effect';
3
3
  import {computedName} from '../helpers/is';
4
- import {Reactive, type ReactiveState} from './reactive';
4
+ import {Reactive, type ReactiveOptions, type ReactiveState} from './reactive';
5
5
 
6
6
  export type ComputedEffect = {
7
7
  dirty: boolean;
@@ -10,7 +10,7 @@ export type ComputedEffect = {
10
10
 
11
11
  export type InternalComputed = {
12
12
  readonly effect: ComputedEffect;
13
- readonly state: ReactiveState<unknown>;
13
+ readonly state: ReactiveState<unknown, unknown>;
14
14
  };
15
15
 
16
16
  export let activeComputed: Computed<unknown> | undefined;
@@ -21,8 +21,8 @@ export class Computed<Value> extends Reactive<Value> {
21
21
  instance: undefined as never,
22
22
  };
23
23
 
24
- constructor(callback: () => Value) {
25
- super(computedName, undefined as never);
24
+ constructor(callback: () => Value, options?: ReactiveOptions<Value>) {
25
+ super(computedName, undefined as never, options);
26
26
 
27
27
  this.effect.instance = effect(() => {
28
28
  if (this.effect.dirty) {
@@ -34,7 +34,7 @@ export class Computed<Value> extends Reactive<Value> {
34
34
 
35
35
  activeComputed = previousComputed;
36
36
 
37
- if (!Object.is(this.state.value, value)) {
37
+ if (!this.state.equal(this.state.value, value)) {
38
38
  this.state.value = value;
39
39
 
40
40
  for (const computed of this.state.computeds) {
@@ -78,6 +78,9 @@ export class Computed<Value> extends Reactive<Value> {
78
78
  /**
79
79
  * Create a computed value
80
80
  */
81
- export function computed<Value>(callback: () => Value): Computed<Value> {
82
- return new Computed(callback);
81
+ export function computed<Value>(
82
+ callback: () => Value,
83
+ options?: ReactiveOptions<Value>,
84
+ ): Computed<Value> {
85
+ return new Computed(callback, options);
83
86
  }
@@ -7,17 +7,22 @@ import {
7
7
  } from '../subscription';
8
8
  import type {Computed} from './computed';
9
9
 
10
- export abstract class Reactive<Value> {
11
- protected readonly state: ReactiveState<Value> = {
10
+ export abstract class Reactive<Value, Equal = Value> {
11
+ protected readonly state: ReactiveState<Value, Equal> = {
12
12
  computeds: new Set(),
13
13
  effects: new Set(),
14
+ equal: Object.is,
14
15
  subscriptions: new Map(),
15
16
  value: undefined as never,
16
17
  };
17
18
 
18
- constructor(name: string, value: Value) {
19
+ constructor(name: string, value: Value, options?: ReactiveOptions<Equal>) {
19
20
  this.state.value = value;
20
21
 
22
+ if (typeof options === 'object' && typeof options.equal === 'function') {
23
+ this.state.equal = options.equal;
24
+ }
25
+
21
26
  Object.defineProperty(this, '$mora', {
22
27
  value: name,
23
28
  });
@@ -64,9 +69,17 @@ export abstract class Reactive<Value> {
64
69
  }
65
70
  }
66
71
 
67
- export type ReactiveState<Value> = {
72
+ export type ReactiveOptions<Value> = {
73
+ /**
74
+ * Method to compare values for equality
75
+ */
76
+ equal?: (first: Value, second: Value) => boolean;
77
+ };
78
+
79
+ export type ReactiveState<Value, Equal> = {
68
80
  computeds: Set<Computed<unknown>>;
69
81
  effects: Set<Effect>;
82
+ equal: (first: Equal, second: Equal) => boolean;
70
83
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
71
84
  value: Value;
72
85
  };
@@ -1,10 +1,10 @@
1
1
  import {signalName} from '../helpers/is';
2
2
  import {differentValues, emitValue, getValue} from '../helpers/value';
3
- import {Reactive} from './reactive';
3
+ import {Reactive, type ReactiveOptions} from './reactive';
4
4
 
5
5
  export class Signal<Value> extends Reactive<Value> {
6
- constructor(value: Value) {
7
- super(signalName, value);
6
+ constructor(value: Value, options?: ReactiveOptions<Value>) {
7
+ super(signalName, value, options);
8
8
  }
9
9
 
10
10
  /**
@@ -18,7 +18,7 @@ export class Signal<Value> extends Reactive<Value> {
18
18
  * Set the value
19
19
  */
20
20
  set(value: Value): void {
21
- if (differentValues(this.state.value, value)) {
21
+ if (differentValues(this.state, this.state.value, value)) {
22
22
  this.state.value = value;
23
23
 
24
24
  emitValue(this.state);
@@ -36,6 +36,9 @@ export class Signal<Value> extends Reactive<Value> {
36
36
  /**
37
37
  * Create a reactive value
38
38
  */
39
- export function signal<Value>(value: Value): Signal<Value> {
40
- return new Signal(value);
39
+ export function signal<Value>(
40
+ value: Value,
41
+ options?: ReactiveOptions<Value>,
42
+ ): Signal<Value> {
43
+ return new Signal<Value>(value, options);
41
44
  }
package/types/batch.d.cts CHANGED
@@ -8,15 +8,15 @@ declare class Effect {
8
8
  }
9
9
  declare class Computed<Value> extends Reactive<Value> {
10
10
  private readonly effect;
11
- constructor(callback: () => Value);
11
+ constructor(callback: () => Value, options?: ReactiveOptions<Value>);
12
12
  /**
13
13
  * @inheritdoc
14
14
  */
15
15
  get(): Value;
16
16
  }
17
- declare abstract class Reactive<Value> {
18
- protected readonly state: ReactiveState<Value>;
19
- constructor(name: string, value: Value);
17
+ declare abstract class Reactive<Value, Equal = Value> {
18
+ protected readonly state: ReactiveState<Value, Equal>;
19
+ constructor(name: string, value: Value, options?: ReactiveOptions<Equal>);
20
20
  /**
21
21
  * Get the value
22
22
  */
@@ -42,16 +42,23 @@ declare abstract class Reactive<Value> {
42
42
  */
43
43
  unsubscribe(callback: (value: Value) => void): void;
44
44
  }
45
- export type ReactiveState<Value> = {
45
+ export type ReactiveOptions<Value> = {
46
+ /**
47
+ * Method to compare values for equality
48
+ */
49
+ equal?: (first: Value, second: Value) => boolean;
50
+ };
51
+ export type ReactiveState<Value, Equal> = {
46
52
  computeds: Set<Computed<unknown>>;
47
53
  effects: Set<Effect>;
54
+ equal: (first: Equal, second: Equal) => boolean;
48
55
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
49
56
  value: Value;
50
57
  };
51
58
  declare class Subscription<Value> {
52
- state: ReactiveState<Value>;
59
+ state: ReactiveState<Value, never>;
53
60
  callback: GenericCallback;
54
- constructor(state: ReactiveState<Value>, callback: GenericCallback);
61
+ constructor(state: ReactiveState<Value, never>, callback: GenericCallback);
55
62
  }
56
63
  /**
57
64
  * Unsubscribe from changes
@@ -8,15 +8,15 @@ declare class Effect {
8
8
  }
9
9
  declare class Computed<Value> extends Reactive<Value> {
10
10
  private readonly effect;
11
- constructor(callback: () => Value);
11
+ constructor(callback: () => Value, options?: ReactiveOptions<Value>);
12
12
  /**
13
13
  * @inheritdoc
14
14
  */
15
15
  get(): Value;
16
16
  }
17
- declare abstract class Reactive<Value> {
18
- protected readonly state: ReactiveState<Value>;
19
- constructor(name: string, value: Value);
17
+ declare abstract class Reactive<Value, Equal = Value> {
18
+ protected readonly state: ReactiveState<Value, Equal>;
19
+ constructor(name: string, value: Value, options?: ReactiveOptions<Equal>);
20
20
  /**
21
21
  * Get the value
22
22
  */
@@ -42,22 +42,29 @@ declare abstract class Reactive<Value> {
42
42
  */
43
43
  unsubscribe(callback: (value: Value) => void): void;
44
44
  }
45
- export type ReactiveState<Value> = {
45
+ export type ReactiveOptions<Value> = {
46
+ /**
47
+ * Method to compare values for equality
48
+ */
49
+ equal?: (first: Value, second: Value) => boolean;
50
+ };
51
+ export type ReactiveState<Value, Equal> = {
46
52
  computeds: Set<Computed<unknown>>;
47
53
  effects: Set<Effect>;
54
+ equal: (first: Equal, second: Equal) => boolean;
48
55
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
49
56
  value: Value;
50
57
  };
51
58
  declare class Subscription<Value> {
52
- state: ReactiveState<Value>;
59
+ state: ReactiveState<Value, never>;
53
60
  callback: GenericCallback;
54
- constructor(state: ReactiveState<Value>, callback: GenericCallback);
61
+ constructor(state: ReactiveState<Value, never>, callback: GenericCallback);
55
62
  }
56
63
  /**
57
64
  * Unsubscribe from changes
58
65
  */
59
66
  export type Unsubscribe = () => void;
60
- declare class ReactiveArray<Item> extends Reactive<Item[]> {
67
+ declare class ReactiveArray<Item> extends Reactive<Item[], Item> {
61
68
  #private;
62
69
  /**
63
70
  * The length of the array
@@ -67,7 +74,7 @@ declare class ReactiveArray<Item> extends Reactive<Item[]> {
67
74
  * Set the length of the array
68
75
  */
69
76
  set length(value: number);
70
- constructor(value: Item[]);
77
+ constructor(value: Item[], options?: ReactiveOptions<Item>);
71
78
  /**
72
79
  * Get an indexed item
73
80
  */
@@ -130,7 +137,7 @@ declare class ReactiveArray<Item> extends Reactive<Item[]> {
130
137
  unshift(...items: Item[]): number;
131
138
  }
132
139
  declare class Signal<Value> extends Reactive<Value> {
133
- constructor(value: Value);
140
+ constructor(value: Value, options?: ReactiveOptions<Value>);
134
141
  /**
135
142
  * @inheritdoc
136
143
  */
@@ -8,15 +8,15 @@ declare class Effect {
8
8
  }
9
9
  declare class Computed<Value> extends Reactive<Value> {
10
10
  private readonly effect;
11
- constructor(callback: () => Value);
11
+ constructor(callback: () => Value, options?: ReactiveOptions<Value>);
12
12
  /**
13
13
  * @inheritdoc
14
14
  */
15
15
  get(): Value;
16
16
  }
17
- declare abstract class Reactive<Value> {
18
- protected readonly state: ReactiveState<Value>;
19
- constructor(name: string, value: Value);
17
+ declare abstract class Reactive<Value, Equal = Value> {
18
+ protected readonly state: ReactiveState<Value, Equal>;
19
+ constructor(name: string, value: Value, options?: ReactiveOptions<Equal>);
20
20
  /**
21
21
  * Get the value
22
22
  */
@@ -42,24 +42,31 @@ declare abstract class Reactive<Value> {
42
42
  */
43
43
  unsubscribe(callback: (value: Value) => void): void;
44
44
  }
45
- export type ReactiveState<Value> = {
45
+ export type ReactiveOptions<Value> = {
46
+ /**
47
+ * Method to compare values for equality
48
+ */
49
+ equal?: (first: Value, second: Value) => boolean;
50
+ };
51
+ export type ReactiveState<Value, Equal> = {
46
52
  computeds: Set<Computed<unknown>>;
47
53
  effects: Set<Effect>;
54
+ equal: (first: Equal, second: Equal) => boolean;
48
55
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
49
56
  value: Value;
50
57
  };
51
58
  declare class Subscription<Value> {
52
- state: ReactiveState<Value>;
59
+ state: ReactiveState<Value, never>;
53
60
  callback: GenericCallback;
54
- constructor(state: ReactiveState<Value>, callback: GenericCallback);
61
+ constructor(state: ReactiveState<Value, never>, callback: GenericCallback);
55
62
  }
56
63
  /**
57
64
  * Unsubscribe from changes
58
65
  */
59
66
  export type Unsubscribe = () => void;
60
- export declare function differentArrays(first: unknown[], second: unknown[]): boolean;
61
- export declare function differentValues(first: unknown, second: unknown): boolean;
62
- export declare function emitValue<Value>(state: ReactiveState<Value>): void;
63
- export declare function getValue<Value>(state: ReactiveState<Value>): Value;
67
+ export declare function differentArrays<Value>(state: ReactiveState<Value[], Value>, first: Value[], second: Value[]): boolean;
68
+ export declare function differentValues<Value>(state: ReactiveState<Value, Value>, first: Value, second: Value): boolean;
69
+ export declare function emitValue<Value>(state: ReactiveState<Value, never>): void;
70
+ export declare function getValue<Value>(state: ReactiveState<Value, never>): Value;
64
71
 
65
72
  export {};
@@ -1,5 +1,5 @@
1
1
  import type { ReactiveState } from '../value/reactive';
2
- export declare function differentArrays(first: unknown[], second: unknown[]): boolean;
3
- export declare function differentValues(first: unknown, second: unknown): boolean;
4
- export declare function emitValue<Value>(state: ReactiveState<Value>): void;
5
- export declare function getValue<Value>(state: ReactiveState<Value>): Value;
2
+ export declare function differentArrays<Value>(state: ReactiveState<Value[], Value>, first: Value[], second: Value[]): boolean;
3
+ export declare function differentValues<Value>(state: ReactiveState<Value, Value>, first: Value, second: Value): boolean;
4
+ export declare function emitValue<Value>(state: ReactiveState<Value, never>): void;
5
+ export declare function getValue<Value>(state: ReactiveState<Value, never>): Value;
package/types/index.d.cts CHANGED
@@ -12,7 +12,7 @@ export declare class Effect {
12
12
  export declare function effect(callback: GenericCallback): Effect;
13
13
  export declare class Computed<Value> extends Reactive<Value> {
14
14
  private readonly effect;
15
- constructor(callback: () => Value);
15
+ constructor(callback: () => Value, options?: ReactiveOptions<Value>);
16
16
  /**
17
17
  * @inheritdoc
18
18
  */
@@ -21,10 +21,10 @@ export declare class Computed<Value> extends Reactive<Value> {
21
21
  /**
22
22
  * Create a computed value
23
23
  */
24
- export declare function computed<Value>(callback: () => Value): Computed<Value>;
25
- export declare abstract class Reactive<Value> {
26
- protected readonly state: ReactiveState<Value>;
27
- constructor(name: string, value: Value);
24
+ export declare function computed<Value>(callback: () => Value, options?: ReactiveOptions<Value>): Computed<Value>;
25
+ export declare abstract class Reactive<Value, Equal = Value> {
26
+ protected readonly state: ReactiveState<Value, Equal>;
27
+ constructor(name: string, value: Value, options?: ReactiveOptions<Equal>);
28
28
  /**
29
29
  * Get the value
30
30
  */
@@ -50,16 +50,23 @@ export declare abstract class Reactive<Value> {
50
50
  */
51
51
  unsubscribe(callback: (value: Value) => void): void;
52
52
  }
53
- export type ReactiveState<Value> = {
53
+ export type ReactiveOptions<Value> = {
54
+ /**
55
+ * Method to compare values for equality
56
+ */
57
+ equal?: (first: Value, second: Value) => boolean;
58
+ };
59
+ export type ReactiveState<Value, Equal> = {
54
60
  computeds: Set<Computed<unknown>>;
55
61
  effects: Set<Effect>;
62
+ equal: (first: Equal, second: Equal) => boolean;
56
63
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
57
64
  value: Value;
58
65
  };
59
66
  declare class Subscription<Value> {
60
- state: ReactiveState<Value>;
67
+ state: ReactiveState<Value, never>;
61
68
  callback: GenericCallback;
62
- constructor(state: ReactiveState<Value>, callback: GenericCallback);
69
+ constructor(state: ReactiveState<Value, never>, callback: GenericCallback);
63
70
  }
64
71
  /**
65
72
  * Unsubscribe from changes
@@ -73,7 +80,7 @@ export declare function startBatch(): void;
73
80
  * Stop batching effects and flush _(run)_ them
74
81
  */
75
82
  export declare function stopBatch(): void;
76
- export declare class ReactiveArray<Item> extends Reactive<Item[]> {
83
+ export declare class ReactiveArray<Item> extends Reactive<Item[], Item> {
77
84
  #private;
78
85
  /**
79
86
  * The length of the array
@@ -83,7 +90,7 @@ export declare class ReactiveArray<Item> extends Reactive<Item[]> {
83
90
  * Set the length of the array
84
91
  */
85
92
  set length(value: number);
86
- constructor(value: Item[]);
93
+ constructor(value: Item[], options?: ReactiveOptions<Item>);
87
94
  /**
88
95
  * Get an indexed item
89
96
  */
@@ -148,9 +155,9 @@ export declare class ReactiveArray<Item> extends Reactive<Item[]> {
148
155
  /**
149
156
  * Create a reactive array
150
157
  */
151
- export declare function array<Item>(value: Item[]): ReactiveArray<Item>;
158
+ export declare function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item>;
152
159
  export declare class Signal<Value> extends Reactive<Value> {
153
- constructor(value: Value);
160
+ constructor(value: Value, options?: ReactiveOptions<Value>);
154
161
  /**
155
162
  * @inheritdoc
156
163
  */
@@ -167,7 +174,7 @@ export declare class Signal<Value> extends Reactive<Value> {
167
174
  /**
168
175
  * Create a reactive value
169
176
  */
170
- export declare function signal<Value>(value: Value): Signal<Value>;
177
+ export declare function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value>;
171
178
  /**
172
179
  * Is the value a reactive array?
173
180
  */
@@ -8,15 +8,15 @@ declare class Effect {
8
8
  }
9
9
  declare class Computed<Value> extends Reactive<Value> {
10
10
  private readonly effect;
11
- constructor(callback: () => Value);
11
+ constructor(callback: () => Value, options?: ReactiveOptions<Value>);
12
12
  /**
13
13
  * @inheritdoc
14
14
  */
15
15
  get(): Value;
16
16
  }
17
- declare abstract class Reactive<Value> {
18
- protected readonly state: ReactiveState<Value>;
19
- constructor(name: string, value: Value);
17
+ declare abstract class Reactive<Value, Equal = Value> {
18
+ protected readonly state: ReactiveState<Value, Equal>;
19
+ constructor(name: string, value: Value, options?: ReactiveOptions<Equal>);
20
20
  /**
21
21
  * Get the value
22
22
  */
@@ -42,23 +42,30 @@ declare abstract class Reactive<Value> {
42
42
  */
43
43
  unsubscribe(callback: (value: Value) => void): void;
44
44
  }
45
- export type ReactiveState<Value> = {
45
+ export type ReactiveOptions<Value> = {
46
+ /**
47
+ * Method to compare values for equality
48
+ */
49
+ equal?: (first: Value, second: Value) => boolean;
50
+ };
51
+ export type ReactiveState<Value, Equal> = {
46
52
  computeds: Set<Computed<unknown>>;
47
53
  effects: Set<Effect>;
54
+ equal: (first: Equal, second: Equal) => boolean;
48
55
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
49
56
  value: Value;
50
57
  };
51
58
  export declare class Subscription<Value> {
52
- state: ReactiveState<Value>;
59
+ state: ReactiveState<Value, never>;
53
60
  callback: GenericCallback;
54
- constructor(state: ReactiveState<Value>, callback: GenericCallback);
61
+ constructor(state: ReactiveState<Value, never>, callback: GenericCallback);
55
62
  }
56
63
  /**
57
64
  * Unsubscribe from changes
58
65
  */
59
66
  export type Unsubscribe = () => void;
60
67
  export declare function noop(): void;
61
- export declare function subscribe<Value>(state: ReactiveState<Value>, callback: (value: Value) => void): Unsubscribe;
62
- export declare function unsubscribe<Value>(state: ReactiveState<Value>, callback: (value: Value) => void): void;
68
+ export declare function subscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): Unsubscribe;
69
+ export declare function unsubscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): void;
63
70
 
64
71
  export {};
@@ -1,14 +1,14 @@
1
1
  import type { GenericCallback } from '@oscarpalmer/atoms/models';
2
2
  import type { ReactiveState } from './value/reactive';
3
3
  export declare class Subscription<Value> {
4
- state: ReactiveState<Value>;
4
+ state: ReactiveState<Value, never>;
5
5
  callback: GenericCallback;
6
- constructor(state: ReactiveState<Value>, callback: GenericCallback);
6
+ constructor(state: ReactiveState<Value, never>, callback: GenericCallback);
7
7
  }
8
8
  /**
9
9
  * Unsubscribe from changes
10
10
  */
11
11
  export type Unsubscribe = () => void;
12
12
  export declare function noop(): void;
13
- export declare function subscribe<Value>(state: ReactiveState<Value>, callback: (value: Value) => void): Unsubscribe;
14
- export declare function unsubscribe<Value>(state: ReactiveState<Value>, callback: (value: Value) => void): void;
13
+ export declare function subscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): Unsubscribe;
14
+ export declare function unsubscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): void;
@@ -8,15 +8,15 @@ declare class Effect {
8
8
  }
9
9
  declare class Computed<Value> extends Reactive<Value> {
10
10
  private readonly effect;
11
- constructor(callback: () => Value);
11
+ constructor(callback: () => Value, options?: ReactiveOptions<Value>);
12
12
  /**
13
13
  * @inheritdoc
14
14
  */
15
15
  get(): Value;
16
16
  }
17
- declare abstract class Reactive<Value> {
18
- protected readonly state: ReactiveState<Value>;
19
- constructor(name: string, value: Value);
17
+ declare abstract class Reactive<Value, Equal = Value> {
18
+ protected readonly state: ReactiveState<Value, Equal>;
19
+ constructor(name: string, value: Value, options?: ReactiveOptions<Equal>);
20
20
  /**
21
21
  * Get the value
22
22
  */
@@ -42,22 +42,29 @@ declare abstract class Reactive<Value> {
42
42
  */
43
43
  unsubscribe(callback: (value: Value) => void): void;
44
44
  }
45
- export type ReactiveState<Value> = {
45
+ export type ReactiveOptions<Value> = {
46
+ /**
47
+ * Method to compare values for equality
48
+ */
49
+ equal?: (first: Value, second: Value) => boolean;
50
+ };
51
+ export type ReactiveState<Value, Equal> = {
46
52
  computeds: Set<Computed<unknown>>;
47
53
  effects: Set<Effect>;
54
+ equal: (first: Equal, second: Equal) => boolean;
48
55
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
49
56
  value: Value;
50
57
  };
51
58
  declare class Subscription<Value> {
52
- state: ReactiveState<Value>;
59
+ state: ReactiveState<Value, never>;
53
60
  callback: GenericCallback;
54
- constructor(state: ReactiveState<Value>, callback: GenericCallback);
61
+ constructor(state: ReactiveState<Value, never>, callback: GenericCallback);
55
62
  }
56
63
  /**
57
64
  * Unsubscribe from changes
58
65
  */
59
66
  export type Unsubscribe = () => void;
60
- export declare class ReactiveArray<Item> extends Reactive<Item[]> {
67
+ export declare class ReactiveArray<Item> extends Reactive<Item[], Item> {
61
68
  #private;
62
69
  /**
63
70
  * The length of the array
@@ -67,7 +74,7 @@ export declare class ReactiveArray<Item> extends Reactive<Item[]> {
67
74
  * Set the length of the array
68
75
  */
69
76
  set length(value: number);
70
- constructor(value: Item[]);
77
+ constructor(value: Item[], options?: ReactiveOptions<Item>);
71
78
  /**
72
79
  * Get an indexed item
73
80
  */
@@ -132,6 +139,6 @@ export declare class ReactiveArray<Item> extends Reactive<Item[]> {
132
139
  /**
133
140
  * Create a reactive array
134
141
  */
135
- export declare function array<Item>(value: Item[]): ReactiveArray<Item>;
142
+ export declare function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item>;
136
143
 
137
144
  export {};
@@ -1,6 +1,6 @@
1
1
  import { type Computed } from './computed';
2
- import { Reactive } from './reactive';
3
- export declare class ReactiveArray<Item> extends Reactive<Item[]> {
2
+ import { Reactive, type ReactiveOptions } from './reactive';
3
+ export declare class ReactiveArray<Item> extends Reactive<Item[], Item> {
4
4
  #private;
5
5
  /**
6
6
  * The length of the array
@@ -10,7 +10,7 @@ export declare class ReactiveArray<Item> extends Reactive<Item[]> {
10
10
  * Set the length of the array
11
11
  */
12
12
  set length(value: number);
13
- constructor(value: Item[]);
13
+ constructor(value: Item[], options?: ReactiveOptions<Item>);
14
14
  /**
15
15
  * Get an indexed item
16
16
  */
@@ -75,4 +75,4 @@ export declare class ReactiveArray<Item> extends Reactive<Item[]> {
75
75
  /**
76
76
  * Create a reactive array
77
77
  */
78
- export declare function array<Item>(value: Item[]): ReactiveArray<Item>;
78
+ export declare function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item>;
@@ -12,12 +12,12 @@ export type ComputedEffect = {
12
12
  };
13
13
  export type InternalComputed = {
14
14
  readonly effect: ComputedEffect;
15
- readonly state: ReactiveState<unknown>;
15
+ readonly state: ReactiveState<unknown, unknown>;
16
16
  };
17
17
  export declare let activeComputed: Computed<unknown> | undefined;
18
18
  export declare class Computed<Value> extends Reactive<Value> {
19
19
  private readonly effect;
20
- constructor(callback: () => Value);
20
+ constructor(callback: () => Value, options?: ReactiveOptions<Value>);
21
21
  /**
22
22
  * @inheritdoc
23
23
  */
@@ -26,10 +26,10 @@ export declare class Computed<Value> extends Reactive<Value> {
26
26
  /**
27
27
  * Create a computed value
28
28
  */
29
- export declare function computed<Value>(callback: () => Value): Computed<Value>;
30
- declare abstract class Reactive<Value> {
31
- protected readonly state: ReactiveState<Value>;
32
- constructor(name: string, value: Value);
29
+ export declare function computed<Value>(callback: () => Value, options?: ReactiveOptions<Value>): Computed<Value>;
30
+ declare abstract class Reactive<Value, Equal = Value> {
31
+ protected readonly state: ReactiveState<Value, Equal>;
32
+ constructor(name: string, value: Value, options?: ReactiveOptions<Equal>);
33
33
  /**
34
34
  * Get the value
35
35
  */
@@ -55,16 +55,23 @@ declare abstract class Reactive<Value> {
55
55
  */
56
56
  unsubscribe(callback: (value: Value) => void): void;
57
57
  }
58
- export type ReactiveState<Value> = {
58
+ export type ReactiveOptions<Value> = {
59
+ /**
60
+ * Method to compare values for equality
61
+ */
62
+ equal?: (first: Value, second: Value) => boolean;
63
+ };
64
+ export type ReactiveState<Value, Equal> = {
59
65
  computeds: Set<Computed<unknown>>;
60
66
  effects: Set<Effect>;
67
+ equal: (first: Equal, second: Equal) => boolean;
61
68
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
62
69
  value: Value;
63
70
  };
64
71
  declare class Subscription<Value> {
65
- state: ReactiveState<Value>;
72
+ state: ReactiveState<Value, never>;
66
73
  callback: GenericCallback;
67
- constructor(state: ReactiveState<Value>, callback: GenericCallback);
74
+ constructor(state: ReactiveState<Value, never>, callback: GenericCallback);
68
75
  }
69
76
  /**
70
77
  * Unsubscribe from changes
@@ -1,17 +1,17 @@
1
1
  import { type Effect } from '../effect';
2
- import { Reactive, type ReactiveState } from './reactive';
2
+ import { Reactive, type ReactiveOptions, type ReactiveState } from './reactive';
3
3
  export type ComputedEffect = {
4
4
  dirty: boolean;
5
5
  instance: Effect;
6
6
  };
7
7
  export type InternalComputed = {
8
8
  readonly effect: ComputedEffect;
9
- readonly state: ReactiveState<unknown>;
9
+ readonly state: ReactiveState<unknown, unknown>;
10
10
  };
11
11
  export declare let activeComputed: Computed<unknown> | undefined;
12
12
  export declare class Computed<Value> extends Reactive<Value> {
13
13
  private readonly effect;
14
- constructor(callback: () => Value);
14
+ constructor(callback: () => Value, options?: ReactiveOptions<Value>);
15
15
  /**
16
16
  * @inheritdoc
17
17
  */
@@ -20,4 +20,4 @@ export declare class Computed<Value> extends Reactive<Value> {
20
20
  /**
21
21
  * Create a computed value
22
22
  */
23
- export declare function computed<Value>(callback: () => Value): Computed<Value>;
23
+ export declare function computed<Value>(callback: () => Value, options?: ReactiveOptions<Value>): Computed<Value>;