@webda/debug 4.0.0-beta.4 → 4.0.0-beta.6

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.
@@ -0,0 +1 @@
1
+ :root{--ifm-color-primary: #3578e5;--ifm-color-primary-dark: #1d68e1;--ifm-color-secondary: #ebedf0;--ifm-color-success: #00a400;--ifm-color-info: #54c7ec;--ifm-color-warning: #ffba00;--ifm-color-danger: #fa383e;--ifm-color-gray-0: #fff;--ifm-color-gray-100: #f5f6f7;--ifm-color-gray-200: #ebedf0;--ifm-color-gray-300: #dadde1;--ifm-color-gray-400: #ccd0d5;--ifm-color-gray-500: #bec3c9;--ifm-color-gray-600: #8d949e;--ifm-color-gray-700: #606770;--ifm-color-gray-800: #444950;--ifm-color-gray-900: #1c1e21;--ifm-color-gray-1000: #000;--ifm-color-emphasis-0: var(--ifm-color-gray-0);--ifm-color-emphasis-100: var(--ifm-color-gray-100);--ifm-color-emphasis-200: var(--ifm-color-gray-200);--ifm-color-emphasis-300: var(--ifm-color-gray-300);--ifm-color-emphasis-400: var(--ifm-color-gray-400);--ifm-color-emphasis-500: var(--ifm-color-gray-500);--ifm-color-emphasis-600: var(--ifm-color-gray-600);--ifm-color-emphasis-700: var(--ifm-color-gray-700);--ifm-color-emphasis-800: var(--ifm-color-gray-800);--ifm-color-emphasis-900: var(--ifm-color-gray-900);--ifm-color-emphasis-1000: var(--ifm-color-gray-1000);--ifm-color-content: var(--ifm-color-emphasis-900);--ifm-color-content-inverse: var(--ifm-color-emphasis-0);--ifm-color-content-secondary: #525860;--ifm-background-color: #fff;--ifm-background-surface-color: var(--ifm-color-content-inverse);--ifm-hover-overlay: rgba(0, 0, 0, .05);--ifm-font-color-base: var(--ifm-color-content);--ifm-font-color-secondary: var(--ifm-color-content-secondary);--ifm-font-family-base: system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, BlinkMacSystemFont, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--ifm-font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--ifm-font-size-base: 100%;--ifm-line-height-base: 1.65;--ifm-code-font-size: 90%;--ifm-global-radius: .4rem;--ifm-global-spacing: 1rem;--ifm-link-color: var(--ifm-color-primary);--ifm-navbar-height: 0px}html[data-theme=dark]{--ifm-color-emphasis-0: var(--ifm-color-gray-1000);--ifm-color-emphasis-100: var(--ifm-color-gray-900);--ifm-color-emphasis-200: var(--ifm-color-gray-800);--ifm-color-emphasis-300: var(--ifm-color-gray-700);--ifm-color-emphasis-400: var(--ifm-color-gray-600);--ifm-color-emphasis-500: var(--ifm-color-gray-500);--ifm-color-emphasis-600: var(--ifm-color-gray-400);--ifm-color-emphasis-700: var(--ifm-color-gray-300);--ifm-color-emphasis-800: var(--ifm-color-gray-200);--ifm-color-emphasis-900: var(--ifm-color-gray-100);--ifm-color-emphasis-1000: var(--ifm-color-gray-0);--ifm-background-color: #1b1b1d;--ifm-background-surface-color: #242526;--ifm-hover-overlay: rgba(255, 255, 255, .05);--ifm-color-content: #e3e3e3;--ifm-color-content-secondary: rgba(255, 255, 255, 1)}html,body{margin:0;padding:0;height:100%;background:var(--ifm-background-color);color:var(--ifm-font-color-base);font:var(--ifm-font-size-base) / var(--ifm-line-height-base) var(--ifm-font-family-base);color-scheme:light}html[data-theme=dark]{color-scheme:dark}#app{min-height:100%;display:flex;flex-direction:column}#app>.webda-debug-ui{flex:1}.webda-debug-ui{--wdbg-orange: #ff9901;--wdbg-green: #7ebf6a;--wdbg-blue: #3f51b5;--wdbg-purple: #a855f7;--wdbg-neutral: var(--ifm-color-emphasis-700);--wdbg-red: var(--ifm-color-danger);--wdbg-yellow: var(--ifm-color-warning);--wdbg-border: var(--ifm-color-emphasis-300);--wdbg-surface: var(--ifm-background-surface-color);--wdbg-surface-2: var(--ifm-color-emphasis-100);--wdbg-muted: var(--ifm-color-emphasis-600);--wdbg-radius: var(--ifm-global-radius);--wdbg-mono: var(--ifm-font-family-monospace);--wdbg-graph-inheritance: var(--ifm-color-emphasis-500);--wdbg-graph-link: var(--wdbg-blue);--wdbg-graph-query: var(--wdbg-green);--wdbg-graph-parent: var(--wdbg-purple);--wdbg-graph-binary: var(--wdbg-orange);--wdbg-graph-map: var(--ifm-color-info);--focus-color: var(--wdbg-orange);display:flex;flex-direction:column;min-height:100%;font-family:var(--ifm-font-family-base);font-size:.9375rem;line-height:1.5;color:var(--ifm-font-color-base);background:var(--ifm-background-color);box-sizing:border-box}.webda-debug-ui *,.webda-debug-ui *:before,.webda-debug-ui *:after{box-sizing:border-box}[data-theme=dark] .webda-debug-ui{--wdbg-blue: #8c9eff;--wdbg-neutral: var(--ifm-color-emphasis-800)}.wdbg-header{display:flex;align-items:center;gap:.75rem;height:48px;padding:0 var(--ifm-global-spacing);background:var(--wdbg-surface);border-bottom:2px solid var(--wdbg-border);flex-shrink:0;transition:border-color .3s,filter .3s;animation:wdbg-focus-rotate 9s ease-in-out infinite}.wdbg-disconnected .wdbg-header{border-bottom-color:var(--wdbg-red)}.wdbg-disconnected .wdbg-brand,.wdbg-disconnected .wdbg-tabs{filter:grayscale(1);opacity:.5}.wdbg-disconnected .wdbg-tab-active{color:var(--wdbg-muted)!important;border-bottom-color:var(--wdbg-muted)!important}.wdbg-brand{display:flex;align-items:center;gap:.5rem;white-space:nowrap}.wdbg-logo{width:28px;height:28px;color:var(--wdbg-blue)}.wdbg-brand-title{font-size:1rem;font-weight:600}.wdbg-brand-title span{color:var(--focus-color)}@property --focus-color{syntax: "<color>"; inherits: true; initial-value: #ff9901;}@keyframes wdbg-focus-rotate{0%,to{--focus-color: #ff9901}25%{--focus-color: #7ebf6a}50%{--focus-color: #3f51b5}75%{--focus-color: #a855f7}}@media(prefers-reduced-motion:reduce){.wdbg-header{animation:none}}.wdbg-app-info{padding-left:.75rem;border-left:1px solid var(--wdbg-border);line-height:1.2;min-width:0;flex:0 1 auto}.wdbg-app-name{font-size:.8rem}.wdbg-app-cwd{font-size:.65rem;color:var(--wdbg-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:260px}.wdbg-tabs{display:flex;height:100%;overflow-x:auto;flex:1 0 auto;min-width:0;margin-left:.75rem}.wdbg-tab{padding:0 1rem;height:100%;display:flex;align-items:center;cursor:pointer;color:var(--wdbg-muted);background:none;border:none;border-bottom:2px solid transparent;margin-bottom:-2px;font:inherit;font-size:.875rem;white-space:nowrap;transition:color .15s,border-color .15s}.wdbg-tab:hover{color:var(--ifm-font-color-base)}.wdbg-header-status{margin-left:auto;font-size:.75rem;white-space:nowrap;flex:0 1 auto;min-width:0}.wdbg-header-status .wdbg-conn-label{overflow:hidden;text-overflow:ellipsis}.wdbg-conn{display:inline-flex;align-items:center;gap:.4rem}.wdbg-conn-dot{width:8px;height:8px;border-radius:50%;background:var(--ifm-color-emphasis-400);flex-shrink:0}.wdbg-conn-ok .wdbg-conn-dot{background:var(--ifm-color-success)}.wdbg-conn-warn .wdbg-conn-dot{background:var(--ifm-color-warning);animation:wdbg-pulse 1.5s infinite}.wdbg-conn-off .wdbg-conn-dot{background:var(--ifm-color-danger);animation:wdbg-pulse 1.5s infinite}@keyframes wdbg-pulse{0%,to{opacity:1}50%{opacity:.3}}.wdbg-content{flex:1;padding:var(--ifm-global-spacing);overflow:auto;min-height:0}.wdbg-footer{display:flex;gap:1rem;align-items:center;padding:.4rem var(--ifm-global-spacing);border-top:1px solid var(--wdbg-border);font-size:.75rem;color:var(--wdbg-muted);flex-shrink:0}.wdbg-footer a{color:var(--ifm-link-color)}.wdbg-mono,.webda-debug-ui code,.webda-debug-ui pre{font-family:var(--wdbg-mono)}.webda-debug-ui code{font-size:.85em;background:var(--wdbg-surface-2);padding:.05rem .3rem;border-radius:3px;border:none}.wdbg-muted{color:var(--wdbg-muted)}.wdbg-strong{font-weight:600}.wdbg-accent{color:var(--ifm-color-primary)}.wdbg-small{font-size:.75rem}.wdbg-italic{font-style:italic}.wdbg-break{word-break:break-all}.wdbg-nowrap{white-space:nowrap}.wdbg-pre-wrap{white-space:pre-wrap}.wdbg-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wdbg-right{text-align:right}.wdbg-pad{padding:.5rem}.wdbg-grow{flex:1}.wdbg-link{color:var(--ifm-link-color);text-decoration:none}.wdbg-link:hover{text-decoration:underline}.wdbg-title{font-size:1.25rem;font-weight:600;color:var(--ifm-color-primary);margin:0 0 .5rem}.wdbg-subtitle{font-size:.8125rem;margin-bottom:1rem}.wdbg-count{font-size:.8125rem;margin-bottom:.75rem}.wdbg-empty{color:var(--wdbg-muted);padding:2rem;text-align:center}.wdbg-facts{display:flex;gap:.5rem;margin-bottom:1rem;flex-wrap:wrap;align-items:center}.wdbg-fact{background:var(--wdbg-surface-2);padding:.375rem .625rem;border-radius:var(--wdbg-radius);font-size:.8125rem}.wdbg-badges{display:flex;gap:.375rem;flex-wrap:wrap;margin-bottom:1rem}.wdbg-row-between{display:flex;justify-content:space-between;align-items:center;margin-bottom:.5rem;gap:.5rem}.wdbg-actions{margin-top:1rem;display:flex;gap:.5rem}.wdbg-preview{margin-top:.75rem}.wdbg-preview-label{color:var(--wdbg-muted);font-size:.75rem;text-transform:uppercase;letter-spacing:.05em}.wdbg-inheritance{display:flex;align-items:center;gap:.375rem;flex-wrap:wrap;font-size:.8125rem}.wdbg-pre{background:var(--wdbg-surface-2);padding:.75rem 1rem;border-radius:var(--wdbg-radius);overflow:auto;font-size:.8125rem;line-height:1.5;margin:.25rem 0 0}.wdbg-pre-inline{margin:0;white-space:pre-wrap;font-size:.8125rem;background:none;padding:0}.wdbg-code{margin:0;background:var(--wdbg-surface-2);padding:1rem;border-radius:var(--wdbg-radius);overflow:auto;max-height:500px;font-size:.8125rem;line-height:1.6;-moz-tab-size:2;tab-size:2}.wdbg-hl-keyword{color:#d73a49}.wdbg-hl-string{color:#032f62}.wdbg-hl-number{color:#005cc5}.wdbg-hl-comment{color:var(--wdbg-muted);font-style:italic}[data-theme=dark] .wdbg-hl-keyword{color:#ff7b72}[data-theme=dark] .wdbg-hl-string{color:#a5d6ff}[data-theme=dark] .wdbg-hl-number{color:#79c0ff}.wdbg-table-container{overflow-x:auto}.wdbg-table{width:100%;border-collapse:collapse;font-size:.875rem;display:table;margin:0}.wdbg-table th{text-align:left;padding:.5rem .75rem;border:none;border-bottom:1px solid var(--wdbg-border);color:var(--wdbg-muted);font-weight:500;white-space:nowrap;background:none}.wdbg-table td{padding:.5rem .75rem;border:none;border-bottom:1px solid var(--wdbg-border);vertical-align:top}.wdbg-table tr{background:none;border:none}.wdbg-table tr:hover td{background:var(--ifm-hover-overlay)}.wdbg-row-clickable{cursor:pointer}.wdbg-row-selected td{background:var(--wdbg-surface-2)}.wdbg-url-cell{max-width:400px}.wdbg-headers{width:100%;font-size:.75rem;border-collapse:collapse;display:table}.wdbg-headers td{padding:2px 8px 2px 0;vertical-align:top;border:none;background:none}.wdbg-headers td:first-child{white-space:nowrap}.wdbg-badge{display:inline-block;padding:.125rem .5rem;border-radius:3px;font-size:.75rem;font-weight:500;font-family:var(--wdbg-mono);line-height:1.4;background:var(--wdbg-surface-2);color:var(--wdbg-muted)}.wdbg-badge-small{font-size:.5625rem;padding:.0625rem .25rem}.wdbg-badge-green,.wdbg-method-get{background:#7ebf6a2e;color:#3d7a2c}.wdbg-badge-yellow,.wdbg-method-put{background:#ffba0033;color:#8a5a00}.wdbg-badge-red,.wdbg-method-delete{background:#fa383e26;color:#c21f25}.wdbg-badge-blue,.wdbg-method-post{background:#3f51b526;color:#3f51b5}.wdbg-badge-purple{background:#a855f726;color:#7e22ce}.wdbg-badge-orange,.wdbg-method-patch{background:#ff99012e;color:#b35f00}.wdbg-badge-muted{background:var(--wdbg-surface-2);color:var(--wdbg-muted)}[data-theme=dark] .wdbg-badge-green,[data-theme=dark] .wdbg-method-get{color:#7ebf6a}[data-theme=dark] .wdbg-badge-yellow,[data-theme=dark] .wdbg-method-put{color:#ffba00}[data-theme=dark] .wdbg-badge-red,[data-theme=dark] .wdbg-method-delete{color:#ff6b6f}[data-theme=dark] .wdbg-badge-blue,[data-theme=dark] .wdbg-method-post{color:#8c9eff}[data-theme=dark] .wdbg-badge-purple{color:#c084fc}[data-theme=dark] .wdbg-badge-orange,[data-theme=dark] .wdbg-method-patch{color:#ff9901}.wdbg-level{color:#fff}.wdbg-level-error{background:#ef4444}.wdbg-level-warn{background:#d99a00}.wdbg-level-info{background:#22a35b}.wdbg-level-debug{background:#6b7280}.wdbg-level-trace{background:#4b5563}.wdbg-status-2xx{color:var(--ifm-color-success)}.wdbg-status-3xx{color:var(--ifm-color-warning)}.wdbg-status-4xx{color:var(--wdbg-orange)}.wdbg-status-5xx{color:var(--ifm-color-danger)}.wdbg-status-pending{color:var(--wdbg-muted)}.wdbg-split{display:flex;gap:var(--ifm-global-spacing);min-height:0;height:calc(100vh - var(--ifm-navbar-height, 0px) - 48px - 3rem - 2rem)}.wdbg-split-left{width:280px;flex-shrink:0;overflow-y:auto;border-right:1px solid var(--wdbg-border);padding-right:1rem}.wdbg-split-right{flex:1;overflow-y:auto;min-width:0}.wdbg-list-item{display:flex;justify-content:space-between;align-items:center;gap:.5rem;padding:.5rem .75rem;cursor:pointer;border-radius:var(--wdbg-radius);font-size:.875rem;color:var(--wdbg-muted);transition:background .1s,color .1s;word-break:break-all}.wdbg-list-item:hover{background:var(--ifm-hover-overlay);color:var(--ifm-font-color-base)}.wdbg-list-item:focus-visible{outline:2px solid var(--ifm-color-primary);outline-offset:-2px}.wdbg-list-item-active{background:var(--wdbg-surface-2);color:var(--ifm-color-primary)}.wdbg-list-item-pinned{border-bottom:1px solid var(--wdbg-border);border-radius:0;margin-bottom:.5rem;padding-bottom:.625rem;color:var(--ifm-font-color-base)}.wdbg-op-item{min-width:0;flex:1}.wdbg-op-io{font-size:.6875rem;color:var(--wdbg-muted)}.wdbg-op-rest{font-size:.625rem;margin-top:.125rem;display:flex;align-items:center;gap:.25rem;min-width:0}.wdbg-search,.wdbg-select{width:100%;padding:.5rem .75rem;background:var(--ifm-background-color);border:1px solid var(--wdbg-border);border-radius:var(--wdbg-radius);color:var(--ifm-font-color-base);font:inherit;font-size:.875rem;margin-bottom:.75rem;outline:none}.wdbg-search:focus,.wdbg-select:focus{border-color:var(--ifm-color-primary)}.wdbg-select{width:auto}.wdbg-toolbar{display:flex;gap:.5rem;align-items:center;margin-bottom:.25rem}.wdbg-toolbar .wdbg-search,.wdbg-toolbar .wdbg-select{margin-bottom:0}.wdbg-checkbox{display:flex;align-items:center;gap:.25rem;color:var(--wdbg-muted);font-size:.75rem;white-space:nowrap}.wdbg-logs{overflow-y:auto;max-height:calc(100vh - var(--ifm-navbar-height, 0px) - 220px)}.wdbg-btn{font:inherit;font-size:.8125rem;padding:.375rem .875rem;border-radius:var(--wdbg-radius);border:1px solid var(--wdbg-border);background:var(--wdbg-surface);color:var(--ifm-font-color-base);cursor:pointer;transition:background .1s,color .1s}.wdbg-btn:hover:not(:disabled){background:var(--ifm-hover-overlay)}.wdbg-btn:disabled{opacity:.5;cursor:not-allowed}.wdbg-btn-primary{background:var(--ifm-color-primary);border-color:var(--ifm-color-primary);color:#fff}.wdbg-btn-primary:hover:not(:disabled){background:var(--ifm-color-primary-dark, var(--ifm-color-primary))}.wdbg-btn-ghost{background:transparent}.wdbg-btn-active{border-color:var(--ifm-color-primary);color:var(--ifm-color-primary)}.wdbg-theme-toggle{padding:.25rem .5rem;font-size:1rem;line-height:1}.wdbg-subtabs{display:flex;margin-bottom:.75rem;border-bottom:1px solid var(--wdbg-border);overflow-x:auto}.wdbg-subtab{padding:6px 16px;background:transparent;color:var(--wdbg-muted);border:none;border-bottom:2px solid transparent;margin-bottom:-1px;cursor:pointer;font:inherit;font-size:.875rem;white-space:nowrap}.wdbg-subtab-active{background:var(--wdbg-surface-2);color:var(--ifm-color-primary);border-bottom-color:var(--ifm-color-primary);font-weight:600}.wdbg-card{padding:1rem;border:1px solid var(--wdbg-border);border-radius:var(--wdbg-radius);margin-top:1rem;background:var(--wdbg-surface)}.wdbg-card-error{border-color:var(--ifm-color-danger)}.wdbg-alert{padding:.5rem .75rem;border-radius:var(--wdbg-radius);margin-bottom:1rem;font-size:.875rem}.wdbg-alert-danger{background:#fa383e1a;border:1px solid rgba(250,56,62,.3)}.wdbg-alert-warning{background:#ffba001f;border-bottom:1px solid rgba(255,186,0,.4);margin:0;border-radius:0}.wdbg-request-url{margin-left:.5rem}.wdbg-request-meta{display:flex;gap:1.5rem;font-size:.75rem;color:var(--wdbg-muted);margin-bottom:1rem}.wdbg-request-grid{display:grid;grid-template-columns:1fr 1fr;gap:1rem}.wdbg-request-grid h4{margin:1rem 0 .5rem;font-size:.8125rem}.wdbg-request-grid h4:first-child{margin-top:0}.wdbg-connection-error{max-width:640px;margin:2rem auto;padding:1.5rem;border:1px solid var(--wdbg-border);border-radius:var(--wdbg-radius);background:var(--wdbg-surface)}.wdbg-connection-error h2{margin:0 0 .75rem;font-size:1.125rem}.wdbg-connection-error p{margin:0 0 .5rem}.wdbg-port-picker{display:flex;gap:.5rem;align-items:center;margin-top:1rem;padding-top:1rem;border-top:1px solid var(--wdbg-border)}.wdbg-port-picker label{font-size:.8125rem;color:var(--wdbg-muted)}.wdbg-port-picker .wdbg-search{width:120px;margin-bottom:0}.wdbg-detail-section{margin-bottom:1.5rem}.wdbg-detail-section h3{font-size:.8125rem;color:var(--wdbg-muted);margin:0 0 .5rem;text-transform:uppercase;letter-spacing:.05em}.wdbg-json-tree{font-family:var(--wdbg-mono);font-size:.8125rem;line-height:1.6}.wdbg-json-key{color:var(--ifm-color-primary)}.wdbg-json-string{color:#22863a}.wdbg-json-number{color:#b35f00}.wdbg-json-boolean{color:#7e22ce}.wdbg-json-null{color:var(--wdbg-muted)}[data-theme=dark] .wdbg-json-string{color:#7ebf6a}[data-theme=dark] .wdbg-json-number{color:#ff9901}[data-theme=dark] .wdbg-json-boolean{color:#c084fc}.wdbg-json-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--wdbg-muted);font-size:.6rem}.wdbg-json-indent{padding-left:1.25rem}.wdbg-graph{display:flex;flex-direction:column;height:100%}.wdbg-graph-legend{display:flex;gap:1rem;margin-bottom:.5rem;flex-wrap:wrap;align-items:center;flex-shrink:0}.wdbg-graph-legend-item{display:flex;align-items:center;gap:.3rem;font-size:.7rem;color:var(--wdbg-muted)}.wdbg-graph-legend-dot{width:8px;height:8px;border-radius:50%;display:inline-block}.wdbg-graph-legend-line{width:16px;height:0;border-top-width:2px;display:inline-block}.wdbg-graph-canvas{flex:1;overflow:auto;border:1px solid var(--wdbg-border);border-radius:var(--wdbg-radius);background:var(--ifm-background-color);min-height:200px}.wdbg-graph-node{cursor:pointer}.wdbg-graph-node rect{fill:var(--wdbg-surface-2);stroke:var(--wdbg-blue)}.wdbg-graph-node text{fill:var(--ifm-font-color-base);font-family:var(--ifm-font-family-base)}.wdbg-graph-node:hover rect{stroke:var(--ifm-color-primary)}.wdbg-graph-node-selected rect{stroke:var(--wdbg-orange)}.wdbg-graph-node-selected text{fill:var(--wdbg-orange)}.wdbg-graph-label{font-family:var(--wdbg-mono)}.wdbg-sf-root{font-size:.875rem}.wdbg-sf-title{font-size:1rem;font-weight:600;color:var(--ifm-color-primary);margin-bottom:.25rem}.wdbg-sf-schema-desc{color:var(--wdbg-muted);font-size:.8125rem;margin-bottom:1rem;line-height:1.4}.wdbg-sf-empty{color:var(--wdbg-muted);padding:1rem 0}.wdbg-sf-fields{display:flex;flex-direction:column;gap:.75rem}.wdbg-sf-field{padding:.5rem .625rem;border-radius:var(--wdbg-radius);border:1px solid transparent;transition:border-color .15s}.wdbg-sf-field:hover{border-color:var(--wdbg-border)}.wdbg-sf-has-value{border-left:2px solid var(--ifm-color-primary)}.wdbg-sf-label-row{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:.125rem}.wdbg-sf-label{font-weight:500;font-size:.8125rem}.wdbg-sf-required{color:var(--ifm-color-danger);margin-left:.125rem}.wdbg-sf-type{font-family:var(--wdbg-mono);font-size:.6875rem;color:var(--wdbg-muted);background:var(--wdbg-surface-2);padding:.0625rem .375rem;border-radius:3px}.wdbg-sf-description{color:var(--wdbg-muted);font-size:.75rem;margin-bottom:.375rem;line-height:1.4}.wdbg-sf-default{font-size:.6875rem;color:var(--wdbg-muted);margin-top:.25rem}.wdbg-sf-input{width:100%;padding:.375rem .5rem;background:var(--ifm-background-color);border:1px solid var(--wdbg-border);border-radius:var(--wdbg-radius);color:var(--ifm-font-color-base);font:inherit;font-size:.8125rem;outline:none;transition:border-color .15s}.wdbg-sf-input:focus{border-color:var(--ifm-color-primary)}.wdbg-sf-input:read-only,.wdbg-sf-input:disabled{opacity:.6;cursor:not-allowed}.wdbg-sf-textarea{font-family:var(--wdbg-mono);font-size:.75rem;resize:vertical;min-height:2.5rem}.wdbg-sf-collapsible{border:1px solid var(--wdbg-border);border-radius:var(--wdbg-radius);overflow:hidden}.wdbg-sf-collapsible-header{display:flex;align-items:center;gap:.375rem;padding:.375rem .5rem;background:var(--wdbg-surface-2);cursor:pointer;-webkit-user-select:none;user-select:none;font-size:.8125rem}.wdbg-sf-collapsible-header:hover{background:var(--ifm-hover-overlay)}.wdbg-sf-chevron{font-size:.5rem;color:var(--wdbg-muted);transition:transform .15s}.wdbg-sf-open{transform:rotate(90deg)}.wdbg-sf-collapsible-title{font-weight:500}.wdbg-sf-badge{font-family:var(--wdbg-mono);font-size:.625rem;color:var(--wdbg-muted);background:var(--ifm-background-color);padding:.0625rem .3rem;border-radius:3px;margin-left:auto}.wdbg-sf-collapsible-body{padding:.5rem;border-top:1px solid var(--wdbg-border)}.wdbg-sf-array{display:flex;flex-direction:column;gap:.375rem}.wdbg-sf-array-item{display:flex;gap:.375rem;align-items:flex-start}.wdbg-sf-array-item-content{flex:1;min-width:0}.wdbg-sf-btn{font:inherit;font-size:.75rem;padding:.25rem .5rem;border:1px solid var(--wdbg-border);border-radius:3px;background:var(--wdbg-surface-2);color:var(--wdbg-muted);cursor:pointer}.wdbg-sf-btn:hover{background:var(--ifm-hover-overlay);color:var(--ifm-font-color-base)}.wdbg-sf-btn-remove{color:var(--ifm-color-danger);font-size:.875rem;line-height:1;flex-shrink:0}.wdbg-sf-btn-add{align-self:flex-start;margin-top:.125rem}.webda-debug-ui ::-webkit-scrollbar{width:6px;height:6px}.webda-debug-ui ::-webkit-scrollbar-thumb{background:var(--wdbg-border);border-radius:3px}.wdbg-hosted-bar{display:flex;align-items:center;gap:1rem;padding:.35rem var(--ifm-global-spacing);background:var(--ifm-background-surface-color);border-bottom:1px solid var(--ifm-color-emphasis-300);font-size:.875rem;font-family:var(--ifm-font-family-base)}.wdbg-hosted-brand{display:inline-flex;align-items:center;gap:.4rem;font-weight:600;color:var(--ifm-font-color-base);text-decoration:none}.wdbg-hosted-brand .wdbg-logo{width:22px;height:22px;color:#3f51b5}.wdbg-hosted-link{margin-left:auto;color:var(--ifm-link-color)}.wdbg-boot{padding:3rem var(--ifm-global-spacing);text-align:center;color:var(--ifm-color-emphasis-700)}.wdbg-graph-toggle{margin-left:auto}@media(max-width:1440px){.wdbg-app-cwd{max-width:180px}}@media(max-width:1280px){.wdbg-header-status .wdbg-conn-label,.wdbg-app-cwd{display:none}.wdbg-tab{padding:0 .75rem}}@media(max-width:1024px){.wdbg-app-info,.wdbg-brand-title{display:none}}@media(max-width:768px){.wdbg-split{flex-direction:column;height:auto}.wdbg-split-left{width:100%;border-right:none;border-bottom:1px solid var(--wdbg-border);padding-right:0;padding-bottom:1rem;max-height:200px}.wdbg-request-grid{grid-template-columns:1fr}.wdbg-app-info,.wdbg-conn-label{display:none}}
package/webui/index.html CHANGED
@@ -1,22 +1,15 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Webda Debug Dashboard</title>
7
- <link rel="stylesheet" href="/styles.css" />
8
- <script type="importmap">
9
- {
10
- "imports": {
11
- "preact": "/vendor/preact.js",
12
- "preact/hooks": "/vendor/preact-hooks.js",
13
- "htm": "/vendor/htm.js"
14
- }
15
- }
16
- </script>
17
- </head>
18
- <body>
19
- <div id="app"></div>
20
- <script type="module" src="/app.js"></script>
21
- </body>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <meta name="robots" content="noindex" />
7
+ <title>Webda Debug Dashboard</title>
8
+ <link rel="icon" href="./assets/favicon-CVPPk1M-.svg" type="image/svg+xml" />
9
+ <script type="module" crossorigin src="./assets/index-BSEtev2p.js"></script>
10
+ <link rel="stylesheet" crossorigin href="./assets/index-Bw7FTaDv.css">
11
+ </head>
12
+ <body>
13
+ <div id="app"></div>
14
+ </body>
22
15
  </html>
package/webui/app.js DELETED
@@ -1,177 +0,0 @@
1
- import { h, render } from "preact";
2
- import { useState, useEffect, useRef, useCallback } from "preact/hooks";
3
- import htm from "htm";
4
-
5
- import { ModelsPanel } from "./components/models.js";
6
- import { ServicesPanel } from "./components/services.js";
7
- import { OperationsPanel } from "./components/operations.js";
8
- import { RequestsPanel } from "./components/requests.js";
9
- import { LogsPanel } from "./components/logs.js";
10
-
11
- const html = htm.bind(h);
12
-
13
- const TABS = [
14
- { id: "logs", label: "Logs", color: "#f7992c" },
15
- { id: "models", label: "Models", color: "#81bf6b" },
16
- { id: "services", label: "Services", color: "#6b8fd4" },
17
- { id: "operations", label: "Operations", color: "#f4f4f4" },
18
- { id: "requests", label: "Requests", color: "#6b8fd4" }
19
- ];
20
-
21
- /**
22
- * Fetch JSON from the debug API.
23
- * @param {string} path
24
- * @returns {Promise<any>}
25
- */
26
- async function fetchApi(path) {
27
- const res = await fetch(path);
28
- return res.json();
29
- }
30
-
31
- function App() {
32
- const [tab, setTab] = useState("logs");
33
- const [wsConnected, setWsConnected] = useState(false);
34
- const [wsEvents, setWsEvents] = useState([]);
35
- const [dataVersion, setDataVersion] = useState(0);
36
- const [cache, setCache] = useState({});
37
- const wsRef = useRef(null);
38
- const reconnectTimer = useRef(null);
39
-
40
- // Load all data upfront and on rebuild (restart event)
41
- useEffect(() => {
42
- Promise.all([
43
- fetchApi("/api/info").catch(() => null),
44
- fetchApi("/api/models").catch(() => []),
45
- fetchApi("/api/services").catch(() => []),
46
- fetchApi("/api/operations").catch(() => []),
47
- fetchApi("/api/config").catch(() => {}),
48
- fetchApi("/api/requests").catch(() => []),
49
- fetchApi("/api/logs").catch(() => [])
50
- ]).then(([info, models, services, operations, config, requests, logs]) => {
51
- setCache({ info, models, services, operations, config, requests, logs });
52
- });
53
- }, [dataVersion]);
54
-
55
- useEffect(() => {
56
- const onKeyDown = (e) => {
57
- if (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA" || e.target.tagName === "SELECT") return;
58
- if (e.key === "ArrowLeft") {
59
- e.preventDefault();
60
- setTab((prev) => {
61
- const idx = TABS.findIndex((t) => t.id === prev);
62
- return TABS[(idx - 1 + TABS.length) % TABS.length].id;
63
- });
64
- } else if (e.key === "ArrowRight") {
65
- e.preventDefault();
66
- setTab((prev) => {
67
- const idx = TABS.findIndex((t) => t.id === prev);
68
- return TABS[(idx + 1) % TABS.length].id;
69
- });
70
- }
71
- };
72
- window.addEventListener("keydown", onKeyDown);
73
- return () => window.removeEventListener("keydown", onKeyDown);
74
- }, []);
75
-
76
- const connectWs = useCallback(() => {
77
- if (wsRef.current && wsRef.current.readyState <= 1) return;
78
-
79
- const protocol = location.protocol === "https:" ? "wss:" : "ws:";
80
- const ws = new WebSocket(`${protocol}//${location.host}/ws`);
81
- wsRef.current = ws;
82
-
83
- ws.addEventListener("open", () => {
84
- setWsConnected(true);
85
- if (reconnectTimer.current) {
86
- clearTimeout(reconnectTimer.current);
87
- reconnectTimer.current = null;
88
- }
89
- });
90
-
91
- ws.addEventListener("message", (e) => {
92
- try {
93
- const data = JSON.parse(e.data);
94
- if (data.type === "restart") {
95
- // Trigger data refetch across all panels
96
- setDataVersion((v) => v + 1);
97
- return;
98
- }
99
- // Dispatch custom event so individual panels can listen
100
- window.dispatchEvent(new CustomEvent("debug-ws-event", { detail: data }));
101
- setWsEvents((prev) => [data, ...prev].slice(0, 500));
102
- } catch {
103
- // ignore parse errors
104
- }
105
- });
106
-
107
- ws.addEventListener("close", () => {
108
- setWsConnected(false);
109
- wsRef.current = null;
110
- // Auto-reconnect after 2 seconds
111
- reconnectTimer.current = setTimeout(connectWs, 2000);
112
- });
113
-
114
- ws.addEventListener("error", () => {
115
- ws.close();
116
- });
117
- }, []);
118
-
119
- useEffect(() => {
120
- connectWs();
121
- return () => {
122
- if (wsRef.current) wsRef.current.close();
123
- if (reconnectTimer.current) clearTimeout(reconnectTimer.current);
124
- };
125
- }, [connectWs]);
126
-
127
- const renderPanel = () => {
128
- switch (tab) {
129
- case "models":
130
- return html`<${ModelsPanel} data=${cache.models} fetchApi=${fetchApi} dataVersion=${dataVersion} />`;
131
- case "services":
132
- return html`<${ServicesPanel} data=${cache.services} config=${cache.config} fetchApi=${fetchApi} dataVersion=${dataVersion} />`;
133
- case "operations":
134
- return html`<${OperationsPanel} data=${cache.operations} fetchApi=${fetchApi} dataVersion=${dataVersion} />`;
135
- case "requests":
136
- return html`<${RequestsPanel} data=${cache.requests} fetchApi=${fetchApi} dataVersion=${dataVersion} wsEvents=${wsEvents} />`;
137
- case "logs":
138
- return html`<${LogsPanel} data=${cache.logs} fetchApi=${fetchApi} dataVersion=${dataVersion} />`;
139
- default:
140
- return null;
141
- }
142
- };
143
-
144
- return html`
145
- <div class="header ${wsConnected ? "" : "disconnected"}">
146
- <div class="header-logo">
147
- <img src="/logo.svg" alt="Webda" />
148
- <div class="header-title">web<span>da</span> debug</div>
149
- ${cache.info && html`<div class="header-app-info">
150
- <div class="header-app-name">${cache.info.package?.name || "unknown"}</div>
151
- <div class="header-cwd">${(cache.info.workingDirectory || "").replace(/^\/(Users|home)\/[^/]+\//, "~/")}</div>
152
- </div>`}
153
- </div>
154
- <nav class="nav-tabs">
155
- ${TABS.map(
156
- (t) => html`
157
- <button
158
- key=${t.id}
159
- class="nav-tab ${tab === t.id ? "active" : ""}"
160
- style="${tab === t.id ? `color:${t.color};border-bottom-color:${t.color}` : ""}"
161
- onClick=${() => setTab(t.id)}
162
- >
163
- ${t.label}
164
- </button>
165
- `
166
- )}
167
- </nav>
168
- <div class="ws-indicator">
169
- <span class="ws-dot ${wsConnected ? "" : "disconnected"}"></span>
170
- <span>${wsConnected ? "Connected" : "Reconnecting..."}</span>
171
- </div>
172
- </div>
173
- <div class="content">${renderPanel()}</div>
174
- `;
175
- }
176
-
177
- render(html`<${App} />`, document.getElementById("app"));
@@ -1,128 +0,0 @@
1
- import { h } from "preact";
2
- import { useState, useEffect, useRef, useMemo } from "preact/hooks";
3
- import htm from "htm";
4
-
5
- const html = htm.bind(h);
6
-
7
- const LEVEL_COLORS = {
8
- ERROR: "#ef4444",
9
- WARN: "#eab308",
10
- INFO: "#22c55e",
11
- DEBUG: "#6b7280",
12
- TRACE: "#4b5563"
13
- };
14
-
15
- const LEVEL_ORDER = ["TRACE", "DEBUG", "INFO", "WARN", "ERROR"];
16
-
17
- function formatTime(ts) {
18
- if (!ts) return "-";
19
- return new Date(ts).toISOString().substring(11, 23);
20
- }
21
-
22
- export function LogsPanel({ data }) {
23
- const [liveEntries, setLiveEntries] = useState([]);
24
- const [search, setSearch] = useState("");
25
- const [autoScroll, setAutoScroll] = useState(true);
26
- const [levelFilter, setLevelFilter] = useState(() => localStorage.getItem("webda-log-level") || "INFO");
27
- const listRef = useRef(null);
28
-
29
-
30
- // Merge cached + live, deduplicate by id
31
- const allEntries = useMemo(() => {
32
- const seen = new Set();
33
- const merged = [];
34
- for (const e of liveEntries) {
35
- if (!seen.has(e.id)) { seen.add(e.id); merged.push(e); }
36
- }
37
- for (const e of (data || [])) {
38
- if (!seen.has(e.id)) { seen.add(e.id); merged.push(e); }
39
- }
40
- return merged;
41
- }, [data, liveEntries]);
42
-
43
- const entries = search
44
- ? allEntries.filter(e => e.message?.toLowerCase().includes(search.toLowerCase()) || e.level?.toLowerCase().includes(search.toLowerCase()))
45
- : allEntries;
46
-
47
- // Listen for live log events via custom event dispatched from WebSocket handler
48
- useEffect(() => {
49
- const handler = (event) => {
50
- if (event.detail?.type === "log") {
51
- setLiveEntries((prev) => [event.detail, ...prev].slice(0, 2000));
52
- }
53
- };
54
- window.addEventListener("debug-ws-event", handler);
55
- return () => window.removeEventListener("debug-ws-event", handler);
56
- }, []);
57
-
58
- useEffect(() => {
59
- if (autoScroll && listRef.current) {
60
- listRef.current.scrollTop = listRef.current.scrollHeight;
61
- }
62
- }, [entries, autoScroll]);
63
-
64
- const minLevel = LEVEL_ORDER.indexOf(levelFilter);
65
- const filtered = minLevel <= 0 ? entries : entries.filter((e) => LEVEL_ORDER.indexOf(e.level) >= minLevel);
66
-
67
- return html`
68
- <div>
69
- <div style="display:flex;gap:8px;margin-bottom:12px;align-items:center">
70
- <input
71
- type="text"
72
- placeholder="Search logs..."
73
- value=${search}
74
- onInput=${(e) => setSearch(e.target.value)}
75
- style="flex:1;padding:6px 10px;background:var(--bg-tertiary);border:1px solid var(--border);color:var(--text-primary);border-radius:4px;font-family:monospace"
76
- />
77
- <select
78
- value=${levelFilter}
79
- onChange=${(e) => { setLevelFilter(e.target.value); localStorage.setItem("webda-log-level", e.target.value); }}
80
- style="padding:6px;background:var(--bg-tertiary);border:1px solid var(--border);color:var(--text-primary);border-radius:4px"
81
- >
82
- <option value="ERROR">ERROR</option>
83
- <option value="WARN">WARN+</option>
84
- <option value="INFO">INFO+</option>
85
- <option value="DEBUG">DEBUG+</option>
86
- <option value="TRACE">TRACE+</option>
87
- </select>
88
- <label style="display:flex;align-items:center;gap:4px;color:var(--text-muted);font-size:12px">
89
- <input type="checkbox" checked=${autoScroll} onChange=${(e) => setAutoScroll(e.target.checked)} />
90
- Auto-scroll
91
- </label>
92
- </div>
93
- <div style="margin-bottom:0.75rem;color:var(--text-muted);font-size:0.8125rem">
94
- ${filtered.length} log${filtered.length !== 1 ? "s" : ""}
95
- </div>
96
- <div ref=${listRef} class="table-container" style="overflow-y:auto;max-height:calc(100vh - 200px)">
97
- <table>
98
- <thead>
99
- <tr>
100
- <th style="width:120px">Time</th>
101
- <th style="width:70px">Level</th>
102
- <th>Message</th>
103
- </tr>
104
- </thead>
105
- <tbody>
106
- ${filtered.map(
107
- (entry) => html`
108
- <tr key=${entry.id}>
109
- <td class="mono" style="white-space:nowrap;color:var(--text-muted);font-size:12px">${formatTime(entry.timestamp)}</td>
110
- <td><span class="badge" style="background:${LEVEL_COLORS[entry.level] || "#666"}">${entry.level}</span></td>
111
- <td class="mono" style="font-size:13px;white-space:pre-wrap;word-break:break-all">${entry.message}</td>
112
- </tr>
113
- `
114
- )}
115
- ${filtered.length === 0 &&
116
- html`
117
- <tr>
118
- <td colspan="3" style="color:var(--text-muted);text-align:center;padding:2rem">
119
- No logs${search ? " matching search" : " yet"}. Logs will appear here in real-time.
120
- </td>
121
- </tr>
122
- `}
123
- </tbody>
124
- </table>
125
- </div>
126
- </div>
127
- `;
128
- }