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/index.cjs
CHANGED
|
@@ -403,16 +403,27 @@ function printReport(report, options) {
|
|
|
403
403
|
}
|
|
404
404
|
|
|
405
405
|
// src/state.ts
|
|
406
|
+
var MAX_SEEN_COMPONENTS = 500;
|
|
406
407
|
var KEY = /* @__PURE__ */ Symbol.for("rerender-lens.state");
|
|
407
408
|
function getState() {
|
|
408
409
|
const g = globalThis;
|
|
409
410
|
let s = g[KEY];
|
|
410
411
|
if (!s) {
|
|
411
|
-
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 };
|
|
412
|
+
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 };
|
|
412
413
|
g[KEY] = s;
|
|
413
414
|
}
|
|
414
415
|
return s;
|
|
415
416
|
}
|
|
417
|
+
function noteRendered(s, name, tracked) {
|
|
418
|
+
if (!s.seen.has(name)) {
|
|
419
|
+
if (s.seen.size >= MAX_SEEN_COMPONENTS) {
|
|
420
|
+
s.seenOverflow = true;
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
s.seen.add(name);
|
|
424
|
+
}
|
|
425
|
+
if (tracked) s.seenTracked.add(name);
|
|
426
|
+
}
|
|
416
427
|
function warnOnce(key, message) {
|
|
417
428
|
const s = getState();
|
|
418
429
|
if (s.warnedOnce.has(key)) return;
|
|
@@ -1139,8 +1150,11 @@ function onCommit(root, commitPriority) {
|
|
|
1139
1150
|
const alt = fiber.alternate;
|
|
1140
1151
|
if (alt && isComponentTag(fiber.tag) && didRender(fiber)) {
|
|
1141
1152
|
if (isHotSwapped(fiber, alt)) hot = true;
|
|
1142
|
-
|
|
1143
|
-
|
|
1153
|
+
const name = fiberName(fiber);
|
|
1154
|
+
renderedNames.add(name);
|
|
1155
|
+
const tracked = shouldTrack(fiberType(fiber), o);
|
|
1156
|
+
noteRendered(s, name, tracked);
|
|
1157
|
+
if (tracked) rendered.push(fiber);
|
|
1144
1158
|
}
|
|
1145
1159
|
if (fiber.tag === SuspenseComponent && alt && alt.memoizedState !== null && fiber.memoizedState === null) (resolvedBoundaries ?? (resolvedBoundaries = [])).push(fiber);
|
|
1146
1160
|
if (!alt || fiber.child !== alt.child) {
|
|
@@ -1265,10 +1279,53 @@ function shouldTrack(type, o) {
|
|
|
1265
1279
|
if (o.trackAllMemoized) return isMemo(type) || isPureClass(type);
|
|
1266
1280
|
return false;
|
|
1267
1281
|
}
|
|
1282
|
+
var ANONYMOUS = "Anonymous";
|
|
1283
|
+
function explainTracking(type, o) {
|
|
1284
|
+
if (typeof type === "string")
|
|
1285
|
+
return { tracked: false, name: type, memoized: false, reason: `<${type}> is a DOM element, not a React component; only components are tracked.` };
|
|
1286
|
+
if (!isComponentLike(type))
|
|
1287
|
+
return { tracked: false, name: ANONYMOUS, memoized: false, reason: "This is not a React component type, so it is never tracked." };
|
|
1288
|
+
const name = getDisplayName(type);
|
|
1289
|
+
const memo = isMemo(type);
|
|
1290
|
+
const memoized = memo || isPureClass(type);
|
|
1291
|
+
if (o.exclude?.some((m) => matches(m, name)))
|
|
1292
|
+
return { tracked: false, name, memoized, reason: `<${name}> matches "exclude", which wins over every other rule.`, fix: `Remove "${name}" from the exclude list.` };
|
|
1293
|
+
if (hasMarker(type)) return { tracked: true, name, memoized, reason: `<${name}> is marked with track() (the ${MARKER} static).` };
|
|
1294
|
+
if (o.include?.some((m) => matches(m, name))) return { tracked: true, name, memoized, reason: `<${name}> matches "include".` };
|
|
1295
|
+
if (o.trackAllComponents) return { tracked: true, name, memoized, reason: '"Track every component" is on, so every component is tracked.' };
|
|
1296
|
+
if (o.trackAllMemoized && memoized)
|
|
1297
|
+
return { tracked: true, name, memoized, reason: `<${name}> is ${memo ? "a React.memo component" : "a PureComponent"}, and "Track every React.memo and PureComponent" is on.` };
|
|
1298
|
+
if (name === ANONYMOUS)
|
|
1299
|
+
return {
|
|
1300
|
+
tracked: false,
|
|
1301
|
+
name,
|
|
1302
|
+
memoized,
|
|
1303
|
+
reason: 'This component has no display name, so "include" and "exclude" cannot address it.',
|
|
1304
|
+
fix: "Give the function a name, set displayName, or mark it with track(fn, 'Name')."
|
|
1305
|
+
};
|
|
1306
|
+
if (o.trackAllMemoized)
|
|
1307
|
+
return {
|
|
1308
|
+
tracked: false,
|
|
1309
|
+
name,
|
|
1310
|
+
memoized,
|
|
1311
|
+
reason: `"Track every React.memo and PureComponent" only covers React.memo components and PureComponent classes, and <${name}> is neither.`,
|
|
1312
|
+
fix: `Add "${name}" to include, wrap it in React.memo, or turn on "Track every component".`
|
|
1313
|
+
};
|
|
1314
|
+
return {
|
|
1315
|
+
tracked: false,
|
|
1316
|
+
name,
|
|
1317
|
+
memoized,
|
|
1318
|
+
reason: `Nothing selects <${name}>: it is not marked with track(), no "include" pattern matches it, and neither "track every" option is on.`,
|
|
1319
|
+
fix: `Add "${name}" to include, or turn on "Track every React.memo and PureComponent" / "Track every component".`
|
|
1320
|
+
};
|
|
1321
|
+
}
|
|
1268
1322
|
function init(options = {}) {
|
|
1269
1323
|
const s = getState();
|
|
1270
1324
|
s.options = { ...options };
|
|
1271
1325
|
s.printed.clear();
|
|
1326
|
+
s.seen.clear();
|
|
1327
|
+
s.seenTracked.clear();
|
|
1328
|
+
s.seenOverflow = false;
|
|
1272
1329
|
if (!s.enabled) {
|
|
1273
1330
|
s.detach = attach();
|
|
1274
1331
|
s.enabled = true;
|
|
@@ -1939,7 +1996,7 @@ function flash(target, duration = 500) {
|
|
|
1939
1996
|
}
|
|
1940
1997
|
|
|
1941
1998
|
// src/version.ts
|
|
1942
|
-
var VERSION = "0.
|
|
1999
|
+
var VERSION = "0.7.0" ;
|
|
1943
2000
|
|
|
1944
2001
|
// src/devtools.ts
|
|
1945
2002
|
var DEVTOOLS_MARKER = "__rerenderLens";
|
|
@@ -2065,6 +2122,18 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
2065
2122
|
target.postMessage(msg, "*");
|
|
2066
2123
|
};
|
|
2067
2124
|
const source = options.source ?? "page";
|
|
2125
|
+
const trackingSummary = () => {
|
|
2126
|
+
const s = getState();
|
|
2127
|
+
const o = s.options;
|
|
2128
|
+
return {
|
|
2129
|
+
mode: o.trackAllComponents ? "all" : o.trackAllMemoized ? "memoized" : "marked",
|
|
2130
|
+
include: (o.include ?? []).map(matcherToString).filter((x) => x !== null),
|
|
2131
|
+
exclude: (o.exclude ?? []).map(matcherToString).filter((x) => x !== null),
|
|
2132
|
+
renderedCount: s.seen.size,
|
|
2133
|
+
trackedCount: s.seenTracked.size,
|
|
2134
|
+
overflow: s.seenOverflow
|
|
2135
|
+
};
|
|
2136
|
+
};
|
|
2068
2137
|
const info = () => ({
|
|
2069
2138
|
count: buffer.length,
|
|
2070
2139
|
library: VERSION,
|
|
@@ -2078,7 +2147,8 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
2078
2147
|
scheduled: getState().scheduled,
|
|
2079
2148
|
commits: getState().commits,
|
|
2080
2149
|
overhead: { totalMs: getState().overheadMs, maxCommitMs: getState().maxCommitMs },
|
|
2081
|
-
truncated: getState().truncated
|
|
2150
|
+
truncated: getState().truncated,
|
|
2151
|
+
tracking: trackingSummary()
|
|
2082
2152
|
});
|
|
2083
2153
|
const bridge = {
|
|
2084
2154
|
replay: () => {
|
|
@@ -2124,6 +2194,10 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
2124
2194
|
flashAvoidable: (on) => {
|
|
2125
2195
|
flashOn = !!on;
|
|
2126
2196
|
},
|
|
2197
|
+
explain: (target2) => {
|
|
2198
|
+
const comp = typeof target2 === "number" ? fiberById(target2) : nearestComponent(fiberForNode(target2));
|
|
2199
|
+
return comp ? explainTracking(fiberType(comp), getState().options) : null;
|
|
2200
|
+
},
|
|
2127
2201
|
inspect: (node) => {
|
|
2128
2202
|
const comp = nearestComponent(fiberForNode(node));
|
|
2129
2203
|
if (!comp) return null;
|
|
@@ -2138,6 +2212,7 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
2138
2212
|
component: fiberName(comp),
|
|
2139
2213
|
instanceId: id,
|
|
2140
2214
|
tracked: shouldTrack(fiberType(comp), getState().options),
|
|
2215
|
+
tracking: explainTracking(fiberType(comp), getState().options),
|
|
2141
2216
|
path,
|
|
2142
2217
|
reports: id === null ? [] : buffer.filter((e) => e.instanceId === id).slice(-20).map((e) => e.payload)
|
|
2143
2218
|
};
|
|
@@ -2172,6 +2247,9 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
2172
2247
|
bridge.flashAvoidable(!!data.arg);
|
|
2173
2248
|
reply.result = true;
|
|
2174
2249
|
break;
|
|
2250
|
+
case "explain":
|
|
2251
|
+
reply.result = bridge.explain(data.arg);
|
|
2252
|
+
break;
|
|
2175
2253
|
default:
|
|
2176
2254
|
reply.error = `unknown command ${String(data.cmd)}`;
|
|
2177
2255
|
}
|
|
@@ -2180,6 +2258,7 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
2180
2258
|
}
|
|
2181
2259
|
return reply;
|
|
2182
2260
|
};
|
|
2261
|
+
const isRelayGreeting = (data) => !!data && typeof data === "object" && data.__rerenderLensRelay === true && typeof data.app === "string";
|
|
2183
2262
|
const isCommand = (data) => !!data && typeof data === "object" && data.__rerenderLensCmd === true && typeof data.id === "string";
|
|
2184
2263
|
const envelope = (type, payload) => ({ [DEVTOOLS_MARKER]: true, version: PROTOCOL_VERSION, type, payload });
|
|
2185
2264
|
const sinks = [];
|
|
@@ -2202,14 +2281,20 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
2202
2281
|
const relayUrl = options.relay ?? (typeof window !== "undefined" ? window.__RERENDER_LENS_RELAY__ : void 0);
|
|
2203
2282
|
const ES = options.eventSource ?? (typeof EventSource === "function" ? EventSource : null);
|
|
2204
2283
|
if (relayUrl && ES && typeof fetch === "function") {
|
|
2205
|
-
const
|
|
2284
|
+
const [rawBase, relayQuery = ""] = relayUrl.split("?");
|
|
2285
|
+
const base = (rawBase ?? "").replace(/\/$/, "");
|
|
2286
|
+
const relayToken = new URLSearchParams(relayQuery).get("token");
|
|
2287
|
+
const auth = relayToken ? `token=${encodeURIComponent(relayToken)}` : "";
|
|
2206
2288
|
let queue = [];
|
|
2207
2289
|
let scheduled = false;
|
|
2290
|
+
let appId = null;
|
|
2208
2291
|
const flush = () => {
|
|
2209
2292
|
scheduled = false;
|
|
2210
2293
|
const batch = queue;
|
|
2211
2294
|
queue = [];
|
|
2212
|
-
|
|
2295
|
+
const params = [appId ? `app=${encodeURIComponent(appId)}` : "", auth].filter(Boolean).join("&");
|
|
2296
|
+
const to = `${base}/message${params ? `?${params}` : ""}`;
|
|
2297
|
+
fetch(to, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(batch), keepalive: true }).catch(() => {
|
|
2213
2298
|
});
|
|
2214
2299
|
};
|
|
2215
2300
|
const relaySend = (message) => {
|
|
@@ -2220,7 +2305,8 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
2220
2305
|
}
|
|
2221
2306
|
};
|
|
2222
2307
|
try {
|
|
2223
|
-
const
|
|
2308
|
+
const label = typeof location !== "undefined" ? `${location.host}${location.pathname}`.slice(0, 120) : "";
|
|
2309
|
+
const stream = new ES(`${base}/events?role=app${label ? `&label=${encodeURIComponent(label)}` : ""}${auth ? `&${auth}` : ""}`);
|
|
2224
2310
|
stream.onmessage = (event) => {
|
|
2225
2311
|
let parsed;
|
|
2226
2312
|
try {
|
|
@@ -2228,7 +2314,10 @@ function createDevtoolsNotifier(options = {}) {
|
|
|
2228
2314
|
} catch {
|
|
2229
2315
|
return;
|
|
2230
2316
|
}
|
|
2231
|
-
for (const m of Array.isArray(parsed) ? parsed : [parsed])
|
|
2317
|
+
for (const m of Array.isArray(parsed) ? parsed : [parsed]) {
|
|
2318
|
+
if (isRelayGreeting(m)) appId = m.app;
|
|
2319
|
+
else if (isCommand(m)) relaySend(runCommand(m));
|
|
2320
|
+
}
|
|
2232
2321
|
};
|
|
2233
2322
|
stream.onerror = () => {
|
|
2234
2323
|
};
|
|
@@ -2299,6 +2388,7 @@ exports.diffLeaves = diffLeaves;
|
|
|
2299
2388
|
exports.diffRecords = diffRecords;
|
|
2300
2389
|
exports.disable = disable;
|
|
2301
2390
|
exports.ensureDevtoolsHook = ensureDevtoolsHook;
|
|
2391
|
+
exports.explainTracking = explainTracking;
|
|
2302
2392
|
exports.firstDifferentPath = firstDifferentPath;
|
|
2303
2393
|
exports.fixKey = fixKey;
|
|
2304
2394
|
exports.fixesFor = fixesFor;
|