mutts 1.0.13 → 1.0.15

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 (54) hide show
  1. package/BROWSER_ASYNC_POLYFILL.md +79 -0
  2. package/README.md +2 -2
  3. package/dist/browser.cjs +216 -97
  4. package/dist/browser.cjs.map +1 -1
  5. package/dist/browser.d.ts +42 -9
  6. package/dist/browser.dev.cjs +81 -71
  7. package/dist/browser.dev.cjs.map +1 -1
  8. package/dist/browser.dev.d.ts +2 -2
  9. package/dist/browser.dev.esm.js +2 -2
  10. package/dist/browser.esm.js +137 -28
  11. package/dist/browser.esm.js.map +1 -1
  12. package/dist/chunks/{proxy-BtmPFjSr.esm.js → effects-CPjf6gNA.esm.js} +2605 -2155
  13. package/dist/chunks/effects-CPjf6gNA.esm.js.map +1 -0
  14. package/dist/chunks/{proxy-DBHj3kGK.cjs → effects-oUauWxxl.cjs} +2615 -2156
  15. package/dist/chunks/effects-oUauWxxl.cjs.map +1 -0
  16. package/dist/chunks/{index-CAdnMJev.cjs → index-Dtj2qZ0d.cjs} +418 -350
  17. package/dist/chunks/index-Dtj2qZ0d.cjs.map +1 -0
  18. package/dist/chunks/{index-XsYTUhHx.esm.js → index-YGpb1te7.esm.js} +156 -88
  19. package/dist/chunks/index-YGpb1te7.esm.js.map +1 -0
  20. package/dist/chunks/node-CKuro-Uk.cjs +187 -0
  21. package/dist/chunks/node-CKuro-Uk.cjs.map +1 -0
  22. package/dist/chunks/node-sQtns7M-.esm.js +185 -0
  23. package/dist/chunks/node-sQtns7M-.esm.js.map +1 -0
  24. package/dist/debug.cjs +76 -49
  25. package/dist/debug.cjs.map +1 -1
  26. package/dist/debug.esm.js +37 -10
  27. package/dist/debug.esm.js.map +1 -1
  28. package/dist/mutts.umd.js +4169 -3532
  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 +82 -72
  33. package/dist/node.cjs.map +1 -1
  34. package/dist/node.d.ts +2 -2
  35. package/dist/node.dev.cjs +82 -72
  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.d.ts +30 -15
  41. package/docs/ai/api-reference.md +3 -1
  42. package/docs/ai/manual.md +17 -5
  43. package/docs/reactive/advanced.md +169 -10
  44. package/docs/reactive/debugging.md +15 -13
  45. package/docs/reactive.md +2 -1
  46. package/package.json +12 -7
  47. package/dist/chunks/index-CAdnMJev.cjs.map +0 -1
  48. package/dist/chunks/index-XsYTUhHx.esm.js.map +0 -1
  49. package/dist/chunks/node-DrrphEPf.cjs +0 -98
  50. package/dist/chunks/node-DrrphEPf.cjs.map +0 -1
  51. package/dist/chunks/node-NEZvVo4M.esm.js +0 -96
  52. package/dist/chunks/node-NEZvVo4M.esm.js.map +0 -1
  53. package/dist/chunks/proxy-BtmPFjSr.esm.js.map +0 -1
  54. package/dist/chunks/proxy-DBHj3kGK.cjs.map +0 -1
package/dist/debug.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var proxy = require('./chunks/proxy-DBHj3kGK.cjs');
3
+ var effects = require('./chunks/effects-oUauWxxl.cjs');
4
4
 
5
5
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
6
6
  const lineageObjects = new WeakSet();
@@ -48,10 +48,10 @@ function parseStackFrames(stack) {
48
48
  if (!rawStack)
49
49
  return [];
50
50
  const lines = rawStack.split('\n');
51
- const lastLine = lines.findIndex((line) => line.includes(proxy.effectMarker.enter));
51
+ const lastLine = lines.findIndex((line) => line.includes(effects.effectMarker.enter));
52
52
  if (lastLine !== -1)
53
53
  lines.splice(lastLine);
54
- const firstLine = lines.findLastIndex((line) => line.includes(proxy.effectMarker.leave));
54
+ const firstLine = lines.findLastIndex((line) => line.includes(effects.effectMarker.leave));
55
55
  if (firstLine !== -1)
56
56
  lines.splice(0, firstLine + 1);
57
57
  else {
@@ -134,7 +134,7 @@ function ensureSignature(signature) {
134
134
  }
135
135
  function getLineage(effect, currentStack = new Error()) {
136
136
  return ensureSignature({
137
- effect: effect ?? proxy.getActiveEffect(),
137
+ effect: effect ?? effects.getActiveEffect(),
138
138
  stack: currentStack,
139
139
  toString() {
140
140
  return formatLineage(this);
@@ -163,13 +163,13 @@ function digestLineage(lineage) {
163
163
  let current = currentEffect;
164
164
  let lastStack = currentStack;
165
165
  while (current) {
166
- const rootFn = proxy.getRoot(current);
166
+ const rootFn = effects.getRoot(current);
167
167
  segments.push({
168
168
  effect: rootFn,
169
169
  effectName: rootFn.name || 'anonymous',
170
170
  stack: lastStack,
171
171
  });
172
- const node = proxy.getEffectNode(current);
172
+ const node = effects.getEffectNode(current);
173
173
  const parent = node.parent;
174
174
  const creationStack = parseStackFrames(node.creationStack);
175
175
  if (parent) {
@@ -197,7 +197,7 @@ function formatLineage(lineage) {
197
197
  const segment = segments[i];
198
198
  if (i > 0) {
199
199
  const triggerEffect = segments[i - 1].effect;
200
- const triggerName = triggerEffect ? proxy.getRoot(triggerEffect).name || 'anonymous' : 'root';
200
+ const triggerName = triggerEffect ? effects.getRoot(triggerEffect).name || 'anonymous' : 'root';
201
201
  result.push(` --- effect: ${triggerName} ---`);
202
202
  }
203
203
  for (const frame of segment.stack)
@@ -510,21 +510,21 @@ function renderLineageList(details, colors) {
510
510
  function formatReasonWithoutChain(reason) {
511
511
  switch (reason.type) {
512
512
  case 'propChange':
513
- return proxy.formatCleanupReason({ type: 'propChange', triggers: reason.triggers });
513
+ return effects.formatCleanupReason({ type: 'propChange', triggers: reason.triggers });
514
514
  case 'invalidate':
515
- return proxy.formatCleanupReason({ type: 'invalidate', cause: reason.cause });
515
+ return effects.formatCleanupReason({ type: 'invalidate', cause: reason.cause });
516
516
  case 'stopped':
517
- return proxy.formatCleanupReason(reason.detail ? { type: 'stopped', detail: reason.detail } : { type: 'stopped' });
517
+ return effects.formatCleanupReason(reason.detail ? { type: 'stopped', detail: reason.detail } : { type: 'stopped' });
518
518
  case 'external':
519
- return proxy.formatCleanupReason({ type: 'external', detail: reason.detail });
519
+ return effects.formatCleanupReason({ type: 'external', detail: reason.detail });
520
520
  case 'gc':
521
- return proxy.formatCleanupReason({ type: 'gc' });
521
+ return effects.formatCleanupReason({ type: 'gc' });
522
522
  case 'lineage':
523
- return proxy.formatCleanupReason({ type: 'lineage', parent: reason.parent });
523
+ return effects.formatCleanupReason({ type: 'lineage', parent: reason.parent });
524
524
  case 'error':
525
- return proxy.formatCleanupReason({ type: 'error', error: reason.error });
525
+ return effects.formatCleanupReason({ type: 'error', error: reason.error });
526
526
  case 'multiple':
527
- return proxy.formatCleanupReason({ type: 'multiple', reasons: reason.reasons });
527
+ return effects.formatCleanupReason({ type: 'multiple', reasons: reason.reasons });
528
528
  }
529
529
  }
530
530
  function logReason(reason, tag) {
@@ -667,7 +667,7 @@ function showLineagePanel() {
667
667
  atText: '#999',
668
668
  linkText: '#005cc5',
669
669
  };
670
- const state = proxy.reactive({
670
+ const state = effects.reactive({
671
671
  activeLineage: [],
672
672
  isVisible: true,
673
673
  });
@@ -731,13 +731,13 @@ function showLineagePanel() {
731
731
  panel.appendChild(content);
732
732
  document.body.appendChild(panel);
733
733
  // Reactivity: Update Visibility
734
- proxy.effect(() => {
734
+ effects.effect `lineage-panel:visibility`(() => {
735
735
  panel.style.opacity = state.isVisible ? '1' : '0';
736
736
  panel.style.pointerEvents = state.isVisible ? 'all' : 'none';
737
737
  panel.style.transform = state.isVisible ? 'translateY(0)' : 'translateY(20px)';
738
738
  });
739
739
  // Reactivity: Update Content
740
- proxy.effect(() => {
740
+ effects.effect `lineage-panel:content`(() => {
741
741
  if (state.activeLineage.length === 0) {
742
742
  content.innerHTML = `<div style="color: ${colors.placeholderText}; font-style: italic; text-align: center; margin-top: 20px;">No effect triggered yet...</div>`;
743
743
  return;
@@ -756,7 +756,7 @@ function showLineagePanel() {
756
756
  marginBottom: '6px',
757
757
  color: colors.titleText,
758
758
  });
759
- const effectName = segment.effect ? (proxy.getRoot(segment.effect).name || 'anonymous') : 'root';
759
+ const effectName = segment.effect ? (effects.getRoot(segment.effect).name || 'anonymous') : 'root';
760
760
  title.innerText = i === 0 ? `📍 Current: ${effectName}` : `↖ Effect: ${effectName}`;
761
761
  segDiv.appendChild(title);
762
762
  segment.stack.forEach(frame => {
@@ -779,6 +779,35 @@ function showLineagePanel() {
779
779
  });
780
780
  }
781
781
 
782
+ function getColors() {
783
+ const isDark = typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches;
784
+ return {
785
+ accent: isDark ? '#b392f0' : '#6f42c1',
786
+ meta: isDark ? '#8b949e' : '#57606a',
787
+ };
788
+ }
789
+ function getReactiveTarget(obj) {
790
+ if (!obj || typeof obj !== 'object' || !effects.isReactive(obj))
791
+ return undefined;
792
+ return effects.unwrap(obj);
793
+ }
794
+ const reactiveFormatter = {
795
+ header: (obj) => {
796
+ const target = getReactiveTarget(obj);
797
+ if (!target)
798
+ return null;
799
+ const colors = getColors();
800
+ return [
801
+ 'span',
802
+ {},
803
+ ['span', { style: `color: ${colors.accent}; font-weight: bold;` }, 'Reactive<'],
804
+ ['object', { object: target }],
805
+ ['span', { style: `color: ${colors.accent}; font-weight: bold;` }, '>'],
806
+ ];
807
+ },
808
+ hasBody: () => false,
809
+ };
810
+
782
811
  /**
783
812
  * Debug utilities for the reactivity system
784
813
  * - Captures effect metadata (names, parent relationships)
@@ -789,7 +818,7 @@ function showLineagePanel() {
789
818
  * Log an error with detailed context if error logging is enabled
790
819
  */
791
820
  function logError(error, context, effect) {
792
- if (!proxy.options.introspection?.logErrors)
821
+ if (!effects.options.introspection?.logErrors)
793
822
  return;
794
823
  const contextStr = context === 'throw' ? '🔴 Thrown' : '🟡 Caught';
795
824
  console.group(`${contextStr} Error: ${error.message}`);
@@ -815,7 +844,7 @@ const triggerGraph = new Map();
815
844
  function ensureEffectName(effect) {
816
845
  let name = effectNames.get(effect);
817
846
  if (!name) {
818
- const root = proxy.getRoot(effect);
847
+ const root = effects.getRoot(effect);
819
848
  name = root?.name?.trim() || `effect_${++effectCounter}`;
820
849
  }
821
850
  effectNames.set(effect, name);
@@ -835,7 +864,7 @@ function ensureObjectName(obj) {
835
864
  }
836
865
  function describeProp(obj, prop) {
837
866
  const objectName = ensureObjectName(obj);
838
- if (prop === proxy.allProps)
867
+ if (prop === effects.allProps)
839
868
  return `${objectName}.*`;
840
869
  if (typeof prop === 'symbol')
841
870
  return `${objectName}.${prop.description ?? prop.toString()}`;
@@ -845,7 +874,7 @@ function addEffectToRegistry(effect) {
845
874
  if (!effect || debugEffectRegistry.has(effect))
846
875
  return;
847
876
  debugEffectRegistry.add(effect);
848
- const deps = proxy.effectToReactiveObjects.get(effect);
877
+ const deps = effects.effectToReactiveObjects.get(effect);
849
878
  if (deps) {
850
879
  for (const obj of deps) {
851
880
  documentObject(obj);
@@ -861,13 +890,13 @@ function dbRegisterObject(obj) {
861
890
  debugObjectRegistry.add(obj);
862
891
  ensureObjectName(obj);
863
892
  }
864
- function ensureParentChains(effects) {
865
- const queue = Array.from(effects);
893
+ function ensureParentChains(effects$1) {
894
+ const queue = Array.from(effects$1);
866
895
  for (let i = 0; i < queue.length; i++) {
867
896
  const effect = queue[i];
868
- const parent = proxy.getEffectNode(effect).parent;
869
- if (parent && !effects.has(parent)) {
870
- effects.add(parent);
897
+ const parent = effects.getEffectNode(effect).parent;
898
+ if (parent && !effects$1.has(parent)) {
899
+ effects$1.add(parent);
871
900
  queue.push(parent);
872
901
  }
873
902
  }
@@ -932,7 +961,7 @@ function registerObjectForDebug(obj) {
932
961
  * @param evolution - The type of change (set/add/del/bunch)
933
962
  */
934
963
  function recordTriggerLink(source, target, obj, prop, evolution) {
935
- if (proxy.options.introspection?.enableHistory) {
964
+ if (effects.options.introspection?.enableHistory) {
936
965
  addToMutationHistory(source, target, obj, prop, evolution);
937
966
  }
938
967
  if (!devtoolsEnabled)
@@ -1014,14 +1043,14 @@ function buildEffectNodes(allEffects) {
1014
1043
  const cached = depthCache.get(effect);
1015
1044
  if (cached !== undefined)
1016
1045
  return cached;
1017
- const parent = proxy.getEffectNode(effect).parent;
1046
+ const parent = effects.getEffectNode(effect).parent;
1018
1047
  const depth = computeDepth(parent) + (parent ? 1 : 0);
1019
1048
  depthCache.set(effect, depth);
1020
1049
  return depth;
1021
1050
  };
1022
1051
  for (const [effect, node] of nodeByEffect) {
1023
1052
  node.depth = computeDepth(effect);
1024
- const parent = proxy.getEffectNode(effect).parent;
1053
+ const parent = effects.getEffectNode(effect).parent;
1025
1054
  if (parent) {
1026
1055
  const parentNode = nodeByEffect.get(parent);
1027
1056
  if (parentNode) {
@@ -1063,7 +1092,7 @@ function buildReactivityGraph() {
1063
1092
  const effectId = nodeIds.get(effect);
1064
1093
  if (!effectId)
1065
1094
  continue;
1066
- const deps = proxy.effectToReactiveObjects.get(effect);
1095
+ const deps = effects.effectToReactiveObjects.get(effect);
1067
1096
  if (!deps)
1068
1097
  continue;
1069
1098
  for (const obj of deps) {
@@ -1126,8 +1155,8 @@ function enableDevTools() {
1126
1155
  if (devtoolsEnabled)
1127
1156
  return;
1128
1157
  devtoolsEnabled = true;
1129
- if (proxy.options.introspection) {
1130
- proxy.options.introspection.logErrors = true;
1158
+ if (effects.options.introspection) {
1159
+ effects.options.introspection.logErrors = true;
1131
1160
  }
1132
1161
  globalScope.__MUTTS_DEBUG__ = {
1133
1162
  getGraph: buildReactivityGraph,
@@ -1155,22 +1184,19 @@ function enableDevTools() {
1155
1184
  * @type {() => import('../src/reactive/types').CleanupReason | undefined}
1156
1185
  */
1157
1186
  get reason() {
1158
- const activeEffect = proxy.getActiveEffect();
1187
+ const activeEffect = effects.getActiveEffect();
1159
1188
  if (!activeEffect)
1160
1189
  return undefined;
1161
- const node = proxy.getEffectNode(activeEffect);
1190
+ const node = effects.getEffectNode(activeEffect);
1162
1191
  return node?.currentReason;
1163
1192
  },
1164
1193
  };
1165
1194
  // @ts-ignore - devtoolsFormatters is a Chrome-specific array
1166
- if (globalScope.devtoolsFormatters) {
1167
- globalScope.devtoolsFormatters.push(lineageFormatter);
1168
- globalScope.devtoolsFormatters.push(reasonFormatter);
1169
- }
1170
- else {
1171
- globalScope.devtoolsFormatters = [lineageFormatter, reasonFormatter];
1172
- }
1173
- proxy.setDebugHooks({
1195
+ if (globalScope.devtoolsFormatters)
1196
+ globalScope.devtoolsFormatters.push(lineageFormatter, reasonFormatter, reactiveFormatter);
1197
+ else
1198
+ globalScope.devtoolsFormatters = [lineageFormatter, reasonFormatter, reactiveFormatter];
1199
+ effects.setDebugHooks({
1174
1200
  isDevtoolsEnabled: () => devtoolsEnabled,
1175
1201
  registerEffect: registerEffectForDebug,
1176
1202
  getTriggerChain: getTriggerChain,
@@ -1195,7 +1221,7 @@ function enableDevTools() {
1195
1221
  },
1196
1222
  recordTriggerLink: recordTriggerLink,
1197
1223
  decorateError: (error, trigger) => {
1198
- if (proxy.options.introspection?.logErrors &&
1224
+ if (effects.options.introspection?.logErrors &&
1199
1225
  error &&
1200
1226
  typeof error === 'object' &&
1201
1227
  'stack' in error &&
@@ -1204,8 +1230,8 @@ function enableDevTools() {
1204
1230
  }
1205
1231
  },
1206
1232
  });
1207
- const originalWarn = proxy.options.warn;
1208
- proxy.options.warn = (...args) => {
1233
+ const originalWarn = effects.options.warn;
1234
+ effects.options.warn = (...args) => {
1209
1235
  const lineage = captureLineage();
1210
1236
  originalWarn(...args, lineage);
1211
1237
  };
@@ -1262,7 +1288,7 @@ function getDependents(obj) {
1262
1288
  * Returns a list of objects that the given effect depends on.
1263
1289
  */
1264
1290
  function getDependencies(effect) {
1265
- const deps = proxy.effectToReactiveObjects.get(effect);
1291
+ const deps = effects.effectToReactiveObjects.get(effect);
1266
1292
  return deps ? Array.from(deps) : [];
1267
1293
  }
1268
1294
  const mutationHistory = [];
@@ -1278,7 +1304,7 @@ function addToMutationHistory(source, target, obj, prop, evolution) {
1278
1304
  type: evolution.type,
1279
1305
  };
1280
1306
  mutationHistory.push(record);
1281
- if (mutationHistory.length > (proxy.options.introspection?.historySize ?? 50)) {
1307
+ if (mutationHistory.length > (effects.options.introspection?.historySize ?? 50)) {
1282
1308
  mutationHistory.shift();
1283
1309
  }
1284
1310
  }
@@ -1322,6 +1348,7 @@ function isDevelopmentMode() {
1322
1348
  }
1323
1349
  // Auto-enable devtools when the module loads in development
1324
1350
  if (isDevelopmentMode() && !devtoolsEnabled) {
1351
+ Object.assign(effects.options, effects.devPreset);
1325
1352
  enableDevTools();
1326
1353
  // Optional: Log that devtools were enabled (only in development)
1327
1354
  if (typeof console !== 'undefined' && console.info) {