rerender-lens 0.5.0 → 0.7.0
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/CHANGELOG.md +50 -1
- package/README.md +23 -4
- package/dist/{budget-CRswn-nC.d.cts → budget-CA1MS7lB.d.cts} +1 -1
- package/dist/{budget-BnJlYwrV.d.ts → budget-ok1VDJ4t.d.ts} +1 -1
- package/dist/cli.cjs +78 -26
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +78 -26
- package/dist/cli.js.map +1 -1
- package/dist/{devtools-BYWat7nQ.d.ts → devtools-Cl5n_52v.d.ts} +11 -2
- package/dist/{devtools-DJi_6AfJ.d.cts → devtools-UwQx2VYS.d.cts} +11 -2
- package/dist/index.cjs +99 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -7
- package/dist/index.d.ts +13 -7
- package/dist/index.js +99 -10
- package/dist/index.js.map +1 -1
- package/dist/jest-setup.cjs +20 -3
- package/dist/jest-setup.cjs.map +1 -1
- package/dist/jest-setup.d.cts +4 -4
- package/dist/jest-setup.d.ts +4 -4
- package/dist/jest-setup.js +20 -3
- package/dist/jest-setup.js.map +1 -1
- package/dist/jest.cjs +20 -3
- package/dist/jest.cjs.map +1 -1
- package/dist/jest.d.cts +4 -4
- package/dist/jest.d.ts +4 -4
- package/dist/jest.js +20 -3
- package/dist/jest.js.map +1 -1
- package/dist/{notifiers-DwKlvv4H.d.cts → notifiers-B5poAEvE.d.cts} +2 -2
- package/dist/{notifiers-FNzKHs0a.d.ts → notifiers-CqQW0Eum.d.ts} +2 -2
- package/dist/playwright.d.cts +4 -4
- package/dist/playwright.d.ts +4 -4
- package/dist/relay.cjs +65 -21
- package/dist/relay.cjs.map +1 -1
- package/dist/relay.d.cts +25 -3
- package/dist/relay.d.ts +25 -3
- package/dist/relay.js +65 -21
- package/dist/relay.js.map +1 -1
- package/dist/rerender-lens.iife.js +105 -12
- package/dist/{runner-report-CW8X5RwK.d.ts → runner-report-Bvqoe89M.d.ts} +2 -2
- package/dist/{runner-report-B8Sc3FZO.d.cts → runner-report-CvpDg2zt.d.cts} +2 -2
- package/dist/setup.cjs +98 -9
- package/dist/setup.cjs.map +1 -1
- package/dist/setup.js +98 -9
- package/dist/setup.js.map +1 -1
- package/dist/{types-DW5-N2XH.d.cts → types-DwNN5cWe.d.cts} +28 -1
- package/dist/{types-DW5-N2XH.d.ts → types-DwNN5cWe.d.ts} +28 -1
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vitest-setup.cjs +20 -3
- package/dist/vitest-setup.cjs.map +1 -1
- package/dist/vitest-setup.d.cts +4 -4
- package/dist/vitest-setup.d.ts +4 -4
- package/dist/vitest-setup.js +20 -3
- package/dist/vitest-setup.js.map +1 -1
- package/dist/vitest.cjs +20 -3
- package/dist/vitest.cjs.map +1 -1
- package/dist/vitest.d.cts +5 -5
- package/dist/vitest.d.ts +5 -5
- package/dist/vitest.js +20 -3
- package/dist/vitest.js.map +1 -1
- package/package.json +3 -2
- package/panel/panel.css +48 -0
- package/panel/panel.js +348 -20
package/dist/setup.js
CHANGED
|
@@ -381,16 +381,27 @@ function printReport(report, options) {
|
|
|
381
381
|
}
|
|
382
382
|
|
|
383
383
|
// src/state.ts
|
|
384
|
+
var MAX_SEEN_COMPONENTS = 500;
|
|
384
385
|
var KEY = /* @__PURE__ */ Symbol.for("rerender-lens.state");
|
|
385
386
|
function getState() {
|
|
386
387
|
const g = globalThis;
|
|
387
388
|
let s = g[KEY];
|
|
388
389
|
if (!s) {
|
|
389
|
-
s = { options: {}, enabled: false, printed: /* @__PURE__ */ new Map(), detach: null, nextInstanceId: 1, nextCommitId: 1, warnedOnce: /* @__PURE__ */ new Set(), scheduled: 0, commits: 0, overheadMs: 0, maxCommitMs: 0, truncated: 0 };
|
|
390
|
+
s = { options: {}, enabled: false, printed: /* @__PURE__ */ new Map(), detach: null, nextInstanceId: 1, nextCommitId: 1, warnedOnce: /* @__PURE__ */ new Set(), scheduled: 0, commits: 0, overheadMs: 0, maxCommitMs: 0, truncated: 0, seen: /* @__PURE__ */ new Set(), seenTracked: /* @__PURE__ */ new Set(), seenOverflow: false };
|
|
390
391
|
g[KEY] = s;
|
|
391
392
|
}
|
|
392
393
|
return s;
|
|
393
394
|
}
|
|
395
|
+
function noteRendered(s, name, tracked) {
|
|
396
|
+
if (!s.seen.has(name)) {
|
|
397
|
+
if (s.seen.size >= MAX_SEEN_COMPONENTS) {
|
|
398
|
+
s.seenOverflow = true;
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
s.seen.add(name);
|
|
402
|
+
}
|
|
403
|
+
if (tracked) s.seenTracked.add(name);
|
|
404
|
+
}
|
|
394
405
|
function warnOnce(key, message) {
|
|
395
406
|
const s = getState();
|
|
396
407
|
if (s.warnedOnce.has(key)) return;
|
|
@@ -1117,8 +1128,11 @@ function onCommit(root, commitPriority) {
|
|
|
1117
1128
|
const alt = fiber.alternate;
|
|
1118
1129
|
if (alt && isComponentTag(fiber.tag) && didRender(fiber)) {
|
|
1119
1130
|
if (isHotSwapped(fiber, alt)) hot = true;
|
|
1120
|
-
|
|
1121
|
-
|
|
1131
|
+
const name = fiberName(fiber);
|
|
1132
|
+
renderedNames.add(name);
|
|
1133
|
+
const tracked = shouldTrack(fiberType(fiber), o);
|
|
1134
|
+
noteRendered(s, name, tracked);
|
|
1135
|
+
if (tracked) rendered.push(fiber);
|
|
1122
1136
|
}
|
|
1123
1137
|
if (fiber.tag === SuspenseComponent && alt && alt.memoizedState !== null && fiber.memoizedState === null) (resolvedBoundaries ?? (resolvedBoundaries = [])).push(fiber);
|
|
1124
1138
|
if (!alt || fiber.child !== alt.child) {
|
|
@@ -1243,10 +1257,53 @@ function shouldTrack(type, o) {
|
|
|
1243
1257
|
if (o.trackAllMemoized) return isMemo(type) || isPureClass(type);
|
|
1244
1258
|
return false;
|
|
1245
1259
|
}
|
|
1260
|
+
var ANONYMOUS = "Anonymous";
|
|
1261
|
+
function explainTracking(type, o) {
|
|
1262
|
+
if (typeof type === "string")
|
|
1263
|
+
return { tracked: false, name: type, memoized: false, reason: `<${type}> is a DOM element, not a React component; only components are tracked.` };
|
|
1264
|
+
if (!isComponentLike(type))
|
|
1265
|
+
return { tracked: false, name: ANONYMOUS, memoized: false, reason: "This is not a React component type, so it is never tracked." };
|
|
1266
|
+
const name = getDisplayName(type);
|
|
1267
|
+
const memo = isMemo(type);
|
|
1268
|
+
const memoized = memo || isPureClass(type);
|
|
1269
|
+
if (o.exclude?.some((m) => matches(m, name)))
|
|
1270
|
+
return { tracked: false, name, memoized, reason: `<${name}> matches "exclude", which wins over every other rule.`, fix: `Remove "${name}" from the exclude list.` };
|
|
1271
|
+
if (hasMarker(type)) return { tracked: true, name, memoized, reason: `<${name}> is marked with track() (the ${MARKER} static).` };
|
|
1272
|
+
if (o.include?.some((m) => matches(m, name))) return { tracked: true, name, memoized, reason: `<${name}> matches "include".` };
|
|
1273
|
+
if (o.trackAllComponents) return { tracked: true, name, memoized, reason: '"Track every component" is on, so every component is tracked.' };
|
|
1274
|
+
if (o.trackAllMemoized && memoized)
|
|
1275
|
+
return { tracked: true, name, memoized, reason: `<${name}> is ${memo ? "a React.memo component" : "a PureComponent"}, and "Track every React.memo and PureComponent" is on.` };
|
|
1276
|
+
if (name === ANONYMOUS)
|
|
1277
|
+
return {
|
|
1278
|
+
tracked: false,
|
|
1279
|
+
name,
|
|
1280
|
+
memoized,
|
|
1281
|
+
reason: 'This component has no display name, so "include" and "exclude" cannot address it.',
|
|
1282
|
+
fix: "Give the function a name, set displayName, or mark it with track(fn, 'Name')."
|
|
1283
|
+
};
|
|
1284
|
+
if (o.trackAllMemoized)
|
|
1285
|
+
return {
|
|
1286
|
+
tracked: false,
|
|
1287
|
+
name,
|
|
1288
|
+
memoized,
|
|
1289
|
+
reason: `"Track every React.memo and PureComponent" only covers React.memo components and PureComponent classes, and <${name}> is neither.`,
|
|
1290
|
+
fix: `Add "${name}" to include, wrap it in React.memo, or turn on "Track every component".`
|
|
1291
|
+
};
|
|
1292
|
+
return {
|
|
1293
|
+
tracked: false,
|
|
1294
|
+
name,
|
|
1295
|
+
memoized,
|
|
1296
|
+
reason: `Nothing selects <${name}>: it is not marked with track(), no "include" pattern matches it, and neither "track every" option is on.`,
|
|
1297
|
+
fix: `Add "${name}" to include, or turn on "Track every React.memo and PureComponent" / "Track every component".`
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1246
1300
|
function init(options = {}) {
|
|
1247
1301
|
const s = getState();
|
|
1248
1302
|
s.options = { ...options };
|
|
1249
1303
|
s.printed.clear();
|
|
1304
|
+
s.seen.clear();
|
|
1305
|
+
s.seenTracked.clear();
|
|
1306
|
+
s.seenOverflow = false;
|
|
1250
1307
|
if (!s.enabled) {
|
|
1251
1308
|
s.detach = attach();
|
|
1252
1309
|
s.enabled = true;
|
|
@@ -1372,7 +1429,7 @@ function flash(target, duration = 500) {
|
|
|
1372
1429
|
}
|
|
1373
1430
|
|
|
1374
1431
|
// src/version.ts
|
|
1375
|
-
var VERSION = "0.
|
|
1432
|
+
var VERSION = "0.7.0" ;
|
|
1376
1433
|
|
|
1377
1434
|
// src/devtools.ts
|
|
1378
1435
|
var DEVTOOLS_MARKER = "__rerenderLens";
|
|
@@ -1498,6 +1555,18 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
1498
1555
|
target.postMessage(msg, "*");
|
|
1499
1556
|
};
|
|
1500
1557
|
const source = options.source ?? "page";
|
|
1558
|
+
const trackingSummary = () => {
|
|
1559
|
+
const s = getState();
|
|
1560
|
+
const o = s.options;
|
|
1561
|
+
return {
|
|
1562
|
+
mode: o.trackAllComponents ? "all" : o.trackAllMemoized ? "memoized" : "marked",
|
|
1563
|
+
include: (o.include ?? []).map(matcherToString).filter((x) => x !== null),
|
|
1564
|
+
exclude: (o.exclude ?? []).map(matcherToString).filter((x) => x !== null),
|
|
1565
|
+
renderedCount: s.seen.size,
|
|
1566
|
+
trackedCount: s.seenTracked.size,
|
|
1567
|
+
overflow: s.seenOverflow
|
|
1568
|
+
};
|
|
1569
|
+
};
|
|
1501
1570
|
const info = () => ({
|
|
1502
1571
|
count: buffer.length,
|
|
1503
1572
|
library: VERSION,
|
|
@@ -1511,7 +1580,8 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
1511
1580
|
scheduled: getState().scheduled,
|
|
1512
1581
|
commits: getState().commits,
|
|
1513
1582
|
overhead: { totalMs: getState().overheadMs, maxCommitMs: getState().maxCommitMs },
|
|
1514
|
-
truncated: getState().truncated
|
|
1583
|
+
truncated: getState().truncated,
|
|
1584
|
+
tracking: trackingSummary()
|
|
1515
1585
|
});
|
|
1516
1586
|
const bridge = {
|
|
1517
1587
|
replay: () => {
|
|
@@ -1557,6 +1627,10 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
1557
1627
|
flashAvoidable: (on) => {
|
|
1558
1628
|
flashOn = !!on;
|
|
1559
1629
|
},
|
|
1630
|
+
explain: (target2) => {
|
|
1631
|
+
const comp = typeof target2 === "number" ? fiberById(target2) : nearestComponent(fiberForNode(target2));
|
|
1632
|
+
return comp ? explainTracking(fiberType(comp), getState().options) : null;
|
|
1633
|
+
},
|
|
1560
1634
|
inspect: (node) => {
|
|
1561
1635
|
const comp = nearestComponent(fiberForNode(node));
|
|
1562
1636
|
if (!comp) return null;
|
|
@@ -1571,6 +1645,7 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
1571
1645
|
component: fiberName(comp),
|
|
1572
1646
|
instanceId: id,
|
|
1573
1647
|
tracked: shouldTrack(fiberType(comp), getState().options),
|
|
1648
|
+
tracking: explainTracking(fiberType(comp), getState().options),
|
|
1574
1649
|
path,
|
|
1575
1650
|
reports: id === null ? [] : buffer.filter((e) => e.instanceId === id).slice(-20).map((e) => e.payload)
|
|
1576
1651
|
};
|
|
@@ -1605,6 +1680,9 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
1605
1680
|
bridge.flashAvoidable(!!data.arg);
|
|
1606
1681
|
reply.result = true;
|
|
1607
1682
|
break;
|
|
1683
|
+
case "explain":
|
|
1684
|
+
reply.result = bridge.explain(data.arg);
|
|
1685
|
+
break;
|
|
1608
1686
|
default:
|
|
1609
1687
|
reply.error = `unknown command ${String(data.cmd)}`;
|
|
1610
1688
|
}
|
|
@@ -1613,6 +1691,7 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
1613
1691
|
}
|
|
1614
1692
|
return reply;
|
|
1615
1693
|
};
|
|
1694
|
+
const isRelayGreeting = (data) => !!data && typeof data === "object" && data.__rerenderLensRelay === true && typeof data.app === "string";
|
|
1616
1695
|
const isCommand = (data) => !!data && typeof data === "object" && data.__rerenderLensCmd === true && typeof data.id === "string";
|
|
1617
1696
|
const envelope = (type, payload) => ({ [DEVTOOLS_MARKER]: true, version: PROTOCOL_VERSION, type, payload });
|
|
1618
1697
|
const sinks = [];
|
|
@@ -1635,14 +1714,20 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
1635
1714
|
const relayUrl = options.relay ?? (typeof window !== "undefined" ? window.__RERENDER_LENS_RELAY__ : void 0);
|
|
1636
1715
|
const ES = options.eventSource ?? (typeof EventSource === "function" ? EventSource : null);
|
|
1637
1716
|
if (relayUrl && ES && typeof fetch === "function") {
|
|
1638
|
-
const
|
|
1717
|
+
const [rawBase, relayQuery = ""] = relayUrl.split("?");
|
|
1718
|
+
const base = (rawBase ?? "").replace(/\/$/, "");
|
|
1719
|
+
const relayToken = new URLSearchParams(relayQuery).get("token");
|
|
1720
|
+
const auth = relayToken ? `token=${encodeURIComponent(relayToken)}` : "";
|
|
1639
1721
|
let queue = [];
|
|
1640
1722
|
let scheduled = false;
|
|
1723
|
+
let appId = null;
|
|
1641
1724
|
const flush = () => {
|
|
1642
1725
|
scheduled = false;
|
|
1643
1726
|
const batch = queue;
|
|
1644
1727
|
queue = [];
|
|
1645
|
-
|
|
1728
|
+
const params = [appId ? `app=${encodeURIComponent(appId)}` : "", auth].filter(Boolean).join("&");
|
|
1729
|
+
const to = `${base}/message${params ? `?${params}` : ""}`;
|
|
1730
|
+
fetch(to, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(batch), keepalive: true }).catch(() => {
|
|
1646
1731
|
});
|
|
1647
1732
|
};
|
|
1648
1733
|
const relaySend = (message) => {
|
|
@@ -1653,7 +1738,8 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
1653
1738
|
}
|
|
1654
1739
|
};
|
|
1655
1740
|
try {
|
|
1656
|
-
const
|
|
1741
|
+
const label = typeof location !== "undefined" ? `${location.host}${location.pathname}`.slice(0, 120) : "";
|
|
1742
|
+
const stream = new ES(`${base}/events?role=app${label ? `&label=${encodeURIComponent(label)}` : ""}${auth ? `&${auth}` : ""}`);
|
|
1657
1743
|
stream.onmessage = (event) => {
|
|
1658
1744
|
let parsed;
|
|
1659
1745
|
try {
|
|
@@ -1661,7 +1747,10 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
1661
1747
|
} catch {
|
|
1662
1748
|
return;
|
|
1663
1749
|
}
|
|
1664
|
-
for (const m of Array.isArray(parsed) ? parsed : [parsed])
|
|
1750
|
+
for (const m of Array.isArray(parsed) ? parsed : [parsed]) {
|
|
1751
|
+
if (isRelayGreeting(m)) appId = m.app;
|
|
1752
|
+
else if (isCommand(m)) relaySend(runCommand(m));
|
|
1753
|
+
}
|
|
1665
1754
|
};
|
|
1666
1755
|
stream.onerror = () => {
|
|
1667
1756
|
};
|