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.
- package/BROWSER_ASYNC_POLYFILL.md +79 -0
- package/README.md +2 -2
- package/dist/browser.cjs +216 -97
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +42 -9
- package/dist/browser.dev.cjs +81 -71
- package/dist/browser.dev.cjs.map +1 -1
- package/dist/browser.dev.d.ts +2 -2
- package/dist/browser.dev.esm.js +2 -2
- package/dist/browser.esm.js +137 -28
- package/dist/browser.esm.js.map +1 -1
- package/dist/chunks/{proxy-BtmPFjSr.esm.js → effects-CPjf6gNA.esm.js} +2605 -2155
- package/dist/chunks/effects-CPjf6gNA.esm.js.map +1 -0
- package/dist/chunks/{proxy-DBHj3kGK.cjs → effects-oUauWxxl.cjs} +2615 -2156
- package/dist/chunks/effects-oUauWxxl.cjs.map +1 -0
- package/dist/chunks/{index-CAdnMJev.cjs → index-Dtj2qZ0d.cjs} +418 -350
- package/dist/chunks/index-Dtj2qZ0d.cjs.map +1 -0
- package/dist/chunks/{index-XsYTUhHx.esm.js → index-YGpb1te7.esm.js} +156 -88
- package/dist/chunks/index-YGpb1te7.esm.js.map +1 -0
- package/dist/chunks/node-CKuro-Uk.cjs +187 -0
- package/dist/chunks/node-CKuro-Uk.cjs.map +1 -0
- package/dist/chunks/node-sQtns7M-.esm.js +185 -0
- package/dist/chunks/node-sQtns7M-.esm.js.map +1 -0
- package/dist/debug.cjs +76 -49
- package/dist/debug.cjs.map +1 -1
- package/dist/debug.esm.js +37 -10
- package/dist/debug.esm.js.map +1 -1
- package/dist/mutts.umd.js +4169 -3532
- package/dist/mutts.umd.js.map +1 -1
- package/dist/mutts.umd.min.js +1 -1
- package/dist/mutts.umd.min.js.map +1 -1
- package/dist/node.cjs +82 -72
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.dev.cjs +82 -72
- package/dist/node.dev.cjs.map +1 -1
- package/dist/node.dev.d.ts +2 -2
- package/dist/node.dev.esm.js +3 -3
- package/dist/node.esm.js +3 -3
- package/dist/types.d.ts +30 -15
- package/docs/ai/api-reference.md +3 -1
- package/docs/ai/manual.md +17 -5
- package/docs/reactive/advanced.md +169 -10
- package/docs/reactive/debugging.md +15 -13
- package/docs/reactive.md +2 -1
- package/package.json +12 -7
- package/dist/chunks/index-CAdnMJev.cjs.map +0 -1
- package/dist/chunks/index-XsYTUhHx.esm.js.map +0 -1
- package/dist/chunks/node-DrrphEPf.cjs +0 -98
- package/dist/chunks/node-DrrphEPf.cjs.map +0 -1
- package/dist/chunks/node-NEZvVo4M.esm.js +0 -96
- package/dist/chunks/node-NEZvVo4M.esm.js.map +0 -1
- package/dist/chunks/proxy-BtmPFjSr.esm.js.map +0 -1
- 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
|
|
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(
|
|
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(
|
|
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 ??
|
|
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 =
|
|
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 =
|
|
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 ?
|
|
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
|
|
513
|
+
return effects.formatCleanupReason({ type: 'propChange', triggers: reason.triggers });
|
|
514
514
|
case 'invalidate':
|
|
515
|
-
return
|
|
515
|
+
return effects.formatCleanupReason({ type: 'invalidate', cause: reason.cause });
|
|
516
516
|
case 'stopped':
|
|
517
|
-
return
|
|
517
|
+
return effects.formatCleanupReason(reason.detail ? { type: 'stopped', detail: reason.detail } : { type: 'stopped' });
|
|
518
518
|
case 'external':
|
|
519
|
-
return
|
|
519
|
+
return effects.formatCleanupReason({ type: 'external', detail: reason.detail });
|
|
520
520
|
case 'gc':
|
|
521
|
-
return
|
|
521
|
+
return effects.formatCleanupReason({ type: 'gc' });
|
|
522
522
|
case 'lineage':
|
|
523
|
-
return
|
|
523
|
+
return effects.formatCleanupReason({ type: 'lineage', parent: reason.parent });
|
|
524
524
|
case 'error':
|
|
525
|
-
return
|
|
525
|
+
return effects.formatCleanupReason({ type: 'error', error: reason.error });
|
|
526
526
|
case 'multiple':
|
|
527
|
-
return
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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 ? (
|
|
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 (!
|
|
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 =
|
|
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 ===
|
|
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 =
|
|
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 =
|
|
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 (
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 (
|
|
1130
|
-
|
|
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 =
|
|
1187
|
+
const activeEffect = effects.getActiveEffect();
|
|
1159
1188
|
if (!activeEffect)
|
|
1160
1189
|
return undefined;
|
|
1161
|
-
const node =
|
|
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
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
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 (
|
|
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 =
|
|
1208
|
-
|
|
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 =
|
|
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 > (
|
|
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) {
|