mutts 1.0.3 → 1.0.5
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 +1 -1
- package/dist/chunks/{index-HNVqPzjz.js → index-Cvxdw6Ax.js} +230 -61
- package/dist/chunks/index-Cvxdw6Ax.js.map +1 -0
- package/dist/chunks/{index-DzUDtFc7.esm.js → index-qiWwozOc.esm.js} +228 -62
- package/dist/chunks/index-qiWwozOc.esm.js.map +1 -0
- package/dist/destroyable.esm.js.map +1 -1
- package/dist/destroyable.js.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/mutts.umd.js +1 -1
- 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/reactive.d.ts +30 -1
- package/dist/reactive.esm.js +1 -1
- package/dist/reactive.js +4 -1
- package/dist/reactive.js.map +1 -1
- package/dist/std-decorators.esm.js.map +1 -1
- package/dist/std-decorators.js.map +1 -1
- package/docs/reactive/core.md +16 -16
- package/docs/reactive.md +7 -0
- package/package.json +1 -1
- package/src/destroyable.ts +2 -2
- package/src/reactive/array.ts +3 -5
- package/src/reactive/change.ts +6 -2
- package/src/reactive/effects.ts +132 -51
- package/src/reactive/index.ts +3 -1
- package/src/reactive/interface.ts +1 -1
- package/src/reactive/map.ts +6 -6
- package/src/reactive/mapped.ts +2 -3
- package/src/reactive/project.ts +103 -6
- package/src/reactive/proxy.ts +5 -1
- package/src/reactive/set.ts +6 -6
- package/src/reactive/types.ts +22 -0
- package/src/reactive/zone.ts +1 -1
- package/src/std-decorators.ts +1 -1
- package/dist/chunks/index-DzUDtFc7.esm.js.map +0 -1
- package/dist/chunks/index-HNVqPzjz.js.map +0 -1
- /package/{src/reactive/project.project.md → docs/reactive/project.md} +0 -0
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ npm install mutts
|
|
|
16
16
|
|
|
17
17
|
> [!TIP]
|
|
18
18
|
> **Are you an AI Agent?**
|
|
19
|
-
> If you are an LLM or autonomous agent trying to fix bugs or understand this codebase, please read the **[AI Agent Manual](./docs/ai.md)**.
|
|
19
|
+
> If you are an LLM or autonomous agent trying to fix bugs or understand this codebase, please read the **[AI Agent Manual](./docs/ai/manual.md)**.
|
|
20
20
|
> It contains structured protocols, error code definitions, and introspection API details designed specifically for you.
|
|
21
21
|
> A precise **[API Reference](./docs/ai/api-reference.md)** is also available for type lookups.
|
|
22
22
|
|
|
@@ -354,6 +354,10 @@ const prototypeForwarding = Symbol('prototype-forwarding');
|
|
|
354
354
|
* Symbol representing all properties in reactive tracking
|
|
355
355
|
*/
|
|
356
356
|
const allProps = Symbol('all-props');
|
|
357
|
+
/**
|
|
358
|
+
* Symbol for accessing projection information on reactive objects
|
|
359
|
+
*/
|
|
360
|
+
const projectionInfo = Symbol('projection-info');
|
|
357
361
|
// Symbol to mark functions with their root function
|
|
358
362
|
const rootFunction = Symbol('root-function');
|
|
359
363
|
/**
|
|
@@ -428,6 +432,12 @@ const options = {
|
|
|
428
432
|
* @default 100
|
|
429
433
|
*/
|
|
430
434
|
maxEffectChain: 100,
|
|
435
|
+
/**
|
|
436
|
+
* Maximum number of times an effect can be triggered by the same cause in a single batch
|
|
437
|
+
* Used to detect aggressive re-computation or infinite loops
|
|
438
|
+
* @default 10
|
|
439
|
+
*/
|
|
440
|
+
maxTriggerPerBatch: 10,
|
|
431
441
|
/**
|
|
432
442
|
* Debug purpose: maximum effect reaction (like call stack max depth)
|
|
433
443
|
* Used to prevent infinite loops
|
|
@@ -1260,6 +1270,50 @@ function formatRoots(roots, limit = 20) {
|
|
|
1260
1270
|
const end = names.slice(-10);
|
|
1261
1271
|
return `${start.join(' → ')} ... (${names.length - 15} more) ... ${end.join(' → ')}`;
|
|
1262
1272
|
}
|
|
1273
|
+
// Nested map structure for efficient counting and batch cleanup
|
|
1274
|
+
// batchId -> effect root -> obj -> prop -> count
|
|
1275
|
+
let activationRegistry;
|
|
1276
|
+
const activationLog = new Array(100);
|
|
1277
|
+
function getActivationLog() {
|
|
1278
|
+
return activationLog;
|
|
1279
|
+
}
|
|
1280
|
+
function recordActivation(effect, obj, evolution, prop) {
|
|
1281
|
+
const root = getRoot(effect);
|
|
1282
|
+
if (!activationRegistry)
|
|
1283
|
+
return;
|
|
1284
|
+
let effectData = activationRegistry.get(root);
|
|
1285
|
+
if (!effectData) {
|
|
1286
|
+
effectData = new Map();
|
|
1287
|
+
activationRegistry.set(root, effectData);
|
|
1288
|
+
}
|
|
1289
|
+
let objData = effectData.get(obj);
|
|
1290
|
+
if (!objData) {
|
|
1291
|
+
objData = new Map();
|
|
1292
|
+
effectData.set(obj, objData);
|
|
1293
|
+
}
|
|
1294
|
+
const count = (objData.get(prop) ?? 0) + 1;
|
|
1295
|
+
objData.set(prop, count);
|
|
1296
|
+
// Keep a limited history for diagnostics
|
|
1297
|
+
activationLog.unshift({
|
|
1298
|
+
effect,
|
|
1299
|
+
obj,
|
|
1300
|
+
evolution,
|
|
1301
|
+
prop,
|
|
1302
|
+
});
|
|
1303
|
+
activationLog.pop();
|
|
1304
|
+
if (count >= options.maxTriggerPerBatch) {
|
|
1305
|
+
const effectName = root?.name || 'anonymous';
|
|
1306
|
+
const message = `Aggressive trigger detected: effect "${effectName}" triggered ${count} times in the batch by the same cause.`;
|
|
1307
|
+
if (options.maxEffectReaction === 'throw') {
|
|
1308
|
+
throw new ReactiveError(message, {
|
|
1309
|
+
code: ReactiveErrorCode.MaxReactionExceeded,
|
|
1310
|
+
count,
|
|
1311
|
+
effect: effectName,
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
options.warn(`[reactive] ${message}`);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1263
1317
|
/**
|
|
1264
1318
|
* Registers a debug callback that is called when the current effect is triggered by a dependency change
|
|
1265
1319
|
*
|
|
@@ -1549,6 +1603,9 @@ function cleanupEffectFromGraph(effect) {
|
|
|
1549
1603
|
// Track currently executing effects to prevent re-execution
|
|
1550
1604
|
// These are all the effects triggered under `activeEffect`
|
|
1551
1605
|
let batchQueue;
|
|
1606
|
+
function hasBatched(effect) {
|
|
1607
|
+
return batchQueue?.all.has(getRoot(effect));
|
|
1608
|
+
}
|
|
1552
1609
|
const batchCleanups = new Set();
|
|
1553
1610
|
/**
|
|
1554
1611
|
* Computes and caches in-degrees for all effects in the batch
|
|
@@ -1955,21 +2012,29 @@ function batch(effect, immediate) {
|
|
|
1955
2012
|
addToBatch(effect[i], caller, immediate === 'immediate');
|
|
1956
2013
|
}
|
|
1957
2014
|
if (immediate) {
|
|
2015
|
+
const firstReturn = {};
|
|
1958
2016
|
// Execute immediately (before batch returns)
|
|
1959
2017
|
for (let i = 0; i < effect.length; i++) {
|
|
1960
2018
|
try {
|
|
1961
|
-
effect[i]();
|
|
2019
|
+
const rv = effect[i]();
|
|
2020
|
+
if (rv !== undefined && !('value' in firstReturn))
|
|
2021
|
+
firstReturn.value = rv;
|
|
1962
2022
|
}
|
|
1963
2023
|
finally {
|
|
1964
2024
|
const root = getRoot(effect[i]);
|
|
1965
2025
|
batchQueue.all.delete(root);
|
|
1966
2026
|
}
|
|
1967
2027
|
}
|
|
2028
|
+
return firstReturn.value;
|
|
1968
2029
|
}
|
|
1969
2030
|
// Otherwise, effects will be picked up in next executeNext() call
|
|
1970
2031
|
}
|
|
1971
2032
|
else {
|
|
1972
2033
|
// New batch - initialize
|
|
2034
|
+
if (!activationRegistry)
|
|
2035
|
+
activationRegistry = new Map();
|
|
2036
|
+
else
|
|
2037
|
+
throw new Error('Batch already in progress');
|
|
1973
2038
|
options.beginChain(roots);
|
|
1974
2039
|
batchQueue = {
|
|
1975
2040
|
all: new Map(),
|
|
@@ -2048,6 +2113,7 @@ function batch(effect, immediate) {
|
|
|
2048
2113
|
return firstReturn.value;
|
|
2049
2114
|
}
|
|
2050
2115
|
finally {
|
|
2116
|
+
activationRegistry = undefined;
|
|
2051
2117
|
batchQueue = undefined;
|
|
2052
2118
|
options.endChain();
|
|
2053
2119
|
}
|
|
@@ -2056,60 +2122,69 @@ function batch(effect, immediate) {
|
|
|
2056
2122
|
// Execute in dependency order
|
|
2057
2123
|
const firstReturn = {};
|
|
2058
2124
|
try {
|
|
2059
|
-
while
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
:
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2125
|
+
// Outer loop: continue while there are effects OR cleanups pending.
|
|
2126
|
+
// This ensures effects triggered by cleanups are not lost.
|
|
2127
|
+
while (batchQueue.all.size > 0 || batchCleanups.size > 0) {
|
|
2128
|
+
// Inner loop: execute all pending effects
|
|
2129
|
+
while (batchQueue.all.size > 0) {
|
|
2130
|
+
if (effectuatedRoots.length > options.maxEffectChain) {
|
|
2131
|
+
const cycle = findCycleInChain(effectuatedRoots);
|
|
2132
|
+
const trace = formatRoots(effectuatedRoots);
|
|
2133
|
+
const message = cycle
|
|
2134
|
+
? `Max effect chain reached (cycle detected: ${formatRoots(cycle)})`
|
|
2135
|
+
: `Max effect chain reached (trace: ${trace})`;
|
|
2136
|
+
const queuedRoots = batchQueue ? Array.from(batchQueue.all.keys()) : [];
|
|
2137
|
+
const queued = queuedRoots.map((r) => r.name || '<anonymous>');
|
|
2138
|
+
const debugInfo = {
|
|
2139
|
+
code: ReactiveErrorCode.MaxDepthExceeded,
|
|
2140
|
+
effectuatedRoots,
|
|
2141
|
+
cycle,
|
|
2142
|
+
trace,
|
|
2143
|
+
maxEffectChain: options.maxEffectChain,
|
|
2144
|
+
queued: queued.slice(0, 50),
|
|
2145
|
+
queuedCount: queued.length,
|
|
2146
|
+
// Try to get causation for the last effect
|
|
2147
|
+
causalChain: effectuatedRoots.length > 0
|
|
2148
|
+
? getTriggerChain(batchQueue.all.get(effectuatedRoots[effectuatedRoots.length - 1]))
|
|
2149
|
+
: [],
|
|
2150
|
+
};
|
|
2151
|
+
switch (options.maxEffectReaction) {
|
|
2152
|
+
case 'throw':
|
|
2153
|
+
throw new ReactiveError(`[reactive] ${message}`, debugInfo);
|
|
2154
|
+
case 'debug':
|
|
2155
|
+
// biome-ignore lint/suspicious/noDebugger: This is the whole point here
|
|
2156
|
+
debugger;
|
|
2157
|
+
throw new ReactiveError(`[reactive] ${message}`, debugInfo);
|
|
2158
|
+
case 'warn':
|
|
2159
|
+
options.warn(`[reactive] ${message} (queued: ${queued.slice(0, 10).join(', ')}${queued.length > 10 ? ', …' : ''})`);
|
|
2160
|
+
break;
|
|
2161
|
+
}
|
|
2091
2162
|
}
|
|
2163
|
+
const rv = executeNext(effectuatedRoots);
|
|
2164
|
+
// executeNext() returns null when batch is complete or cycle detected (throws error)
|
|
2165
|
+
// But functions can legitimately return null, so we check batchQueue.all.size instead
|
|
2166
|
+
if (batchQueue.all.size === 0) {
|
|
2167
|
+
// Batch complete
|
|
2168
|
+
break;
|
|
2169
|
+
}
|
|
2170
|
+
// If executeNext() returned null but batch is not empty, it means a cycle was detected
|
|
2171
|
+
// and an error was thrown, so we won't reach here
|
|
2172
|
+
if (rv !== undefined && !('value' in firstReturn))
|
|
2173
|
+
firstReturn.value = rv;
|
|
2174
|
+
// Note: executeNext() already removed it from batchQueue, so we track by count
|
|
2092
2175
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2176
|
+
// Process cleanups. If they trigger new effects, the outer loop will catch them.
|
|
2177
|
+
if (batchCleanups.size > 0) {
|
|
2178
|
+
const cleanups = Array.from(batchCleanups);
|
|
2179
|
+
batchCleanups.clear();
|
|
2180
|
+
for (const cleanup of cleanups)
|
|
2181
|
+
cleanup();
|
|
2099
2182
|
}
|
|
2100
|
-
// If executeNext() returned null but batch is not empty, it means a cycle was detected
|
|
2101
|
-
// and an error was thrown, so we won't reach here
|
|
2102
|
-
if (rv !== undefined && !('value' in firstReturn))
|
|
2103
|
-
firstReturn.value = rv;
|
|
2104
|
-
// Note: executeNext() already removed it from batchQueue, so we track by count
|
|
2105
2183
|
}
|
|
2106
|
-
const cleanups = Array.from(batchCleanups);
|
|
2107
|
-
batchCleanups.clear();
|
|
2108
|
-
for (const cleanup of cleanups)
|
|
2109
|
-
cleanup();
|
|
2110
2184
|
return firstReturn.value;
|
|
2111
2185
|
}
|
|
2112
2186
|
finally {
|
|
2187
|
+
activationRegistry = undefined;
|
|
2113
2188
|
batchQueue = undefined;
|
|
2114
2189
|
options.endChain();
|
|
2115
2190
|
}
|
|
@@ -2479,7 +2554,11 @@ function collectEffects(obj, evolution, effects, objectWatchers, ...keyChains) {
|
|
|
2479
2554
|
options.skipRunningEffect(effect, runningChain);
|
|
2480
2555
|
continue;
|
|
2481
2556
|
}
|
|
2482
|
-
effects.
|
|
2557
|
+
if (!effects.has(effect)) {
|
|
2558
|
+
effects.add(effect);
|
|
2559
|
+
if (!hasBatched(effect))
|
|
2560
|
+
recordActivation(effect, obj, evolution, key);
|
|
2561
|
+
}
|
|
2483
2562
|
const trackers = effectTrackers.get(effect);
|
|
2484
2563
|
recordTriggerLink(sourceEffect, effect, obj, key, evolution);
|
|
2485
2564
|
if (trackers) {
|
|
@@ -2547,6 +2626,7 @@ function touchedOpaque(obj, evolution, prop) {
|
|
|
2547
2626
|
continue;
|
|
2548
2627
|
}
|
|
2549
2628
|
effects.add(effect);
|
|
2629
|
+
recordActivation(effect, obj, evolution, prop);
|
|
2550
2630
|
const trackers = effectTrackers.get(effect);
|
|
2551
2631
|
recordTriggerLink(sourceEffect, effect, obj, prop, evolution);
|
|
2552
2632
|
if (trackers) {
|
|
@@ -2866,7 +2946,11 @@ const reactiveHandlers = {
|
|
|
2866
2946
|
dependant(current, prop);
|
|
2867
2947
|
if (Object.hasOwn(current, prop))
|
|
2868
2948
|
break;
|
|
2869
|
-
|
|
2949
|
+
let next = reactiveObject(Object.getPrototypeOf(current));
|
|
2950
|
+
if (next === current) {
|
|
2951
|
+
next = reactiveObject(Object.getPrototypeOf(unwrap(current)));
|
|
2952
|
+
}
|
|
2953
|
+
current = next;
|
|
2870
2954
|
}
|
|
2871
2955
|
}
|
|
2872
2956
|
const value = decorator.ReflectGet(obj, prop, receiver);
|
|
@@ -3331,7 +3415,6 @@ function* makeReactiveEntriesIterator(iterator) {
|
|
|
3331
3415
|
const native$2 = Symbol('native');
|
|
3332
3416
|
const isArray = Array.isArray;
|
|
3333
3417
|
Array.isArray = ((value) => isArray(value) ||
|
|
3334
|
-
// biome-ignore lint/suspicious/useIsArray: We are defining it
|
|
3335
3418
|
(value &&
|
|
3336
3419
|
typeof value === 'object' &&
|
|
3337
3420
|
prototypeForwarding in value &&
|
|
@@ -4227,6 +4310,17 @@ function register(keyFn, initial) {
|
|
|
4227
4310
|
return new RegisterClass(keyFn, initial);
|
|
4228
4311
|
}
|
|
4229
4312
|
|
|
4313
|
+
/**
|
|
4314
|
+
* Maps projection effects (item effects) to their projection context
|
|
4315
|
+
*/
|
|
4316
|
+
const effectProjectionMetadata = new WeakMap();
|
|
4317
|
+
/**
|
|
4318
|
+
* Returns the projection context of the currently running effect, if any.
|
|
4319
|
+
*/
|
|
4320
|
+
function getActiveProjection() {
|
|
4321
|
+
const active = getActiveEffect();
|
|
4322
|
+
return active ? effectProjectionMetadata.get(active) : undefined;
|
|
4323
|
+
}
|
|
4230
4324
|
function defineAccessValue(access) {
|
|
4231
4325
|
Object.defineProperty(access, 'value', {
|
|
4232
4326
|
get: access.get,
|
|
@@ -4235,7 +4329,15 @@ function defineAccessValue(access) {
|
|
|
4235
4329
|
enumerable: true,
|
|
4236
4330
|
});
|
|
4237
4331
|
}
|
|
4238
|
-
function makeCleanup(target, effectMap, onDispose) {
|
|
4332
|
+
function makeCleanup(target, effectMap, onDispose, metadata) {
|
|
4333
|
+
if (metadata) {
|
|
4334
|
+
Object.defineProperty(target, projectionInfo, {
|
|
4335
|
+
value: metadata,
|
|
4336
|
+
writable: false,
|
|
4337
|
+
enumerable: false,
|
|
4338
|
+
configurable: true,
|
|
4339
|
+
});
|
|
4340
|
+
}
|
|
4239
4341
|
return cleanedBy(target, () => {
|
|
4240
4342
|
onDispose();
|
|
4241
4343
|
for (const stop of effectMap.values())
|
|
@@ -4258,6 +4360,8 @@ function projectArray(source, apply) {
|
|
|
4258
4360
|
Reflect.deleteProperty(target, index);
|
|
4259
4361
|
}
|
|
4260
4362
|
}
|
|
4363
|
+
const parent = getActiveProjection();
|
|
4364
|
+
const depth = parent ? parent.depth + 1 : 0;
|
|
4261
4365
|
const cleanupLength = effect(function projectArrayLengthEffect({ ascend }) {
|
|
4262
4366
|
const length = observedSource.length;
|
|
4263
4367
|
normalizeTargetLength(length);
|
|
@@ -4280,6 +4384,14 @@ function projectArray(source, apply) {
|
|
|
4280
4384
|
const produced = apply(accessBase, target);
|
|
4281
4385
|
target[index] = produced;
|
|
4282
4386
|
});
|
|
4387
|
+
setEffectName(stop, `project[${depth}]:${index}`);
|
|
4388
|
+
effectProjectionMetadata.set(stop, {
|
|
4389
|
+
source: observedSource,
|
|
4390
|
+
key: index,
|
|
4391
|
+
target,
|
|
4392
|
+
depth,
|
|
4393
|
+
parent,
|
|
4394
|
+
});
|
|
4283
4395
|
indexEffects.set(i, stop);
|
|
4284
4396
|
});
|
|
4285
4397
|
}
|
|
@@ -4287,7 +4399,13 @@ function projectArray(source, apply) {
|
|
|
4287
4399
|
if (index >= length)
|
|
4288
4400
|
disposeIndex(index);
|
|
4289
4401
|
});
|
|
4290
|
-
return makeCleanup(target, indexEffects, () => cleanupLength()
|
|
4402
|
+
return makeCleanup(target, indexEffects, () => cleanupLength(), {
|
|
4403
|
+
source: observedSource,
|
|
4404
|
+
target,
|
|
4405
|
+
apply,
|
|
4406
|
+
depth,
|
|
4407
|
+
parent,
|
|
4408
|
+
});
|
|
4291
4409
|
}
|
|
4292
4410
|
function projectRegister(source, apply) {
|
|
4293
4411
|
const observedSource = reactive(source);
|
|
@@ -4302,6 +4420,8 @@ function projectRegister(source, apply) {
|
|
|
4302
4420
|
target.delete(key);
|
|
4303
4421
|
}
|
|
4304
4422
|
}
|
|
4423
|
+
const parent = getActiveProjection();
|
|
4424
|
+
const depth = parent ? parent.depth + 1 : 0;
|
|
4305
4425
|
const cleanupKeys = effect(function projectRegisterEffect({ ascend }) {
|
|
4306
4426
|
const keys = new Set();
|
|
4307
4427
|
for (const key of observedSource.mapKeys())
|
|
@@ -4326,6 +4446,14 @@ function projectRegister(source, apply) {
|
|
|
4326
4446
|
const produced = apply(accessBase, target);
|
|
4327
4447
|
target.set(key, produced);
|
|
4328
4448
|
});
|
|
4449
|
+
setEffectName(stop, `project[${depth}]:${String(key)}`);
|
|
4450
|
+
effectProjectionMetadata.set(stop, {
|
|
4451
|
+
source: observedSource,
|
|
4452
|
+
key,
|
|
4453
|
+
target,
|
|
4454
|
+
depth,
|
|
4455
|
+
parent,
|
|
4456
|
+
});
|
|
4329
4457
|
keyEffects.set(key, stop);
|
|
4330
4458
|
});
|
|
4331
4459
|
}
|
|
@@ -4333,7 +4461,13 @@ function projectRegister(source, apply) {
|
|
|
4333
4461
|
if (!keys.has(key))
|
|
4334
4462
|
disposeKey(key);
|
|
4335
4463
|
});
|
|
4336
|
-
return makeCleanup(target, keyEffects, () => cleanupKeys()
|
|
4464
|
+
return makeCleanup(target, keyEffects, () => cleanupKeys(), {
|
|
4465
|
+
source: observedSource,
|
|
4466
|
+
target,
|
|
4467
|
+
apply,
|
|
4468
|
+
depth,
|
|
4469
|
+
parent,
|
|
4470
|
+
});
|
|
4337
4471
|
}
|
|
4338
4472
|
function projectRecord(source, apply) {
|
|
4339
4473
|
const observedSource = reactive(source);
|
|
@@ -4347,6 +4481,8 @@ function projectRecord(source, apply) {
|
|
|
4347
4481
|
Reflect.deleteProperty(target, key);
|
|
4348
4482
|
}
|
|
4349
4483
|
}
|
|
4484
|
+
const parent = getActiveProjection();
|
|
4485
|
+
const depth = parent ? parent.depth + 1 : 0;
|
|
4350
4486
|
const cleanupKeys = effect(function projectRecordEffect({ ascend }) {
|
|
4351
4487
|
const keys = new Set();
|
|
4352
4488
|
for (const key in observedSource)
|
|
@@ -4372,6 +4508,14 @@ function projectRecord(source, apply) {
|
|
|
4372
4508
|
const produced = apply(accessBase, target);
|
|
4373
4509
|
target[sourceKey] = produced;
|
|
4374
4510
|
});
|
|
4511
|
+
setEffectName(stop, `project[${depth}]:${String(key)}`);
|
|
4512
|
+
effectProjectionMetadata.set(stop, {
|
|
4513
|
+
source: observedSource,
|
|
4514
|
+
key,
|
|
4515
|
+
target,
|
|
4516
|
+
depth,
|
|
4517
|
+
parent,
|
|
4518
|
+
});
|
|
4375
4519
|
keyEffects.set(key, stop);
|
|
4376
4520
|
});
|
|
4377
4521
|
}
|
|
@@ -4379,7 +4523,13 @@ function projectRecord(source, apply) {
|
|
|
4379
4523
|
if (!keys.has(key))
|
|
4380
4524
|
disposeKey(key);
|
|
4381
4525
|
});
|
|
4382
|
-
return makeCleanup(target, keyEffects, () => cleanupKeys()
|
|
4526
|
+
return makeCleanup(target, keyEffects, () => cleanupKeys(), {
|
|
4527
|
+
source: observedSource,
|
|
4528
|
+
target,
|
|
4529
|
+
apply,
|
|
4530
|
+
depth,
|
|
4531
|
+
parent,
|
|
4532
|
+
});
|
|
4383
4533
|
}
|
|
4384
4534
|
function projectMap(source, apply) {
|
|
4385
4535
|
const observedSource = reactive(source);
|
|
@@ -4394,6 +4544,8 @@ function projectMap(source, apply) {
|
|
|
4394
4544
|
target.delete(key);
|
|
4395
4545
|
}
|
|
4396
4546
|
}
|
|
4547
|
+
const parent = getActiveProjection();
|
|
4548
|
+
const depth = parent ? parent.depth + 1 : 0;
|
|
4397
4549
|
const cleanupKeys = effect(function projectMapEffect({ ascend }) {
|
|
4398
4550
|
const keys = new Set();
|
|
4399
4551
|
for (const key of observedSource.keys())
|
|
@@ -4418,6 +4570,14 @@ function projectMap(source, apply) {
|
|
|
4418
4570
|
const produced = apply(accessBase, target);
|
|
4419
4571
|
target.set(key, produced);
|
|
4420
4572
|
});
|
|
4573
|
+
setEffectName(stop, `project[${depth}]:${String(key)}`);
|
|
4574
|
+
effectProjectionMetadata.set(stop, {
|
|
4575
|
+
source: observedSource,
|
|
4576
|
+
key,
|
|
4577
|
+
target,
|
|
4578
|
+
depth,
|
|
4579
|
+
parent,
|
|
4580
|
+
});
|
|
4421
4581
|
keyEffects.set(key, stop);
|
|
4422
4582
|
});
|
|
4423
4583
|
}
|
|
@@ -4425,7 +4585,13 @@ function projectMap(source, apply) {
|
|
|
4425
4585
|
if (!keys.has(key))
|
|
4426
4586
|
disposeKey(key);
|
|
4427
4587
|
});
|
|
4428
|
-
return makeCleanup(target, keyEffects, () => cleanupKeys()
|
|
4588
|
+
return makeCleanup(target, keyEffects, () => cleanupKeys(), {
|
|
4589
|
+
source: observedSource,
|
|
4590
|
+
target,
|
|
4591
|
+
apply,
|
|
4592
|
+
depth,
|
|
4593
|
+
parent,
|
|
4594
|
+
});
|
|
4429
4595
|
}
|
|
4430
4596
|
function projectCore(source, apply) {
|
|
4431
4597
|
if (Array.isArray(source))
|
|
@@ -4573,7 +4739,7 @@ class ReactiveWeakMap {
|
|
|
4573
4739
|
Object.defineProperties(this, {
|
|
4574
4740
|
[native$1]: { value: original },
|
|
4575
4741
|
[prototypeForwarding]: { value: original },
|
|
4576
|
-
content: { value: Symbol('
|
|
4742
|
+
content: { value: Symbol('WeakMapContent') },
|
|
4577
4743
|
[Symbol.toStringTag]: { value: 'ReactiveWeakMap' },
|
|
4578
4744
|
});
|
|
4579
4745
|
}
|
|
@@ -4613,7 +4779,7 @@ class ReactiveMap {
|
|
|
4613
4779
|
Object.defineProperties(this, {
|
|
4614
4780
|
[native$1]: { value: original },
|
|
4615
4781
|
[prototypeForwarding]: { value: original },
|
|
4616
|
-
content: { value: Symbol('
|
|
4782
|
+
content: { value: Symbol('MapContent') },
|
|
4617
4783
|
[Symbol.toStringTag]: { value: 'ReactiveMap' },
|
|
4618
4784
|
});
|
|
4619
4785
|
}
|
|
@@ -4708,7 +4874,7 @@ class ReactiveWeakSet {
|
|
|
4708
4874
|
Object.defineProperties(this, {
|
|
4709
4875
|
[native]: { value: original },
|
|
4710
4876
|
[prototypeForwarding]: { value: original },
|
|
4711
|
-
content: { value: Symbol('
|
|
4877
|
+
content: { value: Symbol('WeakSetContent') },
|
|
4712
4878
|
[Symbol.toStringTag]: { value: 'ReactiveWeakSet' },
|
|
4713
4879
|
});
|
|
4714
4880
|
}
|
|
@@ -4743,7 +4909,7 @@ class ReactiveSet {
|
|
|
4743
4909
|
Object.defineProperties(this, {
|
|
4744
4910
|
[native]: { value: original },
|
|
4745
4911
|
[prototypeForwarding]: { value: original },
|
|
4746
|
-
content: { value: Symbol('
|
|
4912
|
+
content: { value: Symbol('SetContent') },
|
|
4747
4913
|
[Symbol.toStringTag]: { value: 'ReactiveSet' },
|
|
4748
4914
|
});
|
|
4749
4915
|
}
|
|
@@ -4847,6 +5013,7 @@ exports.ReadOnlyError = ReadOnlyError;
|
|
|
4847
5013
|
exports.Register = Register;
|
|
4848
5014
|
exports.addBatchCleanup = addBatchCleanup;
|
|
4849
5015
|
exports.atomic = atomic;
|
|
5016
|
+
exports.batch = batch;
|
|
4850
5017
|
exports.biDi = biDi;
|
|
4851
5018
|
exports.buildReactivityGraph = buildReactivityGraph;
|
|
4852
5019
|
exports.cleanedBy = cleanedBy;
|
|
@@ -4856,7 +5023,9 @@ exports.defer = defer;
|
|
|
4856
5023
|
exports.derived = derived;
|
|
4857
5024
|
exports.effect = effect;
|
|
4858
5025
|
exports.enableDevTools = enableDevTools;
|
|
5026
|
+
exports.getActivationLog = getActivationLog;
|
|
4859
5027
|
exports.getActiveEffect = getActiveEffect;
|
|
5028
|
+
exports.getActiveProjection = getActiveProjection;
|
|
4860
5029
|
exports.getState = getState;
|
|
4861
5030
|
exports.immutables = immutables;
|
|
4862
5031
|
exports.isDevtoolsEnabled = isDevtoolsEnabled;
|
|
@@ -4888,4 +5057,4 @@ exports.unreactive = unreactive;
|
|
|
4888
5057
|
exports.untracked = untracked;
|
|
4889
5058
|
exports.unwrap = unwrap;
|
|
4890
5059
|
exports.watch = watch;
|
|
4891
|
-
//# sourceMappingURL=index-
|
|
5060
|
+
//# sourceMappingURL=index-Cvxdw6Ax.js.map
|