@oscarpalmer/mora 0.27.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.
@@ -1,5 +1,6 @@
1
1
  import { ACTIVE, BATCH, NAME_COMPUTED } from "../constants.mjs";
2
2
  import { effect, runEffect } from "../effect.mjs";
3
+ import { flushHandlers } from "../batch.mjs";
3
4
  import { Reactive } from "./reactive.mjs";
4
5
  //#region src/value/computed.ts
5
6
  var Computed = class extends Reactive {
@@ -10,18 +11,10 @@ var Computed = class extends Reactive {
10
11
  constructor(callback, options) {
11
12
  super(NAME_COMPUTED, void 0, options);
12
13
  this.effect.instance = effect(() => {
13
- if (!this.effect.dirty) return;
14
- const previousComputed = ACTIVE.computed;
15
- ACTIVE.computed = this;
16
- const value = callback();
17
- ACTIVE.computed = previousComputed;
18
- if (!this.state.equal(this.state.value, value)) {
19
- this.state.value = value;
20
- for (const computed of this.state.computeds) computed.effect.dirty = true;
21
- for (const effect of this.state.effects) BATCH.handlers.add(effect);
22
- for (const [, subscription] of this.state.subscriptions) subscription.callback(value);
14
+ if (this.effect.dirty) {
15
+ setValue(this, this.state, callback);
16
+ this.effect.dirty = false;
23
17
  }
24
- this.effect.dirty = false;
25
18
  });
26
19
  }
27
20
  /**
@@ -43,5 +36,33 @@ var Computed = class extends Reactive {
43
36
  function computed(callback, options) {
44
37
  return new Computed(callback, options);
45
38
  }
39
+ function setAndEmit(state, value) {
40
+ if (state.equal(state.value, value)) return;
41
+ state.value = value;
42
+ for (const computed of state.computeds) computed.effect.dirty = true;
43
+ for (const effect of state.effects) BATCH.handlers.add(effect);
44
+ for (const [, subscription] of state.subscriptions) subscription.callback(value);
45
+ flushHandlers();
46
+ }
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
+ }
46
67
  //#endregion
47
68
  export { Computed, computed };
@@ -1,2 +1,40 @@
1
- import { h as Reactive } from "../models-QwNga87R.mjs";
1
+ import { ReactiveOptions, ReactiveState, Unsubscribe } from "../models.mjs";
2
+
3
+ //#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
+ }
39
+ //#endregion
2
40
  export { Reactive };
@@ -1,2 +1,44 @@
1
- import { d as Signal, f as signal } from "../models-QwNga87R.mjs";
1
+ import { Reactive } from "./reactive.mjs";
2
+ import { ReactiveOptions } from "../models.mjs";
3
+
4
+ //#region src/value/signal.d.ts
5
+ declare class Signal<Value> extends Reactive<Value> {
6
+ constructor(value: Value, options?: ReactiveOptions<Value>);
7
+ /**
8
+ * @inheritdoc
9
+ */
10
+ get(): Value;
11
+ /**
12
+ * Set the value
13
+ * @param value New value
14
+ */
15
+ set(value: Value | (() => Value | Promise<Value>) | Promise<Value>): void;
16
+ /**
17
+ * Update the value _(based on the current value)_
18
+ * @param callback Callback to update the value
19
+ */
20
+ update(callback: (value: Value) => Value): void;
21
+ }
22
+ /**
23
+ * Create a reactive value from a function result
24
+ * @param value Initial value
25
+ * @param options Reactivity options
26
+ * @returns Reactive value
27
+ */
28
+ declare function signal<Value>(value: () => Value | Promise<Value>, options?: ReactiveOptions<Value>): Signal<Value>;
29
+ /**
30
+ * Create a reactive value from a promise
31
+ * @param value Initial value
32
+ * @param options Reactivity options
33
+ * @returns Reactive value
34
+ */
35
+ declare function signal<Value>(value: Promise<Value>, options?: ReactiveOptions<Value>): Signal<Value>;
36
+ /**
37
+ * Create a reactive value
38
+ * @param value Initial value
39
+ * @param options Reactivity options
40
+ * @returns Reactive value
41
+ */
42
+ declare function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value>;
43
+ //#endregion
2
44
  export { Signal, signal };
@@ -17,10 +17,7 @@ var Signal = class extends Reactive {
17
17
  * @param value New value
18
18
  */
19
19
  set(value) {
20
- if (!this.state.equal(this.state.value, value)) {
21
- this.state.value = value;
22
- emitValue(this.state);
23
- }
20
+ setValue(this.state, value);
24
21
  }
25
22
  /**
26
23
  * Update the value _(based on the current value)_
@@ -30,14 +27,33 @@ var Signal = class extends Reactive {
30
27
  this.set(callback(this.state.value));
31
28
  }
32
29
  };
33
- /**
34
- * Create a reactive value
35
- * @param value Initial value
36
- * @param options Reactivity options
37
- * @returns Reactive value
38
- */
30
+ function setAndEmit(state, value) {
31
+ if (!state.equal(state.value, value)) {
32
+ state.value = value;
33
+ emitValue(state);
34
+ }
35
+ }
36
+ function setValue(state, value) {
37
+ try {
38
+ let actual = value;
39
+ if (typeof value === "function") actual = value();
40
+ if (actual instanceof Promise) {
41
+ state.promise = actual;
42
+ actual.then((value) => {
43
+ if (actual === state.promise) {
44
+ state.promise = void 0;
45
+ setAndEmit(state, value);
46
+ }
47
+ }).catch(() => {
48
+ if (actual === state.promise) state.promise = void 0;
49
+ });
50
+ } else setAndEmit(state, actual);
51
+ } catch {}
52
+ }
39
53
  function signal(value, options) {
40
- return new Signal(value, options);
54
+ const instance = new Signal(void 0, options);
55
+ instance.set(value);
56
+ return instance;
41
57
  }
42
58
  //#endregion
43
59
  export { Signal, signal };
@@ -1,4 +1,5 @@
1
- import { h as Reactive, s as ReactiveOptions, u as Unsubscribe } from "../models-QwNga87R.mjs";
1
+ import { Reactive } from "./reactive.mjs";
2
+ import { ReactiveOptions, Unsubscribe } from "../models.mjs";
2
3
  import { Key, PlainObject } from "@oscarpalmer/atoms/models";
3
4
 
4
5
  //#region src/value/store.d.ts
@@ -49,13 +50,13 @@ declare class Store<Value extends PlainObject> extends Reactive<Value, Value> {
49
50
  * Set the value
50
51
  * @param value New value _(defaults to an empty object)_
51
52
  */
52
- set(value?: Value): void;
53
+ set(value?: Value | (() => null | undefined | Value | Promise<null | undefined | Value>) | Promise<null | undefined | Value>): void;
53
54
  /**
54
55
  * Set a value by key
55
56
  * @param key Key of the value to set
56
57
  * @param value New value
57
58
  */
58
- set<Key extends keyof Value>(key: Key, value: Value[Key]): void;
59
+ set<Key extends keyof Value>(key: Key, value: Value[Key] | (() => Value[Key] | Promise<Value[Key]>) | Promise<Value[Key]>): void;
59
60
  /**
60
61
  * Set a value by key
61
62
  * @param key Key of the value to set
@@ -86,6 +87,20 @@ declare class Store<Value extends PlainObject> extends Reactive<Value, Value> {
86
87
  */
87
88
  update(callback: (value: Value) => Value): void;
88
89
  }
90
+ /**
91
+ * Create a reactive store from a function result
92
+ * @param value Initial object value
93
+ * @param options Reactivity options
94
+ * @returns Reactive store
95
+ */
96
+ declare function store<Value extends PlainObject>(value: () => Value | Promise<Value>, options?: ReactiveOptions<Value>): Store<Value>;
97
+ /**
98
+ * Create a reactive store from a promise
99
+ * @param value Initial object value
100
+ * @param options Reactivity options
101
+ * @returns Reactive store
102
+ */
103
+ declare function store<Value extends PlainObject>(value: Promise<Value>, options?: ReactiveOptions<Value>): Store<Value>;
89
104
  /**
90
105
  * Create a reactive store
91
106
  * @param value Initial object value
@@ -1,4 +1,5 @@
1
1
  import { NAME_STORE } from "../constants.mjs";
2
+ import { startBatch, stopBatch } from "../batch.mjs";
2
3
  import { noop, subscribe } from "../subscription.mjs";
3
4
  import { Reactive } from "./reactive.mjs";
4
5
  import { getValue } from "../helpers/value.mjs";
@@ -32,8 +33,7 @@ var Store = class extends Reactive {
32
33
  return isKey(key) ? this.state.value[key] : { ...this.state.value };
33
34
  }
34
35
  set(first, second) {
35
- if (isKey(first)) this.state.value[first] = second;
36
- else if (first == null || isPlainObject(first)) setProxyValue(this.state.value, first ?? {});
36
+ setProxyValue(false, this.state, isStoreObject, isKey, setObject, setProperty, first, second);
37
37
  }
38
38
  subscribe(first, second) {
39
39
  if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
@@ -44,18 +44,38 @@ var Store = class extends Reactive {
44
44
  * @param callback Callback to update the value
45
45
  */
46
46
  update(callback) {
47
- const updated = callback({ ...this.state.value });
48
- if (updated == null || isPlainObject(updated)) setProxyValue(this.state.value, updated ?? {});
47
+ const updated = callback(this.state.value);
48
+ if (updated == null || isPlainObject(updated)) setObject(this.state, updated);
49
49
  }
50
50
  };
51
- /**
52
- * Create a reactive store
53
- * @param value Initial object value
54
- * @param options Reactivity options
55
- * @returns Reactive store
56
- */
51
+ function isStoreObject(value) {
52
+ return value == null || isPlainObject(value);
53
+ }
54
+ function setObject(state, value) {
55
+ startBatch();
56
+ const actual = value ?? {};
57
+ const proxy = state.value;
58
+ const proxyKeys = Object.keys(proxy);
59
+ const actualKeys = Object.keys(actual);
60
+ let { length } = proxyKeys;
61
+ for (let index = 0; index < length; index += 1) {
62
+ const key = proxyKeys[index];
63
+ proxy[key] = actualKeys.includes(key) ? actual[key] : void 0;
64
+ }
65
+ length = actualKeys.length;
66
+ for (let index = 0; index < length; index += 1) {
67
+ const key = actualKeys[index];
68
+ if (!proxyKeys.includes(key)) proxy[key] = actual[key];
69
+ }
70
+ stopBatch();
71
+ }
72
+ function setProperty(state, key, value) {
73
+ state.value[key] = value;
74
+ }
57
75
  function store(value, options) {
58
- return new Store(isPlainObject(value) ? value : {}, options);
76
+ const instance = new Store({}, options);
77
+ instance.set(value);
78
+ return instance;
59
79
  }
60
80
  //#endregion
61
81
  export { Store, store };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/mora",
3
- "version": "0.27.0",
3
+ "version": "0.28.0",
4
4
  "description": "Signals and stuff…",
5
5
  "keywords": [
6
6
  "reactive",
@@ -39,12 +39,12 @@
39
39
  "test:leak": "vpx vp test run --detect-async-leaks --coverage"
40
40
  },
41
41
  "dependencies": {
42
- "@oscarpalmer/atoms": "^0.165"
42
+ "@oscarpalmer/atoms": "^0.172"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/node": "^25.5",
46
46
  "@vitest/coverage-istanbul": "^4.1",
47
- "jsdom": "^28.1",
47
+ "jsdom": "^29",
48
48
  "tsdown": "^0.21",
49
49
  "typescript": "^5.9",
50
50
  "vite": "npm:@voidzero-dev/vite-plus-core@latest",
@@ -1,5 +1,4 @@
1
1
  import type {ArrayOrPlainObject, Key, PlainObject} from '@oscarpalmer/atoms/models';
2
- import {startBatch, stopBatch} from '../batch';
3
2
  import {PROPERTY_LENGTH} from '../constants';
4
3
  import type {InternalComputed, ReactiveState, SetValueInProxyParameters} from '../models';
5
4
  import type {ReactiveArray} from '../value/array';
@@ -66,33 +65,81 @@ export function getReactiveValueInProxy(
66
65
  return item;
67
66
  }
68
67
 
69
- export function setProxyValue(proxy: ArrayOrPlainObject, value: ArrayOrPlainObject): void {
70
- startBatch();
68
+ export function setProxyValue<Value, Item = Value>(
69
+ array: boolean,
70
+ state: ReactiveState<Value, Item>,
71
+ isObject: (value: unknown) => value is Value | undefined,
72
+ isProperty: (value: unknown) => boolean,
73
+ setObject: (state: ReactiveState<Value, Item>, value: Value | undefined) => void,
74
+ setProperty: (state: ReactiveState<Value, Item>, property: unknown, value: Item) => void,
75
+ first?: unknown,
76
+ second?: unknown,
77
+ ): void {
78
+ if (array && first === PROPERTY_LENGTH) {
79
+ (state.value as unknown[]).length = second as number;
71
80
 
72
- const proxyKeys = Object.keys(proxy);
73
- const valueKeys = Object.keys(value);
81
+ return;
82
+ }
74
83
 
75
- let {length} = proxyKeys;
84
+ if (isObject(first)) {
85
+ setObject(state, first);
76
86
 
77
- for (let index = 0; index < length; index += 1) {
78
- const key = proxyKeys[index];
79
-
80
- (proxy as PlainObject)[key] = valueKeys.includes(key) ? (value as PlainObject)[key] : undefined;
87
+ return;
81
88
  }
82
89
 
83
- length = valueKeys.length;
90
+ const property = isProperty(first);
84
91
 
85
- for (let index = 0; index < length; index += 1) {
86
- const key = valueKeys[index];
92
+ if (array && property && Number.isNaN(first)) {
93
+ return;
94
+ }
87
95
 
88
- if (!proxyKeys.includes(key)) {
89
- const keyedValue = (value as PlainObject)[key];
96
+ let actual = property ? second : first;
90
97
 
91
- (proxy as PlainObject)[key] = keyedValue;
98
+ if (typeof actual === 'function') {
99
+ try {
100
+ actual = (actual as Function)();
101
+ } catch {
102
+ return;
92
103
  }
93
104
  }
94
105
 
95
- stopBatch();
106
+ if (actual instanceof Promise) {
107
+ if (property) {
108
+ state.promises ??= new Map();
109
+
110
+ state.promises.set(first as Key, actual as Promise<never>);
111
+ } else {
112
+ state.promise = actual as Promise<never>;
113
+ }
114
+
115
+ void actual
116
+ .then(value => {
117
+ if (property && state.promises!.get(first as Key) === actual) {
118
+ state.promises!.delete(first as Key);
119
+
120
+ setProperty(state, first, value);
121
+
122
+ return;
123
+ }
124
+
125
+ if (!property && isObject(value) && state.promise === actual) {
126
+ state.promise = undefined;
127
+
128
+ setObject(state, value);
129
+ }
130
+ })
131
+ .catch(() => {
132
+ if (property && state.promises!.get(first as Key) === actual) {
133
+ state.promises!.delete(first as Key);
134
+ } else if (!property && state.promise === actual) {
135
+ state.promise = undefined;
136
+ }
137
+ });
138
+ } else if (property) {
139
+ setProperty(state, first, actual as Item);
140
+ } else if (isObject(actual)) {
141
+ setObject(state, actual);
142
+ }
96
143
  }
97
144
 
98
145
  export function setValueInProxy<Value extends ArrayOrPlainObject, Equal>(
package/src/models.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type {GenericCallback} from '@oscarpalmer/atoms/models';
1
+ import type {GenericCallback, Key} from '@oscarpalmer/atoms/models';
2
2
  import type {Effect} from './effect';
3
3
  import type {Subscription} from './subscription';
4
4
  import type {Computed} from './value/computed';
@@ -47,6 +47,8 @@ export type ReactiveState<Value, Equal> = {
47
47
  computeds: Set<Computed<unknown>>;
48
48
  effects: Set<Effect>;
49
49
  equal: (first: Equal, second: Equal) => boolean;
50
+ promise?: Promise<Value>;
51
+ promises?: Map<Key, Promise<never>>;
50
52
  subscriptions: Map<GenericCallback, Subscription>;
51
53
  value: Value;
52
54
  };
@@ -1,6 +1,11 @@
1
1
  import type {GenericCallback} from '@oscarpalmer/atoms/models';
2
2
  import {METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ARRAY, PROPERTY_LENGTH} from '../constants';
3
- import {emityProxyValues, getReactiveValueInProxy, setValueInProxy} from '../helpers/proxy';
3
+ import {
4
+ emityProxyValues,
5
+ getReactiveValueInProxy,
6
+ setProxyValue,
7
+ setValueInProxy,
8
+ } from '../helpers/proxy';
4
9
  import {emitValue, equalArrays, getValue} from '../helpers/value';
5
10
  import type {ReactiveOptions, ReactiveState, Unsubscribe} from '../models';
6
11
  import {noop, subscribe} from '../subscription';
@@ -137,7 +142,7 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
137
142
  return this.#size.peek();
138
143
  }
139
144
 
140
- return typeof value === 'number' ? this.state.value.at(value) : [...this.state.value];
145
+ return typeof value === 'number' ? this.state.value.at(value) : this.state.value.slice();
141
146
  }
142
147
 
143
148
  /**
@@ -161,14 +166,19 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
161
166
  * Set the value
162
167
  * @param value New array of items _(defaults to an empty array)_
163
168
  */
164
- set(value?: Item[]): void;
169
+ set(
170
+ value?:
171
+ | Item[]
172
+ | (() => null | undefined | Item[] | Promise<null | undefined | Item[]>)
173
+ | Promise<null | undefined | Item[]>,
174
+ ): void;
165
175
 
166
176
  /**
167
177
  * Set the value at an index
168
178
  * @param index Index of item to set __(if negative, starts from the end)_
169
179
  * @param value New item
170
180
  */
171
- set(index: number, value: Item): void;
181
+ set(index: number, value: Item | (() => Item | Promise<Item>) | Promise<Item>): void;
172
182
 
173
183
  /**
174
184
  * Set the length of the array
@@ -176,14 +186,17 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
176
186
  */
177
187
  set(property: typeof PROPERTY_LENGTH, value: number): void;
178
188
 
179
- set(first?: number | typeof PROPERTY_LENGTH | Item[], second?: number | Item): void {
180
- if (first == null || Array.isArray(first)) {
181
- this.state.value.splice(0, this.state.value.length, ...(first ?? []));
182
- } else if (first === PROPERTY_LENGTH) {
183
- this.length = second as number;
184
- } else if (typeof first === 'number' && !Number.isNaN(first)) {
185
- setAtIndex(this.state.value, first, second as Item);
186
- }
189
+ set(first?: unknown, second?: unknown): void {
190
+ setProxyValue<Item[], Item>(
191
+ true,
192
+ this.state,
193
+ isArrayValue,
194
+ isArrayIndex,
195
+ setArray,
196
+ setAtIndex,
197
+ first,
198
+ second,
199
+ );
187
200
  }
188
201
 
189
202
  /**
@@ -248,14 +261,53 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
248
261
  }
249
262
  }
250
263
 
264
+ /**
265
+ * Create a reactive array from a function result
266
+ * @param value Initial array of items
267
+ * @param options Reactivity options
268
+ * @returns Reactive array
269
+ */
270
+ export function array<Item>(
271
+ value: () => Item[] | Promise<Item[]>,
272
+ options?: ReactiveOptions<Item>,
273
+ ): ReactiveArray<Item>;
274
+
275
+ /**
276
+ * Create a reactive array from a promise
277
+ * @param value Initial array of items
278
+ * @param options Reactivity options
279
+ * @returns Reactive array
280
+ */
281
+ export function array<Item>(
282
+ value: Promise<Item[]>,
283
+ options?: ReactiveOptions<Item>,
284
+ ): ReactiveArray<Item>;
285
+
251
286
  /**
252
287
  * Create a reactive array
253
288
  * @param value Initial array of items
254
289
  * @param options Reactivity options
255
290
  * @returns Reactive array
256
291
  */
257
- export function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item> {
258
- return new ReactiveArray(Array.isArray(value) ? value : [], options);
292
+ export function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item>;
293
+
294
+ export function array<Item>(
295
+ value: Item[] | (() => Item[] | Promise<Item[]>) | Promise<Item[]>,
296
+ options?: ReactiveOptions<Item>,
297
+ ): ReactiveArray<Item> {
298
+ const instance = new ReactiveArray([], options);
299
+
300
+ instance.set(value);
301
+
302
+ return instance;
303
+ }
304
+
305
+ function isArrayIndex(value: unknown): boolean {
306
+ return typeof value === 'number';
307
+ }
308
+
309
+ function isArrayValue<Item>(value: unknown): value is Item[] | undefined {
310
+ return value == null || Array.isArray(value);
259
311
  }
260
312
 
261
313
  function updateArray<Item>(
@@ -265,7 +317,7 @@ function updateArray<Item>(
265
317
  length: Signal<number>,
266
318
  ): unknown {
267
319
  const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
268
- const previousArray = affectsLength ? [] : [...array];
320
+ const previousArray = affectsLength ? [] : array.slice();
269
321
  const previousLength = array.length;
270
322
 
271
323
  return (...args: unknown[]): unknown => {
@@ -283,10 +335,14 @@ function updateArray<Item>(
283
335
  };
284
336
  }
285
337
 
286
- function setAtIndex<Item>(array: Item[], index: number, value: Item): void {
287
- const actual = index < 0 ? array.length + index : index;
338
+ function setArray<Item>(state: ReactiveState<Item[], Item>, value: Item[] | undefined): void {
339
+ state.value.splice(0, state.value.length, ...(value ?? []));
340
+ }
341
+
342
+ function setAtIndex<Item>(state: ReactiveState<Item[], Item>, index: unknown, value: Item): void {
343
+ const actual = (index as number) < 0 ? state.value.length + (index as number) : (index as number);
288
344
 
289
345
  if (actual > -1) {
290
- array[actual] = value;
346
+ state.value[actual] = value;
291
347
  }
292
348
  }