rerender-lens 0.3.0 → 0.4.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/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { O as Options, C as ChangeKind, a as Change, H as HookChange, b as HookSnapshot, P as ParentInfo, c as CommitPriority, S as SourceLocation, d as CommitCause, R as RenderReport } from './types-BzUEVkxJ.cjs';
2
2
  export { e as ComponentMatcher, M as MARKER, N as Notifier, f as RenderTrigger } from './types-BzUEVkxJ.cjs';
3
- import { F as Fiber } from './devtools-DmhWiWcN.cjs';
4
- export { C as ChannelCommand, a as ChannelReply, D as DEFAULT_CHANNEL, b as DEVTOOLS_MARKER, c as DevtoolsBridge, d as DevtoolsMessage, e as DevtoolsNotifierOptions, H as HelloPayload, I as InspectResult, P as PROTOCOL_VERSION, f as PullResult, R as RendererInfo, S as SerializableOptions, g as createDevtoolsNotifier, h as deserializeOptions, i as ensureDevtoolsHook, j as getRenderers, k as isProductionReact, s as serialize, l as serializeOptions } from './devtools-DmhWiWcN.cjs';
3
+ import { F as Fiber } from './devtools-BkCct3cJ.cjs';
4
+ export { C as ChannelCommand, a as ChannelReply, D as DEFAULT_CHANNEL, b as DEVTOOLS_MARKER, c as DevtoolsBridge, d as DevtoolsMessage, e as DevtoolsNotifierOptions, H as HelloPayload, I as InspectResult, P as PROTOCOL_VERSION, f as PullResult, R as RendererInfo, S as SerializableOptions, g as createDevtoolsNotifier, h as deserializeOptions, i as ensureDevtoolsHook, j as getRenderers, k as isProductionReact, s as serialize, l as serializeOptions } from './devtools-BkCct3cJ.cjs';
5
5
  export { B as Budget, a as BudgetResult, b as BudgetViolation, F as Fix, d as FixKind, R as RankedFix, e as assertWithinBudget, g as avoidableCounts, c as checkBudget, h as fixKey, i as fixesFor, f as formatFixes, r as rankFixes, t as toBudget } from './budget-COBu7jBU.cjs';
6
6
  export { C as Collector, a as CompareRow, b as Comparison, S as SessionSummary, c as combineNotifiers, d as compareSummaries, e as createCollector, f as formatComparison, p as parseExport, s as summarizeReports } from './notifiers-BGQtWKfX.cjs';
7
7
 
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { O as Options, C as ChangeKind, a as Change, H as HookChange, b as HookSnapshot, P as ParentInfo, c as CommitPriority, S as SourceLocation, d as CommitCause, R as RenderReport } from './types-BzUEVkxJ.js';
2
2
  export { e as ComponentMatcher, M as MARKER, N as Notifier, f as RenderTrigger } from './types-BzUEVkxJ.js';
3
- import { F as Fiber } from './devtools-BHGUUo-p.js';
4
- export { C as ChannelCommand, a as ChannelReply, D as DEFAULT_CHANNEL, b as DEVTOOLS_MARKER, c as DevtoolsBridge, d as DevtoolsMessage, e as DevtoolsNotifierOptions, H as HelloPayload, I as InspectResult, P as PROTOCOL_VERSION, f as PullResult, R as RendererInfo, S as SerializableOptions, g as createDevtoolsNotifier, h as deserializeOptions, i as ensureDevtoolsHook, j as getRenderers, k as isProductionReact, s as serialize, l as serializeOptions } from './devtools-BHGUUo-p.js';
3
+ import { F as Fiber } from './devtools-CZebzpF6.js';
4
+ export { C as ChannelCommand, a as ChannelReply, D as DEFAULT_CHANNEL, b as DEVTOOLS_MARKER, c as DevtoolsBridge, d as DevtoolsMessage, e as DevtoolsNotifierOptions, H as HelloPayload, I as InspectResult, P as PROTOCOL_VERSION, f as PullResult, R as RendererInfo, S as SerializableOptions, g as createDevtoolsNotifier, h as deserializeOptions, i as ensureDevtoolsHook, j as getRenderers, k as isProductionReact, s as serialize, l as serializeOptions } from './devtools-CZebzpF6.js';
5
5
  export { B as Budget, a as BudgetResult, b as BudgetViolation, F as Fix, d as FixKind, R as RankedFix, e as assertWithinBudget, g as avoidableCounts, c as checkBudget, h as fixKey, i as fixesFor, f as formatFixes, r as rankFixes, t as toBudget } from './budget-LkNjGtRc.js';
6
6
  export { C as Collector, a as CompareRow, b as Comparison, S as SessionSummary, c as combineNotifiers, d as compareSummaries, e as createCollector, f as formatComparison, p as parseExport, s as summarizeReports } from './notifiers-BjjGSHpp.js';
7
7
 
package/dist/index.js CHANGED
@@ -26,10 +26,49 @@ function remember(seen, a, b) {
26
26
  set.add(b);
27
27
  return false;
28
28
  }
29
+ var scope = null;
30
+ var DEFAULT_DIFF_BUDGET = 5e4;
31
+ function beginDiffScope(budget = 2e5) {
32
+ const previous = scope;
33
+ scope = { cache: /* @__PURE__ */ new WeakMap(), remaining: budget, exhausted: false };
34
+ return () => {
35
+ scope = previous;
36
+ };
37
+ }
38
+ function diffBudgetExhausted() {
39
+ return scope?.exhausted === true;
40
+ }
29
41
  function deepEqual(a, b, seen = /* @__PURE__ */ new Map()) {
30
42
  if (Object.is(a, b)) return true;
31
43
  if (typeof a !== typeof b) return false;
32
44
  if (typeof a !== "object" || a === null || b === null) return false;
45
+ if (!scope) {
46
+ const end = beginDiffScope(DEFAULT_DIFF_BUDGET);
47
+ try {
48
+ return deepEqual(a, b, seen);
49
+ } finally {
50
+ end();
51
+ }
52
+ }
53
+ const sc = scope;
54
+ const objA = a;
55
+ const objB = b;
56
+ const hit = sc.cache.get(objA)?.get(objB);
57
+ if (hit !== void 0) return hit;
58
+ if (--sc.remaining < 0) {
59
+ sc.exhausted = true;
60
+ return false;
61
+ }
62
+ const result = deepEqualObjects(objA, objB, seen);
63
+ let m = sc.cache.get(objA);
64
+ if (!m) {
65
+ m = /* @__PURE__ */ new WeakMap();
66
+ sc.cache.set(objA, m);
67
+ }
68
+ m.set(objB, result);
69
+ return result;
70
+ }
71
+ function deepEqualObjects(a, b, seen) {
33
72
  const objA = a;
34
73
  const objB = b;
35
74
  if (remember(seen, objA, objB)) return true;
@@ -58,6 +97,10 @@ function deepEqual(a, b, seen = /* @__PURE__ */ new Map()) {
58
97
  }
59
98
  if (a instanceof Set) {
60
99
  if (!(b instanceof Set) || a.size !== b.size) return false;
100
+ if (a.size > 50) {
101
+ for (const v of a) if (!b.has(v)) return false;
102
+ return true;
103
+ }
61
104
  outer: for (const v of a) {
62
105
  if (b.has(v)) continue;
63
106
  for (const w of b) if (deepEqual(v, w, seen)) continue outer;
@@ -73,9 +116,10 @@ function deepEqual(a, b, seen = /* @__PURE__ */ new Map()) {
73
116
  const ka = Object.keys(a);
74
117
  const kb = Object.keys(b);
75
118
  if (ka.length !== kb.length) return false;
119
+ const rb = b;
76
120
  for (const k of ka) {
77
121
  if (!Object.prototype.hasOwnProperty.call(b, k)) return false;
78
- if (!deepEqual(a[k], b[k], seen)) return false;
122
+ if (!deepEqual(a[k], rb[k], seen)) return false;
79
123
  }
80
124
  return true;
81
125
  }
@@ -117,7 +161,7 @@ function diffRecords(prev, next, basePath = "") {
117
161
  if (Object.is(a, b)) continue;
118
162
  const kind = classify(a, b);
119
163
  if (kind === "different") {
120
- changes.push({ path: firstDifferentPath(a, b, path), kind, prev: a, next: b });
164
+ changes.push({ path: diffBudgetExhausted() ? path : firstDifferentPath(a, b, path), kind, prev: a, next: b });
121
165
  } else {
122
166
  changes.push({ path, kind, prev: a, next: b });
123
167
  }
@@ -328,7 +372,7 @@ function getState() {
328
372
  const g = globalThis;
329
373
  let s = g[KEY];
330
374
  if (!s) {
331
- 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 };
375
+ 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 };
332
376
  g[KEY] = s;
333
377
  }
334
378
  return s;
@@ -358,7 +402,7 @@ function dispatch(report, override) {
358
402
  try {
359
403
  options.notifier(report);
360
404
  } catch (err) {
361
- (options.console ?? console).warn("[rerender-lens] notifier threw", err);
405
+ warnOnce("notifier", `notifier threw: ${String(err)}`);
362
406
  }
363
407
  }
364
408
  }
@@ -701,11 +745,14 @@ var counts = /* @__PURE__ */ new WeakMap();
701
745
  var ids = /* @__PURE__ */ new WeakMap();
702
746
  var fibersById = /* @__PURE__ */ new Map();
703
747
  var hasWeakRef = typeof WeakRef === "function";
748
+ var pruneAt = 5e3;
704
749
  function remember2(id, fiber) {
705
750
  if (!hasWeakRef) return;
751
+ if (fibersById.get(id)?.deref() === fiber) return;
706
752
  fibersById.set(id, new WeakRef(fiber));
707
- if (fibersById.size > 5e3) {
753
+ if (fibersById.size > pruneAt) {
708
754
  for (const [k, ref] of fibersById) if (!ref.deref()) fibersById.delete(k);
755
+ pruneAt = Math.max(5e3, fibersById.size * 2);
709
756
  }
710
757
  }
711
758
  function instanceIdOf(fiber) {
@@ -760,7 +807,7 @@ function nearestComponent(fiber) {
760
807
  }
761
808
  var INTERNAL_FRAME = /react-dom|react_jsx|jsx-(dev-)?runtime|\/react\/|node_modules\/react|react-stack-bottom-frame|react_stack_bottom_frame|scheduler/;
762
809
  function parseStackLocation(stack) {
763
- for (const line of stack.split("\n")) {
810
+ for (const line of stack.split("\n", 24)) {
764
811
  const m = /(?:at\s+(?:.*?\s+)?\(?|@)?((?:https?|file|webpack|vite|blob):[^\s()]+?):(\d+):(\d+)\)?\s*$/.exec(line.trim());
765
812
  if (!m || !m[1] || INTERNAL_FRAME.test(m[1])) continue;
766
813
  return { fileName: m[1], lineNumber: Number(m[2]), columnNumber: Number(m[3]) };
@@ -776,9 +823,16 @@ function sourceOf(fiber) {
776
823
  return out;
777
824
  }
778
825
  const st = fiber._debugStack;
779
- const text = typeof st === "string" ? st : st && typeof st.stack === "string" ? st.stack : null;
780
- return text ? parseStackLocation(text) : void 0;
826
+ if (st && typeof st === "object") {
827
+ if (sourceCache.has(st)) return sourceCache.get(st);
828
+ const text = typeof st.stack === "string" ? st.stack : null;
829
+ const out = text ? parseStackLocation(text) : void 0;
830
+ sourceCache.set(st, out);
831
+ return out;
832
+ }
833
+ return typeof st === "string" ? parseStackLocation(st) : void 0;
781
834
  }
835
+ var sourceCache = /* @__PURE__ */ new WeakMap();
782
836
  function bumpCount(fiber) {
783
837
  const prev = counts.get(fiber) ?? (fiber.alternate ? counts.get(fiber.alternate) : void 0) ?? 0;
784
838
  const n = prev + 1;
@@ -966,6 +1020,8 @@ function updatersOf(root) {
966
1020
  }
967
1021
  var lastCommit = null;
968
1022
  var EFFECT_LOOP_WINDOW_MS = 50;
1023
+ var MAX_REPORTS_PER_COMMIT = 200;
1024
+ var COMMIT_TIME_BUDGET_MS = 25;
969
1025
  function onCommit(root, commitPriority) {
970
1026
  const s = getState();
971
1027
  if (!s.enabled) return;
@@ -996,7 +1052,8 @@ function onCommit(root, commitPriority) {
996
1052
  const updaters = updatersOf(root);
997
1053
  let commitCause;
998
1054
  let afterCommit;
999
- if (lastCommit && at - lastCommit.at < EFFECT_LOOP_WINDOW_MS && updaters.some((u) => lastCommit.rendered.has(u))) {
1055
+ const inputDriven = commitPriority === "immediate" || commitPriority === "user-blocking";
1056
+ if (!inputDriven && lastCommit && at - lastCommit.at < EFFECT_LOOP_WINDOW_MS && updaters.some((u) => lastCommit.rendered.has(u))) {
1000
1057
  commitCause = "effect-after-commit";
1001
1058
  afterCommit = lastCommit.id;
1002
1059
  } else if (suspenseResolved) commitCause = "suspense-resolved";
@@ -1008,47 +1065,59 @@ function onCommit(root, commitPriority) {
1008
1065
  lastCommit = { id: commitId, at, rendered: renderedNames };
1009
1066
  const dispatcherRef = o.resolveHookNames ? getDispatcherRef() : null;
1010
1067
  const parentCache = /* @__PURE__ */ new Map();
1011
- for (const fiber of rendered) {
1012
- const alt = fiber.alternate;
1013
- const a = analyze(fiber, alt, trackHooks);
1014
- const durations = durationsOf(fiber);
1015
- let hookState = o.includeState !== false && trackHooks ? snapshotHooks(fiber) : void 0;
1016
- if (dispatcherRef && fiber.tag !== ClassComponent && (a.hookChanges.length || hookState && hookState.length)) {
1017
- const names = resolveHookNames(fiber, dispatcherRef);
1018
- if (names.size) {
1019
- for (const c of a.hookChanges) if (c.hook !== "useContext" && names.has(c.index)) c.custom = names.get(c.index);
1020
- if (hookState) hookState = hookState.map((h) => names.has(h.index) ? { ...h, custom: names.get(h.index) } : h);
1068
+ const endDiffScope = beginDiffScope();
1069
+ const deadline = at + COMMIT_TIME_BUDGET_MS;
1070
+ try {
1071
+ for (let i = 0; i < rendered.length; i++) {
1072
+ if (i >= MAX_REPORTS_PER_COMMIT || (i & 15) === 15 && nowMs() > deadline) {
1073
+ s.truncated += rendered.length - i;
1074
+ warnOnce("truncated", `a commit rendered ${rendered.length} tracked components; only ${i} were reported (see info().truncated). Narrow \`include\` or turn off includeState.`);
1075
+ break;
1021
1076
  }
1077
+ const fiber = rendered[i];
1078
+ const alt = fiber.alternate;
1079
+ const a = analyze(fiber, alt, trackHooks);
1080
+ const durations = durationsOf(fiber);
1081
+ let hookState = o.includeState !== false && trackHooks ? snapshotHooks(fiber) : void 0;
1082
+ if (dispatcherRef && fiber.tag !== ClassComponent && (a.hookChanges.length || hookState && hookState.length)) {
1083
+ const names = resolveHookNames(fiber, dispatcherRef);
1084
+ if (names.size) {
1085
+ for (const c of a.hookChanges) if (c.hook !== "useContext" && names.has(c.index)) c.custom = names.get(c.index);
1086
+ if (hookState) hookState = hookState.map((h) => names.has(h.index) ? { ...h, custom: names.get(h.index) } : h);
1087
+ }
1088
+ }
1089
+ const report = buildReport({
1090
+ component: fiberName(fiber),
1091
+ instanceId: instanceId(fiber),
1092
+ renderCount: bumpCount(fiber),
1093
+ prevProps: alt.memoizedProps ?? {},
1094
+ nextProps: fiber.memoizedProps ?? {},
1095
+ propChanges: a.propChanges,
1096
+ stateChanges: a.stateChanges,
1097
+ hookChanges: a.hookChanges,
1098
+ ...o.includeState !== false ? {
1099
+ hookState,
1100
+ contexts: trackHooks ? snapshotContexts(fiber) : void 0,
1101
+ state: fiber.tag === ClassComponent && fiber.memoizedState && typeof fiber.memoizedState === "object" ? fiber.memoizedState : void 0
1102
+ } : {},
1103
+ updaters,
1104
+ commitCause,
1105
+ afterCommit,
1106
+ key: fiber.key === null || fiber.key === void 0 ? null : String(fiber.key),
1107
+ parent: a.trigger === "parent" ? nearestRenderedAncestor(fiber, parentCache, trackHooks) : null,
1108
+ owner: ownerName(fiber),
1109
+ path: componentPath(fiber),
1110
+ memoized: isMemoizedFiber(fiber),
1111
+ selfDuration: durations ? durations.self : void 0,
1112
+ treeDuration: durations ? durations.tree : void 0,
1113
+ commitId,
1114
+ commitPriority,
1115
+ source: sourceOf(fiber)
1116
+ });
1117
+ dispatch(report);
1022
1118
  }
1023
- const report = buildReport({
1024
- component: fiberName(fiber),
1025
- instanceId: instanceId(fiber),
1026
- renderCount: bumpCount(fiber),
1027
- prevProps: alt.memoizedProps ?? {},
1028
- nextProps: fiber.memoizedProps ?? {},
1029
- propChanges: a.propChanges,
1030
- stateChanges: a.stateChanges,
1031
- hookChanges: a.hookChanges,
1032
- ...o.includeState !== false ? {
1033
- hookState,
1034
- contexts: trackHooks ? snapshotContexts(fiber) : void 0,
1035
- state: fiber.tag === ClassComponent && fiber.memoizedState && typeof fiber.memoizedState === "object" ? fiber.memoizedState : void 0
1036
- } : {},
1037
- updaters,
1038
- commitCause,
1039
- afterCommit,
1040
- key: fiber.key === null || fiber.key === void 0 ? null : String(fiber.key),
1041
- parent: a.trigger === "parent" ? nearestRenderedAncestor(fiber, parentCache, trackHooks) : null,
1042
- owner: ownerName(fiber),
1043
- path: componentPath(fiber),
1044
- memoized: isMemoizedFiber(fiber),
1045
- selfDuration: durations ? durations.self : void 0,
1046
- treeDuration: durations ? durations.tree : void 0,
1047
- commitId,
1048
- commitPriority,
1049
- source: sourceOf(fiber)
1050
- });
1051
- dispatch(report);
1119
+ } finally {
1120
+ endDiffScope();
1052
1121
  }
1053
1122
  }
1054
1123
 
@@ -1442,13 +1511,24 @@ function highlight(target) {
1442
1511
  for (const s of l.sticky) s.remove();
1443
1512
  l.sticky = [];
1444
1513
  if (!target) return;
1445
- for (const node of target.nodes) {
1446
- const rect = node.getBoundingClientRect();
1447
- if (rect.width === 0 && rect.height === 0) continue;
1514
+ const frag = document.createDocumentFragment();
1515
+ for (const rect of measure(target.nodes)) {
1448
1516
  const b = box(rect, "#1a73e8", "rgba(26, 115, 232, 0.12)", target.label);
1449
- l.root.appendChild(b);
1517
+ frag.appendChild(b);
1450
1518
  l.sticky.push(b);
1451
1519
  }
1520
+ l.root.appendChild(frag);
1521
+ }
1522
+ var MAX_BOXES = 100;
1523
+ function measure(nodes) {
1524
+ const rects = [];
1525
+ for (const node of nodes) {
1526
+ if (rects.length >= MAX_BOXES) break;
1527
+ const rect = node.getBoundingClientRect();
1528
+ if (rect.width === 0 && rect.height === 0) continue;
1529
+ rects.push(rect);
1530
+ }
1531
+ return rects;
1452
1532
  }
1453
1533
  function clearHighlight() {
1454
1534
  highlight(null);
@@ -1456,27 +1536,34 @@ function clearHighlight() {
1456
1536
  function flash(target, duration = 500) {
1457
1537
  const l = ensureLayer();
1458
1538
  if (!l) return;
1459
- for (const node of target.nodes) {
1460
- const rect = node.getBoundingClientRect();
1461
- if (rect.width === 0 && rect.height === 0) continue;
1539
+ const frag = document.createDocumentFragment();
1540
+ const boxes = [];
1541
+ for (const rect of measure(target.nodes)) {
1462
1542
  const b = box(rect, "#d93025", "rgba(217, 48, 37, 0.15)");
1463
1543
  b.style.transition = `opacity ${duration}ms ease-out`;
1464
- l.root.appendChild(b);
1465
- requestAnimationFrame(() => {
1466
- b.style.opacity = "0";
1467
- });
1468
- setTimeout(() => b.remove(), duration + 50);
1544
+ frag.appendChild(b);
1545
+ boxes.push(b);
1469
1546
  }
1547
+ if (!boxes.length) return;
1548
+ l.root.appendChild(frag);
1549
+ requestAnimationFrame(() => {
1550
+ for (const b of boxes) b.style.opacity = "0";
1551
+ });
1552
+ setTimeout(() => {
1553
+ for (const b of boxes) b.remove();
1554
+ }, duration + 50);
1470
1555
  }
1471
1556
 
1472
1557
  // src/version.ts
1473
- var VERSION = "0.3.0" ;
1558
+ var VERSION = "0.4.0" ;
1474
1559
 
1475
1560
  // src/devtools.ts
1476
1561
  var DEVTOOLS_MARKER = "__rerenderLens";
1477
1562
  var PROTOCOL_VERSION = 2;
1478
1563
  var DEFAULT_CHANNEL = "rerender-lens";
1479
- function serialize(value, maxDepth = 6, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
1564
+ var SERIALIZE_MAX_ENTRIES = 100;
1565
+ var SERIALIZE_MAX_NODES = 2e4;
1566
+ function serialize(value, maxDepth = 4, seen = /* @__PURE__ */ new WeakSet(), depth = 0, budget = { nodes: SERIALIZE_MAX_NODES }) {
1480
1567
  if (value === null || value === void 0) return value;
1481
1568
  const t = typeof value;
1482
1569
  if (t === "string" || t === "boolean") return value;
@@ -1487,24 +1574,56 @@ function serialize(value, maxDepth = 6, seen = /* @__PURE__ */ new WeakSet(), de
1487
1574
  const obj = value;
1488
1575
  if (seen.has(obj)) return "[Circular]";
1489
1576
  if (depth >= maxDepth) return "[\u2026]";
1577
+ if (--budget.nodes < 0) return "[\u2026]";
1578
+ const next = (v) => serialize(v, maxDepth, seen, depth + 1, budget);
1490
1579
  seen.add(obj);
1491
1580
  try {
1492
1581
  if (isReactElement(obj)) {
1493
1582
  const out2 = { $type: "element", name: getDisplayName(obj.type) };
1494
1583
  if (obj.key !== null && obj.key !== void 0) out2.key = String(obj.key);
1495
- out2.props = serialize(obj.props, maxDepth, seen, depth + 1);
1584
+ out2.props = next(obj.props);
1496
1585
  return out2;
1497
1586
  }
1498
1587
  if (obj instanceof Date) return { $type: "Date", value: obj.toISOString() };
1499
1588
  if (obj instanceof RegExp) return { $type: "RegExp", value: String(obj) };
1589
+ if (ArrayBuffer.isView(obj) || obj instanceof ArrayBuffer) {
1590
+ const bin = obj;
1591
+ return { $type: bin.constructor?.name || "ArrayBuffer", length: typeof bin.length === "number" ? bin.length : bin.byteLength };
1592
+ }
1593
+ if (obj instanceof Promise) return "[Promise]";
1594
+ if (typeof Node !== "undefined" && obj instanceof Node) return typeof Element !== "undefined" && obj instanceof Element ? `<${obj.tagName.toLowerCase()}>` : `[${obj.nodeName}]`;
1595
+ if (obj === globalThis) return "[Window]";
1500
1596
  if (obj instanceof Map) {
1501
- return { $type: "Map", entries: [...obj].map(([k, v]) => [serialize(k, maxDepth, seen, depth + 1), serialize(v, maxDepth, seen, depth + 1)]) };
1597
+ const entries = [];
1598
+ for (const [k, v] of obj) {
1599
+ if (entries.length >= SERIALIZE_MAX_ENTRIES) {
1600
+ entries.push(["\u2026", `+${obj.size - SERIALIZE_MAX_ENTRIES} more`]);
1601
+ break;
1602
+ }
1603
+ entries.push([next(k), next(v)]);
1604
+ }
1605
+ return { $type: "Map", entries };
1606
+ }
1607
+ if (obj instanceof Set) {
1608
+ const values = [];
1609
+ for (const v of obj) {
1610
+ if (values.length >= SERIALIZE_MAX_ENTRIES) {
1611
+ values.push(`\u2026+${obj.size - SERIALIZE_MAX_ENTRIES} more`);
1612
+ break;
1613
+ }
1614
+ values.push(next(v));
1615
+ }
1616
+ return { $type: "Set", values };
1617
+ }
1618
+ if (Array.isArray(obj)) {
1619
+ const out2 = obj.slice(0, SERIALIZE_MAX_ENTRIES).map(next);
1620
+ if (obj.length > SERIALIZE_MAX_ENTRIES) out2.push(`\u2026+${obj.length - SERIALIZE_MAX_ENTRIES} more`);
1621
+ return out2;
1502
1622
  }
1503
- if (obj instanceof Set) return { $type: "Set", values: [...obj].map((v) => serialize(v, maxDepth, seen, depth + 1)) };
1504
- if (Array.isArray(obj)) return obj.map((v) => serialize(v, maxDepth, seen, depth + 1));
1505
- if (typeof Element !== "undefined" && obj instanceof Element) return `<${obj.tagName.toLowerCase()}>`;
1506
1623
  const out = {};
1507
- for (const k of Object.keys(obj)) out[k] = serialize(obj[k], maxDepth, seen, depth + 1);
1624
+ const keys = Object.keys(obj);
1625
+ for (const k of keys.slice(0, SERIALIZE_MAX_ENTRIES)) out[k] = next(obj[k]);
1626
+ if (keys.length > SERIALIZE_MAX_ENTRIES) out["\u2026"] = `+${keys.length - SERIALIZE_MAX_ENTRIES} more`;
1508
1627
  const proto = Object.getPrototypeOf(obj);
1509
1628
  if (proto && proto !== Object.prototype && proto.constructor?.name) out.$type = proto.constructor.name;
1510
1629
  return out;
@@ -1544,13 +1663,20 @@ function deserializeOptions(o) {
1544
1663
  }
1545
1664
  function createDevtoolsNotifier(options = {}) {
1546
1665
  const bufferSize = options.bufferSize ?? 300;
1547
- const maxDepth = options.maxDepth ?? 6;
1666
+ const maxDepth = options.maxDepth ?? 4;
1548
1667
  const target = options.target ?? (typeof window !== "undefined" ? window : void 0);
1549
1668
  const buffer = [];
1550
1669
  let seq = 0;
1551
1670
  let flashOn = options.flashAvoidable ?? false;
1671
+ let live = !target || typeof target.addEventListener !== "function";
1672
+ if (!live) {
1673
+ target.addEventListener("message", (event) => {
1674
+ const data = event.data;
1675
+ if ((event.source === target || !event.source) && data && data.__rerenderLensReady === true) live = true;
1676
+ });
1677
+ }
1552
1678
  const post = (type, payload) => {
1553
- if (!target) return;
1679
+ if (!target || type === "report" && !live) return;
1554
1680
  const msg = { [DEVTOOLS_MARKER]: true, version: PROTOCOL_VERSION, type, payload };
1555
1681
  target.postMessage(msg, "*");
1556
1682
  };
@@ -1567,10 +1693,12 @@ function createDevtoolsNotifier(options = {}) {
1567
1693
  injected: typeof window !== "undefined" && typeof window.__RERENDER_LENS_INJECTED__ === "string",
1568
1694
  scheduled: getState().scheduled,
1569
1695
  commits: getState().commits,
1570
- overhead: { totalMs: getState().overheadMs, maxCommitMs: getState().maxCommitMs }
1696
+ overhead: { totalMs: getState().overheadMs, maxCommitMs: getState().maxCommitMs },
1697
+ truncated: getState().truncated
1571
1698
  });
1572
1699
  const bridge = {
1573
1700
  replay: () => {
1701
+ live = true;
1574
1702
  post("hello", info());
1575
1703
  for (const e of buffer) post("report", e.payload);
1576
1704
  },