@oscarpalmer/mora 0.23.0 → 0.24.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/dist/constants.js +3 -1
- package/dist/effect.js +2 -2
- package/dist/helpers/is.js +2 -2
- package/dist/helpers/proxy.js +9 -5
- package/dist/mora.full.js +33 -21
- package/dist/value/array.js +5 -7
- package/dist/value/reactive.js +2 -1
- package/dist/value/store.js +5 -2
- package/package.json +4 -5
- package/src/constants.ts +4 -0
- package/src/effect.ts +2 -2
- package/src/helpers/is.ts +4 -3
- package/src/helpers/proxy.ts +36 -9
- package/src/value/array.ts +7 -12
- package/src/value/reactive.ts +2 -1
- package/src/value/store.ts +16 -5
- package/types/constants.d.ts +2 -0
- package/types/helpers/proxy.d.ts +3 -1
- package/types/value/store.d.ts +10 -3
package/dist/constants.js
CHANGED
|
@@ -23,6 +23,7 @@ const METHODS_UPDATE = new Set([
|
|
|
23
23
|
const NAME_ARRAY = "array";
|
|
24
24
|
const NAME_COMPUTED = "computed";
|
|
25
25
|
const NAME_EFFECT = "effect";
|
|
26
|
+
const NAME_MORA = "$mora";
|
|
26
27
|
const NAME_SIGNAL = "signal";
|
|
27
28
|
const NAME_STORE = "store";
|
|
28
29
|
const NAMES = new Set([
|
|
@@ -31,4 +32,5 @@ const NAMES = new Set([
|
|
|
31
32
|
NAME_SIGNAL,
|
|
32
33
|
NAME_STORE
|
|
33
34
|
]);
|
|
34
|
-
|
|
35
|
+
const PROPERTY_LENGTH = "length";
|
|
36
|
+
export { ACTIVE, ARRAY_OFFSET, ARRAY_PEEK, ARRAY_THRESHOLD, BATCH, METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAMES, NAME_ARRAY, NAME_COMPUTED, NAME_EFFECT, NAME_MORA, NAME_SIGNAL, NAME_STORE, PROPERTY_LENGTH };
|
package/dist/effect.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ACTIVE, NAME_EFFECT } from "./constants.js";
|
|
1
|
+
import { ACTIVE, NAME_EFFECT, NAME_MORA } from "./constants.js";
|
|
2
2
|
var Effect = class {
|
|
3
3
|
constructor(callback) {
|
|
4
|
-
Object.defineProperty(this,
|
|
4
|
+
Object.defineProperty(this, NAME_MORA, { value: NAME_EFFECT });
|
|
5
5
|
this.state = { callback };
|
|
6
6
|
runEffect(this);
|
|
7
7
|
}
|
package/dist/helpers/is.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NAMES, NAME_ARRAY, NAME_COMPUTED, NAME_EFFECT, NAME_SIGNAL, NAME_STORE } from "../constants.js";
|
|
1
|
+
import { NAMES, NAME_ARRAY, NAME_COMPUTED, NAME_EFFECT, NAME_MORA, NAME_SIGNAL, NAME_STORE } from "../constants.js";
|
|
2
2
|
function isArray(value) {
|
|
3
3
|
return isMora(value, NAME_ARRAY);
|
|
4
4
|
}
|
|
@@ -9,7 +9,7 @@ function isEffect(value) {
|
|
|
9
9
|
return isMora(value, NAME_EFFECT);
|
|
10
10
|
}
|
|
11
11
|
function isMora(value, name) {
|
|
12
|
-
return typeof value === "object" && value != null && "$mora" in value && (typeof name === "string" ? value
|
|
12
|
+
return typeof value === "object" && value != null && "$mora" in value && (typeof name === "string" ? value["$mora"] === name : name.has(value["$mora"]));
|
|
13
13
|
}
|
|
14
14
|
function isReactive(value) {
|
|
15
15
|
return isMora(value, NAMES);
|
package/dist/helpers/proxy.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
import { PROPERTY_LENGTH } from "../constants.js";
|
|
1
2
|
import { startBatch, stopBatch } from "../batch.js";
|
|
2
3
|
import { computed } from "../value/computed.js";
|
|
3
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
|
+
}
|
|
4
11
|
function getReactiveValueInProxy(reactive, mapped, key, isArray) {
|
|
5
12
|
let item = mapped.get(key);
|
|
6
13
|
if (item == null) {
|
|
7
|
-
item = computed(() =>
|
|
8
|
-
const value = reactive.get();
|
|
9
|
-
return isArray ? value.at(key) : value[key];
|
|
10
|
-
});
|
|
14
|
+
item = computed(() => isArray ? reactive.get().at(key) : reactive.get()[key]);
|
|
11
15
|
mapped.set(key, item);
|
|
12
16
|
}
|
|
13
17
|
return item;
|
|
@@ -41,4 +45,4 @@ function setValueInProxy(parameters) {
|
|
|
41
45
|
}
|
|
42
46
|
return true;
|
|
43
47
|
}
|
|
44
|
-
export { getReactiveValueInProxy, setProxyValue, setValueInProxy };
|
|
48
|
+
export { emityProxyValues, getReactiveValueInProxy, setProxyValue, setValueInProxy };
|
package/dist/mora.full.js
CHANGED
|
@@ -23,6 +23,7 @@ const METHODS_UPDATE = new Set([
|
|
|
23
23
|
const NAME_ARRAY = 'array';
|
|
24
24
|
const NAME_COMPUTED = 'computed';
|
|
25
25
|
const NAME_EFFECT = 'effect';
|
|
26
|
+
const NAME_MORA = '$mora';
|
|
26
27
|
const NAME_SIGNAL = 'signal';
|
|
27
28
|
const NAME_STORE = 'store';
|
|
28
29
|
const NAMES = new Set([
|
|
@@ -31,10 +32,11 @@ const NAMES = new Set([
|
|
|
31
32
|
NAME_SIGNAL,
|
|
32
33
|
NAME_STORE,
|
|
33
34
|
]);
|
|
35
|
+
const PROPERTY_LENGTH = 'length';
|
|
34
36
|
|
|
35
37
|
class Effect {
|
|
36
38
|
constructor(callback) {
|
|
37
|
-
Object.defineProperty(this,
|
|
39
|
+
Object.defineProperty(this, NAME_MORA, {
|
|
38
40
|
value: NAME_EFFECT,
|
|
39
41
|
});
|
|
40
42
|
this.state = {
|
|
@@ -91,10 +93,10 @@ function isEffect(value) {
|
|
|
91
93
|
function isMora(value, name) {
|
|
92
94
|
return (typeof value === 'object' &&
|
|
93
95
|
value != null &&
|
|
94
|
-
|
|
96
|
+
NAME_MORA in value &&
|
|
95
97
|
(typeof name === 'string'
|
|
96
|
-
? value
|
|
97
|
-
: name.has(value
|
|
98
|
+
? value[NAME_MORA] === name
|
|
99
|
+
: name.has(value[NAME_MORA])));
|
|
98
100
|
}
|
|
99
101
|
/**
|
|
100
102
|
* Is the value reactive?
|
|
@@ -186,7 +188,7 @@ class Reactive {
|
|
|
186
188
|
if (typeof options === 'object' && typeof options.equal === 'function') {
|
|
187
189
|
this.state.equal = options.equal;
|
|
188
190
|
}
|
|
189
|
-
Object.defineProperty(this,
|
|
191
|
+
Object.defineProperty(this, NAME_MORA, {
|
|
190
192
|
value: name,
|
|
191
193
|
});
|
|
192
194
|
}
|
|
@@ -328,15 +330,20 @@ function getValue(state) {
|
|
|
328
330
|
return state.value;
|
|
329
331
|
}
|
|
330
332
|
|
|
333
|
+
function emityProxyValues(state, mapped) {
|
|
334
|
+
const values = [...mapped.values()];
|
|
335
|
+
const { length } = values;
|
|
336
|
+
for (let index = 0; index < length; index += 1) {
|
|
337
|
+
values[index].effect.dirty = true;
|
|
338
|
+
}
|
|
339
|
+
emitValue(state);
|
|
340
|
+
}
|
|
331
341
|
function getReactiveValueInProxy(reactive, mapped, key, isArray) {
|
|
332
342
|
let item = mapped.get(key);
|
|
333
343
|
if (item == null) {
|
|
334
|
-
item = computed(() =>
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
? value.at(key)
|
|
338
|
-
: value[key];
|
|
339
|
-
});
|
|
344
|
+
item = computed(() => isArray
|
|
345
|
+
? reactive.get().at(key)
|
|
346
|
+
: reactive.get()[key]);
|
|
340
347
|
mapped.set(key, item);
|
|
341
348
|
}
|
|
342
349
|
return item;
|
|
@@ -366,7 +373,7 @@ function setValueInProxy(parameters) {
|
|
|
366
373
|
const { isArray, length, property, state, target, value } = parameters;
|
|
367
374
|
if (isArray) {
|
|
368
375
|
const isIndex = !Number.isNaN(Number(property));
|
|
369
|
-
const isLength = property ===
|
|
376
|
+
const isLength = property === PROPERTY_LENGTH;
|
|
370
377
|
if (!(isIndex || isLength)) {
|
|
371
378
|
return Reflect.set(target, property, value);
|
|
372
379
|
}
|
|
@@ -473,10 +480,7 @@ class ReactiveArray extends Reactive {
|
|
|
473
480
|
if (typeof first === 'number') {
|
|
474
481
|
return getReactiveValueInProxy(this, this.#indiced, first, true).get();
|
|
475
482
|
}
|
|
476
|
-
|
|
477
|
-
return this.length;
|
|
478
|
-
}
|
|
479
|
-
return getValue(this.state);
|
|
483
|
+
return first === PROPERTY_LENGTH ? this.length : getValue(this.state);
|
|
480
484
|
}
|
|
481
485
|
/**
|
|
482
486
|
* Create a computed, mapped array
|
|
@@ -493,16 +497,15 @@ class ReactiveArray extends Reactive {
|
|
|
493
497
|
* Use this only if you're modifying nested data that would be ignored by equality checks._
|
|
494
498
|
*/
|
|
495
499
|
notify() {
|
|
496
|
-
|
|
500
|
+
emityProxyValues(this.state, this.#indiced);
|
|
497
501
|
}
|
|
498
502
|
peek(value) {
|
|
499
503
|
if (value === 'length') {
|
|
500
504
|
return this.#size.peek();
|
|
501
505
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
return [...this.state.value];
|
|
506
|
+
return typeof value === 'number'
|
|
507
|
+
? this.state.value.at(value)
|
|
508
|
+
: [...this.state.value];
|
|
506
509
|
}
|
|
507
510
|
/**
|
|
508
511
|
* Remove and return the last item of the array
|
|
@@ -631,6 +634,15 @@ class Store extends Reactive {
|
|
|
631
634
|
? getReactiveValueInProxy(this, this.#keyed, key, false).get()
|
|
632
635
|
: getValue(this.state);
|
|
633
636
|
}
|
|
637
|
+
/**
|
|
638
|
+
* Notify dependents of changes
|
|
639
|
+
*
|
|
640
|
+
* _This bypasses equality checks and will immediately notify dependents.
|
|
641
|
+
* Use this only if you're modifying nested data that would be ignored by equality checks._
|
|
642
|
+
*/
|
|
643
|
+
notify() {
|
|
644
|
+
emityProxyValues(this.state, this.#keyed);
|
|
645
|
+
}
|
|
634
646
|
peek(key) {
|
|
635
647
|
return isKey(key) ? this.state.value[key] : { ...this.state.value };
|
|
636
648
|
}
|
package/dist/value/array.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ARRAY, PROPERTY_LENGTH } from "../constants.js";
|
|
1
2
|
import { noop, subscribe } from "../subscription.js";
|
|
2
|
-
import { METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ARRAY } from "../constants.js";
|
|
3
3
|
import { Reactive } from "./reactive.js";
|
|
4
4
|
import { computed } from "./computed.js";
|
|
5
5
|
import { emitValue, equalArrays, getValue } from "../helpers/value.js";
|
|
6
|
-
import { getReactiveValueInProxy, setValueInProxy } from "../helpers/proxy.js";
|
|
6
|
+
import { emityProxyValues, getReactiveValueInProxy, setValueInProxy } from "../helpers/proxy.js";
|
|
7
7
|
import { signal } from "./signal.js";
|
|
8
8
|
var ReactiveArray = class extends Reactive {
|
|
9
9
|
#indiced = /* @__PURE__ */ new Map();
|
|
@@ -36,19 +36,17 @@ var ReactiveArray = class extends Reactive {
|
|
|
36
36
|
}
|
|
37
37
|
get(first) {
|
|
38
38
|
if (typeof first === "number") return getReactiveValueInProxy(this, this.#indiced, first, true).get();
|
|
39
|
-
|
|
40
|
-
return getValue(this.state);
|
|
39
|
+
return first === "length" ? this.length : getValue(this.state);
|
|
41
40
|
}
|
|
42
41
|
map(callback) {
|
|
43
42
|
return computed(() => this.get().map(callback));
|
|
44
43
|
}
|
|
45
44
|
notify() {
|
|
46
|
-
|
|
45
|
+
emityProxyValues(this.state, this.#indiced);
|
|
47
46
|
}
|
|
48
47
|
peek(value) {
|
|
49
48
|
if (value === "length") return this.#size.peek();
|
|
50
|
-
|
|
51
|
-
return [...this.state.value];
|
|
49
|
+
return typeof value === "number" ? this.state.value.at(value) : [...this.state.value];
|
|
52
50
|
}
|
|
53
51
|
pop() {
|
|
54
52
|
return this.state.value.pop();
|
package/dist/value/reactive.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NAME_MORA } from "../constants.js";
|
|
1
2
|
import { subscribe, unsubscribe } from "../subscription.js";
|
|
2
3
|
var Reactive = class {
|
|
3
4
|
state = {
|
|
@@ -10,7 +11,7 @@ var Reactive = class {
|
|
|
10
11
|
constructor(name, value, options) {
|
|
11
12
|
this.state.value = value;
|
|
12
13
|
if (typeof options === "object" && typeof options.equal === "function") this.state.equal = options.equal;
|
|
13
|
-
Object.defineProperty(this,
|
|
14
|
+
Object.defineProperty(this, NAME_MORA, { value: name });
|
|
14
15
|
}
|
|
15
16
|
peek() {
|
|
16
17
|
return this.state.value;
|
package/dist/value/store.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { noop, subscribe } from "../subscription.js";
|
|
2
1
|
import { NAME_STORE } from "../constants.js";
|
|
2
|
+
import { noop, subscribe } from "../subscription.js";
|
|
3
3
|
import { Reactive } from "./reactive.js";
|
|
4
4
|
import { getValue } from "../helpers/value.js";
|
|
5
|
-
import { getReactiveValueInProxy, setProxyValue, setValueInProxy } from "../helpers/proxy.js";
|
|
5
|
+
import { emityProxyValues, getReactiveValueInProxy, setProxyValue, setValueInProxy } from "../helpers/proxy.js";
|
|
6
6
|
import { isKey, isPlainObject } from "@oscarpalmer/atoms/is";
|
|
7
7
|
var Store = class extends Reactive {
|
|
8
8
|
#keyed = /* @__PURE__ */ new Map();
|
|
@@ -18,6 +18,9 @@ var Store = class extends Reactive {
|
|
|
18
18
|
get(key) {
|
|
19
19
|
return isKey(key) ? getReactiveValueInProxy(this, this.#keyed, key, false).get() : getValue(this.state);
|
|
20
20
|
}
|
|
21
|
+
notify() {
|
|
22
|
+
emityProxyValues(this.state, this.#keyed);
|
|
23
|
+
}
|
|
21
24
|
peek(key) {
|
|
22
25
|
return isKey(key) ? this.state.value[key] : { ...this.state.value };
|
|
23
26
|
}
|
package/package.json
CHANGED
|
@@ -11,11 +11,10 @@
|
|
|
11
11
|
"@biomejs/biome": "^2.3",
|
|
12
12
|
"@rollup/plugin-node-resolve": "^16",
|
|
13
13
|
"@rollup/plugin-typescript": "^12.3",
|
|
14
|
-
"@types/node": "^24.
|
|
14
|
+
"@types/node": "^24.10",
|
|
15
15
|
"@vitest/coverage-istanbul": "^4",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"rollup": "^4.52",
|
|
16
|
+
"jsdom": "^27.2",
|
|
17
|
+
"rollup": "^4.53",
|
|
19
18
|
"tslib": "^2.8",
|
|
20
19
|
"typescript": "^5.9",
|
|
21
20
|
"vite": "npm:rolldown-vite@latest",
|
|
@@ -47,5 +46,5 @@
|
|
|
47
46
|
},
|
|
48
47
|
"type": "module",
|
|
49
48
|
"types": "./types/index.d.ts",
|
|
50
|
-
"version": "0.
|
|
49
|
+
"version": "0.24.0"
|
|
51
50
|
}
|
package/src/constants.ts
CHANGED
|
@@ -37,6 +37,8 @@ export const NAME_COMPUTED = 'computed';
|
|
|
37
37
|
|
|
38
38
|
export const NAME_EFFECT = 'effect';
|
|
39
39
|
|
|
40
|
+
export const NAME_MORA = '$mora';
|
|
41
|
+
|
|
40
42
|
export const NAME_SIGNAL = 'signal';
|
|
41
43
|
|
|
42
44
|
export const NAME_STORE = 'store';
|
|
@@ -47,3 +49,5 @@ export const NAMES: Set<string> = new Set([
|
|
|
47
49
|
NAME_SIGNAL,
|
|
48
50
|
NAME_STORE,
|
|
49
51
|
]);
|
|
52
|
+
|
|
53
|
+
export const PROPERTY_LENGTH = 'length';
|
package/src/effect.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type {GenericCallback} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import {ACTIVE, NAME_EFFECT} from './constants';
|
|
2
|
+
import {ACTIVE, NAME_EFFECT, NAME_MORA} from './constants';
|
|
3
3
|
import type {EffectState, InternalEffect} from './models';
|
|
4
4
|
|
|
5
5
|
export class Effect {
|
|
@@ -8,7 +8,7 @@ export class Effect {
|
|
|
8
8
|
private declare readonly state: EffectState;
|
|
9
9
|
|
|
10
10
|
constructor(callback: GenericCallback) {
|
|
11
|
-
Object.defineProperty(this,
|
|
11
|
+
Object.defineProperty(this, NAME_MORA, {
|
|
12
12
|
value: NAME_EFFECT,
|
|
13
13
|
});
|
|
14
14
|
|
package/src/helpers/is.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
NAME_ARRAY,
|
|
4
4
|
NAME_COMPUTED,
|
|
5
5
|
NAME_EFFECT,
|
|
6
|
+
NAME_MORA,
|
|
6
7
|
NAME_SIGNAL,
|
|
7
8
|
NAME_STORE,
|
|
8
9
|
NAMES,
|
|
@@ -45,10 +46,10 @@ function isMora<T>(value: unknown, name: string | Set<string>): value is T {
|
|
|
45
46
|
return (
|
|
46
47
|
typeof value === 'object' &&
|
|
47
48
|
value != null &&
|
|
48
|
-
|
|
49
|
+
NAME_MORA in value &&
|
|
49
50
|
(typeof name === 'string'
|
|
50
|
-
? (value as PlainObject)
|
|
51
|
-
: name.has((value as PlainObject)
|
|
51
|
+
? (value as PlainObject)[NAME_MORA] === name
|
|
52
|
+
: name.has((value as PlainObject)[NAME_MORA] as never))
|
|
52
53
|
);
|
|
53
54
|
}
|
|
54
55
|
|
package/src/helpers/proxy.ts
CHANGED
|
@@ -4,12 +4,41 @@ import type {
|
|
|
4
4
|
PlainObject,
|
|
5
5
|
} from '@oscarpalmer/atoms/models';
|
|
6
6
|
import {startBatch, stopBatch} from '../batch';
|
|
7
|
-
import
|
|
7
|
+
import {PROPERTY_LENGTH} from '../constants';
|
|
8
|
+
import type {
|
|
9
|
+
InternalComputed,
|
|
10
|
+
ReactiveState,
|
|
11
|
+
SetValueInProxyParameters,
|
|
12
|
+
} from '../models';
|
|
8
13
|
import type {ReactiveArray} from '../value/array';
|
|
9
14
|
import {type Computed, computed} from '../value/computed';
|
|
10
15
|
import type {Store} from '../value/store';
|
|
11
16
|
import {emitValue} from './value';
|
|
12
17
|
|
|
18
|
+
export function emityProxyValues<Value>(
|
|
19
|
+
state: ReactiveState<Value, Value>,
|
|
20
|
+
mapped: Map<Key, Computed<unknown>>,
|
|
21
|
+
): void;
|
|
22
|
+
|
|
23
|
+
export function emityProxyValues<Value>(
|
|
24
|
+
state: ReactiveState<Value[], Value>,
|
|
25
|
+
mapped: Map<Key, Computed<unknown>>,
|
|
26
|
+
): void;
|
|
27
|
+
|
|
28
|
+
export function emityProxyValues(
|
|
29
|
+
state: ReactiveState<unknown, unknown>,
|
|
30
|
+
mapped: Map<Key, Computed<unknown>>,
|
|
31
|
+
): void {
|
|
32
|
+
const values = [...mapped.values()];
|
|
33
|
+
const {length} = values;
|
|
34
|
+
|
|
35
|
+
for (let index = 0; index < length; index += 1) {
|
|
36
|
+
(values[index] as unknown as InternalComputed).effect.dirty = true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
emitValue(state);
|
|
40
|
+
}
|
|
41
|
+
|
|
13
42
|
export function getReactiveValueInProxy<Value>(
|
|
14
43
|
array: ReactiveArray<Value>,
|
|
15
44
|
mapped: Map<Key, Computed<unknown>>,
|
|
@@ -33,13 +62,11 @@ export function getReactiveValueInProxy(
|
|
|
33
62
|
let item = mapped.get(key);
|
|
34
63
|
|
|
35
64
|
if (item == null) {
|
|
36
|
-
item = computed(() =>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
: (value as PlainObject)[key];
|
|
42
|
-
}) as Computed<unknown>;
|
|
65
|
+
item = computed(() =>
|
|
66
|
+
isArray
|
|
67
|
+
? (reactive.get() as unknown[]).at(key as number)
|
|
68
|
+
: (reactive.get() as PlainObject)[key],
|
|
69
|
+
) as Computed<unknown>;
|
|
43
70
|
|
|
44
71
|
mapped.set(key, item);
|
|
45
72
|
}
|
|
@@ -88,7 +115,7 @@ export function setValueInProxy<Value extends ArrayOrPlainObject, Equal>(
|
|
|
88
115
|
|
|
89
116
|
if (isArray) {
|
|
90
117
|
const isIndex = !Number.isNaN(Number(property));
|
|
91
|
-
const isLength = property ===
|
|
118
|
+
const isLength = property === PROPERTY_LENGTH;
|
|
92
119
|
|
|
93
120
|
if (!(isIndex || isLength)) {
|
|
94
121
|
return Reflect.set(target, property, value);
|
package/src/value/array.ts
CHANGED
|
@@ -3,8 +3,9 @@ import {
|
|
|
3
3
|
METHODS_AFFECTING_LENGTH,
|
|
4
4
|
METHODS_UPDATE,
|
|
5
5
|
NAME_ARRAY,
|
|
6
|
+
PROPERTY_LENGTH,
|
|
6
7
|
} from '../constants';
|
|
7
|
-
import {getReactiveValueInProxy, setValueInProxy} from '../helpers/proxy';
|
|
8
|
+
import {emityProxyValues, getReactiveValueInProxy, setValueInProxy} from '../helpers/proxy';
|
|
8
9
|
import {emitValue, equalArrays, getValue} from '../helpers/value';
|
|
9
10
|
import type {ReactiveOptions, ReactiveState, Unsubscribe} from '../models';
|
|
10
11
|
import {noop, subscribe} from '../subscription';
|
|
@@ -102,11 +103,7 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
|
|
|
102
103
|
return getReactiveValueInProxy(this, this.#indiced, first, true).get();
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
return this.length;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return getValue(this.state);
|
|
106
|
+
return first === PROPERTY_LENGTH ? this.length : getValue(this.state);
|
|
110
107
|
}
|
|
111
108
|
|
|
112
109
|
/**
|
|
@@ -127,7 +124,7 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
|
|
|
127
124
|
* Use this only if you're modifying nested data that would be ignored by equality checks._
|
|
128
125
|
*/
|
|
129
126
|
notify(): void {
|
|
130
|
-
|
|
127
|
+
emityProxyValues(this.state, this.#indiced);
|
|
131
128
|
}
|
|
132
129
|
|
|
133
130
|
/**
|
|
@@ -153,11 +150,9 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
|
|
|
153
150
|
return this.#size.peek();
|
|
154
151
|
}
|
|
155
152
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return [...this.state.value];
|
|
153
|
+
return typeof value === 'number'
|
|
154
|
+
? this.state.value.at(value)
|
|
155
|
+
: [...this.state.value];
|
|
161
156
|
}
|
|
162
157
|
|
|
163
158
|
/**
|
package/src/value/reactive.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {NAME_MORA} from '../constants';
|
|
1
2
|
import type {ReactiveOptions, ReactiveState, Unsubscribe} from '../models';
|
|
2
3
|
import {subscribe, unsubscribe} from '../subscription';
|
|
3
4
|
|
|
@@ -17,7 +18,7 @@ export abstract class Reactive<Value, Equal = Value> {
|
|
|
17
18
|
this.state.equal = options.equal;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
Object.defineProperty(this,
|
|
21
|
+
Object.defineProperty(this, NAME_MORA, {
|
|
21
22
|
value: name,
|
|
22
23
|
});
|
|
23
24
|
}
|
package/src/value/store.ts
CHANGED
|
@@ -7,11 +7,12 @@ import type {
|
|
|
7
7
|
import {NAME_STORE} from '../constants';
|
|
8
8
|
import {
|
|
9
9
|
getReactiveValueInProxy,
|
|
10
|
+
emityProxyValues,
|
|
10
11
|
setProxyValue,
|
|
11
12
|
setValueInProxy,
|
|
12
13
|
} from '../helpers/proxy';
|
|
13
|
-
import {getValue} from '../helpers/value';
|
|
14
|
-
import type {ReactiveOptions, Unsubscribe} from '../models';
|
|
14
|
+
import {emitValue, getValue} from '../helpers/value';
|
|
15
|
+
import type {InternalComputed, ReactiveOptions, Unsubscribe} from '../models';
|
|
15
16
|
import {noop, subscribe} from '../subscription';
|
|
16
17
|
import type {Computed} from './computed';
|
|
17
18
|
import {Reactive} from './reactive';
|
|
@@ -46,7 +47,7 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
46
47
|
* @param key Key of the value to get
|
|
47
48
|
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
48
49
|
*/
|
|
49
|
-
get(key:
|
|
50
|
+
get<Key extends keyof Value>(key: Key): Value[Key];
|
|
50
51
|
|
|
51
52
|
/**
|
|
52
53
|
* Get a value by key
|
|
@@ -61,6 +62,16 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
61
62
|
: getValue(this.state);
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Notify dependents of changes
|
|
67
|
+
*
|
|
68
|
+
* _This bypasses equality checks and will immediately notify dependents.
|
|
69
|
+
* Use this only if you're modifying nested data that would be ignored by equality checks._
|
|
70
|
+
*/
|
|
71
|
+
notify(): void {
|
|
72
|
+
emityProxyValues(this.state, this.#keyed);
|
|
73
|
+
}
|
|
74
|
+
|
|
64
75
|
/**
|
|
65
76
|
* Get the value _(without reactivity)_
|
|
66
77
|
* @returns The current value
|
|
@@ -72,7 +83,7 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
72
83
|
* @param key Key of the value to get
|
|
73
84
|
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
74
85
|
*/
|
|
75
|
-
peek(key:
|
|
86
|
+
peek<Key extends keyof Value>(key: Key): Value[Key];
|
|
76
87
|
|
|
77
88
|
/**
|
|
78
89
|
* Get a value by key _(without reactivity)_
|
|
@@ -96,7 +107,7 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
96
107
|
* @param key Key of the value to set
|
|
97
108
|
* @param value New value
|
|
98
109
|
*/
|
|
99
|
-
set(key:
|
|
110
|
+
set<Key extends keyof Value>(key: Key, value: Value[Key]): void;
|
|
100
111
|
|
|
101
112
|
/**
|
|
102
113
|
* Set a value by key
|
package/types/constants.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export declare const METHODS_UPDATE: Set<string>;
|
|
|
9
9
|
export declare const NAME_ARRAY = "array";
|
|
10
10
|
export declare const NAME_COMPUTED = "computed";
|
|
11
11
|
export declare const NAME_EFFECT = "effect";
|
|
12
|
+
export declare const NAME_MORA = "$mora";
|
|
12
13
|
export declare const NAME_SIGNAL = "signal";
|
|
13
14
|
export declare const NAME_STORE = "store";
|
|
14
15
|
export declare const NAMES: Set<string>;
|
|
16
|
+
export declare const PROPERTY_LENGTH = "length";
|
package/types/helpers/proxy.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ArrayOrPlainObject, Key, PlainObject } from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type { SetValueInProxyParameters } from '../models';
|
|
2
|
+
import type { ReactiveState, SetValueInProxyParameters } from '../models';
|
|
3
3
|
import type { ReactiveArray } from '../value/array';
|
|
4
4
|
import { type Computed } from '../value/computed';
|
|
5
5
|
import type { Store } from '../value/store';
|
|
6
|
+
export declare function emityProxyValues<Value>(state: ReactiveState<Value, Value>, mapped: Map<Key, Computed<unknown>>): void;
|
|
7
|
+
export declare function emityProxyValues<Value>(state: ReactiveState<Value[], Value>, mapped: Map<Key, Computed<unknown>>): void;
|
|
6
8
|
export declare function getReactiveValueInProxy<Value>(array: ReactiveArray<Value>, mapped: Map<Key, Computed<unknown>>, index: number, isArray: true): Computed<unknown>;
|
|
7
9
|
export declare function getReactiveValueInProxy<Value extends PlainObject>(store: Store<Value>, mapped: Map<Key, Computed<unknown>>, key: Key, isArray: false): Computed<unknown>;
|
|
8
10
|
export declare function setProxyValue(proxy: ArrayOrPlainObject, value: ArrayOrPlainObject): void;
|
package/types/value/store.d.ts
CHANGED
|
@@ -13,13 +13,20 @@ export declare class Store<Value extends PlainObject> extends Reactive<Value, Va
|
|
|
13
13
|
* @param key Key of the value to get
|
|
14
14
|
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
15
15
|
*/
|
|
16
|
-
get(key:
|
|
16
|
+
get<Key extends keyof Value>(key: Key): Value[Key];
|
|
17
17
|
/**
|
|
18
18
|
* Get a value by key
|
|
19
19
|
* @param key Key of the value to get
|
|
20
20
|
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
21
21
|
*/
|
|
22
22
|
get(key: Key): unknown;
|
|
23
|
+
/**
|
|
24
|
+
* Notify dependents of changes
|
|
25
|
+
*
|
|
26
|
+
* _This bypasses equality checks and will immediately notify dependents.
|
|
27
|
+
* Use this only if you're modifying nested data that would be ignored by equality checks._
|
|
28
|
+
*/
|
|
29
|
+
notify(): void;
|
|
23
30
|
/**
|
|
24
31
|
* Get the value _(without reactivity)_
|
|
25
32
|
* @returns The current value
|
|
@@ -30,7 +37,7 @@ export declare class Store<Value extends PlainObject> extends Reactive<Value, Va
|
|
|
30
37
|
* @param key Key of the value to get
|
|
31
38
|
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
32
39
|
*/
|
|
33
|
-
peek(key:
|
|
40
|
+
peek<Key extends keyof Value>(key: Key): Value[Key];
|
|
34
41
|
/**
|
|
35
42
|
* Get a value by key _(without reactivity)_
|
|
36
43
|
* @param key Key of the value to get
|
|
@@ -47,7 +54,7 @@ export declare class Store<Value extends PlainObject> extends Reactive<Value, Va
|
|
|
47
54
|
* @param key Key of the value to set
|
|
48
55
|
* @param value New value
|
|
49
56
|
*/
|
|
50
|
-
set(key:
|
|
57
|
+
set<Key extends keyof Value>(key: Key, value: Value[Key]): void;
|
|
51
58
|
/**
|
|
52
59
|
* Set a value by key
|
|
53
60
|
* @param key Key of the value to set
|