why-hydration 0.1.4 → 0.2.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +108 -1
  2. package/README.md +220 -33
  3. package/dist/{chunk-WQLUD25W.js → chunk-3OAI2ZHY.js} +375 -118
  4. package/dist/chunk-3OAI2ZHY.js.map +1 -0
  5. package/dist/{chunk-OGQEPU7G.cjs → chunk-DXPTZB3Z.cjs} +44 -2
  6. package/dist/chunk-DXPTZB3Z.cjs.map +1 -0
  7. package/dist/{chunk-DSO337ME.cjs → chunk-KX6G7I4Y.cjs} +384 -118
  8. package/dist/chunk-KX6G7I4Y.cjs.map +1 -0
  9. package/dist/chunk-MK3TYHKM.js +966 -0
  10. package/dist/chunk-MK3TYHKM.js.map +1 -0
  11. package/dist/chunk-R7IWOK5M.cjs +989 -0
  12. package/dist/chunk-R7IWOK5M.cjs.map +1 -0
  13. package/dist/{chunk-FV3PEJQE.js → chunk-XIM33ZGB.js} +44 -2
  14. package/dist/chunk-XIM33ZGB.js.map +1 -0
  15. package/dist/index.cjs +32 -24
  16. package/dist/index.d.cts +43 -5
  17. package/dist/index.d.ts +43 -5
  18. package/dist/index.js +2 -2
  19. package/dist/next/index.cjs +5 -5
  20. package/dist/next/index.d.cts +1 -1
  21. package/dist/next/index.d.ts +1 -1
  22. package/dist/next/index.js +3 -3
  23. package/dist/next/script.cjs +2 -2
  24. package/dist/next/script.js +1 -1
  25. package/dist/react.cjs +5 -5
  26. package/dist/react.d.cts +23 -3
  27. package/dist/react.d.ts +23 -3
  28. package/dist/react.js +3 -3
  29. package/dist/{types-6wTih14e.d.cts → types-C14vcpBO.d.cts} +9 -0
  30. package/dist/{types-6wTih14e.d.ts → types-C14vcpBO.d.ts} +9 -0
  31. package/package.json +1 -1
  32. package/dist/chunk-3KULWJ7A.js +0 -569
  33. package/dist/chunk-3KULWJ7A.js.map +0 -1
  34. package/dist/chunk-5CBGYE7A.cjs +0 -592
  35. package/dist/chunk-5CBGYE7A.cjs.map +0 -1
  36. package/dist/chunk-DSO337ME.cjs.map +0 -1
  37. package/dist/chunk-FV3PEJQE.js.map +0 -1
  38. package/dist/chunk-OGQEPU7G.cjs.map +0 -1
  39. package/dist/chunk-WQLUD25W.js.map +0 -1
@@ -1,592 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkDSO337ME_cjs = require('./chunk-DSO337ME.cjs');
4
- var chunkOGQEPU7G_cjs = require('./chunk-OGQEPU7G.cjs');
5
- var React2 = require('react');
6
-
7
- function _interopNamespace(e) {
8
- if (e && e.__esModule) return e;
9
- var n = Object.create(null);
10
- if (e) {
11
- Object.keys(e).forEach(function (k) {
12
- if (k !== 'default') {
13
- var d = Object.getOwnPropertyDescriptor(e, k);
14
- Object.defineProperty(n, k, d.get ? d : {
15
- enumerable: true,
16
- get: function () { return e[k]; }
17
- });
18
- }
19
- });
20
- }
21
- n.default = e;
22
- return Object.freeze(n);
23
- }
24
-
25
- var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
26
-
27
- // src/react/console.ts
28
- function installConsoleInterceptor(onMessage) {
29
- if (typeof console === "undefined") return () => {
30
- };
31
- const original = console.error.bind(console);
32
- const patched = (...args) => {
33
- try {
34
- const message = chunkDSO337ME_cjs.formatConsoleArgs(args);
35
- if (message && chunkDSO337ME_cjs.isHydrationMessage(message)) {
36
- onMessage(message, args);
37
- }
38
- } catch {
39
- }
40
- original(...args);
41
- };
42
- console.error = patched;
43
- return () => {
44
- if (console.error === patched) {
45
- console.error = original;
46
- }
47
- };
48
- }
49
- var BADGE = "color:#f59e0b;font-weight:bold";
50
- var DIM = "color:#9ca3af";
51
- function createConsoleReporter() {
52
- const sink = (report) => {
53
- const title = `%c\u2B21 why-hydration%c ${report.cause.category} \u2014 ${report.node.path}`;
54
- console.group(title, BADGE, DIM);
55
- console.log("%cServer:%c", "color:#fb7185", "", report.server ?? "(none)");
56
- console.log("%cClient:%c", "color:#4ade80", "", report.client ?? "(none)");
57
- if (report.component) {
58
- console.log("%cComponent:%c", DIM, "", `<${report.component}>`);
59
- }
60
- if (report.location?.file) {
61
- const loc = report.location.line ? `${report.location.file}:${report.location.line}` : report.location.file;
62
- console.log("%cSource:%c", DIM, "", loc);
63
- }
64
- console.log("%cWhy:%c", DIM, "", report.cause.explanation);
65
- console.log("%cFix:%c", "color:#86efac", "", report.cause.suggestion);
66
- if (report.cause.docsUrl) {
67
- console.log("%cDocs:%c", DIM, "", report.cause.docsUrl);
68
- }
69
- if (report.componentStack) {
70
- console.log("%cComponent stack:%c", DIM, "", report.componentStack);
71
- }
72
- console.groupEnd();
73
- };
74
- return sink;
75
- }
76
-
77
- // src/react/overlay.ts
78
- var CONTAINER_ID = "why-hydration-overlay";
79
- var CATEGORY_LABELS = {
80
- "non-deterministic-value": "Non-deterministic value",
81
- "date-time": "Date / time",
82
- "locale-format": "Locale formatting",
83
- "browser-only-api": "Browser-only API",
84
- "viewport-branching": "Viewport branching",
85
- "invalid-html-nesting": "Invalid HTML nesting",
86
- "whitespace-minification": "Whitespace / minification",
87
- "third-party-dom-mutation": "Third-party DOM mutation",
88
- "attribute-mismatch": "Attribute mismatch",
89
- unknown: "Unknown"
90
- };
91
- var STYLES = `
92
- :host {
93
- all: initial;
94
- /* The "all" shorthand deliberately excludes direction/unicode-bidi (CSS spec),
95
- so a host page with <html dir="rtl"> would otherwise leak direction:rtl
96
- into this shadow tree and flip flex/grid order + text alignment. Report
97
- content is English, so the overlay always renders left-to-right,
98
- independent of the host page's directionality. */
99
- direction: ltr;
100
- unicode-bidi: isolate;
101
- }
102
- * { box-sizing: border-box; }
103
- .wh-panel {
104
- position: fixed;
105
- z-index: 2147483647;
106
- width: min(420px, calc(100vw - 32px));
107
- max-height: min(70vh, 640px);
108
- display: flex;
109
- flex-direction: column;
110
- font: 13px/1.5 ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
111
- color: #e5e7eb;
112
- background: #0b0f17;
113
- border: 1px solid #1f2937;
114
- border-radius: 12px;
115
- box-shadow: 0 12px 40px rgba(0,0,0,.5);
116
- overflow: hidden;
117
- direction: ltr;
118
- text-align: left;
119
- }
120
- .wh-bottom-right { bottom: 16px; right: 16px; }
121
- .wh-bottom-left { bottom: 16px; left: 16px; }
122
- .wh-top-right { top: 16px; right: 16px; }
123
- .wh-top-left { top: 16px; left: 16px; }
124
- .wh-header {
125
- display: flex; align-items: center; gap: 8px;
126
- padding: 10px 12px;
127
- background: linear-gradient(180deg, #151b26, #0d1220);
128
- border-bottom: 1px solid #1f2937;
129
- }
130
- .wh-dot { width: 8px; height: 8px; border-radius: 50%; background: #f59e0b; flex: none; }
131
- .wh-title { font-weight: 600; color: #f3f4f6; }
132
- .wh-count {
133
- margin-left: auto; font-size: 11px; color: #9ca3af;
134
- background: #111827; border: 1px solid #1f2937; border-radius: 999px;
135
- padding: 1px 8px;
136
- }
137
- .wh-btn {
138
- appearance: none; border: 1px solid #1f2937; background: #111827;
139
- color: #9ca3af; border-radius: 6px; cursor: pointer;
140
- font-size: 12px; padding: 3px 8px;
141
- }
142
- .wh-btn:hover { color: #f3f4f6; border-color: #374151; }
143
- .wh-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 8px; display: flex; flex-direction: column; gap: 8px; }
144
- .wh-card { flex: 0 0 auto; border: 1px solid #1f2937; border-radius: 10px; background: #0f1521; overflow: hidden; }
145
- .wh-card-head { display: flex; align-items: center; gap: 8px; padding: 8px 10px; }
146
- .wh-cat {
147
- font-weight: 600; color: #fbbf24; font-size: 12px;
148
- }
149
- .wh-conf { margin-left: auto; font-size: 11px; color: #6b7280; }
150
- .wh-body { padding: 0 10px 10px; }
151
- .wh-where { font-size: 11px; color: #9ca3af; word-break: break-all; margin-bottom: 4px; }
152
- .wh-where code { color: #93c5fd; }
153
- .wh-comp { color: #f3f4f6; font-weight: 600; }
154
- .wh-loc { font-size: 11px; color: #7dd3fc; word-break: break-all; margin-bottom: 8px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
155
- .wh-diff { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 8px; }
156
- .wh-side { border-radius: 8px; padding: 6px 8px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; word-break: break-word; }
157
- .wh-server { background: rgba(244,63,94,.08); border: 1px solid rgba(244,63,94,.35); }
158
- .wh-client { background: rgba(34,197,94,.08); border: 1px solid rgba(34,197,94,.35); }
159
- .wh-side .wh-label { display: block; font-family: inherit; font-size: 9px; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 3px; }
160
- .wh-server .wh-label { color: #fb7185; }
161
- .wh-client .wh-label { color: #4ade80; }
162
- .wh-explain { color: #cbd5e1; margin-bottom: 8px; }
163
- .wh-fix { color: #e5e7eb; background: #111827; border-left: 3px solid #22c55e; border-radius: 4px; padding: 6px 8px; }
164
- .wh-fix strong { color: #86efac; }
165
- .wh-docs { display: inline-block; margin-top: 6px; color: #60a5fa; text-decoration: none; font-size: 11px; }
166
- .wh-docs:hover { text-decoration: underline; }
167
- .wh-empty-value { color: #6b7280; font-style: italic; }
168
- .wh-hint {
169
- display: none; align-items: center; gap: 8px;
170
- padding: 7px 12px; font-size: 11px; color: #cbd5e1;
171
- background: #0d1220; border-top: 1px solid #1f2937;
172
- animation: wh-fade .2s ease;
173
- }
174
- .wh-hint.wh-show { display: flex; }
175
- .wh-hint-text { flex: 1; }
176
- .wh-hint-x {
177
- appearance: none; border: 0; background: transparent; cursor: pointer;
178
- color: #9ca3af; font-size: 14px; line-height: 1; padding: 2px 4px;
179
- }
180
- .wh-hint-x:hover { color: #f3f4f6; }
181
- @keyframes wh-fade { from { opacity: 0 } to { opacity: 1 } }
182
- @media (max-width: 420px) {
183
- .wh-panel { width: auto; max-height: min(80vh, 640px); }
184
- .wh-bottom-right, .wh-bottom-left { left: 8px; right: 8px; }
185
- .wh-top-right, .wh-top-left { left: 8px; right: 8px; }
186
- .wh-diff { grid-template-columns: 1fr; }
187
- }
188
- `;
189
- function el(tag, className, text) {
190
- const node = document.createElement(tag);
191
- if (className) node.className = className;
192
- if (text != null) node.textContent = text;
193
- return node;
194
- }
195
- function shortenPath(file) {
196
- const normalized = file.replace(/\\/g, "/");
197
- const marker = normalized.match(/(?:^|\/)(?:src|app|pages|components)\//);
198
- if (marker && marker.index != null) {
199
- return normalized.slice(marker.index).replace(/^\//, "");
200
- }
201
- const parts = normalized.split("/");
202
- return parts.slice(-2).join("/");
203
- }
204
- function renderValue(value) {
205
- if (value == null || value === "") {
206
- return el("span", "wh-empty-value", value === "" ? "(empty)" : "(none)");
207
- }
208
- const span = document.createElement("span");
209
- span.textContent = value;
210
- return span;
211
- }
212
- function renderCard(report) {
213
- const card = el("div", "wh-card");
214
- const head = el("div", "wh-card-head");
215
- head.appendChild(
216
- el("span", "wh-cat", CATEGORY_LABELS[report.cause.category] ?? "Mismatch")
217
- );
218
- head.appendChild(
219
- el("span", "wh-conf", `${Math.round(report.cause.confidence * 100)}%`)
220
- );
221
- card.appendChild(head);
222
- const body = el("div", "wh-body");
223
- const where = el("div", "wh-where");
224
- if (report.component) {
225
- where.appendChild(el("strong", "wh-comp", `<${report.component}>`));
226
- where.append(" \xB7 ");
227
- } else if (report.node.tagName) {
228
- where.append(`<${report.node.tagName.toLowerCase()}> \xB7 `);
229
- }
230
- const code = el("code");
231
- code.textContent = report.node.path;
232
- where.appendChild(code);
233
- if (report.node.attribute) {
234
- where.append(` \xB7 @${report.node.attribute}`);
235
- }
236
- body.appendChild(where);
237
- if (report.location?.file) {
238
- const loc = el("div", "wh-loc");
239
- const file = shortenPath(report.location.file);
240
- loc.textContent = report.location.line ? `${file}:${report.location.line}` : file;
241
- body.appendChild(loc);
242
- }
243
- const diff = el("div", "wh-diff");
244
- const server = el("div", "wh-side wh-server");
245
- server.appendChild(el("span", "wh-label", "Server"));
246
- server.appendChild(renderValue(report.server));
247
- const client = el("div", "wh-side wh-client");
248
- client.appendChild(el("span", "wh-label", "Client"));
249
- client.appendChild(renderValue(report.client));
250
- diff.appendChild(server);
251
- diff.appendChild(client);
252
- body.appendChild(diff);
253
- body.appendChild(el("div", "wh-explain", report.cause.explanation));
254
- const fix = el("div", "wh-fix");
255
- const strong = el("strong");
256
- strong.textContent = "Fix: ";
257
- fix.appendChild(strong);
258
- fix.append(report.cause.suggestion);
259
- body.appendChild(fix);
260
- if (report.cause.docsUrl && /^https?:\/\//i.test(report.cause.docsUrl)) {
261
- const a = el("a", "wh-docs", "Learn more \u2192");
262
- a.href = report.cause.docsUrl;
263
- a.target = "_blank";
264
- a.rel = "noreferrer noopener";
265
- body.appendChild(a);
266
- }
267
- card.appendChild(body);
268
- return card;
269
- }
270
- function createOverlay(options = {}) {
271
- const position = options.position ?? "bottom-right";
272
- let host = null;
273
- let listEl = null;
274
- let countEl = null;
275
- let hintEl = null;
276
- let hintTextEl = null;
277
- let hintCheckTimer = null;
278
- let hintDismissed = false;
279
- let count = 0;
280
- function ensureMounted() {
281
- if (host) return;
282
- document.getElementById(CONTAINER_ID)?.remove();
283
- host = document.createElement("div");
284
- host.id = CONTAINER_ID;
285
- host.setAttribute("data-why-hydration", "overlay");
286
- host.setAttribute("aria-hidden", "false");
287
- const shadow = host.attachShadow({ mode: "open" });
288
- const style = document.createElement("style");
289
- style.textContent = STYLES;
290
- shadow.appendChild(style);
291
- const panel = el("div", `wh-panel wh-${position}`);
292
- panel.setAttribute("role", "dialog");
293
- panel.setAttribute("aria-label", "Hydration mismatch diagnostics");
294
- const header = el("div", "wh-header");
295
- header.appendChild(el("span", "wh-dot"));
296
- header.appendChild(el("span", "wh-title", "Hydration mismatch"));
297
- countEl = el("span", "wh-count", "0");
298
- header.appendChild(countEl);
299
- const close = el("button", "wh-btn", "Dismiss");
300
- close.setAttribute("aria-label", "Dismiss diagnostics overlay");
301
- close.addEventListener("click", () => destroy());
302
- header.appendChild(close);
303
- panel.appendChild(header);
304
- listEl = el("div", "wh-list");
305
- panel.appendChild(listEl);
306
- hintEl = el("div", "wh-hint");
307
- hintTextEl = el("span", "wh-hint-text");
308
- hintEl.appendChild(hintTextEl);
309
- const hintX = el("button", "wh-hint-x", "\u2715");
310
- hintX.setAttribute("aria-label", "Dismiss hint");
311
- hintX.addEventListener("click", () => dismissHint());
312
- hintEl.appendChild(hintX);
313
- panel.appendChild(hintEl);
314
- shadow.appendChild(panel);
315
- document.body.appendChild(host);
316
- host.addEventListener("keydown", (e) => {
317
- if (e.key === "Escape") destroy();
318
- });
319
- }
320
- function dismissHint() {
321
- hintDismissed = true;
322
- hintEl?.classList.remove("wh-show");
323
- }
324
- function updateHint() {
325
- if (!hintEl || !hintTextEl || hintDismissed) return;
326
- hintTextEl.textContent = `\u2193 ${count} issues \u2014 scroll to see all`;
327
- if (count >= 4) hintEl.classList.add("wh-show");
328
- }
329
- function destroy() {
330
- if (hintCheckTimer) clearTimeout(hintCheckTimer);
331
- hintCheckTimer = null;
332
- host?.remove();
333
- host = null;
334
- listEl = null;
335
- countEl = null;
336
- hintEl = null;
337
- hintTextEl = null;
338
- }
339
- function push(report) {
340
- ensureMounted();
341
- count += 1;
342
- if (countEl) countEl.textContent = String(count);
343
- listEl?.appendChild(renderCard(report));
344
- if (hintCheckTimer) clearTimeout(hintCheckTimer);
345
- hintCheckTimer = setTimeout(updateHint, 400);
346
- }
347
- return { push, destroy };
348
- }
349
-
350
- // src/react/fiber.ts
351
- function getFiber(node) {
352
- for (const key in node) {
353
- if (key.startsWith("__reactFiber$") || key.startsWith("__reactInternalInstance$")) {
354
- return node[key] ?? null;
355
- }
356
- }
357
- return null;
358
- }
359
- function componentName(type) {
360
- if (!type || typeof type === "string") return void 0;
361
- if (typeof type === "function") {
362
- const fn = type;
363
- return fn.displayName || fn.name || void 0;
364
- }
365
- if (typeof type === "object") {
366
- const obj = type;
367
- if (obj.displayName) return obj.displayName;
368
- if (obj.render) return obj.render.displayName || obj.render.name;
369
- if (obj.type) return componentName(obj.type);
370
- }
371
- return void 0;
372
- }
373
- function resolveReactSource(node) {
374
- if (!node) return {};
375
- try {
376
- let fiber = getFiber(node);
377
- let component;
378
- let location;
379
- let hops = 0;
380
- while (fiber && hops < 80) {
381
- if (!component) {
382
- const name = componentName(fiber.type);
383
- if (name && !/^[a-z]/.test(name)) component = name;
384
- }
385
- if (!location && fiber._debugSource?.fileName) {
386
- location = {
387
- file: fiber._debugSource.fileName,
388
- line: fiber._debugSource.lineNumber,
389
- column: fiber._debugSource.columnNumber
390
- };
391
- }
392
- if (component && location) break;
393
- fiber = fiber.return ?? null;
394
- hops += 1;
395
- }
396
- const result = {};
397
- if (component) result.component = component;
398
- if (location) result.location = location;
399
- return result;
400
- } catch {
401
- return {};
402
- }
403
- }
404
-
405
- // src/react/controller.ts
406
- function buildIgnore(ignore) {
407
- if (!ignore || ignore.length === 0) return void 0;
408
- return (divergence) => {
409
- const node = divergence.element ?? null;
410
- for (const rule of ignore) {
411
- if (typeof rule === "function") {
412
- if (node && rule(node)) return true;
413
- } else if (node) {
414
- try {
415
- if (node.matches(rule) || node.closest(rule)) return true;
416
- } catch {
417
- }
418
- }
419
- }
420
- return false;
421
- };
422
- }
423
- var InspectorController = class {
424
- constructor(options = {}) {
425
- this.cleanups = [];
426
- this.started = false;
427
- this.pendingContext = {};
428
- this.messages = /* @__PURE__ */ new Set();
429
- this.settlingTimers = [];
430
- this.onRecoverableError = (error, info) => {
431
- if (!chunkDSO337ME_cjs.isDev) return;
432
- const message = error instanceof Error ? error.message : String(error);
433
- this.messages.add(message);
434
- this.mergeContext({
435
- componentStack: info?.componentStack,
436
- component: firstComponentFromStack(info?.componentStack),
437
- reactMessage: message
438
- });
439
- this.scheduleInspect();
440
- };
441
- this.options = options;
442
- this.collector = new chunkDSO337ME_cjs.ReportCollector({
443
- maxReports: options.maxReports,
444
- extra: options.classify,
445
- ignore: buildIgnore(options.ignore)
446
- });
447
- }
448
- start() {
449
- if (this.started || !chunkDSO337ME_cjs.isDev || typeof window === "undefined") return;
450
- this.started = true;
451
- this.pendingContext = {};
452
- this.messages.clear();
453
- if (this.options.onReport) {
454
- this.collector.addSink(this.options.onReport);
455
- }
456
- this.collector.addSink(createConsoleReporter());
457
- if (this.options.overlay !== false) {
458
- const overlayOpts = typeof this.options.overlay === "object" ? this.options.overlay : {};
459
- const handle = createOverlay(overlayOpts);
460
- this.collector.addSink(handle.push);
461
- this.cleanups.push(() => handle.destroy());
462
- }
463
- const restore = installConsoleInterceptor((message) => {
464
- this.messages.add(message);
465
- this.mergeContext({ reactMessage: message });
466
- this.scheduleInspect();
467
- });
468
- this.cleanups.push(restore);
469
- this.scheduleSettlingInspections();
470
- }
471
- // React applies client values to mismatched subtrees via a client re-render a
472
- // few hundred ms after the initial hydration commit. We diff once per frame
473
- // and then across this short "settling window" to catch that, deduped. This
474
- // is a bounded, one-shot window — NOT a standing observer — so DOM changes
475
- // from later app state are never mistaken for hydration mismatches.
476
- scheduleSettlingInspections() {
477
- this.scheduleInspect();
478
- for (const delay of [80, 250, 700, 1500]) {
479
- const timer = setTimeout(() => this.inspectAllRoots(), delay);
480
- this.settlingTimers.push(timer);
481
- }
482
- }
483
- mergeContext(ctx) {
484
- this.pendingContext = {
485
- componentStack: this.pendingContext.componentStack ?? ctx.componentStack,
486
- component: this.pendingContext.component ?? ctx.component,
487
- location: this.pendingContext.location ?? ctx.location,
488
- reactMessage: this.pendingContext.reactMessage ?? ctx.reactMessage
489
- };
490
- }
491
- stop() {
492
- for (const timer of this.settlingTimers.splice(0)) clearTimeout(timer);
493
- for (const cleanup of this.cleanups.splice(0)) cleanup();
494
- this.messages.clear();
495
- this.started = false;
496
- }
497
- getReports() {
498
- return this.collector.getReports();
499
- }
500
- inspectNow(context = {}) {
501
- this.mergeContext(context);
502
- this.inspectAllRoots();
503
- }
504
- inspectAllRoots() {
505
- if (!this.started || typeof document === "undefined" || this.collector.isFull) {
506
- return;
507
- }
508
- const selectors = this.options.roots ?? snapshotSelectors();
509
- const seen = /* @__PURE__ */ new Set();
510
- for (const selector of selectors) {
511
- const root = document.querySelector(selector);
512
- if (!root || seen.has(root)) continue;
513
- seen.add(root);
514
- chunkDSO337ME_cjs.inspectRoot(
515
- root,
516
- this.collector,
517
- this.pendingContext,
518
- (divergence) => resolveReactSource(divergence.element ?? null)
519
- );
520
- }
521
- for (const message of this.messages) {
522
- chunkDSO337ME_cjs.reportFromMessage(message, this.collector, this.pendingContext);
523
- }
524
- }
525
- scheduleInspect() {
526
- const run = () => this.inspectAllRoots();
527
- if (typeof requestAnimationFrame === "function") {
528
- requestAnimationFrame(run);
529
- } else {
530
- Promise.resolve().then(run);
531
- }
532
- }
533
- };
534
- function snapshotSelectors() {
535
- const snapshot = chunkOGQEPU7G_cjs.readSnapshot();
536
- const keys = snapshot ? Object.keys(snapshot.roots) : [];
537
- return keys.length > 0 ? keys : [...chunkOGQEPU7G_cjs.DEFAULT_SNAPSHOT_SELECTORS];
538
- }
539
- function firstComponentFromStack(stack) {
540
- if (!stack) return void 0;
541
- const match = /\n?\s*(?:at|in)\s+([A-Za-z0-9_$]+)/.exec(stack);
542
- return match?.[1];
543
- }
544
- function InspectorImpl(props) {
545
- const { children, overlay, onReport, ignore, classify, maxReports } = props;
546
- const controllerRef = React2__namespace.useRef(null);
547
- if (controllerRef.current === null) {
548
- controllerRef.current = new InspectorController({
549
- overlay,
550
- onReport,
551
- ignore,
552
- classify,
553
- maxReports
554
- });
555
- controllerRef.current.start();
556
- }
557
- React2__namespace.useEffect(() => {
558
- const controller = controllerRef.current;
559
- return () => controller?.stop();
560
- }, []);
561
- return React2__namespace.createElement(React2__namespace.Fragment, null, children);
562
- }
563
-
564
- // src/react/index.tsx
565
- function PassThrough(props) {
566
- return React2__namespace.createElement(React2__namespace.Fragment, null, props.children);
567
- }
568
- var HydrationInspector = process.env.NODE_ENV !== "production" ? InspectorImpl : PassThrough;
569
- function createHydrationInspector(options = {}) {
570
- if (process.env.NODE_ENV === "production") {
571
- return {
572
- onRecoverableError: () => {
573
- },
574
- Provider: PassThrough
575
- };
576
- }
577
- const controller = new InspectorController(options);
578
- controller.start();
579
- function Provider(props) {
580
- React2__namespace.useEffect(() => () => controller.stop(), []);
581
- return React2__namespace.createElement(React2__namespace.Fragment, null, props.children);
582
- }
583
- return {
584
- onRecoverableError: controller.onRecoverableError,
585
- Provider
586
- };
587
- }
588
-
589
- exports.HydrationInspector = HydrationInspector;
590
- exports.createHydrationInspector = createHydrationInspector;
591
- //# sourceMappingURL=chunk-5CBGYE7A.cjs.map
592
- //# sourceMappingURL=chunk-5CBGYE7A.cjs.map