mutts 1.0.12 → 1.0.14
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 +7 -4
- package/dist/browser.cjs +150 -27
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +1440 -2
- package/dist/browser.dev.cjs +17 -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 +137 -28
- package/dist/browser.esm.js.map +1 -1
- package/dist/chunks/{index-yK0HVxHv.cjs → index-BnTNC9eC.cjs} +347 -156
- package/dist/chunks/index-BnTNC9eC.cjs.map +1 -0
- package/dist/chunks/{index-BUop6B2U.esm.js → index-CAWVZL7P.esm.js} +345 -154
- package/dist/chunks/index-CAWVZL7P.esm.js.map +1 -0
- package/dist/chunks/node-Df_5r_WA.cjs +187 -0
- package/dist/chunks/node-Df_5r_WA.cjs.map +1 -0
- package/dist/chunks/node-DuIduHw3.esm.js +185 -0
- package/dist/chunks/node-DuIduHw3.esm.js.map +1 -0
- package/dist/chunks/{proxy-D2C49sXH.esm.js → proxy-C2lnvvbx.esm.js} +943 -272
- package/dist/chunks/proxy-C2lnvvbx.esm.js.map +1 -0
- package/dist/chunks/{proxy-BvM4yewA.cjs → proxy-HA_QQnd5.cjs} +959 -273
- package/dist/chunks/proxy-HA_QQnd5.cjs.map +1 -0
- package/dist/debug.cjs +571 -173
- package/dist/debug.cjs.map +1 -1
- package/dist/debug.d.ts +96 -80
- package/dist/debug.esm.js +567 -173
- package/dist/debug.esm.js.map +1 -1
- package/dist/devtools/panel.js.map +1 -1
- package/dist/mutts.umd.js +4351 -3366
- 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 +18 -4
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.dev.cjs +18 -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} +42 -15
- package/docs/ai/api-reference.md +105 -13
- package/docs/ai/manual.md +77 -29
- package/docs/debug-getReason.md +161 -0
- package/docs/flavored.md +98 -1
- package/docs/reactive/advanced.md +184 -12
- package/docs/reactive/attend.md +32 -0
- package/docs/reactive/core.md +40 -6
- package/docs/reactive/debugging.md +40 -15
- package/docs/reactive.md +4 -1
- package/package.json +13 -9
- package/dist/chunks/index-BUop6B2U.esm.js.map +0 -1
- package/dist/chunks/index-yK0HVxHv.cjs.map +0 -1
- package/dist/chunks/node-Bo7WU5S2.esm.js +0 -96
- package/dist/chunks/node-Bo7WU5S2.esm.js.map +0 -1
- package/dist/chunks/node-Dd0esp5F.cjs +0 -98
- package/dist/chunks/node-Dd0esp5F.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,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var proxy = require('./proxy-
|
|
3
|
+
var proxy = require('./proxy-HA_QQnd5.cjs');
|
|
4
4
|
|
|
5
5
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
6
6
|
// Integrated with `using` statement via Symbol.dispose
|
|
@@ -259,46 +259,57 @@ function buildPatches(history, A, B, offset, finalX, finalY, finalD, finalK, vOf
|
|
|
259
259
|
var _a, _b;
|
|
260
260
|
const events = Symbol('events');
|
|
261
261
|
const hooks = Symbol('hooks');
|
|
262
|
+
function getEventMap(target) {
|
|
263
|
+
return target[events];
|
|
264
|
+
}
|
|
265
|
+
function getHookSet(target) {
|
|
266
|
+
return target[hooks];
|
|
267
|
+
}
|
|
262
268
|
const eventBehavior = {
|
|
263
269
|
on(eventOrEvents, cb) {
|
|
270
|
+
const self = this;
|
|
271
|
+
const eventMap = getEventMap(self);
|
|
264
272
|
if (typeof eventOrEvents === 'object') {
|
|
265
273
|
for (const e of Object.keys(eventOrEvents)) {
|
|
266
274
|
this.on(e, eventOrEvents[e]);
|
|
267
275
|
}
|
|
268
276
|
}
|
|
269
277
|
else if (cb !== undefined) {
|
|
270
|
-
const callbacks =
|
|
278
|
+
const callbacks = eventMap.get(eventOrEvents) ?? new Set();
|
|
271
279
|
if (!callbacks.has(cb))
|
|
272
280
|
callbacks.add(cb);
|
|
273
|
-
|
|
281
|
+
eventMap.set(eventOrEvents, callbacks);
|
|
274
282
|
}
|
|
275
283
|
return () => this.off(eventOrEvents, cb);
|
|
276
284
|
},
|
|
277
285
|
off(eventOrEvents, cb) {
|
|
286
|
+
const self = this;
|
|
287
|
+
const eventMap = getEventMap(self);
|
|
278
288
|
if (typeof eventOrEvents === 'object') {
|
|
279
289
|
for (const e of Object.keys(eventOrEvents)) {
|
|
280
290
|
this.off(e, eventOrEvents[e]);
|
|
281
291
|
}
|
|
282
292
|
}
|
|
283
293
|
else if (cb !== null && cb !== undefined) {
|
|
284
|
-
const callbacks =
|
|
294
|
+
const callbacks = eventMap.get(eventOrEvents);
|
|
285
295
|
if (callbacks) {
|
|
286
296
|
callbacks.delete(cb);
|
|
287
297
|
if (!callbacks.size)
|
|
288
|
-
|
|
298
|
+
eventMap.delete(eventOrEvents);
|
|
289
299
|
}
|
|
290
300
|
}
|
|
291
301
|
else {
|
|
292
302
|
// Remove all listeners for this event
|
|
293
|
-
|
|
303
|
+
eventMap.delete(eventOrEvents);
|
|
294
304
|
}
|
|
295
305
|
},
|
|
296
306
|
emit(event, ...args) {
|
|
297
|
-
const
|
|
307
|
+
const self = this;
|
|
308
|
+
const callbacks = getEventMap(self).get(event);
|
|
298
309
|
if (callbacks)
|
|
299
310
|
for (const cb of callbacks)
|
|
300
311
|
cb.apply(this, args);
|
|
301
|
-
for (const cb of
|
|
312
|
+
for (const cb of getHookSet(self))
|
|
302
313
|
cb.call(this, event, ...args);
|
|
303
314
|
},
|
|
304
315
|
};
|
|
@@ -308,7 +319,7 @@ function perEvent(eventful, fct, use) {
|
|
|
308
319
|
get(target, prop) {
|
|
309
320
|
if (typeof prop !== 'string')
|
|
310
321
|
return target[prop];
|
|
311
|
-
if (use && !eventful
|
|
322
|
+
if (use && !getEventMap(eventful).has(prop) && !getHookSet(eventful).size)
|
|
312
323
|
return () => { };
|
|
313
324
|
// Return cached function or create and cache
|
|
314
325
|
let cached = cache.get(prop);
|
|
@@ -747,7 +758,7 @@ function chainPromise(given) {
|
|
|
747
758
|
return chained;
|
|
748
759
|
}
|
|
749
760
|
|
|
750
|
-
function attend(source, callback) {
|
|
761
|
+
const attend = proxy.captioned(function attend(source, callback) {
|
|
751
762
|
const enumerate = typeof source === 'function'
|
|
752
763
|
? source
|
|
753
764
|
: Array.isArray(source)
|
|
@@ -758,14 +769,16 @@ function attend(source, callback) {
|
|
|
758
769
|
? () => source.values()
|
|
759
770
|
: () => Object.keys(source);
|
|
760
771
|
const keyEffects = new Map();
|
|
761
|
-
const
|
|
772
|
+
const callbackLabel = callback.name ? callback.name : '';
|
|
773
|
+
const outer = proxy.effect `attend`(({ ascend }) => {
|
|
762
774
|
const keys = new Set();
|
|
763
775
|
for (const key of enumerate())
|
|
764
776
|
keys.add(key);
|
|
765
777
|
for (const key of keys) {
|
|
766
778
|
if (keyEffects.has(key))
|
|
767
779
|
continue;
|
|
768
|
-
|
|
780
|
+
const indexRef = { value: key };
|
|
781
|
+
keyEffects.set(key, ascend(() => proxy.effect `attend${callbackLabel ? `:${callbackLabel}` : ''}:${key}`((access) => callback(indexRef.value, access))));
|
|
769
782
|
}
|
|
770
783
|
for (const key of Array.from(keyEffects.keys())) {
|
|
771
784
|
if (!keys.has(key)) {
|
|
@@ -780,17 +793,50 @@ function attend(source, callback) {
|
|
|
780
793
|
stop(reason);
|
|
781
794
|
keyEffects.clear();
|
|
782
795
|
};
|
|
783
|
-
}
|
|
784
|
-
|
|
796
|
+
}, {
|
|
797
|
+
name: 'attend',
|
|
798
|
+
callbackIndex: 1,
|
|
799
|
+
warn: (message) => proxy.options.warn(`[reactive] ${message}`),
|
|
800
|
+
});
|
|
801
|
+
/**
|
|
802
|
+
* Lifts a callback that returns an object into a reactive object that automatically
|
|
803
|
+
* synchronizes with the source object returned by the callback.
|
|
804
|
+
*
|
|
805
|
+
* The returned reactive object will update whenever the callback's dependencies change,
|
|
806
|
+
* efficiently syncing only the properties that differ from the previous result using
|
|
807
|
+
* Object.assign(). Properties that no longer exist in the source are automatically removed.
|
|
808
|
+
*
|
|
809
|
+
* @example
|
|
810
|
+
* ```typescript
|
|
811
|
+
* const user = reactive({ name: 'John', age: 30 })
|
|
812
|
+
* const profile = lift(() => ({
|
|
813
|
+
* displayName: user.name.toUpperCase(),
|
|
814
|
+
* isAdult: user.age >= 18,
|
|
815
|
+
* description: `${user.name} is ${user.age} years old`
|
|
816
|
+
* }))
|
|
817
|
+
*
|
|
818
|
+
* console.log(profile.displayName) // JOHN
|
|
819
|
+
* console.log(profile.isAdult) // true
|
|
820
|
+
*
|
|
821
|
+
* user.name = 'Jane'
|
|
822
|
+
* console.log(profile.displayName) // JANE
|
|
823
|
+
* console.log(profile.description) // Jane is 30 years old
|
|
824
|
+
* ```
|
|
825
|
+
*
|
|
826
|
+
* @param cb Callback function that returns an object
|
|
827
|
+
* @returns A reactive object synchronized with the callback's result, with a [cleanup] property to stop tracking
|
|
828
|
+
*/
|
|
829
|
+
const lift = proxy.captioned(function lift(cb) {
|
|
785
830
|
let result;
|
|
786
831
|
let rawResult;
|
|
787
|
-
const
|
|
832
|
+
const resultName = `lift:${cb.name || 'anonymous'}`;
|
|
833
|
+
const liftCleanup = proxy.effect `lift:${cb.name}`(proxy.markWithRoot((access) => {
|
|
788
834
|
const source = cb(access);
|
|
789
835
|
if (!source || typeof source !== 'object')
|
|
790
836
|
throw new Error('lift callback must return an array or object');
|
|
791
837
|
const sourceProto = Object.getPrototypeOf(source);
|
|
792
838
|
if (!result) {
|
|
793
|
-
rawResult = Array.isArray(source) ? [] : Object.create(sourceProto);
|
|
839
|
+
rawResult = proxy.tag(resultName, Array.isArray(source) ? [] : Object.create(sourceProto));
|
|
794
840
|
result = proxy.reactive(rawResult);
|
|
795
841
|
}
|
|
796
842
|
if (sourceProto !== Object.getPrototypeOf(result))
|
|
@@ -801,6 +847,7 @@ function lift(cb) {
|
|
|
801
847
|
res.splice(indexA, sliceA.length, ...sliceB);
|
|
802
848
|
}
|
|
803
849
|
else {
|
|
850
|
+
const recordResult = rawResult;
|
|
804
851
|
for (const key of Object.keys(source)) {
|
|
805
852
|
const had = key in rawResult;
|
|
806
853
|
const newDesc = Object.getOwnPropertyDescriptor(source, key);
|
|
@@ -809,7 +856,7 @@ function lift(cb) {
|
|
|
809
856
|
const sameAccessor = oldDesc && newDesc.get && oldDesc.get === newDesc.get;
|
|
810
857
|
Object.defineProperty(rawResult, key, newDesc);
|
|
811
858
|
if (!sameAccessor &&
|
|
812
|
-
|
|
859
|
+
recordResult[key] !==
|
|
813
860
|
(oldDesc ? (oldDesc.get ? oldDesc.get() : oldDesc.value) : undefined))
|
|
814
861
|
proxy.touched1(rawResult, { type: 'set', prop: key }, key);
|
|
815
862
|
}
|
|
@@ -820,13 +867,16 @@ function lift(cb) {
|
|
|
820
867
|
}
|
|
821
868
|
for (const key of Object.keys(rawResult))
|
|
822
869
|
if (!(key in source)) {
|
|
823
|
-
delete
|
|
870
|
+
delete recordResult[key];
|
|
824
871
|
proxy.touched1(rawResult, { type: 'del', prop: key }, key);
|
|
825
872
|
}
|
|
826
873
|
}
|
|
827
874
|
}, cb));
|
|
828
875
|
return proxy.link(result, liftCleanup);
|
|
829
|
-
}
|
|
876
|
+
}, {
|
|
877
|
+
name: 'lift',
|
|
878
|
+
warn: (message) => proxy.options.warn(`[reactive] ${message}`),
|
|
879
|
+
});
|
|
830
880
|
/**
|
|
831
881
|
* Reactively maps an array source through `fn`, producing a lazy reactive output array.
|
|
832
882
|
*
|
|
@@ -846,16 +896,26 @@ function lift(cb) {
|
|
|
846
896
|
*/
|
|
847
897
|
function morphArray(source, fn, options) {
|
|
848
898
|
if (typeof source !== 'function' && !proxy.isReactive(source) && options?.pure === true) {
|
|
849
|
-
return source.map((i) => fn(i));
|
|
899
|
+
return source.map((i) => fn(i, { index: 0 }));
|
|
850
900
|
}
|
|
851
901
|
let track;
|
|
852
902
|
const itemEffects = new Map();
|
|
853
|
-
const cache = [];
|
|
903
|
+
const cache = proxy.tag(`morph:${fn.name || 'anonymous'}`, []);
|
|
854
904
|
let input = [];
|
|
905
|
+
function currentCleanupReason() {
|
|
906
|
+
const activeEffect = proxy.getActiveEffect();
|
|
907
|
+
if (!activeEffect)
|
|
908
|
+
return undefined;
|
|
909
|
+
const node = proxy.getEffectNode(activeEffect);
|
|
910
|
+
return node.currentReason;
|
|
911
|
+
}
|
|
912
|
+
function stopEntry(entry) {
|
|
913
|
+
entry.stop(proxy.chainExternalReason({ type: 'stopped', chain: currentCleanupReason() }));
|
|
914
|
+
}
|
|
855
915
|
function stopItem(key) {
|
|
856
916
|
const entry = itemEffects.get(key);
|
|
857
917
|
if (entry) {
|
|
858
|
-
entry
|
|
918
|
+
stopEntry(entry);
|
|
859
919
|
itemEffects.delete(key);
|
|
860
920
|
}
|
|
861
921
|
}
|
|
@@ -863,20 +923,33 @@ function morphArray(source, fn, options) {
|
|
|
863
923
|
const isPure = options?.pure === true || (typeof options?.pure === 'function' && options.pure(input));
|
|
864
924
|
if (isPure) {
|
|
865
925
|
track(() => {
|
|
866
|
-
cache[key] = fn(input);
|
|
926
|
+
cache[key] = fn(input, { index: key });
|
|
867
927
|
});
|
|
868
928
|
}
|
|
869
929
|
else {
|
|
870
|
-
const
|
|
871
|
-
const stop = track(() => proxy.effect.
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
delete cache[indexRef.value];
|
|
930
|
+
const position = proxy.reactive({ index: key });
|
|
931
|
+
const stop = track(() => proxy.effect.opaque `morph:${fn.name}:${key}`((access) => {
|
|
932
|
+
if (access.reaction) {
|
|
933
|
+
delete cache[position.index];
|
|
875
934
|
proxy.touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
|
|
876
|
-
|
|
877
|
-
|
|
935
|
+
const activeEffect = proxy.getActiveEffect();
|
|
936
|
+
let chain;
|
|
937
|
+
if (activeEffect) {
|
|
938
|
+
const node = proxy.getEffectNode(activeEffect);
|
|
939
|
+
chain = node.currentReason;
|
|
940
|
+
}
|
|
941
|
+
stop?.({
|
|
942
|
+
type: 'invalidate',
|
|
943
|
+
cause: proxy.chainExternalReason(!access.reaction || access.reaction === true
|
|
944
|
+
? { type: 'stopped', chain }
|
|
945
|
+
: access.reaction),
|
|
946
|
+
chain: proxy.chainExternalReason(chain),
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
else
|
|
950
|
+
cache[position.index] = fn(input, position, access);
|
|
878
951
|
}));
|
|
879
|
-
itemEffects.set(key, { stop,
|
|
952
|
+
itemEffects.set(key, { stop, position });
|
|
880
953
|
}
|
|
881
954
|
}
|
|
882
955
|
const proxy$1 = proxy.reactive(cache, {
|
|
@@ -892,40 +965,64 @@ function morphArray(source, fn, options) {
|
|
|
892
965
|
return Reflect.has(input, prop);
|
|
893
966
|
},
|
|
894
967
|
});
|
|
895
|
-
const stopMain = proxy.effect
|
|
968
|
+
const stopMain = proxy.effect `morph:${fn.name}`(({ ascend }) => {
|
|
896
969
|
track = ascend;
|
|
897
970
|
const newInput = [...(typeof source === 'function' ? source() : source)];
|
|
898
971
|
const diffs = arrayDiff(input, newInput).toSorted((a, b) => b.indexA - a.indexA);
|
|
899
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();
|
|
900
1012
|
for (const diff of diffs) {
|
|
901
|
-
|
|
902
|
-
for (let i =
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
if (
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
}
|
|
915
|
-
// Re-add them with shifted indices
|
|
916
|
-
for (const [idx, entry] of entries) {
|
|
917
|
-
if (idx >= diff.indexA + diff.sliceA.length) {
|
|
918
|
-
const newIdx = idx + shift;
|
|
919
|
-
entry.index.value = newIdx;
|
|
920
|
-
itemEffects.set(newIdx, entry);
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
// Splice the cache
|
|
925
|
-
cache.splice(diff.indexA, diff.sliceA.length, ...new Array(diff.sliceB.length).fill(undefined));
|
|
926
|
-
// Make holes for lazy computation
|
|
927
|
-
for (let i = diff.indexA; i < diff.indexA + diff.sliceB.length; i++)
|
|
928
|
-
delete cache[i];
|
|
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);
|
|
929
1026
|
}
|
|
930
1027
|
const invalidates = new Set([proxy.keysOf]);
|
|
931
1028
|
if (input.length !== newInput.length)
|
|
@@ -966,12 +1063,18 @@ function morphMap(source, fn, options) {
|
|
|
966
1063
|
}
|
|
967
1064
|
let track;
|
|
968
1065
|
const itemEffects = new Map();
|
|
969
|
-
const cache = new Map();
|
|
1066
|
+
const cache = proxy.tag(`morph:${fn.name || 'anonymous'}`, new Map());
|
|
970
1067
|
Object.defineProperty(cache, 'constructor', { value: Object, enumerable: false });
|
|
971
1068
|
function stopItem(key) {
|
|
972
1069
|
const stop = itemEffects.get(key);
|
|
973
1070
|
if (stop) {
|
|
974
|
-
|
|
1071
|
+
const activeEffect = proxy.getActiveEffect();
|
|
1072
|
+
let chain;
|
|
1073
|
+
if (activeEffect) {
|
|
1074
|
+
const node = proxy.getEffectNode(activeEffect);
|
|
1075
|
+
chain = node.currentReason;
|
|
1076
|
+
}
|
|
1077
|
+
stop({ type: 'stopped', chain });
|
|
975
1078
|
itemEffects.delete(key);
|
|
976
1079
|
}
|
|
977
1080
|
}
|
|
@@ -981,12 +1084,25 @@ function morphMap(source, fn, options) {
|
|
|
981
1084
|
cache.set(key, track(() => fn(val, key)));
|
|
982
1085
|
}
|
|
983
1086
|
else {
|
|
984
|
-
const stop = track(() => proxy.effect.
|
|
985
|
-
|
|
1087
|
+
const stop = track(() => proxy.effect.opaque `morph:${fn.name}:${key}`((access) => {
|
|
1088
|
+
const next = source.get(key);
|
|
1089
|
+
if (next === undefined && !source.has(key))
|
|
1090
|
+
return;
|
|
1091
|
+
cache.set(key, fn(next, key, access));
|
|
986
1092
|
return (reason) => {
|
|
987
1093
|
cache.delete(key);
|
|
988
1094
|
proxy.touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
|
|
989
|
-
|
|
1095
|
+
const activeEffect = proxy.getActiveEffect();
|
|
1096
|
+
let chain;
|
|
1097
|
+
if (activeEffect) {
|
|
1098
|
+
const node = proxy.getEffectNode(activeEffect);
|
|
1099
|
+
chain = node.currentReason;
|
|
1100
|
+
}
|
|
1101
|
+
stop?.({
|
|
1102
|
+
type: 'invalidate',
|
|
1103
|
+
cause: proxy.chainExternalReason(reason ?? { type: 'stopped', chain }),
|
|
1104
|
+
chain: proxy.chainExternalReason(chain),
|
|
1105
|
+
});
|
|
990
1106
|
};
|
|
991
1107
|
}));
|
|
992
1108
|
itemEffects.set(key, stop);
|
|
@@ -1030,7 +1146,7 @@ function morphMap(source, fn, options) {
|
|
|
1030
1146
|
},
|
|
1031
1147
|
});
|
|
1032
1148
|
let stateSnapshot = proxy.getState(source);
|
|
1033
|
-
const stopMain = proxy.effect
|
|
1149
|
+
const stopMain = proxy.effect `morph:${fn.name}`(({ ascend }) => {
|
|
1034
1150
|
track = ascend;
|
|
1035
1151
|
proxy.dependant(source, proxy.keysOf);
|
|
1036
1152
|
while ('evolution' in stateSnapshot) {
|
|
@@ -1077,7 +1193,13 @@ function morphRecord(source, fn, options) {
|
|
|
1077
1193
|
function stopItem(key) {
|
|
1078
1194
|
const stop = itemEffects.get(key);
|
|
1079
1195
|
if (stop) {
|
|
1080
|
-
|
|
1196
|
+
const activeEffect = proxy.getActiveEffect();
|
|
1197
|
+
let chain;
|
|
1198
|
+
if (activeEffect) {
|
|
1199
|
+
const node = proxy.getEffectNode(activeEffect);
|
|
1200
|
+
chain = node.currentReason;
|
|
1201
|
+
}
|
|
1202
|
+
stop({ type: 'stopped', chain });
|
|
1081
1203
|
itemEffects.delete(key);
|
|
1082
1204
|
}
|
|
1083
1205
|
}
|
|
@@ -1087,12 +1209,22 @@ function morphRecord(source, fn, options) {
|
|
|
1087
1209
|
cache[key] = track(() => fn(val, key));
|
|
1088
1210
|
}
|
|
1089
1211
|
else {
|
|
1090
|
-
const stop = track(() => proxy.effect.
|
|
1212
|
+
const stop = track(() => proxy.effect.opaque `morph:${fn.name}:${key}`((access) => {
|
|
1091
1213
|
cache[key] = fn(source[key], key, access);
|
|
1092
1214
|
return (reason) => {
|
|
1093
1215
|
delete cache[key];
|
|
1094
1216
|
proxy.touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
|
|
1095
|
-
|
|
1217
|
+
const activeEffect = proxy.getActiveEffect();
|
|
1218
|
+
let chain;
|
|
1219
|
+
if (activeEffect) {
|
|
1220
|
+
const node = proxy.getEffectNode(activeEffect);
|
|
1221
|
+
chain = node.currentReason;
|
|
1222
|
+
}
|
|
1223
|
+
stop?.({
|
|
1224
|
+
type: 'invalidate',
|
|
1225
|
+
cause: proxy.chainExternalReason(reason ?? { type: 'stopped', chain }),
|
|
1226
|
+
chain: proxy.chainExternalReason(chain),
|
|
1227
|
+
});
|
|
1096
1228
|
};
|
|
1097
1229
|
}));
|
|
1098
1230
|
itemEffects.set(key, stop);
|
|
@@ -1119,7 +1251,7 @@ function morphRecord(source, fn, options) {
|
|
|
1119
1251
|
},
|
|
1120
1252
|
});
|
|
1121
1253
|
let stateSnapshot = proxy.getState(source);
|
|
1122
|
-
const stopMain = proxy.effect
|
|
1254
|
+
const stopMain = proxy.effect `morph:${fn.name}`(({ ascend }) => {
|
|
1123
1255
|
track = ascend;
|
|
1124
1256
|
// Track only structural changes on source
|
|
1125
1257
|
proxy.dependant(source, proxy.keysOf);
|
|
@@ -1160,7 +1292,7 @@ function morphRecord(source, fn, options) {
|
|
|
1160
1292
|
* // Changing users[0].name only recomputes names[0]
|
|
1161
1293
|
* ```
|
|
1162
1294
|
*/
|
|
1163
|
-
const morph = proxy.flavored(function morph(source, fn, options) {
|
|
1295
|
+
const morph = proxy.captioned(proxy.flavored(function morph(source, fn, options) {
|
|
1164
1296
|
if (Array.isArray(source) || typeof source === 'function')
|
|
1165
1297
|
return morphArray(source, fn, options);
|
|
1166
1298
|
if (source instanceof Map)
|
|
@@ -1170,6 +1302,10 @@ const morph = proxy.flavored(function morph(source, fn, options) {
|
|
|
1170
1302
|
get pure() {
|
|
1171
1303
|
return (source, fn, _opt) => this(source, fn, { pure: true });
|
|
1172
1304
|
},
|
|
1305
|
+
}), {
|
|
1306
|
+
name: 'morph',
|
|
1307
|
+
callbackIndex: 1,
|
|
1308
|
+
warn: (message) => proxy.options.warn(`[reactive] ${message}`),
|
|
1173
1309
|
});
|
|
1174
1310
|
|
|
1175
1311
|
/**
|
|
@@ -1195,7 +1331,7 @@ function deepWatch(target, callback, { immediate = false } = {}) {
|
|
|
1195
1331
|
const wrappedCallback = proxy.markWithRoot((() => callback(target)), callback);
|
|
1196
1332
|
proxy.registerDeepWatcher();
|
|
1197
1333
|
// Use the existing effect system to register dependencies
|
|
1198
|
-
return proxy.effect
|
|
1334
|
+
return proxy.effect `deepWatch`(() => {
|
|
1199
1335
|
// Mark the target object as having deep watchers
|
|
1200
1336
|
proxy.objectsWithDeepWatchers.add(target);
|
|
1201
1337
|
// Track which objects this effect is watching for cleanup
|
|
@@ -1259,7 +1395,7 @@ function deepWatch(target, callback, { immediate = false } = {}) {
|
|
|
1259
1395
|
traverseAndTrack(target);
|
|
1260
1396
|
// Only call the callback if immediate is true or if it's not the first run
|
|
1261
1397
|
if (immediate) {
|
|
1262
|
-
proxy.untracked(() => callback(target));
|
|
1398
|
+
proxy.untracked `deepWatch:callback`(() => callback(target));
|
|
1263
1399
|
}
|
|
1264
1400
|
immediate = true;
|
|
1265
1401
|
// Return a cleanup function that properly removes deep watcher tracking
|
|
@@ -1320,13 +1456,16 @@ function memoizeFunction(fn, opts) {
|
|
|
1320
1456
|
for (const arg of args) {
|
|
1321
1457
|
node = getBranch(node, arg);
|
|
1322
1458
|
}
|
|
1459
|
+
if (proxy.inertDepth > 0) {
|
|
1460
|
+
return fn.apply(this, args);
|
|
1461
|
+
}
|
|
1323
1462
|
proxy.dependant(node, 'memoize');
|
|
1324
1463
|
if ('result' in node) {
|
|
1325
1464
|
if (proxy.options.onMemoizationDiscrepancy) {
|
|
1326
1465
|
const wasVerification = proxy.options.isVerificationRun;
|
|
1327
1466
|
proxy.options.isVerificationRun = true;
|
|
1328
1467
|
try {
|
|
1329
|
-
const fresh = proxy.untracked(() => fn.apply(this, args));
|
|
1468
|
+
const fresh = proxy.untracked `memoize:verify-calculation`(() => fn.apply(this, args));
|
|
1330
1469
|
if (!proxy.deepCompare(node.result, fresh)) {
|
|
1331
1470
|
proxy.optionCall('onMemoizationDiscrepancy', node.result, fresh, fn, args, 'calculation');
|
|
1332
1471
|
}
|
|
@@ -1339,7 +1478,7 @@ function memoizeFunction(fn, opts) {
|
|
|
1339
1478
|
}
|
|
1340
1479
|
// Create memoize internal effect to track dependencies and invalidate cache
|
|
1341
1480
|
// Use untracked to prevent the effect creation from being affected by parent effects
|
|
1342
|
-
node.cleanup = proxy.root(() => proxy.effect
|
|
1481
|
+
node.cleanup = proxy.root `memoize:root`(() => proxy.effect `memoize`(() => {
|
|
1343
1482
|
// Execute the function and track its dependencies
|
|
1344
1483
|
// The function execution will automatically track dependencies on reactive objects
|
|
1345
1484
|
node.result = fn.apply(this, args);
|
|
@@ -1350,7 +1489,17 @@ function memoizeFunction(fn, opts) {
|
|
|
1350
1489
|
// Lazy memoization: stop the effect so it doesn't re-run immediately.
|
|
1351
1490
|
// It will be re-created on next access.
|
|
1352
1491
|
if (node.cleanup) {
|
|
1353
|
-
|
|
1492
|
+
const activeEffect = proxy.getActiveEffect();
|
|
1493
|
+
let chain;
|
|
1494
|
+
if (activeEffect) {
|
|
1495
|
+
const effectNode = proxy.getEffectNode(activeEffect);
|
|
1496
|
+
chain = effectNode.currentReason;
|
|
1497
|
+
}
|
|
1498
|
+
node.cleanup({
|
|
1499
|
+
type: 'invalidate',
|
|
1500
|
+
cause: proxy.chainExternalReason(reason ?? { type: 'stopped', chain }),
|
|
1501
|
+
chain: proxy.chainExternalReason(chain),
|
|
1502
|
+
});
|
|
1354
1503
|
node.cleanup = undefined;
|
|
1355
1504
|
}
|
|
1356
1505
|
};
|
|
@@ -1359,7 +1508,7 @@ function memoizeFunction(fn, opts) {
|
|
|
1359
1508
|
const wasVerification = proxy.options.isVerificationRun;
|
|
1360
1509
|
proxy.options.isVerificationRun = true;
|
|
1361
1510
|
try {
|
|
1362
|
-
const fresh = proxy.untracked(() => fn.apply(this, args));
|
|
1511
|
+
const fresh = proxy.untracked `memoize:verify-comparison`(() => fn.apply(this, args));
|
|
1363
1512
|
if (!proxy.deepCompare(node.result, fresh)) {
|
|
1364
1513
|
proxy.optionCall('onMemoizationDiscrepancy', node.result, fresh, fn, args, 'comparison');
|
|
1365
1514
|
}
|
|
@@ -1551,12 +1700,12 @@ const memoize = proxy.flavored(makeMemoizeDecorator(), {
|
|
|
1551
1700
|
function organized(source, apply, baseTarget = {}) {
|
|
1552
1701
|
const observedSource = proxy.reactive(source);
|
|
1553
1702
|
const target = proxy.reactive(baseTarget);
|
|
1554
|
-
const stop = attend(()
|
|
1703
|
+
const stop = attend `organized:entries`(function enumerateObservedSourceKeys() {
|
|
1555
1704
|
const keys = [];
|
|
1556
1705
|
for (const key in observedSource)
|
|
1557
1706
|
keys.push(key);
|
|
1558
1707
|
return keys;
|
|
1559
|
-
}, (key)
|
|
1708
|
+
}, function applyObservedSourceKey(key) {
|
|
1560
1709
|
const sourceKey = key;
|
|
1561
1710
|
const accessBase = {
|
|
1562
1711
|
key: sourceKey,
|
|
@@ -1594,7 +1743,7 @@ function organize(target, property, access) {
|
|
|
1594
1743
|
|
|
1595
1744
|
//#region watch
|
|
1596
1745
|
const unsetYet = Symbol('unset-yet');
|
|
1597
|
-
const watch = proxy.flavored(function watch(value, //object | ((dep: DependencyAccess) => object),
|
|
1746
|
+
const watch = proxy.captioned(proxy.flavored(function watch(value, //object | ((dep: DependencyAccess) => object),
|
|
1598
1747
|
changed, options = {}) {
|
|
1599
1748
|
return typeof value === 'function'
|
|
1600
1749
|
? watchCallBack(value, changed, options)
|
|
@@ -1610,11 +1759,14 @@ changed, options = {}) {
|
|
|
1610
1759
|
get immediate() {
|
|
1611
1760
|
return proxy.flavorOptions(this, { immediate: true });
|
|
1612
1761
|
},
|
|
1762
|
+
}), {
|
|
1763
|
+
name: 'watch',
|
|
1764
|
+
warn: (message) => proxy.options.warn(`[reactive] ${message}`),
|
|
1613
1765
|
});
|
|
1614
1766
|
function watchObject(value, changed, { immediate = false, deep = false } = {}) {
|
|
1615
1767
|
if (deep)
|
|
1616
1768
|
return deepWatch(value, changed, { immediate });
|
|
1617
|
-
return proxy.effect
|
|
1769
|
+
return proxy.effect `watch:object`(() => {
|
|
1618
1770
|
proxy.dependant(value);
|
|
1619
1771
|
if (immediate)
|
|
1620
1772
|
changed(value);
|
|
@@ -1624,16 +1776,16 @@ function watchObject(value, changed, { immediate = false, deep = false } = {}) {
|
|
|
1624
1776
|
function watchCallBack(value, changed, { immediate = false, deep = false } = {}) {
|
|
1625
1777
|
let oldValue = unsetYet;
|
|
1626
1778
|
let deepCleanup;
|
|
1627
|
-
const cbCleanup = proxy.effect
|
|
1779
|
+
const cbCleanup = proxy.effect `watch:callback`(proxy.markWithRoot((access) => {
|
|
1628
1780
|
const newValue = value(access);
|
|
1629
1781
|
if (oldValue !== newValue) {
|
|
1630
1782
|
const old = oldValue;
|
|
1631
1783
|
if (old === unsetYet) {
|
|
1632
1784
|
if (immediate)
|
|
1633
|
-
proxy.untracked(() => changed(newValue));
|
|
1785
|
+
proxy.untracked `watch:changed`(() => changed(newValue));
|
|
1634
1786
|
}
|
|
1635
1787
|
else
|
|
1636
|
-
proxy.untracked(() => changed(newValue, old));
|
|
1788
|
+
proxy.untracked `watch:changed`(() => changed(newValue, old));
|
|
1637
1789
|
}
|
|
1638
1790
|
oldValue = newValue;
|
|
1639
1791
|
if (deep) {
|
|
@@ -1660,7 +1812,7 @@ function watchCallBack(value, changed, { immediate = false, deep = false } = {})
|
|
|
1660
1812
|
function when(predicate, timeout) {
|
|
1661
1813
|
return new Promise((resolve, reject) => {
|
|
1662
1814
|
let timer;
|
|
1663
|
-
const stop = proxy.effect
|
|
1815
|
+
const stop = proxy.effect `watch:when`((access) => {
|
|
1664
1816
|
try {
|
|
1665
1817
|
const value = predicate(access);
|
|
1666
1818
|
if (value) {
|
|
@@ -1767,7 +1919,7 @@ function resource(fetcher, options = {}) {
|
|
|
1767
1919
|
// Solve race conditions: make sure a new fast request is not overloaded by a slow old one
|
|
1768
1920
|
let counter = 0;
|
|
1769
1921
|
return lazyInit(resource, () => {
|
|
1770
|
-
proxy.link(resource, proxy.effect
|
|
1922
|
+
proxy.link(resource, proxy.effect `watch:resource`((access) => {
|
|
1771
1923
|
// Track reload signal to enable manual reloading
|
|
1772
1924
|
void reloadSignal.value;
|
|
1773
1925
|
const id = ++counter;
|
|
@@ -1933,6 +2085,7 @@ let ReactiveArrayWrapper = (() => {
|
|
|
1933
2085
|
return super.findLastIndex((v, i, a) => predicate.call(thisArg, proxy.reactive(v), i, a), thisArg);
|
|
1934
2086
|
}
|
|
1935
2087
|
flat(depth) {
|
|
2088
|
+
proxy.dependant(this, proxy.keysOf);
|
|
1936
2089
|
return proxy.reactive(super.flat(depth));
|
|
1937
2090
|
}
|
|
1938
2091
|
flatMap(callbackfn, thisArg) {
|
|
@@ -1944,14 +2097,28 @@ let ReactiveArrayWrapper = (() => {
|
|
|
1944
2097
|
}, thisArg);
|
|
1945
2098
|
}
|
|
1946
2099
|
includes(searchElement, fromIndex) {
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
2100
|
+
const target = proxy.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 = proxy.unwrap(this[i]);
|
|
2107
|
+
if (value === target)
|
|
2108
|
+
return true;
|
|
2109
|
+
}
|
|
2110
|
+
return false;
|
|
1950
2111
|
}
|
|
1951
2112
|
indexOf(searchElement, fromIndex) {
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
2113
|
+
const target = proxy.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 (proxy.unwrap(this[i]) === target)
|
|
2120
|
+
return i;
|
|
2121
|
+
return -1;
|
|
1955
2122
|
}
|
|
1956
2123
|
join(separator) {
|
|
1957
2124
|
return super.join(separator);
|
|
@@ -1961,9 +2128,17 @@ let ReactiveArrayWrapper = (() => {
|
|
|
1961
2128
|
return super.keys();
|
|
1962
2129
|
}
|
|
1963
2130
|
lastIndexOf(searchElement, fromIndex) {
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
2131
|
+
const target = proxy.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 (proxy.unwrap(this[i]) === target)
|
|
2140
|
+
return i;
|
|
2141
|
+
return -1;
|
|
1967
2142
|
}
|
|
1968
2143
|
map(callbackfn, thisArg) {
|
|
1969
2144
|
return proxy.reactive(super.map((v, i, a) => proxy.unwrap(callbackfn.call(thisArg, proxy.reactive(v), i, a)), thisArg));
|
|
@@ -2003,13 +2178,25 @@ let ReactiveArrayWrapper = (() => {
|
|
|
2003
2178
|
return super.sort(wrappedCompare);
|
|
2004
2179
|
}
|
|
2005
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;
|
|
2006
2188
|
if (arguments.length > 2)
|
|
2007
|
-
|
|
2008
|
-
if (arguments.length === 2)
|
|
2009
|
-
|
|
2010
|
-
if (arguments.length === 1)
|
|
2011
|
-
|
|
2012
|
-
|
|
2189
|
+
result = super.splice(start, deleteCount, ...items.map(proxy.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
|
+
proxy.touched(this, { type: 'set', prop: 'length' }, ['length']);
|
|
2198
|
+
}
|
|
2199
|
+
return proxy.reactive(result);
|
|
2013
2200
|
}
|
|
2014
2201
|
unshift(...items) {
|
|
2015
2202
|
return super.unshift(...items.map(proxy.unwrap));
|
|
@@ -2064,6 +2251,12 @@ let ReactiveArrayWrapper = (() => {
|
|
|
2064
2251
|
_a;
|
|
2065
2252
|
})();
|
|
2066
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.
|
|
2067
2260
|
/**
|
|
2068
2261
|
* Reactive wrapper around JavaScript's WeakMap class
|
|
2069
2262
|
* Only tracks individual key operations, no size tracking (WeakMap limitation)
|
|
@@ -2112,10 +2305,8 @@ class ReactiveMap extends Map {
|
|
|
2112
2305
|
if (hadEntries) {
|
|
2113
2306
|
const evolution = { type: 'bunch', method: 'clear' };
|
|
2114
2307
|
// Clear triggers all effects since all keys are affected
|
|
2115
|
-
proxy.
|
|
2116
|
-
|
|
2117
|
-
proxy.touched(proxy.contentRef(this), evolution);
|
|
2118
|
-
});
|
|
2308
|
+
proxy.touched1(this, evolution, 'size');
|
|
2309
|
+
proxy.touched(proxy.contentRef(this), evolution);
|
|
2119
2310
|
}
|
|
2120
2311
|
}
|
|
2121
2312
|
entries() {
|
|
@@ -2153,10 +2344,8 @@ class ReactiveMap extends Map {
|
|
|
2153
2344
|
const result = super.delete(key);
|
|
2154
2345
|
if (hadKey) {
|
|
2155
2346
|
const evolution = { type: 'del', prop: key };
|
|
2156
|
-
proxy.
|
|
2157
|
-
|
|
2158
|
-
proxy.touched1(this, evolution, 'size');
|
|
2159
|
-
});
|
|
2347
|
+
proxy.touched1(proxy.contentRef(this), evolution, key);
|
|
2348
|
+
proxy.touched1(this, evolution, 'size');
|
|
2160
2349
|
}
|
|
2161
2350
|
return result;
|
|
2162
2351
|
}
|
|
@@ -2174,17 +2363,21 @@ class ReactiveMap extends Map {
|
|
|
2174
2363
|
const reactiveValue = proxy.reactive(value);
|
|
2175
2364
|
super.set(key, reactiveValue);
|
|
2176
2365
|
if (!hadKey || oldValue !== reactiveValue) {
|
|
2177
|
-
proxy.
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
proxy.touched1(this, evolution, 'size');
|
|
2182
|
-
});
|
|
2366
|
+
proxy.notifyPropertyChange(proxy.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
|
+
proxy.touched1(this, evolution, 'size');
|
|
2183
2370
|
}
|
|
2184
2371
|
return this;
|
|
2185
2372
|
}
|
|
2186
2373
|
}
|
|
2187
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.
|
|
2188
2381
|
/**
|
|
2189
2382
|
* Reactive wrapper around JavaScript's WeakSet class
|
|
2190
2383
|
* Only tracks individual value operations, no size tracking (WeakSet limitation)
|
|
@@ -2229,10 +2422,8 @@ class ReactiveSet extends Set {
|
|
|
2229
2422
|
if (!had) {
|
|
2230
2423
|
const evolution = { type: 'add', prop: reactiveValue };
|
|
2231
2424
|
// touch for value-specific and aggregate dependencies
|
|
2232
|
-
proxy.
|
|
2233
|
-
|
|
2234
|
-
proxy.touched1(this, evolution, 'size');
|
|
2235
|
-
});
|
|
2425
|
+
proxy.touched1(proxy.contentRef(this), evolution, reactiveValue);
|
|
2426
|
+
proxy.touched1(this, evolution, 'size');
|
|
2236
2427
|
}
|
|
2237
2428
|
return this;
|
|
2238
2429
|
}
|
|
@@ -2241,10 +2432,8 @@ class ReactiveSet extends Set {
|
|
|
2241
2432
|
super.clear();
|
|
2242
2433
|
if (hadEntries) {
|
|
2243
2434
|
const evolution = { type: 'bunch', method: 'clear' };
|
|
2244
|
-
proxy.
|
|
2245
|
-
|
|
2246
|
-
proxy.touched(proxy.contentRef(this), evolution);
|
|
2247
|
-
});
|
|
2435
|
+
proxy.touched1(this, evolution, 'size');
|
|
2436
|
+
proxy.touched(proxy.contentRef(this), evolution);
|
|
2248
2437
|
}
|
|
2249
2438
|
}
|
|
2250
2439
|
delete(value) {
|
|
@@ -2252,10 +2441,8 @@ class ReactiveSet extends Set {
|
|
|
2252
2441
|
const res = super.delete(value);
|
|
2253
2442
|
if (had) {
|
|
2254
2443
|
const evolution = { type: 'del', prop: value };
|
|
2255
|
-
proxy.
|
|
2256
|
-
|
|
2257
|
-
proxy.touched1(this, evolution, 'size');
|
|
2258
|
-
});
|
|
2444
|
+
proxy.touched1(proxy.contentRef(this), evolution, value);
|
|
2445
|
+
proxy.touched1(this, evolution, 'size');
|
|
2259
2446
|
}
|
|
2260
2447
|
return res;
|
|
2261
2448
|
}
|
|
@@ -2359,59 +2546,62 @@ function isCached(object, propertyKey) {
|
|
|
2359
2546
|
function cache(object, propertyKey, value) {
|
|
2360
2547
|
Object.defineProperty(object, propertyKey, { value });
|
|
2361
2548
|
}
|
|
2549
|
+
function descriptorBase(descriptor) {
|
|
2550
|
+
return function descriptorDecorator(...properties) {
|
|
2551
|
+
return (Base) => {
|
|
2552
|
+
return class extends Base {
|
|
2553
|
+
constructor(...args) {
|
|
2554
|
+
super(...args);
|
|
2555
|
+
for (const key of properties) {
|
|
2556
|
+
const existing = Object.getOwnPropertyDescriptor(this, key);
|
|
2557
|
+
Object.defineProperty(this, key, Object.assign(existing || {}, descriptor));
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
};
|
|
2561
|
+
};
|
|
2562
|
+
};
|
|
2563
|
+
}
|
|
2362
2564
|
/**
|
|
2363
2565
|
* Creates a decorator that modifies property descriptors for specified properties
|
|
2364
2566
|
* @param descriptor - The descriptor properties to apply
|
|
2365
2567
|
* @returns A class decorator that applies the descriptor to specified properties
|
|
2366
2568
|
*/
|
|
2367
|
-
const descriptor =
|
|
2368
|
-
return (...properties) => (Base) => {
|
|
2369
|
-
return class extends Base {
|
|
2370
|
-
constructor(...args) {
|
|
2371
|
-
super(...args);
|
|
2372
|
-
for (const key of properties) {
|
|
2373
|
-
const existing = Object.getOwnPropertyDescriptor(this, key);
|
|
2374
|
-
Object.defineProperty(this, key, Object.assign(existing || {}, descriptor));
|
|
2375
|
-
}
|
|
2376
|
-
}
|
|
2377
|
-
};
|
|
2378
|
-
};
|
|
2379
|
-
}, {
|
|
2569
|
+
const descriptor = Object.assign(descriptorBase, {
|
|
2380
2570
|
/**
|
|
2381
2571
|
* enumerable: true
|
|
2382
2572
|
*/
|
|
2383
2573
|
get enumerable() {
|
|
2384
|
-
return
|
|
2574
|
+
return descriptorBase({ enumerable: true });
|
|
2385
2575
|
},
|
|
2386
2576
|
/**
|
|
2387
2577
|
* enumerable: false
|
|
2388
2578
|
*/
|
|
2389
2579
|
get hidden() {
|
|
2390
|
-
return
|
|
2580
|
+
return descriptorBase({ enumerable: false });
|
|
2391
2581
|
},
|
|
2392
2582
|
/**
|
|
2393
2583
|
* configurable: true
|
|
2394
2584
|
*/
|
|
2395
2585
|
get configurable() {
|
|
2396
|
-
return
|
|
2586
|
+
return descriptorBase({ configurable: true });
|
|
2397
2587
|
},
|
|
2398
2588
|
/**
|
|
2399
2589
|
* configurable: false
|
|
2400
2590
|
*/
|
|
2401
2591
|
get frozen() {
|
|
2402
|
-
return
|
|
2592
|
+
return descriptorBase({ configurable: false });
|
|
2403
2593
|
},
|
|
2404
2594
|
/**
|
|
2405
2595
|
* writable: true
|
|
2406
2596
|
*/
|
|
2407
2597
|
get writable() {
|
|
2408
|
-
return
|
|
2598
|
+
return descriptorBase({ writable: true });
|
|
2409
2599
|
},
|
|
2410
2600
|
/**
|
|
2411
2601
|
* writable: false
|
|
2412
2602
|
*/
|
|
2413
2603
|
get readonly() {
|
|
2414
|
-
return
|
|
2604
|
+
return descriptorBase({ writable: false });
|
|
2415
2605
|
},
|
|
2416
2606
|
});
|
|
2417
2607
|
/**
|
|
@@ -2540,26 +2730,27 @@ function throttle(delay) {
|
|
|
2540
2730
|
});
|
|
2541
2731
|
}
|
|
2542
2732
|
|
|
2543
|
-
var version$1 = "1.0.
|
|
2733
|
+
var version$1 = "1.0.14";
|
|
2544
2734
|
var pkg = {
|
|
2545
2735
|
version: version$1};
|
|
2546
2736
|
|
|
2547
2737
|
const { version } = pkg;
|
|
2548
2738
|
const GLOBAL_MUTTS_KEY = '__MUTTS_INSTANCE__';
|
|
2739
|
+
const runtimeGlobals = globalThis;
|
|
2549
2740
|
const globalScope = (typeof globalThis !== 'undefined'
|
|
2550
2741
|
? globalThis
|
|
2551
|
-
:
|
|
2552
|
-
? window
|
|
2553
|
-
:
|
|
2554
|
-
? global
|
|
2742
|
+
: runtimeGlobals.window
|
|
2743
|
+
? runtimeGlobals.window
|
|
2744
|
+
: runtimeGlobals.global
|
|
2745
|
+
? runtimeGlobals.global
|
|
2555
2746
|
: false);
|
|
2556
2747
|
if (globalScope) {
|
|
2557
2748
|
let source = 'mutts/index';
|
|
2558
2749
|
try {
|
|
2559
|
-
if (
|
|
2560
|
-
source = __filename;
|
|
2561
|
-
else if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunks/index-
|
|
2562
|
-
source = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunks/index-
|
|
2750
|
+
if (runtimeGlobals.__filename)
|
|
2751
|
+
source = runtimeGlobals.__filename;
|
|
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-BnTNC9eC.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-BnTNC9eC.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-BnTNC9eC.cjs', document.baseURI).href));
|
|
2563
2754
|
}
|
|
2564
2755
|
}
|
|
2565
2756
|
catch (_e) { }
|
|
@@ -2609,4 +2800,4 @@ exports.throttle = throttle;
|
|
|
2609
2800
|
exports.unreactive = unreactive;
|
|
2610
2801
|
exports.watch = watch;
|
|
2611
2802
|
exports.when = when;
|
|
2612
|
-
//# sourceMappingURL=index-
|
|
2803
|
+
//# sourceMappingURL=index-BnTNC9eC.cjs.map
|