@oscarpalmer/mora 0.26.0 → 0.28.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 (46) hide show
  1. package/dist/batch.d.mts +14 -0
  2. package/dist/{batch.js → batch.mjs} +13 -3
  3. package/dist/constants.d.mts +20 -0
  4. package/dist/{constants.js → constants.mjs} +2 -0
  5. package/dist/effect.d.mts +17 -0
  6. package/dist/{effect.js → effect.mjs} +11 -4
  7. package/dist/helpers/is.d.mts +47 -0
  8. package/dist/helpers/is.mjs +55 -0
  9. package/dist/helpers/proxy.d.mts +15 -0
  10. package/dist/helpers/proxy.mjs +72 -0
  11. package/dist/helpers/value.d.mts +8 -0
  12. package/dist/helpers/{value.js → value.mjs} +4 -2
  13. package/dist/index.d.mts +10 -0
  14. package/dist/index.mjs +8 -0
  15. package/dist/models.d.mts +62 -0
  16. package/dist/models.mjs +1 -0
  17. package/dist/{mora.full.js → mora.full.mjs} +206 -106
  18. package/dist/subscription.d.mts +15 -0
  19. package/dist/{subscription.js → subscription.mjs} +2 -0
  20. package/dist/value/array.d.mts +156 -0
  21. package/dist/value/array.mjs +165 -0
  22. package/dist/value/computed.d.mts +21 -0
  23. package/dist/value/computed.mjs +68 -0
  24. package/dist/value/reactive.d.mts +40 -0
  25. package/dist/value/{reactive.js → reactive.mjs} +25 -2
  26. package/dist/value/signal.d.mts +44 -0
  27. package/dist/value/signal.mjs +59 -0
  28. package/dist/value/store.d.mts +112 -0
  29. package/dist/value/store.mjs +81 -0
  30. package/package.json +41 -35
  31. package/src/constants.ts +1 -6
  32. package/src/helpers/is.ts +1 -1
  33. package/src/helpers/proxy.ts +64 -17
  34. package/src/models.ts +3 -1
  35. package/src/value/array.ts +79 -23
  36. package/src/value/computed.ts +65 -30
  37. package/src/value/signal.ts +77 -9
  38. package/src/value/store.ts +101 -12
  39. package/dist/helpers/is.js +0 -23
  40. package/dist/helpers/proxy.js +0 -48
  41. package/dist/index.js +0 -8
  42. package/dist/models.js +0 -0
  43. package/dist/value/array.js +0 -100
  44. package/dist/value/computed.js +0 -36
  45. package/dist/value/signal.js +0 -24
  46. package/dist/value/store.js +0 -43
@@ -1,6 +1,7 @@
1
+ import {flushHandlers} from '../batch';
1
2
  import {ACTIVE, BATCH, NAME_COMPUTED} from '../constants';
2
3
  import {effect, runEffect} from '../effect';
3
- import type {ComputedEffect, ReactiveOptions} from '../models';
4
+ import type {ComputedEffect, InternalComputed, ReactiveOptions, ReactiveState} from '../models';
4
5
  import {Reactive} from './reactive';
5
6
 
6
7
  export class Computed<Value> extends Reactive<Value> {
@@ -9,39 +10,15 @@ export class Computed<Value> extends Reactive<Value> {
9
10
  instance: undefined as never,
10
11
  };
11
12
 
12
- constructor(callback: () => Value, options?: ReactiveOptions<Value>) {
13
+ constructor(callback: () => Value | Promise<Value>, options?: ReactiveOptions<Value>) {
13
14
  super(NAME_COMPUTED, undefined as never, options);
14
15
 
15
16
  this.effect.instance = effect(() => {
16
- if (!this.effect.dirty) {
17
- return;
18
- }
19
-
20
- const previousComputed = ACTIVE.computed;
21
-
22
- ACTIVE.computed = this as never;
23
-
24
- const value = callback();
25
-
26
- ACTIVE.computed = previousComputed;
27
-
28
- if (!this.state.equal(this.state.value, value)) {
29
- this.state.value = value;
17
+ if (this.effect.dirty) {
18
+ setValue(this, this.state, callback);
30
19
 
31
- for (const computed of this.state.computeds) {
32
- computed.effect.dirty = true;
33
- }
34
-
35
- for (const effect of this.state.effects) {
36
- BATCH.handlers.add(effect);
37
- }
38
-
39
- for (const [, subscription] of this.state.subscriptions) {
40
- subscription.callback(value);
41
- }
20
+ this.effect.dirty = false;
42
21
  }
43
-
44
- this.effect.dirty = false;
45
22
  });
46
23
  }
47
24
 
@@ -72,8 +49,66 @@ export class Computed<Value> extends Reactive<Value> {
72
49
  * @returns Computed value
73
50
  */
74
51
  export function computed<Value>(
75
- callback: () => Value,
52
+ callback: () => Value | Promise<Value>,
76
53
  options?: ReactiveOptions<Value>,
77
54
  ): Computed<Value> {
78
55
  return new Computed(callback, options);
79
56
  }
57
+
58
+ function setAndEmit<Value>(state: ReactiveState<Value, Value>, value: Value): void {
59
+ if (state.equal(state.value, value)) {
60
+ return;
61
+ }
62
+
63
+ state.value = value;
64
+
65
+ for (const computed of state.computeds) {
66
+ (computed as unknown as InternalComputed).effect.dirty = true;
67
+ }
68
+
69
+ for (const effect of state.effects) {
70
+ BATCH.handlers.add(effect);
71
+ }
72
+
73
+ for (const [, subscription] of state.subscriptions) {
74
+ subscription.callback(value);
75
+ }
76
+
77
+ flushHandlers();
78
+ }
79
+
80
+ function setValue<Value>(
81
+ instance: Computed<Value>,
82
+ state: ReactiveState<Value, Value>,
83
+ callback: () => Value | Promise<Value>,
84
+ ): void {
85
+ const previousComputed = ACTIVE.computed;
86
+
87
+ ACTIVE.computed = instance as never;
88
+
89
+ try {
90
+ const value = callback();
91
+
92
+ if (value instanceof Promise) {
93
+ state.promise = value;
94
+
95
+ value
96
+ .then(resolvedValue => {
97
+ if (state.promise === value) {
98
+ state.promise = undefined;
99
+
100
+ setAndEmit(state, resolvedValue);
101
+ }
102
+ })
103
+ .catch(() => {
104
+ if (state.promise === value) {
105
+ state.promise = undefined;
106
+ }
107
+ });
108
+ } else {
109
+ setAndEmit(state, value);
110
+ }
111
+ } finally {
112
+ ACTIVE.computed = previousComputed;
113
+ }
114
+ }
@@ -1,6 +1,6 @@
1
1
  import {NAME_SIGNAL} from '../constants';
2
2
  import {emitValue, getValue} from '../helpers/value';
3
- import type {ReactiveOptions} from '../models';
3
+ import type {ReactiveOptions, ReactiveState} from '../models';
4
4
  import {Reactive} from './reactive';
5
5
 
6
6
  export class Signal<Value> extends Reactive<Value> {
@@ -19,12 +19,8 @@ export class Signal<Value> extends Reactive<Value> {
19
19
  * Set the value
20
20
  * @param value New value
21
21
  */
22
- set(value: Value): void {
23
- if (!this.state.equal(this.state.value, value)) {
24
- this.state.value = value;
25
-
26
- emitValue(this.state);
27
- }
22
+ set(value: Value | (() => Value | Promise<Value>) | Promise<Value>): void {
23
+ setValue<Value>(this.state, value);
28
24
  }
29
25
 
30
26
  /**
@@ -36,12 +32,84 @@ export class Signal<Value> extends Reactive<Value> {
36
32
  }
37
33
  }
38
34
 
35
+ function setAndEmit<Value>(state: ReactiveState<Value, Value>, value: Value): void {
36
+ if (!state.equal(state.value, value)) {
37
+ state.value = value;
38
+
39
+ emitValue(state);
40
+ }
41
+ }
42
+
43
+ function setValue<Value>(
44
+ state: ReactiveState<Value, Value>,
45
+ value: Value | (() => Value | Promise<Value>) | Promise<Value>,
46
+ ): void {
47
+ try {
48
+ let actual = value;
49
+
50
+ if (typeof value === 'function') {
51
+ actual = (value as () => Value | Promise<Value>)() as Value | Promise<Value>;
52
+ }
53
+
54
+ if (actual instanceof Promise) {
55
+ state.promise = actual;
56
+
57
+ void actual
58
+ .then(value => {
59
+ if (actual === state.promise) {
60
+ state.promise = undefined;
61
+
62
+ setAndEmit(state, value);
63
+ }
64
+ })
65
+ .catch(() => {
66
+ if (actual === state.promise) {
67
+ state.promise = undefined;
68
+ }
69
+ });
70
+ } else {
71
+ setAndEmit(state, actual as Value);
72
+ }
73
+ } catch {}
74
+ }
75
+
76
+ /**
77
+ * Create a reactive value from a function result
78
+ * @param value Initial value
79
+ * @param options Reactivity options
80
+ * @returns Reactive value
81
+ */
82
+ export function signal<Value>(
83
+ value: () => Value | Promise<Value>,
84
+ options?: ReactiveOptions<Value>,
85
+ ): Signal<Value>;
86
+
87
+ /**
88
+ * Create a reactive value from a promise
89
+ * @param value Initial value
90
+ * @param options Reactivity options
91
+ * @returns Reactive value
92
+ */
93
+ export function signal<Value>(
94
+ value: Promise<Value>,
95
+ options?: ReactiveOptions<Value>,
96
+ ): Signal<Value>;
97
+
39
98
  /**
40
99
  * Create a reactive value
41
100
  * @param value Initial value
42
101
  * @param options Reactivity options
43
102
  * @returns Reactive value
44
103
  */
45
- export function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value> {
46
- return new Signal<Value>(value, options);
104
+ export function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value>;
105
+
106
+ export function signal<Value>(
107
+ value: Value | (() => Value | Promise<Value>) | Promise<Value>,
108
+ options?: ReactiveOptions<Value>,
109
+ ): Signal<Value> {
110
+ const instance = new Signal<Value>(undefined as unknown as Value, options);
111
+
112
+ instance.set(value);
113
+
114
+ return instance;
47
115
  }
@@ -1,14 +1,15 @@
1
1
  import {isKey, isPlainObject} from '@oscarpalmer/atoms/is';
2
2
  import type {GenericCallback, Key, PlainObject} from '@oscarpalmer/atoms/models';
3
+ import {startBatch, stopBatch} from '../batch';
3
4
  import {NAME_STORE} from '../constants';
4
5
  import {
5
- getReactiveValueInProxy,
6
6
  emityProxyValues,
7
+ getReactiveValueInProxy,
7
8
  setProxyValue,
8
9
  setValueInProxy,
9
10
  } from '../helpers/proxy';
10
11
  import {getValue} from '../helpers/value';
11
- import type {ReactiveOptions, Unsubscribe} from '../models';
12
+ import type {ReactiveOptions, ReactiveState, Unsubscribe} from '../models';
12
13
  import {noop, subscribe} from '../subscription';
13
14
  import type {Computed} from './computed';
14
15
  import {Reactive} from './reactive';
@@ -96,14 +97,22 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
96
97
  * Set the value
97
98
  * @param value New value _(defaults to an empty object)_
98
99
  */
99
- set(value?: Value): void;
100
+ set(
101
+ value?:
102
+ | Value
103
+ | (() => null | undefined | Value | Promise<null | undefined | Value>)
104
+ | Promise<null | undefined | Value>,
105
+ ): void;
100
106
 
101
107
  /**
102
108
  * Set a value by key
103
109
  * @param key Key of the value to set
104
110
  * @param value New value
105
111
  */
106
- set<Key extends keyof Value>(key: Key, value: Value[Key]): void;
112
+ set<Key extends keyof Value>(
113
+ key: Key,
114
+ value: Value[Key] | (() => Value[Key] | Promise<Value[Key]>) | Promise<Value[Key]>,
115
+ ): void;
107
116
 
108
117
  /**
109
118
  * Set a value by key
@@ -113,11 +122,16 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
113
122
  set(key: Key, value: unknown): void;
114
123
 
115
124
  set(first?: unknown, second?: unknown): void {
116
- if (isKey(first)) {
117
- (this.state.value as PlainObject)[first] = second;
118
- } else if (first == null || isPlainObject(first)) {
119
- setProxyValue(this.state.value, first ?? {});
120
- }
125
+ setProxyValue<Value>(
126
+ false,
127
+ this.state,
128
+ isStoreObject,
129
+ isKey,
130
+ setObject,
131
+ setProperty,
132
+ first,
133
+ second,
134
+ );
121
135
  }
122
136
 
123
137
  /**
@@ -157,14 +171,80 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
157
171
  * @param callback Callback to update the value
158
172
  */
159
173
  update(callback: (value: Value) => Value): void {
160
- const updated = callback({...this.state.value});
174
+ const updated = callback(this.state.value);
161
175
 
162
176
  if (updated == null || isPlainObject(updated)) {
163
- setProxyValue(this.state.value, updated ?? {});
177
+ setObject(this.state, updated);
164
178
  }
165
179
  }
166
180
  }
167
181
 
182
+ function isStoreObject<Value extends PlainObject>(value: unknown): value is Value | undefined {
183
+ return value == null || isPlainObject(value);
184
+ }
185
+
186
+ function setObject(state: ReactiveState<PlainObject, never>, value: PlainObject | undefined): void {
187
+ startBatch();
188
+
189
+ const actual = value ?? {};
190
+ const proxy = state.value as PlainObject;
191
+
192
+ const proxyKeys = Object.keys(proxy);
193
+ const actualKeys = Object.keys(actual);
194
+
195
+ let {length} = proxyKeys;
196
+
197
+ for (let index = 0; index < length; index += 1) {
198
+ const key = proxyKeys[index];
199
+
200
+ proxy[key] = actualKeys.includes(key) ? actual[key] : undefined;
201
+ }
202
+
203
+ length = actualKeys.length;
204
+
205
+ for (let index = 0; index < length; index += 1) {
206
+ const key = actualKeys[index];
207
+
208
+ if (!proxyKeys.includes(key)) {
209
+ const keyedValue = actual[key];
210
+
211
+ proxy[key] = keyedValue;
212
+ }
213
+ }
214
+
215
+ stopBatch();
216
+ }
217
+
218
+ function setProperty<Value extends PlainObject>(
219
+ state: ReactiveState<Value, Value>,
220
+ key: unknown,
221
+ value: unknown,
222
+ ): void {
223
+ (state.value as PlainObject)[key as Key] = value;
224
+ }
225
+
226
+ /**
227
+ * Create a reactive store from a function result
228
+ * @param value Initial object value
229
+ * @param options Reactivity options
230
+ * @returns Reactive store
231
+ */
232
+ export function store<Value extends PlainObject>(
233
+ value: () => Value | Promise<Value>,
234
+ options?: ReactiveOptions<Value>,
235
+ ): Store<Value>;
236
+
237
+ /**
238
+ * Create a reactive store from a promise
239
+ * @param value Initial object value
240
+ * @param options Reactivity options
241
+ * @returns Reactive store
242
+ */
243
+ export function store<Value extends PlainObject>(
244
+ value: Promise<Value>,
245
+ options?: ReactiveOptions<Value>,
246
+ ): Store<Value>;
247
+
168
248
  /**
169
249
  * Create a reactive store
170
250
  * @param value Initial object value
@@ -174,6 +254,15 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
174
254
  export function store<Value extends PlainObject>(
175
255
  value: Value,
176
256
  options?: ReactiveOptions<Value>,
257
+ ): Store<Value>;
258
+
259
+ export function store<Value extends PlainObject>(
260
+ value: Value | (() => Value | Promise<Value>) | Promise<Value>,
261
+ options?: ReactiveOptions<Value>,
177
262
  ): Store<Value> {
178
- return new Store((isPlainObject(value) ? value : {}) as Value, options);
263
+ const instance = new Store({} as unknown as Value, options);
264
+
265
+ instance.set(value);
266
+
267
+ return instance;
179
268
  }
@@ -1,23 +0,0 @@
1
- import { NAME_ALL, NAME_ARRAY, NAME_COMPUTED, NAME_EFFECT, NAME_MORA, NAME_SIGNAL, NAME_STORE } from "../constants.js";
2
- function isArray(value) {
3
- return isMora(value, NAME_ARRAY);
4
- }
5
- function isComputed(value) {
6
- return isMora(value, NAME_COMPUTED);
7
- }
8
- function isEffect(value) {
9
- return isMora(value, NAME_EFFECT);
10
- }
11
- function isMora(value, name) {
12
- return typeof value === "object" && value != null && "$mora" in value && (typeof name === "string" ? value["$mora"] === name : name.has(value["$mora"]));
13
- }
14
- function isReactive(value) {
15
- return isMora(value, NAME_ALL);
16
- }
17
- function isSignal(value) {
18
- return isMora(value, NAME_SIGNAL);
19
- }
20
- function isStore(value) {
21
- return isMora(value, NAME_STORE);
22
- }
23
- export { isArray, isComputed, isEffect, isReactive, isSignal, isStore };
@@ -1,48 +0,0 @@
1
- import { PROPERTY_LENGTH } from "../constants.js";
2
- import { startBatch, stopBatch } from "../batch.js";
3
- import { computed } from "../value/computed.js";
4
- import { emitValue } from "./value.js";
5
- function emityProxyValues(state, mapped) {
6
- const values = [...mapped.values()];
7
- const { length } = values;
8
- for (let index = 0; index < length; index += 1) values[index].effect.dirty = true;
9
- emitValue(state);
10
- }
11
- function getReactiveValueInProxy(reactive, mapped, key, isArray) {
12
- let item = mapped.get(key);
13
- if (item == null) {
14
- item = computed(() => isArray ? reactive.get().at(key) : reactive.get()[key]);
15
- mapped.set(key, item);
16
- }
17
- return item;
18
- }
19
- function setProxyValue(proxy, value) {
20
- startBatch();
21
- const proxyKeys = Object.keys(proxy);
22
- const valueKeys = Object.keys(value);
23
- let { length } = proxyKeys;
24
- for (let index = 0; index < length; index += 1) {
25
- const key = proxyKeys[index];
26
- proxy[key] = valueKeys.includes(key) ? value[key] : void 0;
27
- }
28
- length = valueKeys.length;
29
- for (let index = 0; index < length; index += 1) {
30
- const key = valueKeys[index];
31
- if (!proxyKeys.includes(key)) proxy[key] = value[key];
32
- }
33
- stopBatch();
34
- }
35
- function setValueInProxy(parameters) {
36
- const { isArray, length, property, state, target, value } = parameters;
37
- if (isArray) {
38
- if (!(!Number.isNaN(Number(property)) || property === "length")) return Reflect.set(target, property, value);
39
- }
40
- const previous = Reflect.get(target, property);
41
- if (!state.equal(previous, value)) {
42
- Reflect.set(target, property, value);
43
- emitValue(state);
44
- if (isArray) length?.set(target.length);
45
- }
46
- return true;
47
- }
48
- export { emityProxyValues, getReactiveValueInProxy, setProxyValue, setValueInProxy };
package/dist/index.js DELETED
@@ -1,8 +0,0 @@
1
- import { effect } from "./effect.js";
2
- import { isArray, isComputed, isEffect, isReactive, isSignal } from "./helpers/is.js";
3
- import { startBatch, stopBatch } from "./batch.js";
4
- import { computed } from "./value/computed.js";
5
- import { signal } from "./value/signal.js";
6
- import { array } from "./value/array.js";
7
- import { store } from "./value/store.js";
8
- export { array, computed, effect, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
package/dist/models.js DELETED
File without changes
@@ -1,100 +0,0 @@
1
- import { METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ARRAY, PROPERTY_LENGTH } from "../constants.js";
2
- import { noop, subscribe } from "../subscription.js";
3
- import { Reactive } from "./reactive.js";
4
- import { computed } from "./computed.js";
5
- import { emitValue, equalArrays, getValue } from "../helpers/value.js";
6
- import { emityProxyValues, getReactiveValueInProxy, setValueInProxy } from "../helpers/proxy.js";
7
- import { signal } from "./signal.js";
8
- var ReactiveArray = class extends Reactive {
9
- #indiced = /* @__PURE__ */ new Map();
10
- #size = signal(0);
11
- get length() {
12
- return this.#size.get();
13
- }
14
- set length(value) {
15
- if (typeof value === "number" && value >= 0 && value !== this.state.value.length) this.get().length = value;
16
- }
17
- constructor(value, options) {
18
- super(NAME_ARRAY, new Proxy(value, {
19
- get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(property, target, this.state, this.#size) : Reflect.get(target, property),
20
- set: (target, property, value$1) => setValueInProxy({
21
- property,
22
- target,
23
- value: value$1,
24
- isArray: true,
25
- state: this.state,
26
- length: this.#size
27
- })
28
- }), options);
29
- this.#size.set(value.length);
30
- }
31
- clear() {
32
- this.length = 0;
33
- }
34
- filter(callback) {
35
- return computed(() => this.get().filter(callback));
36
- }
37
- get(first) {
38
- if (typeof first === "number") return getReactiveValueInProxy(this, this.#indiced, first, true).get();
39
- return first === "length" ? this.length : getValue(this.state);
40
- }
41
- map(callback) {
42
- return computed(() => this.get().map(callback));
43
- }
44
- notify() {
45
- emityProxyValues(this.state, this.#indiced);
46
- }
47
- peek(value) {
48
- if (value === "length") return this.#size.peek();
49
- return typeof value === "number" ? this.state.value.at(value) : [...this.state.value];
50
- }
51
- pop() {
52
- return this.state.value.pop();
53
- }
54
- push(...items) {
55
- return this.state.value.push(...items);
56
- }
57
- set(first, second) {
58
- if (first == null || Array.isArray(first)) this.state.value.splice(0, this.state.value.length, ...first ?? []);
59
- else if (first === "length") this.length = second;
60
- else if (typeof first === "number" && !Number.isNaN(first)) setAtIndex(this.state.value, first, second);
61
- }
62
- shift() {
63
- return this.state.value.shift();
64
- }
65
- splice(from, to, ...items) {
66
- return this.state.value.splice(from, to ?? this.state.value.length, ...items);
67
- }
68
- subscribe(first, second) {
69
- if (typeof first === "number" && typeof second === "function") return getReactiveValueInProxy(this, this.#indiced, first, true).subscribe(second);
70
- return typeof first === "function" ? subscribe(this.state, first) : noop;
71
- }
72
- unshift(...items) {
73
- return this.state.value.unshift(...items);
74
- }
75
- update(callback) {
76
- const updated = callback(this.state.value);
77
- if (updated == null || Array.isArray(updated)) this.set(updated);
78
- }
79
- };
80
- function array(value, options) {
81
- return new ReactiveArray(Array.isArray(value) ? value : [], options);
82
- }
83
- function updateArray(type, array$1, state, length) {
84
- const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
85
- const previousArray = affectsLength ? [] : [...array$1];
86
- const previousLength = array$1.length;
87
- return (...args) => {
88
- const result = array$1[type](...args);
89
- if (affectsLength ? array$1.length !== previousLength : !equalArrays(state, previousArray, array$1)) {
90
- emitValue(state);
91
- length.set(array$1.length);
92
- }
93
- return result;
94
- };
95
- }
96
- function setAtIndex(array$1, index, value) {
97
- const actual = index < 0 ? array$1.length + index : index;
98
- if (actual > -1) array$1[actual] = value;
99
- }
100
- export { ReactiveArray, array };
@@ -1,36 +0,0 @@
1
- import { ACTIVE, BATCH, NAME_COMPUTED } from "../constants.js";
2
- import { effect, runEffect } from "../effect.js";
3
- import { Reactive } from "./reactive.js";
4
- var Computed = class extends Reactive {
5
- effect = {
6
- dirty: true,
7
- instance: void 0
8
- };
9
- constructor(callback, options) {
10
- super(NAME_COMPUTED, void 0, options);
11
- this.effect.instance = effect(() => {
12
- if (!this.effect.dirty) return;
13
- const previousComputed = ACTIVE.computed;
14
- ACTIVE.computed = this;
15
- const value = callback();
16
- ACTIVE.computed = previousComputed;
17
- if (!this.state.equal(this.state.value, value)) {
18
- this.state.value = value;
19
- for (const computed$1 of this.state.computeds) computed$1.effect.dirty = true;
20
- for (const effect$1 of this.state.effects) BATCH.handlers.add(effect$1);
21
- for (const [, subscription] of this.state.subscriptions) subscription.callback(value);
22
- }
23
- this.effect.dirty = false;
24
- });
25
- }
26
- get() {
27
- if (ACTIVE.computed != null && this !== ACTIVE.computed) this.state.computeds.add(ACTIVE.computed);
28
- if (ACTIVE.effect != null && ACTIVE.effect !== this.effect.instance) this.state.effects.add(ACTIVE.effect);
29
- if (this.effect.dirty && BATCH.depth === 0) runEffect(this.effect.instance);
30
- return this.state.value;
31
- }
32
- };
33
- function computed(callback, options) {
34
- return new Computed(callback, options);
35
- }
36
- export { Computed, computed };
@@ -1,24 +0,0 @@
1
- import { NAME_SIGNAL } from "../constants.js";
2
- import { Reactive } from "./reactive.js";
3
- import { emitValue, getValue } from "../helpers/value.js";
4
- var Signal = class extends Reactive {
5
- constructor(value, options) {
6
- super(NAME_SIGNAL, value, options);
7
- }
8
- get() {
9
- return getValue(this.state);
10
- }
11
- set(value) {
12
- if (!this.state.equal(this.state.value, value)) {
13
- this.state.value = value;
14
- emitValue(this.state);
15
- }
16
- }
17
- update(callback) {
18
- this.set(callback(this.state.value));
19
- }
20
- };
21
- function signal(value, options) {
22
- return new Signal(value, options);
23
- }
24
- export { Signal, signal };
@@ -1,43 +0,0 @@
1
- import { NAME_STORE } from "../constants.js";
2
- import { noop, subscribe } from "../subscription.js";
3
- import { Reactive } from "./reactive.js";
4
- import { getValue } from "../helpers/value.js";
5
- import { emityProxyValues, getReactiveValueInProxy, setProxyValue, setValueInProxy } from "../helpers/proxy.js";
6
- import { isKey, isPlainObject } from "@oscarpalmer/atoms/is";
7
- var Store = class extends Reactive {
8
- #keyed = /* @__PURE__ */ new Map();
9
- constructor(value, options) {
10
- super(NAME_STORE, new Proxy(value, { set: (target, property, value$1) => setValueInProxy({
11
- target,
12
- property,
13
- value: value$1,
14
- isArray: false,
15
- state: this.state
16
- }) }), options);
17
- }
18
- get(key) {
19
- return isKey(key) ? getReactiveValueInProxy(this, this.#keyed, key, false).get() : getValue(this.state);
20
- }
21
- notify() {
22
- emityProxyValues(this.state, this.#keyed);
23
- }
24
- peek(key) {
25
- return isKey(key) ? this.state.value[key] : { ...this.state.value };
26
- }
27
- set(first, second) {
28
- if (isKey(first)) this.state.value[first] = second;
29
- else if (first == null || isPlainObject(first)) setProxyValue(this.state.value, first ?? {});
30
- }
31
- subscribe(first, second) {
32
- if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
33
- return typeof first === "function" ? subscribe(this.state, first) : noop;
34
- }
35
- update(callback) {
36
- const updated = callback({ ...this.state.value });
37
- if (updated == null || isPlainObject(updated)) setProxyValue(this.state.value, updated ?? {});
38
- }
39
- };
40
- function store(value, options) {
41
- return new Store(isPlainObject(value) ? value : {}, options);
42
- }
43
- export { Store, store };