mutts 1.0.12 → 1.0.13
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/README.md +5 -2
- package/dist/browser.cjs +7 -3
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +1407 -2
- package/dist/browser.dev.cjs +7 -3
- 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 +3 -3
- package/dist/chunks/{index-yK0HVxHv.cjs → index-CAdnMJev.cjs} +202 -79
- package/dist/chunks/index-CAdnMJev.cjs.map +1 -0
- package/dist/chunks/{index-BUop6B2U.esm.js → index-XsYTUhHx.esm.js} +200 -77
- package/dist/chunks/index-XsYTUhHx.esm.js.map +1 -0
- package/dist/chunks/{node-Dd0esp5F.cjs → node-DrrphEPf.cjs} +2 -2
- package/dist/chunks/{node-Dd0esp5F.cjs.map → node-DrrphEPf.cjs.map} +1 -1
- package/dist/chunks/{node-Bo7WU5S2.esm.js → node-NEZvVo4M.esm.js} +2 -2
- package/dist/chunks/{node-Bo7WU5S2.esm.js.map → node-NEZvVo4M.esm.js.map} +1 -1
- package/dist/chunks/{proxy-D2C49sXH.esm.js → proxy-BtmPFjSr.esm.js} +307 -66
- package/dist/chunks/proxy-BtmPFjSr.esm.js.map +1 -0
- package/dist/chunks/{proxy-BvM4yewA.cjs → proxy-DBHj3kGK.cjs} +313 -66
- package/dist/chunks/proxy-DBHj3kGK.cjs.map +1 -0
- package/dist/debug.cjs +537 -166
- package/dist/debug.cjs.map +1 -1
- package/dist/debug.d.ts +96 -80
- package/dist/debug.esm.js +533 -166
- package/dist/debug.esm.js.map +1 -1
- package/dist/devtools/panel.js.map +1 -1
- package/dist/mutts.umd.js +508 -140
- 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 +8 -4
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.dev.cjs +8 -4
- 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-Bx2PhORg.d.ts → types.d.ts} +12 -0
- package/docs/ai/api-reference.md +102 -12
- package/docs/ai/manual.md +60 -24
- package/docs/debug-getReason.md +161 -0
- package/docs/flavored.md +98 -1
- package/docs/reactive/advanced.md +15 -2
- package/docs/reactive/attend.md +32 -0
- package/docs/reactive/core.md +40 -6
- package/docs/reactive/debugging.md +25 -2
- package/docs/reactive.md +2 -0
- package/package.json +2 -3
- package/dist/chunks/index-BUop6B2U.esm.js.map +0 -1
- package/dist/chunks/index-yK0HVxHv.cjs.map +0 -1
- package/dist/chunks/proxy-BvM4yewA.cjs.map +0 -1
- package/dist/chunks/proxy-D2C49sXH.esm.js.map +0 -1
- package/dist/index.d.ts +0 -1322
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { u as decorator, p as captioned, a4 as options, y as effect, af as markWithRoot, W as link, F as flavored, a7 as tag, a3 as reactive, a9 as touched1, T as isReactive, a8 as touched, K as getState, ag as dependant, J as getActiveEffect, ah as getEffectNode, ai as chainExternalReason, aj as keysOf, ak as objectsWithDeepWatchers, al as effectToDeepWatchedObjects, ab as untracked, am as deepWatchers, P as isNonReactive, ac as unwrap, an as registerDeepWatcher, _ as named, ao as rootFunctionSymbol, a2 as proxyToObject, ap as getRoot, v as deepCompare, aq as optionCall, a6 as root, ar as FoolProof, E as flavorOptions, as as effectHistory, q as captured, at as unreactiveProperties, g as addUnreactiveProps, au as __runInitializers, av as __esDecorate, n as atomic, aw as batch, ax as contentRef, ay as notifyPropertyChange, az as metaProtos, aA as wrapProtos, aB as objectParents, aC as watchers, aD as effectToReactiveObjects, $ as objectToProxy } from './proxy-BtmPFjSr.esm.js';
|
|
2
2
|
|
|
3
3
|
// Integrated with `using` statement via Symbol.dispose
|
|
4
4
|
const fr = new FinalizationRegistry((f) => f());
|
|
@@ -256,46 +256,57 @@ function buildPatches(history, A, B, offset, finalX, finalY, finalD, finalK, vOf
|
|
|
256
256
|
var _a, _b;
|
|
257
257
|
const events = Symbol('events');
|
|
258
258
|
const hooks = Symbol('hooks');
|
|
259
|
+
function getEventMap(target) {
|
|
260
|
+
return target[events];
|
|
261
|
+
}
|
|
262
|
+
function getHookSet(target) {
|
|
263
|
+
return target[hooks];
|
|
264
|
+
}
|
|
259
265
|
const eventBehavior = {
|
|
260
266
|
on(eventOrEvents, cb) {
|
|
267
|
+
const self = this;
|
|
268
|
+
const eventMap = getEventMap(self);
|
|
261
269
|
if (typeof eventOrEvents === 'object') {
|
|
262
270
|
for (const e of Object.keys(eventOrEvents)) {
|
|
263
271
|
this.on(e, eventOrEvents[e]);
|
|
264
272
|
}
|
|
265
273
|
}
|
|
266
274
|
else if (cb !== undefined) {
|
|
267
|
-
const callbacks =
|
|
275
|
+
const callbacks = eventMap.get(eventOrEvents) ?? new Set();
|
|
268
276
|
if (!callbacks.has(cb))
|
|
269
277
|
callbacks.add(cb);
|
|
270
|
-
|
|
278
|
+
eventMap.set(eventOrEvents, callbacks);
|
|
271
279
|
}
|
|
272
280
|
return () => this.off(eventOrEvents, cb);
|
|
273
281
|
},
|
|
274
282
|
off(eventOrEvents, cb) {
|
|
283
|
+
const self = this;
|
|
284
|
+
const eventMap = getEventMap(self);
|
|
275
285
|
if (typeof eventOrEvents === 'object') {
|
|
276
286
|
for (const e of Object.keys(eventOrEvents)) {
|
|
277
287
|
this.off(e, eventOrEvents[e]);
|
|
278
288
|
}
|
|
279
289
|
}
|
|
280
290
|
else if (cb !== null && cb !== undefined) {
|
|
281
|
-
const callbacks =
|
|
291
|
+
const callbacks = eventMap.get(eventOrEvents);
|
|
282
292
|
if (callbacks) {
|
|
283
293
|
callbacks.delete(cb);
|
|
284
294
|
if (!callbacks.size)
|
|
285
|
-
|
|
295
|
+
eventMap.delete(eventOrEvents);
|
|
286
296
|
}
|
|
287
297
|
}
|
|
288
298
|
else {
|
|
289
299
|
// Remove all listeners for this event
|
|
290
|
-
|
|
300
|
+
eventMap.delete(eventOrEvents);
|
|
291
301
|
}
|
|
292
302
|
},
|
|
293
303
|
emit(event, ...args) {
|
|
294
|
-
const
|
|
304
|
+
const self = this;
|
|
305
|
+
const callbacks = getEventMap(self).get(event);
|
|
295
306
|
if (callbacks)
|
|
296
307
|
for (const cb of callbacks)
|
|
297
308
|
cb.apply(this, args);
|
|
298
|
-
for (const cb of
|
|
309
|
+
for (const cb of getHookSet(self))
|
|
299
310
|
cb.call(this, event, ...args);
|
|
300
311
|
},
|
|
301
312
|
};
|
|
@@ -305,7 +316,7 @@ function perEvent(eventful, fct, use) {
|
|
|
305
316
|
get(target, prop) {
|
|
306
317
|
if (typeof prop !== 'string')
|
|
307
318
|
return target[prop];
|
|
308
|
-
if (use && !eventful
|
|
319
|
+
if (use && !getEventMap(eventful).has(prop) && !getHookSet(eventful).size)
|
|
309
320
|
return () => { };
|
|
310
321
|
// Return cached function or create and cache
|
|
311
322
|
let cached = cache.get(prop);
|
|
@@ -744,7 +755,7 @@ function chainPromise(given) {
|
|
|
744
755
|
return chained;
|
|
745
756
|
}
|
|
746
757
|
|
|
747
|
-
function attend(source, callback) {
|
|
758
|
+
const attend = captioned(function attend(source, callback) {
|
|
748
759
|
const enumerate = typeof source === 'function'
|
|
749
760
|
? source
|
|
750
761
|
: Array.isArray(source)
|
|
@@ -755,14 +766,16 @@ function attend(source, callback) {
|
|
|
755
766
|
? () => source.values()
|
|
756
767
|
: () => Object.keys(source);
|
|
757
768
|
const keyEffects = new Map();
|
|
758
|
-
const
|
|
769
|
+
const callbackLabel = callback.name ? callback.name : '';
|
|
770
|
+
const outer = effect `attend`(({ ascend }) => {
|
|
759
771
|
const keys = new Set();
|
|
760
772
|
for (const key of enumerate())
|
|
761
773
|
keys.add(key);
|
|
762
774
|
for (const key of keys) {
|
|
763
775
|
if (keyEffects.has(key))
|
|
764
776
|
continue;
|
|
765
|
-
|
|
777
|
+
const indexRef = { value: key };
|
|
778
|
+
keyEffects.set(key, ascend(() => effect `attend${callbackLabel ? `:${callbackLabel}` : ''}:${key}`((access) => callback(indexRef.value, access))));
|
|
766
779
|
}
|
|
767
780
|
for (const key of Array.from(keyEffects.keys())) {
|
|
768
781
|
if (!keys.has(key)) {
|
|
@@ -777,17 +790,50 @@ function attend(source, callback) {
|
|
|
777
790
|
stop(reason);
|
|
778
791
|
keyEffects.clear();
|
|
779
792
|
};
|
|
780
|
-
}
|
|
781
|
-
|
|
793
|
+
}, {
|
|
794
|
+
name: 'attend',
|
|
795
|
+
callbackIndex: 1,
|
|
796
|
+
warn: (message) => options.warn(`[reactive] ${message}`),
|
|
797
|
+
});
|
|
798
|
+
/**
|
|
799
|
+
* Lifts a callback that returns an object into a reactive object that automatically
|
|
800
|
+
* synchronizes with the source object returned by the callback.
|
|
801
|
+
*
|
|
802
|
+
* The returned reactive object will update whenever the callback's dependencies change,
|
|
803
|
+
* efficiently syncing only the properties that differ from the previous result using
|
|
804
|
+
* Object.assign(). Properties that no longer exist in the source are automatically removed.
|
|
805
|
+
*
|
|
806
|
+
* @example
|
|
807
|
+
* ```typescript
|
|
808
|
+
* const user = reactive({ name: 'John', age: 30 })
|
|
809
|
+
* const profile = lift(() => ({
|
|
810
|
+
* displayName: user.name.toUpperCase(),
|
|
811
|
+
* isAdult: user.age >= 18,
|
|
812
|
+
* description: `${user.name} is ${user.age} years old`
|
|
813
|
+
* }))
|
|
814
|
+
*
|
|
815
|
+
* console.log(profile.displayName) // JOHN
|
|
816
|
+
* console.log(profile.isAdult) // true
|
|
817
|
+
*
|
|
818
|
+
* user.name = 'Jane'
|
|
819
|
+
* console.log(profile.displayName) // JANE
|
|
820
|
+
* console.log(profile.description) // Jane is 30 years old
|
|
821
|
+
* ```
|
|
822
|
+
*
|
|
823
|
+
* @param cb Callback function that returns an object
|
|
824
|
+
* @returns A reactive object synchronized with the callback's result, with a [cleanup] property to stop tracking
|
|
825
|
+
*/
|
|
826
|
+
const lift = captioned(function lift(cb) {
|
|
782
827
|
let result;
|
|
783
828
|
let rawResult;
|
|
784
|
-
const
|
|
829
|
+
const resultName = `lift:${cb.name || 'anonymous'}`;
|
|
830
|
+
const liftCleanup = effect `lift:${cb.name}`(markWithRoot((access) => {
|
|
785
831
|
const source = cb(access);
|
|
786
832
|
if (!source || typeof source !== 'object')
|
|
787
833
|
throw new Error('lift callback must return an array or object');
|
|
788
834
|
const sourceProto = Object.getPrototypeOf(source);
|
|
789
835
|
if (!result) {
|
|
790
|
-
rawResult = Array.isArray(source) ? [] : Object.create(sourceProto);
|
|
836
|
+
rawResult = tag(resultName, Array.isArray(source) ? [] : Object.create(sourceProto));
|
|
791
837
|
result = reactive(rawResult);
|
|
792
838
|
}
|
|
793
839
|
if (sourceProto !== Object.getPrototypeOf(result))
|
|
@@ -798,6 +844,7 @@ function lift(cb) {
|
|
|
798
844
|
res.splice(indexA, sliceA.length, ...sliceB);
|
|
799
845
|
}
|
|
800
846
|
else {
|
|
847
|
+
const recordResult = rawResult;
|
|
801
848
|
for (const key of Object.keys(source)) {
|
|
802
849
|
const had = key in rawResult;
|
|
803
850
|
const newDesc = Object.getOwnPropertyDescriptor(source, key);
|
|
@@ -806,7 +853,7 @@ function lift(cb) {
|
|
|
806
853
|
const sameAccessor = oldDesc && newDesc.get && oldDesc.get === newDesc.get;
|
|
807
854
|
Object.defineProperty(rawResult, key, newDesc);
|
|
808
855
|
if (!sameAccessor &&
|
|
809
|
-
|
|
856
|
+
recordResult[key] !==
|
|
810
857
|
(oldDesc ? (oldDesc.get ? oldDesc.get() : oldDesc.value) : undefined))
|
|
811
858
|
touched1(rawResult, { type: 'set', prop: key }, key);
|
|
812
859
|
}
|
|
@@ -817,13 +864,16 @@ function lift(cb) {
|
|
|
817
864
|
}
|
|
818
865
|
for (const key of Object.keys(rawResult))
|
|
819
866
|
if (!(key in source)) {
|
|
820
|
-
delete
|
|
867
|
+
delete recordResult[key];
|
|
821
868
|
touched1(rawResult, { type: 'del', prop: key }, key);
|
|
822
869
|
}
|
|
823
870
|
}
|
|
824
871
|
}, cb));
|
|
825
872
|
return link(result, liftCleanup);
|
|
826
|
-
}
|
|
873
|
+
}, {
|
|
874
|
+
name: 'lift',
|
|
875
|
+
warn: (message) => options.warn(`[reactive] ${message}`),
|
|
876
|
+
});
|
|
827
877
|
/**
|
|
828
878
|
* Reactively maps an array source through `fn`, producing a lazy reactive output array.
|
|
829
879
|
*
|
|
@@ -847,12 +897,18 @@ function morphArray(source, fn, options) {
|
|
|
847
897
|
}
|
|
848
898
|
let track;
|
|
849
899
|
const itemEffects = new Map();
|
|
850
|
-
const cache = [];
|
|
900
|
+
const cache = tag(`morph:${fn.name || 'anonymous'}`, []);
|
|
851
901
|
let input = [];
|
|
852
902
|
function stopItem(key) {
|
|
853
903
|
const entry = itemEffects.get(key);
|
|
854
904
|
if (entry) {
|
|
855
|
-
|
|
905
|
+
const activeEffect = getActiveEffect();
|
|
906
|
+
let chain;
|
|
907
|
+
if (activeEffect) {
|
|
908
|
+
const node = getEffectNode(activeEffect);
|
|
909
|
+
chain = node.currentReason;
|
|
910
|
+
}
|
|
911
|
+
entry.stop(chainExternalReason({ type: 'stopped', chain }));
|
|
856
912
|
itemEffects.delete(key);
|
|
857
913
|
}
|
|
858
914
|
}
|
|
@@ -865,12 +921,22 @@ function morphArray(source, fn, options) {
|
|
|
865
921
|
}
|
|
866
922
|
else {
|
|
867
923
|
const indexRef = { value: key };
|
|
868
|
-
const stop = track(() => effect.
|
|
924
|
+
const stop = track(() => effect.opaque `morph:${fn.name}:${key}`((access) => {
|
|
869
925
|
cache[indexRef.value] = fn(input, access);
|
|
870
926
|
return (reason) => {
|
|
871
927
|
delete cache[indexRef.value];
|
|
872
928
|
touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
|
|
873
|
-
|
|
929
|
+
const activeEffect = getActiveEffect();
|
|
930
|
+
let chain;
|
|
931
|
+
if (activeEffect) {
|
|
932
|
+
const node = getEffectNode(activeEffect);
|
|
933
|
+
chain = node.currentReason;
|
|
934
|
+
}
|
|
935
|
+
stop?.({
|
|
936
|
+
type: 'invalidate',
|
|
937
|
+
cause: chainExternalReason(reason ?? { type: 'stopped', chain }),
|
|
938
|
+
chain: chainExternalReason(chain),
|
|
939
|
+
});
|
|
874
940
|
};
|
|
875
941
|
}));
|
|
876
942
|
itemEffects.set(key, { stop, index: indexRef });
|
|
@@ -889,7 +955,7 @@ function morphArray(source, fn, options) {
|
|
|
889
955
|
return Reflect.has(input, prop);
|
|
890
956
|
},
|
|
891
957
|
});
|
|
892
|
-
const stopMain = effect
|
|
958
|
+
const stopMain = effect `morph:${fn.name}`(({ ascend }) => {
|
|
893
959
|
track = ascend;
|
|
894
960
|
const newInput = [...(typeof source === 'function' ? source() : source)];
|
|
895
961
|
const diffs = arrayDiff(input, newInput).toSorted((a, b) => b.indexA - a.indexA);
|
|
@@ -963,12 +1029,18 @@ function morphMap(source, fn, options) {
|
|
|
963
1029
|
}
|
|
964
1030
|
let track;
|
|
965
1031
|
const itemEffects = new Map();
|
|
966
|
-
const cache = new Map();
|
|
1032
|
+
const cache = tag(`morph:${fn.name || 'anonymous'}`, new Map());
|
|
967
1033
|
Object.defineProperty(cache, 'constructor', { value: Object, enumerable: false });
|
|
968
1034
|
function stopItem(key) {
|
|
969
1035
|
const stop = itemEffects.get(key);
|
|
970
1036
|
if (stop) {
|
|
971
|
-
|
|
1037
|
+
const activeEffect = getActiveEffect();
|
|
1038
|
+
let chain;
|
|
1039
|
+
if (activeEffect) {
|
|
1040
|
+
const node = getEffectNode(activeEffect);
|
|
1041
|
+
chain = node.currentReason;
|
|
1042
|
+
}
|
|
1043
|
+
stop({ type: 'stopped', chain });
|
|
972
1044
|
itemEffects.delete(key);
|
|
973
1045
|
}
|
|
974
1046
|
}
|
|
@@ -978,12 +1050,25 @@ function morphMap(source, fn, options) {
|
|
|
978
1050
|
cache.set(key, track(() => fn(val, key)));
|
|
979
1051
|
}
|
|
980
1052
|
else {
|
|
981
|
-
const stop = track(() => effect.
|
|
982
|
-
|
|
1053
|
+
const stop = track(() => effect.opaque `morph:${fn.name}:${key}`((access) => {
|
|
1054
|
+
const next = source.get(key);
|
|
1055
|
+
if (next === undefined && !source.has(key))
|
|
1056
|
+
return;
|
|
1057
|
+
cache.set(key, fn(next, key, access));
|
|
983
1058
|
return (reason) => {
|
|
984
1059
|
cache.delete(key);
|
|
985
1060
|
touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
|
|
986
|
-
|
|
1061
|
+
const activeEffect = getActiveEffect();
|
|
1062
|
+
let chain;
|
|
1063
|
+
if (activeEffect) {
|
|
1064
|
+
const node = getEffectNode(activeEffect);
|
|
1065
|
+
chain = node.currentReason;
|
|
1066
|
+
}
|
|
1067
|
+
stop?.({
|
|
1068
|
+
type: 'invalidate',
|
|
1069
|
+
cause: chainExternalReason(reason ?? { type: 'stopped', chain }),
|
|
1070
|
+
chain: chainExternalReason(chain),
|
|
1071
|
+
});
|
|
987
1072
|
};
|
|
988
1073
|
}));
|
|
989
1074
|
itemEffects.set(key, stop);
|
|
@@ -1027,7 +1112,7 @@ function morphMap(source, fn, options) {
|
|
|
1027
1112
|
},
|
|
1028
1113
|
});
|
|
1029
1114
|
let stateSnapshot = getState(source);
|
|
1030
|
-
const stopMain = effect
|
|
1115
|
+
const stopMain = effect `morph:${fn.name}`(({ ascend }) => {
|
|
1031
1116
|
track = ascend;
|
|
1032
1117
|
dependant(source, keysOf);
|
|
1033
1118
|
while ('evolution' in stateSnapshot) {
|
|
@@ -1074,7 +1159,13 @@ function morphRecord(source, fn, options) {
|
|
|
1074
1159
|
function stopItem(key) {
|
|
1075
1160
|
const stop = itemEffects.get(key);
|
|
1076
1161
|
if (stop) {
|
|
1077
|
-
|
|
1162
|
+
const activeEffect = getActiveEffect();
|
|
1163
|
+
let chain;
|
|
1164
|
+
if (activeEffect) {
|
|
1165
|
+
const node = getEffectNode(activeEffect);
|
|
1166
|
+
chain = node.currentReason;
|
|
1167
|
+
}
|
|
1168
|
+
stop({ type: 'stopped', chain });
|
|
1078
1169
|
itemEffects.delete(key);
|
|
1079
1170
|
}
|
|
1080
1171
|
}
|
|
@@ -1084,12 +1175,22 @@ function morphRecord(source, fn, options) {
|
|
|
1084
1175
|
cache[key] = track(() => fn(val, key));
|
|
1085
1176
|
}
|
|
1086
1177
|
else {
|
|
1087
|
-
const stop = track(() => effect.
|
|
1178
|
+
const stop = track(() => effect.opaque `morph:${fn.name}:${key}`((access) => {
|
|
1088
1179
|
cache[key] = fn(source[key], key, access);
|
|
1089
1180
|
return (reason) => {
|
|
1090
1181
|
delete cache[key];
|
|
1091
1182
|
touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
|
|
1092
|
-
|
|
1183
|
+
const activeEffect = getActiveEffect();
|
|
1184
|
+
let chain;
|
|
1185
|
+
if (activeEffect) {
|
|
1186
|
+
const node = getEffectNode(activeEffect);
|
|
1187
|
+
chain = node.currentReason;
|
|
1188
|
+
}
|
|
1189
|
+
stop?.({
|
|
1190
|
+
type: 'invalidate',
|
|
1191
|
+
cause: chainExternalReason(reason ?? { type: 'stopped', chain }),
|
|
1192
|
+
chain: chainExternalReason(chain),
|
|
1193
|
+
});
|
|
1093
1194
|
};
|
|
1094
1195
|
}));
|
|
1095
1196
|
itemEffects.set(key, stop);
|
|
@@ -1116,7 +1217,7 @@ function morphRecord(source, fn, options) {
|
|
|
1116
1217
|
},
|
|
1117
1218
|
});
|
|
1118
1219
|
let stateSnapshot = getState(source);
|
|
1119
|
-
const stopMain = effect
|
|
1220
|
+
const stopMain = effect `morph:${fn.name}`(({ ascend }) => {
|
|
1120
1221
|
track = ascend;
|
|
1121
1222
|
// Track only structural changes on source
|
|
1122
1223
|
dependant(source, keysOf);
|
|
@@ -1157,7 +1258,7 @@ function morphRecord(source, fn, options) {
|
|
|
1157
1258
|
* // Changing users[0].name only recomputes names[0]
|
|
1158
1259
|
* ```
|
|
1159
1260
|
*/
|
|
1160
|
-
const morph = flavored(function morph(source, fn, options) {
|
|
1261
|
+
const morph = captioned(flavored(function morph(source, fn, options) {
|
|
1161
1262
|
if (Array.isArray(source) || typeof source === 'function')
|
|
1162
1263
|
return morphArray(source, fn, options);
|
|
1163
1264
|
if (source instanceof Map)
|
|
@@ -1167,6 +1268,10 @@ const morph = flavored(function morph(source, fn, options) {
|
|
|
1167
1268
|
get pure() {
|
|
1168
1269
|
return (source, fn, _opt) => this(source, fn, { pure: true });
|
|
1169
1270
|
},
|
|
1271
|
+
}), {
|
|
1272
|
+
name: 'morph',
|
|
1273
|
+
callbackIndex: 1,
|
|
1274
|
+
warn: (message) => options.warn(`[reactive] ${message}`),
|
|
1170
1275
|
});
|
|
1171
1276
|
|
|
1172
1277
|
/**
|
|
@@ -1192,7 +1297,7 @@ function deepWatch(target, callback, { immediate = false } = {}) {
|
|
|
1192
1297
|
const wrappedCallback = markWithRoot((() => callback(target)), callback);
|
|
1193
1298
|
registerDeepWatcher();
|
|
1194
1299
|
// Use the existing effect system to register dependencies
|
|
1195
|
-
return effect
|
|
1300
|
+
return effect `deepWatch`(() => {
|
|
1196
1301
|
// Mark the target object as having deep watchers
|
|
1197
1302
|
objectsWithDeepWatchers.add(target);
|
|
1198
1303
|
// Track which objects this effect is watching for cleanup
|
|
@@ -1256,7 +1361,7 @@ function deepWatch(target, callback, { immediate = false } = {}) {
|
|
|
1256
1361
|
traverseAndTrack(target);
|
|
1257
1362
|
// Only call the callback if immediate is true or if it's not the first run
|
|
1258
1363
|
if (immediate) {
|
|
1259
|
-
untracked(() => callback(target));
|
|
1364
|
+
untracked `deepWatch:callback`(() => callback(target));
|
|
1260
1365
|
}
|
|
1261
1366
|
immediate = true;
|
|
1262
1367
|
// Return a cleanup function that properly removes deep watcher tracking
|
|
@@ -1323,7 +1428,7 @@ function memoizeFunction(fn, opts) {
|
|
|
1323
1428
|
const wasVerification = options.isVerificationRun;
|
|
1324
1429
|
options.isVerificationRun = true;
|
|
1325
1430
|
try {
|
|
1326
|
-
const fresh = untracked(() => fn.apply(this, args));
|
|
1431
|
+
const fresh = untracked `memoize:verify-calculation`(() => fn.apply(this, args));
|
|
1327
1432
|
if (!deepCompare(node.result, fresh)) {
|
|
1328
1433
|
optionCall('onMemoizationDiscrepancy', node.result, fresh, fn, args, 'calculation');
|
|
1329
1434
|
}
|
|
@@ -1336,7 +1441,7 @@ function memoizeFunction(fn, opts) {
|
|
|
1336
1441
|
}
|
|
1337
1442
|
// Create memoize internal effect to track dependencies and invalidate cache
|
|
1338
1443
|
// Use untracked to prevent the effect creation from being affected by parent effects
|
|
1339
|
-
node.cleanup = root(() => effect
|
|
1444
|
+
node.cleanup = root `memoize:root`(() => effect `memoize`(() => {
|
|
1340
1445
|
// Execute the function and track its dependencies
|
|
1341
1446
|
// The function execution will automatically track dependencies on reactive objects
|
|
1342
1447
|
node.result = fn.apply(this, args);
|
|
@@ -1347,7 +1452,17 @@ function memoizeFunction(fn, opts) {
|
|
|
1347
1452
|
// Lazy memoization: stop the effect so it doesn't re-run immediately.
|
|
1348
1453
|
// It will be re-created on next access.
|
|
1349
1454
|
if (node.cleanup) {
|
|
1350
|
-
|
|
1455
|
+
const activeEffect = getActiveEffect();
|
|
1456
|
+
let chain;
|
|
1457
|
+
if (activeEffect) {
|
|
1458
|
+
const effectNode = getEffectNode(activeEffect);
|
|
1459
|
+
chain = effectNode.currentReason;
|
|
1460
|
+
}
|
|
1461
|
+
node.cleanup({
|
|
1462
|
+
type: 'invalidate',
|
|
1463
|
+
cause: chainExternalReason(reason ?? { type: 'stopped', chain }),
|
|
1464
|
+
chain: chainExternalReason(chain),
|
|
1465
|
+
});
|
|
1351
1466
|
node.cleanup = undefined;
|
|
1352
1467
|
}
|
|
1353
1468
|
};
|
|
@@ -1356,7 +1471,7 @@ function memoizeFunction(fn, opts) {
|
|
|
1356
1471
|
const wasVerification = options.isVerificationRun;
|
|
1357
1472
|
options.isVerificationRun = true;
|
|
1358
1473
|
try {
|
|
1359
|
-
const fresh = untracked(() => fn.apply(this, args));
|
|
1474
|
+
const fresh = untracked `memoize:verify-comparison`(() => fn.apply(this, args));
|
|
1360
1475
|
if (!deepCompare(node.result, fresh)) {
|
|
1361
1476
|
optionCall('onMemoizationDiscrepancy', node.result, fresh, fn, args, 'comparison');
|
|
1362
1477
|
}
|
|
@@ -1548,12 +1663,12 @@ const memoize = flavored(makeMemoizeDecorator(), {
|
|
|
1548
1663
|
function organized(source, apply, baseTarget = {}) {
|
|
1549
1664
|
const observedSource = reactive(source);
|
|
1550
1665
|
const target = reactive(baseTarget);
|
|
1551
|
-
const stop = attend(()
|
|
1666
|
+
const stop = attend `organized:entries`(function enumerateObservedSourceKeys() {
|
|
1552
1667
|
const keys = [];
|
|
1553
1668
|
for (const key in observedSource)
|
|
1554
1669
|
keys.push(key);
|
|
1555
1670
|
return keys;
|
|
1556
|
-
}, (key)
|
|
1671
|
+
}, function applyObservedSourceKey(key) {
|
|
1557
1672
|
const sourceKey = key;
|
|
1558
1673
|
const accessBase = {
|
|
1559
1674
|
key: sourceKey,
|
|
@@ -1591,7 +1706,7 @@ function organize(target, property, access) {
|
|
|
1591
1706
|
|
|
1592
1707
|
//#region watch
|
|
1593
1708
|
const unsetYet = Symbol('unset-yet');
|
|
1594
|
-
const watch = flavored(function watch(value, //object | ((dep: DependencyAccess) => object),
|
|
1709
|
+
const watch = captioned(flavored(function watch(value, //object | ((dep: DependencyAccess) => object),
|
|
1595
1710
|
changed, options = {}) {
|
|
1596
1711
|
return typeof value === 'function'
|
|
1597
1712
|
? watchCallBack(value, changed, options)
|
|
@@ -1607,11 +1722,14 @@ changed, options = {}) {
|
|
|
1607
1722
|
get immediate() {
|
|
1608
1723
|
return flavorOptions(this, { immediate: true });
|
|
1609
1724
|
},
|
|
1725
|
+
}), {
|
|
1726
|
+
name: 'watch',
|
|
1727
|
+
warn: (message) => options.warn(`[reactive] ${message}`),
|
|
1610
1728
|
});
|
|
1611
1729
|
function watchObject(value, changed, { immediate = false, deep = false } = {}) {
|
|
1612
1730
|
if (deep)
|
|
1613
1731
|
return deepWatch(value, changed, { immediate });
|
|
1614
|
-
return effect
|
|
1732
|
+
return effect `watch:object`(() => {
|
|
1615
1733
|
dependant(value);
|
|
1616
1734
|
if (immediate)
|
|
1617
1735
|
changed(value);
|
|
@@ -1621,16 +1739,16 @@ function watchObject(value, changed, { immediate = false, deep = false } = {}) {
|
|
|
1621
1739
|
function watchCallBack(value, changed, { immediate = false, deep = false } = {}) {
|
|
1622
1740
|
let oldValue = unsetYet;
|
|
1623
1741
|
let deepCleanup;
|
|
1624
|
-
const cbCleanup = effect
|
|
1742
|
+
const cbCleanup = effect `watch:callback`(markWithRoot((access) => {
|
|
1625
1743
|
const newValue = value(access);
|
|
1626
1744
|
if (oldValue !== newValue) {
|
|
1627
1745
|
const old = oldValue;
|
|
1628
1746
|
if (old === unsetYet) {
|
|
1629
1747
|
if (immediate)
|
|
1630
|
-
untracked(() => changed(newValue));
|
|
1748
|
+
untracked `watch:changed`(() => changed(newValue));
|
|
1631
1749
|
}
|
|
1632
1750
|
else
|
|
1633
|
-
untracked(() => changed(newValue, old));
|
|
1751
|
+
untracked `watch:changed`(() => changed(newValue, old));
|
|
1634
1752
|
}
|
|
1635
1753
|
oldValue = newValue;
|
|
1636
1754
|
if (deep) {
|
|
@@ -1657,7 +1775,7 @@ function watchCallBack(value, changed, { immediate = false, deep = false } = {})
|
|
|
1657
1775
|
function when(predicate, timeout) {
|
|
1658
1776
|
return new Promise((resolve, reject) => {
|
|
1659
1777
|
let timer;
|
|
1660
|
-
const stop = effect
|
|
1778
|
+
const stop = effect `watch:when`((access) => {
|
|
1661
1779
|
try {
|
|
1662
1780
|
const value = predicate(access);
|
|
1663
1781
|
if (value) {
|
|
@@ -1764,7 +1882,7 @@ function resource(fetcher, options = {}) {
|
|
|
1764
1882
|
// Solve race conditions: make sure a new fast request is not overloaded by a slow old one
|
|
1765
1883
|
let counter = 0;
|
|
1766
1884
|
return lazyInit(resource, () => {
|
|
1767
|
-
link(resource, effect
|
|
1885
|
+
link(resource, effect `watch:resource`((access) => {
|
|
1768
1886
|
// Track reload signal to enable manual reloading
|
|
1769
1887
|
void reloadSignal.value;
|
|
1770
1888
|
const id = ++counter;
|
|
@@ -1930,6 +2048,7 @@ let ReactiveArrayWrapper = (() => {
|
|
|
1930
2048
|
return super.findLastIndex((v, i, a) => predicate.call(thisArg, reactive(v), i, a), thisArg);
|
|
1931
2049
|
}
|
|
1932
2050
|
flat(depth) {
|
|
2051
|
+
dependant(this, keysOf);
|
|
1933
2052
|
return reactive(super.flat(depth));
|
|
1934
2053
|
}
|
|
1935
2054
|
flatMap(callbackfn, thisArg) {
|
|
@@ -2356,59 +2475,62 @@ function isCached(object, propertyKey) {
|
|
|
2356
2475
|
function cache(object, propertyKey, value) {
|
|
2357
2476
|
Object.defineProperty(object, propertyKey, { value });
|
|
2358
2477
|
}
|
|
2478
|
+
function descriptorBase(descriptor) {
|
|
2479
|
+
return function descriptorDecorator(...properties) {
|
|
2480
|
+
return (Base) => {
|
|
2481
|
+
return class extends Base {
|
|
2482
|
+
constructor(...args) {
|
|
2483
|
+
super(...args);
|
|
2484
|
+
for (const key of properties) {
|
|
2485
|
+
const existing = Object.getOwnPropertyDescriptor(this, key);
|
|
2486
|
+
Object.defineProperty(this, key, Object.assign(existing || {}, descriptor));
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
};
|
|
2490
|
+
};
|
|
2491
|
+
};
|
|
2492
|
+
}
|
|
2359
2493
|
/**
|
|
2360
2494
|
* Creates a decorator that modifies property descriptors for specified properties
|
|
2361
2495
|
* @param descriptor - The descriptor properties to apply
|
|
2362
2496
|
* @returns A class decorator that applies the descriptor to specified properties
|
|
2363
2497
|
*/
|
|
2364
|
-
const descriptor =
|
|
2365
|
-
return (...properties) => (Base) => {
|
|
2366
|
-
return class extends Base {
|
|
2367
|
-
constructor(...args) {
|
|
2368
|
-
super(...args);
|
|
2369
|
-
for (const key of properties) {
|
|
2370
|
-
const existing = Object.getOwnPropertyDescriptor(this, key);
|
|
2371
|
-
Object.defineProperty(this, key, Object.assign(existing || {}, descriptor));
|
|
2372
|
-
}
|
|
2373
|
-
}
|
|
2374
|
-
};
|
|
2375
|
-
};
|
|
2376
|
-
}, {
|
|
2498
|
+
const descriptor = Object.assign(descriptorBase, {
|
|
2377
2499
|
/**
|
|
2378
2500
|
* enumerable: true
|
|
2379
2501
|
*/
|
|
2380
2502
|
get enumerable() {
|
|
2381
|
-
return
|
|
2503
|
+
return descriptorBase({ enumerable: true });
|
|
2382
2504
|
},
|
|
2383
2505
|
/**
|
|
2384
2506
|
* enumerable: false
|
|
2385
2507
|
*/
|
|
2386
2508
|
get hidden() {
|
|
2387
|
-
return
|
|
2509
|
+
return descriptorBase({ enumerable: false });
|
|
2388
2510
|
},
|
|
2389
2511
|
/**
|
|
2390
2512
|
* configurable: true
|
|
2391
2513
|
*/
|
|
2392
2514
|
get configurable() {
|
|
2393
|
-
return
|
|
2515
|
+
return descriptorBase({ configurable: true });
|
|
2394
2516
|
},
|
|
2395
2517
|
/**
|
|
2396
2518
|
* configurable: false
|
|
2397
2519
|
*/
|
|
2398
2520
|
get frozen() {
|
|
2399
|
-
return
|
|
2521
|
+
return descriptorBase({ configurable: false });
|
|
2400
2522
|
},
|
|
2401
2523
|
/**
|
|
2402
2524
|
* writable: true
|
|
2403
2525
|
*/
|
|
2404
2526
|
get writable() {
|
|
2405
|
-
return
|
|
2527
|
+
return descriptorBase({ writable: true });
|
|
2406
2528
|
},
|
|
2407
2529
|
/**
|
|
2408
2530
|
* writable: false
|
|
2409
2531
|
*/
|
|
2410
2532
|
get readonly() {
|
|
2411
|
-
return
|
|
2533
|
+
return descriptorBase({ writable: false });
|
|
2412
2534
|
},
|
|
2413
2535
|
});
|
|
2414
2536
|
/**
|
|
@@ -2537,24 +2659,25 @@ function throttle(delay) {
|
|
|
2537
2659
|
});
|
|
2538
2660
|
}
|
|
2539
2661
|
|
|
2540
|
-
var version$1 = "1.0.
|
|
2662
|
+
var version$1 = "1.0.13";
|
|
2541
2663
|
var pkg = {
|
|
2542
2664
|
version: version$1};
|
|
2543
2665
|
|
|
2544
2666
|
const { version } = pkg;
|
|
2545
2667
|
const GLOBAL_MUTTS_KEY = '__MUTTS_INSTANCE__';
|
|
2668
|
+
const runtimeGlobals = globalThis;
|
|
2546
2669
|
const globalScope = (typeof globalThis !== 'undefined'
|
|
2547
2670
|
? globalThis
|
|
2548
|
-
:
|
|
2549
|
-
? window
|
|
2550
|
-
:
|
|
2551
|
-
? global
|
|
2671
|
+
: runtimeGlobals.window
|
|
2672
|
+
? runtimeGlobals.window
|
|
2673
|
+
: runtimeGlobals.global
|
|
2674
|
+
? runtimeGlobals.global
|
|
2552
2675
|
: false);
|
|
2553
2676
|
if (globalScope) {
|
|
2554
2677
|
let source = 'mutts/index';
|
|
2555
2678
|
try {
|
|
2556
|
-
if (
|
|
2557
|
-
source = __filename;
|
|
2679
|
+
if (runtimeGlobals.__filename)
|
|
2680
|
+
source = runtimeGlobals.__filename;
|
|
2558
2681
|
else if (typeof import.meta !== 'undefined' && import.meta.url) {
|
|
2559
2682
|
source = import.meta.url;
|
|
2560
2683
|
}
|
|
@@ -2574,4 +2697,4 @@ if (globalScope) {
|
|
|
2574
2697
|
}
|
|
2575
2698
|
|
|
2576
2699
|
export { ArrayReadForward as A, unreactive as B, watch as C, Destroyable as D, Eventful as E, when as F, Indexable as I, DestructionError as a, allocated as b, allocatedValues as c, arrayDiff as d, attend as e, cache as f, cached as g, callOnGC as h, chainPromise as i, debounce as j, deepWatch as k, deprecated as l, descriptor as m, destructor as n, forwardArray as o, getAt as p, isCached as q, lift as r, memoize as s, morph as t, organize as u, organized as v, profileInfo as w, resource as x, setAt as y, throttle as z };
|
|
2577
|
-
//# sourceMappingURL=index-
|
|
2700
|
+
//# sourceMappingURL=index-XsYTUhHx.esm.js.map
|