@oscarpalmer/mora 0.34.0 → 0.35.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.
package/src/models.ts CHANGED
@@ -15,7 +15,7 @@ export type Batch = {
15
15
  handlers: Map<EffectState | Subscription, EffectState | StoredSubscription>;
16
16
  };
17
17
 
18
- export type Computed<Value> = Reactive<Value> & SimpleReactive<Value>;
18
+ export type Computed<Value> = Reactive<Value>;
19
19
 
20
20
  export type ComputedEffect = {
21
21
  dirty: boolean;
@@ -28,23 +28,46 @@ export type EffectState = {
28
28
  callback: GenericCallback;
29
29
  };
30
30
 
31
+ export type InternalArray = {
32
+ [SYMBOL_STATE]: ReactiveProxyState;
33
+ } & ReactiveArray<unknown>;
34
+
31
35
  export type InternalComputed = {
32
36
  [SYMBOL_EFFECT]: ComputedEffect;
33
- } & InternalSignal;
34
-
35
- export type InternalProxy = {
36
- [SYMBOL_STATE]: ReactiveProxyState;
37
- };
37
+ [SYMBOL_STATE]: SignalState;
38
+ } & Computed<unknown>;
38
39
 
39
40
  export type InternalReadonly = {
40
41
  frozen: boolean;
41
- } & InternalSignal;
42
+ } & InternalStateful &
43
+ ReadonlySignal<unknown>;
42
44
 
43
- export type InternalSignal = {
45
+ export type InternalSignal = InternalStateful & Signal<unknown>;
46
+
47
+ export type InternalStateful = {
44
48
  [SYMBOL_STATE]: SignalState;
45
49
  };
46
50
 
51
+ export type InternalStore = {
52
+ [SYMBOL_STATE]: ReactiveProxyState;
53
+ } & ReactiveStore<PlainObject>;
54
+
47
55
  export type Reactive<Value> = {
56
+ /**
57
+ * Get the value
58
+ *
59
+ * @returns Current value
60
+ */
61
+ get(): Value;
62
+
63
+ /**
64
+ * Get the value _(without reactivity)_
65
+ *
66
+ * @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
67
+ * @returns Current value
68
+ */
69
+ peek(copy?: boolean): Value;
70
+
48
71
  /**
49
72
  * _JSON_ representation of the value
50
73
  *
@@ -59,6 +82,15 @@ export type Reactive<Value> = {
59
82
  * @returns Value as string
60
83
  */
61
84
  toString(json?: boolean): string;
85
+
86
+ /**
87
+ * Subscribe to changes
88
+ *
89
+ * @param subscriber Callback for changes
90
+ * @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
91
+ * @returns Subscription
92
+ */
93
+ subscribe(subscriber: Subscriber<Value>, copy?: boolean): Subscription;
62
94
  };
63
95
 
64
96
  export type ReactiveArray<Item> = {
@@ -292,17 +324,17 @@ export type ReactiveOptions<Value> = {
292
324
  export type ReactiveProxyState = {
293
325
  isArray: boolean;
294
326
  length?: Signal<number>;
295
- mapped?: Map<string, [Computed<unknown>, ComputedEffect]>;
327
+ mapped?: Map<string, [InternalComputed, ComputedEffect]>;
296
328
  } & SignalState;
297
329
 
298
- export type ReactiveState = {
330
+ export type ReactiveState<Value = unknown, Item = Value> = {
299
331
  computeds?: Set<ComputedEffect>;
300
332
  effects?: Set<EffectState>;
301
- equal?: (first: unknown, second: unknown) => boolean;
333
+ equal?: (first: Item, second: Item) => boolean;
302
334
  promise?: Promise<unknown>;
303
335
  promises?: Map<Key, Promise<never>>;
304
336
  subscriptions?: Subscriptions<GenericCallback>;
305
- value: unknown;
337
+ value: Value;
306
338
  };
307
339
 
308
340
  export type ReactiveStore<Store> = {
@@ -465,8 +497,7 @@ export type ReadonlySignal<Value> = {
465
497
  * Is the signal frozen?
466
498
  */
467
499
  get frozen(): boolean;
468
- } & Reactive<Value> &
469
- SimpleReactive<Value>;
500
+ } & Reactive<Value>;
470
501
 
471
502
  export type ReadonlySignalValue<Value> = Value extends unknown[]
472
503
  ? Readonly<Value>
@@ -506,44 +537,17 @@ export type Signal<Value> = {
506
537
  * @param callback Callback to update the value
507
538
  */
508
539
  update(callback: (value: Value) => Value): void;
509
- } & Reactive<Value> &
510
- SimpleReactive<Value>;
540
+ } & Reactive<Value>;
511
541
 
512
542
  export type SignalState = {
513
543
  readonlies?: ReadonlyInstances<unknown>;
514
544
  } & ReactiveState;
515
545
 
516
- type SimpleReactive<Value> = {
517
- /**
518
- * Get the value
519
- *
520
- * @returns Current value
521
- */
522
- get(): Value;
523
-
524
- /**
525
- * Get the value _(without reactivity)_
526
- *
527
- * @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
528
- * @returns Current value
529
- */
530
- peek(copy?: boolean): Value;
531
-
532
- /**
533
- * Subscribe to changes
534
- *
535
- * @param subscriber Callback for changes
536
- * @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
537
- * @returns Subscription
538
- */
539
- subscribe(subscriber: Subscriber<Value>, copy?: boolean): Subscription;
540
- };
541
-
542
546
  export type StoredSubscription = {
543
547
  callback: GenericCallback;
544
548
  copy: boolean;
545
549
  frozen: boolean;
546
- instance: InternalSignal;
550
+ instance: InternalStateful;
547
551
  state: SignalState;
548
552
  };
549
553
 
@@ -18,10 +18,10 @@ import {
18
18
  updateProxyValue,
19
19
  } from '../helpers/proxy';
20
20
  import {subscribeToProxy} from '../helpers/subscription';
21
- import {emitValue, equalArrays, getStringValue} from '../helpers/value';
22
- import type {InternalProxy, ReactiveArray, ReactiveOptions, ReactiveState} from '../models';
21
+ import {emitValue, equalArrays, getJsonValue, getStringValue} from '../helpers/value';
22
+ import type {Computed, InternalArray, ReactiveArray, ReactiveOptions} from '../models';
23
23
  import {computed} from './computed';
24
- import {getReadonlyInstance} from './readonly';
24
+ import {getReadonlySignal} from './readonly';
25
25
  import {signal} from './signal';
26
26
 
27
27
  // #region Instance
@@ -35,73 +35,43 @@ function ReactiveArray(this: any, value: unknown, options?: ReactiveOptions<unkn
35
35
 
36
36
  this[SYMBOL_STATE].value = new Proxy([], {
37
37
  get: (target, property) =>
38
- METHODS_UPDATE.has(property as string)
39
- ? updateArray(this, property as string, target)
38
+ METHODS_UPDATE.has(property)
39
+ ? updateArray(this, property, target)
40
40
  : Reflect.get(target, property),
41
41
  set: (target, property, value) => setValueInProxy(this, target, property, value),
42
42
  });
43
43
 
44
- Object.defineProperty(this, PROPERTY_LENGTH, {
45
- enumerable: true,
46
- get: () => this[SYMBOL_STATE].length.get(),
47
- set: (value: number) => setArrayLength(this[SYMBOL_STATE], value),
48
- });
49
-
50
44
  setProxyValue.call(this, value);
51
45
  }
52
46
 
53
47
  ReactiveArray.prototype[NAME_MORA] = NAME_ARRAY;
54
48
 
55
- ReactiveArray.prototype.asReadonly = getReadonlyInstance;
49
+ Object.defineProperty(ReactiveArray.prototype, PROPERTY_LENGTH, {
50
+ enumerable: true,
51
+ get: getArrayLength,
52
+ set: setArrayLength,
53
+ });
54
+
55
+ ReactiveArray.prototype.asReadonly = getReadonlySignal;
56
56
  ReactiveArray.prototype.at = getArrayValues;
57
+ ReactiveArray.prototype.clear = clearArrayValues;
58
+ ReactiveArray.prototype.filter = filterArrayValues;
57
59
  ReactiveArray.prototype.get = getArrayValues;
60
+ ReactiveArray.prototype.map = mapArrayValues;
58
61
  ReactiveArray.prototype.notify = emitProxyValues;
59
62
  ReactiveArray.prototype.peek = peekArrayValue;
63
+ ReactiveArray.prototype.pop = popArrayValue;
64
+ ReactiveArray.prototype.push = pushArrayValues;
65
+ ReactiveArray.prototype.select = selectArrayValues;
66
+ ReactiveArray.prototype.shift = shiftArrayValue;
60
67
  ReactiveArray.prototype.set = setProxyValue;
68
+ ReactiveArray.prototype.splice = spliceArrayValues;
61
69
  ReactiveArray.prototype.subscribe = subscribeToProxy;
62
70
  ReactiveArray.prototype.toString = getStringValue;
71
+ ReactiveArray.prototype.toJSON = getJsonValue;
72
+ ReactiveArray.prototype.unshift = unshiftArrayValues;
63
73
  ReactiveArray.prototype.update = updateProxyValue;
64
74
 
65
- ReactiveArray.prototype.clear = function () {
66
- this[SYMBOL_STATE].value.length = 0;
67
- };
68
-
69
- ReactiveArray.prototype.filter = function (callback: never) {
70
- return computed(() => filter(getArrayValues.call(this) as never, callback) as never);
71
- };
72
-
73
- ReactiveArray.prototype.map = function (callback: never) {
74
- return computed(() => (getArrayValues.call(this) as unknown[]).map(callback));
75
- };
76
-
77
- ReactiveArray.prototype.pop = function () {
78
- return this[SYMBOL_STATE].value.pop();
79
- };
80
-
81
- ReactiveArray.prototype.push = function (...items: unknown[]) {
82
- return this[SYMBOL_STATE].value.push(...items);
83
- };
84
-
85
- ReactiveArray.prototype.select = function (filter: never, map: never) {
86
- return computed(() => select(getArrayValues.call(this) as unknown[], filter, map));
87
- };
88
-
89
- ReactiveArray.prototype.shift = function () {
90
- return this[SYMBOL_STATE].value.shift();
91
- };
92
-
93
- ReactiveArray.prototype.splice = function (from: never, to?: never, ...items: unknown[]) {
94
- return this[SYMBOL_STATE].value.splice(from, to ?? this[SYMBOL_STATE].value.length, ...items);
95
- };
96
-
97
- ReactiveArray.prototype.toJSON = function () {
98
- return this[SYMBOL_STATE].value;
99
- };
100
-
101
- ReactiveArray.prototype.unshift = function (...items: unknown[]) {
102
- return this[SYMBOL_STATE].value.unshift(...items);
103
- };
104
-
105
75
  // #endregion
106
76
 
107
77
  // #region Functions
@@ -144,30 +114,75 @@ export function array(value: unknown, options?: ReactiveOptions<unknown>): React
144
114
  return new ReactiveArray(value, options);
145
115
  }
146
116
 
147
- function getArrayValues(this: InternalProxy, value?: unknown): unknown {
117
+ function clearArrayValues(this: InternalArray): void {
118
+ (this[SYMBOL_STATE].value as unknown[]).length = 0;
119
+ }
120
+
121
+ function filterArrayValues(this: InternalArray, callback: never): Computed<unknown[]> {
122
+ return computed(() => filter(getArrayValues.call(this) as never, callback) as never);
123
+ }
124
+
125
+ function getArrayLength(this: InternalArray): number {
126
+ return this[SYMBOL_STATE].length!.get();
127
+ }
128
+
129
+ function getArrayValues(this: InternalArray, value?: unknown): unknown {
148
130
  return value === PROPERTY_LENGTH
149
131
  ? this[SYMBOL_STATE].length!.get()
150
132
  : getValueInProxy.call(this, value);
151
133
  }
152
134
 
153
- function peekArrayValue(this: InternalProxy, first?: unknown, second?: boolean): unknown {
135
+ function mapArrayValues(this: InternalArray, callback: never): Computed<unknown[]> {
136
+ return computed(() => (getArrayValues.call(this) as unknown[]).map(callback));
137
+ }
138
+
139
+ function peekArrayValue(this: InternalArray, first?: unknown, second?: boolean): unknown {
154
140
  return first === PROPERTY_LENGTH
155
141
  ? this[SYMBOL_STATE].length!.peek()
156
142
  : peekValueInProxy.call(this, first, second);
157
143
  }
158
144
 
159
- function setArrayLength(state: ReactiveState, value: number): void {
160
- if (
161
- typeof value === 'number' &&
162
- !Number.isNaN(value) &&
163
- value >= 0 &&
164
- value !== (state.value as unknown[]).length
165
- ) {
166
- (state.value as unknown[]).length = value;
145
+ function popArrayValue(this: InternalArray): unknown {
146
+ return (this[SYMBOL_STATE].value as unknown[]).pop();
147
+ }
148
+
149
+ function pushArrayValues(this: InternalArray, ...items: unknown[]): number {
150
+ return (this[SYMBOL_STATE].value as unknown[]).push(...items);
151
+ }
152
+
153
+ function selectArrayValues(this: InternalArray, filter: never, map: never): Computed<unknown[]> {
154
+ return computed(() => select(getArrayValues.call(this) as unknown[], filter, map));
155
+ }
156
+
157
+ function setArrayLength(this: InternalArray, value: number): void {
158
+ const state = this[SYMBOL_STATE];
159
+ const values = state.value as unknown[];
160
+
161
+ if (typeof value === 'number' && !Number.isNaN(value) && value >= 0 && value !== values.length) {
162
+ values.length = value;
167
163
  }
168
164
  }
169
165
 
170
- function updateArray(instance: InternalProxy, type: string, array: unknown[]): unknown {
166
+ function shiftArrayValue(this: InternalArray): unknown {
167
+ return (this[SYMBOL_STATE].value as unknown[]).shift();
168
+ }
169
+
170
+ function spliceArrayValues(
171
+ this: InternalArray,
172
+ from: never,
173
+ to?: never,
174
+ ...items: unknown[]
175
+ ): unknown[] {
176
+ const values = this[SYMBOL_STATE].value as unknown[];
177
+
178
+ return values.splice(from, to ?? values.length, ...items);
179
+ }
180
+
181
+ function unshiftArrayValues(this: InternalArray, ...items: unknown[]): number {
182
+ return (this[SYMBOL_STATE].value as unknown[]).unshift(...items);
183
+ }
184
+
185
+ function updateArray(instance: InternalArray, type: string | symbol, array: unknown[]): unknown {
171
186
  const state = instance[SYMBOL_STATE];
172
187
 
173
188
  const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
@@ -178,7 +193,9 @@ function updateArray(instance: InternalProxy, type: string, array: unknown[]): u
178
193
  const result = (array[type as never] as (...args: unknown[]) => unknown)(...args);
179
194
 
180
195
  if (
181
- affectsLength ? array.length !== previousLength : !equalArrays(state, previousArray, array)
196
+ affectsLength
197
+ ? array.length !== previousLength
198
+ : !equalArrays(previousArray, array, state.equal)
182
199
  ) {
183
200
  emitValue(instance);
184
201
 
@@ -14,20 +14,19 @@ import {
14
14
  import {internalEffect, runEffect} from '../effect';
15
15
  import {getState} from '../helpers/misc';
16
16
  import {subscribeToSignal} from '../helpers/subscription';
17
- import {getStringValue, handleSignalValue, peekSignalValue} from '../helpers/value';
17
+ import {getJsonValue, getStringValue, handleSignal, peekSignalValue} from '../helpers/value';
18
18
  import type {
19
19
  Computed,
20
20
  ComputedEffect,
21
- ReactiveOptions,
22
21
  InternalComputed,
23
- InternalSignal,
22
+ InternalStateful,
23
+ ReactiveOptions,
24
24
  } from '../models';
25
25
 
26
26
  // #region Instance
27
27
 
28
28
  function Computed(this: any, callback: GenericCallback, options?: ReactiveOptions<unknown>) {
29
29
  this[SYMBOL_STATE] = getState(undefined, options);
30
-
31
30
  this[SYMBOL_EFFECT] = getComputedEffect(this, callback);
32
31
  }
33
32
 
@@ -36,12 +35,9 @@ Computed.prototype[NAME_MORA] = NAME_COMPUTED;
36
35
  Computed.prototype.get = getComputedValue;
37
36
  Computed.prototype.peek = peekSignalValue;
38
37
  Computed.prototype.subscribe = subscribeToSignal;
38
+ Computed.prototype.toJSON = getJsonValue;
39
39
  Computed.prototype.toString = getStringValue;
40
40
 
41
- Computed.prototype.toJSON = function () {
42
- return this[SYMBOL_STATE].value;
43
- };
44
-
45
41
  // #endregion
46
42
 
47
43
  // #region Functions
@@ -57,13 +53,13 @@ export function computed<Value>(
57
53
  callback: () => Value | Promise<Value>,
58
54
  options?: ReactiveOptions<Value>,
59
55
  ): Computed<Value> {
60
- return getComputed(callback, options)[0];
56
+ return getComputed(callback, options)[0] as Computed<Value>;
61
57
  }
62
58
 
63
59
  function getComputed<Value>(
64
60
  callback: GenericCallback,
65
61
  options?: ReactiveOptions<Value>,
66
- ): [Computed<Value>, ComputedEffect] {
62
+ ): [InternalComputed, ComputedEffect] {
67
63
  if (typeof callback !== 'function') {
68
64
  throw new TypeError('Computed callback must be a function');
69
65
  }
@@ -71,11 +67,11 @@ function getComputed<Value>(
71
67
  // @ts-expect-error All good, no worries :-)
72
68
  const instance = new Computed(callback, options);
73
69
 
74
- return [instance as never, instance[SYMBOL_EFFECT]];
70
+ return [instance, instance[SYMBOL_EFFECT]];
75
71
  }
76
72
 
77
73
  function getComputedEffect(
78
- instance: InternalSignal,
74
+ instance: InternalStateful,
79
75
  callback: GenericAsyncCallback,
80
76
  ): ComputedEffect {
81
77
  const fx: ComputedEffect = {
@@ -89,7 +85,7 @@ function getComputedEffect(
89
85
 
90
86
  ACTIVE.computed = fx;
91
87
 
92
- handleSignalValue(instance, callback, setAndEmit, () => {
88
+ handleSignal(instance, callback, setAndEmit, () => {
93
89
  ACTIVE.computed = previousComputed;
94
90
  });
95
91
 
@@ -126,14 +122,14 @@ function getComputedValue(this: InternalComputed): unknown {
126
122
  export function internalComputed(
127
123
  callback: GenericCallback,
128
124
  options?: ReactiveOptions<unknown>,
129
- ): [Computed<unknown>, ComputedEffect] {
125
+ ): [InternalComputed, ComputedEffect] {
130
126
  return getComputed(callback, options);
131
127
  }
132
128
 
133
- function setAndEmit(instance: InternalSignal, value: unknown): void {
129
+ function setAndEmit(instance: InternalStateful, value: unknown): void {
134
130
  const state = instance[SYMBOL_STATE];
135
131
 
136
- if ((state.equal ?? Object.is)(state.value as never, value as never)) {
132
+ if ((state.equal ?? Object.is)(state.value, value)) {
137
133
  return;
138
134
  }
139
135
 
@@ -6,42 +6,51 @@ import {
6
6
  SYMBOL_STATE,
7
7
  } from '../constants';
8
8
  import {subscribeToReadonly} from '../helpers/subscription';
9
- import {getFrozenValue, getSignalValue, getStringValue, peekSignalValue} from '../helpers/value';
10
- import type {ReadonlyFrozenSignal, ReadonlySignal, SignalState, InternalSignal} from '../models';
9
+ import {
10
+ getFrozenValue,
11
+ getJsonValue,
12
+ getSignalValue,
13
+ getStringValue,
14
+ peekSignalValue,
15
+ } from '../helpers/value';
16
+ import type {InternalSignal, ReadonlyFrozenSignal, ReadonlySignal, SignalState} from '../models';
17
+
18
+ // #region Types
19
+
20
+ type InternalReadonly = {
21
+ [SUBSCRIPTION_TYPE_FROZEN]: boolean;
22
+ } & InternalSignal;
23
+
24
+ // #endregion
11
25
 
12
26
  // #region Instance
13
27
 
14
28
  function Readonly(this: any, state: SignalState, frozen: boolean) {
29
+ this[SUBSCRIPTION_TYPE_FROZEN] = frozen;
15
30
  this[SYMBOL_STATE] = state;
16
-
17
- Object.defineProperty(this, SUBSCRIPTION_TYPE_FROZEN, {
18
- enumerable: true,
19
- value: frozen,
20
- });
21
31
  }
22
32
 
23
33
  Readonly.prototype[NAME_MORA] = NAME_READONLY;
24
34
 
35
+ Readonly.prototype.get = getReadonlyValue;
36
+ Readonly.prototype.peek = peekReadonlyValue;
25
37
  Readonly.prototype.subscribe = subscribeToReadonly;
38
+ Readonly.prototype.toJSON = getJsonValue;
26
39
  Readonly.prototype.toString = getStringValue;
27
40
 
28
- Readonly.prototype.get = function () {
29
- return getReadonlyValue(this, false, this[SUBSCRIPTION_TYPE_FROZEN]);
30
- };
31
-
32
- Readonly.prototype.peek = function (copy?: boolean) {
33
- return getReadonlyValue(this, true, this[SUBSCRIPTION_TYPE_FROZEN], copy);
34
- };
35
-
36
- Readonly.prototype.toJSON = function () {
37
- return this[SYMBOL_STATE].value;
38
- };
39
-
40
41
  // #endregion
41
42
 
42
43
  // #region Functions
43
44
 
44
- export function getReadonlyInstance<Value>(
45
+ export function getReadonlyInstance(
46
+ state: SignalState,
47
+ frozen: boolean,
48
+ ): ReadonlySignal<unknown> | ReadonlyFrozenSignal<unknown> {
49
+ // @ts-expect-error All good, no worries :-)
50
+ return new Readonly(state, frozen);
51
+ }
52
+
53
+ export function getReadonlySignal<Value>(
45
54
  this: InternalSignal,
46
55
  frozen?: never,
47
56
  ): ReadonlySignal<Value> {
@@ -49,7 +58,7 @@ export function getReadonlyInstance<Value>(
49
58
 
50
59
  this[SYMBOL_STATE].readonlies ??= {};
51
60
 
52
- this[SYMBOL_STATE].readonlies[key] ??= getReadonlySignal(
61
+ this[SYMBOL_STATE].readonlies[key] ??= getReadonlyInstance(
53
62
  this[SYMBOL_STATE],
54
63
  frozen === true,
55
64
  ) as never;
@@ -57,16 +66,12 @@ export function getReadonlyInstance<Value>(
57
66
  return this[SYMBOL_STATE].readonlies[key] as never;
58
67
  }
59
68
 
60
- export function getReadonlySignal(
61
- state: SignalState,
62
- frozen: boolean,
63
- ): ReadonlySignal<unknown> | ReadonlyFrozenSignal<unknown> {
64
- // @ts-expect-error All good, no worries :-)
65
- return new Readonly(state, frozen);
69
+ function getReadonlyValue(this: InternalReadonly) {
70
+ return handleReadonlyValue(this, false, this[SUBSCRIPTION_TYPE_FROZEN]);
66
71
  }
67
72
 
68
- function getReadonlyValue(
69
- instance: InternalSignal,
73
+ function handleReadonlyValue(
74
+ instance: InternalReadonly,
70
75
  peek: boolean,
71
76
  frozen: boolean,
72
77
  copy?: boolean,
@@ -82,4 +87,8 @@ function getReadonlyValue(
82
87
  return frozen ? getFrozenValue(value) : value;
83
88
  }
84
89
 
90
+ function peekReadonlyValue(this: InternalReadonly, copy?: boolean) {
91
+ return handleReadonlyValue(this, true, this[SUBSCRIPTION_TYPE_FROZEN], copy);
92
+ }
93
+
85
94
  // #endregion
@@ -3,57 +3,53 @@ import {getState} from '../helpers/misc';
3
3
  import {subscribeToSignal} from '../helpers/subscription';
4
4
  import {
5
5
  emitValue,
6
+ getJsonValue,
6
7
  getSignalValue,
7
8
  getStringValue,
8
- handleSignalValue,
9
+ handleSignal,
9
10
  peekSignalValue,
10
- updateSignalValue,
11
+ updateSignal,
11
12
  } from '../helpers/value';
12
- import type {ReactiveOptions, Signal, InternalSignal} from '../models';
13
- import {getReadonlyInstance} from './readonly';
13
+ import type {InternalSignal, InternalStateful, ReactiveOptions, Signal} from '../models';
14
+ import {getReadonlySignal} from './readonly';
14
15
 
15
16
  // #region Instance
16
17
 
17
18
  function Signal(this: any, value: unknown, options?: ReactiveOptions<unknown>) {
18
19
  this[SYMBOL_STATE] = getState(undefined, options);
19
20
 
20
- handleSignalValue(this, value, setAndEmit);
21
+ handleSignal(this, value, setAndEmit);
21
22
  }
22
23
 
23
24
  Signal.prototype[NAME_MORA] = NAME_SIGNAL;
24
25
 
25
- Signal.prototype.asReadonly = getReadonlyInstance;
26
+ Signal.prototype.asReadonly = getReadonlySignal;
26
27
  Signal.prototype.get = getSignalValue;
27
28
  Signal.prototype.peek = peekSignalValue;
29
+ Signal.prototype.set = setSignalValue;
28
30
  Signal.prototype.subscribe = subscribeToSignal;
29
31
  Signal.prototype.toString = getStringValue;
30
-
31
- Signal.prototype.set = function (value: never) {
32
- return handleSignalValue(this, value, setAndEmit);
33
- };
34
-
35
- Signal.prototype.toJSON = function () {
36
- return this[SYMBOL_STATE].value;
37
- };
38
-
39
- Signal.prototype.update = function (callback: never) {
40
- return updateSignalValue(this, callback, setAndEmit);
41
- };
32
+ Signal.prototype.toJSON = getJsonValue;
33
+ Signal.prototype.update = updateSignalValue;
42
34
 
43
35
  // #endregion
44
36
 
45
37
  // #region Functions
46
38
 
47
- function setAndEmit(instance: InternalSignal, value: unknown): void {
39
+ function setAndEmit(instance: InternalStateful, value: unknown): void {
48
40
  const state = instance[SYMBOL_STATE];
49
41
 
50
- if (!(state.equal ?? Object.is)(state.value as never, value as never)) {
42
+ if (!(state.equal ?? Object.is)(state.value, value)) {
51
43
  state.value = value;
52
44
 
53
45
  emitValue(instance);
54
46
  }
55
47
  }
56
48
 
49
+ function setSignalValue(this: InternalSignal, value: unknown): void {
50
+ handleSignal(this, value, setAndEmit);
51
+ }
52
+
57
53
  /**
58
54
  * Create a reactive value from a function result
59
55
  *
@@ -92,4 +88,8 @@ export function signal(value: unknown, options?: ReactiveOptions<unknown>): Sign
92
88
  return new Signal(value, options);
93
89
  }
94
90
 
91
+ function updateSignalValue(this: InternalSignal, callback: never): void {
92
+ updateSignal(this, callback, setAndEmit);
93
+ }
94
+
95
95
  // #endregion
@@ -10,9 +10,9 @@ import {
10
10
  updateProxyValue,
11
11
  } from '../helpers/proxy';
12
12
  import {subscribeToProxy} from '../helpers/subscription';
13
- import {getStringValue} from '../helpers/value';
13
+ import {getJsonValue, getStringValue} from '../helpers/value';
14
14
  import type {ReactiveOptions, ReactiveStore} from '../models';
15
- import {getReadonlyInstance} from './readonly';
15
+ import {getReadonlySignal} from './readonly';
16
16
 
17
17
  // #region Instance
18
18
 
@@ -34,19 +34,16 @@ function ReactiveStore(this: any, value: never, options?: ReactiveOptions<unknow
34
34
 
35
35
  ReactiveStore.prototype[NAME_MORA] = NAME_STORE;
36
36
 
37
- ReactiveStore.prototype.asReadonly = getReadonlyInstance;
37
+ ReactiveStore.prototype.asReadonly = getReadonlySignal;
38
38
  ReactiveStore.prototype.get = getValueInProxy;
39
39
  ReactiveStore.prototype.notify = emitProxyValues;
40
40
  ReactiveStore.prototype.peek = peekValueInProxy;
41
41
  ReactiveStore.prototype.set = setProxyValue;
42
42
  ReactiveStore.prototype.subscribe = subscribeToProxy;
43
+ ReactiveStore.prototype.toJSON = getJsonValue;
43
44
  ReactiveStore.prototype.toString = getStringValue;
44
45
  ReactiveStore.prototype.update = updateProxyValue;
45
46
 
46
- ReactiveStore.prototype.toJSON = function () {
47
- return this[SYMBOL_STATE].value;
48
- };
49
-
50
47
  // #endregion
51
48
 
52
49
  // #region Functions