mutts 1.0.12 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +5 -2
  2. package/dist/browser.cjs +7 -3
  3. package/dist/browser.cjs.map +1 -1
  4. package/dist/browser.d.ts +1407 -2
  5. package/dist/browser.dev.cjs +7 -3
  6. package/dist/browser.dev.cjs.map +1 -1
  7. package/dist/browser.dev.d.ts +2 -2
  8. package/dist/browser.dev.esm.js +2 -2
  9. package/dist/browser.esm.js +3 -3
  10. package/dist/chunks/{index-yK0HVxHv.cjs → index-CAdnMJev.cjs} +202 -79
  11. package/dist/chunks/index-CAdnMJev.cjs.map +1 -0
  12. package/dist/chunks/{index-BUop6B2U.esm.js → index-XsYTUhHx.esm.js} +200 -77
  13. package/dist/chunks/index-XsYTUhHx.esm.js.map +1 -0
  14. package/dist/chunks/{node-Dd0esp5F.cjs → node-DrrphEPf.cjs} +2 -2
  15. package/dist/chunks/{node-Dd0esp5F.cjs.map → node-DrrphEPf.cjs.map} +1 -1
  16. package/dist/chunks/{node-Bo7WU5S2.esm.js → node-NEZvVo4M.esm.js} +2 -2
  17. package/dist/chunks/{node-Bo7WU5S2.esm.js.map → node-NEZvVo4M.esm.js.map} +1 -1
  18. package/dist/chunks/{proxy-D2C49sXH.esm.js → proxy-BtmPFjSr.esm.js} +307 -66
  19. package/dist/chunks/proxy-BtmPFjSr.esm.js.map +1 -0
  20. package/dist/chunks/{proxy-BvM4yewA.cjs → proxy-DBHj3kGK.cjs} +313 -66
  21. package/dist/chunks/proxy-DBHj3kGK.cjs.map +1 -0
  22. package/dist/debug.cjs +537 -166
  23. package/dist/debug.cjs.map +1 -1
  24. package/dist/debug.d.ts +96 -80
  25. package/dist/debug.esm.js +533 -166
  26. package/dist/debug.esm.js.map +1 -1
  27. package/dist/devtools/panel.js.map +1 -1
  28. package/dist/mutts.umd.js +508 -140
  29. package/dist/mutts.umd.js.map +1 -1
  30. package/dist/mutts.umd.min.js +1 -1
  31. package/dist/mutts.umd.min.js.map +1 -1
  32. package/dist/node.cjs +8 -4
  33. package/dist/node.cjs.map +1 -1
  34. package/dist/node.d.ts +2 -2
  35. package/dist/node.dev.cjs +8 -4
  36. package/dist/node.dev.cjs.map +1 -1
  37. package/dist/node.dev.d.ts +2 -2
  38. package/dist/node.dev.esm.js +3 -3
  39. package/dist/node.esm.js +3 -3
  40. package/dist/{types-Bx2PhORg.d.ts → types.d.ts} +12 -0
  41. package/docs/ai/api-reference.md +102 -12
  42. package/docs/ai/manual.md +60 -24
  43. package/docs/debug-getReason.md +161 -0
  44. package/docs/flavored.md +98 -1
  45. package/docs/reactive/advanced.md +15 -2
  46. package/docs/reactive/attend.md +32 -0
  47. package/docs/reactive/core.md +40 -6
  48. package/docs/reactive/debugging.md +25 -2
  49. package/docs/reactive.md +2 -0
  50. package/package.json +2 -3
  51. package/dist/chunks/index-BUop6B2U.esm.js.map +0 -1
  52. package/dist/chunks/index-yK0HVxHv.cjs.map +0 -1
  53. package/dist/chunks/proxy-BvM4yewA.cjs.map +0 -1
  54. package/dist/chunks/proxy-D2C49sXH.esm.js.map +0 -1
  55. package/dist/index.d.ts +0 -1322
package/dist/node.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- require('./chunks/node-Dd0esp5F.cjs');
4
- var index = require('./chunks/index-yK0HVxHv.cjs');
5
- var proxy = require('./chunks/proxy-BvM4yewA.cjs');
3
+ require('./chunks/node-DrrphEPf.cjs');
4
+ var index = require('./chunks/index-CAdnMJev.cjs');
5
+ var proxy = require('./chunks/proxy-DBHj3kGK.cjs');
6
6
  require('node:async_hooks');
7
7
 
8
8
 
@@ -34,7 +34,6 @@ exports.morph = index.morph;
34
34
  exports.organize = index.organize;
35
35
  exports.organized = index.organized;
36
36
  exports.profileInfo = index.profileInfo;
37
- exports.project = index.morph;
38
37
  exports.resource = index.resource;
39
38
  exports.setAt = index.setAt;
40
39
  exports.throttle = index.throttle;
@@ -42,6 +41,7 @@ exports.unreactive = index.unreactive;
42
41
  exports.watch = index.watch;
43
42
  exports.when = index.when;
44
43
  exports.AZone = proxy.AZone;
44
+ exports.CompareSymbol = proxy.CompareSymbol;
45
45
  exports.DecoratorError = proxy.DecoratorError;
46
46
  exports.IterableWeakMap = proxy.IterableWeakMap;
47
47
  exports.IterableWeakSet = proxy.IterableWeakSet;
@@ -64,6 +64,7 @@ exports.asyncZone = proxy.asyncZone;
64
64
  exports.atom = proxy.atom;
65
65
  exports.atomic = proxy.atomic;
66
66
  exports.biDi = proxy.biDi;
67
+ exports.captioned = proxy.captioned;
67
68
  exports.captured = proxy.captured;
68
69
  exports.caught = proxy.caught;
69
70
  exports.createFlavor = proxy.createFlavor;
@@ -74,6 +75,7 @@ exports.defer = proxy.defer;
74
75
  exports.devPreset = proxy.devPreset;
75
76
  exports.effect = proxy.effect;
76
77
  exports.effectAggregator = proxy.effectAggregator;
78
+ exports.effectContext = proxy.effectContext;
77
79
  exports.flavorOptions = proxy.flavorOptions;
78
80
  exports.flavored = proxy.flavored;
79
81
  exports.formatCleanupReason = proxy.formatCleanupReason;
@@ -81,6 +83,7 @@ exports.getActivationLog = proxy.getActivationLog;
81
83
  exports.getActiveEffect = proxy.getActiveEffect;
82
84
  exports.getState = proxy.getState;
83
85
  exports.hooks = proxy.hooks;
86
+ exports.inheritCaption = proxy.inheritCaption;
84
87
  exports.isConstructor = proxy.isConstructor;
85
88
  exports.isDev = proxy.isDev;
86
89
  exports.isNonReactive = proxy.isNonReactive;
@@ -107,5 +110,6 @@ exports.touched1 = proxy.touched1;
107
110
  exports.unlink = proxy.unlink;
108
111
  exports.untracked = proxy.untracked;
109
112
  exports.unwrap = proxy.unwrap;
113
+ exports.withEffectContext = proxy.withEffectContext;
110
114
  exports.zip = proxy.zip;
111
115
  //# sourceMappingURL=node.cjs.map
package/dist/node.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"node.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"node.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/node.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { ArrayDiffResult, ArrayReadForward, ContextManager, Decorator, DecoratorDescription, DecoratorError, DecoratorFactory, Destroyable, DestructionError, Eventful, EventsBase, GenericClassDecorator, Hook, Indexable, IterableWeakMap, IterableWeakSet, LegacyClassDecorator, LegacyPropertyDecorator, Memoizable, MemoizableArgument, MixinClass, MixinFunction, ModernAccessorDecorator, ModernClassDecorator, ModernGetterDecorator, ModernMethodDecorator, ModernSetterDecorator, PromiseChain, ReactiveBase, Resource, Restorer, addBatchCleanup, addUnreactiveProps, allocated, allocatedValues, arrayDiff, arrayEquals, assertUntracked, asyncHook, asyncHooks, atom, atomic, attend, biDi, cache, cached, callOnGC, captured, caught, chainPromise, createFlavor, debounce, decorator, deepCompare, deepWatch, defer, deprecated, descriptor, destructor, effect, effectAggregator, flavorOptions, flavored, forwardArray, getActivationLog, getActiveEffect, getAt, getState, hooks, isCached, isConstructor, isDev, isNonReactive, isObject, isProd, isTest, legacyDecorator, lift, link, memoize, mixin, modernDecorator, morph, named, onEffectThrow, organize, organized, profileInfo, morph as project, reactive, reset, resource, root, setAt, tag, throttle, touched, touched1, unlink, unreactive, untracked, watch, when, zip } from './index.js';
2
- export { A as AZone, C as CleanupReason, c as EffectAccess, b as EffectCleanup, d as EffectCloser, g as EffectOptions, E as EffectTrigger, a as Evolution, G as GetterWrapper, H as HistoryValue, P as PropTrigger, R as ReactiveError, h as ReactiveErrorCode, S as ScopedCallback, i as Zone, Z as ZoneAggregator, j as ZoneHistory, k as asyncZone, l as debugPreset, m as devPreset, n as formatCleanupReason, o as isReactive, p as objectToProxy, q as prodPreset, r as proxyToObject, s as reactiveOptions, u as unwrap } from './types-Bx2PhORg.js';
1
+ export { ArrayDiffResult, ArrayReadForward, Captioned, CompareSymbol, ContextManager, Decorator, DecoratorDescription, DecoratorError, DecoratorFactory, Destroyable, DestructionError, EffectContext, Eventful, EventsBase, GenericClassDecorator, Hook, Indexable, IterableWeakMap, IterableWeakSet, LegacyClassDecorator, LegacyPropertyDecorator, Memoizable, MemoizableArgument, MixinClass, MixinFunction, ModernAccessorDecorator, ModernClassDecorator, ModernGetterDecorator, ModernMethodDecorator, ModernSetterDecorator, PromiseChain, ReactiveBase, Resource, Restorer, addBatchCleanup, addUnreactiveProps, allocated, allocatedValues, arrayDiff, arrayEquals, assertUntracked, asyncHook, asyncHooks, atom, atomic, attend, biDi, cache, cached, callOnGC, captioned, captured, caught, chainPromise, createFlavor, debounce, decorator, deepCompare, deepWatch, defer, deprecated, descriptor, destructor, effect, effectAggregator, effectContext, flavorOptions, flavored, forwardArray, getActivationLog, getActiveEffect, getAt, getState, hooks, inheritCaption, isCached, isConstructor, isDev, isNonReactive, isObject, isProd, isTest, legacyDecorator, lift, link, memoize, mixin, modernDecorator, morph, named, onEffectThrow, organize, organized, profileInfo, reactive, reset, resource, root, setAt, tag, throttle, touched, touched1, unlink, unreactive, untracked, watch, when, withEffectContext, zip } from './browser.js';
2
+ export { A as AZone, C as CleanupReason, c as EffectAccess, b as EffectCleanup, d as EffectCloser, g as EffectOptions, E as EffectTrigger, a as Evolution, G as GetterWrapper, H as HistoryValue, P as PropTrigger, R as ReactiveError, h as ReactiveErrorCode, S as ScopedCallback, i as Zone, Z as ZoneAggregator, j as ZoneHistory, k as asyncZone, l as debugPreset, m as devPreset, n as formatCleanupReason, o as isReactive, p as objectToProxy, q as prodPreset, r as proxyToObject, s as reactiveOptions, u as unwrap } from './types.js';
package/dist/node.dev.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  require('./debug.cjs');
4
- require('./chunks/node-Dd0esp5F.cjs');
5
- var index = require('./chunks/index-yK0HVxHv.cjs');
6
- var proxy = require('./chunks/proxy-BvM4yewA.cjs');
4
+ require('./chunks/node-DrrphEPf.cjs');
5
+ var index = require('./chunks/index-CAdnMJev.cjs');
6
+ var proxy = require('./chunks/proxy-DBHj3kGK.cjs');
7
7
  require('node:async_hooks');
8
8
 
9
9
 
@@ -35,7 +35,6 @@ exports.morph = index.morph;
35
35
  exports.organize = index.organize;
36
36
  exports.organized = index.organized;
37
37
  exports.profileInfo = index.profileInfo;
38
- exports.project = index.morph;
39
38
  exports.resource = index.resource;
40
39
  exports.setAt = index.setAt;
41
40
  exports.throttle = index.throttle;
@@ -43,6 +42,7 @@ exports.unreactive = index.unreactive;
43
42
  exports.watch = index.watch;
44
43
  exports.when = index.when;
45
44
  exports.AZone = proxy.AZone;
45
+ exports.CompareSymbol = proxy.CompareSymbol;
46
46
  exports.DecoratorError = proxy.DecoratorError;
47
47
  exports.IterableWeakMap = proxy.IterableWeakMap;
48
48
  exports.IterableWeakSet = proxy.IterableWeakSet;
@@ -65,6 +65,7 @@ exports.asyncZone = proxy.asyncZone;
65
65
  exports.atom = proxy.atom;
66
66
  exports.atomic = proxy.atomic;
67
67
  exports.biDi = proxy.biDi;
68
+ exports.captioned = proxy.captioned;
68
69
  exports.captured = proxy.captured;
69
70
  exports.caught = proxy.caught;
70
71
  exports.createFlavor = proxy.createFlavor;
@@ -75,6 +76,7 @@ exports.defer = proxy.defer;
75
76
  exports.devPreset = proxy.devPreset;
76
77
  exports.effect = proxy.effect;
77
78
  exports.effectAggregator = proxy.effectAggregator;
79
+ exports.effectContext = proxy.effectContext;
78
80
  exports.flavorOptions = proxy.flavorOptions;
79
81
  exports.flavored = proxy.flavored;
80
82
  exports.formatCleanupReason = proxy.formatCleanupReason;
@@ -82,6 +84,7 @@ exports.getActivationLog = proxy.getActivationLog;
82
84
  exports.getActiveEffect = proxy.getActiveEffect;
83
85
  exports.getState = proxy.getState;
84
86
  exports.hooks = proxy.hooks;
87
+ exports.inheritCaption = proxy.inheritCaption;
85
88
  exports.isConstructor = proxy.isConstructor;
86
89
  exports.isDev = proxy.isDev;
87
90
  exports.isNonReactive = proxy.isNonReactive;
@@ -108,5 +111,6 @@ exports.touched1 = proxy.touched1;
108
111
  exports.unlink = proxy.unlink;
109
112
  exports.untracked = proxy.untracked;
110
113
  exports.unwrap = proxy.unwrap;
114
+ exports.withEffectContext = proxy.withEffectContext;
111
115
  exports.zip = proxy.zip;
112
116
  //# sourceMappingURL=node.dev.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.dev.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"node.dev.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,2 +1,2 @@
1
- export { A as AZone, C as CleanupReason, c as EffectAccess, b as EffectCleanup, d as EffectCloser, g as EffectOptions, E as EffectTrigger, a as Evolution, G as GetterWrapper, H as HistoryValue, P as PropTrigger, R as ReactiveError, h as ReactiveErrorCode, S as ScopedCallback, i as Zone, Z as ZoneAggregator, j as ZoneHistory, k as asyncZone, l as debugPreset, m as devPreset, n as formatCleanupReason, o as isReactive, p as objectToProxy, q as prodPreset, r as proxyToObject, s as reactiveOptions, u as unwrap } from './types-Bx2PhORg.js';
2
- export { ArrayDiffResult, ArrayReadForward, ContextManager, Decorator, DecoratorDescription, DecoratorError, DecoratorFactory, Destroyable, DestructionError, Eventful, EventsBase, GenericClassDecorator, Hook, Indexable, IterableWeakMap, IterableWeakSet, LegacyClassDecorator, LegacyPropertyDecorator, Memoizable, MemoizableArgument, MixinClass, MixinFunction, ModernAccessorDecorator, ModernClassDecorator, ModernGetterDecorator, ModernMethodDecorator, ModernSetterDecorator, PromiseChain, ReactiveBase, Resource, Restorer, addBatchCleanup, addUnreactiveProps, allocated, allocatedValues, arrayDiff, arrayEquals, assertUntracked, asyncHook, asyncHooks, atom, atomic, attend, biDi, cache, cached, callOnGC, captured, caught, chainPromise, createFlavor, debounce, decorator, deepCompare, deepWatch, defer, deprecated, descriptor, destructor, effect, effectAggregator, flavorOptions, flavored, forwardArray, getActivationLog, getActiveEffect, getAt, getState, hooks, isCached, isConstructor, isDev, isNonReactive, isObject, isProd, isTest, legacyDecorator, lift, link, memoize, mixin, modernDecorator, morph, named, onEffectThrow, organize, organized, profileInfo, morph as project, reactive, reset, resource, root, setAt, tag, throttle, touched, touched1, unlink, unreactive, untracked, watch, when, zip } from './index.js';
1
+ export { A as AZone, C as CleanupReason, c as EffectAccess, b as EffectCleanup, d as EffectCloser, g as EffectOptions, E as EffectTrigger, a as Evolution, G as GetterWrapper, H as HistoryValue, P as PropTrigger, R as ReactiveError, h as ReactiveErrorCode, S as ScopedCallback, i as Zone, Z as ZoneAggregator, j as ZoneHistory, k as asyncZone, l as debugPreset, m as devPreset, n as formatCleanupReason, o as isReactive, p as objectToProxy, q as prodPreset, r as proxyToObject, s as reactiveOptions, u as unwrap } from './types.js';
2
+ export { ArrayDiffResult, ArrayReadForward, Captioned, CompareSymbol, ContextManager, Decorator, DecoratorDescription, DecoratorError, DecoratorFactory, Destroyable, DestructionError, EffectContext, Eventful, EventsBase, GenericClassDecorator, Hook, Indexable, IterableWeakMap, IterableWeakSet, LegacyClassDecorator, LegacyPropertyDecorator, Memoizable, MemoizableArgument, MixinClass, MixinFunction, ModernAccessorDecorator, ModernClassDecorator, ModernGetterDecorator, ModernMethodDecorator, ModernSetterDecorator, PromiseChain, ReactiveBase, Resource, Restorer, addBatchCleanup, addUnreactiveProps, allocated, allocatedValues, arrayDiff, arrayEquals, assertUntracked, asyncHook, asyncHooks, atom, atomic, attend, biDi, cache, cached, callOnGC, captioned, captured, caught, chainPromise, createFlavor, debounce, decorator, deepCompare, deepWatch, defer, deprecated, descriptor, destructor, effect, effectAggregator, effectContext, flavorOptions, flavored, forwardArray, getActivationLog, getActiveEffect, getAt, getState, hooks, inheritCaption, isCached, isConstructor, isDev, isNonReactive, isObject, isProd, isTest, legacyDecorator, lift, link, memoize, mixin, modernDecorator, morph, named, onEffectThrow, organize, organized, profileInfo, reactive, reset, resource, root, setAt, tag, throttle, touched, touched1, unlink, unreactive, untracked, watch, when, withEffectContext, zip } from './browser.js';
@@ -1,6 +1,6 @@
1
1
  import './debug.esm.js';
2
- import './chunks/node-Bo7WU5S2.esm.js';
3
- export { A as ArrayReadForward, D as Destroyable, a as DestructionError, E as Eventful, I as Indexable, b as allocated, c as allocatedValues, d as arrayDiff, e as attend, f as cache, g as cached, h as callOnGC, i as chainPromise, j as debounce, k as deepWatch, l as deprecated, m as descriptor, n as destructor, o as forwardArray, p as getAt, q as isCached, r as lift, s as memoize, t as morph, u as organize, v as organized, w as profileInfo, t as project, x as resource, y as setAt, z as throttle, B as unreactive, C as watch, F as when } from './chunks/index-BUop6B2U.esm.js';
4
- export { A as AZone, D as DecoratorError, I as IterableWeakMap, a as IterableWeakSet, R as ReactiveBase, b as ReactiveError, c as ReactiveErrorCode, Z as Zone, d as ZoneAggregator, e as ZoneHistory, f as addBatchCleanup, g as addUnreactiveProps, h as arrayEquals, i as assertUntracked, j as asyncHook, k as asyncHooks, l as asyncZone, m as atom, n as atomic, o as biDi, p as captured, q as caught, r as createFlavor, s as debugPreset, t as decorator, u as deepCompare, v as defer, w as devPreset, x as effect, y as effectAggregator, z as flavorOptions, B as flavored, C as formatCleanupReason, E as getActivationLog, F as getActiveEffect, G as getState, H as hooks, J as isConstructor, K as isDev, L as isNonReactive, M as isObject, N as isProd, O as isReactive, P as isTest, Q as legacyDecorator, S as link, T as mixin, U as modernDecorator, V as named, W as objectToProxy, X as onEffectThrow, Y as prodPreset, _ as proxyToObject, $ as reactive, a0 as reactiveOptions, a1 as reset, a2 as root, a3 as tag, a4 as touched, a5 as touched1, a6 as unlink, a7 as untracked, a8 as unwrap, a9 as zip } from './chunks/proxy-D2C49sXH.esm.js';
2
+ import './chunks/node-NEZvVo4M.esm.js';
3
+ export { A as ArrayReadForward, D as Destroyable, a as DestructionError, E as Eventful, I as Indexable, b as allocated, c as allocatedValues, d as arrayDiff, e as attend, f as cache, g as cached, h as callOnGC, i as chainPromise, j as debounce, k as deepWatch, l as deprecated, m as descriptor, n as destructor, o as forwardArray, p as getAt, q as isCached, r as lift, s as memoize, t as morph, u as organize, v as organized, w as profileInfo, x as resource, y as setAt, z as throttle, B as unreactive, C as watch, F as when } from './chunks/index-XsYTUhHx.esm.js';
4
+ export { A as AZone, C as CompareSymbol, D as DecoratorError, I as IterableWeakMap, a as IterableWeakSet, R as ReactiveBase, b as ReactiveError, c as ReactiveErrorCode, Z as Zone, d as ZoneAggregator, e as ZoneHistory, f as addBatchCleanup, g as addUnreactiveProps, h as arrayEquals, i as assertUntracked, j as asyncHook, k as asyncHooks, l as asyncZone, m as atom, n as atomic, o as biDi, p as captioned, q as captured, r as caught, s as createFlavor, t as debugPreset, u as decorator, v as deepCompare, w as defer, x as devPreset, y as effect, z as effectAggregator, B as effectContext, E as flavorOptions, F as flavored, G as formatCleanupReason, H as getActivationLog, J as getActiveEffect, K as getState, L as hooks, M as inheritCaption, N as isConstructor, O as isDev, P as isNonReactive, Q as isObject, S as isProd, T as isReactive, U as isTest, V as legacyDecorator, W as link, X as mixin, Y as modernDecorator, _ as named, $ as objectToProxy, a0 as onEffectThrow, a1 as prodPreset, a2 as proxyToObject, a3 as reactive, a4 as reactiveOptions, a5 as reset, a6 as root, a7 as tag, a8 as touched, a9 as touched1, aa as unlink, ab as untracked, ac as unwrap, ad as withEffectContext, ae as zip } from './chunks/proxy-BtmPFjSr.esm.js';
5
5
  import 'node:async_hooks';
6
6
  //# sourceMappingURL=node.dev.esm.js.map
package/dist/node.esm.js CHANGED
@@ -1,5 +1,5 @@
1
- import './chunks/node-Bo7WU5S2.esm.js';
2
- export { A as ArrayReadForward, D as Destroyable, a as DestructionError, E as Eventful, I as Indexable, b as allocated, c as allocatedValues, d as arrayDiff, e as attend, f as cache, g as cached, h as callOnGC, i as chainPromise, j as debounce, k as deepWatch, l as deprecated, m as descriptor, n as destructor, o as forwardArray, p as getAt, q as isCached, r as lift, s as memoize, t as morph, u as organize, v as organized, w as profileInfo, t as project, x as resource, y as setAt, z as throttle, B as unreactive, C as watch, F as when } from './chunks/index-BUop6B2U.esm.js';
3
- export { A as AZone, D as DecoratorError, I as IterableWeakMap, a as IterableWeakSet, R as ReactiveBase, b as ReactiveError, c as ReactiveErrorCode, Z as Zone, d as ZoneAggregator, e as ZoneHistory, f as addBatchCleanup, g as addUnreactiveProps, h as arrayEquals, i as assertUntracked, j as asyncHook, k as asyncHooks, l as asyncZone, m as atom, n as atomic, o as biDi, p as captured, q as caught, r as createFlavor, s as debugPreset, t as decorator, u as deepCompare, v as defer, w as devPreset, x as effect, y as effectAggregator, z as flavorOptions, B as flavored, C as formatCleanupReason, E as getActivationLog, F as getActiveEffect, G as getState, H as hooks, J as isConstructor, K as isDev, L as isNonReactive, M as isObject, N as isProd, O as isReactive, P as isTest, Q as legacyDecorator, S as link, T as mixin, U as modernDecorator, V as named, W as objectToProxy, X as onEffectThrow, Y as prodPreset, _ as proxyToObject, $ as reactive, a0 as reactiveOptions, a1 as reset, a2 as root, a3 as tag, a4 as touched, a5 as touched1, a6 as unlink, a7 as untracked, a8 as unwrap, a9 as zip } from './chunks/proxy-D2C49sXH.esm.js';
1
+ import './chunks/node-NEZvVo4M.esm.js';
2
+ export { A as ArrayReadForward, D as Destroyable, a as DestructionError, E as Eventful, I as Indexable, b as allocated, c as allocatedValues, d as arrayDiff, e as attend, f as cache, g as cached, h as callOnGC, i as chainPromise, j as debounce, k as deepWatch, l as deprecated, m as descriptor, n as destructor, o as forwardArray, p as getAt, q as isCached, r as lift, s as memoize, t as morph, u as organize, v as organized, w as profileInfo, x as resource, y as setAt, z as throttle, B as unreactive, C as watch, F as when } from './chunks/index-XsYTUhHx.esm.js';
3
+ export { A as AZone, C as CompareSymbol, D as DecoratorError, I as IterableWeakMap, a as IterableWeakSet, R as ReactiveBase, b as ReactiveError, c as ReactiveErrorCode, Z as Zone, d as ZoneAggregator, e as ZoneHistory, f as addBatchCleanup, g as addUnreactiveProps, h as arrayEquals, i as assertUntracked, j as asyncHook, k as asyncHooks, l as asyncZone, m as atom, n as atomic, o as biDi, p as captioned, q as captured, r as caught, s as createFlavor, t as debugPreset, u as decorator, v as deepCompare, w as defer, x as devPreset, y as effect, z as effectAggregator, B as effectContext, E as flavorOptions, F as flavored, G as formatCleanupReason, H as getActivationLog, J as getActiveEffect, K as getState, L as hooks, M as inheritCaption, N as isConstructor, O as isDev, P as isNonReactive, Q as isObject, S as isProd, T as isReactive, U as isTest, V as legacyDecorator, W as link, X as mixin, Y as modernDecorator, _ as named, $ as objectToProxy, a0 as onEffectThrow, a1 as prodPreset, a2 as proxyToObject, a3 as reactive, a4 as reactiveOptions, a5 as reset, a6 as root, a7 as tag, a8 as touched, a9 as touched1, aa as unlink, ab as untracked, ac as unwrap, ad as withEffectContext, ae as zip } from './chunks/proxy-BtmPFjSr.esm.js';
4
4
  import 'node:async_hooks';
5
5
  //# sourceMappingURL=node.esm.js.map
@@ -124,23 +124,34 @@ type PropTrigger = {
124
124
  type CleanupReason = {
125
125
  type: 'propChange';
126
126
  triggers: PropTrigger[];
127
+ chain?: CleanupReason;
127
128
  } | {
128
129
  type: 'invalidate';
129
130
  cause: CleanupReason;
131
+ chain?: CleanupReason;
132
+ } | {
133
+ type: 'external';
134
+ detail: string;
135
+ chain?: CleanupReason;
130
136
  } | {
131
137
  type: 'stopped';
132
138
  detail?: string;
139
+ chain?: CleanupReason;
133
140
  } | {
134
141
  type: 'gc';
142
+ chain?: CleanupReason;
135
143
  } | {
136
144
  type: 'lineage';
137
145
  parent: CleanupReason;
146
+ chain?: CleanupReason;
138
147
  } | {
139
148
  type: 'error';
140
149
  error: unknown;
150
+ chain?: CleanupReason;
141
151
  } | {
142
152
  type: 'multiple';
143
153
  reasons: CleanupReason[];
154
+ chain?: CleanupReason;
144
155
  };
145
156
  /**
146
157
  * Console-friendly description of a `CleanupReason`.
@@ -419,6 +430,7 @@ declare const options: {
419
430
  */
420
431
  asyncMode: AsyncExecutionMode | false;
421
432
  warn: (...args: any[]) => void;
433
+ error: (...args: any[]) => void;
422
434
  /**
423
435
  * Introspection and debug aids. Set to `null` to disable all debug overhead in production.
424
436
  *
@@ -24,22 +24,72 @@ export declare const Reactive: unique symbol;
24
24
  * Symbol to map back from a reactive proxy to its original target
25
25
  */
26
26
  export declare const Raw: unique symbol;
27
- export type ScopedCallback = (() => void | (() => void)) & {
28
- [cleanup]?: () => void;
27
+ export type PropTrigger = {
28
+ obj: object;
29
+ evolution: Evolution;
30
+ dependency?: unknown;
31
+ touch?: unknown;
29
32
  };
30
- export type DependencyFunction = <T>(fn: () => T) => T;
31
- export type DependencyAccess = {
32
- tracked: DependencyFunction;
33
- ascend: DependencyFunction;
34
- reaction: boolean;
33
+ export type CleanupReason = {
34
+ type: 'propChange';
35
+ triggers: PropTrigger[];
36
+ } | {
37
+ type: 'invalidate';
38
+ cause: CleanupReason;
39
+ } | {
40
+ type: 'stopped';
41
+ detail?: string;
42
+ } | {
43
+ type: 'gc';
44
+ } | {
45
+ type: 'lineage';
46
+ parent: CleanupReason;
47
+ } | {
48
+ type: 'error';
49
+ error: unknown;
50
+ } | {
51
+ type: 'multiple';
52
+ reasons: CleanupReason[];
53
+ };
54
+ export type ScopedCallback = (reason?: CleanupReason) => void;
55
+ export type EffectCleanup = ScopedCallback;
56
+ export type EffectCloser = (reason?: CleanupReason) => void;
57
+ export type EffectAccess = {
58
+ tracked: <T>(fn: () => T) => T;
59
+ ascend: <T>(fn: () => T) => T;
60
+ reaction: boolean | CleanupReason;
61
+ signal: AbortSignal;
62
+ };
63
+ export type EffectOptions = {
64
+ asyncMode?: 'cancel' | 'queue' | 'ignore';
65
+ opaque?: boolean;
66
+ dependencyHook?: (obj: any, prop: any) => void;
67
+ name?: string;
68
+ };
69
+ export type Evolution = {
70
+ type: 'set' | 'del' | 'add' | 'invalidate';
71
+ prop: any;
72
+ } | {
73
+ type: 'bunch';
74
+ method: string;
35
75
  };
36
76
 
77
+ export declare const effect: {
78
+ (fn: (access: EffectAccess) => EffectCloser | undefined | void | Promise<any>, effectOptions?: EffectOptions): EffectCleanup;
79
+ readonly opaque: typeof effect;
80
+ named(name: string): typeof effect;
81
+ };
37
82
  export declare function reactive<T extends object>(target: T): T;
38
- export declare function effect(fn: (access: DependencyAccess, ...args: any[]) => (ScopedCallback | undefined | void), ...args: any[]): ScopedCallback;
39
83
  export declare function unwrap<T>(obj: T): T;
40
84
  export declare function isReactive(obj: any): boolean;
85
+ export declare class ReactiveBase {}
41
86
  export declare function isNonReactive(obj: any): boolean;
42
87
  export declare function untracked<T>(fn: () => T): T;
88
+ export declare function root<T>(fn: () => T): T;
89
+ export declare function assertUntracked<T>(fn: () => T): T;
90
+ export declare function getState(obj: any): {};
91
+ export declare function touched(obj: any, evolution: Evolution, props?: any[]): void;
92
+ export declare function touched1(obj: any, evolution: Evolution, prop: any): void;
43
93
 
44
94
  // --------------------------------------------------------------------------------
45
95
  // REACTIVE HELPERS
@@ -48,15 +98,55 @@ export declare function untracked<T>(fn: () => T): T;
48
98
  export declare function atomic<T extends (...args: any[]) => any>(fn: T): T;
49
99
  export declare function atom<T>(fn: () => T): T;
50
100
  export declare function memoize<Result, Args extends any[]>(fn: (...args: Args) => Result, maxArgs?: number): (...args: Args) => Result;
51
- export declare function deepWatch(source: any, callback: (path: string[], value: any) => void): () => void;
52
- export declare function biDi<T>(target: (val: T) => void, source: { get: () => T, set: (v: T) => void }): (val: T) => void;
101
+ export declare function deepWatch<T extends object>(target: T, callback: (value: T) => void, options?: { immediate?: boolean }): EffectCleanup | undefined;
102
+ export declare function biDi<T>(received: (value: T) => void, value: { get: () => T, set: (value: T) => void }): (value: T) => void;
103
+ export declare function biDi<T>(received: (value: T) => void, get: () => T, set: (value: T) => void): (value: T) => void;
104
+ export declare function addBatchCleanup(cleanup: () => void): void;
105
+ export declare const defer: typeof addBatchCleanup;
106
+ export declare function caught(onThrow: (error: unknown) => EffectCloser | undefined | void): void;
107
+ export declare const onEffectThrow: typeof caught;
108
+ export declare function getActiveEffect(): ScopedCallback;
109
+ export declare const effectAggregator: unknown;
110
+ export declare function link(owner: object, ...deps: (ScopedCallback | object)[]): void;
111
+ export declare function unlink(owner: object, reason?: CleanupReason): void;
53
112
 
54
113
  // --------------------------------------------------------------------------------
55
114
  // COLLECTIONS
56
115
  // --------------------------------------------------------------------------------
57
116
 
58
- export declare function project<S, R>(source: S, apply: (access: any, target: any) => any): R;
117
+ export declare function attend<T>(source: readonly T[], callback: (index: number, access: EffectAccess) => EffectCloser | void): ScopedCallback;
118
+ export declare function attend<K, V>(source: Map<K, V>, callback: (key: K, access: EffectAccess) => EffectCloser | void): ScopedCallback;
119
+ export declare function attend<T>(source: Set<T>, callback: (value: T, access: EffectAccess) => EffectCloser | void): ScopedCallback;
120
+ export declare function attend<S extends object>(source: S, callback: (key: keyof S & string, access: EffectAccess) => EffectCloser | void): ScopedCallback;
121
+ export declare function attend<Key>(enumerate: () => Iterable<Key>, callback: (key: Key, access: EffectAccess) => EffectCloser | void): ScopedCallback;
122
+ export declare function lift<Output extends any[]>(cb: (access: EffectAccess) => Output): Output;
123
+ export declare function lift<Output extends object>(cb: (access: EffectAccess) => Output): Output;
124
+ export declare const morph: {
125
+ <I, O>(source: readonly I[] | (() => readonly I[]), fn: (arg: I, access?: EffectAccess) => O, options?: { pure?: boolean | ((i: I) => boolean) }): readonly O[];
126
+ <K, V, O>(source: Map<K, V>, fn: (arg: V, key: K, access?: EffectAccess) => O, options?: { pure?: boolean | ((i: V) => boolean) }): Map<K, O>;
127
+ <S extends Record<PropertyKey, any>, O>(source: S, fn: (arg: S[keyof S], key: keyof S, access?: EffectAccess) => O, options?: { pure?: boolean | ((i: S[keyof S]) => boolean) }): { [K in keyof S]: O };
128
+ pure: typeof morph;
129
+ };
59
130
  export declare function organized<S, T>(source: S, apply: (access: any, target: T) => any, baseTarget?: T): T;
131
+ export declare function organize<T>(target: object, property: PropertyKey, access: { get?(): T, set?(value: T): boolean }): () => boolean;
132
+ export declare const watch: {
133
+ <T>(value: (dep: EffectAccess) => T, changed: (value: T, oldValue?: T) => void, options?: { immediate?: boolean, deep?: false }): EffectCleanup;
134
+ <T extends object | any[]>(value: (dep: EffectAccess) => T, changed: (value: T, oldValue?: T) => void, options?: { immediate?: boolean, deep: true }): EffectCleanup;
135
+ <T extends object | any[]>(value: T, changed: (value: T) => void, options?: { immediate?: boolean, deep?: boolean }): EffectCleanup;
136
+ readonly deep: typeof watch;
137
+ readonly immediate: typeof watch;
138
+ };
139
+ export declare function when<T>(predicate: (dep: EffectAccess) => T, timeout?: number): Promise<T>;
140
+ export interface Resource<T> {
141
+ value: T | undefined;
142
+ loading: boolean;
143
+ error: any;
144
+ latest: T | undefined;
145
+ reload(): void;
146
+ promise: Promise<void>;
147
+ }
148
+ export declare function resource<T>(fetcher: (access: EffectAccess) => Promise<T> | T, options?: { initialValue?: T }): Resource<T>;
149
+ export declare function unreactive<T extends object>(obj: T): T;
60
150
 
61
151
  // --------------------------------------------------------------------------------
62
152
  // DESTROYABLE
@@ -96,7 +186,7 @@ export declare function deprecated(message?: string): Function;
96
186
 
97
187
  export declare const reactiveOptions: {
98
188
  cycleHandling: 'production' | 'development' | 'debug';
99
- introspection: { enableHistory: boolean; historySize: number; logErrors: boolean };
189
+ introspection: unknown;
100
190
  };
101
191
 
102
192
  export enum ReactiveErrorCode {
package/docs/ai/manual.md CHANGED
@@ -13,7 +13,7 @@ Proxy-based **fine-grained reactivity** — changes propagate synchronously thro
13
13
  | State | `reactive(obj)` — proxy wraps, tracks reads/writes |
14
14
  | Reactions | `effect(() => {})` — auto-tracks deps, re-runs on change |
15
15
  | Computed | `memoize(fn)` — cached, invalidates on tracked deps |
16
- | Collections | `project(arr, fn)` — per-entry effects, not `.map()` |
16
+ | Collections | `morph(arr, fn)` — per-entry reactive transform |
17
17
  | Async context | `Zone` + `asyncZone` — propagates across await |
18
18
  | Batching | `atomic(() => {})` wraps, `atom(() => {})` runs immediately — fire effects once after all mutations |
19
19
  | Cleanup | Return fn from effect — runs before re-run/disposal |
@@ -22,11 +22,11 @@ Proxy-based **fine-grained reactivity** — changes propagate synchronously thro
22
22
 
23
23
  ```ts
24
24
  import { reactive, effect, memoize, morph, attend, lift, cleanup,
25
- atom, atomic, defer, untracked, unreactive, watch, when, biDi, caught, why,
26
- cleanedBy, organized,
25
+ atom, atomic, defer, untracked, unreactive, watch, when, biDi, caught,
26
+ organized, organize, resource, root,
27
27
  Zone, asyncZone, ZoneHistory, ZoneAggregator,
28
28
  decorator, mixin, Eventful, Destroyable, flavored, Indexable, chainPromise,
29
- reactiveOptions, isReactive, unwrap, getState
29
+ reactiveOptions, isReactive, unwrap, getState, ReactiveBase
30
30
  } from 'mutts'
31
31
  ```
32
32
 
@@ -107,14 +107,14 @@ array.splice(0) // also works — explicit clear
107
107
  ```
108
108
 
109
109
  ### TRAP 6: Using .map() for reactive transforms
110
- `.map()` is static — full rebuild on any change. Use `project()` for per-entry reactivity.
110
+ `.map()` is static — full rebuild on any change. Use `morph()` for per-entry reactivity.
111
111
 
112
112
  ```ts
113
113
  // BAD — full rebuild
114
114
  const doubled = items.map(x => x.value * 2)
115
115
 
116
116
  // GOOD — per-entry effects
117
- const doubled = project(items, ({ get }) => get().value * 2)
117
+ const doubled = morph(items, (value) => value * 2)
118
118
  ```
119
119
 
120
120
  ### TRAP 7: Deep watch overhead
@@ -164,7 +164,11 @@ state.count++ // triggers
164
164
  stop() // disposes
165
165
  ```
166
166
 
167
- - **Access object**: `{ reaction, tracked(fn), ascend(fn) }` — `reaction` = false on first run, true after. `tracked` restores context in async. `ascend` tracks in parent effect.
167
+ - **Access object**: `{ reaction, tracked(fn), ascend(fn), signal }`
168
+ - `reaction` is `false` on first run, then `true` or a `CleanupReason` on re-runs.
169
+ - `tracked` restores effect tracking in async or escaped callbacks.
170
+ - `ascend` records dependencies on the parent effect context.
171
+ - `signal` aborts when the effect is cleaned up or invalidated.
168
172
  - **Parent-child**: effects inside effects are children — parent disposal cascades.
169
173
  - **GC**: unreferenced top-level effects may GC — store `stop` to keep alive.
170
174
  - **Modifiers**: `effect.opaque(() => {})` (identity-only), `effect.named('x')(() => {})` (debug label). Chainable.
@@ -231,16 +235,15 @@ input.addEventListener('input', () => provide(input.value))
231
235
  ```ts
232
236
  watch(() => state.count, (newVal, oldVal) => {}) // specific derivation
233
237
  watch(state, () => {}) // any property
234
- watch(state, () => {}, { deep: true }) // deep (expensive)
238
+ watch.deep(state, () => {}) // deep (expensive)
239
+ watch.immediate(() => state.count, (newVal, oldVal) => {}) // immediate first call
235
240
  ```
236
241
 
237
- ### 3.10 cleanedBy() — Attach cleanup to objects
242
+ `watch` has 3 useful shapes:
238
243
 
239
- ```ts
240
- const obj = cleanedBy({ data: [] }, () => console.log('cleaned up'))
241
- obj[cleanup]() // triggers cleanup
242
- // Chains: if obj already has a cleanup, both run
243
- ```
244
+ - `watch(() => value, callback)`
245
+ - `watch.deep(() => object, callback)`
246
+ - `watch(object, callback)`
244
247
 
245
248
  ### 3.11 Lazy computed values
246
249
 
@@ -258,9 +261,25 @@ effect(() => console.log(d.value)) // recomputes immediately, .value is reactive
258
261
 
259
262
  ```ts
260
263
  await when(() => state.loaded) // resolves when truthy
261
- await when(() => state.ready, { timeout: 5000 }) // rejects after 5s
264
+ await when(() => state.ready, 5000) // rejects after 5s
262
265
  ```
263
266
 
267
+ ### 3.13 resource() — Async reactive state
268
+
269
+ ```ts
270
+ const user = resource(async () => fetchUser(state.userId), { initialValue: null })
271
+
272
+ effect(() => {
273
+ if (user.loading) return
274
+ console.log(user.value)
275
+ })
276
+
277
+ user.reload()
278
+ await user.promise
279
+ ```
280
+
281
+ `resource()` returns `{ value, loading, error, latest, reload(), promise }`.
282
+
264
283
  ---
265
284
 
266
285
  ## 4. COLLECTIONS
@@ -280,15 +299,22 @@ Array methods (`push`, `splice`, `sort`, etc.) all trigger reactivity.
280
299
 
281
300
  All transforms return reactive results. Cleanup via `result[cleanup]()`.
282
301
 
283
- ### 5.1 project() — Per-entry reactive map
302
+ ### 5.1 morph() — Per-entry reactive map
284
303
 
285
304
  ```ts
286
- const names = project(users, ({ get }) => get().name.toUpperCase())
305
+ const names = morph(users, (user) => user.name.toUpperCase())
287
306
  // names[0] recomputes ONLY when users[0] changes
288
- // Variants: project.record(), project.map() auto-dispatches by source type
307
+ // Use morph.pure(...) when the callback has no reactive reads
289
308
  ```
290
309
 
291
- **Access object**: `{ get(), set(v), key, source, old, value }`
310
+ For arrays the callback is `(value, access?) => mapped`.
311
+ For Maps and records it also receives the key.
312
+
313
+ The mapper can also be captioned, even though it is the second argument:
314
+
315
+ ```ts
316
+ const names = morph`user:names`(users, (user) => user.name.toUpperCase())
317
+ ```
292
318
 
293
319
  ### 5.2 attend() — Per-key lifecycle
294
320
 
@@ -297,9 +323,17 @@ attend(reactiveRecord, (key) => {
297
323
  console.log(`${key} = ${reactiveRecord[key]}`)
298
324
  return () => console.log(`cleanup: ${key}`) // disposed when key disappears
299
325
  })
300
- // Works with: arrays, Maps, Sets, or raw () => Iterable<Key>
301
326
  ```
302
327
 
328
+ `attend` also supports callback captions on its second argument:
329
+
330
+ ```ts
331
+ attend`record:entries`(reactiveRecord, (key) => {
332
+ console.log(`${key} = ${reactiveRecord[key]}`)
333
+ })
334
+ ```
335
+ Works with: arrays, Maps, Sets, or raw `() => Iterable<Key>`.
336
+
303
337
  ### 5.3 organized() — Per-key record transform
304
338
 
305
339
  ```ts
@@ -309,7 +343,7 @@ const doubled = organized(source, (access, target) => {
309
343
  })
310
344
  ```
311
345
 
312
- ### 5.6 lift() — Sync a computed array/object
346
+ ### 5.4 lift() — Sync a computed array/object
313
347
 
314
348
  ```ts
315
349
  const filtered = lift(() => items.filter(x => x.active))
@@ -318,7 +352,7 @@ const filtered = lift(() => items.filter(x => x.active))
318
352
 
319
353
  **lift vs deep touching**: Deep touching handles `state.items = newArray` (replacement diffs). `lift` is for **derived collections** (filter/map/reshape) where there's no single assignment — the output is recomputed from scratch.
320
354
 
321
- **lift vs memoize**: `memoize` is lazy (invalidate → recompute on next read), returns raw values, keyed by args. `lift` is eager (recompute immediately), returns a **stable reactive proxy** with per-element diffing. Use `lift` for derived collections consumed by `project()`/effects; use `memoize` for parameterized caching or lazy evaluation.
355
+ **lift vs memoize**: `memoize` is lazy (invalidate → recompute on next read), returns raw values, keyed by args. `lift` is eager (recompute immediately), returns a **stable reactive proxy** with per-element diffing. Use `lift` for derived collections consumed by effects; use `memoize` for parameterized caching or lazy evaluation.
322
356
 
323
357
  ---
324
358
 
@@ -387,6 +421,8 @@ const graph = buildReactivityGraph()
387
421
 
388
422
  **ReactiveError.debugInfo**: `causalChain`, `creationStack`, `cycle` (for CYCLE_DETECTED).
389
423
 
424
+ `onEffectThrow` is still exported as a deprecated alias of `caught`.
425
+
390
426
  ---
391
427
 
392
428
  ## 9. ZONES (Async Context)
@@ -484,7 +520,7 @@ const theme = await chainPromise(api.getUser('123')).getProfile().getSettings().
484
520
  ## 11. PHILOSOPHY
485
521
 
486
522
  - **Affirmative state**: Declare `Y = f(X)`. Don't say "when X changes, update Y".
487
- - **Events are legacy**: Use reactive derivations (`effect`, `memoize`, `project`) for internal logic. Events only for DOM/external APIs.
523
+ - **Events are legacy**: Use reactive derivations (`effect`, `memoize`, `morph`) for internal logic. Events only for DOM/external APIs.
488
524
  - **Cleanup ≠ undo**: Cleanup releases subscriptions, does NOT undo side effects.
489
525
 
490
526
  ---
@@ -504,5 +540,5 @@ const theme = await chainPromise(api.getUser('123')).getProfile().getSettings().
504
540
  | `isReactive(obj)` to check | `obj._mutts_isReactive` |
505
541
  | Store `stop = effect(...)` | letting effect GC unintentionally |
506
542
  | `import { x } from 'mutts'` | `import { x } from 'mutts/reactive'` (no subpaths) |
507
- | `cleanedBy(obj, fn)` for cleanup | manual `obj[cleanup] = fn` |
543
+ | `caught(handler)` for effect-local error handling | ad-hoc try/catch around reactive graph edges |
508
544
  | `memoize(() => a + b)` for computed | `effect` + manual state sync |