@oscarpalmer/mora 0.34.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.d.mts +2 -2
- package/dist/helpers/proxy.d.mts +8 -8
- package/dist/helpers/proxy.mjs +32 -25
- package/dist/helpers/subscription.d.mts +3 -3
- package/dist/helpers/value.d.mts +9 -8
- package/dist/helpers/value.mjs +15 -11
- package/dist/index.d.mts +2 -2
- package/dist/models.d.mts +40 -37
- package/dist/mora.full.mjs +127 -111
- package/dist/value/array.mjs +53 -41
- package/dist/value/computed.d.mts +2 -2
- package/dist/value/computed.mjs +3 -5
- package/dist/value/readonly.d.mts +2 -2
- package/dist/value/readonly.mjs +16 -19
- package/dist/value/signal.mjs +13 -13
- package/dist/value/store.mjs +4 -6
- package/package.json +1 -1
- package/src/batch.ts +2 -2
- package/src/constants.ts +7 -2
- package/src/helpers/is.ts +1 -3
- package/src/helpers/proxy.ts +68 -57
- package/src/helpers/subscription.ts +7 -6
- package/src/helpers/value.ts +30 -20
- package/src/index.ts +1 -0
- package/src/models.ts +47 -43
- package/src/value/array.ts +81 -64
- package/src/value/computed.ts +12 -16
- package/src/value/readonly.ts +38 -29
- package/src/value/signal.ts +20 -20
- package/src/value/store.ts +4 -7
package/dist/mora.full.mjs
CHANGED
|
@@ -125,10 +125,10 @@ function emitValue(instance) {
|
|
|
125
125
|
}
|
|
126
126
|
if (BATCH.depth === 0) flushHandlers();
|
|
127
127
|
}
|
|
128
|
-
function equalArrays(
|
|
128
|
+
function equalArrays(first, second, equal) {
|
|
129
129
|
const { length } = first;
|
|
130
130
|
if (length !== second.length) return false;
|
|
131
|
-
const eq =
|
|
131
|
+
const eq = equal ?? Object.is;
|
|
132
132
|
let offset = 0;
|
|
133
133
|
if (length >= 100) {
|
|
134
134
|
offset = Math.round(length / 10);
|
|
@@ -145,21 +145,25 @@ function getFrozenValue(value) {
|
|
|
145
145
|
else if (isPlainObject(frozen)) frozen = Object.freeze({ ...frozen });
|
|
146
146
|
return frozen;
|
|
147
147
|
}
|
|
148
|
+
function getJsonValue() {
|
|
149
|
+
return this[SYMBOL_STATE].value;
|
|
150
|
+
}
|
|
148
151
|
function getSignalValue() {
|
|
152
|
+
const state = this[SYMBOL_STATE];
|
|
149
153
|
if (ACTIVE.computed != null) {
|
|
150
|
-
|
|
151
|
-
|
|
154
|
+
state.computeds ??= /* @__PURE__ */ new Set();
|
|
155
|
+
state.computeds.add(ACTIVE.computed);
|
|
152
156
|
}
|
|
153
157
|
if (ACTIVE.effect != null) {
|
|
154
|
-
|
|
155
|
-
|
|
158
|
+
state.effects ??= /* @__PURE__ */ new Set();
|
|
159
|
+
state.effects.add(ACTIVE.effect);
|
|
156
160
|
}
|
|
157
|
-
return
|
|
161
|
+
return state.value;
|
|
158
162
|
}
|
|
159
163
|
function getStringValue(json) {
|
|
160
164
|
return json === true ? JSON.stringify(this[SYMBOL_STATE].value) : String(this[SYMBOL_STATE].value);
|
|
161
165
|
}
|
|
162
|
-
function
|
|
166
|
+
function handleSignal(instance, origin, setValue, onAfter) {
|
|
163
167
|
const state = instance[SYMBOL_STATE];
|
|
164
168
|
try {
|
|
165
169
|
let actual = typeof origin === "function" ? origin() : origin;
|
|
@@ -185,9 +189,9 @@ function peekSignalValue(copy) {
|
|
|
185
189
|
else if (isPlainObject(peeked)) peeked = { ...peeked };
|
|
186
190
|
return peeked;
|
|
187
191
|
}
|
|
188
|
-
function
|
|
192
|
+
function updateSignal(instance, callback, setValue) {
|
|
189
193
|
if (typeof callback !== "function") throw new TypeError("Callback must be a function");
|
|
190
|
-
|
|
194
|
+
handleSignal(instance, callback(instance[SYMBOL_STATE].value), setValue);
|
|
191
195
|
}
|
|
192
196
|
//#endregion
|
|
193
197
|
//#region src/batch.ts
|
|
@@ -689,10 +693,8 @@ Computed.prototype[NAME_MORA] = NAME_COMPUTED;
|
|
|
689
693
|
Computed.prototype.get = getComputedValue;
|
|
690
694
|
Computed.prototype.peek = peekSignalValue;
|
|
691
695
|
Computed.prototype.subscribe = subscribeToSignal;
|
|
696
|
+
Computed.prototype.toJSON = getJsonValue;
|
|
692
697
|
Computed.prototype.toString = getStringValue;
|
|
693
|
-
Computed.prototype.toJSON = function() {
|
|
694
|
-
return this[SYMBOL_STATE].value;
|
|
695
|
-
};
|
|
696
698
|
/**
|
|
697
699
|
* Create a computed value
|
|
698
700
|
*
|
|
@@ -717,7 +719,7 @@ function getComputedEffect(instance, callback) {
|
|
|
717
719
|
if (fx.dirty) {
|
|
718
720
|
const previousComputed = ACTIVE.computed;
|
|
719
721
|
ACTIVE.computed = fx;
|
|
720
|
-
|
|
722
|
+
handleSignal(instance, callback, setAndEmit$1, () => {
|
|
721
723
|
ACTIVE.computed = previousComputed;
|
|
722
724
|
});
|
|
723
725
|
fx.dirty = false;
|
|
@@ -780,8 +782,12 @@ function getReactiveValueInProxy(instance, key) {
|
|
|
780
782
|
return item[0];
|
|
781
783
|
}
|
|
782
784
|
function getValueInProxy(first) {
|
|
783
|
-
|
|
784
|
-
|
|
785
|
+
let signal;
|
|
786
|
+
if (this[SYMBOL_STATE].isArray ? typeof first === "number" : isKey(first)) signal = getReactiveValueInProxy(this, first);
|
|
787
|
+
return getSignalValue.call(signal ?? this);
|
|
788
|
+
}
|
|
789
|
+
function isProxyKey(isArray, value) {
|
|
790
|
+
return isArray ? typeof value === "number" : isKey(value);
|
|
785
791
|
}
|
|
786
792
|
function isProxyObject(isArray, value) {
|
|
787
793
|
return value == null || (isArray ? Array.isArray(value) : isPlainObject(value));
|
|
@@ -795,23 +801,24 @@ function peekValueInProxy(first, second) {
|
|
|
795
801
|
}
|
|
796
802
|
function setProxyObject(state, value) {
|
|
797
803
|
if (state.isArray) {
|
|
798
|
-
|
|
804
|
+
const values = state.value;
|
|
805
|
+
values.splice(0, values.length, ...value ?? []);
|
|
799
806
|
return;
|
|
800
807
|
}
|
|
801
808
|
startBatch();
|
|
802
|
-
const
|
|
803
|
-
const
|
|
804
|
-
const
|
|
805
|
-
const
|
|
806
|
-
let { length } =
|
|
809
|
+
const current = state.value;
|
|
810
|
+
const next = value ?? {};
|
|
811
|
+
const currentKeys = Object.keys(current);
|
|
812
|
+
const nextKeys = Object.keys(next);
|
|
813
|
+
let { length } = currentKeys;
|
|
807
814
|
for (let index = 0; index < length; index += 1) {
|
|
808
|
-
const key =
|
|
809
|
-
|
|
815
|
+
const key = currentKeys[index];
|
|
816
|
+
current[key] = nextKeys.includes(key) ? next[key] : void 0;
|
|
810
817
|
}
|
|
811
|
-
length =
|
|
818
|
+
length = nextKeys.length;
|
|
812
819
|
for (let index = 0; index < length; index += 1) {
|
|
813
|
-
const key =
|
|
814
|
-
if (!
|
|
820
|
+
const key = nextKeys[index];
|
|
821
|
+
if (!currentKeys.includes(key)) current[key] = next[key];
|
|
815
822
|
}
|
|
816
823
|
stopBatch();
|
|
817
824
|
}
|
|
@@ -820,8 +827,10 @@ function setProxyProperty(state, property, value) {
|
|
|
820
827
|
state.value[property] = value;
|
|
821
828
|
return;
|
|
822
829
|
}
|
|
823
|
-
const
|
|
824
|
-
|
|
830
|
+
const array = state.value;
|
|
831
|
+
const index = property;
|
|
832
|
+
const actual = index < 0 ? array.length + index : index;
|
|
833
|
+
if (actual > -1) array[actual] = value;
|
|
825
834
|
}
|
|
826
835
|
function setProxyValue(first, second) {
|
|
827
836
|
const state = this[SYMBOL_STATE];
|
|
@@ -833,34 +842,34 @@ function setProxyValue(first, second) {
|
|
|
833
842
|
setProxyObject(state, first);
|
|
834
843
|
return;
|
|
835
844
|
}
|
|
836
|
-
const
|
|
837
|
-
if (state.isArray &&
|
|
838
|
-
let actual =
|
|
845
|
+
const keyed = isProxyKey(state.isArray, first);
|
|
846
|
+
if (state.isArray && keyed && Number.isNaN(first)) return;
|
|
847
|
+
let actual = keyed ? second : first;
|
|
839
848
|
if (typeof actual === "function") try {
|
|
840
849
|
actual = actual();
|
|
841
850
|
} catch {
|
|
842
851
|
return;
|
|
843
852
|
}
|
|
844
853
|
if (actual instanceof Promise) {
|
|
845
|
-
if (
|
|
854
|
+
if (keyed) {
|
|
846
855
|
state.promises ??= /* @__PURE__ */ new Map();
|
|
847
856
|
state.promises.set(first, actual);
|
|
848
857
|
} else state.promise = actual;
|
|
849
858
|
actual.then((value) => {
|
|
850
|
-
if (
|
|
851
|
-
state.promises
|
|
859
|
+
if (keyed && state.promises?.get(first) === actual) {
|
|
860
|
+
state.promises?.delete(first);
|
|
852
861
|
setProxyProperty(state, first, value);
|
|
853
862
|
return;
|
|
854
863
|
}
|
|
855
|
-
if (!
|
|
864
|
+
if (!keyed && isProxyObject(state.isArray, value) && state.promise === actual) {
|
|
856
865
|
state.promise = void 0;
|
|
857
866
|
setProxyObject(state, value);
|
|
858
867
|
}
|
|
859
868
|
}).catch(() => {
|
|
860
|
-
if (
|
|
861
|
-
else if (!
|
|
869
|
+
if (keyed && state.promises?.get(first) === actual) state.promises?.delete(first);
|
|
870
|
+
else if (!keyed && state.promise === actual) state.promise = void 0;
|
|
862
871
|
});
|
|
863
|
-
} else if (
|
|
872
|
+
} else if (keyed) setProxyProperty(state, first, actual);
|
|
864
873
|
else if (isProxyObject(state.isArray, actual)) setProxyObject(state, actual);
|
|
865
874
|
}
|
|
866
875
|
function setValueInProxy(instance, target, property, value) {
|
|
@@ -883,60 +892,51 @@ function updateProxyValue(callback) {
|
|
|
883
892
|
//#endregion
|
|
884
893
|
//#region src/value/readonly.ts
|
|
885
894
|
function Readonly(state, frozen) {
|
|
895
|
+
this[SUBSCRIPTION_TYPE_FROZEN] = frozen;
|
|
886
896
|
this[SYMBOL_STATE] = state;
|
|
887
|
-
Object.defineProperty(this, SUBSCRIPTION_TYPE_FROZEN, {
|
|
888
|
-
enumerable: true,
|
|
889
|
-
value: frozen
|
|
890
|
-
});
|
|
891
897
|
}
|
|
892
898
|
Readonly.prototype[NAME_MORA] = NAME_READONLY;
|
|
899
|
+
Readonly.prototype.get = getReadonlyValue;
|
|
900
|
+
Readonly.prototype.peek = peekReadonlyValue;
|
|
893
901
|
Readonly.prototype.subscribe = subscribeToReadonly;
|
|
902
|
+
Readonly.prototype.toJSON = getJsonValue;
|
|
894
903
|
Readonly.prototype.toString = getStringValue;
|
|
895
|
-
|
|
896
|
-
return
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
return getReadonlyValue(this, true, this[SUBSCRIPTION_TYPE_FROZEN], copy);
|
|
900
|
-
};
|
|
901
|
-
Readonly.prototype.toJSON = function() {
|
|
902
|
-
return this[SYMBOL_STATE].value;
|
|
903
|
-
};
|
|
904
|
-
function getReadonlyInstance(frozen) {
|
|
904
|
+
function getReadonlyInstance(state, frozen) {
|
|
905
|
+
return new Readonly(state, frozen);
|
|
906
|
+
}
|
|
907
|
+
function getReadonlySignal(frozen) {
|
|
905
908
|
const key = frozen === true ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_ORIGINAL;
|
|
906
909
|
this[SYMBOL_STATE].readonlies ??= {};
|
|
907
|
-
this[SYMBOL_STATE].readonlies[key] ??=
|
|
910
|
+
this[SYMBOL_STATE].readonlies[key] ??= getReadonlyInstance(this[SYMBOL_STATE], frozen === true);
|
|
908
911
|
return this[SYMBOL_STATE].readonlies[key];
|
|
909
912
|
}
|
|
910
|
-
function
|
|
911
|
-
return
|
|
913
|
+
function getReadonlyValue() {
|
|
914
|
+
return handleReadonlyValue(this, false, this[SUBSCRIPTION_TYPE_FROZEN]);
|
|
912
915
|
}
|
|
913
|
-
function
|
|
916
|
+
function handleReadonlyValue(instance, peek, frozen, copy) {
|
|
914
917
|
let value;
|
|
915
918
|
if (peek) value = peekSignalValue.call(instance, copy === true);
|
|
916
919
|
else value = getSignalValue.call(instance);
|
|
917
920
|
return frozen ? getFrozenValue(value) : value;
|
|
918
921
|
}
|
|
922
|
+
function peekReadonlyValue(copy) {
|
|
923
|
+
return handleReadonlyValue(this, true, this[SUBSCRIPTION_TYPE_FROZEN], copy);
|
|
924
|
+
}
|
|
919
925
|
//#endregion
|
|
920
926
|
//#region src/value/signal.ts
|
|
921
927
|
function Signal(value, options) {
|
|
922
928
|
this[SYMBOL_STATE] = getState(void 0, options);
|
|
923
|
-
|
|
929
|
+
handleSignal(this, value, setAndEmit);
|
|
924
930
|
}
|
|
925
931
|
Signal.prototype[NAME_MORA] = NAME_SIGNAL;
|
|
926
|
-
Signal.prototype.asReadonly =
|
|
932
|
+
Signal.prototype.asReadonly = getReadonlySignal;
|
|
927
933
|
Signal.prototype.get = getSignalValue;
|
|
928
934
|
Signal.prototype.peek = peekSignalValue;
|
|
935
|
+
Signal.prototype.set = setSignalValue;
|
|
929
936
|
Signal.prototype.subscribe = subscribeToSignal;
|
|
930
937
|
Signal.prototype.toString = getStringValue;
|
|
931
|
-
Signal.prototype.
|
|
932
|
-
|
|
933
|
-
};
|
|
934
|
-
Signal.prototype.toJSON = function() {
|
|
935
|
-
return this[SYMBOL_STATE].value;
|
|
936
|
-
};
|
|
937
|
-
Signal.prototype.update = function(callback) {
|
|
938
|
-
return updateSignalValue(this, callback, setAndEmit);
|
|
939
|
-
};
|
|
938
|
+
Signal.prototype.toJSON = getJsonValue;
|
|
939
|
+
Signal.prototype.update = updateSignalValue;
|
|
940
940
|
function setAndEmit(instance, value) {
|
|
941
941
|
const state = instance[SYMBOL_STATE];
|
|
942
942
|
if (!(state.equal ?? Object.is)(state.value, value)) {
|
|
@@ -944,9 +944,15 @@ function setAndEmit(instance, value) {
|
|
|
944
944
|
emitValue(instance);
|
|
945
945
|
}
|
|
946
946
|
}
|
|
947
|
+
function setSignalValue(value) {
|
|
948
|
+
handleSignal(this, value, setAndEmit);
|
|
949
|
+
}
|
|
947
950
|
function signal(value, options) {
|
|
948
951
|
return new Signal(value, options);
|
|
949
952
|
}
|
|
953
|
+
function updateSignalValue(callback) {
|
|
954
|
+
updateSignal(this, callback, setAndEmit);
|
|
955
|
+
}
|
|
950
956
|
//#endregion
|
|
951
957
|
//#region src/value/array.ts
|
|
952
958
|
function ReactiveArray(value, options) {
|
|
@@ -959,64 +965,76 @@ function ReactiveArray(value, options) {
|
|
|
959
965
|
get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(this, property, target) : Reflect.get(target, property),
|
|
960
966
|
set: (target, property, value) => setValueInProxy(this, target, property, value)
|
|
961
967
|
});
|
|
962
|
-
Object.defineProperty(this, PROPERTY_LENGTH, {
|
|
963
|
-
enumerable: true,
|
|
964
|
-
get: () => this[SYMBOL_STATE].length.get(),
|
|
965
|
-
set: (value) => setArrayLength(this[SYMBOL_STATE], value)
|
|
966
|
-
});
|
|
967
968
|
setProxyValue.call(this, value);
|
|
968
969
|
}
|
|
969
970
|
ReactiveArray.prototype[NAME_MORA] = NAME_ARRAY;
|
|
970
|
-
ReactiveArray.prototype
|
|
971
|
+
Object.defineProperty(ReactiveArray.prototype, PROPERTY_LENGTH, {
|
|
972
|
+
enumerable: true,
|
|
973
|
+
get: getArrayLength,
|
|
974
|
+
set: setArrayLength
|
|
975
|
+
});
|
|
976
|
+
ReactiveArray.prototype.asReadonly = getReadonlySignal;
|
|
971
977
|
ReactiveArray.prototype.at = getArrayValues;
|
|
978
|
+
ReactiveArray.prototype.clear = clearArrayValues;
|
|
979
|
+
ReactiveArray.prototype.filter = filterArrayValues;
|
|
972
980
|
ReactiveArray.prototype.get = getArrayValues;
|
|
981
|
+
ReactiveArray.prototype.map = mapArrayValues;
|
|
973
982
|
ReactiveArray.prototype.notify = emitProxyValues;
|
|
974
983
|
ReactiveArray.prototype.peek = peekArrayValue;
|
|
984
|
+
ReactiveArray.prototype.pop = popArrayValue;
|
|
985
|
+
ReactiveArray.prototype.push = pushArrayValues;
|
|
986
|
+
ReactiveArray.prototype.select = selectArrayValues;
|
|
987
|
+
ReactiveArray.prototype.shift = shiftArrayValue;
|
|
975
988
|
ReactiveArray.prototype.set = setProxyValue;
|
|
989
|
+
ReactiveArray.prototype.splice = spliceArrayValues;
|
|
976
990
|
ReactiveArray.prototype.subscribe = subscribeToProxy;
|
|
977
991
|
ReactiveArray.prototype.toString = getStringValue;
|
|
992
|
+
ReactiveArray.prototype.toJSON = getJsonValue;
|
|
993
|
+
ReactiveArray.prototype.unshift = unshiftArrayValues;
|
|
978
994
|
ReactiveArray.prototype.update = updateProxyValue;
|
|
979
|
-
ReactiveArray.prototype.clear = function() {
|
|
980
|
-
this[SYMBOL_STATE].value.length = 0;
|
|
981
|
-
};
|
|
982
|
-
ReactiveArray.prototype.filter = function(callback) {
|
|
983
|
-
return computed(() => filter(getArrayValues.call(this), callback));
|
|
984
|
-
};
|
|
985
|
-
ReactiveArray.prototype.map = function(callback) {
|
|
986
|
-
return computed(() => getArrayValues.call(this).map(callback));
|
|
987
|
-
};
|
|
988
|
-
ReactiveArray.prototype.pop = function() {
|
|
989
|
-
return this[SYMBOL_STATE].value.pop();
|
|
990
|
-
};
|
|
991
|
-
ReactiveArray.prototype.push = function(...items) {
|
|
992
|
-
return this[SYMBOL_STATE].value.push(...items);
|
|
993
|
-
};
|
|
994
|
-
ReactiveArray.prototype.select = function(filter, map) {
|
|
995
|
-
return computed(() => select(getArrayValues.call(this), filter, map));
|
|
996
|
-
};
|
|
997
|
-
ReactiveArray.prototype.shift = function() {
|
|
998
|
-
return this[SYMBOL_STATE].value.shift();
|
|
999
|
-
};
|
|
1000
|
-
ReactiveArray.prototype.splice = function(from, to, ...items) {
|
|
1001
|
-
return this[SYMBOL_STATE].value.splice(from, to ?? this[SYMBOL_STATE].value.length, ...items);
|
|
1002
|
-
};
|
|
1003
|
-
ReactiveArray.prototype.toJSON = function() {
|
|
1004
|
-
return this[SYMBOL_STATE].value;
|
|
1005
|
-
};
|
|
1006
|
-
ReactiveArray.prototype.unshift = function(...items) {
|
|
1007
|
-
return this[SYMBOL_STATE].value.unshift(...items);
|
|
1008
|
-
};
|
|
1009
995
|
function array(value, options) {
|
|
1010
996
|
return new ReactiveArray(value, options);
|
|
1011
997
|
}
|
|
998
|
+
function clearArrayValues() {
|
|
999
|
+
this[SYMBOL_STATE].value.length = 0;
|
|
1000
|
+
}
|
|
1001
|
+
function filterArrayValues(callback) {
|
|
1002
|
+
return computed(() => filter(getArrayValues.call(this), callback));
|
|
1003
|
+
}
|
|
1004
|
+
function getArrayLength() {
|
|
1005
|
+
return this[SYMBOL_STATE].length.get();
|
|
1006
|
+
}
|
|
1012
1007
|
function getArrayValues(value) {
|
|
1013
1008
|
return value === "length" ? this[SYMBOL_STATE].length.get() : getValueInProxy.call(this, value);
|
|
1014
1009
|
}
|
|
1010
|
+
function mapArrayValues(callback) {
|
|
1011
|
+
return computed(() => getArrayValues.call(this).map(callback));
|
|
1012
|
+
}
|
|
1015
1013
|
function peekArrayValue(first, second) {
|
|
1016
1014
|
return first === "length" ? this[SYMBOL_STATE].length.peek() : peekValueInProxy.call(this, first, second);
|
|
1017
1015
|
}
|
|
1018
|
-
function
|
|
1019
|
-
|
|
1016
|
+
function popArrayValue() {
|
|
1017
|
+
return this[SYMBOL_STATE].value.pop();
|
|
1018
|
+
}
|
|
1019
|
+
function pushArrayValues(...items) {
|
|
1020
|
+
return this[SYMBOL_STATE].value.push(...items);
|
|
1021
|
+
}
|
|
1022
|
+
function selectArrayValues(filter, map) {
|
|
1023
|
+
return computed(() => select(getArrayValues.call(this), filter, map));
|
|
1024
|
+
}
|
|
1025
|
+
function setArrayLength(value) {
|
|
1026
|
+
const values = this[SYMBOL_STATE].value;
|
|
1027
|
+
if (typeof value === "number" && !Number.isNaN(value) && value >= 0 && value !== values.length) values.length = value;
|
|
1028
|
+
}
|
|
1029
|
+
function shiftArrayValue() {
|
|
1030
|
+
return this[SYMBOL_STATE].value.shift();
|
|
1031
|
+
}
|
|
1032
|
+
function spliceArrayValues(from, to, ...items) {
|
|
1033
|
+
const values = this[SYMBOL_STATE].value;
|
|
1034
|
+
return values.splice(from, to ?? values.length, ...items);
|
|
1035
|
+
}
|
|
1036
|
+
function unshiftArrayValues(...items) {
|
|
1037
|
+
return this[SYMBOL_STATE].value.unshift(...items);
|
|
1020
1038
|
}
|
|
1021
1039
|
function updateArray(instance, type, array) {
|
|
1022
1040
|
const state = instance[SYMBOL_STATE];
|
|
@@ -1025,7 +1043,7 @@ function updateArray(instance, type, array) {
|
|
|
1025
1043
|
const previousLength = array.length;
|
|
1026
1044
|
return (...args) => {
|
|
1027
1045
|
const result = array[type](...args);
|
|
1028
|
-
if (affectsLength ? array.length !== previousLength : !equalArrays(
|
|
1046
|
+
if (affectsLength ? array.length !== previousLength : !equalArrays(previousArray, array, state.equal)) {
|
|
1029
1047
|
emitValue(instance);
|
|
1030
1048
|
state.length.set(array.length);
|
|
1031
1049
|
}
|
|
@@ -1043,17 +1061,15 @@ function ReactiveStore(value, options) {
|
|
|
1043
1061
|
setProxyValue.call(this, value);
|
|
1044
1062
|
}
|
|
1045
1063
|
ReactiveStore.prototype[NAME_MORA] = NAME_STORE;
|
|
1046
|
-
ReactiveStore.prototype.asReadonly =
|
|
1064
|
+
ReactiveStore.prototype.asReadonly = getReadonlySignal;
|
|
1047
1065
|
ReactiveStore.prototype.get = getValueInProxy;
|
|
1048
1066
|
ReactiveStore.prototype.notify = emitProxyValues;
|
|
1049
1067
|
ReactiveStore.prototype.peek = peekValueInProxy;
|
|
1050
1068
|
ReactiveStore.prototype.set = setProxyValue;
|
|
1051
1069
|
ReactiveStore.prototype.subscribe = subscribeToProxy;
|
|
1070
|
+
ReactiveStore.prototype.toJSON = getJsonValue;
|
|
1052
1071
|
ReactiveStore.prototype.toString = getStringValue;
|
|
1053
1072
|
ReactiveStore.prototype.update = updateProxyValue;
|
|
1054
|
-
ReactiveStore.prototype.toJSON = function() {
|
|
1055
|
-
return this[SYMBOL_STATE].value;
|
|
1056
|
-
};
|
|
1057
1073
|
function store(value, options) {
|
|
1058
1074
|
return new ReactiveStore(value, options);
|
|
1059
1075
|
}
|
package/dist/value/array.mjs
CHANGED
|
@@ -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 {
|
|
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
|
|
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
|
|
79
|
-
|
|
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(
|
|
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>): [
|
|
13
|
+
export declare function internalComputed(callback: GenericCallback, options?: ReactiveOptions<unknown>): [InternalComputed, ComputedEffect];
|
|
14
14
|
//#endregion
|
package/dist/value/computed.mjs
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
|
4
|
-
export declare function getReadonlySignal(
|
|
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
|
package/dist/value/readonly.mjs
CHANGED
|
@@ -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
|
-
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
|
|
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] ??=
|
|
21
|
+
this[SYMBOL_STATE].readonlies[key] ??= getReadonlyInstance(this[SYMBOL_STATE], frozen === true);
|
|
28
22
|
return this[SYMBOL_STATE].readonlies[key];
|
|
29
23
|
}
|
|
30
|
-
function
|
|
31
|
-
return
|
|
24
|
+
function getReadonlyValue() {
|
|
25
|
+
return handleReadonlyValue(this, false, this[SUBSCRIPTION_TYPE_FROZEN]);
|
|
32
26
|
}
|
|
33
|
-
function
|
|
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 };
|