mutts 1.0.5 → 1.0.7

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 (114) hide show
  1. package/README.md +2 -1
  2. package/dist/browser.d.ts +2 -0
  3. package/dist/browser.esm.js +70 -0
  4. package/dist/browser.esm.js.map +1 -0
  5. package/dist/browser.js +161 -0
  6. package/dist/browser.js.map +1 -0
  7. package/dist/chunks/{index-Cvxdw6Ax.js → index-BFYK02LG.js} +5377 -4059
  8. package/dist/chunks/index-BFYK02LG.js.map +1 -0
  9. package/dist/chunks/{index-qiWwozOc.esm.js → index-CNR6QRUl.esm.js} +5247 -3963
  10. package/dist/chunks/index-CNR6QRUl.esm.js.map +1 -0
  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/node.d.ts +2 -0
  16. package/dist/node.esm.js +45 -0
  17. package/dist/node.esm.js.map +1 -0
  18. package/dist/node.js +136 -0
  19. package/dist/node.js.map +1 -0
  20. package/docs/ai/api-reference.md +0 -2
  21. package/docs/ai/manual.md +14 -95
  22. package/docs/reactive/advanced.md +7 -111
  23. package/docs/reactive/collections.md +0 -125
  24. package/docs/reactive/core.md +27 -24
  25. package/docs/reactive/debugging.md +168 -0
  26. package/docs/reactive/project.md +1 -1
  27. package/docs/reactive/scan.md +78 -0
  28. package/docs/reactive.md +8 -6
  29. package/docs/std-decorators.md +1 -0
  30. package/docs/zone.md +88 -0
  31. package/package.json +47 -65
  32. package/src/async/browser.ts +87 -0
  33. package/src/async/index.ts +8 -0
  34. package/src/async/node.ts +46 -0
  35. package/src/decorator.ts +15 -9
  36. package/src/destroyable.ts +4 -4
  37. package/src/index.ts +54 -0
  38. package/src/indexable.ts +42 -0
  39. package/src/mixins.ts +2 -2
  40. package/src/reactive/array.ts +149 -141
  41. package/src/reactive/buffer.ts +168 -0
  42. package/src/reactive/change.ts +3 -3
  43. package/src/reactive/debug.ts +1 -1
  44. package/src/reactive/deep-touch.ts +1 -1
  45. package/src/reactive/deep-watch.ts +1 -1
  46. package/src/reactive/effect-context.ts +15 -91
  47. package/src/reactive/effects.ts +138 -170
  48. package/src/reactive/index.ts +10 -13
  49. package/src/reactive/interface.ts +20 -33
  50. package/src/reactive/map.ts +48 -61
  51. package/src/reactive/memoize.ts +87 -31
  52. package/src/reactive/project.ts +43 -22
  53. package/src/reactive/proxy.ts +18 -43
  54. package/src/reactive/record.ts +3 -3
  55. package/src/reactive/register.ts +5 -7
  56. package/src/reactive/registry.ts +59 -0
  57. package/src/reactive/set.ts +42 -56
  58. package/src/reactive/tracking.ts +5 -62
  59. package/src/reactive/types.ts +79 -19
  60. package/src/std-decorators.ts +9 -9
  61. package/src/utils.ts +203 -19
  62. package/src/zone.ts +127 -0
  63. package/dist/chunks/_tslib-BgjropY9.js +0 -81
  64. package/dist/chunks/_tslib-BgjropY9.js.map +0 -1
  65. package/dist/chunks/_tslib-Mzh1rNsX.esm.js +0 -75
  66. package/dist/chunks/_tslib-Mzh1rNsX.esm.js.map +0 -1
  67. package/dist/chunks/decorator-DLvrD0UF.js +0 -265
  68. package/dist/chunks/decorator-DLvrD0UF.js.map +0 -1
  69. package/dist/chunks/decorator-DqiszP7i.esm.js +0 -253
  70. package/dist/chunks/decorator-DqiszP7i.esm.js.map +0 -1
  71. package/dist/chunks/index-Cvxdw6Ax.js.map +0 -1
  72. package/dist/chunks/index-qiWwozOc.esm.js.map +0 -1
  73. package/dist/decorator.d.ts +0 -107
  74. package/dist/decorator.esm.js +0 -2
  75. package/dist/decorator.esm.js.map +0 -1
  76. package/dist/decorator.js +0 -11
  77. package/dist/decorator.js.map +0 -1
  78. package/dist/destroyable.d.ts +0 -90
  79. package/dist/destroyable.esm.js +0 -109
  80. package/dist/destroyable.esm.js.map +0 -1
  81. package/dist/destroyable.js +0 -116
  82. package/dist/destroyable.js.map +0 -1
  83. package/dist/eventful.d.ts +0 -20
  84. package/dist/eventful.esm.js +0 -66
  85. package/dist/eventful.esm.js.map +0 -1
  86. package/dist/eventful.js +0 -68
  87. package/dist/eventful.js.map +0 -1
  88. package/dist/index.d.ts +0 -19
  89. package/dist/index.esm.js +0 -8
  90. package/dist/index.esm.js.map +0 -1
  91. package/dist/index.js +0 -95
  92. package/dist/index.js.map +0 -1
  93. package/dist/indexable.d.ts +0 -243
  94. package/dist/indexable.esm.js +0 -285
  95. package/dist/indexable.esm.js.map +0 -1
  96. package/dist/indexable.js +0 -291
  97. package/dist/indexable.js.map +0 -1
  98. package/dist/promiseChain.d.ts +0 -21
  99. package/dist/promiseChain.esm.js +0 -78
  100. package/dist/promiseChain.esm.js.map +0 -1
  101. package/dist/promiseChain.js +0 -80
  102. package/dist/promiseChain.js.map +0 -1
  103. package/dist/reactive.d.ts +0 -885
  104. package/dist/reactive.esm.js +0 -5
  105. package/dist/reactive.esm.js.map +0 -1
  106. package/dist/reactive.js +0 -59
  107. package/dist/reactive.js.map +0 -1
  108. package/dist/std-decorators.d.ts +0 -52
  109. package/dist/std-decorators.esm.js +0 -196
  110. package/dist/std-decorators.esm.js.map +0 -1
  111. package/dist/std-decorators.js +0 -204
  112. package/dist/std-decorators.js.map +0 -1
  113. package/src/reactive/mapped.ts +0 -129
  114. package/src/reactive/zone.ts +0 -208
package/dist/node.d.ts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { };
@@ -0,0 +1,45 @@
1
+ import { createHook } from 'node:async_hooks';
2
+ import { a as asyncHooks } from './chunks/index-CNR6QRUl.esm.js';
3
+ export { A as AZone, b as ArrayReadForward, D as DecoratorError, c as Destroyable, d as DestructionError, E as Eventful, F as FoolProof, I as Indexable, e as IterableWeakMap, f as IterableWeakSet, R as ReactiveBase, g as ReactiveError, h as ReactiveErrorCode, i as Register, Z as Zone, j as ZoneAggregator, k as ZoneHistory, l as addBatchCleanup, m as allocated, n as allocatedValues, o as arrayEquals, p as asyncZone, q as atomic, r as biDi, s as buildReactivityGraph, t as cache, u as cached, v as callOnGC, w as chainPromise, x as cleanedBy, y as cleanup, z as contentRef, B as debounce, C as decorator, G as deepCompare, H as deepWatch, J as defer, K as deprecated, L as derived, M as describe, N as destructor, O as effect, P as enableDevTools, Q as forwardArray, S as getActivationLog, T as getActiveProjection, U as getAt, V as getState, W as immutables, X as isCached, Y as isConstructor, _ as isDevtoolsEnabled, $ as isNonReactive, a0 as isOwnAccessor, a1 as isReactive, a2 as legacyDecorator, a3 as memoize, a4 as mixin, a5 as modernDecorator, a6 as named, a7 as organize, a8 as organized, a9 as profileInfo, aa as project, ab as reactive, ac as reactiveOptions, ad as register, ae as registerEffectForDebug, af as registerNativeReactivity, ag as registerObjectForDebug, ah as renamed, ai as root, aj as scan, ak as setAt, al as setEffectName, am as setObjectName, an as tag, ao as throttle, ap as touched, aq as touched1, ar as trackEffect, as as unreactive, at as untracked, au as unwrap, av as watch, aw as zip } from './chunks/index-CNR6QRUl.esm.js';
4
+
5
+ const hooks = new Set();
6
+ const restorersPerAsyncId = new Map();
7
+ const undoersPerAsyncId = new Map();
8
+ createHook({
9
+ init(asyncId) {
10
+ const restorers = new Set();
11
+ for (const hook of hooks) {
12
+ restorers.add(hook());
13
+ }
14
+ restorersPerAsyncId.set(asyncId, restorers);
15
+ },
16
+ before(asyncId) {
17
+ const restorers = restorersPerAsyncId.get(asyncId);
18
+ if (restorers) {
19
+ const undoers = new Set();
20
+ for (const restore of restorers) {
21
+ undoers.add(restore());
22
+ }
23
+ undoersPerAsyncId.set(asyncId, undoers);
24
+ }
25
+ },
26
+ after(asyncId) {
27
+ const undoers = undoersPerAsyncId.get(asyncId);
28
+ if (undoers) {
29
+ for (const undo of undoers)
30
+ undo();
31
+ undoersPerAsyncId.delete(asyncId);
32
+ }
33
+ },
34
+ destroy(asyncId) {
35
+ restorersPerAsyncId.delete(asyncId);
36
+ undoersPerAsyncId.delete(asyncId);
37
+ }
38
+ }).enable();
39
+ asyncHooks.addHook = function (hook) {
40
+ hooks.add(hook);
41
+ return () => {
42
+ hooks.delete(hook);
43
+ };
44
+ };
45
+ //# sourceMappingURL=node.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.esm.js","sources":["../src/async/node.ts"],"sourcesContent":["import { createHook } from 'node:async_hooks'\nimport { Hook, Restorer, asyncHooks } from '.'\n\nconst hooks = new Set<Hook>()\nconst restorersPerAsyncId = new Map<number, Set<Restorer>>()\nconst undoersPerAsyncId = new Map<number, Set<() => void>>()\n\ncreateHook({\n\tinit(asyncId) {\n\t\tconst restorers = new Set<Restorer>()\n\t\tfor (const hook of hooks) {\n\t\t\trestorers.add(hook())\n\t\t}\n\t\trestorersPerAsyncId.set(asyncId, restorers)\n\t},\n\tbefore(asyncId) {\n\t\tconst restorers = restorersPerAsyncId.get(asyncId)\n\t\tif (restorers) {\n\t\t\tconst undoers = new Set<() => void>()\n\t\t\tfor (const restore of restorers) {\n\t\t\t\tundoers.add(restore())\n\t\t\t}\n\t\t\tundoersPerAsyncId.set(asyncId, undoers)\n\t\t}\n\t},\n\tafter(asyncId) {\n\t\tconst undoers = undoersPerAsyncId.get(asyncId)\n\t\tif (undoers) {\n\t\t\tfor (const undo of undoers) undo()\n\t\t\tundoersPerAsyncId.delete(asyncId)\n\t\t}\n\t},\n\tdestroy(asyncId) {\n\t\trestorersPerAsyncId.delete(asyncId)\n\t\tundoersPerAsyncId.delete(asyncId)\n\t}\n}).enable()\n\nasyncHooks.addHook = function (hook: Hook) {\n\thooks.add(hook)\n\treturn () => {\n\t\thooks.delete(hook)\n\t}\n}\n\nexport * from '../index'\n"],"names":[],"mappings":";;;;AAGA,MAAM,KAAK,GAAG,IAAI,GAAG,EAAQ;AAC7B,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAyB;AAC5D,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA2B;AAE5D,UAAU,CAAC;AACV,IAAA,IAAI,CAAC,OAAO,EAAA;AACX,QAAA,MAAM,SAAS,GAAG,IAAI,GAAG,EAAY;AACrC,QAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACzB,YAAA,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACtB;AACA,QAAA,mBAAmB,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5C,CAAC;AACD,IAAA,MAAM,CAAC,OAAO,EAAA;QACb,MAAM,SAAS,GAAG,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC;QAClD,IAAI,SAAS,EAAE;AACd,YAAA,MAAM,OAAO,GAAG,IAAI,GAAG,EAAc;AACrC,YAAA,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE;AAChC,gBAAA,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACvB;AACA,YAAA,iBAAiB,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;QACxC;IACD,CAAC;AACD,IAAA,KAAK,CAAC,OAAO,EAAA;QACZ,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC;QAC9C,IAAI,OAAO,EAAE;YACZ,KAAK,MAAM,IAAI,IAAI,OAAO;AAAE,gBAAA,IAAI,EAAE;AAClC,YAAA,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC;QAClC;IACD,CAAC;AACD,IAAA,OAAO,CAAC,OAAO,EAAA;AACd,QAAA,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC;AACnC,QAAA,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC;IAClC;CACA,CAAC,CAAC,MAAM,EAAE;AAEX,UAAU,CAAC,OAAO,GAAG,UAAU,IAAU,EAAA;AACxC,IAAA,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;AACf,IAAA,OAAO,MAAK;AACX,QAAA,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;AACnB,IAAA,CAAC;AACF,CAAC"}
package/dist/node.js ADDED
@@ -0,0 +1,136 @@
1
+ 'use strict';
2
+
3
+ var node_async_hooks = require('node:async_hooks');
4
+ var index = require('./chunks/index-BFYK02LG.js');
5
+
6
+ const hooks = new Set();
7
+ const restorersPerAsyncId = new Map();
8
+ const undoersPerAsyncId = new Map();
9
+ node_async_hooks.createHook({
10
+ init(asyncId) {
11
+ const restorers = new Set();
12
+ for (const hook of hooks) {
13
+ restorers.add(hook());
14
+ }
15
+ restorersPerAsyncId.set(asyncId, restorers);
16
+ },
17
+ before(asyncId) {
18
+ const restorers = restorersPerAsyncId.get(asyncId);
19
+ if (restorers) {
20
+ const undoers = new Set();
21
+ for (const restore of restorers) {
22
+ undoers.add(restore());
23
+ }
24
+ undoersPerAsyncId.set(asyncId, undoers);
25
+ }
26
+ },
27
+ after(asyncId) {
28
+ const undoers = undoersPerAsyncId.get(asyncId);
29
+ if (undoers) {
30
+ for (const undo of undoers)
31
+ undo();
32
+ undoersPerAsyncId.delete(asyncId);
33
+ }
34
+ },
35
+ destroy(asyncId) {
36
+ restorersPerAsyncId.delete(asyncId);
37
+ undoersPerAsyncId.delete(asyncId);
38
+ }
39
+ }).enable();
40
+ index.asyncHooks.addHook = function (hook) {
41
+ hooks.add(hook);
42
+ return () => {
43
+ hooks.delete(hook);
44
+ };
45
+ };
46
+
47
+ exports.AZone = index.AZone;
48
+ exports.ArrayReadForward = index.ArrayReadForward;
49
+ exports.DecoratorError = index.DecoratorError;
50
+ exports.Destroyable = index.Destroyable;
51
+ exports.DestructionError = index.DestructionError;
52
+ exports.Eventful = index.Eventful;
53
+ exports.FoolProof = index.FoolProof;
54
+ exports.Indexable = index.Indexable;
55
+ exports.IterableWeakMap = index.IterableWeakMap;
56
+ exports.IterableWeakSet = index.IterableWeakSet;
57
+ exports.ReactiveBase = index.ReactiveBase;
58
+ exports.ReactiveError = index.ReactiveError;
59
+ Object.defineProperty(exports, "ReactiveErrorCode", {
60
+ enumerable: true,
61
+ get: function () { return index.ReactiveErrorCode; }
62
+ });
63
+ exports.Register = index.Register;
64
+ exports.Zone = index.Zone;
65
+ exports.ZoneAggregator = index.ZoneAggregator;
66
+ exports.ZoneHistory = index.ZoneHistory;
67
+ exports.addBatchCleanup = index.addBatchCleanup;
68
+ exports.allocated = index.allocated;
69
+ exports.allocatedValues = index.allocatedValues;
70
+ exports.arrayEquals = index.arrayEquals;
71
+ exports.asyncZone = index.asyncZone;
72
+ exports.atomic = index.atomic;
73
+ exports.biDi = index.biDi;
74
+ exports.buildReactivityGraph = index.buildReactivityGraph;
75
+ exports.cache = index.cache;
76
+ exports.cached = index.cached;
77
+ exports.callOnGC = index.callOnGC;
78
+ exports.chainPromise = index.chainPromise;
79
+ exports.cleanedBy = index.cleanedBy;
80
+ exports.cleanup = index.cleanup;
81
+ exports.contentRef = index.contentRef;
82
+ exports.debounce = index.debounce;
83
+ exports.decorator = index.decorator;
84
+ exports.deepCompare = index.deepCompare;
85
+ exports.deepWatch = index.deepWatch;
86
+ exports.defer = index.defer;
87
+ exports.deprecated = index.deprecated;
88
+ exports.derived = index.derived;
89
+ exports.describe = index.describe;
90
+ exports.destructor = index.destructor;
91
+ exports.effect = index.effect;
92
+ exports.enableDevTools = index.enableDevTools;
93
+ exports.forwardArray = index.forwardArray;
94
+ exports.getActivationLog = index.getActivationLog;
95
+ exports.getActiveProjection = index.getActiveProjection;
96
+ exports.getAt = index.getAt;
97
+ exports.getState = index.getState;
98
+ exports.immutables = index.immutables;
99
+ exports.isCached = index.isCached;
100
+ exports.isConstructor = index.isConstructor;
101
+ exports.isDevtoolsEnabled = index.isDevtoolsEnabled;
102
+ exports.isNonReactive = index.isNonReactive;
103
+ exports.isOwnAccessor = index.isOwnAccessor;
104
+ exports.isReactive = index.isReactive;
105
+ exports.legacyDecorator = index.legacyDecorator;
106
+ exports.memoize = index.memoize;
107
+ exports.mixin = index.mixin;
108
+ exports.modernDecorator = index.modernDecorator;
109
+ exports.named = index.named;
110
+ exports.organize = index.organize;
111
+ exports.organized = index.organized;
112
+ exports.profileInfo = index.profileInfo;
113
+ exports.project = index.project;
114
+ exports.reactive = index.reactive;
115
+ exports.reactiveOptions = index.options;
116
+ exports.register = index.register;
117
+ exports.registerEffectForDebug = index.registerEffectForDebug;
118
+ exports.registerNativeReactivity = index.registerNativeReactivity;
119
+ exports.registerObjectForDebug = index.registerObjectForDebug;
120
+ exports.renamed = index.renamed;
121
+ exports.root = index.root;
122
+ exports.scan = index.scan;
123
+ exports.setAt = index.setAt;
124
+ exports.setEffectName = index.setEffectName;
125
+ exports.setObjectName = index.setObjectName;
126
+ exports.tag = index.tag;
127
+ exports.throttle = index.throttle;
128
+ exports.touched = index.touched;
129
+ exports.touched1 = index.touched1;
130
+ exports.trackEffect = index.trackEffect;
131
+ exports.unreactive = index.unreactive;
132
+ exports.untracked = index.untracked;
133
+ exports.unwrap = index.unwrap;
134
+ exports.watch = index.watch;
135
+ exports.zip = index.zip;
136
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sources":["../src/async/node.ts"],"sourcesContent":["import { createHook } from 'node:async_hooks'\nimport { Hook, Restorer, asyncHooks } from '.'\n\nconst hooks = new Set<Hook>()\nconst restorersPerAsyncId = new Map<number, Set<Restorer>>()\nconst undoersPerAsyncId = new Map<number, Set<() => void>>()\n\ncreateHook({\n\tinit(asyncId) {\n\t\tconst restorers = new Set<Restorer>()\n\t\tfor (const hook of hooks) {\n\t\t\trestorers.add(hook())\n\t\t}\n\t\trestorersPerAsyncId.set(asyncId, restorers)\n\t},\n\tbefore(asyncId) {\n\t\tconst restorers = restorersPerAsyncId.get(asyncId)\n\t\tif (restorers) {\n\t\t\tconst undoers = new Set<() => void>()\n\t\t\tfor (const restore of restorers) {\n\t\t\t\tundoers.add(restore())\n\t\t\t}\n\t\t\tundoersPerAsyncId.set(asyncId, undoers)\n\t\t}\n\t},\n\tafter(asyncId) {\n\t\tconst undoers = undoersPerAsyncId.get(asyncId)\n\t\tif (undoers) {\n\t\t\tfor (const undo of undoers) undo()\n\t\t\tundoersPerAsyncId.delete(asyncId)\n\t\t}\n\t},\n\tdestroy(asyncId) {\n\t\trestorersPerAsyncId.delete(asyncId)\n\t\tundoersPerAsyncId.delete(asyncId)\n\t}\n}).enable()\n\nasyncHooks.addHook = function (hook: Hook) {\n\thooks.add(hook)\n\treturn () => {\n\t\thooks.delete(hook)\n\t}\n}\n\nexport * from '../index'\n"],"names":["createHook","asyncHooks"],"mappings":";;;;;AAGA,MAAM,KAAK,GAAG,IAAI,GAAG,EAAQ;AAC7B,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAyB;AAC5D,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA2B;AAE5DA,2BAAU,CAAC;AACV,IAAA,IAAI,CAAC,OAAO,EAAA;AACX,QAAA,MAAM,SAAS,GAAG,IAAI,GAAG,EAAY;AACrC,QAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACzB,YAAA,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACtB;AACA,QAAA,mBAAmB,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5C,CAAC;AACD,IAAA,MAAM,CAAC,OAAO,EAAA;QACb,MAAM,SAAS,GAAG,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC;QAClD,IAAI,SAAS,EAAE;AACd,YAAA,MAAM,OAAO,GAAG,IAAI,GAAG,EAAc;AACrC,YAAA,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE;AAChC,gBAAA,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACvB;AACA,YAAA,iBAAiB,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;QACxC;IACD,CAAC;AACD,IAAA,KAAK,CAAC,OAAO,EAAA;QACZ,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC;QAC9C,IAAI,OAAO,EAAE;YACZ,KAAK,MAAM,IAAI,IAAI,OAAO;AAAE,gBAAA,IAAI,EAAE;AAClC,YAAA,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC;QAClC;IACD,CAAC;AACD,IAAA,OAAO,CAAC,OAAO,EAAA;AACd,QAAA,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC;AACnC,QAAA,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC;IAClC;CACA,CAAC,CAAC,MAAM,EAAE;AAEXC,gBAAU,CAAC,OAAO,GAAG,UAAU,IAAU,EAAA;AACxC,IAAA,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;AACf,IAAA,OAAO,MAAK;AACX,QAAA,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;AACnB,IAAA,CAAC;AACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -68,8 +68,6 @@ export interface Register<T, K extends PropertyKey = PropertyKey> extends Iterab
68
68
  }
69
69
 
70
70
  export declare function register<T, K extends PropertyKey = PropertyKey>(keyFn: (item: T) => K, initial?: Iterable<T>): Register<T, K>;
71
- export declare function mapped<T, U>(inputs: readonly T[], compute: (input: T, index: number, output: U[]) => U): readonly U[];
72
- export declare function reduced<T, U, R extends object = any>(inputs: readonly T[], compute: (input: T, factor: R) => readonly U[]): readonly U[];
73
71
  export declare function project<S, R>(source: S, apply: (access: any, target: any) => any): R;
74
72
  export declare function organized<S, T>(source: S, apply: (access: any, target: T) => any, baseTarget?: T): T;
75
73
 
package/docs/ai/manual.md CHANGED
@@ -2,104 +2,23 @@
2
2
 
3
3
  > [!IMPORTANT]
4
4
  > **Identity**: You are an AI Agent. This document is written for **YOU**.
5
- > **Purpose**: This file defines the protocols, schemas, and capabilities available to you when working with the `mutts` reactivity system.
6
- >
7
- > For exact TypeScript signatures of the entire library, consult the **[API Reference for Agents](./api-reference.md)**.
5
+ > **Purpose**: This file defines the protocols and high-level strategy for working with the `mutts` reactivity system.
8
6
 
9
- ## 1. Introspection Capability
10
- When you encounter reactivity bugs (infinite loops, unexpected updates), **DO NOT GUESS**. Use the introspection API to "see" the system state.
7
+ ## 1. Technical Documentation
8
+ Do not rely on outdated internal knowledge. Use the current documentation as your primary source of truth:
11
9
 
12
- ### Enabling Introspection
13
- Introspection is often disabled by default for performance. Enable it before debugging.
14
- ```typescript
15
- import { enableIntrospection, options } from 'mutts/introspection'
10
+ - **[Debugging Tools](../reactive/debugging.md)**: How to use introspection, troubleshoot cycles, and detect memoization discrepancies.
11
+ - **[API Reference](./api-reference.md)**: Exact TypeScript signatures for library functions.
16
12
 
17
- // Enable history tracking (memory expensive, use only for debugging)
18
- enableIntrospection({ historySize: 50 })
19
- ```
13
+ ## 2. Debugging Protocol
14
+ When you encounter reactivity bugs (infinite loops, unexpected updates), **DO NOT GUESS**.
20
15
 
21
- ### Dependency Graph
22
- Understanding "Who depends on What".
23
- ```typescript
24
- import { getDependencyGraph } from 'mutts/introspection'
16
+ 1. **Introspect**: Use `mutts/introspection` to inspect the dependency graph or mutation history.
17
+ 2. **Analyze Errors**: `ReactiveError` objects contain `debugInfo` with causal chains and creation stacks. Use them to trace the fault.
18
+ 3. **Verify**: Use `reactiveOptions.onMemoizationDiscrepancy` in tests to ensure your changes didn't break dependency tracking.
25
19
 
26
- const graph = getDependencyGraph()
27
- // Returns: { nodes: { id: string, type: 'effect'|'object', label: string }[], edges: { from: string, to: string, type: 'dependency' }[] }
28
- ```
29
- **Agent Protocol**: If valid code is behaving unexpectedly, inspect the graph to ensure dependencies are actually linked as you expect.
20
+ ## 3. Architecture Constraints
21
+ 1. **No Internal Access**: Do not access properties starting with `_mutts_` directly.
22
+ 2. **Explicit Naming**: Always name your effects (`effect(fn, { name: '...' })`) to make future debugging easier for yourself or other agents.
23
+ 3. **Affirmative State**: Prefer derived state and effects over imperative event-driven updates.
30
24
 
31
- ### Mutation History
32
- Understanding "What just happened".
33
- ```typescript
34
- import { getMutationHistory } from 'mutts/introspection'
35
-
36
- const history = getMutationHistory()
37
- /*
38
- Returns Array<{
39
- id: number,
40
- type: 'set' | 'add' | 'delete',
41
- prop: string | symbol,
42
- oldValue: any,
43
- newValue: any,
44
- objectName: string, // "Human readable name"
45
- source: string, // "Effect X" or "External"
46
- timestamp: number
47
- }>
48
- */
49
- ```
50
- **Agent Protocol**: When diagnosing "why is this value wrong?", check the *last mutation* of that property in history.
51
-
52
- ## 2. Structured Error Handling
53
- `mutts` throws `ReactiveError` instances. These are designed to be machine-parseable.
54
-
55
- ### ReactiveErrorCode
56
- Always check `error.debugInfo.code`.
57
- ```typescript
58
- enum ReactiveErrorCode {
59
- CycleDetected = 'CYCLE_DETECTED',
60
- MaxDepthExceeded = 'MAX_DEPTH_EXCEEDED',
61
- MaxReactionExceeded = 'MAX_REACTION_EXCEEDED',
62
- WriteInComputed = 'WRITE_IN_COMPUTED',
63
- TrackingError = 'TRACKING_ERROR'
64
- }
65
- ```
66
-
67
- ### Debugging Protocols
68
-
69
- #### Protocol: Handling `CycleDetected` / `MaxDepthExceeded`
70
- **Symptom**: `ReactiveError` with code `CycleDetected` or `MaxDepthExceeded`.
71
- **Action**:
72
- 1. Read `error.debugInfo.cycle` (Array of effect names).
73
- 2. **CRITICAL**: Read `error.debugInfo.causalChain`.
74
- * It tells you the *logical path*: `Effect A` -> (modifies `x`) -> `Effect B` -> (modifies `y`) -> `Effect A`.
75
- 3. **CRITICAL**: Read `error.debugInfo.creationStack`.
76
- * This gives you the **File path and Line number** where the problematic effect was defined.
77
-
78
- **Example Error Object**:
79
- ```json
80
- {
81
- "message": "[reactive] Max effect chain reached...",
82
- "debugInfo": {
83
- "code": "MAX_DEPTH_EXCEEDED",
84
- "causalChain": [
85
- "Effect(Anonymous) -> (set 'count') -> Effect(Display)",
86
- "Effect(Display) -> (set 'dummy') -> Effect(Anonymous)"
87
- ],
88
- "creationStack": " at tests/my-test.ts:45:10\n at ...",
89
- "cycle": ["Effect(Anonymous)", "Effect(Display)"]
90
- }
91
- }
92
- ```
93
-
94
- ## 3. Strict Mode
95
- If you are writing new code that might be complex, verify it with "Strict Mode".
96
- This forces a graph check *before* execution, preventing infinite loops from hanging the runtime.
97
- ```typescript
98
- import { options } from 'mutts/introspection'
99
- options.cycleHandling = 'strict'
100
- ```
101
-
102
- ## 4. Architecture Constraints for Agents
103
- 1. **Do not** access properties starting with `_mutts_` directly unless instructed. These are internal implementation details.
104
- 2. **Do not** rely on `batchQueue` global state in your reasoning; it is ephemeral.
105
- 3. **Do** name your effects when possible (`effect(() => {}, { name: 'MyEffect' })`) to make your own future debugging easier.
@@ -1161,120 +1161,16 @@ class Example {
1161
1161
  }
1162
1162
  ```
1163
1163
 
1164
- ### Working with `mapped()`
1165
-
1166
- Pair `memoize()` with [`mapped()`](#mapped) to keep derived array elements stable across reorders (see [Identity-preserving mapped arrays](#identity-preserving-mapped-arrays)). Memoizing the mapper ensures each input object is processed at most once and its derived state persists while the input reference lives.
1167
-
1168
1164
  ## Debugging and Development
1169
1165
 
1170
- ### Cycle Detection
1171
-
1172
- The reactive system automatically detects circular dependencies between effects. When one effect triggers another effect that eventually triggers the first effect again, a cycle is detected.
1173
-
1174
- #### Cycle Detection Behavior
1175
-
1176
- By default, cycles are detected and an error is thrown. You can configure the behavior using `reactiveOptions.cycleHandling`:
1177
-
1178
- ```typescript
1179
- import { reactiveOptions } from 'mutts/reactive'
1180
-
1181
- // Options: 'throw' (default), 'warn', or 'break'
1182
- reactiveOptions.cycleHandling = 'warn' // Warn instead of throwing
1183
- reactiveOptions.cycleHandling = 'break' // Silently break the cycle
1184
- ```
1185
-
1186
- **Cycle handling modes:**
1187
-
1188
- - **`'throw'`** (default): Throws a `ReactiveError` with a detailed cycle path when a cycle is detected
1189
- - **`'warn'`**: Logs a warning message with the cycle path but continues execution (breaks the cycle)
1190
- - **`'break'`**: Silently breaks the cycle without any message
1191
- - **`'strict'`**: Checks the graph BEFORE execution. Prevents infinite loops at the source (higher overhead).
1192
-
1193
- #### Cycle Error Messages
1194
-
1195
- When a cycle is detected, the error message includes the full cycle path showing which effects form the cycle:
1196
-
1197
- ```typescript
1198
- const state = reactive({ a: 0, b: 0, c: 0 })
1199
-
1200
- effect(() => {
1201
- state.b = state.a + 1 // Effect A
1202
- })
1203
-
1204
- effect(() => {
1205
- state.c = state.b + 1 // Effect B
1206
- })
1207
-
1208
- // This will throw with a detailed cycle path
1209
- try {
1210
- effect(() => {
1211
- state.a = state.c + 1 // Effect C - creates cycle: A → B → C → A
1212
- })
1213
- } catch (e) {
1214
- console.error(e.message)
1215
- // "[reactive] Cycle detected: effectA → effectB → effectC → effectA"
1216
- }
1217
- ```
1218
-
1219
- The cycle path shows the sequence of effects that form the circular dependency, making it easier to identify and fix the issue.
1220
-
1221
- #### Common Cycle Patterns
1222
-
1223
- **Direct cycle:**
1224
- ```typescript
1225
- const state = reactive({ a: 0, b: 0 })
1226
-
1227
- effect(() => {
1228
- state.b = state.a + 1 // Effect A
1229
- })
1230
-
1231
- effect(() => {
1232
- state.a = state.b + 1 // Effect B - creates cycle: A → B → A
1233
- })
1234
- ```
1235
-
1236
- **Indirect cycle:**
1237
- ```typescript
1238
- const state = reactive({ a: 0, b: 0, c: 0 })
1239
-
1240
- effect(() => {
1241
- state.b = state.a + 1 // Effect A
1242
- })
1243
-
1244
- effect(() => {
1245
- state.c = state.b + 1 // Effect B
1246
- })
1247
-
1248
- effect(() => {
1249
- state.a = state.c + 1 // Effect C - creates cycle: A → B → C → A
1250
- })
1251
- ```
1252
-
1253
- #### Preventing Cycles
1254
-
1255
- To avoid cycles, consider:
1166
+ The `mutts` reactive system includes built-in tools for troubleshooting complex dependency graphs and identifying performance bottlenecks.
1256
1167
 
1257
- 1. **Separate read and write effects**: Don't have an effect that both reads and writes the same reactive properties
1258
- 2. **Use `untracked()`**: For operations that shouldn't create dependencies
1259
- 3. **Use `atomic()`**: To batch operations and prevent intermediate triggers
1260
- 4. **Restructure logic**: Break circular dependencies by introducing intermediate state or computed values
1168
+ For a full guide on debugging, including cycle detection and memoization discrepancy tools, see the dedicated **[Debugging Tools](./debugging.md)** documentation.
1261
1169
 
1262
- **Example - Using `untracked()` to break cycles:**
1263
- ```typescript
1264
- const state = reactive({ count: 0 })
1265
-
1266
- effect(() => {
1267
- // Read count
1268
- const current = state.count
1269
-
1270
- // Write to count without creating a dependency cycle
1271
- untracked(() => {
1272
- if (current < 10) {
1273
- state.count = current + 1
1274
- }
1275
- })
1276
- })
1277
- ```
1170
+ ### Quick Summary
1278
1171
 
1279
- **Note:** Self-loops (an effect reading and writing the same property, like `obj.prop++`) are automatically ignored and do not create dependency relationships or cycles.
1172
+ - **Cycle Detection**: Automatically catch circular dependencies via `reactiveOptions.cycleHandling`. Note: Instant mathematical detection requires choosing a mode other than `'none'`.
1173
+ - **Flat Mode**: The default `reactiveOptions.cycleHandling = 'none'` provides maximum performance in high-frequency update scenarios by disabling graph maintenance.
1174
+ - **Memoization Discrepancy**: Detect "missing dependencies" by running computations twice during development using `reactiveOptions.onMemoizationDiscrepancy`.
1175
+ - **Global Hooks**: Use `reactiveOptions.touched`, `enter`, and `leave` to observe system activity.
1280
1176
 
@@ -352,115 +352,6 @@ Notes:
352
352
  - Assigning to an index (`list[i] = value`) uses the key function to bind that slot to `value`’s key.
353
353
 
354
354
  ## Class Reactivity
355
- ## Array Mapping
356
-
357
- ### `mapped()`
358
-
359
- Creates a reactive array by mapping over an input array. The mapper receives the current item value, its index, and the previous mapped value for that index.
360
-
361
- ```typescript
362
- import { mapped, reactive } from 'mutts/reactive'
363
-
364
- const input = reactive([1, 2, 3])
365
- const doubles = mapped(input, (value, index, oldValue) => value * 2)
366
-
367
- console.log(doubles) // [2, 4, 6]
368
-
369
- // When input changes, the mapped output updates in place
370
- input.push(4)
371
- console.log(doubles) // [2, 4, 6, 8]
372
- ```
373
-
374
- **Mapper signature:**
375
-
376
- ```typescript
377
- (value: T, index: number, oldValue?: U) => U
378
- ```
379
-
380
- - **value**: current element from the input array
381
- - **index**: current element index
382
- - **oldValue**: previously computed value at the same index (useful for incremental updates)
383
-
384
- **Key features:**
385
-
386
- - **Live reactivity**: Output array updates when the input array changes (push/pop/splice/assignments).
387
- - **Granular recompute**: Only indices that change are recomputed; `oldValue` enables incremental updates.
388
- - **Simple contract**: Mapper works directly with `(value, index, oldValue)` and can freely return reactive objects.
389
-
390
- **Performance characteristics:**
391
-
392
- ```typescript
393
- const users = reactive([
394
- { name: 'John', age: 30 },
395
- { name: 'Jane', age: 25 }
396
- ])
397
-
398
- let computeCount = 0
399
- const processedUsers = mapped(users, (user) => {
400
- computeCount++
401
- return `${user.name} (${user.age})`
402
- })
403
-
404
- console.log(computeCount) // 2 (initial computation)
405
-
406
- // Modify one user - only that index recomputes
407
- users[0].age = 31
408
- console.log(processedUsers[0]) // "John (31)"
409
- console.log(computeCount) // 3
410
- ```
411
-
412
- **Advanced usage:**
413
-
414
- ```typescript
415
- const orders = reactive([
416
- { items: [{ price: 10 }, { price: 20 }] },
417
- { items: [{ price: 15 }] }
418
- ])
419
-
420
- const orderTotals = mapped(orders, (order) => (
421
- order.items.reduce((sum, item) => sum + item.price, 0)
422
- ))
423
- ```
424
-
425
- ### Identity-preserving mapped arrays
426
-
427
- Combine `mapped()` with [`memoize()`](#memoize) when you need to reuse mapped results for the same input identity. The memoized mapper runs at most once per input object, even when the source array is reordered, and it can host additional reactive state that should survive reordering.
428
-
429
- ```typescript
430
- import { effect, mapped, memoize, reactive } from 'mutts/reactive'
431
-
432
- const inputs = reactive([{ name: 'John' }, { name: 'Jane' }])
433
-
434
- const memoizedCard = memoize((user: { name: string }) => {
435
- const view: { name?: string; setName(next: string): void } = {
436
- setName(next) {
437
- user.name = next
438
- },
439
- }
440
-
441
- effect(() => {
442
- view.name = user.name.toUpperCase()
443
- })
444
-
445
- return view
446
- })
447
-
448
- const cards = mapped(inputs, (user) => memoizedCard(user))
449
-
450
- cards[0].setName('Johnny')
451
- console.log(cards[0].name) // 'JOHNNY'
452
-
453
- // Reorder: cached output follows the original object
454
- const first = inputs.shift()!
455
- inputs.push(first)
456
- console.log(cards[1].name) // still 'JOHNNY'
457
- ```
458
-
459
- Use this pattern when:
460
-
461
- - You are mapping an array of reactive objects and want to keep derived objects stable across reorders.
462
- - The mapper returns objects with internal state or nested effects that should survive reordering.
463
- - You prefer to share memoized helpers across multiple mapped arrays.
464
355
 
465
356
  ## Projection
466
357
 
@@ -468,8 +359,6 @@ Use this pattern when:
468
359
 
469
360
  `project()` provides a unified API for transforming reactive collections (arrays, records, and maps) into new reactive collections. Each source entry gets its own reactive effect that recomputes only when that specific entry changes, enabling granular updates perfect for rendering pipelines.
470
361
 
471
- **Note:** `project()` is the modern replacement for `mapped()`. It offers the same per-entry reactivity benefits but works across all collection types with a consistent API.
472
-
473
362
  #### Basic Usage
474
363
 
475
364
  ```typescript
@@ -617,23 +506,10 @@ result[cleanup]() // Stops all effects and cleans up
617
506
  - **Data Transformation**: Convert between collection types while maintaining reactivity
618
507
  - **Performance Optimization**: Avoid full recomputation when only a few entries change
619
508
 
620
- #### Comparison with `mapped()`
621
-
622
- `project()` is designed to eventually replace `mapped()`. Key differences:
623
-
624
- - **Unified API**: Works with arrays, records, and maps (vs. `mapped()` only for arrays)
625
- - **Access Pattern**: Uses an access object with `get()`/`set()` instead of direct value/index parameters
626
- - **Automatic Target Creation**: Creates its own reactive target container (no need to provide a base target)
627
- - **Consistent Behavior**: Same per-entry reactivity model across all collection types
628
-
629
- For new code, prefer `project()` over `mapped()`. Existing `mapped()` code will continue to work, but consider migrating for better consistency and future features.
630
-
631
509
  ## Record Organization
632
510
 
633
511
  ### `organized()`
634
512
 
635
- `organized()` is the record companion to [`mapped()`](#mapped). Instead of iterating over numeric indices, it reacts to property additions, updates, and deletions on any `Record<PropertyKey, T>` (plain objects, dictionaries, even reactive proxies) and lets you build **whatever target structure you need**—a new record, nested buckets, a `Map`, or a more elaborate object with metadata.
636
-
637
513
  ```typescript
638
514
  import { cleanup, organized, reactive } from 'mutts/reactive'
639
515
 
@@ -677,7 +553,6 @@ function organized<
677
553
 
678
554
  Under the hood there is:
679
555
 
680
- - One effect watching `Reflect.ownKeys(source)` (similar to how `mapped()` tracks `length`)
681
556
  - A child effect per key that re-runs whenever that key’s value changes, automatically reusing and replacing the cleanup you returned.
682
557
  - Automatic disposal when keys disappear or when `target[cleanup]()` is invoked.
683
558