@oscarpalmer/mora 0.13.0 → 0.14.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/batch.cjs +2 -2
- package/dist/batch.js +1 -1
- package/dist/effect.cjs +2 -1
- package/dist/effect.js +2 -1
- package/dist/helpers/emit.cjs +42 -0
- package/dist/helpers/emit.js +42 -0
- package/dist/helpers/is.cjs +34 -0
- package/dist/helpers/is.js +34 -0
- package/dist/helpers/value.cjs +22 -0
- package/dist/helpers/value.js +22 -0
- package/dist/index.cjs +12 -11
- package/dist/index.js +5 -4
- package/dist/mora.full.js +152 -140
- package/dist/{array.cjs → value/array.cjs} +27 -49
- package/dist/{array.js → value/array.js} +9 -31
- package/dist/{computed.cjs → value/computed.cjs} +6 -5
- package/dist/{computed.js → value/computed.js} +4 -3
- package/dist/{reactive.cjs → value/reactive.cjs} +1 -1
- package/dist/{reactive.js → value/reactive.js} +1 -1
- package/dist/value/signal.cjs +33 -0
- package/dist/{signal.js → value/signal.js} +3 -2
- package/package.json +1 -1
- package/src/batch.ts +1 -1
- package/src/effect.ts +12 -11
- package/src/helpers/emit.ts +52 -0
- package/src/helpers/is.ts +56 -0
- package/src/helpers/value.ts +27 -0
- package/src/index.ts +11 -5
- package/src/subscription.ts +1 -1
- package/src/{array.ts → value/array.ts} +10 -41
- package/src/{computed.ts → value/computed.ts} +4 -3
- package/src/{reactive.ts → value/reactive.ts} +3 -3
- package/src/{signal.ts → value/signal.ts} +3 -2
- package/types/batch.d.cts +9 -9
- package/types/helpers/emit.d.cts +63 -0
- package/types/helpers/emit.d.ts +3 -0
- package/types/{is.d.cts → helpers/is.d.cts} +53 -9
- package/types/helpers/is.d.ts +26 -0
- package/types/{value.d.cts → helpers/value.d.cts} +9 -10
- package/types/{value.d.ts → helpers/value.d.ts} +1 -2
- package/types/index.d.cts +42 -38
- package/types/index.d.ts +5 -5
- package/types/subscription.d.cts +12 -12
- package/types/subscription.d.ts +1 -1
- package/types/{computed.d.ts → value/computed.d.ts} +1 -1
- package/types/{reactive.d.ts → value/reactive.d.ts} +2 -2
- package/dist/is.cjs +0 -21
- package/dist/is.js +0 -21
- package/dist/signal.cjs +0 -32
- package/dist/value.cjs +0 -38
- package/dist/value.js +0 -38
- package/src/is.ts +0 -39
- package/src/value.ts +0 -47
- package/types/is.d.ts +0 -17
- package/types/{array.d.cts → value/array.d.cts} +9 -9
- package/types/{array.d.ts → value/array.d.ts} +0 -0
- package/types/{computed.d.cts → value/computed.d.cts} +9 -9
- package/types/{reactive.d.cts → value/reactive.d.cts} +9 -9
- package/types/{signal.d.cts → value/signal.d.cts} +9 -9
- /package/types/{signal.d.ts → value/signal.d.ts} +0 -0
|
@@ -4,23 +4,25 @@ var __typeError = (msg) => {
|
|
|
4
4
|
};
|
|
5
5
|
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
6
6
|
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
7
|
-
var __privateAdd = (obj, member,
|
|
7
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
8
8
|
var _size;
|
|
9
9
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const helpers_emit = require("../helpers/emit.cjs");
|
|
11
|
+
const helpers_is = require("../helpers/is.cjs");
|
|
12
|
+
const helpers_value = require("../helpers/value.cjs");
|
|
13
|
+
const value_reactive = require("./reactive.cjs");
|
|
14
|
+
const value_signal = require("./signal.cjs");
|
|
15
|
+
class ReactiveArray extends value_reactive.Reactive {
|
|
16
|
+
constructor(value) {
|
|
15
17
|
super(
|
|
16
|
-
|
|
17
|
-
new Proxy(
|
|
18
|
+
helpers_is.arrayName,
|
|
19
|
+
new Proxy(value, {
|
|
18
20
|
get: (target, property) => updateMethods.has(property) ? updateArray(property, target, this.state, __privateGet(this, _size)) : Reflect.get(target, property),
|
|
19
|
-
set: (target, property,
|
|
21
|
+
set: (target, property, value2) => setValue(target, property, value2, this.state, __privateGet(this, _size))
|
|
20
22
|
})
|
|
21
23
|
);
|
|
22
|
-
__privateAdd(this, _size,
|
|
23
|
-
__privateGet(this, _size).set(
|
|
24
|
+
__privateAdd(this, _size, value_signal.signal(0));
|
|
25
|
+
__privateGet(this, _size).set(value.length);
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
26
28
|
* The length of the array
|
|
@@ -31,16 +33,16 @@ class ReactiveArray extends reactive.Reactive {
|
|
|
31
33
|
/**
|
|
32
34
|
* Set the length of the array
|
|
33
35
|
*/
|
|
34
|
-
set length(
|
|
35
|
-
if (typeof
|
|
36
|
-
this.get().length =
|
|
36
|
+
set length(value) {
|
|
37
|
+
if (typeof value === "number" && value >= 0 && value !== this.state.value.length) {
|
|
38
|
+
this.get().length = value;
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
/**
|
|
40
42
|
* @inheritdoc
|
|
41
43
|
*/
|
|
42
44
|
get() {
|
|
43
|
-
return
|
|
45
|
+
return helpers_value.getValue(this.state);
|
|
44
46
|
}
|
|
45
47
|
peek(length) {
|
|
46
48
|
return length === true ? __privateGet(this, _size).peek() : [...this.state.value];
|
|
@@ -56,45 +58,21 @@ class ReactiveArray extends reactive.Reactive {
|
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
60
|
_size = new WeakMap();
|
|
59
|
-
function array(
|
|
60
|
-
return new ReactiveArray(Array.isArray(
|
|
61
|
+
function array(value) {
|
|
62
|
+
return new ReactiveArray(Array.isArray(value) ? value : []);
|
|
61
63
|
}
|
|
62
|
-
function
|
|
63
|
-
let { length } = first;
|
|
64
|
-
if (length !== second.length) {
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
let offset = 0;
|
|
68
|
-
if (length >= 100) {
|
|
69
|
-
offset = Math.round(length / 10);
|
|
70
|
-
offset = offset > 25 ? 25 : offset;
|
|
71
|
-
for (let index = 0; index < offset; index += 1) {
|
|
72
|
-
if (!Object.is(first[index], second[index])) {
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
length -= offset;
|
|
78
|
-
for (let index = offset; index < length; index += 1) {
|
|
79
|
-
if (!Object.is(first[index], second[index])) {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
function setValue(target, property, value$1, state, length) {
|
|
64
|
+
function setValue(target, property, value, state, length) {
|
|
86
65
|
const isIndex = !Number.isNaN(Number(property));
|
|
87
66
|
const isLength = property === "length";
|
|
88
67
|
if (!isIndex && !isLength) {
|
|
89
|
-
return Reflect.set(target, property, value
|
|
68
|
+
return Reflect.set(target, property, value);
|
|
90
69
|
}
|
|
91
70
|
const previous = Reflect.get(target, property);
|
|
92
|
-
if (Object.is(previous, value
|
|
93
|
-
|
|
71
|
+
if (!Object.is(previous, value)) {
|
|
72
|
+
Reflect.set(target, property, value);
|
|
73
|
+
helpers_emit.emitValue(state);
|
|
74
|
+
length.set(target.length);
|
|
94
75
|
}
|
|
95
|
-
Reflect.set(target, property, value$1);
|
|
96
|
-
value.emitValue(state);
|
|
97
|
-
length.set(target.length);
|
|
98
76
|
return true;
|
|
99
77
|
}
|
|
100
78
|
function updateArray(type, array2, state, length) {
|
|
@@ -105,8 +83,8 @@ function updateArray(type, array2, state, length) {
|
|
|
105
83
|
const result = array2[type](
|
|
106
84
|
...args
|
|
107
85
|
);
|
|
108
|
-
if (affectsLength ? array2.length !== previousLength :
|
|
109
|
-
|
|
86
|
+
if (affectsLength ? array2.length !== previousLength : helpers_emit.emitArrayChanges(previousArray, array2)) {
|
|
87
|
+
helpers_emit.emitValue(state);
|
|
110
88
|
length.set(array2.length);
|
|
111
89
|
}
|
|
112
90
|
return result;
|
|
@@ -5,13 +5,15 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
|
|
|
5
5
|
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
6
6
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7
7
|
var _size;
|
|
8
|
+
import { emitValue, emitArrayChanges } from "../helpers/emit.js";
|
|
9
|
+
import { arrayName } from "../helpers/is.js";
|
|
10
|
+
import { getValue } from "../helpers/value.js";
|
|
8
11
|
import { Reactive } from "./reactive.js";
|
|
9
12
|
import { signal } from "./signal.js";
|
|
10
|
-
import { getValue, emitValue } from "./value.js";
|
|
11
13
|
class ReactiveArray extends Reactive {
|
|
12
14
|
constructor(value) {
|
|
13
15
|
super(
|
|
14
|
-
|
|
16
|
+
arrayName,
|
|
15
17
|
new Proxy(value, {
|
|
16
18
|
get: (target, property) => updateMethods.has(property) ? updateArray(property, target, this.state, __privateGet(this, _size)) : Reflect.get(target, property),
|
|
17
19
|
set: (target, property, value2) => setValue(target, property, value2, this.state, __privateGet(this, _size))
|
|
@@ -57,29 +59,6 @@ _size = new WeakMap();
|
|
|
57
59
|
function array(value) {
|
|
58
60
|
return new ReactiveArray(Array.isArray(value) ? value : []);
|
|
59
61
|
}
|
|
60
|
-
function emit(first, second) {
|
|
61
|
-
let { length } = first;
|
|
62
|
-
if (length !== second.length) {
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
let offset = 0;
|
|
66
|
-
if (length >= 100) {
|
|
67
|
-
offset = Math.round(length / 10);
|
|
68
|
-
offset = offset > 25 ? 25 : offset;
|
|
69
|
-
for (let index = 0; index < offset; index += 1) {
|
|
70
|
-
if (!Object.is(first[index], second[index])) {
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
length -= offset;
|
|
76
|
-
for (let index = offset; index < length; index += 1) {
|
|
77
|
-
if (!Object.is(first[index], second[index])) {
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
62
|
function setValue(target, property, value, state, length) {
|
|
84
63
|
const isIndex = !Number.isNaN(Number(property));
|
|
85
64
|
const isLength = property === "length";
|
|
@@ -87,12 +66,11 @@ function setValue(target, property, value, state, length) {
|
|
|
87
66
|
return Reflect.set(target, property, value);
|
|
88
67
|
}
|
|
89
68
|
const previous = Reflect.get(target, property);
|
|
90
|
-
if (Object.is(previous, value)) {
|
|
91
|
-
|
|
69
|
+
if (!Object.is(previous, value)) {
|
|
70
|
+
Reflect.set(target, property, value);
|
|
71
|
+
emitValue(state);
|
|
72
|
+
length.set(target.length);
|
|
92
73
|
}
|
|
93
|
-
Reflect.set(target, property, value);
|
|
94
|
-
emitValue(state);
|
|
95
|
-
length.set(target.length);
|
|
96
74
|
return true;
|
|
97
75
|
}
|
|
98
76
|
function updateArray(type, array2, state, length) {
|
|
@@ -103,7 +81,7 @@ function updateArray(type, array2, state, length) {
|
|
|
103
81
|
const result = array2[type](
|
|
104
82
|
...args
|
|
105
83
|
);
|
|
106
|
-
if (affectsLength ? array2.length !== previousLength :
|
|
84
|
+
if (affectsLength ? array2.length !== previousLength : emitArrayChanges(previousArray, array2)) {
|
|
107
85
|
emitValue(state);
|
|
108
86
|
length.set(array2.length);
|
|
109
87
|
}
|
|
@@ -3,13 +3,14 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
6
|
-
const batch = require("
|
|
7
|
-
const effect = require("
|
|
8
|
-
const
|
|
6
|
+
const batch = require("../batch.cjs");
|
|
7
|
+
const effect = require("../effect.cjs");
|
|
8
|
+
const helpers_is = require("../helpers/is.cjs");
|
|
9
|
+
const value_reactive = require("./reactive.cjs");
|
|
9
10
|
exports.activeComputed = void 0;
|
|
10
|
-
class Computed extends
|
|
11
|
+
class Computed extends value_reactive.Reactive {
|
|
11
12
|
constructor(callback) {
|
|
12
|
-
super(
|
|
13
|
+
super(helpers_is.computedName, void 0);
|
|
13
14
|
__publicField(this, "effect", {
|
|
14
15
|
dirty: true,
|
|
15
16
|
instance: void 0
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { batchedHandlers, batchDepth } from "
|
|
5
|
-
import { effect, activeEffect, runEffect } from "
|
|
4
|
+
import { batchedHandlers, batchDepth } from "../batch.js";
|
|
5
|
+
import { effect, activeEffect, runEffect } from "../effect.js";
|
|
6
|
+
import { computedName } from "../helpers/is.js";
|
|
6
7
|
import { Reactive } from "./reactive.js";
|
|
7
8
|
let activeComputed;
|
|
8
9
|
class Computed extends Reactive {
|
|
9
10
|
constructor(callback) {
|
|
10
|
-
super(
|
|
11
|
+
super(computedName, void 0);
|
|
11
12
|
__publicField(this, "effect", {
|
|
12
13
|
dirty: true,
|
|
13
14
|
instance: void 0
|
|
@@ -3,7 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
6
|
-
const subscription = require("
|
|
6
|
+
const subscription = require("../subscription.cjs");
|
|
7
7
|
class Reactive {
|
|
8
8
|
constructor(name, value) {
|
|
9
9
|
__publicField(this, "state", {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { subscribe, unsubscribe } from "
|
|
4
|
+
import { subscribe, unsubscribe } from "../subscription.js";
|
|
5
5
|
class Reactive {
|
|
6
6
|
constructor(name, value) {
|
|
7
7
|
__publicField(this, "state", {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const helpers_is = require("../helpers/is.cjs");
|
|
4
|
+
const helpers_value = require("../helpers/value.cjs");
|
|
5
|
+
const value_reactive = require("./reactive.cjs");
|
|
6
|
+
class Signal extends value_reactive.Reactive {
|
|
7
|
+
constructor(value) {
|
|
8
|
+
super(helpers_is.signalName, value);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* @inheritdoc
|
|
12
|
+
*/
|
|
13
|
+
get() {
|
|
14
|
+
return helpers_value.getValue(this.state);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Set the value
|
|
18
|
+
*/
|
|
19
|
+
set(value) {
|
|
20
|
+
helpers_value.setValue(this.state, value);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Update the value
|
|
24
|
+
*/
|
|
25
|
+
update(callback) {
|
|
26
|
+
this.set(callback(this.state.value));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function signal(value) {
|
|
30
|
+
return new Signal(value);
|
|
31
|
+
}
|
|
32
|
+
exports.Signal = Signal;
|
|
33
|
+
exports.signal = signal;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { signalName } from "../helpers/is.js";
|
|
2
|
+
import { getValue, setValue } from "../helpers/value.js";
|
|
1
3
|
import { Reactive } from "./reactive.js";
|
|
2
|
-
import { getValue, setValue } from "./value.js";
|
|
3
4
|
class Signal extends Reactive {
|
|
4
5
|
constructor(value) {
|
|
5
|
-
super(
|
|
6
|
+
super(signalName, value);
|
|
6
7
|
}
|
|
7
8
|
/**
|
|
8
9
|
* @inheritdoc
|
package/package.json
CHANGED
package/src/batch.ts
CHANGED
package/src/effect.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {GenericCallback} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import {effectName} from './helpers/is';
|
|
2
3
|
|
|
3
4
|
type EffectState = {
|
|
4
5
|
callback: GenericCallback;
|
|
@@ -9,22 +10,22 @@ type InternalEffect = {
|
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
export class Effect {
|
|
12
|
-
|
|
13
|
+
private declare readonly $mora: string;
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
private declare readonly state: EffectState;
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
constructor(callback: GenericCallback) {
|
|
18
|
+
Object.defineProperty(this, '$mora', {
|
|
19
|
+
value: effectName,
|
|
20
|
+
});
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
this.state = {
|
|
23
|
+
callback,
|
|
24
|
+
};
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
}
|
|
26
|
+
runEffect(this);
|
|
27
27
|
}
|
|
28
|
+
}
|
|
28
29
|
|
|
29
30
|
export function runEffect(effect: Effect): void {
|
|
30
31
|
const previousEffect = activeEffect;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {batchDepth, batchedHandlers, flushEffects} from '../batch';
|
|
2
|
+
import type {InternalComputed} from '../value/computed';
|
|
3
|
+
import type {ReactiveState} from '../value/reactive';
|
|
4
|
+
|
|
5
|
+
export function emitArrayChanges(first: unknown[], second: unknown[]): boolean {
|
|
6
|
+
let {length} = first;
|
|
7
|
+
|
|
8
|
+
if (length !== second.length) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let offset = 0;
|
|
13
|
+
|
|
14
|
+
if (length >= 100) {
|
|
15
|
+
offset = Math.round(length / 10);
|
|
16
|
+
offset = offset > 25 ? 25 : offset;
|
|
17
|
+
|
|
18
|
+
for (let index = 0; index < offset; index += 1) {
|
|
19
|
+
if (!Object.is(first[index], second[index])) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
length -= offset;
|
|
26
|
+
|
|
27
|
+
for (let index = offset; index < length; index += 1) {
|
|
28
|
+
if (!Object.is(first[index], second[index])) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function emitValue<Value>(state: ReactiveState<Value>): void {
|
|
37
|
+
for (const computed of state.computeds) {
|
|
38
|
+
(computed as unknown as InternalComputed).effect.dirty = true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
for (const effect of state.effects) {
|
|
42
|
+
batchedHandlers.add(effect);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (const [, subscription] of state.subscriptions) {
|
|
46
|
+
batchedHandlers.add(subscription as never);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (batchDepth === 0) {
|
|
50
|
+
flushEffects();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import type {Effect} from '../effect';
|
|
3
|
+
import type {ReactiveArray} from '../value/array';
|
|
4
|
+
import type {Computed} from '../value/computed';
|
|
5
|
+
import type {Reactive} from '../value/reactive';
|
|
6
|
+
import {signal, type Signal} from '../value/signal';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Is the value a reactive array?
|
|
10
|
+
*/
|
|
11
|
+
export function isArray(value: unknown): value is ReactiveArray<unknown> {
|
|
12
|
+
return isMora<ReactiveArray<unknown>>(value, arrayName);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Is the value a computed signal?
|
|
17
|
+
*/
|
|
18
|
+
export function isComputed(value: unknown): value is Computed<unknown> {
|
|
19
|
+
return isMora<Computed<unknown>>(value, computedName);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Is the value an effect?
|
|
24
|
+
*/
|
|
25
|
+
export function isEffect(value: unknown): value is Effect {
|
|
26
|
+
return isMora<Effect>(value, effectName);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function isMora<T>(value: unknown, name: string | Set<string>): value is T {
|
|
30
|
+
return (
|
|
31
|
+
typeof value === 'object' &&
|
|
32
|
+
value != null &&
|
|
33
|
+
'$mora' in value &&
|
|
34
|
+
(typeof name === 'string'
|
|
35
|
+
? (value as PlainObject).$mora === name
|
|
36
|
+
: name.has((value as PlainObject).$mora as never))
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function isReactive(value: unknown): value is Reactive<unknown> {
|
|
41
|
+
return isMora<Reactive<unknown>>(value, reactiveNames);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Is the value a signal?
|
|
46
|
+
*/
|
|
47
|
+
export function isSignal(value: unknown): value is Signal<unknown> {
|
|
48
|
+
return isMora<Signal<unknown>>(value, signalName);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const arrayName = 'array';
|
|
52
|
+
export const computedName = 'computed';
|
|
53
|
+
export const effectName = 'effect';
|
|
54
|
+
export const signalName = 'signal';
|
|
55
|
+
|
|
56
|
+
const reactiveNames = new Set([arrayName, computedName, signalName]);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {activeEffect} from '../effect';
|
|
2
|
+
import {activeComputed} from '../value/computed';
|
|
3
|
+
import type {ReactiveState} from '../value/reactive';
|
|
4
|
+
import {emitValue} from './emit';
|
|
5
|
+
|
|
6
|
+
export function getValue<Value>(state: ReactiveState<Value>): Value {
|
|
7
|
+
if (activeComputed != null) {
|
|
8
|
+
state.computeds.add(activeComputed);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (activeEffect != null) {
|
|
12
|
+
state.effects.add(activeEffect);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return state.value;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function setValue<Value>(
|
|
19
|
+
state: ReactiveState<Value>,
|
|
20
|
+
value: Value,
|
|
21
|
+
): void {
|
|
22
|
+
if (!Object.is(state.value, value)) {
|
|
23
|
+
state.value = value;
|
|
24
|
+
|
|
25
|
+
emitValue(state);
|
|
26
|
+
}
|
|
27
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
export {array, type ReactiveArray} from './array';
|
|
2
1
|
export {startBatch, stopBatch} from './batch';
|
|
3
|
-
export {computed, type Computed} from './computed';
|
|
4
2
|
export {effect, type Effect} from './effect';
|
|
5
|
-
export {
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
export {
|
|
4
|
+
isArray,
|
|
5
|
+
isComputed,
|
|
6
|
+
isEffect,
|
|
7
|
+
isReactive,
|
|
8
|
+
isSignal,
|
|
9
|
+
} from './helpers/is';
|
|
10
|
+
export {array, type ReactiveArray} from './value/array';
|
|
11
|
+
export {computed, type Computed} from './value/computed';
|
|
12
|
+
export type {Reactive} from './value/reactive';
|
|
13
|
+
export {signal, type Signal} from './value/signal';
|
package/src/subscription.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import {emitArrayChanges, emitValue} from '../helpers/emit';
|
|
2
|
+
import {arrayName} from '../helpers/is';
|
|
3
|
+
import {getValue} from '../helpers/value';
|
|
1
4
|
import {Reactive, type ReactiveState} from './reactive';
|
|
2
5
|
import {type Signal, signal} from './signal';
|
|
3
|
-
import {emitValue, getValue} from './value';
|
|
4
6
|
|
|
5
7
|
export class ReactiveArray<Item> extends Reactive<Item[]> {
|
|
6
8
|
#size = signal(0);
|
|
@@ -27,7 +29,7 @@ export class ReactiveArray<Item> extends Reactive<Item[]> {
|
|
|
27
29
|
|
|
28
30
|
constructor(value: Item[]) {
|
|
29
31
|
super(
|
|
30
|
-
|
|
32
|
+
arrayName,
|
|
31
33
|
new Proxy(value, {
|
|
32
34
|
get: (target, property) =>
|
|
33
35
|
updateMethods.has(property as string)
|
|
@@ -95,37 +97,6 @@ export function array<Item>(value: Item[]): ReactiveArray<Item> {
|
|
|
95
97
|
return new ReactiveArray(Array.isArray(value) ? value : []);
|
|
96
98
|
}
|
|
97
99
|
|
|
98
|
-
function emit(first: unknown[], second: unknown[]): boolean {
|
|
99
|
-
let {length} = first;
|
|
100
|
-
|
|
101
|
-
if (length !== second.length) {
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
let offset = 0;
|
|
106
|
-
|
|
107
|
-
if (length >= 100) {
|
|
108
|
-
offset = Math.round(length / 10);
|
|
109
|
-
offset = offset > 25 ? 25 : offset;
|
|
110
|
-
|
|
111
|
-
for (let index = 0; index < offset; index += 1) {
|
|
112
|
-
if (!Object.is(first[index], second[index])) {
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
length -= offset;
|
|
119
|
-
|
|
120
|
-
for (let index = offset; index < length; index += 1) {
|
|
121
|
-
if (!Object.is(first[index], second[index])) {
|
|
122
|
-
return true;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
100
|
function setValue<Item>(
|
|
130
101
|
target: Item[],
|
|
131
102
|
property: PropertyKey,
|
|
@@ -142,15 +113,13 @@ function setValue<Item>(
|
|
|
142
113
|
|
|
143
114
|
const previous = Reflect.get(target, property);
|
|
144
115
|
|
|
145
|
-
if (Object.is(previous, value)) {
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
Reflect.set(target, property, value);
|
|
116
|
+
if (!Object.is(previous, value)) {
|
|
117
|
+
Reflect.set(target, property, value);
|
|
150
118
|
|
|
151
|
-
|
|
119
|
+
emitValue(state);
|
|
152
120
|
|
|
153
|
-
|
|
121
|
+
length.set(target.length);
|
|
122
|
+
}
|
|
154
123
|
|
|
155
124
|
return true;
|
|
156
125
|
}
|
|
@@ -173,7 +142,7 @@ function updateArray<Item>(
|
|
|
173
142
|
if (
|
|
174
143
|
affectsLength
|
|
175
144
|
? array.length !== previousLength
|
|
176
|
-
:
|
|
145
|
+
: emitArrayChanges(previousArray, array)
|
|
177
146
|
) {
|
|
178
147
|
emitValue(state);
|
|
179
148
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {batchDepth, batchedHandlers} from '
|
|
2
|
-
import {type Effect, activeEffect, effect, runEffect} from '
|
|
1
|
+
import {batchDepth, batchedHandlers} from '../batch';
|
|
2
|
+
import {type Effect, activeEffect, effect, runEffect} from '../effect';
|
|
3
|
+
import {computedName} from '../helpers/is';
|
|
3
4
|
import {Reactive, type ReactiveState} from './reactive';
|
|
4
5
|
|
|
5
6
|
type ComputedEffect = {
|
|
@@ -21,7 +22,7 @@ export class Computed<Value> extends Reactive<Value> {
|
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
constructor(callback: () => Value) {
|
|
24
|
-
super(
|
|
25
|
+
super(computedName, undefined as never);
|
|
25
26
|
|
|
26
27
|
this.effect.instance = effect(() => {
|
|
27
28
|
if (this.effect.dirty) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {Effect} from './effect';
|
|
1
|
+
import type {Effect} from '../effect';
|
|
3
2
|
import {
|
|
4
3
|
type Subscription,
|
|
5
4
|
type Unsubscribe,
|
|
6
5
|
subscribe,
|
|
7
6
|
unsubscribe,
|
|
8
|
-
} from '
|
|
7
|
+
} from '../subscription';
|
|
8
|
+
import type {Computed} from './computed';
|
|
9
9
|
|
|
10
10
|
export abstract class Reactive<Value> {
|
|
11
11
|
protected readonly state: ReactiveState<Value> = {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import {signalName} from '../helpers/is';
|
|
2
|
+
import {getValue, setValue} from '../helpers/value';
|
|
1
3
|
import {Reactive} from './reactive';
|
|
2
|
-
import {getValue, setValue} from './value';
|
|
3
4
|
|
|
4
5
|
export class Signal<Value> extends Reactive<Value> {
|
|
5
6
|
constructor(value: Value) {
|
|
6
|
-
super(
|
|
7
|
+
super(signalName, value);
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
/**
|