@wcstack/devtools 1.27.0 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/auto.min.js CHANGED
@@ -1,2 +1,2 @@
1
- const e="__WCSTACK_DEVTOOLS_HOOK__";function t(){const t=globalThis,n=t[e];if(void 0!==n)return 1!==n.version&&console.warn(`[wcstack/devtools] hook registry version mismatch: found ${n.version}, expected 1. Keeping the existing registry (first-wins).`),n;const i=function(){const e=new Map,t=new Set,n=e=>{if(0===t.size)return void e._setSink(null);const n=e.id;e._setSink(e=>{for(const i of t)i.onEvent?.(n,e)})};return{version:1,sources:e,register(i){if(!e.has(i.id)){e.set(i.id,i),n(i);for(const e of t)e.onSourceRegistered?.(i)}},unregister(n){const i=e.get(n);if(void 0!==i){i._setSink(null),e.delete(n);for(const e of t)e.onSourceUnregistered?.(n)}},addListener(i){t.add(i);for(const t of e.values())n(t),i.onSourceRegistered?.(t);return()=>{if(t.delete(i))for(const t of e.values())n(t)}}}}();return t[e]=i,i}const n=80;function i(e){const t=e.constructor,n=t?.name;return"string"==typeof n&&n.length>0?n:"Object"}function s(e,t=2){switch(typeof e){case"string":return`"${e.length>n?e.slice(0,n)+"…":e}"`;case"number":case"boolean":case"bigint":return String(e);case"symbol":return e.toString();case"undefined":return"undefined";case"function":return"[[Function]]"}if(null===e)return"null";const o=e;if(Array.isArray(o)){if(t<=0)return`[[Array(${o.length})]]`;const e=o.slice(0,3).map(e=>s(e,t-1)),n=o.length>3?`, …(${o.length})`:"";return`[${e.join(", ")}${n}]`}if(function(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}(o)){if(t<=0)return"[[Object]]";const e=Object.keys(o),n=e.slice(0,3).map(e=>`${e}: ${s(o[e],t-1)}`),i=e.length>3?`, …(${e.length})`:"";return`{${n.join(", ")}${i}}`}return`[[${i(o)}]]`}function o(e){if(null!==e&&"object"==typeof e){const{name:t,message:s}=e;if("string"==typeof s){const o="string"==typeof t&&t.length>0?t:i(e),r=s.length>n?s.slice(0,n)+"…":s;return r.length>0?`${o}: ${r}`:o}}return s(e,1)}function r(e){if(0===e.length)return"";const t=e.slice(0,3).map(e=>{const t=s(e,1);return t.length>n?t.slice(0,n)+"…":t}),i=e.length>3?`, …(${e.length})`:"";return`${t.join(", ")}${i}`}function a(e,t){return e+"\0"+t}class l{_timelineCapacity;_hiddenStateNames;_removeListener=null;_sources=new Map;_roster=new Map;_wiringByPathKey=new Map;_wiringEntryByBinding=new WeakMap;_timeline=[];_seq=0;_paused=!1;_changeListeners=new Set;constructor(e){this._timelineCapacity=e?.timelineCapacity??500,this._hiddenStateNames=new Set(e?.hiddenStateNames??[])}get connected(){return null!==this._removeListener}get paused(){return this._paused}set paused(e){this._paused=e}isHiddenStateName(e){return null!==e&&(e.startsWith("wcs-devtools")||this._hiddenStateNames.has(e))}connect(){if(null!==this._removeListener)return;const e=t();this._removeListener=e.addListener({onSourceRegistered:e=>{this._sources.set(e.id,e),this._refreshRosterOf(e),this._notify("sources")},onSourceUnregistered:e=>{this._sources.delete(e),this._roster.delete(e),this._notify("sources"),this._notify("roster")},onEvent:(e,t)=>{this._ingest(e,t)}})}disconnect(){null!==this._removeListener&&(this._removeListener(),this._removeListener=null,this._sources.clear(),this._roster.clear(),this._wiringByPathKey.clear(),this._wiringEntryByBinding=new WeakMap,this._notify("sources"),this._notify("roster"),this._notify("wiring"))}onChange(e){return this._changeListeners.add(e),()=>{this._changeListeners.delete(e)}}getSources(){return[...this._sources.values()]}getRoster(){const e=[];for(const t of this._roster.values())e.push(...t);return e}refreshRoster(){for(const e of this._sources.values())this._refreshRosterOf(e);this._notify("roster")}getTimeline(){return this._timeline}clearTimeline(){this._timeline=[],this._notify("timeline")}getWiringForPath(e,t){const n=this._wiringByPathKey.get(a(e,t));return void 0===n?[]:this._collectAlive(n)}getAllWiring(){const e=[];for(const t of this._wiringByPathKey.values())e.push(...this._collectAlive(t));return e}getWiringForNode(e){const t=[];for(const n of this._wiringByPathKey.values())for(const i of this._collectAlive(n)){const n=i.bindingRef.deref();(n.node===e||n.replaceNode===e||e.contains(n.node)||e.contains(n.replaceNode))&&t.push(i)}return t}keysOf(e){const t=this._sources.get(e.sourceId);return void 0===t||"function"!=typeof t.keys?[]:t.keys(e.name,e.rootNode)}readValue(e,t,n){const i=this._sources.get(e.sourceId);if(void 0!==i)return i.read(e.name,e.rootNode,t,n)}writeValue(e,t,n,i){const s=this._sources.get(e.sourceId);void 0!==s&&s.write(e.name,e.rootNode,t,n,i)}_notify(e){for(const t of this._changeListeners)t(e)}_refreshRosterOf(e){const t=[];for(const n of e.getStateElements())this.isHiddenStateName(n.name)||t.push({sourceId:e.id,name:n.name,rootNode:n.rootNode,summary:n});this._roster.set(e.id,t)}_collectAlive(e){const t=[];for(const n of e)void 0!==n.bindingRef.deref()?t.push(n):e.delete(n);return t}_appendTimeline(e){if(this._paused)return;this._timeline.push({...e,seq:this._seq++,time:performance.now()});const t=this._timeline.length-this._timelineCapacity;t>0&&this._timeline.splice(0,t),this._notify("timeline")}_labelOf(e){const t=e.listIndex?.indexes,n=e.absolutePathInfo.pathInfo.path;return void 0!==t?`${n}[${t.join(",")}]`:n}_ingest(e,t){switch(t.type){case"state:element-registered":{if(this.isHiddenStateName(t.name))return;const n=this._sources.get(e);return void 0!==n&&(this._refreshRosterOf(n),this._notify("roster")),void this._appendTimeline({sourceId:e,kind:"element-registered",stateName:t.name,label:t.name,detail:"",subscriberCount:null})}case"state:element-unregistered":{if(this.isHiddenStateName(t.name))return;const n=this._sources.get(e);return void 0!==n&&(this._refreshRosterOf(n),this._notify("roster")),void this._appendTimeline({sourceId:e,kind:"element-unregistered",stateName:t.name,label:t.name,detail:"",subscriberCount:null})}case"state:write":{const n=t.absoluteAddress.absolutePathInfo.stateName;if(this.isHiddenStateName(n))return;const i=t.hasOldValue?`${s(t.value)} (was ${s(t.oldValue)})`:s(t.value);return void this._appendTimeline({sourceId:e,kind:"write",stateName:n,label:this._labelOf(t.absoluteAddress),detail:i,subscriberCount:null})}case"state:update-batch":{const n=[];let i=0;for(const e of t.addresses)this.isHiddenStateName(e.absolutePathInfo.stateName)||(i++,n.length<3&&n.push(this._labelOf(e)));if(0===i)return;const s=i>n.length?`, …(${i})`:"";return void this._appendTimeline({sourceId:e,kind:"batch",stateName:null,label:`${i} address${1===i?"":"es"}`,detail:`${n.join(", ")}${s}`,subscriberCount:null})}case"state:binding-added":{const n=t.absoluteAddress.absolutePathInfo.stateName;if(this.isHiddenStateName(n))return;const i=t.absoluteAddress.absolutePathInfo.pathInfo.path,s=a(n,i);let o=this._wiringByPathKey.get(s);void 0===o&&(o=new Set,this._wiringByPathKey.set(s,o));const r={sourceId:e,stateName:n,path:i,propName:t.binding.propName,bindingType:t.binding.bindingType,bindingRef:new WeakRef(t.binding)};return o.add(r),this._wiringEntryByBinding.set(t.binding,r),void this._notify("wiring")}case"state:binding-removed":{const e=this._wiringEntryByBinding.get(t.binding);if(void 0===e)return;this._wiringEntryByBinding.delete(t.binding);const n=a(e.stateName,e.path),i=this._wiringByPathKey.get(n);return void 0!==i&&(i.delete(e),0===i.size&&this._wiringByPathKey.delete(n)),void this._notify("wiring")}case"state:binding-cleared":{const e=a(t.absoluteAddress.absolutePathInfo.stateName,t.absoluteAddress.absolutePathInfo.pathInfo.path);return void(this._wiringByPathKey.delete(e)&&this._notify("wiring"))}case"state:token-emit":if(this.isHiddenStateName(t.stateName))return;return void this._appendTimeline({sourceId:e,kind:t.kind,stateName:t.stateName,label:t.tokenName,detail:r(t.args),subscriberCount:t.subscriberCount});case"state:watch-error":if(this.isHiddenStateName(t.stateName))return;return void this._appendTimeline({sourceId:e,kind:"watch-error",stateName:t.stateName,label:t.path,detail:`${t.phase}: ${o(t.error)}`,subscriberCount:null});case"state:watch-chain-limit":return void this._appendTimeline({sourceId:e,kind:"watch-chain-limit",stateName:null,label:`depth > ${t.maxDepth}`,detail:t.paths.join(", "),subscriberCount:null})}}}const d=["wcs-text","wcs-for","wcs-if","wcs-elseif","wcs-else"];function c(e,t,n){const i=t.trim();if(0===i.length)return null;const s=i.indexOf(":");if(s<0)return null;const o=i.slice(0,s).trim(),r=i.slice(s+1).trim();if(0===o.length||0===r.length)return null;const[a,...l]=r.split("|").map(e=>e.trim());let d=a,c="default";const h=a.lastIndexOf("@");return h>0&&(d=a.slice(0,h).trim(),c=a.slice(h+1).trim()),{element:e,propName:o,path:d,stateName:c,filters:l.filter(e=>e.length>0),origin:n,raw:i}}class h extends HTMLElement{static get observedAttributes(){return["open","dock","hotkey"]}_core=null;_removeCoreListener=null;_panel=null;_badge=null;_stateSelect=null;_paneElements={};_highlightLayer=null;_dirtyPanes=new Set;_renderScheduled=!1;_selectedRosterKey=null;_selectedPath=null;_pickedNode=null;_pickMode=!1;_expanded=new Set;_hotkeyHandler=null;_pickHandler=null;get core(){return this._core}connectedCallback(){if(document.documentElement.hasAttribute("data-wcs-server"))return;null===this.shadowRoot&&this._buildShadow();const e=Number(this.getAttribute("buffer")??""),t=(this.getAttribute("hidden-states")??"").split(",").map(e=>e.trim()).filter(e=>e.length>0);this._core=new l({timelineCapacity:Number.isFinite(e)&&e>0?e:void 0,hiddenStateNames:t}),this._removeCoreListener=this._core.onChange(e=>{"roster"===e||"sources"===e?(this._markDirty("state"),this._markDirty("wiring")):"wiring"===e?this._markDirty("wiring"):this._markDirty("timeline")}),this._core.connect(),this._applyDock(),this._applyOpen(),this._installHotkey(),this._markDirty("state"),this._markDirty("wiring"),this._markDirty("timeline")}disconnectedCallback(){this._removeCoreListener?.(),this._removeCoreListener=null,this._core?.disconnect(),this._core=null,this._uninstallHotkey(),this._exitPickMode()}attributeChangedCallback(e){null!==this.shadowRoot&&("open"===e?this._applyOpen():"dock"===e?this._applyDock():"hotkey"===e&&(this._uninstallHotkey(),this._installHotkey()))}__flushRenderForTest(){this._renderDirty()}_buildShadow(){const e=this.attachShadow({mode:"open"}),t=document.createElement("style");t.textContent='\n:host {\n all: initial;\n position: fixed;\n z-index: 2147483647;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n inset: auto 0 0 auto;\n}\n* { box-sizing: border-box; }\n.badge {\n position: fixed;\n right: 12px;\n bottom: 12px;\n width: 40px;\n height: 40px;\n border-radius: 20px;\n border: 1px solid #2b4f78;\n background: #10263f;\n color: #9fd0ff;\n font-weight: 700;\n cursor: pointer;\n}\n.panel {\n position: fixed;\n display: flex;\n flex-direction: column;\n background: #0d1b2a;\n color: #d7e3f4;\n border: 1px solid #2b4f78;\n box-shadow: 0 0 24px rgba(0,0,0,.5);\n}\n.panel.dock-bottom { left: 0; right: 0; bottom: 0; height: 45vh; }\n.panel.dock-right { top: 0; right: 0; bottom: 0; width: 420px; }\n.panel[hidden] { display: none; }\nheader {\n display: flex;\n gap: 6px;\n align-items: center;\n padding: 6px 8px;\n border-bottom: 1px solid #2b4f78;\n background: #10263f;\n}\nheader .title { font-weight: 700; color: #9fd0ff; margin-right: 4px; }\nheader select, header button {\n font: inherit;\n background: #16324f;\n color: #d7e3f4;\n border: 1px solid #2b4f78;\n border-radius: 4px;\n padding: 2px 8px;\n cursor: pointer;\n}\nheader button[aria-pressed="true"] { background: #2b5d8f; }\nheader .spacer { flex: 1; }\n.panes { display: flex; flex: 1; min-height: 0; }\n.pane { flex: 1; min-width: 0; overflow: auto; padding: 6px 8px; border-right: 1px solid #1d3a5c; }\n.pane:last-child { border-right: none; }\n.pane h3 {\n margin: 0 0 6px;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .08em;\n color: #7ba7d4;\n}\n.tree-row { display: flex; gap: 6px; padding: 1px 0; align-items: baseline; white-space: nowrap; }\n.tree-row .toggle { width: 14px; cursor: pointer; color: #7ba7d4; user-select: none; }\n.tree-row .key { color: #9fd0ff; cursor: pointer; }\n.tree-row .value { color: #ffd9a0; overflow: hidden; text-overflow: ellipsis; }\n.tree-row .value.editable { cursor: pointer; }\n.tree-row input { font: inherit; background: #16324f; color: #ffd9a0; border: 1px solid #2b4f78; }\n.badge-tag {\n display: inline-block;\n padding: 0 4px;\n border-radius: 3px;\n font-size: 10px;\n background: #26456a;\n color: #a8c6e8;\n}\n.badge-tag.warn { background: #6a3326; color: #ffb3a0; }\n.badge-tag.declared { background: #4a4426; color: #efe3a0; }\n.wiring-row, .timeline-row { padding: 1px 0; white-space: nowrap; }\n.wiring-row .prop { color: #b7f0c0; }\n.wiring-row .path { color: #9fd0ff; }\n.timeline-row .t { color: #6f88a3; }\n.timeline-row .label { color: #9fd0ff; }\n.timeline-row .detail { color: #ffd9a0; }\n.timeline-row .kind { display: inline-block; min-width: 52px; text-align: center; }\n.empty { color: #6f88a3; font-style: italic; padding: 4px 0; }\n.notice { color: #efe3a0; padding: 2px 0 6px; }\n.notice button { font: inherit; margin-left: 6px; cursor: pointer; }\n.hl-box {\n position: fixed;\n pointer-events: none;\n border: 1px solid #58c2ff;\n background: rgba(88,194,255,.18);\n}\n',e.append(t);const n=document.createElement("button");n.className="badge",n.title="wcstack DevTools",n.textContent="WCS",n.addEventListener("click",()=>this.toggle()),e.append(n),this._badge=n;const i=document.createElement("div");i.className="panel dock-bottom",i.hidden=!0;const s=document.createElement("header"),o=document.createElement("span");o.className="title",o.textContent="wcstack devtools",s.append(o);const r=document.createElement("select");r.title="state element",r.addEventListener("change",()=>{this._selectedRosterKey=r.value||null,this._selectedPath=null,this._expanded.clear(),this._markDirty("state"),this._markDirty("wiring")}),s.append(r),this._stateSelect=r;const a=this._headerButton(s,"⌖ pick","pick a page element");a.addEventListener("click",()=>{this._pickMode?this._exitPickMode():this._enterPickMode(),a.setAttribute("aria-pressed",String(this._pickMode))}),a.dataset.role="pick";const l=this._headerButton(s,"⏸","pause timeline");l.addEventListener("click",()=>{const e=this._core;null!==e&&(e.paused=!e.paused,l.setAttribute("aria-pressed",String(e.paused)))}),l.dataset.role="pause";const d=this._headerButton(s,"🗑","clear timeline");d.addEventListener("click",()=>{this._core?.clearTimeline()}),d.dataset.role="clear";const c=document.createElement("span");c.className="spacer",s.append(c);const h=this._headerButton(s,"dock","toggle dock position");h.addEventListener("click",()=>{const e="bottom"===(this.getAttribute("dock")??"bottom")?"right":"bottom";this.setAttribute("dock",e)}),h.dataset.role="dock";const u=this._headerButton(s,"×","close");u.addEventListener("click",()=>this.toggle(!1)),u.dataset.role="close",i.append(s);const p=document.createElement("div");p.className="panes";for(const[e,t]of[["state","State"],["wiring","Wiring"],["timeline","Timeline"]]){const n=document.createElement("section");n.className=`pane pane-${e}`;const i=document.createElement("h3");i.textContent=t;const s=document.createElement("div");s.className="pane-body",n.append(i,s),p.append(n),this._paneElements[e]=s}i.append(p),e.append(i),this._panel=i;const m=document.createElement("div");m.className="hl-layer",e.append(m),this._highlightLayer=m}_headerButton(e,t,n){const i=document.createElement("button");return i.textContent=t,i.title=n,i.setAttribute("aria-pressed","false"),e.append(i),i}get open(){return this.hasAttribute("open")}toggle(e){e??!this.open?this.setAttribute("open",""):this.removeAttribute("open")}_applyOpen(){this._panel.hidden=!this.open,this._badge.hidden=this.open,this.open&&(this._markDirty("state"),this._markDirty("wiring"),this._markDirty("timeline"))}_applyDock(){const e="right"===this.getAttribute("dock")?"right":"bottom";this._panel.classList.toggle("dock-right","right"===e),this._panel.classList.toggle("dock-bottom","bottom"===e)}_installHotkey(){const e=this.getAttribute("hotkey")??"Alt+Shift+D";if("none"===e)return;const t=e.split("+").map(e=>e.trim().toLowerCase()),n=t[t.length-1],i=t.includes("alt"),s=t.includes("shift"),o=t.includes("ctrl"),r=t.includes("meta");this._hotkeyHandler=e=>{e.key.toLowerCase()===n&&e.altKey===i&&e.shiftKey===s&&e.ctrlKey===o&&e.metaKey===r&&(e.preventDefault(),this.toggle())},window.addEventListener("keydown",this._hotkeyHandler)}_uninstallHotkey(){null!==this._hotkeyHandler&&(window.removeEventListener("keydown",this._hotkeyHandler),this._hotkeyHandler=null)}_enterPickMode(){this._pickMode=!0,this._pickHandler=e=>{const t=e.target;t.getRootNode()!==this.shadowRoot&&t!==this&&(e.preventDefault(),e.stopPropagation(),this._pickedNode=t,this._selectedPath=null,this._exitPickMode(),this._markDirty("wiring"))},document.addEventListener("click",this._pickHandler,{capture:!0})}_exitPickMode(){null!==this._pickHandler&&(document.removeEventListener("click",this._pickHandler,{capture:!0}),this._pickHandler=null),this._pickMode=!1;const e=this.shadowRoot?.querySelector('button[data-role="pick"]');e?.setAttribute("aria-pressed","false")}_markDirty(e){this._dirtyPanes.add(e),this._renderScheduled||(this._renderScheduled=!0,requestAnimationFrame(()=>{this._renderDirty()}))}_renderDirty(){if(this._renderScheduled=!1,null===this._core||null===this.shadowRoot)return void this._dirtyPanes.clear();const e=this._dirtyPanes;this._dirtyPanes=new Set,e.has("state")&&this._renderStatePane(),e.has("wiring")&&this._renderWiringPane(),e.has("timeline")&&this._renderTimelinePane()}_rosterKey(e){return`${e.sourceId}:${e.name}`}_selectedRoster(){const e=this._core.getRoster();if(0===e.length)return null;return e.find(e=>this._rosterKey(e)===this._selectedRosterKey)??e[0]}_renderStatePane(){const e=this._core,t=this._paneElements.state,n=this._stateSelect,i=e.getRoster(),s=this._selectedRoster();if(n.replaceChildren(...i.map(e=>{const t=document.createElement("option");return t.value=this._rosterKey(e),t.textContent=`${e.name} (${e.sourceId.slice(0,12)})`,t.selected=null!==s&&this._rosterKey(e)===this._rosterKey(s),t})),t.replaceChildren(),null===s)return void t.append(this._emptyRow("no <wcs-state> elements observed"));this._selectedRosterKey=this._rosterKey(s);const o=e.keysOf(s);if(0!==o.length)for(const e of o)this._renderTreeNode(t,s,{path:e,indexes:[]},e,0);else t.append(this._emptyRow("no readable keys (runtime without keys() API?)"))}_renderTreeNode(e,t,n,i,o){const r=this._core;let a,l=!0;try{a=r.readValue(t,n.path,n.indexes)}catch{l=!1}const d=document.createElement("div");d.className="tree-row",d.style.paddingLeft=14*o+"px";const c=l&&function(e){if(Array.isArray(e))return!0;if(null===e||"object"!=typeof e)return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}(a),h=function(e){return`${e.path}#${e.indexes.join(",")}`}(n),u=c&&this._expanded.has(h),p=document.createElement("span");p.className="toggle",p.textContent=c?u?"▾":"▸":"",c&&p.addEventListener("click",()=>{this._expanded.has(h)?this._expanded.delete(h):this._expanded.add(h),this._markDirty("state")}),d.append(p);const m=document.createElement("span");m.className="key",m.textContent=`${i}:`,m.title=n.path,m.addEventListener("click",()=>{this._selectedPath=n.path,this._pickedNode=null,this._markDirty("wiring"),this._highlightPath(t,n.path)}),d.append(m);const g=document.createElement("span");if(g.className="value",l){g.textContent=s(a,1);(null===a||"object"!=typeof a)&&"function"!=typeof a&&(g.classList.add("editable"),g.title="click to edit",g.addEventListener("click",()=>{this._beginEdit(d,g,t,n,a)}))}else g.textContent="(unreadable getter)";if(d.append(g),e.append(d),u)if(Array.isArray(a)){const i=Math.min(a.length,20);for(let s=0;s<i;s++)this._renderTreeNode(e,t,{path:`${n.path}.*`,indexes:[...n.indexes,s]},`[${s}]`,o+1);if(a.length>i){const t=this._emptyRow(`…(${a.length} items)`);t.style.paddingLeft=14*(o+1)+"px",e.append(t)}}else for(const i of Object.keys(a))this._renderTreeNode(e,t,{path:`${n.path}.${i}`,indexes:n.indexes},i,o+1)}_beginEdit(e,t,n,i,s){const o=document.createElement("input");o.value="string"==typeof s?s:String(s);const r=()=>{this._core?.writeValue(n,i.path,function(e){const t=e.trim();try{return JSON.parse(t)}catch{return e}}(o.value),i.indexes),this._markDirty("state")};o.addEventListener("keydown",e=>{"Enter"===e.key?r():"Escape"===e.key&&this._markDirty("state")}),e.replaceChild(o,t),o.focus()}_renderWiringPane(){const e=this._core,t=this._paneElements.wiring;let n,i;if(t.replaceChildren(),null!==this._pickedNode){n=e.getWiringForNode(this._pickedNode);const t=this._pickedNode;i=t instanceof Element?`<${t.tagName.toLowerCase()}>`:t.nodeName}else if(null!==this._selectedPath){const t=this._selectedRoster();n=null!==t?e.getWiringForPath(t.name,this._selectedPath):[],i=this._selectedPath}else n=e.getAllWiring(),i="all";const s=document.createElement("div");if(s.textContent=`context: ${i} — ${n.length} live binding${1===n.length?"":"s"}`,t.append(s),n.length>0){for(const e of n)t.append(this._wiringRow(e));return}const o=this._selectedRoster(),r=null!==o?function(e,t="data-wcs"){const n=[];for(const i of e.querySelectorAll(`[${t}]`)){const e=i.getAttribute(t);for(const t of e.split(";")){const e=c(i,t,"attribute");null!==e&&n.push(e)}}const i=(e.ownerDocument??e).createTreeWalker(e,NodeFilter.SHOW_COMMENT);let s=i.nextNode();for(;null!==s;){const e=s.textContent.trim(),t=d.find(t=>e===t||e.startsWith(t+":"));if(void 0!==t){const i=s.parentNode instanceof Element?s.parentNode:null;if(null!==i){const s=e===t?"":e.slice(t.length+1).trim();if(s.length>0){const e="wcs-text"===t?"textContent":t.slice(4);n.push(c(i,`${e}: ${s}`,"comment"))}}}s=i.nextNode()}return n}(this._scanRootOf(o)):[];if(0===r.length)return void t.append(this._emptyRow("no bindings observed"));const a=document.createElement("div");a.className="notice";const l=document.createElement("span");l.className="badge-tag declared",l.textContent="declared",a.append(l,document.createTextNode(" attached late — reload to capture live bindings "));const h=document.createElement("button");h.textContent="reload",h.addEventListener("click",()=>{location.reload()}),a.append(h),t.append(a);for(const e of r)t.append(this._declaredRow(e))}_scanRootOf(e){const t=e.rootNode;return t.nodeType===Node.DOCUMENT_NODE||t.nodeType===Node.DOCUMENT_FRAGMENT_NODE?t:document}_wiringRow(e){const t=document.createElement("div");t.className="wiring-row";const n=document.createElement("span");n.className="prop",n.textContent=e.propName;const i=document.createTextNode(" ← "),s=document.createElement("span");s.className="path",s.textContent=`${e.path}@${e.stateName}`;const o=document.createElement("span");return o.className="badge-tag",o.textContent=e.bindingType,t.append(o,document.createTextNode(" "),n,i,s),t.addEventListener("click",()=>{const t=e.bindingRef.deref();void 0!==t&&this._highlightNodes([t.node,t.replaceNode])}),t}_declaredRow(e){const t=document.createElement("div");t.className="wiring-row";const n=document.createElement("span");n.className="badge-tag declared",n.textContent=e.origin;const i=document.createElement("span");i.className="prop",i.textContent=e.propName;const s=document.createElement("span");return s.className="path",s.textContent=`${e.path}@${e.stateName}`,t.append(n,document.createTextNode(" "),i,document.createTextNode(" ← "),s),t.addEventListener("click",()=>{this._highlightNodes([e.element])}),t}_renderTimelinePane(){const e=this._core,t=this._paneElements.timeline,n=e.getTimeline(),i=Math.max(0,n.length-200),s=[];i>0&&s.push(this._emptyRow(`…(${i} earlier entries)`));for(let e=i;e<n.length;e++)s.push(this._timelineRow(n[e]));0===s.length&&s.push(this._emptyRow("no activity yet")),t.replaceChildren(...s),t.scrollTop=t.scrollHeight}_timelineRow(e){const t=document.createElement("div");t.className="timeline-row";const n=document.createElement("span");n.className="t",n.textContent=`${(e.time/1e3).toFixed(3)}s `;const i=document.createElement("span");i.className="badge-tag kind",i.textContent=e.kind,0===e.subscriberCount&&(i.classList.add("warn"),i.title="emitted with no subscribers"),"watch-error"!==e.kind&&"watch-chain-limit"!==e.kind||(i.classList.add("warn"),i.title="watch-error"===e.kind?"a $watch threw; the runtime isolated it (console.error only)":"a $watch write chain hit the depth limit and was cut off");const s=document.createElement("span");s.className="label";const o=null!==e.stateName?`@${e.stateName}`:"";s.textContent=` ${e.label}${o} `;const r=document.createElement("span");return r.className="detail",r.textContent=e.detail,t.append(n,i,s,r),t}_emptyRow(e){const t=document.createElement("div");return t.className="empty",t.textContent=e,t}_highlightPath(e,t){const n=this._core,i=[];for(const s of n.getWiringForPath(e.name,t)){const e=s.bindingRef.deref();void 0!==e&&i.push(e.node,e.replaceNode)}this._highlightNodes(i)}_highlightNodes(e){const t=this._highlightLayer;t.replaceChildren();const n=new Set;for(const i of e){const e=i instanceof Element?i:i.parentElement;if(null===e||n.has(e)||!e.isConnected)continue;n.add(e);const s=e.getBoundingClientRect(),o=document.createElement("div");o.className="hl-box",o.style.left=`${s.left}px`,o.style.top=`${s.top}px`,o.style.width=`${s.width}px`,o.style.height=`${s.height}px`,t.append(o)}setTimeout(()=>{t.replaceChildren()},2e3)}}const u="wcs-devtools";function p(){null===document.querySelector(u)&&document.body.appendChild(document.createElement(u))}document.documentElement.hasAttribute("data-wcs-server")||(customElements.get(u)||customElements.define(u,h),null!==document.body?p():document.addEventListener("DOMContentLoaded",p,{once:!0}));
1
+ const e="__WCSTACK_DEVTOOLS_HOOK__";function t(){const t=globalThis,n=t[e];if(void 0!==n)return 1!==n.version&&console.warn(`[wcstack/devtools] hook registry version mismatch: found ${n.version}, expected 1. Keeping the existing registry (first-wins).`),n;const i=function(){const e=new Map,t=new Set,n=e=>{if(0===t.size)return void e._setSink(null);const n=e.id;e._setSink(e=>{for(const i of t)i.onEvent?.(n,e)})};return{version:1,sources:e,register(i){if(!e.has(i.id)){e.set(i.id,i),n(i);for(const e of t)e.onSourceRegistered?.(i)}},unregister(n){const i=e.get(n);if(void 0!==i){i._setSink(null),e.delete(n);for(const e of t)e.onSourceUnregistered?.(n)}},addListener(i){t.add(i);for(const t of e.values())n(t),i.onSourceRegistered?.(t);return()=>{if(t.delete(i))for(const t of e.values())n(t)}}}}();return t[e]=i,i}const n=80;function i(e){const t=e.constructor,n=t?.name;return"string"==typeof n&&n.length>0?n:"Object"}function s(e,t=2){switch(typeof e){case"string":return`"${e.length>n?e.slice(0,n)+"…":e}"`;case"number":case"boolean":case"bigint":return String(e);case"symbol":return e.toString();case"undefined":return"undefined";case"function":return"[[Function]]"}if(null===e)return"null";const o=e;if(Array.isArray(o)){if(t<=0)return`[[Array(${o.length})]]`;const e=o.slice(0,3).map(e=>s(e,t-1)),n=o.length>3?`, …(${o.length})`:"";return`[${e.join(", ")}${n}]`}if(function(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}(o)){if(t<=0)return"[[Object]]";const e=Object.keys(o),n=e.slice(0,3).map(e=>`${e}: ${s(o[e],t-1)}`),i=e.length>3?`, …(${e.length})`:"";return`{${n.join(", ")}${i}}`}return`[[${i(o)}]]`}function o(e){if(null!==e&&"object"==typeof e){const{name:t,message:s}=e;if("string"==typeof s){const o="string"==typeof t&&t.length>0?t:i(e),r=s.length>n?s.slice(0,n)+"…":s;return r.length>0?`${o}: ${r}`:o}}return s(e,1)}function r(e){if(0===e.length)return"";const t=e.slice(0,3).map(e=>{const t=s(e,1);return t.length>n?t.slice(0,n)+"…":t}),i=e.length>3?`, …(${e.length})`:"";return`${t.join(", ")}${i}`}function a(e,t){return e+"\0"+t}class d{_timelineCapacity;_hiddenStateNames;_removeListener=null;_sources=new Map;_roster=new Map;_wiringByPathKey=new Map;_wiringEntryByBinding=new WeakMap;_timeline=[];_seq=0;_paused=!1;_changeListeners=new Set;constructor(e){this._timelineCapacity=e?.timelineCapacity??500,this._hiddenStateNames=new Set(e?.hiddenStateNames??[])}get connected(){return null!==this._removeListener}get paused(){return this._paused}set paused(e){this._paused=e}isHiddenStateName(e){return null!==e&&(e.startsWith("wcs-devtools")||this._hiddenStateNames.has(e))}connect(){if(null!==this._removeListener)return;const e=t();this._removeListener=e.addListener({onSourceRegistered:e=>{this._sources.set(e.id,e),this._refreshRosterOf(e),this._notify("sources")},onSourceUnregistered:e=>{this._sources.delete(e),this._roster.delete(e),this._notify("sources"),this._notify("roster")},onEvent:(e,t)=>{this._ingest(e,t)}})}disconnect(){null!==this._removeListener&&(this._removeListener(),this._removeListener=null,this._sources.clear(),this._roster.clear(),this._wiringByPathKey.clear(),this._wiringEntryByBinding=new WeakMap,this._notify("sources"),this._notify("roster"),this._notify("wiring"))}onChange(e){return this._changeListeners.add(e),()=>{this._changeListeners.delete(e)}}getSources(){return[...this._sources.values()]}getRoster(){const e=[];for(const t of this._roster.values())e.push(...t);return e}refreshRoster(){for(const e of this._sources.values())this._refreshRosterOf(e);this._notify("roster")}getTimeline(){return this._timeline}clearTimeline(){this._timeline=[],this._notify("timeline")}getWiringForPath(e,t){const n=this._wiringByPathKey.get(a(e,t));return void 0===n?[]:this._collectAlive(n)}getAllWiring(){const e=[];for(const t of this._wiringByPathKey.values())e.push(...this._collectAlive(t));return e}getWiringForNode(e){const t=[];for(const n of this._wiringByPathKey.values())for(const i of this._collectAlive(n)){const n=i.bindingRef.deref();(n.node===e||n.replaceNode===e||e.contains(n.node)||e.contains(n.replaceNode))&&t.push(i)}return t}keysOf(e){const t=this._sources.get(e.sourceId);return void 0===t||"function"!=typeof t.keys?[]:t.keys(e.name,e.rootNode)}readValue(e,t,n){const i=this._sources.get(e.sourceId);if(void 0!==i)return i.read(e.name,e.rootNode,t,n)}writeValue(e,t,n,i){const s=this._sources.get(e.sourceId);void 0!==s&&s.write(e.name,e.rootNode,t,n,i)}_notify(e){for(const t of this._changeListeners)t(e)}_refreshRosterOf(e){const t=[];for(const n of e.getStateElements())this.isHiddenStateName(n.name)||t.push({sourceId:e.id,name:n.name,rootNode:n.rootNode,summary:n});this._roster.set(e.id,t)}_collectAlive(e){const t=[];for(const n of e)void 0!==n.bindingRef.deref()?t.push(n):e.delete(n);return t}_appendTimeline(e){if(this._paused)return;this._timeline.push({...e,seq:this._seq++,time:performance.now()});const t=this._timeline.length-this._timelineCapacity;t>0&&this._timeline.splice(0,t),this._notify("timeline")}_labelOf(e){const t=e.listIndex?.indexes,n=e.absolutePathInfo.pathInfo.path;return void 0!==t?`${n}[${t.join(",")}]`:n}_ingest(e,t){switch(t.type){case"state:element-registered":{if(this.isHiddenStateName(t.name))return;const n=this._sources.get(e);return void 0!==n&&(this._refreshRosterOf(n),this._notify("roster")),void this._appendTimeline({sourceId:e,kind:"element-registered",stateName:t.name,label:t.name,detail:"",subscriberCount:null})}case"state:element-unregistered":{if(this.isHiddenStateName(t.name))return;const n=this._sources.get(e);return void 0!==n&&(this._refreshRosterOf(n),this._notify("roster")),void this._appendTimeline({sourceId:e,kind:"element-unregistered",stateName:t.name,label:t.name,detail:"",subscriberCount:null})}case"state:write":{const n=t.absoluteAddress.absolutePathInfo.stateName;if(this.isHiddenStateName(n))return;const i=t.hasOldValue?`${s(t.value)} (was ${s(t.oldValue)})`:s(t.value);return void this._appendTimeline({sourceId:e,kind:"write",stateName:n,label:this._labelOf(t.absoluteAddress),detail:i,subscriberCount:null})}case"state:update-batch":{const n=[];let i=0;for(const e of t.addresses)this.isHiddenStateName(e.absolutePathInfo.stateName)||(i++,n.length<3&&n.push(this._labelOf(e)));if(0===i)return;const s=i>n.length?`, …(${i})`:"";return void this._appendTimeline({sourceId:e,kind:"batch",stateName:null,label:`${i} address${1===i?"":"es"}`,detail:`${n.join(", ")}${s}`,subscriberCount:null})}case"state:binding-added":{const n=t.absoluteAddress.absolutePathInfo.stateName;if(this.isHiddenStateName(n))return;const i=t.absoluteAddress.absolutePathInfo.pathInfo.path,s=a(n,i);let o=this._wiringByPathKey.get(s);void 0===o&&(o=new Set,this._wiringByPathKey.set(s,o));const r={sourceId:e,stateName:n,path:i,propName:t.binding.propName,bindingType:t.binding.bindingType,bindingRef:new WeakRef(t.binding)};return o.add(r),this._wiringEntryByBinding.set(t.binding,r),void this._notify("wiring")}case"state:binding-removed":{const e=this._wiringEntryByBinding.get(t.binding);if(void 0===e)return;this._wiringEntryByBinding.delete(t.binding);const n=a(e.stateName,e.path),i=this._wiringByPathKey.get(n);return void 0!==i&&(i.delete(e),0===i.size&&this._wiringByPathKey.delete(n)),void this._notify("wiring")}case"state:binding-cleared":{const e=a(t.absoluteAddress.absolutePathInfo.stateName,t.absoluteAddress.absolutePathInfo.pathInfo.path);return void(this._wiringByPathKey.delete(e)&&this._notify("wiring"))}case"state:token-emit":if(this.isHiddenStateName(t.stateName))return;return void this._appendTimeline({sourceId:e,kind:t.kind,stateName:t.stateName,label:t.tokenName,detail:r(t.args),subscriberCount:t.subscriberCount});case"state:watch-error":if(this.isHiddenStateName(t.stateName))return;return void this._appendTimeline({sourceId:e,kind:"watch-error",stateName:t.stateName,label:t.path,detail:`${t.phase}: ${o(t.error)}`,subscriberCount:null});case"state:watch-chain-limit":return void this._appendTimeline({sourceId:e,kind:"watch-chain-limit",stateName:null,label:`depth > ${t.maxDepth}`,detail:t.paths.join(", "),subscriberCount:null});case"propagation:suppressed":return void this._appendTimeline({sourceId:e,kind:"propagation-suppressed",stateName:null,label:t.member,detail:`${t.reason} (tx ${t.transactionId}, edge ${t.edgeId})`,subscriberCount:null});case"propagation:coalesced":{const n=t.absoluteAddress.absolutePathInfo.stateName;if(this.isHiddenStateName(n))return;return void this._appendTimeline({sourceId:e,kind:"propagation-coalesced",stateName:n,label:this._labelOf(t.absoluteAddress),detail:`tx ${t.droppedTransactionId} dropped (winner tx ${t.winnerTransactionId})`,subscriberCount:null})}case"propagation:hop-limit":{const n=t.absoluteAddress.absolutePathInfo.stateName;if(this.isHiddenStateName(n))return;return void this._appendTimeline({sourceId:e,kind:"propagation-hop-limit",stateName:n,label:this._labelOf(t.absoluteAddress),detail:`hop ${t.hop} (tx ${t.transactionId})`,subscriberCount:null})}case"contract:drift":{const n=void 0!==t.member?`: ${t.member}`:"",i="event-mismatch"===t.reason?` (sidecar ${t.sidecarEvent??"?"} / live ${t.liveEvent??"?"})`:"";return void this._appendTimeline({sourceId:e,kind:"contract-drift",stateName:null,label:t.tag,detail:`${t.reason}${n}${i}`,subscriberCount:null})}case"contract:manifest-read":case"contract:unsupported-extension":return}}}const l=["wcs-text","wcs-for","wcs-if","wcs-elseif","wcs-else"];function c(e,t,n){const i=t.trim();if(0===i.length)return null;const s=i.indexOf(":");if(s<0)return null;const o=i.slice(0,s).trim(),r=i.slice(s+1).trim();if(0===o.length||0===r.length)return null;const[a,...d]=r.split("|").map(e=>e.trim());let l=a,c="default";const h=a.lastIndexOf("@");return h>0&&(l=a.slice(0,h).trim(),c=a.slice(h+1).trim()),{element:e,propName:o,path:l,stateName:c,filters:d.filter(e=>e.length>0),origin:n,raw:i}}class h extends HTMLElement{static get observedAttributes(){return["open","dock","hotkey"]}_core=null;_removeCoreListener=null;_panel=null;_badge=null;_stateSelect=null;_paneElements={};_highlightLayer=null;_dirtyPanes=new Set;_renderScheduled=!1;_selectedRosterKey=null;_selectedPath=null;_pickedNode=null;_pickMode=!1;_expanded=new Set;_hotkeyHandler=null;_pickHandler=null;get core(){return this._core}connectedCallback(){if(document.documentElement.hasAttribute("data-wcs-server"))return;null===this.shadowRoot&&this._buildShadow();const e=Number(this.getAttribute("buffer")??""),t=(this.getAttribute("hidden-states")??"").split(",").map(e=>e.trim()).filter(e=>e.length>0);this._core=new d({timelineCapacity:Number.isFinite(e)&&e>0?e:void 0,hiddenStateNames:t}),this._removeCoreListener=this._core.onChange(e=>{"roster"===e||"sources"===e?(this._markDirty("state"),this._markDirty("wiring")):"wiring"===e?this._markDirty("wiring"):this._markDirty("timeline")}),this._core.connect(),this._applyDock(),this._applyOpen(),this._installHotkey(),this._markDirty("state"),this._markDirty("wiring"),this._markDirty("timeline")}disconnectedCallback(){this._removeCoreListener?.(),this._removeCoreListener=null,this._core?.disconnect(),this._core=null,this._uninstallHotkey(),this._exitPickMode()}attributeChangedCallback(e){null!==this.shadowRoot&&("open"===e?this._applyOpen():"dock"===e?this._applyDock():"hotkey"===e&&(this._uninstallHotkey(),this._installHotkey()))}__flushRenderForTest(){this._renderDirty()}_buildShadow(){const e=this.attachShadow({mode:"open"}),t=document.createElement("style");t.textContent='\n:host {\n all: initial;\n position: fixed;\n z-index: 2147483647;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n inset: auto 0 0 auto;\n}\n* { box-sizing: border-box; }\n.badge {\n position: fixed;\n right: 12px;\n bottom: 12px;\n width: 40px;\n height: 40px;\n border-radius: 20px;\n border: 1px solid #2b4f78;\n background: #10263f;\n color: #9fd0ff;\n font-weight: 700;\n cursor: pointer;\n}\n.panel {\n position: fixed;\n display: flex;\n flex-direction: column;\n background: #0d1b2a;\n color: #d7e3f4;\n border: 1px solid #2b4f78;\n box-shadow: 0 0 24px rgba(0,0,0,.5);\n}\n.panel.dock-bottom { left: 0; right: 0; bottom: 0; height: 45vh; }\n.panel.dock-right { top: 0; right: 0; bottom: 0; width: 420px; }\n.panel[hidden] { display: none; }\nheader {\n display: flex;\n gap: 6px;\n align-items: center;\n padding: 6px 8px;\n border-bottom: 1px solid #2b4f78;\n background: #10263f;\n}\nheader .title { font-weight: 700; color: #9fd0ff; margin-right: 4px; }\nheader select, header button {\n font: inherit;\n background: #16324f;\n color: #d7e3f4;\n border: 1px solid #2b4f78;\n border-radius: 4px;\n padding: 2px 8px;\n cursor: pointer;\n}\nheader button[aria-pressed="true"] { background: #2b5d8f; }\nheader .spacer { flex: 1; }\n.panes { display: flex; flex: 1; min-height: 0; }\n.pane { flex: 1; min-width: 0; overflow: auto; padding: 6px 8px; border-right: 1px solid #1d3a5c; }\n.pane:last-child { border-right: none; }\n.pane h3 {\n margin: 0 0 6px;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .08em;\n color: #7ba7d4;\n}\n.tree-row { display: flex; gap: 6px; padding: 1px 0; align-items: baseline; white-space: nowrap; }\n.tree-row .toggle { width: 14px; cursor: pointer; color: #7ba7d4; user-select: none; }\n.tree-row .key { color: #9fd0ff; cursor: pointer; }\n.tree-row .value { color: #ffd9a0; overflow: hidden; text-overflow: ellipsis; }\n.tree-row .value.editable { cursor: pointer; }\n.tree-row input { font: inherit; background: #16324f; color: #ffd9a0; border: 1px solid #2b4f78; }\n.badge-tag {\n display: inline-block;\n padding: 0 4px;\n border-radius: 3px;\n font-size: 10px;\n background: #26456a;\n color: #a8c6e8;\n}\n.badge-tag.warn { background: #6a3326; color: #ffb3a0; }\n.badge-tag.declared { background: #4a4426; color: #efe3a0; }\n.wiring-row, .timeline-row { padding: 1px 0; white-space: nowrap; }\n.wiring-row .prop { color: #b7f0c0; }\n.wiring-row .path { color: #9fd0ff; }\n.timeline-row .t { color: #6f88a3; }\n.timeline-row .label { color: #9fd0ff; }\n.timeline-row .detail { color: #ffd9a0; }\n.timeline-row .kind { display: inline-block; min-width: 52px; text-align: center; }\n.empty { color: #6f88a3; font-style: italic; padding: 4px 0; }\n.notice { color: #efe3a0; padding: 2px 0 6px; }\n.notice button { font: inherit; margin-left: 6px; cursor: pointer; }\n.hl-box {\n position: fixed;\n pointer-events: none;\n border: 1px solid #58c2ff;\n background: rgba(88,194,255,.18);\n}\n',e.append(t);const n=document.createElement("button");n.className="badge",n.title="wcstack DevTools",n.textContent="WCS",n.addEventListener("click",()=>this.toggle()),e.append(n),this._badge=n;const i=document.createElement("div");i.className="panel dock-bottom",i.hidden=!0;const s=document.createElement("header"),o=document.createElement("span");o.className="title",o.textContent="wcstack devtools",s.append(o);const r=document.createElement("select");r.title="state element",r.addEventListener("change",()=>{this._selectedRosterKey=r.value||null,this._selectedPath=null,this._expanded.clear(),this._markDirty("state"),this._markDirty("wiring")}),s.append(r),this._stateSelect=r;const a=this._headerButton(s,"⌖ pick","pick a page element");a.addEventListener("click",()=>{this._pickMode?this._exitPickMode():this._enterPickMode(),a.setAttribute("aria-pressed",String(this._pickMode))}),a.dataset.role="pick";const d=this._headerButton(s,"⏸","pause timeline");d.addEventListener("click",()=>{const e=this._core;null!==e&&(e.paused=!e.paused,d.setAttribute("aria-pressed",String(e.paused)))}),d.dataset.role="pause";const l=this._headerButton(s,"🗑","clear timeline");l.addEventListener("click",()=>{this._core?.clearTimeline()}),l.dataset.role="clear";const c=document.createElement("span");c.className="spacer",s.append(c);const h=this._headerButton(s,"dock","toggle dock position");h.addEventListener("click",()=>{const e="bottom"===(this.getAttribute("dock")??"bottom")?"right":"bottom";this.setAttribute("dock",e)}),h.dataset.role="dock";const u=this._headerButton(s,"×","close");u.addEventListener("click",()=>this.toggle(!1)),u.dataset.role="close",i.append(s);const p=document.createElement("div");p.className="panes";for(const[e,t]of[["state","State"],["wiring","Wiring"],["timeline","Timeline"]]){const n=document.createElement("section");n.className=`pane pane-${e}`;const i=document.createElement("h3");i.textContent=t;const s=document.createElement("div");s.className="pane-body",n.append(i,s),p.append(n),this._paneElements[e]=s}i.append(p),e.append(i),this._panel=i;const m=document.createElement("div");m.className="hl-layer",e.append(m),this._highlightLayer=m}_headerButton(e,t,n){const i=document.createElement("button");return i.textContent=t,i.title=n,i.setAttribute("aria-pressed","false"),e.append(i),i}get open(){return this.hasAttribute("open")}toggle(e){e??!this.open?this.setAttribute("open",""):this.removeAttribute("open")}_applyOpen(){this._panel.hidden=!this.open,this._badge.hidden=this.open,this.open&&(this._markDirty("state"),this._markDirty("wiring"),this._markDirty("timeline"))}_applyDock(){const e="right"===this.getAttribute("dock")?"right":"bottom";this._panel.classList.toggle("dock-right","right"===e),this._panel.classList.toggle("dock-bottom","bottom"===e)}_installHotkey(){const e=this.getAttribute("hotkey")??"Alt+Shift+D";if("none"===e)return;const t=e.split("+").map(e=>e.trim().toLowerCase()),n=t[t.length-1],i=t.includes("alt"),s=t.includes("shift"),o=t.includes("ctrl"),r=t.includes("meta");this._hotkeyHandler=e=>{e.key.toLowerCase()===n&&e.altKey===i&&e.shiftKey===s&&e.ctrlKey===o&&e.metaKey===r&&(e.preventDefault(),this.toggle())},window.addEventListener("keydown",this._hotkeyHandler)}_uninstallHotkey(){null!==this._hotkeyHandler&&(window.removeEventListener("keydown",this._hotkeyHandler),this._hotkeyHandler=null)}_enterPickMode(){this._pickMode=!0,this._pickHandler=e=>{const t=e.target;t.getRootNode()!==this.shadowRoot&&t!==this&&(e.preventDefault(),e.stopPropagation(),this._pickedNode=t,this._selectedPath=null,this._exitPickMode(),this._markDirty("wiring"))},document.addEventListener("click",this._pickHandler,{capture:!0})}_exitPickMode(){null!==this._pickHandler&&(document.removeEventListener("click",this._pickHandler,{capture:!0}),this._pickHandler=null),this._pickMode=!1;const e=this.shadowRoot?.querySelector('button[data-role="pick"]');e?.setAttribute("aria-pressed","false")}_markDirty(e){this._dirtyPanes.add(e),this._renderScheduled||(this._renderScheduled=!0,requestAnimationFrame(()=>{this._renderDirty()}))}_renderDirty(){if(this._renderScheduled=!1,null===this._core||null===this.shadowRoot)return void this._dirtyPanes.clear();const e=this._dirtyPanes;this._dirtyPanes=new Set,e.has("state")&&this._renderStatePane(),e.has("wiring")&&this._renderWiringPane(),e.has("timeline")&&this._renderTimelinePane()}_rosterKey(e){return`${e.sourceId}:${e.name}`}_selectedRoster(){const e=this._core.getRoster();if(0===e.length)return null;return e.find(e=>this._rosterKey(e)===this._selectedRosterKey)??e[0]}_renderStatePane(){const e=this._core,t=this._paneElements.state,n=this._stateSelect,i=e.getRoster(),s=this._selectedRoster();if(n.replaceChildren(...i.map(e=>{const t=document.createElement("option");return t.value=this._rosterKey(e),t.textContent=`${e.name} (${e.sourceId.slice(0,12)})`,t.selected=null!==s&&this._rosterKey(e)===this._rosterKey(s),t})),t.replaceChildren(),null===s)return void t.append(this._emptyRow("no <wcs-state> elements observed"));this._selectedRosterKey=this._rosterKey(s);const o=e.keysOf(s);if(0!==o.length)for(const e of o)this._renderTreeNode(t,s,{path:e,indexes:[]},e,0);else t.append(this._emptyRow("no readable keys (runtime without keys() API?)"))}_renderTreeNode(e,t,n,i,o){const r=this._core;let a,d=!0;try{a=r.readValue(t,n.path,n.indexes)}catch{d=!1}const l=document.createElement("div");l.className="tree-row",l.style.paddingLeft=14*o+"px";const c=d&&function(e){if(Array.isArray(e))return!0;if(null===e||"object"!=typeof e)return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}(a),h=function(e){return`${e.path}#${e.indexes.join(",")}`}(n),u=c&&this._expanded.has(h),p=document.createElement("span");p.className="toggle",p.textContent=c?u?"▾":"▸":"",c&&p.addEventListener("click",()=>{this._expanded.has(h)?this._expanded.delete(h):this._expanded.add(h),this._markDirty("state")}),l.append(p);const m=document.createElement("span");m.className="key",m.textContent=`${i}:`,m.title=n.path,m.addEventListener("click",()=>{this._selectedPath=n.path,this._pickedNode=null,this._markDirty("wiring"),this._highlightPath(t,n.path)}),l.append(m);const g=document.createElement("span");if(g.className="value",d){g.textContent=s(a,1);(null===a||"object"!=typeof a)&&"function"!=typeof a&&(g.classList.add("editable"),g.title="click to edit",g.addEventListener("click",()=>{this._beginEdit(l,g,t,n,a)}))}else g.textContent="(unreadable getter)";if(l.append(g),e.append(l),u)if(Array.isArray(a)){const i=Math.min(a.length,20);for(let s=0;s<i;s++)this._renderTreeNode(e,t,{path:`${n.path}.*`,indexes:[...n.indexes,s]},`[${s}]`,o+1);if(a.length>i){const t=this._emptyRow(`…(${a.length} items)`);t.style.paddingLeft=14*(o+1)+"px",e.append(t)}}else for(const i of Object.keys(a))this._renderTreeNode(e,t,{path:`${n.path}.${i}`,indexes:n.indexes},i,o+1)}_beginEdit(e,t,n,i,s){const o=document.createElement("input");o.value="string"==typeof s?s:String(s);const r=()=>{this._core?.writeValue(n,i.path,function(e){const t=e.trim();try{return JSON.parse(t)}catch{return e}}(o.value),i.indexes),this._markDirty("state")};o.addEventListener("keydown",e=>{"Enter"===e.key?r():"Escape"===e.key&&this._markDirty("state")}),e.replaceChild(o,t),o.focus()}_renderWiringPane(){const e=this._core,t=this._paneElements.wiring;let n,i;if(t.replaceChildren(),null!==this._pickedNode){n=e.getWiringForNode(this._pickedNode);const t=this._pickedNode;i=t instanceof Element?`<${t.tagName.toLowerCase()}>`:t.nodeName}else if(null!==this._selectedPath){const t=this._selectedRoster();n=null!==t?e.getWiringForPath(t.name,this._selectedPath):[],i=this._selectedPath}else n=e.getAllWiring(),i="all";const s=document.createElement("div");if(s.textContent=`context: ${i} — ${n.length} live binding${1===n.length?"":"s"}`,t.append(s),n.length>0){for(const e of n)t.append(this._wiringRow(e));return}const o=this._selectedRoster(),r=null!==o?function(e,t="data-wcs"){const n=[];for(const i of e.querySelectorAll(`[${t}]`)){const e=i.getAttribute(t);for(const t of e.split(";")){const e=c(i,t,"attribute");null!==e&&n.push(e)}}const i=(e.ownerDocument??e).createTreeWalker(e,NodeFilter.SHOW_COMMENT);let s=i.nextNode();for(;null!==s;){const e=s.textContent.trim(),t=l.find(t=>e===t||e.startsWith(t+":"));if(void 0!==t){const i=s.parentNode instanceof Element?s.parentNode:null;if(null!==i){const s=e===t?"":e.slice(t.length+1).trim();if(s.length>0){const e="wcs-text"===t?"textContent":t.slice(4);n.push(c(i,`${e}: ${s}`,"comment"))}}}s=i.nextNode()}return n}(this._scanRootOf(o)):[];if(0===r.length)return void t.append(this._emptyRow("no bindings observed"));const a=document.createElement("div");a.className="notice";const d=document.createElement("span");d.className="badge-tag declared",d.textContent="declared",a.append(d,document.createTextNode(" attached late — reload to capture live bindings "));const h=document.createElement("button");h.textContent="reload",h.addEventListener("click",()=>{location.reload()}),a.append(h),t.append(a);for(const e of r)t.append(this._declaredRow(e))}_scanRootOf(e){const t=e.rootNode;return t.nodeType===Node.DOCUMENT_NODE||t.nodeType===Node.DOCUMENT_FRAGMENT_NODE?t:document}_wiringRow(e){const t=document.createElement("div");t.className="wiring-row";const n=document.createElement("span");n.className="prop",n.textContent=e.propName;const i=document.createTextNode(" ← "),s=document.createElement("span");s.className="path",s.textContent=`${e.path}@${e.stateName}`;const o=document.createElement("span");return o.className="badge-tag",o.textContent=e.bindingType,t.append(o,document.createTextNode(" "),n,i,s),t.addEventListener("click",()=>{const t=e.bindingRef.deref();void 0!==t&&this._highlightNodes([t.node,t.replaceNode])}),t}_declaredRow(e){const t=document.createElement("div");t.className="wiring-row";const n=document.createElement("span");n.className="badge-tag declared",n.textContent=e.origin;const i=document.createElement("span");i.className="prop",i.textContent=e.propName;const s=document.createElement("span");return s.className="path",s.textContent=`${e.path}@${e.stateName}`,t.append(n,document.createTextNode(" "),i,document.createTextNode(" ← "),s),t.addEventListener("click",()=>{this._highlightNodes([e.element])}),t}_renderTimelinePane(){const e=this._core,t=this._paneElements.timeline,n=e.getTimeline(),i=Math.max(0,n.length-200),s=[];i>0&&s.push(this._emptyRow(`…(${i} earlier entries)`));for(let e=i;e<n.length;e++)s.push(this._timelineRow(n[e]));0===s.length&&s.push(this._emptyRow("no activity yet")),t.replaceChildren(...s),t.scrollTop=t.scrollHeight}_timelineRow(e){const t=document.createElement("div");t.className="timeline-row";const n=document.createElement("span");n.className="t",n.textContent=`${(e.time/1e3).toFixed(3)}s `;const i=document.createElement("span");i.className="badge-tag kind",i.textContent=e.kind,0===e.subscriberCount&&(i.classList.add("warn"),i.title="emitted with no subscribers"),"watch-error"!==e.kind&&"watch-chain-limit"!==e.kind||(i.classList.add("warn"),i.title="watch-error"===e.kind?"a $watch threw; the runtime isolated it (console.error only)":"a $watch write chain hit the depth limit and was cut off"),"propagation-hop-limit"!==e.kind&&"contract-drift"!==e.kind||(i.classList.add("warn"),i.title="propagation-hop-limit"===e.kind?"a two-way propagation chain hit the hop limit and was cut off":"sidecar manifest drifted from the live wcBindable declaration (live wins)");const s=document.createElement("span");s.className="label";const o=null!==e.stateName?`@${e.stateName}`:"";s.textContent=` ${e.label}${o} `;const r=document.createElement("span");return r.className="detail",r.textContent=e.detail,t.append(n,i,s,r),t}_emptyRow(e){const t=document.createElement("div");return t.className="empty",t.textContent=e,t}_highlightPath(e,t){const n=this._core,i=[];for(const s of n.getWiringForPath(e.name,t)){const e=s.bindingRef.deref();void 0!==e&&i.push(e.node,e.replaceNode)}this._highlightNodes(i)}_highlightNodes(e){const t=this._highlightLayer;t.replaceChildren();const n=new Set;for(const i of e){const e=i instanceof Element?i:i.parentElement;if(null===e||n.has(e)||!e.isConnected)continue;n.add(e);const s=e.getBoundingClientRect(),o=document.createElement("div");o.className="hl-box",o.style.left=`${s.left}px`,o.style.top=`${s.top}px`,o.style.width=`${s.width}px`,o.style.height=`${s.height}px`,t.append(o)}setTimeout(()=>{t.replaceChildren()},2e3)}}const u="wcs-devtools";function p(){null===document.querySelector(u)&&document.body.appendChild(document.createElement(u))}document.documentElement.hasAttribute("data-wcs-server")||(customElements.get(u)||customElements.define(u,h),null!==document.body?p():document.addEventListener("DOMContentLoaded",p,{once:!0}));
2
2
  //# sourceMappingURL=auto.min.js.map