@oscarpalmer/mora 0.18.0 → 0.18.1

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 (44) hide show
  1. package/dist/helpers/is.cjs +7 -1
  2. package/dist/helpers/is.js +8 -2
  3. package/dist/helpers/proxy.cjs +43 -0
  4. package/dist/helpers/proxy.js +43 -0
  5. package/dist/helpers/value.cjs +22 -26
  6. package/dist/helpers/value.js +22 -26
  7. package/dist/index.cjs +2 -0
  8. package/dist/index.js +3 -1
  9. package/dist/mora.full.js +127 -59
  10. package/dist/node_modules/@oscarpalmer/atoms/dist/internal/is.cjs +17 -0
  11. package/dist/node_modules/@oscarpalmer/atoms/dist/internal/is.js +17 -0
  12. package/dist/value/array.cjs +15 -20
  13. package/dist/value/array.js +16 -21
  14. package/dist/value/computed.cjs +5 -5
  15. package/dist/value/computed.js +5 -5
  16. package/dist/value/reactive.cjs +5 -1
  17. package/dist/value/reactive.js +5 -1
  18. package/dist/value/signal.cjs +5 -5
  19. package/dist/value/signal.js +6 -6
  20. package/dist/value/store.cjs +36 -0
  21. package/dist/value/store.js +36 -0
  22. package/package.json +1 -1
  23. package/src/helpers/is.ts +1 -1
  24. package/src/helpers/proxy.ts +0 -1
  25. package/types/helpers/is.d.ts +3 -0
  26. package/types/helpers/proxy.d.ts +5 -0
  27. package/types/helpers/value.d.ts +3 -4
  28. package/types/index.d.ts +1 -0
  29. package/types/subscription.d.ts +4 -4
  30. package/types/value/array.d.ts +4 -4
  31. package/types/value/computed.d.ts +4 -4
  32. package/types/value/reactive.d.ts +11 -4
  33. package/types/value/signal.d.ts +3 -3
  34. package/types/value/store.d.ts +45 -0
  35. package/types/batch.d.cts +0 -72
  36. package/types/effect.d.cts +0 -16
  37. package/types/helpers/is.d.cts +0 -169
  38. package/types/helpers/value.d.cts +0 -65
  39. package/types/index.d.cts +0 -189
  40. package/types/subscription.d.cts +0 -64
  41. package/types/value/array.d.cts +0 -137
  42. package/types/value/computed.d.cts +0 -74
  43. package/types/value/reactive.d.cts +0 -61
  44. package/types/value/signal.d.cts +0 -80
@@ -8,18 +8,27 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
8
8
  var _size;
9
9
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
10
10
  const helpers_is = require("../helpers/is.cjs");
11
+ const helpers_proxy = require("../helpers/proxy.cjs");
11
12
  const helpers_value = require("../helpers/value.cjs");
12
13
  const value_computed = require("./computed.cjs");
13
14
  const value_reactive = require("./reactive.cjs");
14
15
  const value_signal = require("./signal.cjs");
15
16
  class ReactiveArray extends value_reactive.Reactive {
16
- constructor(value) {
17
+ constructor(value, options) {
17
18
  super(
18
19
  helpers_is.arrayName,
19
20
  new Proxy(value, {
20
21
  get: (target, property) => updateMethods.has(property) ? updateArray(property, target, this.state, __privateGet(this, _size)) : Reflect.get(target, property),
21
- set: (target, property, value2) => setValue(target, property, value2, this.state, __privateGet(this, _size))
22
- })
22
+ set: (target, property, value2) => helpers_proxy.setValueInProxy(
23
+ target,
24
+ property,
25
+ value2,
26
+ this.state,
27
+ true,
28
+ __privateGet(this, _size)
29
+ )
30
+ }),
31
+ options
23
32
  );
24
33
  __privateAdd(this, _size, value_signal.signal(0));
25
34
  __privateGet(this, _size).set(value.length);
@@ -116,22 +125,8 @@ class ReactiveArray extends value_reactive.Reactive {
116
125
  }
117
126
  }
118
127
  _size = new WeakMap();
119
- function array(value) {
120
- return new ReactiveArray(Array.isArray(value) ? value : []);
121
- }
122
- function setValue(target, property, value, state, length) {
123
- const isIndex = !Number.isNaN(Number(property));
124
- const isLength = property === "length";
125
- if (!isIndex && !isLength) {
126
- return Reflect.set(target, property, value);
127
- }
128
- const previous = Reflect.get(target, property);
129
- if (!Object.is(previous, value)) {
130
- Reflect.set(target, property, value);
131
- helpers_value.emitValue(state);
132
- length.set(target.length);
133
- }
134
- return true;
128
+ function array(value, options) {
129
+ return new ReactiveArray(Array.isArray(value) ? value : [], options);
135
130
  }
136
131
  function updateArray(type, array2, state, length) {
137
132
  const affectsLength = lengthAffectingMethods.has(type);
@@ -141,7 +136,7 @@ function updateArray(type, array2, state, length) {
141
136
  const result = array2[type](
142
137
  ...args
143
138
  );
144
- if (affectsLength ? array2.length !== previousLength : helpers_value.differentArrays(previousArray, array2)) {
139
+ if (affectsLength ? array2.length !== previousLength : !helpers_value.equalArrays(state, previousArray, array2)) {
145
140
  helpers_value.emitValue(state);
146
141
  length.set(array2.length);
147
142
  }
@@ -6,18 +6,27 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
6
6
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
7
  var _size;
8
8
  import { arrayName } from "../helpers/is.js";
9
- import { getValue, emitValue, differentArrays } from "../helpers/value.js";
9
+ import { setValueInProxy } from "../helpers/proxy.js";
10
+ import { getValue, equalArrays, emitValue } from "../helpers/value.js";
10
11
  import { computed } from "./computed.js";
11
12
  import { Reactive } from "./reactive.js";
12
13
  import { signal } from "./signal.js";
13
14
  class ReactiveArray extends Reactive {
14
- constructor(value) {
15
+ constructor(value, options) {
15
16
  super(
16
17
  arrayName,
17
18
  new Proxy(value, {
18
19
  get: (target, property) => updateMethods.has(property) ? updateArray(property, target, this.state, __privateGet(this, _size)) : Reflect.get(target, property),
19
- set: (target, property, value2) => setValue(target, property, value2, this.state, __privateGet(this, _size))
20
- })
20
+ set: (target, property, value2) => setValueInProxy(
21
+ target,
22
+ property,
23
+ value2,
24
+ this.state,
25
+ true,
26
+ __privateGet(this, _size)
27
+ )
28
+ }),
29
+ options
21
30
  );
22
31
  __privateAdd(this, _size, signal(0));
23
32
  __privateGet(this, _size).set(value.length);
@@ -114,22 +123,8 @@ class ReactiveArray extends Reactive {
114
123
  }
115
124
  }
116
125
  _size = new WeakMap();
117
- function array(value) {
118
- return new ReactiveArray(Array.isArray(value) ? value : []);
119
- }
120
- function setValue(target, property, value, state, length) {
121
- const isIndex = !Number.isNaN(Number(property));
122
- const isLength = property === "length";
123
- if (!isIndex && !isLength) {
124
- return Reflect.set(target, property, value);
125
- }
126
- const previous = Reflect.get(target, property);
127
- if (!Object.is(previous, value)) {
128
- Reflect.set(target, property, value);
129
- emitValue(state);
130
- length.set(target.length);
131
- }
132
- return true;
126
+ function array(value, options) {
127
+ return new ReactiveArray(Array.isArray(value) ? value : [], options);
133
128
  }
134
129
  function updateArray(type, array2, state, length) {
135
130
  const affectsLength = lengthAffectingMethods.has(type);
@@ -139,7 +134,7 @@ function updateArray(type, array2, state, length) {
139
134
  const result = array2[type](
140
135
  ...args
141
136
  );
142
- if (affectsLength ? array2.length !== previousLength : differentArrays(previousArray, array2)) {
137
+ if (affectsLength ? array2.length !== previousLength : !equalArrays(state, previousArray, array2)) {
143
138
  emitValue(state);
144
139
  length.set(array2.length);
145
140
  }
@@ -9,8 +9,8 @@ const helpers_is = require("../helpers/is.cjs");
9
9
  const value_reactive = require("./reactive.cjs");
10
10
  exports.activeComputed = void 0;
11
11
  class Computed extends value_reactive.Reactive {
12
- constructor(callback) {
13
- super(helpers_is.computedName, void 0);
12
+ constructor(callback, options) {
13
+ super(helpers_is.computedName, void 0, options);
14
14
  __publicField(this, "effect", {
15
15
  dirty: true,
16
16
  instance: void 0
@@ -21,7 +21,7 @@ class Computed extends value_reactive.Reactive {
21
21
  exports.activeComputed = this;
22
22
  const value = callback();
23
23
  exports.activeComputed = previousComputed;
24
- if (!Object.is(this.state.value, value)) {
24
+ if (!this.state.equal(this.state.value, value)) {
25
25
  this.state.value = value;
26
26
  for (const computed2 of this.state.computeds) {
27
27
  computed2.effect.dirty = true;
@@ -53,8 +53,8 @@ class Computed extends value_reactive.Reactive {
53
53
  return this.state.value;
54
54
  }
55
55
  }
56
- function computed(callback) {
57
- return new Computed(callback);
56
+ function computed(callback, options) {
57
+ return new Computed(callback, options);
58
58
  }
59
59
  exports.Computed = Computed;
60
60
  exports.computed = computed;
@@ -7,8 +7,8 @@ import { computedName } from "../helpers/is.js";
7
7
  import { Reactive } from "./reactive.js";
8
8
  let activeComputed;
9
9
  class Computed extends Reactive {
10
- constructor(callback) {
11
- super(computedName, void 0);
10
+ constructor(callback, options) {
11
+ super(computedName, void 0, options);
12
12
  __publicField(this, "effect", {
13
13
  dirty: true,
14
14
  instance: void 0
@@ -19,7 +19,7 @@ class Computed extends Reactive {
19
19
  activeComputed = this;
20
20
  const value = callback();
21
21
  activeComputed = previousComputed;
22
- if (!Object.is(this.state.value, value)) {
22
+ if (!this.state.equal(this.state.value, value)) {
23
23
  this.state.value = value;
24
24
  for (const computed2 of this.state.computeds) {
25
25
  computed2.effect.dirty = true;
@@ -51,8 +51,8 @@ class Computed extends Reactive {
51
51
  return this.state.value;
52
52
  }
53
53
  }
54
- function computed(callback) {
55
- return new Computed(callback);
54
+ function computed(callback, options) {
55
+ return new Computed(callback, options);
56
56
  }
57
57
  export {
58
58
  Computed,
@@ -5,14 +5,18 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
5
5
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
6
6
  const subscription = require("../subscription.cjs");
7
7
  class Reactive {
8
- constructor(name, value) {
8
+ constructor(name, value, options) {
9
9
  __publicField(this, "state", {
10
10
  computeds: /* @__PURE__ */ new Set(),
11
11
  effects: /* @__PURE__ */ new Set(),
12
+ equal: Object.is,
12
13
  subscriptions: /* @__PURE__ */ new Map(),
13
14
  value: void 0
14
15
  });
15
16
  this.state.value = value;
17
+ if (typeof options === "object" && typeof options.equal === "function") {
18
+ this.state.equal = options.equal;
19
+ }
16
20
  Object.defineProperty(this, "$mora", {
17
21
  value: name
18
22
  });
@@ -3,14 +3,18 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import { subscribe, unsubscribe } from "../subscription.js";
5
5
  class Reactive {
6
- constructor(name, value) {
6
+ constructor(name, value, options) {
7
7
  __publicField(this, "state", {
8
8
  computeds: /* @__PURE__ */ new Set(),
9
9
  effects: /* @__PURE__ */ new Set(),
10
+ equal: Object.is,
10
11
  subscriptions: /* @__PURE__ */ new Map(),
11
12
  value: void 0
12
13
  });
13
14
  this.state.value = value;
15
+ if (typeof options === "object" && typeof options.equal === "function") {
16
+ this.state.equal = options.equal;
17
+ }
14
18
  Object.defineProperty(this, "$mora", {
15
19
  value: name
16
20
  });
@@ -4,8 +4,8 @@ const helpers_is = require("../helpers/is.cjs");
4
4
  const helpers_value = require("../helpers/value.cjs");
5
5
  const value_reactive = require("./reactive.cjs");
6
6
  class Signal extends value_reactive.Reactive {
7
- constructor(value) {
8
- super(helpers_is.signalName, value);
7
+ constructor(value, options) {
8
+ super(helpers_is.signalName, value, options);
9
9
  }
10
10
  /**
11
11
  * @inheritdoc
@@ -17,7 +17,7 @@ class Signal extends value_reactive.Reactive {
17
17
  * Set the value
18
18
  */
19
19
  set(value) {
20
- if (helpers_value.differentValues(this.state.value, value)) {
20
+ if (!this.state.equal(this.state.value, value)) {
21
21
  this.state.value = value;
22
22
  helpers_value.emitValue(this.state);
23
23
  }
@@ -29,8 +29,8 @@ class Signal extends value_reactive.Reactive {
29
29
  this.set(callback(this.state.value));
30
30
  }
31
31
  }
32
- function signal(value) {
33
- return new Signal(value);
32
+ function signal(value, options) {
33
+ return new Signal(value, options);
34
34
  }
35
35
  exports.Signal = Signal;
36
36
  exports.signal = signal;
@@ -1,9 +1,9 @@
1
1
  import { signalName } from "../helpers/is.js";
2
- import { getValue, differentValues, emitValue } from "../helpers/value.js";
2
+ import { getValue, emitValue } from "../helpers/value.js";
3
3
  import { Reactive } from "./reactive.js";
4
4
  class Signal extends Reactive {
5
- constructor(value) {
6
- super(signalName, value);
5
+ constructor(value, options) {
6
+ super(signalName, value, options);
7
7
  }
8
8
  /**
9
9
  * @inheritdoc
@@ -15,7 +15,7 @@ class Signal extends Reactive {
15
15
  * Set the value
16
16
  */
17
17
  set(value) {
18
- if (differentValues(this.state.value, value)) {
18
+ if (!this.state.equal(this.state.value, value)) {
19
19
  this.state.value = value;
20
20
  emitValue(this.state);
21
21
  }
@@ -27,8 +27,8 @@ class Signal extends Reactive {
27
27
  this.set(callback(this.state.value));
28
28
  }
29
29
  }
30
- function signal(value) {
31
- return new Signal(value);
30
+ function signal(value, options) {
31
+ return new Signal(value, options);
32
32
  }
33
33
  export {
34
34
  Signal,
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const is = require("../node_modules/@oscarpalmer/atoms/dist/internal/is.cjs");
4
+ const helpers_is = require("../helpers/is.cjs");
5
+ const helpers_proxy = require("../helpers/proxy.cjs");
6
+ const helpers_value = require("../helpers/value.cjs");
7
+ const value_reactive = require("./reactive.cjs");
8
+ class Store extends value_reactive.Reactive {
9
+ constructor(value, options) {
10
+ super(
11
+ helpers_is.storeName,
12
+ new Proxy(value, {
13
+ set: (target, property, value2) => helpers_proxy.setValueInProxy(target, property, value2, this.state, false)
14
+ }),
15
+ options
16
+ );
17
+ }
18
+ get(key) {
19
+ return is.isKey(key) ? this.state.value[key] : helpers_value.getValue(this.state);
20
+ }
21
+ peek(key) {
22
+ return is.isKey(key) ? this.state.value[key] : { ...this.state.value };
23
+ }
24
+ set(first, second) {
25
+ if (is.isKey(first)) {
26
+ this.state.value[first] = second;
27
+ } else if (first == null || is.isPlainObject(first)) {
28
+ helpers_proxy.setProxyValue(this.state.value, first ?? {});
29
+ }
30
+ }
31
+ }
32
+ function store(value, options) {
33
+ return new Store(is.isPlainObject(value) ? value : {}, options);
34
+ }
35
+ exports.Store = Store;
36
+ exports.store = store;
@@ -0,0 +1,36 @@
1
+ import { isPlainObject, isKey } from "../node_modules/@oscarpalmer/atoms/dist/internal/is.js";
2
+ import { storeName } from "../helpers/is.js";
3
+ import { setValueInProxy, setProxyValue } from "../helpers/proxy.js";
4
+ import { getValue } from "../helpers/value.js";
5
+ import { Reactive } from "./reactive.js";
6
+ class Store extends Reactive {
7
+ constructor(value, options) {
8
+ super(
9
+ storeName,
10
+ new Proxy(value, {
11
+ set: (target, property, value2) => setValueInProxy(target, property, value2, this.state, false)
12
+ }),
13
+ options
14
+ );
15
+ }
16
+ get(key) {
17
+ return isKey(key) ? this.state.value[key] : getValue(this.state);
18
+ }
19
+ peek(key) {
20
+ return isKey(key) ? this.state.value[key] : { ...this.state.value };
21
+ }
22
+ set(first, second) {
23
+ if (isKey(first)) {
24
+ this.state.value[first] = second;
25
+ } else if (first == null || isPlainObject(first)) {
26
+ setProxyValue(this.state.value, first ?? {});
27
+ }
28
+ }
29
+ }
30
+ function store(value, options) {
31
+ return new Store(isPlainObject(value) ? value : {}, options);
32
+ }
33
+ export {
34
+ Store,
35
+ store
36
+ };
package/package.json CHANGED
@@ -54,5 +54,5 @@
54
54
  },
55
55
  "type": "module",
56
56
  "types": "./types/index.d.ts",
57
- "version": "0.18.0"
57
+ "version": "0.18.1"
58
58
  }
package/src/helpers/is.ts CHANGED
@@ -49,7 +49,7 @@ export function isSignal(value: unknown): value is Signal<unknown> {
49
49
  return isMora<Signal<unknown>>(value, signalName);
50
50
  }
51
51
 
52
- export function isStore(value: unknown): value is Store<unknown> {
52
+ export function isStore(value: unknown): value is Store<PlainObject> {
53
53
  return isMora<Reactive<unknown>>(value, storeName);
54
54
  }
55
55
 
@@ -1,4 +1,3 @@
1
- import {isArrayOrPlainObject} from '@oscarpalmer/atoms/is';
2
1
  import type {ArrayOrPlainObject, PlainObject} from '@oscarpalmer/atoms/models';
3
2
  import {startBatch, stopBatch} from '../batch';
4
3
  import type {ReactiveState} from '../value/reactive';
@@ -3,6 +3,7 @@ import type { ReactiveArray } from '../value/array';
3
3
  import type { Computed } from '../value/computed';
4
4
  import type { Reactive } from '../value/reactive';
5
5
  import type { Signal } from '../value/signal';
6
+ import type { Store } from '../value/store';
6
7
  /**
7
8
  * Is the value a reactive array?
8
9
  */
@@ -20,7 +21,9 @@ export declare function isReactive(value: unknown): value is Reactive<unknown>;
20
21
  * Is the value a signal?
21
22
  */
22
23
  export declare function isSignal(value: unknown): value is Signal<unknown>;
24
+ export declare function isStore(value: unknown): value is Store<unknown>;
23
25
  export declare const arrayName = "array";
24
26
  export declare const computedName = "computed";
25
27
  export declare const effectName = "effect";
26
28
  export declare const signalName = "signal";
29
+ export declare const storeName = "store";
@@ -0,0 +1,5 @@
1
+ import type { ArrayOrPlainObject } from '@oscarpalmer/atoms/models';
2
+ import type { ReactiveState } from '../value/reactive';
3
+ import type { Signal } from '../value/signal';
4
+ export declare function setProxyValue(proxy: ArrayOrPlainObject, value: ArrayOrPlainObject): void;
5
+ export declare function setValueInProxy<Value extends ArrayOrPlainObject, Equal>(target: Value, property: PropertyKey, value: unknown, state: ReactiveState<Value, Equal>, isArray: boolean, length?: Signal<number>): boolean;
@@ -1,5 +1,4 @@
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 emitValue<Value>(state: ReactiveState<Value, never>): void;
3
+ export declare function equalArrays<Value>(state: ReactiveState<Value[], Value>, first: Value[], second: Value[]): boolean;
4
+ export declare function getValue<Value>(state: ReactiveState<Value, never>): Value;
package/types/index.d.ts CHANGED
@@ -5,3 +5,4 @@ export { array, type ReactiveArray } from './value/array';
5
5
  export { computed, type Computed } from './value/computed';
6
6
  export type { Reactive } from './value/reactive';
7
7
  export { signal, type Signal } from './value/signal';
8
+ export { store, type Store } from './value/store';
@@ -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;
@@ -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>;
@@ -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>;
@@ -1,9 +1,9 @@
1
1
  import type { Effect } from '../effect';
2
2
  import { type Subscription, type Unsubscribe } from '../subscription';
3
3
  import type { Computed } from './computed';
4
- export declare abstract class Reactive<Value> {
5
- protected readonly state: ReactiveState<Value>;
6
- constructor(name: string, value: Value);
4
+ export declare abstract class Reactive<Value, Equal = Value> {
5
+ protected readonly state: ReactiveState<Value, Equal>;
6
+ constructor(name: string, value: Value, options?: ReactiveOptions<Equal>);
7
7
  /**
8
8
  * Get the value
9
9
  */
@@ -29,9 +29,16 @@ export declare abstract class Reactive<Value> {
29
29
  */
30
30
  unsubscribe(callback: (value: Value) => void): void;
31
31
  }
32
- export type ReactiveState<Value> = {
32
+ export type ReactiveOptions<Value> = {
33
+ /**
34
+ * Method to compare values for equality
35
+ */
36
+ equal?: (first: Value, second: Value) => boolean;
37
+ };
38
+ export type ReactiveState<Value, Equal> = {
33
39
  computeds: Set<Computed<unknown>>;
34
40
  effects: Set<Effect>;
41
+ equal: (first: Equal, second: Equal) => boolean;
35
42
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
36
43
  value: Value;
37
44
  };
@@ -1,6 +1,6 @@
1
- import { Reactive } from './reactive';
1
+ import { Reactive, type ReactiveOptions } from './reactive';
2
2
  export declare class Signal<Value> extends Reactive<Value> {
3
- constructor(value: Value);
3
+ constructor(value: Value, options?: ReactiveOptions<Value>);
4
4
  /**
5
5
  * @inheritdoc
6
6
  */
@@ -17,4 +17,4 @@ export declare class Signal<Value> extends Reactive<Value> {
17
17
  /**
18
18
  * Create a reactive value
19
19
  */
20
- export declare function signal<Value>(value: Value): Signal<Value>;
20
+ export declare function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value>;
@@ -0,0 +1,45 @@
1
+ import type { Key, PlainObject } from '@oscarpalmer/atoms/models';
2
+ import { Reactive, type ReactiveOptions } from './reactive';
3
+ export declare class Store<Value extends PlainObject> extends Reactive<Value, Value> {
4
+ constructor(value: Value, options?: ReactiveOptions<Value>);
5
+ /**
6
+ * @inheritdoc
7
+ */
8
+ get(): Value;
9
+ /**
10
+ * Get a value by key _(without reactivity)_
11
+ */
12
+ get(key: keyof Value): Value[keyof Value];
13
+ /**
14
+ * Get a value by key _(without reactivity)_
15
+ */
16
+ get(key: Key): unknown;
17
+ /**
18
+ * Get the value _(without reactivity)_
19
+ */
20
+ peek(): Value;
21
+ /**
22
+ * Get a value by key _(without reactivity)_
23
+ */
24
+ peek(key: keyof Value): Value[keyof Value];
25
+ /**
26
+ * Get a value by key _(without reactivity)_
27
+ */
28
+ peek(key: Key): unknown;
29
+ /**
30
+ * Set the value
31
+ */
32
+ set(value?: Value): void;
33
+ /**
34
+ * Set a value by key
35
+ */
36
+ set(key: keyof Value, value: Value[keyof Value]): void;
37
+ /**
38
+ * Set a value by key
39
+ */
40
+ set(key: Key, value: unknown): void;
41
+ }
42
+ /**
43
+ * Create a reactive store
44
+ */
45
+ export declare function store<Value extends PlainObject>(value: Value, options?: ReactiveOptions<Value>): Store<Value>;