mutts 1.0.13 → 1.0.15
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/BROWSER_ASYNC_POLYFILL.md +79 -0
- package/README.md +2 -2
- package/dist/browser.cjs +216 -97
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +42 -9
- package/dist/browser.dev.cjs +81 -71
- package/dist/browser.dev.cjs.map +1 -1
- package/dist/browser.dev.d.ts +2 -2
- package/dist/browser.dev.esm.js +2 -2
- package/dist/browser.esm.js +137 -28
- package/dist/browser.esm.js.map +1 -1
- package/dist/chunks/{proxy-BtmPFjSr.esm.js → effects-CPjf6gNA.esm.js} +2605 -2155
- package/dist/chunks/effects-CPjf6gNA.esm.js.map +1 -0
- package/dist/chunks/{proxy-DBHj3kGK.cjs → effects-oUauWxxl.cjs} +2615 -2156
- package/dist/chunks/effects-oUauWxxl.cjs.map +1 -0
- package/dist/chunks/{index-CAdnMJev.cjs → index-Dtj2qZ0d.cjs} +418 -350
- package/dist/chunks/index-Dtj2qZ0d.cjs.map +1 -0
- package/dist/chunks/{index-XsYTUhHx.esm.js → index-YGpb1te7.esm.js} +156 -88
- package/dist/chunks/index-YGpb1te7.esm.js.map +1 -0
- package/dist/chunks/node-CKuro-Uk.cjs +187 -0
- package/dist/chunks/node-CKuro-Uk.cjs.map +1 -0
- package/dist/chunks/node-sQtns7M-.esm.js +185 -0
- package/dist/chunks/node-sQtns7M-.esm.js.map +1 -0
- package/dist/debug.cjs +76 -49
- package/dist/debug.cjs.map +1 -1
- package/dist/debug.esm.js +37 -10
- package/dist/debug.esm.js.map +1 -1
- package/dist/mutts.umd.js +4169 -3532
- package/dist/mutts.umd.js.map +1 -1
- package/dist/mutts.umd.min.js +1 -1
- package/dist/mutts.umd.min.js.map +1 -1
- package/dist/node.cjs +82 -72
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.dev.cjs +82 -72
- package/dist/node.dev.cjs.map +1 -1
- package/dist/node.dev.d.ts +2 -2
- package/dist/node.dev.esm.js +3 -3
- package/dist/node.esm.js +3 -3
- package/dist/types.d.ts +30 -15
- package/docs/ai/api-reference.md +3 -1
- package/docs/ai/manual.md +17 -5
- package/docs/reactive/advanced.md +169 -10
- package/docs/reactive/debugging.md +15 -13
- package/docs/reactive.md +2 -1
- package/package.json +12 -7
- package/dist/chunks/index-CAdnMJev.cjs.map +0 -1
- package/dist/chunks/index-XsYTUhHx.esm.js.map +0 -1
- package/dist/chunks/node-DrrphEPf.cjs +0 -98
- package/dist/chunks/node-DrrphEPf.cjs.map +0 -1
- package/dist/chunks/node-NEZvVo4M.esm.js +0 -96
- package/dist/chunks/node-NEZvVo4M.esm.js.map +0 -1
- package/dist/chunks/proxy-BtmPFjSr.esm.js.map +0 -1
- package/dist/chunks/proxy-DBHj3kGK.cjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var effects = require('./effects-oUauWxxl.cjs');
|
|
4
4
|
|
|
5
5
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
6
6
|
// Integrated with `using` statement via Symbol.dispose
|
|
@@ -83,7 +83,7 @@ function Destroyable(base, destructorObj) {
|
|
|
83
83
|
* Decorator that marks properties to be stored in the allocated object and passed to the destructor
|
|
84
84
|
* Use with accessor properties or explicit get/set pairs
|
|
85
85
|
*/
|
|
86
|
-
const allocated =
|
|
86
|
+
const allocated = effects.decorator({
|
|
87
87
|
setter(original, _target, propertyKey) {
|
|
88
88
|
return function (value) {
|
|
89
89
|
this[allocatedValues][propertyKey] = value;
|
|
@@ -758,7 +758,7 @@ function chainPromise(given) {
|
|
|
758
758
|
return chained;
|
|
759
759
|
}
|
|
760
760
|
|
|
761
|
-
const attend =
|
|
761
|
+
const attend = effects.captioned(function attend(source, callback) {
|
|
762
762
|
const enumerate = typeof source === 'function'
|
|
763
763
|
? source
|
|
764
764
|
: Array.isArray(source)
|
|
@@ -770,7 +770,7 @@ const attend = proxy.captioned(function attend(source, callback) {
|
|
|
770
770
|
: () => Object.keys(source);
|
|
771
771
|
const keyEffects = new Map();
|
|
772
772
|
const callbackLabel = callback.name ? callback.name : '';
|
|
773
|
-
const outer =
|
|
773
|
+
const outer = effects.effect `attend`(({ ascend }) => {
|
|
774
774
|
const keys = new Set();
|
|
775
775
|
for (const key of enumerate())
|
|
776
776
|
keys.add(key);
|
|
@@ -778,7 +778,7 @@ const attend = proxy.captioned(function attend(source, callback) {
|
|
|
778
778
|
if (keyEffects.has(key))
|
|
779
779
|
continue;
|
|
780
780
|
const indexRef = { value: key };
|
|
781
|
-
keyEffects.set(key, ascend(() =>
|
|
781
|
+
keyEffects.set(key, ascend(() => effects.effect `attend${callbackLabel ? `:${callbackLabel}` : ''}:${key}`((access) => callback(indexRef.value, access))));
|
|
782
782
|
}
|
|
783
783
|
for (const key of Array.from(keyEffects.keys())) {
|
|
784
784
|
if (!keys.has(key)) {
|
|
@@ -796,7 +796,7 @@ const attend = proxy.captioned(function attend(source, callback) {
|
|
|
796
796
|
}, {
|
|
797
797
|
name: 'attend',
|
|
798
798
|
callbackIndex: 1,
|
|
799
|
-
warn: (message) =>
|
|
799
|
+
warn: (message) => effects.options.warn(`[reactive] ${message}`),
|
|
800
800
|
});
|
|
801
801
|
/**
|
|
802
802
|
* Lifts a callback that returns an object into a reactive object that automatically
|
|
@@ -826,18 +826,18 @@ const attend = proxy.captioned(function attend(source, callback) {
|
|
|
826
826
|
* @param cb Callback function that returns an object
|
|
827
827
|
* @returns A reactive object synchronized with the callback's result, with a [cleanup] property to stop tracking
|
|
828
828
|
*/
|
|
829
|
-
const lift =
|
|
829
|
+
const lift = effects.captioned(function lift(cb) {
|
|
830
830
|
let result;
|
|
831
831
|
let rawResult;
|
|
832
832
|
const resultName = `lift:${cb.name || 'anonymous'}`;
|
|
833
|
-
const liftCleanup =
|
|
833
|
+
const liftCleanup = effects.effect `lift:${cb.name}`(effects.markWithRoot((access) => {
|
|
834
834
|
const source = cb(access);
|
|
835
835
|
if (!source || typeof source !== 'object')
|
|
836
836
|
throw new Error('lift callback must return an array or object');
|
|
837
837
|
const sourceProto = Object.getPrototypeOf(source);
|
|
838
838
|
if (!result) {
|
|
839
|
-
rawResult =
|
|
840
|
-
result =
|
|
839
|
+
rawResult = effects.tag(resultName, Array.isArray(source) ? [] : Object.create(sourceProto));
|
|
840
|
+
result = effects.reactive(rawResult);
|
|
841
841
|
}
|
|
842
842
|
if (sourceProto !== Object.getPrototypeOf(result))
|
|
843
843
|
throw new Error('lift callback must return the same type as the previous result');
|
|
@@ -858,24 +858,24 @@ const lift = proxy.captioned(function lift(cb) {
|
|
|
858
858
|
if (!sameAccessor &&
|
|
859
859
|
recordResult[key] !==
|
|
860
860
|
(oldDesc ? (oldDesc.get ? oldDesc.get() : oldDesc.value) : undefined))
|
|
861
|
-
|
|
861
|
+
effects.touched1(rawResult, { type: 'set', prop: key }, key);
|
|
862
862
|
}
|
|
863
863
|
else {
|
|
864
864
|
Object.defineProperty(rawResult, key, newDesc);
|
|
865
|
-
|
|
865
|
+
effects.touched1(rawResult, { type: 'add', prop: key }, key);
|
|
866
866
|
}
|
|
867
867
|
}
|
|
868
868
|
for (const key of Object.keys(rawResult))
|
|
869
869
|
if (!(key in source)) {
|
|
870
870
|
delete recordResult[key];
|
|
871
|
-
|
|
871
|
+
effects.touched1(rawResult, { type: 'del', prop: key }, key);
|
|
872
872
|
}
|
|
873
873
|
}
|
|
874
874
|
}, cb));
|
|
875
|
-
return
|
|
875
|
+
return effects.link(result, liftCleanup);
|
|
876
876
|
}, {
|
|
877
877
|
name: 'lift',
|
|
878
|
-
warn: (message) =>
|
|
878
|
+
warn: (message) => effects.options.warn(`[reactive] ${message}`),
|
|
879
879
|
});
|
|
880
880
|
/**
|
|
881
881
|
* Reactively maps an array source through `fn`, producing a lazy reactive output array.
|
|
@@ -895,23 +895,27 @@ const lift = proxy.captioned(function lift(cb) {
|
|
|
895
895
|
* @returns A readonly reactive array with a `[cleanup]` method to dispose all effects
|
|
896
896
|
*/
|
|
897
897
|
function morphArray(source, fn, options) {
|
|
898
|
-
if (typeof source !== 'function' && !
|
|
899
|
-
return source.map((i) => fn(i));
|
|
898
|
+
if (typeof source !== 'function' && !effects.isReactive(source) && options?.pure === true) {
|
|
899
|
+
return source.map((i) => fn(i, { index: 0 }));
|
|
900
900
|
}
|
|
901
901
|
let track;
|
|
902
902
|
const itemEffects = new Map();
|
|
903
|
-
const cache =
|
|
903
|
+
const cache = effects.tag(`morph:${fn.name || 'anonymous'}`, []);
|
|
904
904
|
let input = [];
|
|
905
|
+
function currentCleanupReason() {
|
|
906
|
+
const activeEffect = effects.getActiveEffect();
|
|
907
|
+
if (!activeEffect)
|
|
908
|
+
return undefined;
|
|
909
|
+
const node = effects.getEffectNode(activeEffect);
|
|
910
|
+
return node.currentReason;
|
|
911
|
+
}
|
|
912
|
+
function stopEntry(entry) {
|
|
913
|
+
entry.stop(effects.chainExternalReason({ type: 'stopped', chain: currentCleanupReason() }));
|
|
914
|
+
}
|
|
905
915
|
function stopItem(key) {
|
|
906
916
|
const entry = itemEffects.get(key);
|
|
907
917
|
if (entry) {
|
|
908
|
-
|
|
909
|
-
let chain;
|
|
910
|
-
if (activeEffect) {
|
|
911
|
-
const node = proxy.getEffectNode(activeEffect);
|
|
912
|
-
chain = node.currentReason;
|
|
913
|
-
}
|
|
914
|
-
entry.stop(proxy.chainExternalReason({ type: 'stopped', chain }));
|
|
918
|
+
stopEntry(entry);
|
|
915
919
|
itemEffects.delete(key);
|
|
916
920
|
}
|
|
917
921
|
}
|
|
@@ -919,33 +923,36 @@ function morphArray(source, fn, options) {
|
|
|
919
923
|
const isPure = options?.pure === true || (typeof options?.pure === 'function' && options.pure(input));
|
|
920
924
|
if (isPure) {
|
|
921
925
|
track(() => {
|
|
922
|
-
cache[key] = fn(input);
|
|
926
|
+
cache[key] = fn(input, { index: key });
|
|
923
927
|
});
|
|
924
928
|
}
|
|
925
929
|
else {
|
|
926
|
-
const
|
|
927
|
-
const stop = track(() =>
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
const activeEffect = proxy.getActiveEffect();
|
|
930
|
+
const position = effects.reactive({ index: key });
|
|
931
|
+
const stop = track(() => effects.effect.opaque `morph:${fn.name}:${key}`((access) => {
|
|
932
|
+
if (access.reaction) {
|
|
933
|
+
delete cache[position.index];
|
|
934
|
+
effects.touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
|
|
935
|
+
const activeEffect = effects.getActiveEffect();
|
|
933
936
|
let chain;
|
|
934
937
|
if (activeEffect) {
|
|
935
|
-
const node =
|
|
938
|
+
const node = effects.getEffectNode(activeEffect);
|
|
936
939
|
chain = node.currentReason;
|
|
937
940
|
}
|
|
938
941
|
stop?.({
|
|
939
942
|
type: 'invalidate',
|
|
940
|
-
cause:
|
|
941
|
-
|
|
943
|
+
cause: effects.chainExternalReason(!access.reaction || access.reaction === true
|
|
944
|
+
? { type: 'stopped', chain }
|
|
945
|
+
: access.reaction),
|
|
946
|
+
chain: effects.chainExternalReason(chain),
|
|
942
947
|
});
|
|
943
|
-
}
|
|
948
|
+
}
|
|
949
|
+
else
|
|
950
|
+
cache[position.index] = fn(input, position, access);
|
|
944
951
|
}));
|
|
945
|
-
itemEffects.set(key, { stop,
|
|
952
|
+
itemEffects.set(key, { stop, position });
|
|
946
953
|
}
|
|
947
954
|
}
|
|
948
|
-
const proxy
|
|
955
|
+
const proxy = effects.reactive(cache, {
|
|
949
956
|
get(cache, prop) {
|
|
950
957
|
const n = typeof prop === 'string' ? Number(prop) : NaN;
|
|
951
958
|
if (Number.isNaN(n))
|
|
@@ -958,42 +965,66 @@ function morphArray(source, fn, options) {
|
|
|
958
965
|
return Reflect.has(input, prop);
|
|
959
966
|
},
|
|
960
967
|
});
|
|
961
|
-
const stopMain =
|
|
968
|
+
const stopMain = effects.effect `morph:${fn.name}`(({ ascend }) => {
|
|
962
969
|
track = ascend;
|
|
963
970
|
const newInput = [...(typeof source === 'function' ? source() : source)];
|
|
964
971
|
const diffs = arrayDiff(input, newInput).toSorted((a, b) => b.indexA - a.indexA);
|
|
965
972
|
if (diffs.length > 0) {
|
|
973
|
+
const reusable = new Map();
|
|
974
|
+
for (const [index, entry] of itemEffects) {
|
|
975
|
+
const value = input[index];
|
|
976
|
+
const entries = reusable.get(value);
|
|
977
|
+
if (entries)
|
|
978
|
+
entries.push({ index, entry });
|
|
979
|
+
else
|
|
980
|
+
reusable.set(value, [{ index, entry }]);
|
|
981
|
+
}
|
|
982
|
+
const nextEffects = new Map();
|
|
983
|
+
const reused = new Set();
|
|
984
|
+
const nextCache = new Map();
|
|
985
|
+
for (let index = 0; index < newInput.length; index++) {
|
|
986
|
+
const entries = reusable.get(newInput[index]);
|
|
987
|
+
const reusedEntry = entries?.shift();
|
|
988
|
+
if (!reusedEntry)
|
|
989
|
+
continue;
|
|
990
|
+
const { index: previousIndex, entry } = reusedEntry;
|
|
991
|
+
reused.add(previousIndex);
|
|
992
|
+
nextEffects.set(index, entry);
|
|
993
|
+
if (entry.position.index !== index)
|
|
994
|
+
entry.position.index = index;
|
|
995
|
+
else if (Object.hasOwn(cache, previousIndex))
|
|
996
|
+
nextCache.set(index, cache[previousIndex]);
|
|
997
|
+
}
|
|
998
|
+
for (const [index, entry] of itemEffects) {
|
|
999
|
+
if (!reused.has(index))
|
|
1000
|
+
stopEntry(entry);
|
|
1001
|
+
}
|
|
1002
|
+
itemEffects.clear();
|
|
1003
|
+
for (const [index, entry] of nextEffects)
|
|
1004
|
+
itemEffects.set(index, entry);
|
|
1005
|
+
const previousLength = cache.length;
|
|
1006
|
+
cache.length = newInput.length;
|
|
1007
|
+
for (let i = 0; i < Math.max(previousLength, newInput.length); i++)
|
|
1008
|
+
delete cache[i];
|
|
1009
|
+
for (const [index, value] of nextCache)
|
|
1010
|
+
cache[index] = value;
|
|
1011
|
+
const eagerIndices = new Set();
|
|
966
1012
|
for (const diff of diffs) {
|
|
967
|
-
|
|
968
|
-
for (let i =
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
if (
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
for (const [idx, entry] of entries) {
|
|
983
|
-
if (idx >= diff.indexA + diff.sliceA.length) {
|
|
984
|
-
const newIdx = idx + shift;
|
|
985
|
-
entry.index.value = newIdx;
|
|
986
|
-
itemEffects.set(newIdx, entry);
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
// Splice the cache
|
|
991
|
-
cache.splice(diff.indexA, diff.sliceA.length, ...new Array(diff.sliceB.length).fill(undefined));
|
|
992
|
-
// Make holes for lazy computation
|
|
993
|
-
for (let i = diff.indexA; i < diff.indexA + diff.sliceB.length; i++)
|
|
994
|
-
delete cache[i];
|
|
995
|
-
}
|
|
996
|
-
const invalidates = new Set([proxy.keysOf]);
|
|
1013
|
+
const max = Math.max(diff.sliceA.length, diff.sliceB.length);
|
|
1014
|
+
for (let i = 0; i < max; i++)
|
|
1015
|
+
eagerIndices.add(diff.indexA + i);
|
|
1016
|
+
}
|
|
1017
|
+
for (const index of eagerIndices) {
|
|
1018
|
+
if (index < 0 || index >= newInput.length || Object.hasOwn(cache, index))
|
|
1019
|
+
continue;
|
|
1020
|
+
const value = newInput[index];
|
|
1021
|
+
const isPure = options?.pure === true || (typeof options?.pure === 'function' && options.pure(value));
|
|
1022
|
+
if (isPure)
|
|
1023
|
+
continue;
|
|
1024
|
+
stopItem(index);
|
|
1025
|
+
computeItem(index, value);
|
|
1026
|
+
}
|
|
1027
|
+
const invalidates = new Set([effects.keysOf]);
|
|
997
1028
|
if (input.length !== newInput.length)
|
|
998
1029
|
invalidates.add('length');
|
|
999
1030
|
for (const diff of diffs) {
|
|
@@ -1001,11 +1032,11 @@ function morphArray(source, fn, options) {
|
|
|
1001
1032
|
for (let i = 0; i < max; i++)
|
|
1002
1033
|
invalidates.add(String(diff.indexA + i));
|
|
1003
1034
|
}
|
|
1004
|
-
|
|
1035
|
+
effects.touched(cache, { type: 'bunch', method: 'morph-input' }, invalidates);
|
|
1005
1036
|
}
|
|
1006
1037
|
input = newInput;
|
|
1007
1038
|
});
|
|
1008
|
-
return
|
|
1039
|
+
return effects.link(proxy, (reason) => {
|
|
1009
1040
|
stopMain(reason);
|
|
1010
1041
|
for (const entry of itemEffects.values())
|
|
1011
1042
|
entry.stop(reason);
|
|
@@ -1024,7 +1055,7 @@ function morphArray(source, fn, options) {
|
|
|
1024
1055
|
* @returns A reactive Map with a `[cleanup]` method to dispose all effects
|
|
1025
1056
|
*/
|
|
1026
1057
|
function morphMap(source, fn, options) {
|
|
1027
|
-
if (!
|
|
1058
|
+
if (!effects.isReactive(source) && options?.pure === true) {
|
|
1028
1059
|
const res = new Map();
|
|
1029
1060
|
for (const [k, v] of source)
|
|
1030
1061
|
res.set(k, fn(v, k));
|
|
@@ -1032,15 +1063,15 @@ function morphMap(source, fn, options) {
|
|
|
1032
1063
|
}
|
|
1033
1064
|
let track;
|
|
1034
1065
|
const itemEffects = new Map();
|
|
1035
|
-
const cache =
|
|
1066
|
+
const cache = effects.tag(`morph:${fn.name || 'anonymous'}`, new Map());
|
|
1036
1067
|
Object.defineProperty(cache, 'constructor', { value: Object, enumerable: false });
|
|
1037
1068
|
function stopItem(key) {
|
|
1038
1069
|
const stop = itemEffects.get(key);
|
|
1039
1070
|
if (stop) {
|
|
1040
|
-
const activeEffect =
|
|
1071
|
+
const activeEffect = effects.getActiveEffect();
|
|
1041
1072
|
let chain;
|
|
1042
1073
|
if (activeEffect) {
|
|
1043
|
-
const node =
|
|
1074
|
+
const node = effects.getEffectNode(activeEffect);
|
|
1044
1075
|
chain = node.currentReason;
|
|
1045
1076
|
}
|
|
1046
1077
|
stop({ type: 'stopped', chain });
|
|
@@ -1053,31 +1084,31 @@ function morphMap(source, fn, options) {
|
|
|
1053
1084
|
cache.set(key, track(() => fn(val, key)));
|
|
1054
1085
|
}
|
|
1055
1086
|
else {
|
|
1056
|
-
const stop = track(() =>
|
|
1087
|
+
const stop = track(() => effects.effect.opaque `morph:${fn.name}:${key}`((access) => {
|
|
1057
1088
|
const next = source.get(key);
|
|
1058
1089
|
if (next === undefined && !source.has(key))
|
|
1059
1090
|
return;
|
|
1060
1091
|
cache.set(key, fn(next, key, access));
|
|
1061
1092
|
return (reason) => {
|
|
1062
1093
|
cache.delete(key);
|
|
1063
|
-
|
|
1064
|
-
const activeEffect =
|
|
1094
|
+
effects.touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
|
|
1095
|
+
const activeEffect = effects.getActiveEffect();
|
|
1065
1096
|
let chain;
|
|
1066
1097
|
if (activeEffect) {
|
|
1067
|
-
const node =
|
|
1098
|
+
const node = effects.getEffectNode(activeEffect);
|
|
1068
1099
|
chain = node.currentReason;
|
|
1069
1100
|
}
|
|
1070
1101
|
stop?.({
|
|
1071
1102
|
type: 'invalidate',
|
|
1072
|
-
cause:
|
|
1073
|
-
chain:
|
|
1103
|
+
cause: effects.chainExternalReason(reason ?? { type: 'stopped', chain }),
|
|
1104
|
+
chain: effects.chainExternalReason(chain),
|
|
1074
1105
|
});
|
|
1075
1106
|
};
|
|
1076
1107
|
}));
|
|
1077
1108
|
itemEffects.set(key, stop);
|
|
1078
1109
|
}
|
|
1079
1110
|
}
|
|
1080
|
-
const proxy
|
|
1111
|
+
const proxy = effects.reactive(cache, {
|
|
1081
1112
|
get(cache, prop) {
|
|
1082
1113
|
if (prop === 'get')
|
|
1083
1114
|
return (key) => {
|
|
@@ -1096,42 +1127,42 @@ function morphMap(source, fn, options) {
|
|
|
1096
1127
|
if (prop === 'values')
|
|
1097
1128
|
return function* () {
|
|
1098
1129
|
for (const key of source.keys()) {
|
|
1099
|
-
yield proxy
|
|
1130
|
+
yield proxy.get(key);
|
|
1100
1131
|
}
|
|
1101
1132
|
};
|
|
1102
1133
|
if (prop === 'entries')
|
|
1103
1134
|
return function* () {
|
|
1104
1135
|
for (const key of source.keys()) {
|
|
1105
|
-
yield [key, proxy
|
|
1136
|
+
yield [key, proxy.get(key)];
|
|
1106
1137
|
}
|
|
1107
1138
|
};
|
|
1108
1139
|
if (prop === Symbol.iterator)
|
|
1109
1140
|
return function* () {
|
|
1110
1141
|
for (const key of source.keys()) {
|
|
1111
|
-
yield [key, proxy
|
|
1142
|
+
yield [key, proxy.get(key)];
|
|
1112
1143
|
}
|
|
1113
1144
|
};
|
|
1114
1145
|
return cache[prop];
|
|
1115
1146
|
},
|
|
1116
1147
|
});
|
|
1117
|
-
let stateSnapshot =
|
|
1118
|
-
const stopMain =
|
|
1148
|
+
let stateSnapshot = effects.getState(source);
|
|
1149
|
+
const stopMain = effects.effect `morph:${fn.name}`(({ ascend }) => {
|
|
1119
1150
|
track = ascend;
|
|
1120
|
-
|
|
1151
|
+
effects.dependant(source, effects.keysOf);
|
|
1121
1152
|
while ('evolution' in stateSnapshot) {
|
|
1122
1153
|
const { evolution } = stateSnapshot;
|
|
1123
1154
|
stateSnapshot = stateSnapshot.next;
|
|
1124
1155
|
if (evolution.type === 'add') {
|
|
1125
|
-
|
|
1156
|
+
effects.touched1(cache, evolution, evolution.prop);
|
|
1126
1157
|
}
|
|
1127
1158
|
else if (evolution.type === 'del') {
|
|
1128
1159
|
stopItem(evolution.prop);
|
|
1129
1160
|
cache.delete(evolution.prop);
|
|
1130
|
-
|
|
1161
|
+
effects.touched1(cache, evolution, evolution.prop);
|
|
1131
1162
|
}
|
|
1132
1163
|
}
|
|
1133
1164
|
});
|
|
1134
|
-
return
|
|
1165
|
+
return effects.link(proxy, (reason) => {
|
|
1135
1166
|
stopMain(reason);
|
|
1136
1167
|
for (const stop of itemEffects.values())
|
|
1137
1168
|
stop(reason);
|
|
@@ -1150,7 +1181,7 @@ function morphMap(source, fn, options) {
|
|
|
1150
1181
|
* @returns A reactive record with a `[cleanup]` method to dispose all effects
|
|
1151
1182
|
*/
|
|
1152
1183
|
function morphRecord(source, fn, options) {
|
|
1153
|
-
if (!
|
|
1184
|
+
if (!effects.isReactive(source) && options?.pure === true) {
|
|
1154
1185
|
const res = {};
|
|
1155
1186
|
for (const k of Object.keys(source))
|
|
1156
1187
|
res[k] = fn(source[k], k);
|
|
@@ -1162,10 +1193,10 @@ function morphRecord(source, fn, options) {
|
|
|
1162
1193
|
function stopItem(key) {
|
|
1163
1194
|
const stop = itemEffects.get(key);
|
|
1164
1195
|
if (stop) {
|
|
1165
|
-
const activeEffect =
|
|
1196
|
+
const activeEffect = effects.getActiveEffect();
|
|
1166
1197
|
let chain;
|
|
1167
1198
|
if (activeEffect) {
|
|
1168
|
-
const node =
|
|
1199
|
+
const node = effects.getEffectNode(activeEffect);
|
|
1169
1200
|
chain = node.currentReason;
|
|
1170
1201
|
}
|
|
1171
1202
|
stop({ type: 'stopped', chain });
|
|
@@ -1178,21 +1209,21 @@ function morphRecord(source, fn, options) {
|
|
|
1178
1209
|
cache[key] = track(() => fn(val, key));
|
|
1179
1210
|
}
|
|
1180
1211
|
else {
|
|
1181
|
-
const stop = track(() =>
|
|
1212
|
+
const stop = track(() => effects.effect.opaque `morph:${fn.name}:${key}`((access) => {
|
|
1182
1213
|
cache[key] = fn(source[key], key, access);
|
|
1183
1214
|
return (reason) => {
|
|
1184
1215
|
delete cache[key];
|
|
1185
|
-
|
|
1186
|
-
const activeEffect =
|
|
1216
|
+
effects.touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
|
|
1217
|
+
const activeEffect = effects.getActiveEffect();
|
|
1187
1218
|
let chain;
|
|
1188
1219
|
if (activeEffect) {
|
|
1189
|
-
const node =
|
|
1220
|
+
const node = effects.getEffectNode(activeEffect);
|
|
1190
1221
|
chain = node.currentReason;
|
|
1191
1222
|
}
|
|
1192
1223
|
stop?.({
|
|
1193
1224
|
type: 'invalidate',
|
|
1194
|
-
cause:
|
|
1195
|
-
chain:
|
|
1225
|
+
cause: effects.chainExternalReason(reason ?? { type: 'stopped', chain }),
|
|
1226
|
+
chain: effects.chainExternalReason(chain),
|
|
1196
1227
|
});
|
|
1197
1228
|
};
|
|
1198
1229
|
}));
|
|
@@ -1204,7 +1235,7 @@ function morphRecord(source, fn, options) {
|
|
|
1204
1235
|
computeItem(prop, source[prop]);
|
|
1205
1236
|
return cache[prop];
|
|
1206
1237
|
}
|
|
1207
|
-
const proxy
|
|
1238
|
+
const proxy = effects.reactive(cache, {
|
|
1208
1239
|
get(_, prop) {
|
|
1209
1240
|
return get(prop);
|
|
1210
1241
|
},
|
|
@@ -1219,25 +1250,25 @@ function morphRecord(source, fn, options) {
|
|
|
1219
1250
|
return { configurable: true, enumerable: true, get: () => get(prop) };
|
|
1220
1251
|
},
|
|
1221
1252
|
});
|
|
1222
|
-
let stateSnapshot =
|
|
1223
|
-
const stopMain =
|
|
1253
|
+
let stateSnapshot = effects.getState(source);
|
|
1254
|
+
const stopMain = effects.effect `morph:${fn.name}`(({ ascend }) => {
|
|
1224
1255
|
track = ascend;
|
|
1225
1256
|
// Track only structural changes on source
|
|
1226
|
-
|
|
1257
|
+
effects.dependant(source, effects.keysOf);
|
|
1227
1258
|
while ('evolution' in stateSnapshot) {
|
|
1228
1259
|
const { evolution } = stateSnapshot;
|
|
1229
1260
|
stateSnapshot = stateSnapshot.next;
|
|
1230
1261
|
if (evolution.type === 'add') {
|
|
1231
|
-
|
|
1262
|
+
effects.touched1(cache, evolution, evolution.prop);
|
|
1232
1263
|
}
|
|
1233
1264
|
else if (evolution.type === 'del') {
|
|
1234
1265
|
stopItem(evolution.prop);
|
|
1235
1266
|
delete cache[evolution.prop];
|
|
1236
|
-
|
|
1267
|
+
effects.touched1(cache, evolution, evolution.prop);
|
|
1237
1268
|
}
|
|
1238
1269
|
}
|
|
1239
1270
|
});
|
|
1240
|
-
return
|
|
1271
|
+
return effects.link(proxy, (reason) => {
|
|
1241
1272
|
stopMain(reason);
|
|
1242
1273
|
for (const stop of itemEffects.values())
|
|
1243
1274
|
stop(reason);
|
|
@@ -1261,7 +1292,7 @@ function morphRecord(source, fn, options) {
|
|
|
1261
1292
|
* // Changing users[0].name only recomputes names[0]
|
|
1262
1293
|
* ```
|
|
1263
1294
|
*/
|
|
1264
|
-
const morph =
|
|
1295
|
+
const morph = effects.captioned(effects.flavored(function morph(source, fn, options) {
|
|
1265
1296
|
if (Array.isArray(source) || typeof source === 'function')
|
|
1266
1297
|
return morphArray(source, fn, options);
|
|
1267
1298
|
if (source instanceof Map)
|
|
@@ -1274,7 +1305,7 @@ const morph = proxy.captioned(proxy.flavored(function morph(source, fn, options)
|
|
|
1274
1305
|
}), {
|
|
1275
1306
|
name: 'morph',
|
|
1276
1307
|
callbackIndex: 1,
|
|
1277
|
-
warn: (message) =>
|
|
1308
|
+
warn: (message) => effects.options.warn(`[reactive] ${message}`),
|
|
1278
1309
|
});
|
|
1279
1310
|
|
|
1280
1311
|
/**
|
|
@@ -1297,17 +1328,17 @@ function deepWatch(target, callback, { immediate = false } = {}) {
|
|
|
1297
1328
|
if (typeof target !== 'object')
|
|
1298
1329
|
throw new Error('Target of deep watching must be an object');
|
|
1299
1330
|
// Create a wrapper callback that matches EffectTrigger signature
|
|
1300
|
-
const wrappedCallback =
|
|
1301
|
-
|
|
1331
|
+
const wrappedCallback = effects.markWithRoot((() => callback(target)), callback);
|
|
1332
|
+
effects.registerDeepWatcher();
|
|
1302
1333
|
// Use the existing effect system to register dependencies
|
|
1303
|
-
return
|
|
1334
|
+
return effects.effect `deepWatch`(() => {
|
|
1304
1335
|
// Mark the target object as having deep watchers
|
|
1305
|
-
|
|
1336
|
+
effects.objectsWithDeepWatchers.add(target);
|
|
1306
1337
|
// Track which objects this effect is watching for cleanup
|
|
1307
|
-
let effectObjects =
|
|
1338
|
+
let effectObjects = effects.effectToDeepWatchedObjects.get(wrappedCallback);
|
|
1308
1339
|
if (!effectObjects) {
|
|
1309
1340
|
effectObjects = new Set();
|
|
1310
|
-
|
|
1341
|
+
effects.effectToDeepWatchedObjects.set(wrappedCallback, effectObjects);
|
|
1311
1342
|
}
|
|
1312
1343
|
effectObjects.add(target);
|
|
1313
1344
|
// Traverse the object graph and register dependencies
|
|
@@ -1315,23 +1346,23 @@ function deepWatch(target, callback, { immediate = false } = {}) {
|
|
|
1315
1346
|
const visited = new WeakSet();
|
|
1316
1347
|
function traverseAndTrack(obj, depth = 0) {
|
|
1317
1348
|
// Prevent infinite recursion and excessive depth
|
|
1318
|
-
if (!obj || visited.has(obj) || typeof obj !== 'object' || depth >
|
|
1349
|
+
if (!obj || visited.has(obj) || typeof obj !== 'object' || depth > effects.options.maxDeepWatchDepth)
|
|
1319
1350
|
return;
|
|
1320
1351
|
// Do not traverse into unreactive objects
|
|
1321
|
-
if (
|
|
1352
|
+
if (effects.isNonReactive(obj))
|
|
1322
1353
|
return;
|
|
1323
1354
|
visited.add(obj);
|
|
1324
1355
|
// Mark this object as having deep watchers
|
|
1325
|
-
|
|
1356
|
+
effects.objectsWithDeepWatchers.add(obj);
|
|
1326
1357
|
effectObjects.add(obj);
|
|
1327
1358
|
// Traverse all properties to register dependencies
|
|
1328
1359
|
// unwrap to avoid kicking dependency
|
|
1329
|
-
for (const key in
|
|
1360
|
+
for (const key in effects.unwrap(obj)) {
|
|
1330
1361
|
if (Object.hasOwn(obj, key)) {
|
|
1331
1362
|
// Access the property to register dependency
|
|
1332
1363
|
const value = obj[key];
|
|
1333
1364
|
// Make the value reactive if it's an object
|
|
1334
|
-
const reactiveValue = typeof value === 'object' && value !== null ?
|
|
1365
|
+
const reactiveValue = typeof value === 'object' && value !== null ? effects.reactive(value) : value;
|
|
1335
1366
|
traverseAndTrack(reactiveValue, depth + 1);
|
|
1336
1367
|
}
|
|
1337
1368
|
}
|
|
@@ -1341,17 +1372,17 @@ function deepWatch(target, callback, { immediate = false } = {}) {
|
|
|
1341
1372
|
// Access the iterator to track additions/removals/collection changes
|
|
1342
1373
|
for (const value of obj) {
|
|
1343
1374
|
// Make the value reactive if it's an object
|
|
1344
|
-
const reactiveValue = typeof value === 'object' && value !== null ?
|
|
1375
|
+
const reactiveValue = typeof value === 'object' && value !== null ? effects.reactive(value) : value;
|
|
1345
1376
|
traverseAndTrack(reactiveValue, depth + 1);
|
|
1346
1377
|
}
|
|
1347
1378
|
// Explicitly depend on length so array mutations changing count trigger re-evaluation
|
|
1348
1379
|
if ('length' in obj) {
|
|
1349
|
-
|
|
1380
|
+
effects.dependant(obj, 'length');
|
|
1350
1381
|
}
|
|
1351
1382
|
// For Maps, also ensure we track values explicitly if the iterator yields entries
|
|
1352
1383
|
if (obj instanceof Map) {
|
|
1353
1384
|
for (const value of obj.values()) {
|
|
1354
|
-
const reactiveValue = typeof value === 'object' && value !== null ?
|
|
1385
|
+
const reactiveValue = typeof value === 'object' && value !== null ? effects.reactive(value) : value;
|
|
1355
1386
|
traverseAndTrack(reactiveValue, depth + 1);
|
|
1356
1387
|
}
|
|
1357
1388
|
}
|
|
@@ -1364,34 +1395,34 @@ function deepWatch(target, callback, { immediate = false } = {}) {
|
|
|
1364
1395
|
traverseAndTrack(target);
|
|
1365
1396
|
// Only call the callback if immediate is true or if it's not the first run
|
|
1366
1397
|
if (immediate) {
|
|
1367
|
-
|
|
1398
|
+
effects.untracked `deepWatch:callback`(() => callback(target));
|
|
1368
1399
|
}
|
|
1369
1400
|
immediate = true;
|
|
1370
1401
|
// Return a cleanup function that properly removes deep watcher tracking
|
|
1371
1402
|
return () => {
|
|
1372
1403
|
// Get the objects this effect was watching
|
|
1373
|
-
const effectObjects =
|
|
1404
|
+
const effectObjects = effects.effectToDeepWatchedObjects.get(wrappedCallback);
|
|
1374
1405
|
if (effectObjects) {
|
|
1375
1406
|
// Remove deep watcher tracking from all objects this effect was watching
|
|
1376
1407
|
for (const obj of effectObjects) {
|
|
1377
1408
|
// Check if this object still has other deep watchers
|
|
1378
|
-
const watchers =
|
|
1409
|
+
const watchers = effects.deepWatchers.get(obj);
|
|
1379
1410
|
if (watchers) {
|
|
1380
1411
|
// Remove this effect's callback from the watchers
|
|
1381
1412
|
watchers.delete(wrappedCallback);
|
|
1382
1413
|
// If no more watchers, remove the object from deep watchers tracking
|
|
1383
1414
|
if (watchers.size === 0) {
|
|
1384
|
-
|
|
1385
|
-
|
|
1415
|
+
effects.deepWatchers.delete(obj);
|
|
1416
|
+
effects.objectsWithDeepWatchers.delete(obj);
|
|
1386
1417
|
}
|
|
1387
1418
|
}
|
|
1388
1419
|
else {
|
|
1389
1420
|
// No watchers found, remove from deep watchers tracking
|
|
1390
|
-
|
|
1421
|
+
effects.objectsWithDeepWatchers.delete(obj);
|
|
1391
1422
|
}
|
|
1392
1423
|
}
|
|
1393
1424
|
// Clean up the tracking data
|
|
1394
|
-
|
|
1425
|
+
effects.effectToDeepWatchedObjects.delete(wrappedCallback);
|
|
1395
1426
|
}
|
|
1396
1427
|
};
|
|
1397
1428
|
});
|
|
@@ -1409,12 +1440,12 @@ function getBranch(tree, key) {
|
|
|
1409
1440
|
return branch;
|
|
1410
1441
|
}
|
|
1411
1442
|
function memoizeFunction(fn, opts) {
|
|
1412
|
-
const fnRoot =
|
|
1443
|
+
const fnRoot = effects.getRoot(fn);
|
|
1413
1444
|
const existing = memoizedRegistry.get(fnRoot);
|
|
1414
1445
|
if (existing)
|
|
1415
1446
|
return existing;
|
|
1416
1447
|
const cacheRoot = {};
|
|
1417
|
-
const memoized =
|
|
1448
|
+
const memoized = effects.markWithRoot(function memoized(...args) {
|
|
1418
1449
|
if (args.some((arg) => !(arg && ['object', 'symbol', 'function'].includes(typeof arg)))) {
|
|
1419
1450
|
if (opts?.lenient)
|
|
1420
1451
|
return fn.apply(this, args);
|
|
@@ -1425,62 +1456,65 @@ function memoizeFunction(fn, opts) {
|
|
|
1425
1456
|
for (const arg of args) {
|
|
1426
1457
|
node = getBranch(node, arg);
|
|
1427
1458
|
}
|
|
1428
|
-
|
|
1459
|
+
if (effects.inertDepth > 0) {
|
|
1460
|
+
return fn.apply(this, args);
|
|
1461
|
+
}
|
|
1462
|
+
effects.dependant(node, 'memoize');
|
|
1429
1463
|
if ('result' in node) {
|
|
1430
|
-
if (
|
|
1431
|
-
const wasVerification =
|
|
1432
|
-
|
|
1464
|
+
if (effects.options.onMemoizationDiscrepancy) {
|
|
1465
|
+
const wasVerification = effects.options.isVerificationRun;
|
|
1466
|
+
effects.options.isVerificationRun = true;
|
|
1433
1467
|
try {
|
|
1434
|
-
const fresh =
|
|
1435
|
-
if (!
|
|
1436
|
-
|
|
1468
|
+
const fresh = effects.untracked `memoize:verify-calculation`(() => fn.apply(this, args));
|
|
1469
|
+
if (!effects.deepCompare(node.result, fresh)) {
|
|
1470
|
+
effects.optionCall('onMemoizationDiscrepancy', node.result, fresh, fn, args, 'calculation');
|
|
1437
1471
|
}
|
|
1438
1472
|
}
|
|
1439
1473
|
finally {
|
|
1440
|
-
|
|
1474
|
+
effects.options.isVerificationRun = wasVerification;
|
|
1441
1475
|
}
|
|
1442
1476
|
}
|
|
1443
1477
|
return node.result;
|
|
1444
1478
|
}
|
|
1445
1479
|
// Create memoize internal effect to track dependencies and invalidate cache
|
|
1446
1480
|
// Use untracked to prevent the effect creation from being affected by parent effects
|
|
1447
|
-
node.cleanup =
|
|
1481
|
+
node.cleanup = effects.root `memoize:root`(() => effects.effect `memoize`(() => {
|
|
1448
1482
|
// Execute the function and track its dependencies
|
|
1449
1483
|
// The function execution will automatically track dependencies on reactive objects
|
|
1450
1484
|
node.result = fn.apply(this, args);
|
|
1451
1485
|
return (reason) => {
|
|
1452
1486
|
// When dependencies change, clear the cache and notify consumers
|
|
1453
1487
|
delete node.result;
|
|
1454
|
-
|
|
1488
|
+
effects.touched1(node, { type: 'invalidate', prop: args }, 'memoize');
|
|
1455
1489
|
// Lazy memoization: stop the effect so it doesn't re-run immediately.
|
|
1456
1490
|
// It will be re-created on next access.
|
|
1457
1491
|
if (node.cleanup) {
|
|
1458
|
-
const activeEffect =
|
|
1492
|
+
const activeEffect = effects.getActiveEffect();
|
|
1459
1493
|
let chain;
|
|
1460
1494
|
if (activeEffect) {
|
|
1461
|
-
const effectNode =
|
|
1495
|
+
const effectNode = effects.getEffectNode(activeEffect);
|
|
1462
1496
|
chain = effectNode.currentReason;
|
|
1463
1497
|
}
|
|
1464
1498
|
node.cleanup({
|
|
1465
1499
|
type: 'invalidate',
|
|
1466
|
-
cause:
|
|
1467
|
-
chain:
|
|
1500
|
+
cause: effects.chainExternalReason(reason ?? { type: 'stopped', chain }),
|
|
1501
|
+
chain: effects.chainExternalReason(chain),
|
|
1468
1502
|
});
|
|
1469
1503
|
node.cleanup = undefined;
|
|
1470
1504
|
}
|
|
1471
1505
|
};
|
|
1472
1506
|
}, { opaque: true }));
|
|
1473
|
-
if (
|
|
1474
|
-
const wasVerification =
|
|
1475
|
-
|
|
1507
|
+
if (effects.options.onMemoizationDiscrepancy) {
|
|
1508
|
+
const wasVerification = effects.options.isVerificationRun;
|
|
1509
|
+
effects.options.isVerificationRun = true;
|
|
1476
1510
|
try {
|
|
1477
|
-
const fresh =
|
|
1478
|
-
if (!
|
|
1479
|
-
|
|
1511
|
+
const fresh = effects.untracked `memoize:verify-comparison`(() => fn.apply(this, args));
|
|
1512
|
+
if (!effects.deepCompare(node.result, fresh)) {
|
|
1513
|
+
effects.optionCall('onMemoizationDiscrepancy', node.result, fresh, fn, args, 'comparison');
|
|
1480
1514
|
}
|
|
1481
1515
|
}
|
|
1482
1516
|
finally {
|
|
1483
|
-
|
|
1517
|
+
effects.options.isVerificationRun = wasVerification;
|
|
1484
1518
|
}
|
|
1485
1519
|
}
|
|
1486
1520
|
return node.result;
|
|
@@ -1493,7 +1527,7 @@ function memoizeObject(target, opts) {
|
|
|
1493
1527
|
const existing = memoizedRegistry.get(target);
|
|
1494
1528
|
if (existing)
|
|
1495
1529
|
return existing;
|
|
1496
|
-
const proxy
|
|
1530
|
+
const proxy = new Proxy(target, {
|
|
1497
1531
|
get(source, prop, receiver) {
|
|
1498
1532
|
// 1. Walk prototype chain to find descriptor
|
|
1499
1533
|
let current = source;
|
|
@@ -1511,14 +1545,14 @@ function memoizeObject(target, opts) {
|
|
|
1511
1545
|
const originalGetter = desc.get;
|
|
1512
1546
|
let wrapper = wrapperRegistry.get(originalGetter);
|
|
1513
1547
|
if (!wrapper) {
|
|
1514
|
-
wrapper =
|
|
1548
|
+
wrapper = effects.markWithRoot(effects.named(`${String(source?.constructor?.name ?? 'Object')}.${String(prop)}`, (that) => {
|
|
1515
1549
|
return originalGetter.call(that);
|
|
1516
1550
|
}), {
|
|
1517
1551
|
propertyKey: prop,
|
|
1518
1552
|
});
|
|
1519
|
-
const origRoot = originalGetter[
|
|
1553
|
+
const origRoot = originalGetter[effects.rootFunctionSymbol];
|
|
1520
1554
|
if (origRoot)
|
|
1521
|
-
wrapper[
|
|
1555
|
+
wrapper[effects.rootFunctionSymbol] = origRoot;
|
|
1522
1556
|
wrapperRegistry.set(originalGetter, wrapper);
|
|
1523
1557
|
}
|
|
1524
1558
|
const memoized = memoizeFunction(wrapper, opts);
|
|
@@ -1534,9 +1568,9 @@ function memoizeObject(target, opts) {
|
|
|
1534
1568
|
return Reflect.set(source, prop, value, source);
|
|
1535
1569
|
},
|
|
1536
1570
|
});
|
|
1537
|
-
|
|
1538
|
-
memoizedRegistry.set(target, proxy
|
|
1539
|
-
return proxy
|
|
1571
|
+
effects.proxyToObject.set(proxy, target);
|
|
1572
|
+
memoizedRegistry.set(target, proxy);
|
|
1573
|
+
return proxy;
|
|
1540
1574
|
}
|
|
1541
1575
|
/**
|
|
1542
1576
|
* Decorator and function wrapper for memoizing computed values based on reactive dependencies.
|
|
@@ -1562,20 +1596,20 @@ function memoizeObject(target, opts) {
|
|
|
1562
1596
|
* ```
|
|
1563
1597
|
*/
|
|
1564
1598
|
function makeMemoizeDecorator(memoizeOpts) {
|
|
1565
|
-
return
|
|
1599
|
+
return effects.decorator({
|
|
1566
1600
|
getter(original, target, propertyKey) {
|
|
1567
1601
|
return function () {
|
|
1568
1602
|
let wrapper = wrapperRegistry.get(original);
|
|
1569
1603
|
if (!wrapper) {
|
|
1570
|
-
wrapper =
|
|
1604
|
+
wrapper = effects.markWithRoot(effects.named(`${String(target?.constructor?.name ?? target?.name ?? 'Object')}.${String(propertyKey)}`, (that) => {
|
|
1571
1605
|
return original.call(that);
|
|
1572
1606
|
}), {
|
|
1573
1607
|
method: original,
|
|
1574
1608
|
propertyKey,
|
|
1575
1609
|
});
|
|
1576
|
-
const origRoot = original[
|
|
1610
|
+
const origRoot = original[effects.rootFunctionSymbol];
|
|
1577
1611
|
if (origRoot)
|
|
1578
|
-
wrapper[
|
|
1612
|
+
wrapper[effects.rootFunctionSymbol] = origRoot;
|
|
1579
1613
|
wrapperRegistry.set(original, wrapper);
|
|
1580
1614
|
}
|
|
1581
1615
|
const memoized = memoizeFunction(wrapper, memoizeOpts);
|
|
@@ -1586,15 +1620,15 @@ function makeMemoizeDecorator(memoizeOpts) {
|
|
|
1586
1620
|
return function (...args) {
|
|
1587
1621
|
let wrapper = wrapperRegistry.get(original);
|
|
1588
1622
|
if (!wrapper) {
|
|
1589
|
-
wrapper =
|
|
1623
|
+
wrapper = effects.markWithRoot(effects.named(`${String(target?.constructor?.name ?? target?.name ?? 'Object')}.${String(name)}`, (that, ...args) => {
|
|
1590
1624
|
return original.call(that, ...args);
|
|
1591
1625
|
}), {
|
|
1592
1626
|
method: original,
|
|
1593
1627
|
propertyKey: name,
|
|
1594
1628
|
});
|
|
1595
|
-
const origRoot = original[
|
|
1629
|
+
const origRoot = original[effects.rootFunctionSymbol];
|
|
1596
1630
|
if (origRoot)
|
|
1597
|
-
wrapper[
|
|
1631
|
+
wrapper[effects.rootFunctionSymbol] = origRoot;
|
|
1598
1632
|
wrapperRegistry.set(original, wrapper);
|
|
1599
1633
|
}
|
|
1600
1634
|
const memoized = memoizeFunction(wrapper, memoizeOpts);
|
|
@@ -1606,7 +1640,7 @@ function makeMemoizeDecorator(memoizeOpts) {
|
|
|
1606
1640
|
: memoizeFunction(target, memoizeOpts),
|
|
1607
1641
|
});
|
|
1608
1642
|
}
|
|
1609
|
-
const memoize =
|
|
1643
|
+
const memoize = effects.flavored(makeMemoizeDecorator(), {
|
|
1610
1644
|
get lenient() {
|
|
1611
1645
|
return makeMemoizeDecorator({ lenient: true });
|
|
1612
1646
|
},
|
|
@@ -1664,8 +1698,8 @@ const memoize = proxy.flavored(makeMemoizeDecorator(), {
|
|
|
1664
1698
|
* });
|
|
1665
1699
|
*/
|
|
1666
1700
|
function organized(source, apply, baseTarget = {}) {
|
|
1667
|
-
const observedSource =
|
|
1668
|
-
const target =
|
|
1701
|
+
const observedSource = effects.reactive(source);
|
|
1702
|
+
const target = effects.reactive(baseTarget);
|
|
1669
1703
|
const stop = attend `organized:entries`(function enumerateObservedSourceKeys() {
|
|
1670
1704
|
const keys = [];
|
|
1671
1705
|
for (const key in observedSource)
|
|
@@ -1675,8 +1709,8 @@ function organized(source, apply, baseTarget = {}) {
|
|
|
1675
1709
|
const sourceKey = key;
|
|
1676
1710
|
const accessBase = {
|
|
1677
1711
|
key: sourceKey,
|
|
1678
|
-
get: () =>
|
|
1679
|
-
set: (value) =>
|
|
1712
|
+
get: () => effects.FoolProof.get(observedSource, sourceKey, observedSource),
|
|
1713
|
+
set: (value) => effects.FoolProof.set(observedSource, sourceKey, value, observedSource),
|
|
1680
1714
|
};
|
|
1681
1715
|
Object.defineProperty(accessBase, 'value', {
|
|
1682
1716
|
get: accessBase.get,
|
|
@@ -1686,7 +1720,7 @@ function organized(source, apply, baseTarget = {}) {
|
|
|
1686
1720
|
});
|
|
1687
1721
|
return apply(accessBase, target);
|
|
1688
1722
|
});
|
|
1689
|
-
return
|
|
1723
|
+
return effects.link(target, (reason) => stop(reason));
|
|
1690
1724
|
}
|
|
1691
1725
|
/**
|
|
1692
1726
|
* Organizes a property on a target object
|
|
@@ -1703,13 +1737,13 @@ function organize(target, property, access) {
|
|
|
1703
1737
|
configurable: true,
|
|
1704
1738
|
enumerable: true,
|
|
1705
1739
|
});
|
|
1706
|
-
|
|
1740
|
+
effects.touched1(target, { type: 'set', prop: property }, property);
|
|
1707
1741
|
return () => delete target[property];
|
|
1708
1742
|
}
|
|
1709
1743
|
|
|
1710
1744
|
//#region watch
|
|
1711
1745
|
const unsetYet = Symbol('unset-yet');
|
|
1712
|
-
const watch =
|
|
1746
|
+
const watch = effects.captioned(effects.flavored(function watch(value, //object | ((dep: DependencyAccess) => object),
|
|
1713
1747
|
changed, options = {}) {
|
|
1714
1748
|
return typeof value === 'function'
|
|
1715
1749
|
? watchCallBack(value, changed, options)
|
|
@@ -1720,20 +1754,20 @@ changed, options = {}) {
|
|
|
1720
1754
|
})();
|
|
1721
1755
|
}, {
|
|
1722
1756
|
get deep() {
|
|
1723
|
-
return
|
|
1757
|
+
return effects.flavorOptions(this, { deep: true });
|
|
1724
1758
|
},
|
|
1725
1759
|
get immediate() {
|
|
1726
|
-
return
|
|
1760
|
+
return effects.flavorOptions(this, { immediate: true });
|
|
1727
1761
|
},
|
|
1728
1762
|
}), {
|
|
1729
1763
|
name: 'watch',
|
|
1730
|
-
warn: (message) =>
|
|
1764
|
+
warn: (message) => effects.options.warn(`[reactive] ${message}`),
|
|
1731
1765
|
});
|
|
1732
1766
|
function watchObject(value, changed, { immediate = false, deep = false } = {}) {
|
|
1733
1767
|
if (deep)
|
|
1734
1768
|
return deepWatch(value, changed, { immediate });
|
|
1735
|
-
return
|
|
1736
|
-
|
|
1769
|
+
return effects.effect `watch:object`(() => {
|
|
1770
|
+
effects.dependant(value);
|
|
1737
1771
|
if (immediate)
|
|
1738
1772
|
changed(value);
|
|
1739
1773
|
immediate = true;
|
|
@@ -1742,16 +1776,16 @@ function watchObject(value, changed, { immediate = false, deep = false } = {}) {
|
|
|
1742
1776
|
function watchCallBack(value, changed, { immediate = false, deep = false } = {}) {
|
|
1743
1777
|
let oldValue = unsetYet;
|
|
1744
1778
|
let deepCleanup;
|
|
1745
|
-
const cbCleanup =
|
|
1779
|
+
const cbCleanup = effects.effect `watch:callback`(effects.markWithRoot((access) => {
|
|
1746
1780
|
const newValue = value(access);
|
|
1747
1781
|
if (oldValue !== newValue) {
|
|
1748
1782
|
const old = oldValue;
|
|
1749
1783
|
if (old === unsetYet) {
|
|
1750
1784
|
if (immediate)
|
|
1751
|
-
|
|
1785
|
+
effects.untracked `watch:changed`(() => changed(newValue));
|
|
1752
1786
|
}
|
|
1753
1787
|
else
|
|
1754
|
-
|
|
1788
|
+
effects.untracked `watch:changed`(() => changed(newValue, old));
|
|
1755
1789
|
}
|
|
1756
1790
|
oldValue = newValue;
|
|
1757
1791
|
if (deep) {
|
|
@@ -1778,7 +1812,7 @@ function watchCallBack(value, changed, { immediate = false, deep = false } = {})
|
|
|
1778
1812
|
function when(predicate, timeout) {
|
|
1779
1813
|
return new Promise((resolve, reject) => {
|
|
1780
1814
|
let timer;
|
|
1781
|
-
const stop =
|
|
1815
|
+
const stop = effects.effect `watch:when`((access) => {
|
|
1782
1816
|
try {
|
|
1783
1817
|
const value = predicate(access);
|
|
1784
1818
|
if (value) {
|
|
@@ -1812,10 +1846,10 @@ function when(predicate, timeout) {
|
|
|
1812
1846
|
* @param obj - The object to mark as non-reactive
|
|
1813
1847
|
*/
|
|
1814
1848
|
function shallowNonReactive(obj) {
|
|
1815
|
-
obj =
|
|
1816
|
-
if (
|
|
1849
|
+
obj = effects.unwrap(obj);
|
|
1850
|
+
if (effects.isNonReactive(obj))
|
|
1817
1851
|
return obj;
|
|
1818
|
-
obj[
|
|
1852
|
+
obj[effects.unreactiveProperties] = true;
|
|
1819
1853
|
return obj;
|
|
1820
1854
|
}
|
|
1821
1855
|
function unreactiveApplication(arg1, ...args) {
|
|
@@ -1823,10 +1857,10 @@ function unreactiveApplication(arg1, ...args) {
|
|
|
1823
1857
|
? shallowNonReactive(arg1)
|
|
1824
1858
|
: ((original) => {
|
|
1825
1859
|
// Copy the parent's unreactive properties if they exist
|
|
1826
|
-
const parentMarker = original.prototype[
|
|
1860
|
+
const parentMarker = original.prototype[effects.unreactiveProperties];
|
|
1827
1861
|
// If parent is fully unreactive, child is too
|
|
1828
1862
|
if (parentMarker === true) {
|
|
1829
|
-
original.prototype[
|
|
1863
|
+
original.prototype[effects.unreactiveProperties] = true;
|
|
1830
1864
|
}
|
|
1831
1865
|
else {
|
|
1832
1866
|
const set = new Set(parentMarker || []);
|
|
@@ -1834,7 +1868,7 @@ function unreactiveApplication(arg1, ...args) {
|
|
|
1834
1868
|
set.add(arg1);
|
|
1835
1869
|
for (const arg of args)
|
|
1836
1870
|
set.add(arg);
|
|
1837
|
-
|
|
1871
|
+
effects.addUnreactiveProps(original.prototype, set);
|
|
1838
1872
|
}
|
|
1839
1873
|
return original; // Return the class
|
|
1840
1874
|
});
|
|
@@ -1843,22 +1877,22 @@ function unreactiveApplication(arg1, ...args) {
|
|
|
1843
1877
|
* Decorator that marks classes or properties as non-reactive
|
|
1844
1878
|
* Prevents objects from being made reactive
|
|
1845
1879
|
*/
|
|
1846
|
-
const unreactive =
|
|
1880
|
+
const unreactive = effects.decorator({
|
|
1847
1881
|
class(original) {
|
|
1848
|
-
original.prototype[
|
|
1882
|
+
original.prototype[effects.unreactiveProperties] = true;
|
|
1849
1883
|
},
|
|
1850
1884
|
default: unreactiveApplication,
|
|
1851
1885
|
});
|
|
1852
1886
|
//#endregion
|
|
1853
1887
|
//#region resource
|
|
1854
1888
|
function lazyInit(resource, load) {
|
|
1855
|
-
const creation =
|
|
1889
|
+
const creation = effects.effectHistory.active;
|
|
1856
1890
|
let fresh = true;
|
|
1857
1891
|
return new Proxy(resource, {
|
|
1858
1892
|
[Symbol.toStringTag]: 'LazyInit',
|
|
1859
1893
|
get(target, prop) {
|
|
1860
1894
|
if (fresh) {
|
|
1861
|
-
|
|
1895
|
+
effects.captured(creation, load)();
|
|
1862
1896
|
fresh = false;
|
|
1863
1897
|
}
|
|
1864
1898
|
return target[prop];
|
|
@@ -1872,7 +1906,7 @@ function lazyInit(resource, load) {
|
|
|
1872
1906
|
* @returns Reactive Resource object with value, loading, error, latest properties
|
|
1873
1907
|
*/
|
|
1874
1908
|
function resource(fetcher, options = {}) {
|
|
1875
|
-
const resource =
|
|
1909
|
+
const resource = effects.reactive({
|
|
1876
1910
|
value: options.initialValue,
|
|
1877
1911
|
loading: true,
|
|
1878
1912
|
error: undefined,
|
|
@@ -1881,11 +1915,11 @@ function resource(fetcher, options = {}) {
|
|
|
1881
1915
|
reloadSignal.value++;
|
|
1882
1916
|
},
|
|
1883
1917
|
});
|
|
1884
|
-
const reloadSignal =
|
|
1918
|
+
const reloadSignal = effects.reactive({ value: 0 });
|
|
1885
1919
|
// Solve race conditions: make sure a new fast request is not overloaded by a slow old one
|
|
1886
1920
|
let counter = 0;
|
|
1887
1921
|
return lazyInit(resource, () => {
|
|
1888
|
-
|
|
1922
|
+
effects.link(resource, effects.effect `watch:resource`((access) => {
|
|
1889
1923
|
// Track reload signal to enable manual reloading
|
|
1890
1924
|
void reloadSignal.value;
|
|
1891
1925
|
const id = ++counter;
|
|
@@ -1932,7 +1966,7 @@ function resource(fetcher, options = {}) {
|
|
|
1932
1966
|
function* makeReactiveIterator(iterator) {
|
|
1933
1967
|
let result = iterator.next();
|
|
1934
1968
|
while (!result.done) {
|
|
1935
|
-
yield
|
|
1969
|
+
yield effects.reactive(result.value);
|
|
1936
1970
|
result = iterator.next();
|
|
1937
1971
|
}
|
|
1938
1972
|
}
|
|
@@ -1943,7 +1977,7 @@ function* makeReactiveEntriesIterator(iterator) {
|
|
|
1943
1977
|
let result = iterator.next();
|
|
1944
1978
|
while (!result.done) {
|
|
1945
1979
|
const [key, value] = result.value;
|
|
1946
|
-
yield [
|
|
1980
|
+
yield [effects.reactive(key), effects.reactive(value)];
|
|
1947
1981
|
result = iterator.next();
|
|
1948
1982
|
}
|
|
1949
1983
|
}
|
|
@@ -1955,18 +1989,18 @@ function* index(i, { length = true } = {}) {
|
|
|
1955
1989
|
}
|
|
1956
1990
|
class Indexer extends Array {
|
|
1957
1991
|
get(i) {
|
|
1958
|
-
|
|
1959
|
-
return
|
|
1992
|
+
effects.dependant(this, i);
|
|
1993
|
+
return effects.reactive(this[i]);
|
|
1960
1994
|
}
|
|
1961
1995
|
// Returns undefined intentionally: signals the proxy handler that notifications
|
|
1962
1996
|
// were already dispatched via touched(), preventing double notification
|
|
1963
1997
|
set(i, value) {
|
|
1964
1998
|
const added = i >= this.length;
|
|
1965
1999
|
this[i] = value;
|
|
1966
|
-
|
|
2000
|
+
effects.touched(this, { type: 'set', prop: i }, index(i, { length: added }));
|
|
1967
2001
|
}
|
|
1968
2002
|
}
|
|
1969
|
-
const indexLess = { get:
|
|
2003
|
+
const indexLess = { get: effects.FoolProof.get, set: effects.FoolProof.set };
|
|
1970
2004
|
// Fast numeric-string check: first char is a digit (0-9)
|
|
1971
2005
|
function asIndex(prop) {
|
|
1972
2006
|
const c = prop.charCodeAt(0);
|
|
@@ -1975,7 +2009,7 @@ function asIndex(prop) {
|
|
|
1975
2009
|
const n = +prop; // coerce — faster than parseInt, handles "0", "12", etc.
|
|
1976
2010
|
return n === (n | 0) && n >= 0 ? n : -1;
|
|
1977
2011
|
}
|
|
1978
|
-
Object.assign(
|
|
2012
|
+
Object.assign(effects.FoolProof, {
|
|
1979
2013
|
get(obj, prop, receiver) {
|
|
1980
2014
|
if (Array.isArray(obj) && typeof prop === 'string') {
|
|
1981
2015
|
const i = asIndex(prop);
|
|
@@ -2017,172 +2051,212 @@ let ReactiveArrayWrapper = (() => {
|
|
|
2017
2051
|
let _unshift_decorators;
|
|
2018
2052
|
return _a = class ReactiveArrayWrapper extends _classSuper {
|
|
2019
2053
|
at(index) {
|
|
2020
|
-
return
|
|
2054
|
+
return effects.reactive(super.at(index));
|
|
2021
2055
|
}
|
|
2022
2056
|
concat(...items) {
|
|
2023
|
-
return
|
|
2057
|
+
return effects.reactive(super.concat(...items.map(effects.unwrap)));
|
|
2024
2058
|
}
|
|
2025
2059
|
entries() {
|
|
2026
|
-
|
|
2060
|
+
effects.dependant(this, effects.keysOf);
|
|
2027
2061
|
return makeReactiveEntriesIterator(super.entries());
|
|
2028
2062
|
}
|
|
2029
2063
|
every(predicate, thisArg) {
|
|
2030
|
-
return super.every((v, i, a) => predicate.call(thisArg,
|
|
2064
|
+
return super.every((v, i, a) => predicate.call(thisArg, effects.reactive(v), i, a), thisArg);
|
|
2031
2065
|
}
|
|
2032
2066
|
fill(value, start, end) {
|
|
2033
|
-
return super.fill(
|
|
2067
|
+
return super.fill(effects.unwrap(value), start, end);
|
|
2034
2068
|
}
|
|
2035
2069
|
copyWithin(target, start, end) {
|
|
2036
2070
|
return super.copyWithin(target, start, end);
|
|
2037
2071
|
}
|
|
2038
2072
|
filter(predicate, thisArg) {
|
|
2039
|
-
return
|
|
2073
|
+
return effects.reactive(super.filter((v, i, a) => predicate.call(thisArg, effects.reactive(v), i, a), thisArg));
|
|
2040
2074
|
}
|
|
2041
2075
|
find(predicate, thisArg) {
|
|
2042
|
-
return
|
|
2076
|
+
return effects.reactive(super.find((v, i, a) => predicate.call(thisArg, effects.reactive(v), i, a), thisArg));
|
|
2043
2077
|
}
|
|
2044
2078
|
findIndex(predicate, thisArg) {
|
|
2045
|
-
return super.findIndex((v, i, a) => predicate.call(thisArg,
|
|
2079
|
+
return super.findIndex((v, i, a) => predicate.call(thisArg, effects.reactive(v), i, a), thisArg);
|
|
2046
2080
|
}
|
|
2047
2081
|
findLast(predicate, thisArg) {
|
|
2048
|
-
return
|
|
2082
|
+
return effects.reactive(super.findLast((v, i, a) => predicate.call(thisArg, effects.reactive(v), i, a), thisArg));
|
|
2049
2083
|
}
|
|
2050
2084
|
findLastIndex(predicate, thisArg) {
|
|
2051
|
-
return super.findLastIndex((v, i, a) => predicate.call(thisArg,
|
|
2085
|
+
return super.findLastIndex((v, i, a) => predicate.call(thisArg, effects.reactive(v), i, a), thisArg);
|
|
2052
2086
|
}
|
|
2053
2087
|
flat(depth) {
|
|
2054
|
-
|
|
2055
|
-
return
|
|
2088
|
+
effects.dependant(this, effects.keysOf);
|
|
2089
|
+
return effects.reactive(super.flat(depth));
|
|
2056
2090
|
}
|
|
2057
2091
|
flatMap(callbackfn, thisArg) {
|
|
2058
|
-
return
|
|
2092
|
+
return effects.reactive(super.flatMap((v, i, a) => effects.unwrap(callbackfn.call(thisArg, effects.reactive(v), i, a)), thisArg));
|
|
2059
2093
|
}
|
|
2060
2094
|
forEach(callbackfn, thisArg) {
|
|
2061
2095
|
super.forEach((v, i, a) => {
|
|
2062
|
-
callbackfn.call(thisArg,
|
|
2096
|
+
callbackfn.call(thisArg, effects.reactive(v), i, a);
|
|
2063
2097
|
}, thisArg);
|
|
2064
2098
|
}
|
|
2065
2099
|
includes(searchElement, fromIndex) {
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2100
|
+
const target = effects.unwrap(searchElement);
|
|
2101
|
+
const length = this.length;
|
|
2102
|
+
let start = fromIndex ?? 0;
|
|
2103
|
+
if (start < 0)
|
|
2104
|
+
start = Math.max(length + start, 0);
|
|
2105
|
+
for (let i = start; i < length; i++) {
|
|
2106
|
+
const value = effects.unwrap(this[i]);
|
|
2107
|
+
if (value === target)
|
|
2108
|
+
return true;
|
|
2109
|
+
}
|
|
2110
|
+
return false;
|
|
2069
2111
|
}
|
|
2070
2112
|
indexOf(searchElement, fromIndex) {
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2113
|
+
const target = effects.unwrap(searchElement);
|
|
2114
|
+
const length = this.length;
|
|
2115
|
+
let start = fromIndex ?? 0;
|
|
2116
|
+
if (start < 0)
|
|
2117
|
+
start = Math.max(length + start, 0);
|
|
2118
|
+
for (let i = start; i < length; i++)
|
|
2119
|
+
if (effects.unwrap(this[i]) === target)
|
|
2120
|
+
return i;
|
|
2121
|
+
return -1;
|
|
2074
2122
|
}
|
|
2075
2123
|
join(separator) {
|
|
2076
2124
|
return super.join(separator);
|
|
2077
2125
|
}
|
|
2078
2126
|
keys() {
|
|
2079
|
-
|
|
2127
|
+
effects.dependant(this, 'length');
|
|
2080
2128
|
return super.keys();
|
|
2081
2129
|
}
|
|
2082
2130
|
lastIndexOf(searchElement, fromIndex) {
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2131
|
+
const target = effects.unwrap(searchElement);
|
|
2132
|
+
const length = this.length;
|
|
2133
|
+
let start = fromIndex ?? length - 1;
|
|
2134
|
+
if (start < 0)
|
|
2135
|
+
start = length + start;
|
|
2136
|
+
if (start >= length)
|
|
2137
|
+
start = length - 1;
|
|
2138
|
+
for (let i = start; i >= 0; i--)
|
|
2139
|
+
if (effects.unwrap(this[i]) === target)
|
|
2140
|
+
return i;
|
|
2141
|
+
return -1;
|
|
2086
2142
|
}
|
|
2087
2143
|
map(callbackfn, thisArg) {
|
|
2088
|
-
return
|
|
2144
|
+
return effects.reactive(super.map((v, i, a) => effects.unwrap(callbackfn.call(thisArg, effects.reactive(v), i, a)), thisArg));
|
|
2089
2145
|
}
|
|
2090
2146
|
pop() {
|
|
2091
|
-
return
|
|
2147
|
+
return effects.reactive(super.pop());
|
|
2092
2148
|
}
|
|
2093
2149
|
push(...items) {
|
|
2094
|
-
return super.push(...items.map(
|
|
2150
|
+
return super.push(...items.map(effects.unwrap));
|
|
2095
2151
|
}
|
|
2096
2152
|
reduce(callbackfn, initialValue) {
|
|
2097
|
-
return
|
|
2098
|
-
? super.reduce((acc, v, i, a) =>
|
|
2099
|
-
: super.reduce((acc, v, i, a) =>
|
|
2153
|
+
return effects.reactive(arguments.length > 1
|
|
2154
|
+
? super.reduce((acc, v, i, a) => effects.unwrap(callbackfn(acc, effects.reactive(v), i, a)), initialValue)
|
|
2155
|
+
: super.reduce((acc, v, i, a) => effects.unwrap(callbackfn(acc, effects.reactive(v), i, a))));
|
|
2100
2156
|
}
|
|
2101
2157
|
reduceRight(callbackfn, initialValue) {
|
|
2102
|
-
return
|
|
2103
|
-
? super.reduceRight((acc, v, i, a) =>
|
|
2104
|
-
: super.reduceRight((acc, v, i, a) =>
|
|
2158
|
+
return effects.reactive(arguments.length > 1
|
|
2159
|
+
? super.reduceRight((acc, v, i, a) => effects.unwrap(callbackfn(acc, effects.reactive(v), i, a)), initialValue)
|
|
2160
|
+
: super.reduceRight((acc, v, i, a) => effects.unwrap(callbackfn(acc, effects.reactive(v), i, a))));
|
|
2105
2161
|
}
|
|
2106
2162
|
reverse() {
|
|
2107
|
-
return
|
|
2163
|
+
return effects.reactive(super.reverse());
|
|
2108
2164
|
}
|
|
2109
2165
|
shift() {
|
|
2110
|
-
return
|
|
2166
|
+
return effects.reactive(super.shift());
|
|
2111
2167
|
}
|
|
2112
2168
|
slice(start, end) {
|
|
2113
|
-
return
|
|
2169
|
+
return effects.reactive(super.slice(start, end));
|
|
2114
2170
|
}
|
|
2115
2171
|
some(predicate, thisArg) {
|
|
2116
|
-
return super.some((v, i, a) => predicate.call(thisArg,
|
|
2172
|
+
return super.some((v, i, a) => predicate.call(thisArg, effects.reactive(v), i, a), thisArg);
|
|
2117
2173
|
}
|
|
2118
2174
|
sort(compareFn) {
|
|
2119
2175
|
const wrappedCompare = compareFn
|
|
2120
|
-
? (a, b) => compareFn(
|
|
2176
|
+
? (a, b) => compareFn(effects.reactive(a), effects.reactive(b))
|
|
2121
2177
|
: undefined;
|
|
2122
2178
|
return super.sort(wrappedCompare);
|
|
2123
2179
|
}
|
|
2124
2180
|
splice(start, deleteCount, ...items) {
|
|
2181
|
+
const length = this.length;
|
|
2182
|
+
const normalizedStart = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
|
|
2183
|
+
const actualDeleteCount = arguments.length === 1
|
|
2184
|
+
? length - normalizedStart
|
|
2185
|
+
: Math.min(Math.max(deleteCount, 0), length - normalizedStart);
|
|
2186
|
+
const structural = actualDeleteCount > 0 || items.length > 0;
|
|
2187
|
+
let result;
|
|
2125
2188
|
if (arguments.length > 2)
|
|
2126
|
-
|
|
2127
|
-
if (arguments.length === 2)
|
|
2128
|
-
|
|
2129
|
-
if (arguments.length === 1)
|
|
2130
|
-
|
|
2131
|
-
|
|
2189
|
+
result = super.splice(start, deleteCount, ...items.map(effects.unwrap));
|
|
2190
|
+
else if (arguments.length === 2)
|
|
2191
|
+
result = super.splice(start, deleteCount);
|
|
2192
|
+
else if (arguments.length === 1)
|
|
2193
|
+
result = super.splice(start);
|
|
2194
|
+
else
|
|
2195
|
+
result = [];
|
|
2196
|
+
if (structural && this.length === length) {
|
|
2197
|
+
effects.touched(this, { type: 'set', prop: 'length' }, ['length']);
|
|
2198
|
+
}
|
|
2199
|
+
return effects.reactive(result);
|
|
2132
2200
|
}
|
|
2133
2201
|
unshift(...items) {
|
|
2134
|
-
return super.unshift(...items.map(
|
|
2202
|
+
return super.unshift(...items.map(effects.unwrap));
|
|
2135
2203
|
}
|
|
2136
2204
|
values() {
|
|
2137
|
-
|
|
2205
|
+
effects.dependant(this, effects.keysOf);
|
|
2138
2206
|
return makeReactiveIterator(super.values());
|
|
2139
2207
|
}
|
|
2140
|
-
[(_fill_decorators = [
|
|
2141
|
-
|
|
2208
|
+
[(_fill_decorators = [effects.atomic], _copyWithin_decorators = [effects.atomic], _pop_decorators = [effects.atomic], _push_decorators = [effects.atomic], _reverse_decorators = [effects.atomic], _shift_decorators = [effects.atomic], _sort_decorators = [effects.atomic], _splice_decorators = [effects.atomic], _unshift_decorators = [effects.atomic], Symbol.iterator)]() {
|
|
2209
|
+
effects.dependant(this, effects.keysOf);
|
|
2142
2210
|
return makeReactiveIterator(super[Symbol.iterator]());
|
|
2143
2211
|
}
|
|
2144
2212
|
toReversed() {
|
|
2145
|
-
return
|
|
2213
|
+
return effects.reactive(super.toReversed());
|
|
2146
2214
|
}
|
|
2147
2215
|
toSorted(compareFn) {
|
|
2148
2216
|
const wrappedCompare = compareFn
|
|
2149
|
-
? (a, b) => compareFn(
|
|
2217
|
+
? (a, b) => compareFn(effects.reactive(a), effects.reactive(b))
|
|
2150
2218
|
: undefined;
|
|
2151
|
-
return
|
|
2219
|
+
return effects.reactive(super.toSorted(wrappedCompare));
|
|
2152
2220
|
}
|
|
2153
2221
|
toSpliced(start, deleteCount, ...items) {
|
|
2154
2222
|
if (arguments.length > 2)
|
|
2155
|
-
return
|
|
2223
|
+
return effects.reactive(super.toSpliced(start, deleteCount, ...items.map(effects.unwrap)));
|
|
2156
2224
|
if (arguments.length === 2)
|
|
2157
|
-
return
|
|
2225
|
+
return effects.reactive(super.toSpliced(start, deleteCount));
|
|
2158
2226
|
if (arguments.length === 1)
|
|
2159
|
-
return
|
|
2160
|
-
return
|
|
2227
|
+
return effects.reactive(super.toSpliced(start));
|
|
2228
|
+
return effects.reactive([...this]);
|
|
2161
2229
|
}
|
|
2162
2230
|
with(index, value) {
|
|
2163
|
-
return
|
|
2231
|
+
return effects.reactive(super.with(index, effects.unwrap(value)));
|
|
2164
2232
|
}
|
|
2165
2233
|
constructor() {
|
|
2166
2234
|
super(...arguments);
|
|
2167
|
-
|
|
2235
|
+
effects.__runInitializers(this, _instanceExtraInitializers);
|
|
2168
2236
|
}
|
|
2169
2237
|
},
|
|
2170
2238
|
(() => {
|
|
2171
2239
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2240
|
+
effects.__esDecorate(_a, null, _fill_decorators, { kind: "method", name: "fill", static: false, private: false, access: { has: obj => "fill" in obj, get: obj => obj.fill }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
2241
|
+
effects.__esDecorate(_a, null, _copyWithin_decorators, { kind: "method", name: "copyWithin", static: false, private: false, access: { has: obj => "copyWithin" in obj, get: obj => obj.copyWithin }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
2242
|
+
effects.__esDecorate(_a, null, _pop_decorators, { kind: "method", name: "pop", static: false, private: false, access: { has: obj => "pop" in obj, get: obj => obj.pop }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
2243
|
+
effects.__esDecorate(_a, null, _push_decorators, { kind: "method", name: "push", static: false, private: false, access: { has: obj => "push" in obj, get: obj => obj.push }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
2244
|
+
effects.__esDecorate(_a, null, _reverse_decorators, { kind: "method", name: "reverse", static: false, private: false, access: { has: obj => "reverse" in obj, get: obj => obj.reverse }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
2245
|
+
effects.__esDecorate(_a, null, _shift_decorators, { kind: "method", name: "shift", static: false, private: false, access: { has: obj => "shift" in obj, get: obj => obj.shift }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
2246
|
+
effects.__esDecorate(_a, null, _sort_decorators, { kind: "method", name: "sort", static: false, private: false, access: { has: obj => "sort" in obj, get: obj => obj.sort }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
2247
|
+
effects.__esDecorate(_a, null, _splice_decorators, { kind: "method", name: "splice", static: false, private: false, access: { has: obj => "splice" in obj, get: obj => obj.splice }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
2248
|
+
effects.__esDecorate(_a, null, _unshift_decorators, { kind: "method", name: "unshift", static: false, private: false, access: { has: obj => "unshift" in obj, get: obj => obj.unshift }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
2181
2249
|
if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
2182
2250
|
})(),
|
|
2183
2251
|
_a;
|
|
2184
2252
|
})();
|
|
2185
2253
|
|
|
2254
|
+
// These abstract classes are prototype tables for the reactive proxy, not classes
|
|
2255
|
+
// that are instantiated directly. `this` is the original Map/WeakMap target when
|
|
2256
|
+
// a method is reached through the proxy meta-prototype path, so calls like
|
|
2257
|
+
// `this.get()` or `this.entries()` intentionally re-enter the proxy machinery.
|
|
2258
|
+
// Do not mechanically rewrite them to `super.*` as if these were real subclass
|
|
2259
|
+
// instances; that would bypass parts of the designed reactive dispatch.
|
|
2186
2260
|
/**
|
|
2187
2261
|
* Reactive wrapper around JavaScript's WeakMap class
|
|
2188
2262
|
* Only tracks individual key operations, no size tracking (WeakMap limitation)
|
|
@@ -2193,24 +2267,24 @@ class ReactiveWeakMap extends WeakMap {
|
|
|
2193
2267
|
const hadKey = this.has(key);
|
|
2194
2268
|
const result = super.delete(key);
|
|
2195
2269
|
if (hadKey)
|
|
2196
|
-
|
|
2270
|
+
effects.touched1(effects.contentRef(this), { type: 'del', prop: key }, key);
|
|
2197
2271
|
return result;
|
|
2198
2272
|
}
|
|
2199
2273
|
get(key) {
|
|
2200
|
-
|
|
2201
|
-
return
|
|
2274
|
+
effects.dependant(effects.contentRef(this), key);
|
|
2275
|
+
return effects.reactive(super.get(key));
|
|
2202
2276
|
}
|
|
2203
2277
|
has(key) {
|
|
2204
|
-
|
|
2278
|
+
effects.dependant(effects.contentRef(this), key);
|
|
2205
2279
|
return super.has(key);
|
|
2206
2280
|
}
|
|
2207
2281
|
set(key, value) {
|
|
2208
2282
|
const hadKey = this.has(key);
|
|
2209
2283
|
const oldValue = this.get(key);
|
|
2210
|
-
const reactiveValue =
|
|
2284
|
+
const reactiveValue = effects.reactive(value);
|
|
2211
2285
|
this.set(key, reactiveValue);
|
|
2212
2286
|
if (!hadKey || oldValue !== reactiveValue) {
|
|
2213
|
-
|
|
2287
|
+
effects.notifyPropertyChange(effects.contentRef(this), key, oldValue, reactiveValue, hadKey);
|
|
2214
2288
|
}
|
|
2215
2289
|
return this;
|
|
2216
2290
|
}
|
|
@@ -2222,7 +2296,7 @@ class ReactiveWeakMap extends WeakMap {
|
|
|
2222
2296
|
class ReactiveMap extends Map {
|
|
2223
2297
|
// Implement Map interface methods with reactivity
|
|
2224
2298
|
get size() {
|
|
2225
|
-
|
|
2299
|
+
effects.dependant(this, 'size'); // The ReactiveMap instance still goes through proxy
|
|
2226
2300
|
return super.size;
|
|
2227
2301
|
}
|
|
2228
2302
|
clear() {
|
|
@@ -2231,30 +2305,28 @@ class ReactiveMap extends Map {
|
|
|
2231
2305
|
if (hadEntries) {
|
|
2232
2306
|
const evolution = { type: 'bunch', method: 'clear' };
|
|
2233
2307
|
// Clear triggers all effects since all keys are affected
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
proxy.touched(proxy.contentRef(this), evolution);
|
|
2237
|
-
});
|
|
2308
|
+
effects.touched1(this, evolution, 'size');
|
|
2309
|
+
effects.touched(effects.contentRef(this), evolution);
|
|
2238
2310
|
}
|
|
2239
2311
|
}
|
|
2240
2312
|
entries() {
|
|
2241
|
-
|
|
2313
|
+
effects.dependant(effects.contentRef(this));
|
|
2242
2314
|
return makeReactiveEntriesIterator(this.entries());
|
|
2243
2315
|
}
|
|
2244
2316
|
forEach(callbackfn, thisArg) {
|
|
2245
|
-
|
|
2317
|
+
effects.dependant(effects.contentRef(this));
|
|
2246
2318
|
this.forEach(callbackfn, thisArg);
|
|
2247
2319
|
}
|
|
2248
2320
|
keys() {
|
|
2249
|
-
|
|
2321
|
+
effects.dependant(effects.contentRef(this), effects.keysOf);
|
|
2250
2322
|
return this.keys();
|
|
2251
2323
|
}
|
|
2252
2324
|
values() {
|
|
2253
|
-
|
|
2325
|
+
effects.dependant(effects.contentRef(this));
|
|
2254
2326
|
return makeReactiveIterator(this.values());
|
|
2255
2327
|
}
|
|
2256
2328
|
[Symbol.iterator]() {
|
|
2257
|
-
|
|
2329
|
+
effects.dependant(effects.contentRef(this));
|
|
2258
2330
|
const it = Map.prototype[Symbol.iterator].call(this);
|
|
2259
2331
|
const nativeNext = it.next.bind(it);
|
|
2260
2332
|
it.next = () => {
|
|
@@ -2262,7 +2334,7 @@ class ReactiveMap extends Map {
|
|
|
2262
2334
|
if (result.done)
|
|
2263
2335
|
return result;
|
|
2264
2336
|
const [key, value] = result.value;
|
|
2265
|
-
return { value: [
|
|
2337
|
+
return { value: [effects.reactive(key), effects.reactive(value)], done: false };
|
|
2266
2338
|
};
|
|
2267
2339
|
return it;
|
|
2268
2340
|
}
|
|
@@ -2272,38 +2344,40 @@ class ReactiveMap extends Map {
|
|
|
2272
2344
|
const result = super.delete(key);
|
|
2273
2345
|
if (hadKey) {
|
|
2274
2346
|
const evolution = { type: 'del', prop: key };
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
proxy.touched1(this, evolution, 'size');
|
|
2278
|
-
});
|
|
2347
|
+
effects.touched1(effects.contentRef(this), evolution, key);
|
|
2348
|
+
effects.touched1(this, evolution, 'size');
|
|
2279
2349
|
}
|
|
2280
2350
|
return result;
|
|
2281
2351
|
}
|
|
2282
2352
|
get(key) {
|
|
2283
|
-
|
|
2284
|
-
return
|
|
2353
|
+
effects.dependant(effects.contentRef(this), key);
|
|
2354
|
+
return effects.reactive(super.get(key));
|
|
2285
2355
|
}
|
|
2286
2356
|
has(key) {
|
|
2287
|
-
|
|
2357
|
+
effects.dependant(effects.contentRef(this), key);
|
|
2288
2358
|
return super.has(key);
|
|
2289
2359
|
}
|
|
2290
2360
|
set(key, value) {
|
|
2291
2361
|
const hadKey = this.has(key);
|
|
2292
2362
|
const oldValue = this.get(key);
|
|
2293
|
-
const reactiveValue =
|
|
2363
|
+
const reactiveValue = effects.reactive(value);
|
|
2294
2364
|
super.set(key, reactiveValue);
|
|
2295
2365
|
if (!hadKey || oldValue !== reactiveValue) {
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
proxy.touched1(this, evolution, 'size');
|
|
2301
|
-
});
|
|
2366
|
+
effects.notifyPropertyChange(effects.contentRef(this), key, oldValue, reactiveValue, hadKey);
|
|
2367
|
+
// Also notify size change for Map (WeakMap doesn't track size)
|
|
2368
|
+
const evolution = { type: hadKey ? 'set' : 'add', prop: key };
|
|
2369
|
+
effects.touched1(this, evolution, 'size');
|
|
2302
2370
|
}
|
|
2303
2371
|
return this;
|
|
2304
2372
|
}
|
|
2305
2373
|
}
|
|
2306
2374
|
|
|
2375
|
+
// These abstract classes are prototype tables for the reactive proxy, not classes
|
|
2376
|
+
// that are instantiated directly. `this` is the original Set/WeakSet target when
|
|
2377
|
+
// a method is reached through the proxy meta-prototype path, so calls like
|
|
2378
|
+
// `this.has()` or `this.entries()` intentionally re-enter the proxy machinery.
|
|
2379
|
+
// Do not mechanically rewrite them to `super.*` as if these were real subclass
|
|
2380
|
+
// instances; that would bypass parts of the designed reactive dispatch.
|
|
2307
2381
|
/**
|
|
2308
2382
|
* Reactive wrapper around JavaScript's WeakSet class
|
|
2309
2383
|
* Only tracks individual value operations, no size tracking (WeakSet limitation)
|
|
@@ -2314,7 +2388,7 @@ class ReactiveWeakSet extends WeakSet {
|
|
|
2314
2388
|
super.add(value);
|
|
2315
2389
|
if (!had) {
|
|
2316
2390
|
// touch the specific value and the collection view
|
|
2317
|
-
|
|
2391
|
+
effects.touched1(effects.contentRef(this), { type: 'add', prop: value }, value);
|
|
2318
2392
|
// no size/allProps for WeakSet
|
|
2319
2393
|
}
|
|
2320
2394
|
return this;
|
|
@@ -2323,11 +2397,11 @@ class ReactiveWeakSet extends WeakSet {
|
|
|
2323
2397
|
const had = this.has(value);
|
|
2324
2398
|
const res = super.delete(value);
|
|
2325
2399
|
if (had)
|
|
2326
|
-
|
|
2400
|
+
effects.touched1(effects.contentRef(this), { type: 'del', prop: value }, value);
|
|
2327
2401
|
return res;
|
|
2328
2402
|
}
|
|
2329
2403
|
has(value) {
|
|
2330
|
-
|
|
2404
|
+
effects.dependant(effects.contentRef(this), value);
|
|
2331
2405
|
return super.has(value);
|
|
2332
2406
|
}
|
|
2333
2407
|
}
|
|
@@ -2338,20 +2412,18 @@ class ReactiveWeakSet extends WeakSet {
|
|
|
2338
2412
|
class ReactiveSet extends Set {
|
|
2339
2413
|
get size() {
|
|
2340
2414
|
// size depends on the wrapper instance, like Map counterpart
|
|
2341
|
-
|
|
2415
|
+
effects.dependant(this, 'size');
|
|
2342
2416
|
return this.size;
|
|
2343
2417
|
}
|
|
2344
2418
|
add(value) {
|
|
2345
2419
|
const had = this.has(value);
|
|
2346
|
-
const reactiveValue =
|
|
2420
|
+
const reactiveValue = effects.reactive(value);
|
|
2347
2421
|
super.add(reactiveValue);
|
|
2348
2422
|
if (!had) {
|
|
2349
2423
|
const evolution = { type: 'add', prop: reactiveValue };
|
|
2350
2424
|
// touch for value-specific and aggregate dependencies
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
proxy.touched1(this, evolution, 'size');
|
|
2354
|
-
});
|
|
2425
|
+
effects.touched1(effects.contentRef(this), evolution, reactiveValue);
|
|
2426
|
+
effects.touched1(this, evolution, 'size');
|
|
2355
2427
|
}
|
|
2356
2428
|
return this;
|
|
2357
2429
|
}
|
|
@@ -2360,10 +2432,8 @@ class ReactiveSet extends Set {
|
|
|
2360
2432
|
super.clear();
|
|
2361
2433
|
if (hadEntries) {
|
|
2362
2434
|
const evolution = { type: 'bunch', method: 'clear' };
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
proxy.touched(proxy.contentRef(this), evolution);
|
|
2366
|
-
});
|
|
2435
|
+
effects.touched1(this, evolution, 'size');
|
|
2436
|
+
effects.touched(effects.contentRef(this), evolution);
|
|
2367
2437
|
}
|
|
2368
2438
|
}
|
|
2369
2439
|
delete(value) {
|
|
@@ -2371,66 +2441,64 @@ class ReactiveSet extends Set {
|
|
|
2371
2441
|
const res = super.delete(value);
|
|
2372
2442
|
if (had) {
|
|
2373
2443
|
const evolution = { type: 'del', prop: value };
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
proxy.touched1(this, evolution, 'size');
|
|
2377
|
-
});
|
|
2444
|
+
effects.touched1(effects.contentRef(this), evolution, value);
|
|
2445
|
+
effects.touched1(this, evolution, 'size');
|
|
2378
2446
|
}
|
|
2379
2447
|
return res;
|
|
2380
2448
|
}
|
|
2381
2449
|
has(value) {
|
|
2382
|
-
|
|
2450
|
+
effects.dependant(effects.contentRef(this), value);
|
|
2383
2451
|
return this.has(value);
|
|
2384
2452
|
}
|
|
2385
2453
|
entries() {
|
|
2386
|
-
|
|
2454
|
+
effects.dependant(effects.contentRef(this));
|
|
2387
2455
|
return makeReactiveEntriesIterator(this.entries());
|
|
2388
2456
|
}
|
|
2389
2457
|
forEach(callbackfn, thisArg) {
|
|
2390
|
-
|
|
2458
|
+
effects.dependant(effects.contentRef(this));
|
|
2391
2459
|
this.forEach(callbackfn, thisArg);
|
|
2392
2460
|
}
|
|
2393
2461
|
keys() {
|
|
2394
|
-
|
|
2462
|
+
effects.dependant(effects.contentRef(this));
|
|
2395
2463
|
return makeReactiveIterator(this.keys());
|
|
2396
2464
|
}
|
|
2397
2465
|
values() {
|
|
2398
|
-
|
|
2466
|
+
effects.dependant(effects.contentRef(this));
|
|
2399
2467
|
return makeReactiveIterator(this.values());
|
|
2400
2468
|
}
|
|
2401
2469
|
[Symbol.iterator]() {
|
|
2402
|
-
|
|
2470
|
+
effects.dependant(effects.contentRef(this));
|
|
2403
2471
|
const it = Set.prototype[Symbol.iterator].call(this);
|
|
2404
2472
|
const nativeNext = it.next.bind(it);
|
|
2405
2473
|
it.next = () => {
|
|
2406
2474
|
const result = nativeNext();
|
|
2407
2475
|
if (result.done)
|
|
2408
2476
|
return result;
|
|
2409
|
-
return { value:
|
|
2477
|
+
return { value: effects.reactive(result.value), done: false };
|
|
2410
2478
|
};
|
|
2411
2479
|
return it;
|
|
2412
2480
|
}
|
|
2413
2481
|
}
|
|
2414
2482
|
|
|
2415
2483
|
// Register native collection types to use specialized reactive wrappers
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2484
|
+
effects.metaProtos.set(Array, ReactiveArray.prototype);
|
|
2485
|
+
effects.metaProtos.set(Set, ReactiveSet.prototype);
|
|
2486
|
+
effects.metaProtos.set(WeakSet, ReactiveWeakSet.prototype);
|
|
2487
|
+
effects.metaProtos.set(Map, ReactiveMap.prototype);
|
|
2488
|
+
effects.metaProtos.set(WeakMap, ReactiveWeakMap.prototype);
|
|
2489
|
+
effects.wrapProtos.set(Array, ReactiveArrayWrapper.prototype);
|
|
2422
2490
|
/**
|
|
2423
2491
|
* Object containing internal reactive system state for debugging and profiling
|
|
2424
2492
|
*/
|
|
2425
2493
|
const profileInfo = {
|
|
2426
|
-
objectToProxy:
|
|
2427
|
-
proxyToObject:
|
|
2428
|
-
effectToReactiveObjects:
|
|
2429
|
-
watchers:
|
|
2430
|
-
objectParents:
|
|
2431
|
-
objectsWithDeepWatchers:
|
|
2432
|
-
deepWatchers:
|
|
2433
|
-
effectToDeepWatchedObjects:
|
|
2494
|
+
objectToProxy: effects.objectToProxy,
|
|
2495
|
+
proxyToObject: effects.proxyToObject,
|
|
2496
|
+
effectToReactiveObjects: effects.effectToReactiveObjects,
|
|
2497
|
+
watchers: effects.watchers,
|
|
2498
|
+
objectParents: effects.objectParents,
|
|
2499
|
+
objectsWithDeepWatchers: effects.objectsWithDeepWatchers,
|
|
2500
|
+
deepWatchers: effects.deepWatchers,
|
|
2501
|
+
effectToDeepWatchedObjects: effects.effectToDeepWatchedObjects,
|
|
2434
2502
|
};
|
|
2435
2503
|
|
|
2436
2504
|
// In order to avoid async re-entrance, we could use zone.js or something like that.
|
|
@@ -2439,7 +2507,7 @@ const syncCalculating = [];
|
|
|
2439
2507
|
* Decorator that caches the result of a getter method and only recomputes when dependencies change
|
|
2440
2508
|
* Prevents circular dependencies and provides automatic cache invalidation
|
|
2441
2509
|
*/
|
|
2442
|
-
const cached =
|
|
2510
|
+
const cached = effects.decorator({
|
|
2443
2511
|
getter(original, _target, propertyKey) {
|
|
2444
2512
|
return function () {
|
|
2445
2513
|
const alreadyCalculating = syncCalculating.findIndex((c) => c.object === this && c.prop === propertyKey);
|
|
@@ -2540,7 +2608,7 @@ const descriptor = Object.assign(descriptorBase, {
|
|
|
2540
2608
|
* Decorator that marks methods, properties, or classes as deprecated
|
|
2541
2609
|
* Provides warning messages when deprecated items are used
|
|
2542
2610
|
*/
|
|
2543
|
-
const deprecated = Object.assign(
|
|
2611
|
+
const deprecated = Object.assign(effects.decorator({
|
|
2544
2612
|
method(original, _target, propertyKey) {
|
|
2545
2613
|
return function (...args) {
|
|
2546
2614
|
deprecated.warn(this, propertyKey);
|
|
@@ -2568,7 +2636,7 @@ const deprecated = Object.assign(proxy.decorator({
|
|
|
2568
2636
|
};
|
|
2569
2637
|
},
|
|
2570
2638
|
default(message) {
|
|
2571
|
-
return
|
|
2639
|
+
return effects.decorator({
|
|
2572
2640
|
method(original, _target, propertyKey) {
|
|
2573
2641
|
return function (...args) {
|
|
2574
2642
|
deprecated.warn(this, propertyKey, message);
|
|
@@ -2599,7 +2667,7 @@ const deprecated = Object.assign(proxy.decorator({
|
|
|
2599
2667
|
},
|
|
2600
2668
|
}), {
|
|
2601
2669
|
warn: (target, propertyKey, message) => {
|
|
2602
|
-
|
|
2670
|
+
effects.options.warn(`${target.constructor.name}.${String(propertyKey)} is deprecated${message ? `: ${message}` : ''}`);
|
|
2603
2671
|
},
|
|
2604
2672
|
});
|
|
2605
2673
|
/**
|
|
@@ -2608,7 +2676,7 @@ const deprecated = Object.assign(proxy.decorator({
|
|
|
2608
2676
|
* @returns A method decorator that debounces method calls
|
|
2609
2677
|
*/
|
|
2610
2678
|
function debounce(delay) {
|
|
2611
|
-
return
|
|
2679
|
+
return effects.decorator({
|
|
2612
2680
|
method(original, _target, _propertyKey) {
|
|
2613
2681
|
let timeoutId = null;
|
|
2614
2682
|
return function (...args) {
|
|
@@ -2631,7 +2699,7 @@ function debounce(delay) {
|
|
|
2631
2699
|
* @returns A method decorator that throttles method calls
|
|
2632
2700
|
*/
|
|
2633
2701
|
function throttle(delay) {
|
|
2634
|
-
return
|
|
2702
|
+
return effects.decorator({
|
|
2635
2703
|
method(original, _target, _propertyKey) {
|
|
2636
2704
|
let lastCallTime = 0;
|
|
2637
2705
|
let timeoutId = null;
|
|
@@ -2662,7 +2730,7 @@ function throttle(delay) {
|
|
|
2662
2730
|
});
|
|
2663
2731
|
}
|
|
2664
2732
|
|
|
2665
|
-
var version$1 = "1.0.
|
|
2733
|
+
var version$1 = "1.0.15";
|
|
2666
2734
|
var pkg = {
|
|
2667
2735
|
version: version$1};
|
|
2668
2736
|
|
|
@@ -2681,8 +2749,8 @@ if (globalScope) {
|
|
|
2681
2749
|
try {
|
|
2682
2750
|
if (runtimeGlobals.__filename)
|
|
2683
2751
|
source = runtimeGlobals.__filename;
|
|
2684
|
-
else if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunks/index-
|
|
2685
|
-
source = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunks/index-
|
|
2752
|
+
else if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunks/index-Dtj2qZ0d.cjs', document.baseURI).href)) }) !== 'undefined' && (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunks/index-Dtj2qZ0d.cjs', document.baseURI).href))) {
|
|
2753
|
+
source = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunks/index-Dtj2qZ0d.cjs', document.baseURI).href));
|
|
2686
2754
|
}
|
|
2687
2755
|
}
|
|
2688
2756
|
catch (_e) { }
|
|
@@ -2732,4 +2800,4 @@ exports.throttle = throttle;
|
|
|
2732
2800
|
exports.unreactive = unreactive;
|
|
2733
2801
|
exports.watch = watch;
|
|
2734
2802
|
exports.when = when;
|
|
2735
|
-
//# sourceMappingURL=index-
|
|
2803
|
+
//# sourceMappingURL=index-Dtj2qZ0d.cjs.map
|