@oscarpalmer/mora 0.33.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.
@@ -1,10 +1,10 @@
1
1
  import { METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ARRAY, NAME_MORA, PROPERTY_LENGTH, SYMBOL_STATE } from "../constants.mjs";
2
- import { emitValue, equalArrays, getStringValue } from "../helpers/value.mjs";
2
+ import { emitValue, equalArrays, getJsonValue, getStringValue } from "../helpers/value.mjs";
3
3
  import { getState } from "../helpers/misc.mjs";
4
4
  import { subscribeToProxy } from "../helpers/subscription.mjs";
5
5
  import { computed } from "./computed.mjs";
6
6
  import { emitProxyValues, getValueInProxy, peekValueInProxy, setProxyValue, setValueInProxy, updateProxyValue } from "../helpers/proxy.mjs";
7
- import { getReadonlyInstance } from "./readonly.mjs";
7
+ import { getReadonlySignal } from "./readonly.mjs";
8
8
  import { signal } from "./signal.mjs";
9
9
  import { select } from "@oscarpalmer/atoms/array";
10
10
  import { filter } from "@oscarpalmer/atoms/array/filter";
@@ -19,64 +19,76 @@ function ReactiveArray(value, options) {
19
19
  get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(this, property, target) : Reflect.get(target, property),
20
20
  set: (target, property, value) => setValueInProxy(this, target, property, value)
21
21
  });
22
- Object.defineProperty(this, PROPERTY_LENGTH, {
23
- enumerable: true,
24
- get: () => this[SYMBOL_STATE].length.get(),
25
- set: (value) => setArrayLength(this[SYMBOL_STATE], value)
26
- });
27
22
  setProxyValue.call(this, value);
28
23
  }
29
24
  ReactiveArray.prototype[NAME_MORA] = NAME_ARRAY;
30
- ReactiveArray.prototype.asReadonly = getReadonlyInstance;
25
+ Object.defineProperty(ReactiveArray.prototype, PROPERTY_LENGTH, {
26
+ enumerable: true,
27
+ get: getArrayLength,
28
+ set: setArrayLength
29
+ });
30
+ ReactiveArray.prototype.asReadonly = getReadonlySignal;
31
31
  ReactiveArray.prototype.at = getArrayValues;
32
+ ReactiveArray.prototype.clear = clearArrayValues;
33
+ ReactiveArray.prototype.filter = filterArrayValues;
32
34
  ReactiveArray.prototype.get = getArrayValues;
35
+ ReactiveArray.prototype.map = mapArrayValues;
33
36
  ReactiveArray.prototype.notify = emitProxyValues;
34
37
  ReactiveArray.prototype.peek = peekArrayValue;
38
+ ReactiveArray.prototype.pop = popArrayValue;
39
+ ReactiveArray.prototype.push = pushArrayValues;
40
+ ReactiveArray.prototype.select = selectArrayValues;
41
+ ReactiveArray.prototype.shift = shiftArrayValue;
35
42
  ReactiveArray.prototype.set = setProxyValue;
43
+ ReactiveArray.prototype.splice = spliceArrayValues;
36
44
  ReactiveArray.prototype.subscribe = subscribeToProxy;
37
45
  ReactiveArray.prototype.toString = getStringValue;
46
+ ReactiveArray.prototype.toJSON = getJsonValue;
47
+ ReactiveArray.prototype.unshift = unshiftArrayValues;
38
48
  ReactiveArray.prototype.update = updateProxyValue;
39
- ReactiveArray.prototype.clear = function() {
40
- this[SYMBOL_STATE].value.length = 0;
41
- };
42
- ReactiveArray.prototype.filter = function(callback) {
43
- return computed(() => filter(getArrayValues.call(this), callback));
44
- };
45
- ReactiveArray.prototype.map = function(callback) {
46
- return computed(() => getArrayValues.call(this).map(callback));
47
- };
48
- ReactiveArray.prototype.pop = function() {
49
- return this[SYMBOL_STATE].value.pop();
50
- };
51
- ReactiveArray.prototype.push = function(...items) {
52
- return this[SYMBOL_STATE].value.push(...items);
53
- };
54
- ReactiveArray.prototype.select = function(filter, map) {
55
- return computed(() => select(getArrayValues.call(this), filter, map));
56
- };
57
- ReactiveArray.prototype.shift = function() {
58
- return this[SYMBOL_STATE].value.shift();
59
- };
60
- ReactiveArray.prototype.splice = function(from, to, ...items) {
61
- return this[SYMBOL_STATE].value.splice(from, to ?? this[SYMBOL_STATE].value.length, ...items);
62
- };
63
- ReactiveArray.prototype.toJSON = function() {
64
- return this[SYMBOL_STATE].value;
65
- };
66
- ReactiveArray.prototype.unshift = function(...items) {
67
- return this[SYMBOL_STATE].value.unshift(...items);
68
- };
69
49
  function array(value, options) {
70
50
  return new ReactiveArray(value, options);
71
51
  }
52
+ function clearArrayValues() {
53
+ this[SYMBOL_STATE].value.length = 0;
54
+ }
55
+ function filterArrayValues(callback) {
56
+ return computed(() => filter(getArrayValues.call(this), callback));
57
+ }
58
+ function getArrayLength() {
59
+ return this[SYMBOL_STATE].length.get();
60
+ }
72
61
  function getArrayValues(value) {
73
62
  return value === "length" ? this[SYMBOL_STATE].length.get() : getValueInProxy.call(this, value);
74
63
  }
64
+ function mapArrayValues(callback) {
65
+ return computed(() => getArrayValues.call(this).map(callback));
66
+ }
75
67
  function peekArrayValue(first, second) {
76
68
  return first === "length" ? this[SYMBOL_STATE].length.peek() : peekValueInProxy.call(this, first, second);
77
69
  }
78
- function setArrayLength(state, value) {
79
- if (typeof value === "number" && !Number.isNaN(value) && value >= 0 && value !== state.value.length) state.value.length = value;
70
+ function popArrayValue() {
71
+ return this[SYMBOL_STATE].value.pop();
72
+ }
73
+ function pushArrayValues(...items) {
74
+ return this[SYMBOL_STATE].value.push(...items);
75
+ }
76
+ function selectArrayValues(filter, map) {
77
+ return computed(() => select(getArrayValues.call(this), filter, map));
78
+ }
79
+ function setArrayLength(value) {
80
+ const values = this[SYMBOL_STATE].value;
81
+ if (typeof value === "number" && !Number.isNaN(value) && value >= 0 && value !== values.length) values.length = value;
82
+ }
83
+ function shiftArrayValue() {
84
+ return this[SYMBOL_STATE].value.shift();
85
+ }
86
+ function spliceArrayValues(from, to, ...items) {
87
+ const values = this[SYMBOL_STATE].value;
88
+ return values.splice(from, to ?? values.length, ...items);
89
+ }
90
+ function unshiftArrayValues(...items) {
91
+ return this[SYMBOL_STATE].value.unshift(...items);
80
92
  }
81
93
  function updateArray(instance, type, array) {
82
94
  const state = instance[SYMBOL_STATE];
@@ -85,7 +97,7 @@ function updateArray(instance, type, array) {
85
97
  const previousLength = array.length;
86
98
  return (...args) => {
87
99
  const result = array[type](...args);
88
- if (affectsLength ? array.length !== previousLength : !equalArrays(state, previousArray, array)) {
100
+ if (affectsLength ? array.length !== previousLength : !equalArrays(previousArray, array, state.equal)) {
89
101
  emitValue(instance);
90
102
  state.length.set(array.length);
91
103
  }
@@ -1,4 +1,4 @@
1
- import { Computed, ComputedEffect, ReactiveOptions } from "../models.mjs";
1
+ import { Computed, ComputedEffect, InternalComputed, ReactiveOptions } from "../models.mjs";
2
2
  import { GenericCallback } from "@oscarpalmer/atoms/models";
3
3
  //#region src/value/computed.d.ts
4
4
  declare function Computed(this: any, callback: GenericCallback, options?: ReactiveOptions<unknown>): void;
@@ -10,5 +10,5 @@ declare function Computed(this: any, callback: GenericCallback, options?: Reacti
10
10
  * @returns Computed value
11
11
  */
12
12
  export declare function computed<Value>(callback: () => Value | Promise<Value>, options?: ReactiveOptions<Value>): Computed<Value>;
13
- export declare function internalComputed(callback: GenericCallback, options?: ReactiveOptions<unknown>): [Computed<unknown>, ComputedEffect];
13
+ export declare function internalComputed(callback: GenericCallback, options?: ReactiveOptions<unknown>): [InternalComputed, ComputedEffect];
14
14
  //#endregion
@@ -1,6 +1,6 @@
1
1
  import { ACTIVE, BATCH, NAME_COMPUTED, NAME_MORA, SUBSCRIPTION_TYPES, SUBSCRIPTION_TYPES_COPY, SYMBOL_EFFECT, SYMBOL_STATE } from "../constants.mjs";
2
2
  import { internalEffect, runEffect } from "../effect.mjs";
3
- import { getStringValue, handleSignalValue, peekSignalValue } from "../helpers/value.mjs";
3
+ import { getJsonValue, getStringValue, handleSignal, peekSignalValue } from "../helpers/value.mjs";
4
4
  import { flushHandlers } from "../batch.mjs";
5
5
  import { getState } from "../helpers/misc.mjs";
6
6
  import { subscribeToSignal } from "../helpers/subscription.mjs";
@@ -13,10 +13,8 @@ Computed.prototype[NAME_MORA] = NAME_COMPUTED;
13
13
  Computed.prototype.get = getComputedValue;
14
14
  Computed.prototype.peek = peekSignalValue;
15
15
  Computed.prototype.subscribe = subscribeToSignal;
16
+ Computed.prototype.toJSON = getJsonValue;
16
17
  Computed.prototype.toString = getStringValue;
17
- Computed.prototype.toJSON = function() {
18
- return this[SYMBOL_STATE].value;
19
- };
20
18
  /**
21
19
  * Create a computed value
22
20
  *
@@ -41,7 +39,7 @@ function getComputedEffect(instance, callback) {
41
39
  if (fx.dirty) {
42
40
  const previousComputed = ACTIVE.computed;
43
41
  ACTIVE.computed = fx;
44
- handleSignalValue(instance, callback, setAndEmit, () => {
42
+ handleSignal(instance, callback, setAndEmit, () => {
45
43
  ACTIVE.computed = previousComputed;
46
44
  });
47
45
  fx.dirty = false;
@@ -1,5 +1,5 @@
1
1
  import { InternalSignal, ReadonlyFrozenSignal, ReadonlySignal, SignalState } from "../models.mjs";
2
2
  //#region src/value/readonly.d.ts
3
- export declare function getReadonlyInstance<Value>(this: InternalSignal, frozen?: never): ReadonlySignal<Value>;
4
- export declare function getReadonlySignal(state: SignalState, frozen: boolean): ReadonlySignal<unknown> | ReadonlyFrozenSignal<unknown>;
3
+ export declare function getReadonlyInstance(state: SignalState, frozen: boolean): ReadonlySignal<unknown> | ReadonlyFrozenSignal<unknown>;
4
+ export declare function getReadonlySignal<Value>(this: InternalSignal, frozen?: never): ReadonlySignal<Value>;
5
5
  //#endregion
@@ -1,40 +1,37 @@
1
1
  import { NAME_MORA, NAME_READONLY, SUBSCRIPTION_TYPE_FROZEN, SUBSCRIPTION_TYPE_ORIGINAL, SYMBOL_STATE } from "../constants.mjs";
2
- import { getFrozenValue, getSignalValue, getStringValue, peekSignalValue } from "../helpers/value.mjs";
2
+ import { getFrozenValue, getJsonValue, getSignalValue, getStringValue, peekSignalValue } from "../helpers/value.mjs";
3
3
  import { subscribeToReadonly } from "../helpers/subscription.mjs";
4
4
  //#region src/value/readonly.ts
5
5
  function Readonly(state, frozen) {
6
+ this[SUBSCRIPTION_TYPE_FROZEN] = frozen;
6
7
  this[SYMBOL_STATE] = state;
7
- Object.defineProperty(this, SUBSCRIPTION_TYPE_FROZEN, {
8
- enumerable: true,
9
- value: frozen
10
- });
11
8
  }
12
9
  Readonly.prototype[NAME_MORA] = NAME_READONLY;
10
+ Readonly.prototype.get = getReadonlyValue;
11
+ Readonly.prototype.peek = peekReadonlyValue;
13
12
  Readonly.prototype.subscribe = subscribeToReadonly;
13
+ Readonly.prototype.toJSON = getJsonValue;
14
14
  Readonly.prototype.toString = getStringValue;
15
- Readonly.prototype.get = function() {
16
- return getReadonlyValue(this, false, this[SUBSCRIPTION_TYPE_FROZEN]);
17
- };
18
- Readonly.prototype.peek = function(copy) {
19
- return getReadonlyValue(this, true, this[SUBSCRIPTION_TYPE_FROZEN], copy);
20
- };
21
- Readonly.prototype.toJSON = function() {
22
- return this[SYMBOL_STATE].value;
23
- };
24
- function getReadonlyInstance(frozen) {
15
+ function getReadonlyInstance(state, frozen) {
16
+ return new Readonly(state, frozen);
17
+ }
18
+ function getReadonlySignal(frozen) {
25
19
  const key = frozen === true ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_ORIGINAL;
26
20
  this[SYMBOL_STATE].readonlies ??= {};
27
- this[SYMBOL_STATE].readonlies[key] ??= getReadonlySignal(this[SYMBOL_STATE], frozen === true);
21
+ this[SYMBOL_STATE].readonlies[key] ??= getReadonlyInstance(this[SYMBOL_STATE], frozen === true);
28
22
  return this[SYMBOL_STATE].readonlies[key];
29
23
  }
30
- function getReadonlySignal(state, frozen) {
31
- return new Readonly(state, frozen);
24
+ function getReadonlyValue() {
25
+ return handleReadonlyValue(this, false, this[SUBSCRIPTION_TYPE_FROZEN]);
32
26
  }
33
- function getReadonlyValue(instance, peek, frozen, copy) {
27
+ function handleReadonlyValue(instance, peek, frozen, copy) {
34
28
  let value;
35
29
  if (peek) value = peekSignalValue.call(instance, copy === true);
36
30
  else value = getSignalValue.call(instance);
37
31
  return frozen ? getFrozenValue(value) : value;
38
32
  }
33
+ function peekReadonlyValue(copy) {
34
+ return handleReadonlyValue(this, true, this[SUBSCRIPTION_TYPE_FROZEN], copy);
35
+ }
39
36
  //#endregion
40
37
  export { getReadonlyInstance, getReadonlySignal };
@@ -1,28 +1,22 @@
1
1
  import { NAME_MORA, NAME_SIGNAL, SYMBOL_STATE } from "../constants.mjs";
2
- import { emitValue, getSignalValue, getStringValue, handleSignalValue, peekSignalValue, updateSignalValue } from "../helpers/value.mjs";
2
+ import { emitValue, getJsonValue, getSignalValue, getStringValue, handleSignal, peekSignalValue, updateSignal } from "../helpers/value.mjs";
3
3
  import { getState } from "../helpers/misc.mjs";
4
4
  import { subscribeToSignal } from "../helpers/subscription.mjs";
5
- import { getReadonlyInstance } from "./readonly.mjs";
5
+ import { getReadonlySignal } from "./readonly.mjs";
6
6
  //#region src/value/signal.ts
7
7
  function Signal(value, options) {
8
8
  this[SYMBOL_STATE] = getState(void 0, options);
9
- handleSignalValue(this, value, setAndEmit);
9
+ handleSignal(this, value, setAndEmit);
10
10
  }
11
11
  Signal.prototype[NAME_MORA] = NAME_SIGNAL;
12
- Signal.prototype.asReadonly = getReadonlyInstance;
12
+ Signal.prototype.asReadonly = getReadonlySignal;
13
13
  Signal.prototype.get = getSignalValue;
14
14
  Signal.prototype.peek = peekSignalValue;
15
+ Signal.prototype.set = setSignalValue;
15
16
  Signal.prototype.subscribe = subscribeToSignal;
16
17
  Signal.prototype.toString = getStringValue;
17
- Signal.prototype.set = function(value) {
18
- return handleSignalValue(this, value, setAndEmit);
19
- };
20
- Signal.prototype.toJSON = function() {
21
- return this[SYMBOL_STATE].value;
22
- };
23
- Signal.prototype.update = function(callback) {
24
- return updateSignalValue(this, callback, setAndEmit);
25
- };
18
+ Signal.prototype.toJSON = getJsonValue;
19
+ Signal.prototype.update = updateSignalValue;
26
20
  function setAndEmit(instance, value) {
27
21
  const state = instance[SYMBOL_STATE];
28
22
  if (!(state.equal ?? Object.is)(state.value, value)) {
@@ -30,8 +24,14 @@ function setAndEmit(instance, value) {
30
24
  emitValue(instance);
31
25
  }
32
26
  }
27
+ function setSignalValue(value) {
28
+ handleSignal(this, value, setAndEmit);
29
+ }
33
30
  function signal(value, options) {
34
31
  return new Signal(value, options);
35
32
  }
33
+ function updateSignalValue(callback) {
34
+ updateSignal(this, callback, setAndEmit);
35
+ }
36
36
  //#endregion
37
37
  export { signal };
@@ -1,9 +1,9 @@
1
1
  import { NAME_MORA, NAME_STORE, SYMBOL_STATE } from "../constants.mjs";
2
- import { getStringValue } from "../helpers/value.mjs";
2
+ import { getJsonValue, getStringValue } from "../helpers/value.mjs";
3
3
  import { getState } from "../helpers/misc.mjs";
4
4
  import { subscribeToProxy } from "../helpers/subscription.mjs";
5
5
  import { emitProxyValues, getValueInProxy, peekValueInProxy, setProxyValue, setValueInProxy, updateProxyValue } from "../helpers/proxy.mjs";
6
- import { getReadonlyInstance } from "./readonly.mjs";
6
+ import { getReadonlySignal } from "./readonly.mjs";
7
7
  //#region src/value/store.ts
8
8
  function ReactiveStore(value, options) {
9
9
  this[SYMBOL_STATE] = {
@@ -14,17 +14,15 @@ function ReactiveStore(value, options) {
14
14
  setProxyValue.call(this, value);
15
15
  }
16
16
  ReactiveStore.prototype[NAME_MORA] = NAME_STORE;
17
- ReactiveStore.prototype.asReadonly = getReadonlyInstance;
17
+ ReactiveStore.prototype.asReadonly = getReadonlySignal;
18
18
  ReactiveStore.prototype.get = getValueInProxy;
19
19
  ReactiveStore.prototype.notify = emitProxyValues;
20
20
  ReactiveStore.prototype.peek = peekValueInProxy;
21
21
  ReactiveStore.prototype.set = setProxyValue;
22
22
  ReactiveStore.prototype.subscribe = subscribeToProxy;
23
+ ReactiveStore.prototype.toJSON = getJsonValue;
23
24
  ReactiveStore.prototype.toString = getStringValue;
24
25
  ReactiveStore.prototype.update = updateProxyValue;
25
- ReactiveStore.prototype.toJSON = function() {
26
- return this[SYMBOL_STATE].value;
27
- };
28
26
  function store(value, options) {
29
27
  return new ReactiveStore(value, options);
30
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/mora",
3
- "version": "0.33.0",
3
+ "version": "0.35.0",
4
4
  "description": "Signals and stuff…",
5
5
  "keywords": [
6
6
  "reactive",
@@ -39,7 +39,7 @@
39
39
  "test:leak": "vpx vp test run --detect-async-leaks --coverage"
40
40
  },
41
41
  "dependencies": {
42
- "@oscarpalmer/atoms": "^0.202"
42
+ "@oscarpalmer/atoms": "^0.203"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/node": "^26.5",
package/src/batch.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import {BATCH} from './constants';
2
2
  import {runEffect} from './effect';
3
3
  import {getFrozenValue, peekSignalValue} from './helpers/value';
4
- import type {EffectState, StoredSubscription} from './models';
4
+ import type {StoredSubscription} from './models';
5
5
 
6
6
  // #region Functions
7
7
 
@@ -30,7 +30,7 @@ export function flushHandlers(): void {
30
30
  : peekSignalValue.call(subscription.instance, subscription.copy),
31
31
  );
32
32
  } else {
33
- runEffect(handler as EffectState);
33
+ runEffect(handler);
34
34
  }
35
35
  }
36
36
  }
package/src/constants.ts CHANGED
@@ -16,9 +16,14 @@ export const BATCH: Batch = {
16
16
  handlers: new Map(),
17
17
  };
18
18
 
19
- export const METHODS_AFFECTING_LENGTH = new Set<string>(['pop', 'push', 'shift', 'unshift']);
19
+ export const METHODS_AFFECTING_LENGTH = new Set<string | symbol>([
20
+ 'pop',
21
+ 'push',
22
+ 'shift',
23
+ 'unshift',
24
+ ]);
20
25
 
21
- export const METHODS_UPDATE = new Set<string>([
26
+ export const METHODS_UPDATE = new Set<string | symbol>([
22
27
  ...METHODS_AFFECTING_LENGTH,
23
28
  'copyWithin',
24
29
  'fill',
package/src/helpers/is.ts CHANGED
@@ -46,9 +46,7 @@ function isMora<Instance>(value: unknown, name: string | Set<string>): value is
46
46
  typeof value === 'object' &&
47
47
  value != null &&
48
48
  NAME_MORA in value &&
49
- (typeof name === 'string'
50
- ? (value as PlainObject)[NAME_MORA] === name
51
- : name.has((value as PlainObject)[NAME_MORA] as never))
49
+ (typeof name === 'string' ? value[NAME_MORA] === name : name.has(value[NAME_MORA] as never))
52
50
  );
53
51
  }
54
52
 
@@ -1,20 +1,19 @@
1
1
  import {isKey, isPlainObject} from '@oscarpalmer/atoms/is';
2
- import type {ArrayOrPlainObject, Key, PlainObject} from '@oscarpalmer/atoms/models';
2
+ import type {
3
+ ArrayOrPlainObject,
4
+ GenericCallback,
5
+ Key,
6
+ PlainObject,
7
+ } from '@oscarpalmer/atoms/models';
3
8
  import {startBatch, stopBatch} from '../batch';
4
9
  import {PROPERTY_LENGTH, SYMBOL_STATE} from '../constants';
5
- import type {
6
- Computed,
7
- ReactiveArray,
8
- ReactiveProxyState,
9
- ReactiveStore,
10
- InternalProxy,
11
- } from '../models';
10
+ import type {InternalArray, InternalComputed, InternalStore, ReactiveProxyState} from '../models';
12
11
  import {internalComputed} from '../value/computed';
13
12
  import {emitValue, getSignalValue, peekSignalValue} from './value';
14
13
 
15
14
  // #region Functions
16
15
 
17
- export function emitProxyValues(this: InternalProxy): void {
16
+ export function emitProxyValues(this: InternalArray | InternalStore): void {
18
17
  const state = this[SYMBOL_STATE];
19
18
 
20
19
  state.mapped ??= new Map();
@@ -30,10 +29,10 @@ export function emitProxyValues(this: InternalProxy): void {
30
29
  }
31
30
 
32
31
  export function getReactiveValueInProxy(
33
- instance: ReactiveArray<unknown> | ReactiveStore<unknown>,
32
+ instance: InternalArray | InternalStore,
34
33
  key: Key,
35
- ): Computed<unknown> {
36
- const state = (instance as unknown as InternalProxy)[SYMBOL_STATE];
34
+ ): InternalComputed {
35
+ const state = instance[SYMBOL_STATE];
37
36
 
38
37
  state.mapped ??= new Map();
39
38
 
@@ -54,19 +53,29 @@ export function getReactiveValueInProxy(
54
53
  return item[0];
55
54
  }
56
55
 
57
- export function getValueInProxy(this: InternalProxy, first?: unknown): unknown {
56
+ export function getValueInProxy(this: InternalArray | InternalStore, first?: unknown): unknown {
57
+ let signal: InternalComputed | undefined;
58
+
58
59
  if (this[SYMBOL_STATE].isArray ? typeof first === 'number' : isKey(first)) {
59
- return getReactiveValueInProxy(this as never, first as Key).get();
60
+ signal = getReactiveValueInProxy(this, first as Key);
60
61
  }
61
62
 
62
- return getSignalValue.call(this);
63
+ return getSignalValue.call(signal ?? this);
64
+ }
65
+
66
+ function isProxyKey(isArray: boolean, value: unknown): value is Key {
67
+ return isArray ? typeof value === 'number' : isKey(value);
63
68
  }
64
69
 
65
70
  function isProxyObject(isArray: boolean, value: unknown): value is ArrayOrPlainObject {
66
71
  return value == null || (isArray ? Array.isArray(value) : isPlainObject(value));
67
72
  }
68
73
 
69
- export function peekValueInProxy(this: InternalProxy, first?: unknown, second?: boolean): unknown {
74
+ export function peekValueInProxy(
75
+ this: InternalArray | InternalStore,
76
+ first?: unknown,
77
+ second?: boolean,
78
+ ): unknown {
70
79
  const state = this[SYMBOL_STATE];
71
80
 
72
81
  let value: unknown;
@@ -84,40 +93,38 @@ export function peekValueInProxy(this: InternalProxy, first?: unknown, second?:
84
93
 
85
94
  function setProxyObject(state: ReactiveProxyState, value: unknown): void {
86
95
  if (state.isArray) {
87
- (state.value as unknown[]).splice(
88
- 0,
89
- (state.value as unknown[]).length,
90
- ...((value ?? []) as unknown[]),
91
- );
96
+ const values = state.value as unknown[];
97
+
98
+ values.splice(0, values.length, ...((value ?? []) as unknown[]));
92
99
 
93
100
  return;
94
101
  }
95
102
 
96
103
  startBatch();
97
104
 
98
- const actual = (value as Record<string, unknown>) ?? {};
99
- const proxy = state.value as PlainObject;
105
+ const current = state.value as PlainObject;
106
+ const next = (value as Record<string, unknown>) ?? {};
100
107
 
101
- const proxyKeys = Object.keys(proxy);
102
- const actualKeys = Object.keys(actual);
108
+ const currentKeys = Object.keys(current);
109
+ const nextKeys = Object.keys(next);
103
110
 
104
- let {length} = proxyKeys;
111
+ let {length} = currentKeys;
105
112
 
106
113
  for (let index = 0; index < length; index += 1) {
107
- const key = proxyKeys[index];
114
+ const key = currentKeys[index];
108
115
 
109
- proxy[key] = actualKeys.includes(key) ? actual[key] : undefined;
116
+ current[key] = nextKeys.includes(key) ? next[key] : undefined;
110
117
  }
111
118
 
112
- length = actualKeys.length;
119
+ length = nextKeys.length;
113
120
 
114
121
  for (let index = 0; index < length; index += 1) {
115
- const key = actualKeys[index];
122
+ const key = nextKeys[index];
116
123
 
117
- if (!proxyKeys.includes(key)) {
118
- const keyedValue = actual[key];
124
+ if (!currentKeys.includes(key)) {
125
+ const keyedValue = next[key];
119
126
 
120
- proxy[key] = keyedValue;
127
+ current[key] = keyedValue;
121
128
  }
122
129
  }
123
130
 
@@ -131,18 +138,22 @@ function setProxyProperty(state: ReactiveProxyState, property: unknown, value: u
131
138
  return;
132
139
  }
133
140
 
134
- const actual =
135
- (property as number) < 0
136
- ? (state.value as unknown[]).length + (property as number)
137
- : (property as number);
141
+ const array = state.value as unknown[];
142
+ const index = property as number;
143
+
144
+ const actual = index < 0 ? array.length + index : index;
138
145
 
139
146
  if (actual > -1) {
140
- (state.value as unknown[])[actual] = value;
147
+ array[actual] = value;
141
148
  }
142
149
  }
143
150
 
144
- export function setProxyValue(this: InternalProxy, first?: unknown, second?: unknown): void {
145
- const state = this[SYMBOL_STATE] as ReactiveProxyState;
151
+ export function setProxyValue(
152
+ this: InternalArray | InternalStore,
153
+ first?: unknown,
154
+ second?: unknown,
155
+ ): void {
156
+ const state = this[SYMBOL_STATE];
146
157
 
147
158
  if (state.isArray && first === PROPERTY_LENGTH) {
148
159
  (state.value as unknown[]).length = second as number;
@@ -156,55 +167,55 @@ export function setProxyValue(this: InternalProxy, first?: unknown, second?: unk
156
167
  return;
157
168
  }
158
169
 
159
- const property = state.isArray ? typeof first === 'number' : isKey(first);
170
+ const keyed = isProxyKey(state.isArray, first);
160
171
 
161
- if (state.isArray && property && Number.isNaN(first)) {
172
+ if (state.isArray && keyed && Number.isNaN(first)) {
162
173
  return;
163
174
  }
164
175
 
165
- let actual = property ? second : first;
176
+ let actual = keyed ? second : first;
166
177
 
167
178
  if (typeof actual === 'function') {
168
179
  try {
169
- actual = (actual as Function)();
180
+ actual = (actual as GenericCallback)();
170
181
  } catch {
171
182
  return;
172
183
  }
173
184
  }
174
185
 
175
186
  if (actual instanceof Promise) {
176
- if (property) {
187
+ if (keyed) {
177
188
  state.promises ??= new Map();
178
189
 
179
- state.promises.set(first as Key, actual as Promise<never>);
190
+ state.promises.set(first, actual as Promise<never>);
180
191
  } else {
181
192
  state.promise = actual as Promise<never>;
182
193
  }
183
194
 
184
195
  void actual
185
196
  .then(value => {
186
- if (property && state.promises!.get(first as Key) === actual) {
187
- state.promises!.delete(first as Key);
197
+ if (keyed && state.promises?.get(first) === actual) {
198
+ state.promises?.delete(first);
188
199
 
189
200
  setProxyProperty(state, first, value);
190
201
 
191
202
  return;
192
203
  }
193
204
 
194
- if (!property && isProxyObject(state.isArray, value) && state.promise === actual) {
205
+ if (!keyed && isProxyObject(state.isArray, value) && state.promise === actual) {
195
206
  state.promise = undefined;
196
207
 
197
208
  setProxyObject(state, value);
198
209
  }
199
210
  })
200
211
  .catch(() => {
201
- if (property && state.promises!.get(first as Key) === actual) {
202
- state.promises!.delete(first as Key);
203
- } else if (!property && state.promise === actual) {
212
+ if (keyed && state.promises?.get(first) === actual) {
213
+ state.promises?.delete(first);
214
+ } else if (!keyed && state.promise === actual) {
204
215
  state.promise = undefined;
205
216
  }
206
217
  });
207
- } else if (property) {
218
+ } else if (keyed) {
208
219
  setProxyProperty(state, first, actual);
209
220
  } else if (isProxyObject(state.isArray, actual)) {
210
221
  setProxyObject(state, actual);
@@ -212,7 +223,7 @@ export function setProxyValue(this: InternalProxy, first?: unknown, second?: unk
212
223
  }
213
224
 
214
225
  export function setValueInProxy(
215
- instance: InternalProxy,
226
+ instance: InternalArray | InternalStore,
216
227
  target: object,
217
228
  property: PropertyKey,
218
229
  value: unknown,
@@ -228,9 +239,9 @@ export function setValueInProxy(
228
239
  }
229
240
  }
230
241
 
231
- const previous = Reflect.get(target as object, property);
242
+ const previous = Reflect.get(target, property);
232
243
 
233
- if (!(state.equal ?? Object.is)(previous as never, value as never)) {
244
+ if (!(state.equal ?? Object.is)(previous, value)) {
234
245
  Reflect.set(target, property, value);
235
246
 
236
247
  emitValue(instance);
@@ -243,7 +254,7 @@ export function setValueInProxy(
243
254
  return true;
244
255
  }
245
256
 
246
- export function updateProxyValue(this: InternalProxy, callback: unknown): void {
257
+ export function updateProxyValue(this: InternalArray | InternalStore, callback: unknown): void {
247
258
  if (typeof callback !== 'function') {
248
259
  throw new TypeError('Callback must be a function');
249
260
  }