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.
Files changed (40) hide show
  1. package/README.md +1 -1
  2. package/dist/chunks/{index-HNVqPzjz.js → index-Cvxdw6Ax.js} +230 -61
  3. package/dist/chunks/index-Cvxdw6Ax.js.map +1 -0
  4. package/dist/chunks/{index-DzUDtFc7.esm.js → index-qiWwozOc.esm.js} +228 -62
  5. package/dist/chunks/index-qiWwozOc.esm.js.map +1 -0
  6. package/dist/destroyable.esm.js.map +1 -1
  7. package/dist/destroyable.js.map +1 -1
  8. package/dist/index.esm.js +1 -1
  9. package/dist/index.js +4 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/mutts.umd.js +1 -1
  12. package/dist/mutts.umd.js.map +1 -1
  13. package/dist/mutts.umd.min.js +1 -1
  14. package/dist/mutts.umd.min.js.map +1 -1
  15. package/dist/reactive.d.ts +30 -1
  16. package/dist/reactive.esm.js +1 -1
  17. package/dist/reactive.js +4 -1
  18. package/dist/reactive.js.map +1 -1
  19. package/dist/std-decorators.esm.js.map +1 -1
  20. package/dist/std-decorators.js.map +1 -1
  21. package/docs/reactive/core.md +16 -16
  22. package/docs/reactive.md +7 -0
  23. package/package.json +1 -1
  24. package/src/destroyable.ts +2 -2
  25. package/src/reactive/array.ts +3 -5
  26. package/src/reactive/change.ts +6 -2
  27. package/src/reactive/effects.ts +132 -51
  28. package/src/reactive/index.ts +3 -1
  29. package/src/reactive/interface.ts +1 -1
  30. package/src/reactive/map.ts +6 -6
  31. package/src/reactive/mapped.ts +2 -3
  32. package/src/reactive/project.ts +103 -6
  33. package/src/reactive/proxy.ts +5 -1
  34. package/src/reactive/set.ts +6 -6
  35. package/src/reactive/types.ts +22 -0
  36. package/src/reactive/zone.ts +1 -1
  37. package/src/std-decorators.ts +1 -1
  38. package/dist/chunks/index-DzUDtFc7.esm.js.map +0 -1
  39. package/dist/chunks/index-HNVqPzjz.js.map +0 -1
  40. /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 (batchQueue.all.size > 0) {
2060
- if (effectuatedRoots.length > options.maxEffectChain) {
2061
- const cycle = findCycleInChain(effectuatedRoots);
2062
- const trace = formatRoots(effectuatedRoots);
2063
- const message = cycle
2064
- ? `Max effect chain reached (cycle detected: ${formatRoots(cycle)})`
2065
- : `Max effect chain reached (trace: ${trace})`;
2066
- const queuedRoots = batchQueue ? Array.from(batchQueue.all.keys()) : [];
2067
- const queued = queuedRoots.map((r) => r.name || '<anonymous>');
2068
- const debugInfo = {
2069
- code: ReactiveErrorCode.MaxDepthExceeded,
2070
- effectuatedRoots,
2071
- cycle,
2072
- trace,
2073
- maxEffectChain: options.maxEffectChain,
2074
- queued: queued.slice(0, 50),
2075
- queuedCount: queued.length,
2076
- // Try to get causation for the last effect
2077
- causalChain: effectuatedRoots.length > 0
2078
- ? getTriggerChain(batchQueue.all.get(effectuatedRoots[effectuatedRoots.length - 1]))
2079
- : [],
2080
- };
2081
- switch (options.maxEffectReaction) {
2082
- case 'throw':
2083
- throw new ReactiveError(`[reactive] ${message}`, debugInfo);
2084
- case 'debug':
2085
- // biome-ignore lint/suspicious/noDebugger: This is the whole point here
2086
- debugger;
2087
- throw new ReactiveError(`[reactive] ${message}`, debugInfo);
2088
- case 'warn':
2089
- options.warn(`[reactive] ${message} (queued: ${queued.slice(0, 10).join(', ')}${queued.length > 10 ? ', …' : ''})`);
2090
- break;
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
- const rv = executeNext(effectuatedRoots);
2094
- // executeNext() returns null when batch is complete or cycle detected (throws error)
2095
- // But functions can legitimately return null, so we check batchQueue.all.size instead
2096
- if (batchQueue.all.size === 0) {
2097
- // Batch complete
2098
- break;
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.add(effect);
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
- current = reactiveObject(Object.getPrototypeOf(current));
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('content') },
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('content') },
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('content') },
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('content') },
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-HNVqPzjz.js.map
5060
+ //# sourceMappingURL=index-Cvxdw6Ax.js.map