nuxt-devtools-observatory 0.1.11 → 0.1.13
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/LICENSE +9 -0
- package/README.md +114 -31
- package/client/dist/assets/index-BFrWlkvI.js +17 -0
- package/client/dist/assets/index-BUQNNbrq.css +1 -0
- package/client/dist/index.html +2 -2
- package/client/src/stores/observatory.ts +59 -15
- package/client/src/views/ComposableTracker.vue +685 -101
- package/client/src/views/ProvideInjectGraph.vue +232 -61
- package/client/src/views/RenderHeatmap.vue +138 -37
- package/client/src/views/TransitionTimeline.vue +2 -2
- package/client/src/views/ValueInspector.vue +124 -0
- package/dist/module.json +1 -1
- package/dist/runtime/composables/composable-registry.d.ts +21 -0
- package/dist/runtime/composables/composable-registry.js +208 -53
- package/dist/runtime/composables/provide-inject-registry.d.ts +13 -1
- package/dist/runtime/composables/provide-inject-registry.js +34 -6
- package/dist/runtime/composables/render-registry.d.ts +18 -8
- package/dist/runtime/composables/render-registry.js +29 -35
- package/dist/runtime/composables/transition-registry.js +13 -7
- package/dist/runtime/plugin.js +49 -17
- package/package.json +7 -3
- package/client/dist/assets/index--Igqz_EM.js +0 -17
- package/client/dist/assets/index-BoC4M4Nb.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.view[data-v-8c1465c0]{display:flex;flex-direction:column;height:100%;overflow:hidden;padding:12px;gap:10px}.stats-row[data-v-8c1465c0]{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;flex-shrink:0}.toolbar[data-v-8c1465c0]{display:flex;align-items:center;gap:6px;flex-shrink:0;flex-wrap:wrap}.split[data-v-8c1465c0]{display:flex;gap:12px;flex:1;overflow:hidden;min-height:0}.table-wrap[data-v-8c1465c0]{flex:1;overflow:auto;border:.5px solid var(--border);border-radius:var(--radius-lg)}.detail-panel[data-v-8c1465c0]{width:280px;flex-shrink:0;display:flex;flex-direction:column;gap:8px;overflow:auto;border:.5px solid var(--border);border-radius:var(--radius-lg);padding:12px;background:var(--bg3)}.detail-empty[data-v-8c1465c0]{width:280px;flex-shrink:0;display:flex;align-items:center;justify-content:center;color:var(--text3);font-size:12px;border:.5px dashed var(--border);border-radius:var(--radius-lg)}.detail-header[data-v-8c1465c0]{display:flex;align-items:center;justify-content:space-between}.meta-grid[data-v-8c1465c0]{display:grid;grid-template-columns:auto 1fr;gap:4px 12px;font-size:11px}.section-label[data-v-8c1465c0]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin-top:6px}.payload-box[data-v-8c1465c0]{font-family:var(--mono);font-size:11px;color:var(--text2);background:var(--bg2);border-radius:var(--radius);padding:8px 10px;overflow:auto;white-space:pre;max-height:160px}.waterfall[data-v-8c1465c0]{flex-shrink:0;background:var(--bg3);border:.5px solid var(--border);border-radius:var(--radius-lg);padding:10px 12px}.waterfall-header[data-v-8c1465c0]{display:flex;align-items:center;justify-content:space-between;gap:8px}.waterfall-body[data-v-8c1465c0]{margin-top:6px}.wf-row[data-v-8c1465c0]{display:flex;align-items:center;gap:8px;margin-bottom:4px}.wf-track[data-v-8c1465c0]{flex:1;position:relative;height:8px;background:var(--bg2);border-radius:2px;overflow:hidden}.wf-bar[data-v-8c1465c0]{position:absolute;top:0;height:100%;border-radius:2px;opacity:.8}.view[data-v-f074866d]{display:flex;flex-direction:column;height:100%;overflow:hidden;padding:12px;gap:10px}.toolbar[data-v-f074866d]{display:flex;align-items:center;gap:6px;flex-shrink:0;flex-wrap:wrap}.split[data-v-f074866d]{display:flex;gap:12px;flex:1;overflow:hidden;min-height:0}.graph-area[data-v-f074866d]{flex:1;overflow:auto;border:.5px solid var(--border);border-radius:var(--radius-lg);padding:12px;background:var(--bg3)}.legend[data-v-f074866d]{display:flex;align-items:center;gap:12px;font-size:11px;color:var(--text2);margin-bottom:12px}.canvas-stage[data-v-f074866d]{display:flex;justify-content:center;align-items:flex-start;min-width:100%}.dot[data-v-f074866d]{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px}.canvas-wrap[data-v-f074866d]{position:relative}.edges-svg[data-v-f074866d]{position:absolute;top:0;left:0;pointer-events:none}.edge[data-v-f074866d]{stroke:var(--border);stroke-width:1.5}.graph-node[data-v-f074866d]{position:absolute;display:flex;align-items:center;gap:7px;padding:0 10px;height:32px;border-radius:var(--radius);border:.5px solid var(--border);background:var(--bg3);cursor:pointer;transition:border-color .12s,background .12s;overflow:hidden;box-sizing:border-box;white-space:nowrap}.graph-node[data-v-f074866d]:hover{border-color:var(--text3)}.graph-node.is-selected[data-v-f074866d]{border-color:var(--node-color);background:color-mix(in srgb,var(--node-color) 8%,transparent)}.node-dot[data-v-f074866d]{width:7px;height:7px;border-radius:50%;flex-shrink:0}.node-label[data-v-f074866d]{font-size:11px;flex:1;overflow:hidden;text-overflow:ellipsis}.badge-xs[data-v-f074866d]{font-size:9px;padding:1px 4px}.detail-panel[data-v-f074866d]{width:280px;flex-shrink:0;overflow:auto;border:.5px solid var(--border);border-radius:var(--radius-lg);padding:12px;background:var(--bg3);display:flex;flex-direction:column;gap:4px;min-height:0}.detail-empty[data-v-f074866d]{width:280px;display:flex;align-items:center;justify-content:center;color:var(--text3);font-size:12px;border:.5px dashed var(--border);border-radius:var(--radius-lg);flex-shrink:0}.graph-empty[data-v-f074866d]{display:flex;align-items:center;justify-content:center;min-height:180px;color:var(--text3);font-size:12px}.detail-header[data-v-f074866d]{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}.section-label[data-v-f074866d]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin:8px 0 5px}.detail-section[data-v-f074866d]{display:flex;flex-direction:column;min-height:0}.detail-list[data-v-f074866d]{display:flex;flex-direction:column;gap:3px;overflow:auto;max-height:220px;padding-right:2px}.provide-row[data-v-f074866d]{display:flex;flex-direction:column;gap:4px;padding:5px 8px;background:var(--bg2);border-radius:var(--radius);margin-bottom:3px}.row-warning[data-v-f074866d]{font-size:11px;color:var(--amber);padding:2px 0}.row-consumers[data-v-f074866d]{display:flex;flex-wrap:wrap;align-items:center;gap:4px;padding:2px 0}.consumer-chip[data-v-f074866d]{font-size:10px;padding:1px 6px;border-radius:4px;background:color-mix(in srgb,var(--blue) 10%,var(--bg3));border:.5px solid color-mix(in srgb,var(--blue) 30%,var(--border));color:var(--text2)}.scope-badge[data-v-f074866d]{font-size:10px;padding:1px 6px;border-radius:4px}.scope-global[data-v-f074866d]{background:color-mix(in srgb,var(--amber) 15%,transparent);border:.5px solid color-mix(in srgb,var(--amber) 40%,var(--border));color:color-mix(in srgb,var(--amber) 80%,var(--text))}.scope-layout[data-v-f074866d]{background:color-mix(in srgb,var(--purple) 15%,transparent);border:.5px solid color-mix(in srgb,var(--purple) 40%,var(--border));color:color-mix(in srgb,var(--purple) 80%,var(--text))}.scope-component[data-v-f074866d]{background:var(--bg3);border:.5px solid var(--border);color:var(--text3)}.row-main[data-v-f074866d]{display:flex;align-items:center;gap:8px;min-width:0}.row-key[data-v-f074866d]{min-width:100px;color:var(--text2);flex-shrink:0}.row-value-preview[data-v-f074866d]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.row-toggle[data-v-f074866d]{padding:2px 8px;font-size:10px}.value-box[data-v-f074866d]{font-family:var(--mono);font-size:11px;color:var(--text2);background:#0000001a;border-radius:var(--radius);padding:8px 10px;white-space:pre-wrap;word-break:break-word;overflow:auto;max-height:180px}.inject-row[data-v-f074866d]{display:flex;align-items:center;gap:8px;padding:5px 8px;background:var(--bg2);border-radius:var(--radius);margin-bottom:3px}.row-from[data-v-f074866d]{margin-left:auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.inject-miss[data-v-f074866d]{background:#e24b4a14}.view[data-v-d1ee181e]{display:flex;flex-direction:column;height:100%;overflow:hidden;padding:12px;gap:10px}.stats-row[data-v-d1ee181e]{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;flex-shrink:0}.toolbar[data-v-d1ee181e]{display:flex;align-items:center;gap:6px;flex-shrink:0;flex-wrap:wrap}.clear-btn[data-v-d1ee181e]{color:var(--text3);border-color:var(--border);flex-shrink:0}.clear-btn[data-v-d1ee181e]:hover{color:var(--red);border-color:var(--red);background:transparent}.list[data-v-d1ee181e]{flex:1;overflow:auto;display:flex;flex-direction:column;gap:5px;min-height:0}.comp-card[data-v-d1ee181e]{background:var(--bg3);border:.5px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;cursor:pointer;flex-shrink:0}.comp-card[data-v-d1ee181e]:hover{border-color:var(--text3)}.comp-card.leak[data-v-d1ee181e]{border-left:2px solid var(--red);border-radius:0 var(--radius-lg) var(--radius-lg) 0}.comp-card.expanded[data-v-d1ee181e]{border-color:var(--purple)}.comp-header[data-v-d1ee181e]{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;gap:8px}.comp-identity[data-v-d1ee181e]{display:flex;align-items:baseline;gap:6px;min-width:0;flex:1}.comp-name[data-v-d1ee181e]{font-size:12px;font-weight:500;color:var(--text);flex-shrink:0}.comp-file[data-v-d1ee181e]{font-size:11px;color:var(--text3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.comp-meta[data-v-d1ee181e]{display:flex;align-items:center;gap:5px;flex-shrink:0}.refs-preview[data-v-d1ee181e]{display:flex;flex-wrap:wrap;gap:4px;padding:0 12px 8px;align-items:center}.ref-chip[data-v-d1ee181e]{display:inline-flex;align-items:center;gap:4px;padding:2px 7px;border-radius:4px;background:var(--bg2);border:.5px solid var(--border);font-size:11px;font-family:var(--mono);max-width:220px;overflow:hidden}.ref-chip--reactive[data-v-d1ee181e]{border-color:color-mix(in srgb,var(--purple) 40%,var(--border));background:color-mix(in srgb,var(--purple) 8%,var(--bg2))}.ref-chip--computed[data-v-d1ee181e]{border-color:color-mix(in srgb,var(--blue) 40%,var(--border));background:color-mix(in srgb,var(--blue) 8%,var(--bg2))}.ref-chip-key[data-v-d1ee181e]{color:var(--text2);flex-shrink:0}.ref-chip-val[data-v-d1ee181e]{color:var(--teal);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.comp-detail[data-v-d1ee181e]{padding:4px 12px 12px;border-top:.5px solid var(--border);display:flex;flex-direction:column;gap:3px}.leak-banner[data-v-d1ee181e]{background:color-mix(in srgb,var(--red) 12%,transparent);border:.5px solid color-mix(in srgb,var(--red) 40%,var(--border));border-radius:var(--radius);padding:6px 10px;font-size:11px;color:var(--red);margin-bottom:6px;font-family:var(--mono)}.section-label[data-v-d1ee181e]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin-top:6px;margin-bottom:3px}.ref-row[data-v-d1ee181e]{display:flex;align-items:center;gap:8px;padding:3px 0}.ref-key[data-v-d1ee181e]{min-width:90px;color:var(--text2);flex-shrink:0}.ref-val[data-v-d1ee181e]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--teal)}.lc-row[data-v-d1ee181e]{display:flex;align-items:center;gap:8px;padding:2px 0}.lc-dot[data-v-d1ee181e]{width:6px;height:6px;border-radius:50%;flex-shrink:0}.ref-chip--shared[data-v-d1ee181e]{border-color:color-mix(in srgb,var(--amber) 50%,var(--border));background:color-mix(in srgb,var(--amber) 10%,var(--bg2))}.ref-chip-shared-dot[data-v-d1ee181e]{display:inline-block;width:5px;height:5px;border-radius:50%;background:var(--amber);flex-shrink:0;margin-left:1px}.global-banner[data-v-d1ee181e]{display:flex;align-items:flex-start;gap:8px;background:color-mix(in srgb,var(--amber) 10%,transparent);border:.5px solid color-mix(in srgb,var(--amber) 40%,var(--border));border-radius:var(--radius);padding:7px 10px;font-size:11px;color:var(--text2);margin-bottom:6px}.global-dot[data-v-d1ee181e]{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--amber);flex-shrink:0;margin-top:3px}.badge-amber[data-v-d1ee181e]{background:color-mix(in srgb,var(--amber) 15%,transparent);color:color-mix(in srgb,var(--amber) 80%,var(--text));border:.5px solid color-mix(in srgb,var(--amber) 40%,var(--border))}.history-list[data-v-d1ee181e]{display:flex;flex-direction:column;gap:1px;background:var(--bg2);border-radius:var(--radius);padding:4px 8px;max-height:180px;overflow-y:auto}.history-row[data-v-d1ee181e]{display:flex;align-items:center;gap:8px;padding:2px 0;font-size:11px;font-family:var(--mono);border-bottom:.5px solid var(--border)}.history-row[data-v-d1ee181e]:last-child{border-bottom:none}.history-time[data-v-d1ee181e]{min-width:52px;color:var(--text3);flex-shrink:0}.history-key[data-v-d1ee181e]{min-width:80px;color:var(--text2);flex-shrink:0}.history-val[data-v-d1ee181e]{color:var(--amber);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.stat-card[data-v-d1ee181e]{background:var(--bg3);border:.5px solid var(--border);border-radius:var(--radius-lg);padding:10px 14px}.stat-label[data-v-d1ee181e]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin-bottom:4px}.stat-val[data-v-d1ee181e]{font-size:22px;font-weight:500;line-height:1;color:var(--text)}.ref-key--clickable[data-v-d1ee181e]{cursor:pointer;text-decoration:underline dotted var(--text3);text-underline-offset:2px}.ref-key--clickable[data-v-d1ee181e]:hover{color:var(--purple);text-decoration-color:var(--purple)}.edit-btn[data-v-d1ee181e]{font-size:10px;padding:1px 6px;border-radius:var(--radius);border:.5px solid var(--border);background:transparent;color:var(--text3);cursor:pointer;margin-left:auto;flex-shrink:0;font-family:var(--mono)}.edit-btn[data-v-d1ee181e]:hover{border-color:var(--purple);color:var(--purple);background:color-mix(in srgb,var(--purple) 8%,transparent)}.lookup-panel[data-v-d1ee181e]{flex-shrink:0;border:.5px solid var(--border);border-radius:var(--radius-lg);background:var(--bg3);overflow:hidden}.lookup-header[data-v-d1ee181e]{display:flex;align-items:center;gap:6px;padding:7px 12px;border-bottom:.5px solid var(--border);background:var(--bg2)}.lookup-row[data-v-d1ee181e]{display:flex;align-items:center;gap:8px;padding:5px 12px;border-bottom:.5px solid var(--border)}.lookup-row[data-v-d1ee181e]:last-child{border-bottom:none}.edit-overlay[data-v-d1ee181e]{position:fixed;top:0;right:0;bottom:0;left:0;background:#0006;z-index:100;display:flex;align-items:center;justify-content:center}.edit-dialog[data-v-d1ee181e]{background:var(--bg1, var(--bg2));border:.5px solid var(--border);border-radius:var(--radius-lg);padding:14px 16px;width:380px;max-width:92vw;display:flex;flex-direction:column;gap:6px;box-shadow:0 8px 32px #0000004d}.edit-dialog-header[data-v-d1ee181e]{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text2);margin-bottom:2px}.edit-textarea[data-v-d1ee181e]{width:100%;font-family:var(--mono);font-size:12px;padding:8px 10px;background:var(--bg2);border:.5px solid var(--border);border-radius:var(--radius);color:var(--text);resize:vertical;outline:none}.edit-textarea[data-v-d1ee181e]:focus{border-color:var(--purple)}.edit-error[data-v-d1ee181e]{color:var(--red);font-family:var(--mono)}.edit-actions[data-v-d1ee181e]{display:flex;gap:6px;padding-top:4px}.slide-enter-active[data-v-d1ee181e],.slide-leave-active[data-v-d1ee181e]{transition:opacity .15s,transform .15s}.slide-enter-from[data-v-d1ee181e],.slide-leave-to[data-v-d1ee181e]{opacity:0;transform:translateY(6px)}.fade-enter-active[data-v-d1ee181e],.fade-leave-active[data-v-d1ee181e]{transition:opacity .15s}.fade-enter-from[data-v-d1ee181e],.fade-leave-to[data-v-d1ee181e]{opacity:0}.view[data-v-73881a11]{display:flex;flex-direction:column;height:100%;overflow:hidden;padding:12px;gap:10px}.controls[data-v-73881a11]{display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap}.mode-group[data-v-73881a11]{display:flex;gap:2px}.threshold-group[data-v-73881a11]{display:flex;align-items:center;gap:6px}.stats-row[data-v-73881a11]{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;flex-shrink:0}.stat-sub[data-v-73881a11]{margin-top:4px;font-size:11px;color:var(--text3)}.inspector[data-v-73881a11]{display:grid;grid-template-columns:minmax(220px,280px) minmax(0,1fr) minmax(260px,320px);gap:12px;flex:1;min-height:0}.roots-panel[data-v-73881a11],.tree-panel[data-v-73881a11],.detail-panel[data-v-73881a11]{border:.5px solid var(--border);border-radius:var(--radius-lg);background:var(--bg3);min-height:0}.roots-panel[data-v-73881a11],.detail-panel[data-v-73881a11]{display:flex;flex-direction:column;overflow:auto;padding:12px;gap:8px}.panel-title[data-v-73881a11]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3)}.root-item[data-v-73881a11]{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg2);color:var(--text);text-align:left}.root-item.active[data-v-73881a11]{border-color:var(--teal);background:color-mix(in srgb,var(--teal) 16%,var(--bg2))}.root-label[data-v-73881a11]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.root-copy[data-v-73881a11]{display:flex;flex-direction:column;min-width:0}.root-sub[data-v-73881a11]{font-size:11px}.root-meta[data-v-73881a11]{color:var(--text3);font-size:11px}.tree-panel[data-v-73881a11]{display:flex;flex-direction:column;overflow:hidden}.tree-toolbar[data-v-73881a11]{padding:12px;border-bottom:.5px solid var(--border)}.search-input[data-v-73881a11]{width:100%;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg2);color:var(--text)}.tree-frame[data-v-73881a11]{flex:1;min-height:0;overflow:auto;padding:12px}[data-v-73881a11] .tree-canvas{display:inline-block;min-width:100%;width:max-content}[data-v-73881a11] .tree-node{margin-bottom:4px}[data-v-73881a11] .tree-row{display:grid;grid-template-columns:8px 18px minmax(0,1fr) auto;align-items:center;gap:6px;min-width:0;width:100%;padding:4px 8px;padding-left:calc(8px + (var(--tree-depth, 0) * 16px));border:1px solid transparent;border-radius:var(--radius);cursor:pointer;white-space:nowrap}[data-v-73881a11] .tree-row:hover{background:var(--bg2)}[data-v-73881a11] .tree-row.selected{background:color-mix(in srgb,var(--teal) 12%,var(--bg2));border-color:var(--teal)}[data-v-73881a11] .tree-row.hot{box-shadow:inset 2px 0 0 var(--red)}[data-v-73881a11] .tree-toggle{width:16px;height:16px;border:none;background:transparent;color:var(--text3);padding:0;font-size:14px;display:inline-flex;align-items:center;justify-content:center}[data-v-73881a11] .tree-toggle:disabled{cursor:default}[data-v-73881a11] .tree-toggle.empty{opacity:0}[data-v-73881a11] .tree-rail{display:block;width:2px;height:14px;border-radius:999px;background:color-mix(in srgb,var(--border) 75%,transparent)}[data-v-73881a11] .tree-copy{display:flex;align-items:center;min-width:0;gap:6px;overflow:hidden}[data-v-73881a11] .tree-name{font-size:12px;color:var(--text);min-width:0;overflow:hidden;text-overflow:ellipsis}[data-v-73881a11] .tree-badges{display:flex;gap:6px;flex-shrink:0;overflow:hidden}[data-v-73881a11] .tree-badge{border:1px solid var(--border);border-radius:999px;padding:2px 7px;font-size:10px;color:var(--text3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:160px}[data-v-73881a11] .tree-metrics{display:flex;align-items:center;min-width:92px;justify-content:flex-end;flex-shrink:0;gap:6px}[data-v-73881a11] .tree-metric-pill{display:inline-flex;align-items:center;justify-content:center;min-width:78px;padding:2px 8px;border:1px solid var(--border);border-radius:999px;background:var(--bg2);font-size:10px;color:var(--text3)}[data-v-73881a11] .tree-persistent-pill{display:inline-flex;align-items:center;padding:2px 8px;border:1px solid color-mix(in srgb,var(--amber) 55%,var(--border));border-radius:999px;background:color-mix(in srgb,var(--amber) 10%,var(--bg2));font-size:10px;color:color-mix(in srgb,var(--amber) 80%,var(--text))}[data-v-73881a11] .tree-hydration-pill{display:inline-flex;align-items:center;padding:2px 8px;border:1px solid color-mix(in srgb,var(--teal) 55%,var(--border));border-radius:999px;background:color-mix(in srgb,var(--teal) 10%,var(--bg2));font-size:10px;color:color-mix(in srgb,var(--teal) 80%,var(--text))}[data-v-73881a11] .tree-children{margin-left:7px;padding-left:11px;border-left:1px solid color-mix(in srgb,var(--border) 72%,transparent)}.detail-empty[data-v-73881a11]{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text3);font-size:12px}.detail-header[data-v-73881a11]{display:flex;align-items:center;justify-content:space-between}.meta-grid[data-v-73881a11]{display:grid;grid-template-columns:auto 1fr;gap:4px 12px}.detail-pill-row[data-v-73881a11]{display:flex;flex-wrap:wrap;gap:6px}.detail-pill[data-v-73881a11]{border:1px solid var(--border);border-radius:999px;padding:4px 8px;background:var(--bg2);font-size:11px}.detail-pill.hot[data-v-73881a11]{border-color:color-mix(in srgb,var(--red) 50%,var(--border));color:var(--red)}.detail-pill.persistent[data-v-73881a11]{border-color:color-mix(in srgb,var(--amber) 55%,var(--border));color:color-mix(in srgb,var(--amber) 80%,var(--text))}.detail-pill.hydrated[data-v-73881a11]{border-color:color-mix(in srgb,var(--teal) 55%,var(--border));color:color-mix(in srgb,var(--teal) 80%,var(--text))}.detail-pill.muted[data-v-73881a11]{color:var(--text3);border-color:var(--border)}.section-label[data-v-73881a11]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin-top:8px;margin-bottom:4px}.trigger-item[data-v-73881a11]{background:var(--bg2);border-radius:var(--radius);padding:4px 8px;margin-bottom:3px;color:var(--text2)}@media(max-width:1180px){.inspector[data-v-73881a11]{grid-template-columns:minmax(200px,240px) minmax(0,1fr)}.detail-panel[data-v-73881a11]{grid-column:1 / -1;max-height:220px}}.timeline-root[data-v-da869dac]{display:flex;flex-direction:column;height:100%;overflow:hidden}.stats-row[data-v-da869dac]{display:flex;gap:10px;padding:12px 14px 0;flex-shrink:0}.stat-card[data-v-da869dac]{background:var(--bg2);border:.5px solid var(--border);border-radius:var(--radius);padding:8px 14px;min-width:72px;text-align:center}.stat-val[data-v-da869dac]{font-size:20px;font-weight:600;font-family:var(--mono);line-height:1.1}.stat-unit[data-v-da869dac]{font-size:12px;opacity:.6;margin-left:1px}.stat-label[data-v-da869dac]{font-size:10px;color:var(--text3);margin-top:2px;text-transform:uppercase;letter-spacing:.4px}.toolbar[data-v-da869dac]{display:flex;align-items:center;gap:8px;padding:10px 14px;flex-shrink:0;border-bottom:.5px solid var(--border)}.search-input[data-v-da869dac]{flex:1;max-width:260px}.filter-group[data-v-da869dac]{display:flex;gap:4px}.content-area[data-v-da869dac]{display:flex;flex:1;overflow:hidden;min-height:0}.table-pane[data-v-da869dac]{flex:1;overflow:hidden auto;min-width:0}.bar-cell[data-v-da869dac]{width:200px;padding:4px 8px}.bar-track[data-v-da869dac]{position:relative;height:8px;background:var(--bg2);border-radius:4px;overflow:hidden}.bar-fill[data-v-da869dac]{position:absolute;top:0;height:100%;min-width:3px;border-radius:4px;transition:width .15s}.detail-panel[data-v-da869dac]{width:260px;flex-shrink:0;border-left:.5px solid var(--border);overflow-y:auto;background:var(--bg3);padding:0 0 16px}.panel-header[data-v-da869dac]{display:flex;align-items:center;justify-content:space-between;padding:10px 14px 8px;border-bottom:.5px solid var(--border);position:sticky;top:0;background:var(--bg3);z-index:1}.panel-title[data-v-da869dac]{font-family:var(--mono);font-size:13px;font-weight:500}.close-btn[data-v-da869dac]{border:none;background:transparent;color:var(--text3);font-size:11px;padding:2px 6px;cursor:pointer}.panel-section[data-v-da869dac]{padding:10px 14px 6px;border-bottom:.5px solid var(--border)}.panel-section-title[data-v-da869dac]{font-size:10px;font-weight:500;color:var(--text3);text-transform:uppercase;letter-spacing:.4px;margin-bottom:8px}.panel-row[data-v-da869dac]{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:3px 0;font-size:12px}.panel-key[data-v-da869dac]{color:var(--text3);flex-shrink:0}.panel-val[data-v-da869dac]{color:var(--text);text-align:right;word-break:break-all}.cancel-notice[data-v-da869dac],.active-notice[data-v-da869dac]{margin:10px 14px 0;font-size:11px;line-height:1.6;padding:8px 10px;border-radius:var(--radius)}.cancel-notice[data-v-da869dac]{background:#e24b4a1a;color:var(--red);border:.5px solid rgb(226 75 74 / 30%)}.active-notice[data-v-da869dac]{background:#7f77dd1a;color:var(--purple);border:.5px solid rgb(127 119 221 / 30%)}code[data-v-da869dac]{font-family:var(--mono);font-size:10px;background:#00000026;padding:1px 4px;border-radius:3px}.panel-slide-enter-active[data-v-da869dac],.panel-slide-leave-active[data-v-da869dac]{transition:transform .18s ease,opacity .18s ease}.panel-slide-enter-from[data-v-da869dac],.panel-slide-leave-to[data-v-da869dac]{transform:translate(12px);opacity:0}#app-root[data-v-08e3ddb5]{display:flex;flex-direction:column;height:100vh;overflow:hidden}.tabbar[data-v-08e3ddb5]{display:flex;align-items:center;gap:2px;padding:8px 12px 0;border-bottom:.5px solid var(--border);background:var(--bg3);flex-shrink:0}.tabbar-brand[data-v-08e3ddb5]{font-size:11px;font-weight:500;color:var(--purple);letter-spacing:.5px;margin-right:12px;padding-bottom:8px}.tab-btn[data-v-08e3ddb5]{border:none;border-bottom:2px solid transparent;border-radius:0;background:transparent;color:var(--text3);font-size:12px;padding:6px 12px 8px;cursor:pointer;transition:color .12s,border-color .12s;display:flex;align-items:center;gap:5px}.tab-btn[data-v-08e3ddb5]:hover{color:var(--text);background:transparent}.tab-btn.active[data-v-08e3ddb5]{color:var(--purple);border-bottom-color:var(--purple)}.tab-icon[data-v-08e3ddb5]{font-size:10px;opacity:.6}.tab-content[data-v-08e3ddb5]{flex:1;overflow:hidden;display:flex;flex-direction:column}*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--font);background:var(--bg);color:var(--text);font-size:13px;line-height:1.5}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}button{font-family:var(--font);font-size:12px;cursor:pointer;border:.5px solid var(--border);background:transparent;color:var(--text2);padding:4px 10px;border-radius:var(--radius);transition:background .12s}button:hover{background:var(--bg2)}button:active{transform:scale(.98)}button.active{background:#7f77dd26;color:var(--purple);border-color:var(--purple)}button.danger-active{background:#e24b4a1f;color:var(--red);border-color:var(--red)}button.success-active{background:#1d9e751f;color:var(--teal);border-color:var(--teal)}input[type=text],input[type=search]{font-family:var(--font);font-size:12px;border:.5px solid var(--border);background:var(--bg2);color:var(--text);padding:5px 10px;border-radius:var(--radius);outline:none;width:100%}input[type=text]:focus,input[type=search]:focus{border-color:var(--purple);box-shadow:0 0 0 2px #7f77dd33}input[type=range]{accent-color:var(--purple);cursor:pointer}.mono{font-family:var(--mono)}.muted{color:var(--text3)}.text-sm{font-size:11px}.text-xs{font-size:10px}.bold{font-weight:500}.badge{display:inline-block;font-size:10px;font-weight:500;padding:2px 7px;border-radius:99px;white-space:nowrap}.badge-ok{background:#1d9e7526;color:var(--teal)}.badge-err{background:#e24b4a1f;color:var(--red)}.badge-warn{background:#ef9f2726;color:var(--amber)}.badge-info{background:#378add1f;color:var(--blue)}.badge-gray{background:var(--bg2);color:var(--text3);border:.5px solid var(--border)}.badge-purple{background:#7f77dd26;color:var(--purple)}.card{background:var(--bg3);border:.5px solid var(--border);border-radius:var(--radius-lg);padding:12px 14px}.data-table{width:100%;border-collapse:collapse;font-size:12px}.data-table th{text-align:left;font-size:10px;font-weight:500;color:var(--text3);padding:6px 8px;border-bottom:.5px solid var(--border);text-transform:uppercase;letter-spacing:.4px;white-space:nowrap}.data-table td{padding:8px;border-bottom:.5px solid var(--border);color:var(--text);vertical-align:middle}.data-table tr:hover td{background:var(--bg2);cursor:pointer}.data-table tr.selected td{background:#7f77dd14}.stat-card{background:var(--bg2);border-radius:var(--radius);padding:10px 12px}.stat-label{font-size:10px;color:var(--text3);text-transform:uppercase;letter-spacing:.4px;margin-bottom:3px}.stat-val{font-size:20px;font-weight:500}.flex{display:flex}.items-center{align-items:center}.gap-2{gap:8px}.gap-3{gap:12px}.flex-1{flex:1}.overflow-auto{overflow:auto}.p-3{padding:12px}.p-4{padding:16px}.mb-2{margin-bottom:8px}.mb-3{margin-bottom:12px}.mt-2{margin-top:8px}
|
package/client/dist/index.html
CHANGED
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
body { font-family: var(--font); background: var(--bg); color: var(--text); font-size: 13px; }
|
|
39
39
|
#app { height: 100vh; display: flex; flex-direction: column; }
|
|
40
40
|
</style>
|
|
41
|
-
<script type="module" crossorigin src="/assets/index
|
|
42
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
41
|
+
<script type="module" crossorigin src="/assets/index-BFrWlkvI.js"></script>
|
|
42
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BUQNNbrq.css">
|
|
43
43
|
</head>
|
|
44
44
|
<body>
|
|
45
45
|
<div id="app"></div>
|
|
@@ -29,6 +29,8 @@ export interface ProvideEntry {
|
|
|
29
29
|
isReactive: boolean
|
|
30
30
|
valueSnapshot: unknown
|
|
31
31
|
line: number
|
|
32
|
+
scope: 'global' | 'layout' | 'component'
|
|
33
|
+
isShadowing: boolean
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
export interface InjectEntry {
|
|
@@ -49,6 +51,12 @@ export interface ProvideInjectSnapshot {
|
|
|
49
51
|
injects: InjectEntry[]
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
export interface RefChangeEvent {
|
|
55
|
+
t: number
|
|
56
|
+
key: string
|
|
57
|
+
value: unknown
|
|
58
|
+
}
|
|
59
|
+
|
|
52
60
|
export interface ComposableEntry {
|
|
53
61
|
id: string
|
|
54
62
|
name: string
|
|
@@ -58,6 +66,8 @@ export interface ComposableEntry {
|
|
|
58
66
|
leak: boolean
|
|
59
67
|
leakReason?: string
|
|
60
68
|
refs: Record<string, { type: 'ref' | 'computed' | 'reactive'; value: unknown }>
|
|
69
|
+
history: RefChangeEvent[]
|
|
70
|
+
sharedKeys: string[]
|
|
61
71
|
watcherCount: number
|
|
62
72
|
intervalCount: number
|
|
63
73
|
lifecycle: {
|
|
@@ -68,6 +78,7 @@ export interface ComposableEntry {
|
|
|
68
78
|
}
|
|
69
79
|
file: string
|
|
70
80
|
line: number
|
|
81
|
+
route?: string
|
|
71
82
|
}
|
|
72
83
|
|
|
73
84
|
export interface RenderEntry {
|
|
@@ -75,14 +86,15 @@ export interface RenderEntry {
|
|
|
75
86
|
name: string
|
|
76
87
|
file: string
|
|
77
88
|
element?: string
|
|
78
|
-
|
|
79
|
-
|
|
89
|
+
mountCount: number
|
|
90
|
+
rerenders: number
|
|
80
91
|
totalMs: number
|
|
81
92
|
avgMs: number
|
|
82
93
|
triggers: Array<{ key: string; type: string; timestamp: number }>
|
|
83
94
|
rect?: { x: number; y: number; width: number; height: number; top: number; left: number }
|
|
84
|
-
children: number[]
|
|
85
95
|
parentUid?: number
|
|
96
|
+
isPersistent: boolean
|
|
97
|
+
isHydrationMount: boolean
|
|
86
98
|
}
|
|
87
99
|
|
|
88
100
|
export interface TransitionEntry {
|
|
@@ -115,7 +127,10 @@ const transitions = ref<TransitionEntry[]>([])
|
|
|
115
127
|
const connected = ref(false)
|
|
116
128
|
|
|
117
129
|
let started = false
|
|
130
|
+
// parentOrigin is only used for the outgoing postMessage target. We always
|
|
131
|
+
// validate incoming messages strictly — see onMessage below.
|
|
118
132
|
let parentOrigin = '*'
|
|
133
|
+
let pollIntervalId: number | null = null
|
|
119
134
|
|
|
120
135
|
function cloneArray<T>(value: T[] | undefined): T[] {
|
|
121
136
|
return value ? value.map((item) => ({ ...item })) : []
|
|
@@ -125,24 +140,28 @@ function normalizeRenderEntries(value: RenderEntry[] | undefined): RenderEntry[]
|
|
|
125
140
|
return value
|
|
126
141
|
? value.map((item) => ({
|
|
127
142
|
...item,
|
|
128
|
-
navigationRenders: Number.isFinite(item.navigationRenders) ? item.navigationRenders : 0,
|
|
129
143
|
}))
|
|
130
144
|
: []
|
|
131
145
|
}
|
|
132
146
|
|
|
133
|
-
function getParentOrigin() {
|
|
134
|
-
if (typeof document === 'undefined'
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
147
|
+
function getParentOrigin(): string {
|
|
148
|
+
if (typeof document === 'undefined') return ''
|
|
149
|
+
// Prefer the opener/embedder origin from document.referrer.
|
|
150
|
+
if (document.referrer) {
|
|
151
|
+
try {
|
|
152
|
+
return new URL(document.referrer).origin
|
|
153
|
+
} catch {
|
|
154
|
+
/* fall through */
|
|
155
|
+
}
|
|
142
156
|
}
|
|
157
|
+
// When opened as a top-level window (e.g. direct navigation) there is no
|
|
158
|
+
// referrer and no parent to receive messages from — return empty string so
|
|
159
|
+
// we never send to or accept from '*'.
|
|
160
|
+
return ''
|
|
143
161
|
}
|
|
144
162
|
|
|
145
163
|
function requestSnapshot() {
|
|
164
|
+
if (!parentOrigin) return
|
|
146
165
|
window.top?.postMessage({ type: 'observatory:request' }, parentOrigin)
|
|
147
166
|
}
|
|
148
167
|
|
|
@@ -151,7 +170,9 @@ function onMessage(event: MessageEvent) {
|
|
|
151
170
|
return
|
|
152
171
|
}
|
|
153
172
|
|
|
154
|
-
|
|
173
|
+
// Always validate the origin of incoming snapshot messages.
|
|
174
|
+
// Accepting '*' would allow any page to inject arbitrary devtools data.
|
|
175
|
+
if (!parentOrigin || event.origin !== parentOrigin) {
|
|
155
176
|
return
|
|
156
177
|
}
|
|
157
178
|
|
|
@@ -177,10 +198,32 @@ function ensureStarted() {
|
|
|
177
198
|
started = true
|
|
178
199
|
parentOrigin = getParentOrigin()
|
|
179
200
|
window.addEventListener('message', onMessage)
|
|
180
|
-
window.setInterval(requestSnapshot, POLL_MS)
|
|
201
|
+
pollIntervalId = window.setInterval(requestSnapshot, POLL_MS)
|
|
181
202
|
requestSnapshot()
|
|
182
203
|
}
|
|
183
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Stops polling and removes the message listener.
|
|
207
|
+
* Call this when tearing down the SPA (e.g. in an onUnmounted hook at the
|
|
208
|
+
* root component level) to prevent the interval from running indefinitely.
|
|
209
|
+
*/
|
|
210
|
+
export function stopObservatoryPolling() {
|
|
211
|
+
if (pollIntervalId !== null) {
|
|
212
|
+
window.clearInterval(pollIntervalId)
|
|
213
|
+
pollIntervalId = null
|
|
214
|
+
}
|
|
215
|
+
window.removeEventListener('message', onMessage)
|
|
216
|
+
started = false
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export function getObservatoryOrigin() {
|
|
220
|
+
return parentOrigin
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export function clearComposables() {
|
|
224
|
+
composables.value = []
|
|
225
|
+
}
|
|
226
|
+
|
|
184
227
|
export function useObservatoryData() {
|
|
185
228
|
ensureStarted()
|
|
186
229
|
|
|
@@ -192,5 +235,6 @@ export function useObservatoryData() {
|
|
|
192
235
|
transitions,
|
|
193
236
|
connected,
|
|
194
237
|
refresh: requestSnapshot,
|
|
238
|
+
clearComposables,
|
|
195
239
|
}
|
|
196
240
|
}
|