@oscarpalmer/mora 0.28.0 → 0.30.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 (42) hide show
  1. package/dist/batch.mjs +15 -6
  2. package/dist/constants.d.mts +0 -1
  3. package/dist/constants.mjs +4 -3
  4. package/dist/effect.d.mts +5 -8
  5. package/dist/effect.mjs +23 -19
  6. package/dist/helpers/is.d.mts +9 -9
  7. package/dist/helpers/is.mjs +6 -0
  8. package/dist/helpers/proxy.d.mts +5 -9
  9. package/dist/helpers/proxy.mjs +4 -4
  10. package/dist/helpers/value.d.mts +3 -3
  11. package/dist/helpers/value.mjs +21 -3
  12. package/dist/index.d.mts +7 -8
  13. package/dist/index.mjs +1 -1
  14. package/dist/models.d.mts +356 -18
  15. package/dist/mora.full.mjs +458 -409
  16. package/dist/subscription.d.mts +1 -9
  17. package/dist/subscription.mjs +14 -15
  18. package/dist/value/array.d.mts +5 -133
  19. package/dist/value/array.mjs +91 -137
  20. package/dist/value/computed.d.mts +4 -12
  21. package/dist/value/computed.mjs +54 -50
  22. package/dist/value/reactive.d.mts +3 -38
  23. package/dist/value/reactive.mjs +10 -49
  24. package/dist/value/signal.d.mts +5 -21
  25. package/dist/value/signal.mjs +27 -49
  26. package/dist/value/store.d.mts +9 -92
  27. package/dist/value/store.mjs +42 -49
  28. package/package.json +8 -8
  29. package/src/batch.ts +22 -9
  30. package/src/constants.ts +3 -4
  31. package/src/effect.ts +31 -26
  32. package/src/helpers/is.ts +11 -10
  33. package/src/helpers/proxy.ts +23 -18
  34. package/src/helpers/value.ts +38 -3
  35. package/src/index.ts +6 -7
  36. package/src/models.ts +431 -16
  37. package/src/subscription.ts +20 -20
  38. package/src/value/array.ts +183 -265
  39. package/src/value/computed.ts +80 -74
  40. package/src/value/reactive.ts +16 -64
  41. package/src/value/signal.ts +34 -71
  42. package/src/value/store.ts +84 -177
@@ -1,15 +1,7 @@
1
1
  import { ReactiveState, Unsubscribe } from "./models.mjs";
2
- import { GenericCallback } from "@oscarpalmer/atoms/models";
3
-
4
2
  //#region src/subscription.d.ts
5
- declare class Subscription {
6
- callback: GenericCallback;
7
- state: ReactiveState<unknown, never>;
8
- constructor(state: ReactiveState<unknown, never>, callback: GenericCallback);
9
- destroy(): void;
10
- }
11
3
  declare function noop(): void;
12
4
  declare function subscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): Unsubscribe;
13
5
  declare function unsubscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): void;
14
6
  //#endregion
15
- export { Subscription, noop, subscribe, unsubscribe };
7
+ export { noop, subscribe, unsubscribe };
@@ -1,28 +1,27 @@
1
1
  //#region src/subscription.ts
2
- var Subscription = class {
3
- callback;
4
- state;
5
- constructor(state, callback) {
6
- this.state = state;
7
- this.callback = callback;
8
- callback(state.value);
9
- }
10
- destroy() {
11
- this.callback = noop;
12
- this.state = void 0;
13
- }
14
- };
15
2
  function noop() {}
16
3
  function subscribe(state, callback) {
17
4
  if (typeof callback !== "function" || state.subscriptions.has(callback)) return noop;
18
- state.subscriptions.set(callback, new Subscription(state, callback));
5
+ state.subscriptions.set(callback, subscription(state, callback));
19
6
  return () => {
20
7
  unsubscribe(state, callback);
21
8
  };
22
9
  }
10
+ function subscription(state, callback) {
11
+ const instance = {
12
+ callback,
13
+ state,
14
+ destroy: () => {
15
+ instance.callback = noop;
16
+ instance.state = void 0;
17
+ }
18
+ };
19
+ callback(state.value);
20
+ return instance;
21
+ }
23
22
  function unsubscribe(state, callback) {
24
23
  state.subscriptions.get(callback)?.destroy();
25
24
  state.subscriptions.delete(callback);
26
25
  }
27
26
  //#endregion
28
- export { Subscription, noop, subscribe, unsubscribe };
27
+ export { noop, subscribe, unsubscribe };
@@ -1,138 +1,8 @@
1
- import { Reactive } from "./reactive.mjs";
2
- import { Computed } from "./computed.mjs";
3
- import { ReactiveOptions, Unsubscribe } from "../models.mjs";
4
- import { PROPERTY_LENGTH } from "../constants.mjs";
5
-
1
+ import { ReactiveArray, ReactiveOptions } from "../models.mjs";
6
2
  //#region src/value/array.d.ts
7
- declare class ReactiveArray<Item> extends Reactive<Item[], Item> {
8
- #private;
9
- /**
10
- * The length of the array
11
- */
12
- get length(): number;
13
- /**
14
- * Set the length of the array
15
- */
16
- set length(value: number);
17
- constructor(value: Item[], options?: ReactiveOptions<Item>);
18
- /**
19
- * Clear the array
20
- */
21
- clear(): void;
22
- /**
23
- * Create a computed, filtered array
24
- * @param callback Callback to evaluate each item
25
- * @return Computed array of filtered items
26
- */
27
- filter(callback: (item: Item, index: number, array: Item[]) => boolean): Computed<Item[]>;
28
- /**
29
- * @inheritdoc
30
- */
31
- get(): Item[];
32
- /**
33
- * Get the value at an index
34
- * @param index Index of item to get _(if negative, starts from the end)_
35
- * @returns Item at index, or `undefined` if it doesn't exist
36
- */
37
- get(index: number): Item | undefined;
38
- /**
39
- * Get the length of the array
40
- * @returns Length of the array
41
- */
42
- get(property: typeof PROPERTY_LENGTH): number;
43
- /**
44
- * Create a computed, mapped array
45
- * @param callback Callback to transform each item
46
- * @return Computed array of mapped items
47
- */
48
- map<Mapped>(callback: (item: Item, index: number, array: Item[]) => Mapped): Computed<Mapped[]>;
49
- /**
50
- * Notify dependents of changes
51
- *
52
- * _This bypasses equality checks and will immediately notify dependents.
53
- * Use this only if you're modifying nested data that would be ignored by equality checks._
54
- */
55
- notify(): void;
56
- /**
57
- * @inheritdoc
58
- */
59
- peek(): Item[];
60
- /**
61
- * Get the value at an index _(without reactivity)_
62
- * @param index Index of item to get _(if negative, starts from the end)_
63
- * @returns Item at index, or `undefined` if it doesn't exist
64
- */
65
- peek(index: number): Item | undefined;
66
- /**
67
- * Get the length of the array _(without reactivity)_
68
- * @returns Length of the array
69
- */
70
- peek(property: typeof PROPERTY_LENGTH): number;
71
- /**
72
- * Remove and return the last item of the array
73
- * @returns Removed item, or `undefined` if the array is empty
74
- */
75
- pop(): Item | undefined;
76
- /**
77
- * Add items to the end of the array
78
- * @param items Items to add
79
- * @returns New array length
80
- */
81
- push(...items: Item[]): number;
82
- /**
83
- * Set the value
84
- * @param value New array of items _(defaults to an empty array)_
85
- */
86
- set(value?: Item[] | (() => null | undefined | Item[] | Promise<null | undefined | Item[]>) | Promise<null | undefined | Item[]>): void;
87
- /**
88
- * Set the value at an index
89
- * @param index Index of item to set __(if negative, starts from the end)_
90
- * @param value New item
91
- */
92
- set(index: number, value: Item | (() => Item | Promise<Item>) | Promise<Item>): void;
93
- /**
94
- * Set the length of the array
95
- * @param value New array length
96
- */
97
- set(property: typeof PROPERTY_LENGTH, value: number): void;
98
- /**
99
- * Remove and return the first item of the array
100
- * @returns Removed item, or `undefined` if the array is empty
101
- */
102
- shift(): Item | undefined;
103
- /**
104
- * Remove and return items from the array _(and optionally add new items)_
105
- * @param from Index to start removing items from
106
- * @param to Index to stop removing items at _(defaults to the end of the array)_
107
- * @param items Optional items to add
108
- * @returns Removed items
109
- */
110
- splice(from: number, to?: number, ...items: Item[]): Item[];
111
- /**
112
- * @inheritdoc
113
- */
114
- subscribe(callback: (value: Item[]) => void): Unsubscribe;
115
- /**
116
- * Subscribe to changes at a specific index
117
- * @param index Index of item to subscribe to
118
- * @param callback Callback for changes
119
- * @returns Unsubscribe callback
120
- */
121
- subscribe(index: number, callback: (value: Item | undefined) => void): Unsubscribe;
122
- /**
123
- * Add items to the beginning of the array
124
- * @param items Items to add
125
- * @returns New array length
126
- */
127
- unshift(...items: Item[]): number;
128
- /**
129
- * Update the value _(based on the current value)_
130
- * @param callback Callback to update the value
131
- */
132
- update(callback: (value: Item[]) => Item[]): void;
133
- }
134
3
  /**
135
4
  * Create a reactive array from a function result
5
+ *
136
6
  * @param value Initial array of items
137
7
  * @param options Reactivity options
138
8
  * @returns Reactive array
@@ -140,6 +10,7 @@ declare class ReactiveArray<Item> extends Reactive<Item[], Item> {
140
10
  declare function array<Item>(value: () => Item[] | Promise<Item[]>, options?: ReactiveOptions<Item>): ReactiveArray<Item>;
141
11
  /**
142
12
  * Create a reactive array from a promise
13
+ *
143
14
  * @param value Initial array of items
144
15
  * @param options Reactivity options
145
16
  * @returns Reactive array
@@ -147,10 +18,11 @@ declare function array<Item>(value: () => Item[] | Promise<Item[]>, options?: Re
147
18
  declare function array<Item>(value: Promise<Item[]>, options?: ReactiveOptions<Item>): ReactiveArray<Item>;
148
19
  /**
149
20
  * Create a reactive array
21
+ *
150
22
  * @param value Initial array of items
151
23
  * @param options Reactivity options
152
24
  * @returns Reactive array
153
25
  */
154
26
  declare function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item>;
155
27
  //#endregion
156
- export { ReactiveArray, array };
28
+ export { array };
@@ -1,139 +1,82 @@
1
- import { METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ARRAY } from "../constants.mjs";
2
- import { noop, subscribe } from "../subscription.mjs";
3
- import { Reactive } from "./reactive.mjs";
1
+ import { METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ARRAY, NAME_MORA } from "../constants.mjs";
2
+ import { emitValue, equalArrays, getSimpleValue } from "../helpers/value.mjs";
3
+ import { subscribe, unsubscribe } from "../subscription.mjs";
4
+ import { reactive } from "./reactive.mjs";
4
5
  import { computed } from "./computed.mjs";
5
- import { emitValue, equalArrays, getValue } from "../helpers/value.mjs";
6
6
  import { emityProxyValues, getReactiveValueInProxy, setProxyValue, setValueInProxy } from "../helpers/proxy.mjs";
7
7
  import { signal } from "./signal.mjs";
8
+ import { select } from "@oscarpalmer/atoms/array";
9
+ import { filter } from "@oscarpalmer/atoms/array/filter";
10
+ import { noop } from "@oscarpalmer/atoms/function";
8
11
  //#region src/value/array.ts
9
- var ReactiveArray = class extends Reactive {
10
- #indiced = /* @__PURE__ */ new Map();
11
- #size = signal(0);
12
- /**
13
- * The length of the array
14
- */
15
- get length() {
16
- return this.#size.get();
17
- }
18
- /**
19
- * Set the length of the array
20
- */
21
- set length(value) {
22
- if (typeof value === "number" && value >= 0 && value !== this.state.value.length) this.get().length = value;
23
- }
24
- constructor(value, options) {
25
- super(NAME_ARRAY, new Proxy(value, {
26
- get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(property, target, this.state, this.#size) : Reflect.get(target, property),
27
- set: (target, property, value) => setValueInProxy({
28
- property,
29
- target,
30
- value,
31
- isArray: true,
32
- state: this.state,
33
- length: this.#size
34
- })
35
- }), options);
36
- this.#size.set(value.length);
37
- }
38
- /**
39
- * Clear the array
40
- */
41
- clear() {
42
- this.length = 0;
43
- }
44
- /**
45
- * Create a computed, filtered array
46
- * @param callback Callback to evaluate each item
47
- * @return Computed array of filtered items
48
- */
49
- filter(callback) {
50
- return computed(() => this.get().filter(callback));
51
- }
52
- get(first) {
53
- if (typeof first === "number") return getReactiveValueInProxy(this, this.#indiced, first, true).get();
54
- return first === "length" ? this.length : getValue(this.state);
55
- }
56
- /**
57
- * Create a computed, mapped array
58
- * @param callback Callback to transform each item
59
- * @return Computed array of mapped items
60
- */
61
- map(callback) {
62
- return computed(() => this.get().map(callback));
63
- }
64
- /**
65
- * Notify dependents of changes
66
- *
67
- * _This bypasses equality checks and will immediately notify dependents.
68
- * Use this only if you're modifying nested data that would be ignored by equality checks._
69
- */
70
- notify() {
71
- emityProxyValues(this.state, this.#indiced);
72
- }
73
- peek(value) {
74
- if (value === "length") return this.#size.peek();
75
- return typeof value === "number" ? this.state.value.at(value) : this.state.value.slice();
76
- }
77
- /**
78
- * Remove and return the last item of the array
79
- * @returns Removed item, or `undefined` if the array is empty
80
- */
81
- pop() {
82
- return this.state.value.pop();
83
- }
84
- /**
85
- * Add items to the end of the array
86
- * @param items Items to add
87
- * @returns New array length
88
- */
89
- push(...items) {
90
- return this.state.value.push(...items);
91
- }
92
- set(first, second) {
93
- setProxyValue(true, this.state, isArrayValue, isArrayIndex, setArray, setAtIndex, first, second);
94
- }
95
- /**
96
- * Remove and return the first item of the array
97
- * @returns Removed item, or `undefined` if the array is empty
98
- */
99
- shift() {
100
- return this.state.value.shift();
101
- }
102
- /**
103
- * Remove and return items from the array _(and optionally add new items)_
104
- * @param from Index to start removing items from
105
- * @param to Index to stop removing items at _(defaults to the end of the array)_
106
- * @param items Optional items to add
107
- * @returns Removed items
108
- */
109
- splice(from, to, ...items) {
110
- return this.state.value.splice(from, to ?? this.state.value.length, ...items);
111
- }
112
- subscribe(first, second) {
113
- if (typeof first === "number" && typeof second === "function") return getReactiveValueInProxy(this, this.#indiced, first, true).subscribe(second);
114
- return typeof first === "function" ? subscribe(this.state, first) : noop;
115
- }
116
- /**
117
- * Add items to the beginning of the array
118
- * @param items Items to add
119
- * @returns New array length
120
- */
121
- unshift(...items) {
122
- return this.state.value.unshift(...items);
123
- }
124
- /**
125
- * Update the value _(based on the current value)_
126
- * @param callback Callback to update the value
127
- */
128
- update(callback) {
129
- const updated = callback(this.state.value);
130
- if (updated == null || Array.isArray(updated)) this.set(updated);
131
- }
132
- };
133
12
  function array(value, options) {
134
- const instance = new ReactiveArray([], options);
13
+ const [rx, state] = reactive([], options);
14
+ const indiced = /* @__PURE__ */ new Map();
15
+ const length = signal(0);
16
+ state.value = new Proxy([], {
17
+ get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(property, target, state, length) : Reflect.get(target, property),
18
+ set: (target, property, value) => setValueInProxy({
19
+ length,
20
+ property,
21
+ state,
22
+ target,
23
+ value,
24
+ isArray: true
25
+ })
26
+ });
27
+ function get(value) {
28
+ return getArrayValue(instance, indiced, state, length, value);
29
+ }
30
+ const instance = {
31
+ ...rx,
32
+ length: state.value.length,
33
+ at: (index) => get(index),
34
+ clear: () => {
35
+ state.value.length = 0;
36
+ },
37
+ filter: (callback) => computed(() => filter(get(), callback)),
38
+ get: (value) => get(value),
39
+ map: (callback) => computed(() => get().map(callback)),
40
+ notify: () => {
41
+ emityProxyValues(state, indiced);
42
+ },
43
+ peek: (value) => peekArrayValue(state, length, value),
44
+ pop: () => state.value.pop(),
45
+ push: (...items) => state.value.push(...items),
46
+ select: (filter, map) => computed(() => select(get(), filter, map)),
47
+ set: (first, second) => {
48
+ setProxyValue(true, state, isArrayValue, isArrayIndex, setArray, setAtIndex, first, second);
49
+ },
50
+ shift: () => state.value.shift(),
51
+ splice: (from, to, ...items) => state.value.splice(from, to ?? state.value.length, ...items),
52
+ subscribe: (first, second) => {
53
+ if (typeof first === "number" && typeof second === "function") return getReactiveValueInProxy(instance, indiced, first, true).subscribe(second);
54
+ return typeof first === "function" ? subscribe(state, first) : noop;
55
+ },
56
+ unshift: (...items) => state.value.unshift(...items),
57
+ unsubscribe: (first, second) => {
58
+ if (typeof first === "number" && typeof second === "function") getReactiveValueInProxy(instance, indiced, first, true)?.unsubscribe(second);
59
+ else if (typeof first === "function") unsubscribe(state, first);
60
+ },
61
+ update: (callback) => updateArrayValue(instance, state, callback)
62
+ };
63
+ Object.defineProperties(instance, {
64
+ [NAME_MORA]: {
65
+ enumerable: false,
66
+ value: NAME_ARRAY
67
+ },
68
+ length: {
69
+ enumerable: true,
70
+ get: () => length.get(),
71
+ set: (value) => setArrayLength(state, value)
72
+ }
73
+ });
135
74
  instance.set(value);
136
- return instance;
75
+ return Object.freeze(instance);
76
+ }
77
+ function getArrayValue(instance, indiced, state, length, first) {
78
+ if (typeof first === "number") return getReactiveValueInProxy(instance, indiced, first, true).get();
79
+ return first === "length" ? length.get() : getSimpleValue(state);
137
80
  }
138
81
  function isArrayIndex(value) {
139
82
  return typeof value === "number";
@@ -141,6 +84,20 @@ function isArrayIndex(value) {
141
84
  function isArrayValue(value) {
142
85
  return value == null || Array.isArray(value);
143
86
  }
87
+ function peekArrayValue(state, length, value) {
88
+ if (value === "length") return length.peek();
89
+ return typeof value === "number" ? state.value.at(value) : state.value.slice();
90
+ }
91
+ function setArray(state, value) {
92
+ state.value.splice(0, state.value.length, ...value ?? []);
93
+ }
94
+ function setArrayLength(state, value) {
95
+ if (typeof value === "number" && value >= 0 && value !== state.value.length) state.value.length = value;
96
+ }
97
+ function setAtIndex(state, index, value) {
98
+ const actual = index < 0 ? state.value.length + index : index;
99
+ if (actual > -1) state.value[actual] = value;
100
+ }
144
101
  function updateArray(type, array, state, length) {
145
102
  const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
146
103
  const previousArray = affectsLength ? [] : array.slice();
@@ -154,12 +111,9 @@ function updateArray(type, array, state, length) {
154
111
  return result;
155
112
  };
156
113
  }
157
- function setArray(state, value) {
158
- state.value.splice(0, state.value.length, ...value ?? []);
159
- }
160
- function setAtIndex(state, index, value) {
161
- const actual = index < 0 ? state.value.length + index : index;
162
- if (actual > -1) state.value[actual] = value;
114
+ function updateArrayValue(instance, state, callback) {
115
+ const updated = callback(state.value);
116
+ if (updated == null || Array.isArray(updated)) instance.set(updated);
163
117
  }
164
118
  //#endregion
165
- export { ReactiveArray, array };
119
+ export { array };
@@ -1,21 +1,13 @@
1
- import { Reactive } from "./reactive.mjs";
2
- import { ReactiveOptions } from "../models.mjs";
3
-
1
+ import { Computed, ComputedEffect, ReactiveOptions } from "../models.mjs";
4
2
  //#region src/value/computed.d.ts
5
- declare class Computed<Value> extends Reactive<Value> {
6
- private readonly effect;
7
- constructor(callback: () => Value | Promise<Value>, options?: ReactiveOptions<Value>);
8
- /**
9
- * @inheritdoc
10
- */
11
- get(): Value;
12
- }
13
3
  /**
14
4
  * Create a computed value
5
+ *
15
6
  * @param callback Callback to compute the value
16
7
  * @param options Reactivity options
17
8
  * @returns Computed value
18
9
  */
19
10
  declare function computed<Value>(callback: () => Value | Promise<Value>, options?: ReactiveOptions<Value>): Computed<Value>;
11
+ declare function internalComputed<Value>(callback: () => Value | Promise<Value>, options?: ReactiveOptions<Value>): [Computed<Value>, ComputedEffect];
20
12
  //#endregion
21
- export { Computed, computed };
13
+ export { computed, internalComputed };
@@ -1,68 +1,72 @@
1
- import { ACTIVE, BATCH, NAME_COMPUTED } from "../constants.mjs";
2
- import { effect, runEffect } from "../effect.mjs";
1
+ import { ACTIVE, BATCH, NAME_COMPUTED, NAME_MORA } from "../constants.mjs";
2
+ import { internalEffect, runEffect } from "../effect.mjs";
3
3
  import { flushHandlers } from "../batch.mjs";
4
- import { Reactive } from "./reactive.mjs";
4
+ import { handleSimpleValue } from "../helpers/value.mjs";
5
+ import { subscribe } from "../subscription.mjs";
6
+ import { reactive } from "./reactive.mjs";
5
7
  //#region src/value/computed.ts
6
- var Computed = class extends Reactive {
7
- effect = {
8
- dirty: true,
9
- instance: void 0
10
- };
11
- constructor(callback, options) {
12
- super(NAME_COMPUTED, void 0, options);
13
- this.effect.instance = effect(() => {
14
- if (this.effect.dirty) {
15
- setValue(this, this.state, callback);
16
- this.effect.dirty = false;
17
- }
18
- });
19
- }
20
- /**
21
- * @inheritdoc
22
- */
23
- get() {
24
- if (ACTIVE.computed != null && this !== ACTIVE.computed) this.state.computeds.add(ACTIVE.computed);
25
- if (ACTIVE.effect != null && ACTIVE.effect !== this.effect.instance) this.state.effects.add(ACTIVE.effect);
26
- if (this.effect.dirty && BATCH.depth === 0) runEffect(this.effect.instance);
27
- return this.state.value;
28
- }
29
- };
30
8
  /**
31
9
  * Create a computed value
10
+ *
32
11
  * @param callback Callback to compute the value
33
12
  * @param options Reactivity options
34
13
  * @returns Computed value
35
14
  */
36
15
  function computed(callback, options) {
37
- return new Computed(callback, options);
16
+ return getComputed(callback, options)[0];
17
+ }
18
+ function getComputed(callback, options) {
19
+ const [rx, state] = reactive(void 0, options);
20
+ let fx;
21
+ const instance = {
22
+ ...rx,
23
+ get: () => getValue(state, fx),
24
+ peek: () => state.value,
25
+ subscribe: (callback) => subscribe(state, callback),
26
+ unsubscribe: (callback) => {
27
+ state.subscriptions.delete(callback);
28
+ }
29
+ };
30
+ Object.defineProperty(instance, NAME_MORA, {
31
+ enumerable: false,
32
+ value: NAME_COMPUTED
33
+ });
34
+ fx = getComputedEffect(state, callback);
35
+ return [Object.freeze(instance), fx];
36
+ }
37
+ function getComputedEffect(state, callback) {
38
+ const fx = {
39
+ dirty: true,
40
+ instance: void 0
41
+ };
42
+ fx.instance = internalEffect(() => {
43
+ if (fx.dirty) {
44
+ const previousComputed = ACTIVE.computed;
45
+ ACTIVE.computed = fx;
46
+ handleSimpleValue(state, callback, setAndEmit, () => {
47
+ ACTIVE.computed = previousComputed;
48
+ });
49
+ fx.dirty = false;
50
+ }
51
+ });
52
+ return fx;
53
+ }
54
+ function getValue(state, fx) {
55
+ if (ACTIVE.computed != null && fx !== ACTIVE.computed) state.computeds.add(ACTIVE.computed);
56
+ if (ACTIVE.effect != null && ACTIVE.effect !== fx.instance) state.effects.add(ACTIVE.effect);
57
+ if (fx.dirty && BATCH.depth === 0) runEffect(fx.instance);
58
+ return state.value;
59
+ }
60
+ function internalComputed(callback, options) {
61
+ return getComputed(callback, options);
38
62
  }
39
63
  function setAndEmit(state, value) {
40
64
  if (state.equal(state.value, value)) return;
41
65
  state.value = value;
42
- for (const computed of state.computeds) computed.effect.dirty = true;
66
+ for (const computed of state.computeds) computed.dirty = true;
43
67
  for (const effect of state.effects) BATCH.handlers.add(effect);
44
68
  for (const [, subscription] of state.subscriptions) subscription.callback(value);
45
69
  flushHandlers();
46
70
  }
47
- function setValue(instance, state, callback) {
48
- const previousComputed = ACTIVE.computed;
49
- ACTIVE.computed = instance;
50
- try {
51
- const value = callback();
52
- if (value instanceof Promise) {
53
- state.promise = value;
54
- value.then((resolvedValue) => {
55
- if (state.promise === value) {
56
- state.promise = void 0;
57
- setAndEmit(state, resolvedValue);
58
- }
59
- }).catch(() => {
60
- if (state.promise === value) state.promise = void 0;
61
- });
62
- } else setAndEmit(state, value);
63
- } finally {
64
- ACTIVE.computed = previousComputed;
65
- }
66
- }
67
71
  //#endregion
68
- export { Computed, computed };
72
+ export { computed, internalComputed };
@@ -1,40 +1,5 @@
1
- import { ReactiveOptions, ReactiveState, Unsubscribe } from "../models.mjs";
2
-
1
+ import { Reactive, ReactiveOptions, ReactiveState } from "../models.mjs";
3
2
  //#region src/value/reactive.d.ts
4
- declare abstract class Reactive<Value, Equal = Value> {
5
- protected readonly state: ReactiveState<Value, Equal>;
6
- constructor(name: string, value: Value, options?: ReactiveOptions<Equal>);
7
- /**
8
- * Get the value
9
- * @return Current value
10
- */
11
- abstract get(): Value;
12
- /**
13
- * Get the value _(without reactivity)_
14
- * @return Current value
15
- */
16
- peek(): Value;
17
- /**
18
- * Subscribe to changes
19
- * @param callback Callback for changes
20
- * @return Unsubscribe callback
21
- */
22
- subscribe(callback: (value: Value) => void): Unsubscribe;
23
- /**
24
- * JSON representation of the value
25
- * @return JSON value
26
- */
27
- toJSON(): Value;
28
- /**
29
- * String representation of the value
30
- * @return Value as string
31
- */
32
- toString(): string;
33
- /**
34
- * Unsubscribe from changes
35
- * @param callback Callback to unsubscribe
36
- */
37
- unsubscribe(callback: (value: Value) => void): void;
38
- }
3
+ declare function reactive<Value, Equal = Value>(value: Value, options?: ReactiveOptions<Equal>): [Reactive<Value>, ReactiveState<Value, Equal>];
39
4
  //#endregion
40
- export { Reactive };
5
+ export { reactive };