pulse-ui-client 0.1.75 → 0.1.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +13 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -105,7 +105,14 @@ interface NewExpr {
|
|
|
105
105
|
args: VDOMNode[];
|
|
106
106
|
}
|
|
107
107
|
type CallbackPlaceholder = "$cb" | `$cb:${number}`;
|
|
108
|
-
|
|
108
|
+
interface PulseRefPayload {
|
|
109
|
+
channelId: string;
|
|
110
|
+
refId: string;
|
|
111
|
+
}
|
|
112
|
+
interface PulseRefSpec {
|
|
113
|
+
__pulse_ref__: PulseRefPayload;
|
|
114
|
+
}
|
|
115
|
+
type VDOMPropValue = JsonValue | VDOMExpr | VDOMElement | CallbackPlaceholder | PulseRefSpec;
|
|
109
116
|
interface VDOMElement {
|
|
110
117
|
tag: string | VDOMExpr;
|
|
111
118
|
key?: string;
|
|
@@ -347,6 +354,10 @@ declare class PulseSocketIOClient {
|
|
|
347
354
|
sendJsResult(id: string, result: any, error: string | null): void;
|
|
348
355
|
acquireChannel(id: string): ChannelBridge;
|
|
349
356
|
releaseChannel(id: string): void;
|
|
357
|
+
_ensureChannelEntry(id: string): {
|
|
358
|
+
bridge: ChannelBridge;
|
|
359
|
+
refCount: number;
|
|
360
|
+
};
|
|
350
361
|
}
|
|
351
362
|
//#endregion
|
|
352
363
|
//#region src/channel.d.ts
|
|
@@ -414,6 +425,7 @@ declare class VDOMRenderer {
|
|
|
414
425
|
init(view: PulsePrerenderView & {
|
|
415
426
|
vdom: VDOM;
|
|
416
427
|
}): ReactNode;
|
|
428
|
+
dispose(): void;
|
|
417
429
|
/**
|
|
418
430
|
* Evaluate a VDOMNode expression (for run_js support).
|
|
419
431
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Fragment as e,cloneElement as t,createContext as n,createElement as r,forwardRef as i,isValidElement as a,useCallback as o,useContext as s,useEffect as c,useMemo as l,useRef as u,useState as d}from"react";import{useLocation as f,useNavigate as p,useParams as m}from"react-router";import{io as h}from"socket.io-client";import{jsx as g,jsxs as _}from"react/jsx-runtime";function v(){function e(e,t){return n=>{let r={};for(let t of e)r[t]=n[t];if(t)for(let e in t){let i=t[e];r[e]=i(n)}return r}}return e}const y=e=>e.tagName.toLowerCase(),ee=[`id`,`className`,`tagName`,`localName`,`clientHeight`,`clientLeft`,`clientTop`,`clientWidth`,`scrollHeight`,`scrollLeft`,`scrollTop`,`scrollWidth`,`slot`],te=[`autofocus`,`tabIndex`,`nonce`],ne=[`accessKey`,`accessKeyLabel`,`autocapitalize`,`dir`,`draggable`,`hidden`,`inert`,`lang`,`offsetHeight`,`offsetLeft`,`offsetTop`,`offsetWidth`,`popover`,`spellcheck`,`title`,`translate`,`writingSuggestions`,`contentEditable`,`enterKeyHint`,`isContentEditable`,`inputMode`],b=v()(ee,{tagName:y}),x=v()(te),re=v()(ne);function S(e){return{...b(e),...x(e),...re(e)}}function C(e,t){let n=v()(e,t);return e=>({...S(e),...n(e)})}const ie=C([`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`search`,`target`,`download`,`rel`,`hreflang`,`type`,`username`,`ping`,`referrerPolicy`,`text`]),ae=C([`alt`,`coords`,`download`,`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`rel`,`search`,`shape`,`target`,`username`,`ping`,`referrerPolicy`]),w=C([`autoplay`,`controls`,`crossOrigin`,`currentSrc`,`currentTime`,`defaultMuted`,`defaultPlaybackRate`,`duration`,`ended`,`loop`,`muted`,`networkState`,`paused`,`playbackRate`,`preload`,`readyState`,`seeking`,`src`,`volume`,`preservesPitch`]),oe=e=>w(e),se=C([`disabled`,`name`,`type`,`value`,`formAction`,`formEnctype`,`formMethod`,`formNoValidate`,`formTarget`,`popoverTargetAction`]),ce=C([`value`]),le=C([`height`,`src`,`type`,`width`,`align`,`name`]),ue=C([`disabled`,`name`,`type`,`validationMessage`,`willValidate`]),de=C([`acceptCharset`,`action`,`autocomplete`,`encoding`,`enctype`,`length`,`method`,`name`,`noValidate`,`target`,`rel`]),fe=C([`allow`,`allowFullscreen`,`height`,`name`,`referrerPolicy`,`src`,`srcdoc`,`width`,`align`,`frameBorder`,`longDesc`,`marginHeight`,`marginWidth`,`scrolling`,`sandbox`]),pe=C([`alt`,`crossOrigin`,`decoding`,`height`,`isMap`,`loading`,`naturalHeight`,`naturalWidth`,`referrerPolicy`,`sizes`,`src`,`srcset`,`useMap`,`width`,`align`,`border`,`complete`,`hspace`,`longDesc`,`lowsrc`,`name`,`vspace`,`x`,`y`,`fetchPriority`]),me=C(`accept.alt.autocomplete.checked.defaultChecked.defaultValue.dirName.disabled.height.indeterminate.max.maxLength.min.minLength.multiple.name.pattern.placeholder.readOnly.required.selectionDirection.selectionEnd.selectionStart.size.src.step.type.value.valueAsNumber.width.align.capture.formAction.formEnctype.formMethod.formNoValidate.formTarget.useMap.validationMessage.willValidate.popoverTargetAction`.split(`.`),{valueAsNumber:e=>{let t=e.valueAsNumber;return Number.isFinite(t)?t:null}}),he=C([`htmlFor`]),ge=C([`value`,`type`]),_e=C([`as`,`crossOrigin`,`disabled`,`fetchPriority`,`href`,`hreflang`,`imageSizes`,`imageSrcset`,`integrity`,`media`,`referrerPolicy`,`rel`,`type`,`charset`,`rev`,`target`,`sizes`]),ve=C([`name`]),ye=C([`high`,`low`,`max`,`min`,`optimum`,`value`]),T=C([`cite`,`dateTime`]),be=C([`reversed`,`start`,`type`,`compact`]),xe=C([`data`,`height`,`name`,`type`,`useMap`,`width`,`validationMessage`,`willValidate`,`align`,`archive`,`border`,`code`,`codeBase`,`codeType`,`declare`,`hspace`,`standby`,`vspace`]),Se=C([`disabled`,`label`]),Ce=C([`defaultSelected`,`disabled`,`index`,`label`,`selected`,`text`,`value`]),we=C([`defaultValue`,`name`,`type`,`value`,`htmlFor`,`validationMessage`,`willValidate`]),Te=C([`max`,`position`,`value`]),E=C([`cite`]),Ee=e=>S(e),De=v()([`async`,`crossOrigin`,`defer`,`fetchPriority`,`integrity`,`noModule`,`referrerPolicy`,`src`,`text`,`type`,`charset`],{event:e=>e.event,htmlFor:e=>e.htmlFor}),Oe=e=>({...S(e),...De(e)}),ke=C([`autocomplete`,`disabled`,`length`,`multiple`,`name`,`required`,`selectedIndex`,`size`,`type`,`value`,`validationMessage`,`willValidate`]),Ae=C([`name`]),je=C([`height`,`media`,`sizes`,`src`,`srcset`,`type`,`width`]),Me=C([`align`]),D=C([`abbr`,`cellIndex`,`colSpan`,`headers`,`rowSpan`,`scope`,`align`,`axis`,`bgColor`,`ch`,`chOff`,`height`,`noWrap`,`vAlign`,`width`]),O=C([`span`,`align`,`ch`,`chOff`,`vAlign`,`width`]),Ne=C([`align`,`bgColor`,`border`,`cellPadding`,`cellSpacing`,`frame`,`rules`,`summary`,`width`]),Pe=C([`rowIndex`,`sectionRowIndex`,`align`,`bgColor`,`ch`,`chOff`,`vAlign`]),k=C([`align`,`ch`,`chOff`,`vAlign`]),Fe=e=>S(e),Ie=C([`autocomplete`,`cols`,`defaultValue`,`dirName`,`disabled`,`maxLength`,`minLength`,`name`,`placeholder`,`readOnly`,`required`,`rows`,`selectionDirection`,`selectionEnd`,`selectionStart`,`value`,`wrap`,`textLength`,`validationMessage`,`willValidate`]),Le=C([`dateTime`]),Re=C([`default`,`kind`,`label`,`readyState`,`src`,`srclang`]),ze=v()([`height`,`poster`,`videoHeight`,`videoWidth`,`width`,`playsInline`]),Be=e=>({...w(e),...ze(e)}),Ve=C([`clear`]),He=C([`href`,`target`]),Ue=C([`aLink`,`background`,`bgColor`,`link`,`text`,`vLink`]),We=C([`compact`]),Ge=C([`open`]),Ke=C([`open`,`returnValue`]),qe=C([`align`]),Je=e=>S(e),A=C([`align`]),Ye=C([`align`,`color`,`noShade`,`size`,`width`]),Xe=C([`version`]),Ze=e=>S(e),Qe=C([`content`,`httpEquiv`,`name`,`scheme`]),$e=C([`align`]),et=e=>S(e),tt=C([`width`]),nt=e=>S(e),rt=C([`media`,`type`,`disabled`]),it=C([`text`]),at=C([`compact`,`type`]);function j(e){return{...b(e),...x(e)}}function M(e,t){let n=v()(e,t);return e=>({...j(e),...n(e)})}const ot={A:ie,AREA:ae,AUDIO:oe,BASE:He,BLOCKQUOTE:E,Q:E,BODY:Ue,BR:Ve,BUTTON:se,CANVAS:S,CAPTION:Me,CITE:Ee,COL:O,COLGROUP:O,DATA:ce,DETAILS:Ge,DIALOG:Ke,DIV:qe,DL:We,EMBED:le,FIELDSET:ue,FORM:de,H1:A,H2:A,H3:A,H4:A,H5:A,H6:A,HEAD:Je,HR:Ye,HTML:Xe,IFRAME:fe,IMG:pe,INPUT:me,LABEL:he,LI:ge,LINK:_e,MAP:ve,MENU:Ze,META:Qe,METER:ye,INS:T,DEL:T,OBJECT:xe,OL:be,OPTGROUP:Se,OPTION:Ce,OUTPUT:we,P:$e,PICTURE:et,PRE:tt,PROGRESS:Te,SCRIPT:Oe,SELECT:ke,SLOT:Ae,SOURCE:je,SPAN:nt,STYLE:rt,TABLE:Ne,TBODY:k,THEAD:k,TFOOT:k,TD:D,TH:D,TEMPLATE:Fe,TEXTAREA:Ie,TIME:Le,TITLE:it,TR:Pe,TRACK:Re,UL:at,VIDEO:Be,SVG:M([`x`,`y`,`width`,`height`,`currentScale`,`currentTranslate`]),CIRCLE:M([`cx`,`cy`,`r`]),ELLIPSE:M([`cx`,`cy`,`rx`,`ry`]),LINE:M([`x1`,`y1`,`x2`,`y2`]),PATH:M([`pathLength`]),RECT:M([`x`,`y`,`width`,`height`,`rx`,`ry`]),POLYGON:M([`points`]),POLYLINE:M([`points`]),TEXT:M([`x`,`y`,`dx`,`dy`,`rotate`,`textLength`,`lengthAdjust`]),TSPAN:M([`x`,`y`,`dx`,`dy`,`rotate`,`textLength`,`lengthAdjust`]),IMAGE:M([`x`,`y`,`width`,`height`,`href`,`preserveAspectRatio`,`crossOrigin`]),USE:M([`x`,`y`,`width`,`height`,`href`]),DEFS:M([]),G:M([]),LINEARGRADIENT:M([`x1`,`y1`,`x2`,`y2`,`gradientUnits`,`gradientTransform`,`spreadMethod`]),RADIALGRADIENT:M([`cx`,`cy`,`r`,`fx`,`fy`,`fr`,`gradientUnits`,`gradientTransform`,`spreadMethod`]),STOP:M([`offset`]),PATTERN:M([`x`,`y`,`width`,`height`,`patternUnits`,`patternContentUnits`,`patternTransform`,`preserveAspectRatio`,`href`]),CLIPPATH:M([`clipPathUnits`]),MASK:M([`x`,`y`,`width`,`height`,`maskUnits`,`maskContentUnits`])};function st(e){let t=ot[e.tagName.toUpperCase()];if(t)return t(e);throw Error(`Unexpected HTML element tag: ${e.tagName} (update .web/custom/serialize.ts)`)}function ct(e){let t=ot[e.tagName.toUpperCase()];return t?t(e):j(e)}function N(e){return e instanceof HTMLElement?st(e):e instanceof SVGElement?ct(e):b(e)}const lt=e=>N(e.target),P=e=>e.relatedTarget?N(e.relatedTarget):null;function F(e,t){return v()(e,{target:lt,...t||{}})}const I=[`target`,`bubbles`,`cancelable`,`defaultPrevented`,`eventPhase`,`isTrusted`,`timeStamp`,`type`],L=[...I,`detail`],R=[...L,`altKey`,`button`,`buttons`,`clientX`,`clientY`,`ctrlKey`,`metaKey`,`movementX`,`movementY`,`pageX`,`pageY`,`screenX`,`screenY`,`shiftKey`],ut=[...R,`pointerId`,`pressure`,`tangentialPressure`,`tiltX`,`tiltY`,`twist`,`width`,`height`,`pointerType`,`isPrimary`],dt=F(I),ft=F(L),pt=F(R,{relatedTarget:P}),mt=F(I,{clipboardData:e=>B(e.clipboardData)}),ht=F([...I,`data`]),gt=F(R,{relatedTarget:P,dataTransfer:e=>B(e.dataTransfer)}),_t=F(ut,{relatedTarget:P}),vt=F(I,{relatedTarget:P}),yt=F(I),bt=F(I),xt=F(I),St=F([...L,`altKey`,`ctrlKey`,`code`,`key`,`locale`,`location`,`metaKey`,`repeat`,`shiftKey`]),Ct=F([...L,`altKey`,`ctrlKey`,`metaKey`,`shiftKey`,`changedTouches`,`targetTouches`,`touches`],{changedTouches:e=>z(e.changedTouches),targetTouches:e=>z(e.targetTouches),touches:e=>z(e.touches)}),wt=F([...R,`deltaMode`,`deltaX`,`deltaY`,`deltaZ`],{relatedTarget:P}),Tt=F([...I,`animationName`,`elapsedTime`,`pseudoElement`]),Et=F([...I,`oldState`,`newState`]),Dt=F([...I,`elapsedTime`,`propertyName`,`pseudoElement`]);function z(e){return Array.from(e).map(e=>({target:N(e.target),identifier:e.identifier,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY,pageX:e.pageX,pageY:e.pageY}))}function B(e){if(!e)return null;let t=[];if(e.items)for(let n=0;n<e.items.length;n++){let r=e.items[n];t.push({kind:r.kind,type:r.type})}return{drop_effect:e.dropEffect,effect_allowed:e.effectAllowed,items:t,types:Array.from(e.types||[])}}const V={};function H(e,t,n){for(let r of t)e[r]=n}H(V,[`pointerdown`,`pointermove`,`pointerup`,`pointercancel`,`gotpointercapture`,`lostpointercapture`,`pointerenter`,`pointerleave`,`pointerover`,`pointerout`],_t),H(V,[`click`,`contextmenu`,`dblclick`,`mousedown`,`mouseenter`,`mouseleave`,`mousemove`,`mouseout`,`mouseover`,`mouseup`],pt),H(V,[`drag`,`dragend`,`dragenter`,`dragexit`,`dragleave`,`dragover`,`dragstart`,`drop`],gt),H(V,[`keydown`,`keypress`,`keyup`],St),H(V,[`focus`,`blur`],vt),H(V,[`change`,`input`],xt),H(V,[`invalid`],bt),H(V,[`reset`,`submit`],yt),H(V,[`copy`,`cut`,`paste`],mt),H(V,[`compositionend`,`compositionstart`,`compositionupdate`],ht),H(V,[`touchcancel`,`touchend`,`touchmove`,`touchstart`],Ct),H(V,[`scroll`],ft),H(V,[`wheel`],wt),H(V,[`animationstart`,`animationend`,`animationiteration`],Tt),H(V,[`transitionend`],Dt),H(V,[`toggle`],Et);function U(e){if(e&&typeof e==`object`&&`nativeEvent`in e&&typeof e.isDefaultPrevented==`function`){let t=e;if(typeof t.type!=`string`)return e;let n=V[t.type.toLowerCase()];return n?n(t):dt(t)}return e}function W(e){let t=new Map,n=[],r=[],i=[],a=[],o=0;function s(e,c){if(e==null||typeof e==`string`||typeof e==`boolean`)return e;if(typeof e==`number`){if(Number.isNaN(e))return null;if(!Number.isFinite(e)){let t=e>0?`Infinity`:`-Infinity`,n=c?` in '${c}'`:``;throw Error(`Cannot serialize ${t}${n}. NaN and Infinity are not supported because they cannot be serialized to JSON.`)}return e}let l=o++,u=t.get(e);if(u!==void 0)return n.push(l),u;if(t.set(e,l),e instanceof Date)return r.push(l),e.toISOString();if(Array.isArray(e)){let t=e.length,n=Array(t);for(let r=0;r<t;r++)n[r]=s(e[r],c);return n}if(e instanceof Map){a.push(l);let t={};for(let[n,r]of e.entries())t[String(n)]=s(r,String(n));return t}if(e instanceof Set){i.push(l);let t=e.size,n=Array(t),r=0;for(let t of e)n[r]=s(t,c),r+=1;return n}if(typeof e==`object`){let t={},n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t[i]=s(e[i],i)}return t}throw Error(`Unsupported value in serialization: ${e}`)}let c=s(e);return[[n,r,i,a],c]}function G(e,t){let[[n,r,i,a],o]=e,s=new Set(n),c=new Set(r),l=new Set(i),u=new Set(a),d=[];function f(e){let n=d.length;if(s.has(n))return d.push(null),d[e];if(c.has(n)){if(typeof e!=`string`)throw Error(`Date payload must be an ISO string`);let t=kt(e);if(t){let[e,n,r]=t,i=new Date(Date.UTC(e,n-1,r));return d.push(i),i}if(K(e))throw Error(`Invalid date literal: ${e}`);let n=new Date(e);return d.push(n),n}if(e==null||typeof e==`number`||typeof e==`string`||typeof e==`boolean`)return t?.coerceNullsToUndefined?e??void 0:e;if(Array.isArray(e)){if(l.has(n)){let t=new Set;d.push(t);for(let n=0;n<e.length;n++)t.add(f(e[n]));return t}let t=e.length,r=Array(t);d.push(r);for(let n=0;n<t;n++)r[n]=f(e[n]);return r}if(typeof e==`object`){if(u.has(n)){let t=new Map;d.push(t);let n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t.set(i,f(e[i]))}return t}let t={};d.push(t);let r=Object.keys(e);for(let n=0;n<r.length;n++){let i=r[n];t[i]=f(e[i])}return t}throw Error(`Unsupported value in deserialization: ${e}`)}return f(o)}const Ot=/^\d{4}-\d{2}-\d{2}$/;function K(e){return Ot.test(e)}function kt(e){if(!K(e))return null;let[t,n,r]=e.split(`-`),i=Number(t),a=Number(n),o=Number(r);if(!Number.isInteger(i)||!Number.isInteger(a)||!Number.isInteger(o)||a<1||a>12||o<1||o>31)return null;let s=new Date(Date.UTC(i,a-1,o));return s.getUTCFullYear()!==i||s.getUTCMonth()!==a-1||s.getUTCDate()!==o?null:[i,a,o]}var At=class{#e;#t=null;#n;#r=new Set;#i=new Map;#a;#o;#s;#c;#l=!1;#u=null;#d=null;#f=`ok`;constructor(e,t,n,r){this.#a=e,this.#s=t,this.#o=n,this.#t=null,this.#e=new Map,this.#n=[],this.#c=r}setDirectives(e){this.#s=e}isConnected(){return this.#t?.connected??!1}#p(){this.#u&&=(clearTimeout(this.#u),null),this.#d&&=(clearTimeout(this.#d),null)}#m(e){this.#p(),this.#f=e,this.#v(e)}#h(){this.#l=!0,this.#m(`ok`)}#g(){this.#m(`ok`),this.#u=setTimeout(()=>{this.#m(`connecting`),this.#d=setTimeout(()=>{this.#m(`error`)},this.#c.initialErrorDelay)},this.#c.initialConnectingDelay)}#_(){this.#m(`reconnecting`),this.#d=setTimeout(()=>{this.#m(`error`)},this.#c.reconnectErrorDelay)}async connect(){if(!this.#t)return this.#l||this.#g(),new Promise((e,t)=>{let n=h(this.#a,{transports:[`websocket`,`webtransport`],auth:this.#s.socketio?.auth,extraHeaders:this.#s.socketio?.headers});this.#t=n,n.on(`connect`,()=>{console.log(`[SocketIOTransport] Connected:`,this.#t?.id);for(let[e,t]of this.#e)n.emit(`message`,W({type:`attach`,path:e,routeInfo:t.routeInfo}));for(let e of this.#n)e.type===`attach`&&this.#e.has(e.path)||e.type!==`update`&&n.emit(`message`,W(e));this.#n=[],this.#h(),e()}),n.on(`connect_error`,e=>{console.error(`[SocketIOTransport] Connection failed:`,e),this.#_(),t(e)}),n.on(`disconnect`,()=>{console.log(`[SocketIOTransport] Disconnected`),this.#T(),this.#_()}),n.on(`message`,e=>this.#y(G(e,{coerceNullsToUndefined:!0})))})}onConnectionChange(e){return this.#r.add(e),e(this.#f),()=>{this.#r.delete(e)}}#v(e){for(let t of this.#r)t(e)}sendMessage(e){this.isConnected()?this.#t.emit(`message`,W(e)):this.#n.push(e)}attach(e,t){if(this.#e.has(e))throw Error(`Path ${e} is already attached`);this.#e.set(e,t),this.sendMessage({type:`attach`,path:e,routeInfo:t.routeInfo})}updateRoute(e,t){let n=this.#e.get(e);n&&(n.routeInfo=t,this.sendMessage({type:`update`,path:e,routeInfo:t}))}detach(e){this.sendMessage({type:`detach`,path:e}),this.#e.delete(e)}disconnect(){this.#p(),this.#t?.disconnect(),this.#t=null,this.#n=[],this.#r.clear(),this.#e.clear();for(let{bridge:e}of this.#i.values())e.dispose(new $(`Client disconnected`));this.#i.clear(),this.#f=`ok`,this.#l=!1}#y(e){switch(e.type){case`vdom_init`:{let t=this.#e.get(e.path);if(!t)return;t.onInit(e);break}case`vdom_update`:{let t=this.#e.get(e.path);if(!t)return;t.onUpdate(e.ops);break}case`server_error`:{let t=this.#e.get(e.path);if(!t)return;t.onServerError(e.error);break}case`api_call`:this.#b(e);break;case`navigate_to`:{let t=!!e.replace,n=e.path||``;n.startsWith(`//`)&&(n=`${window.location.protocol}${n}`);let r=()=>t?window.location.replace(n):window.location.assign(n);if(e.hard){r();break}if(!/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(n)){this.#o(n,{replace:t});break}if(/^https?:\/\//.test(n))try{let e=new URL(n);if(e.origin===window.location.origin){this.#o(`${e.pathname}${e.search}${e.hash}`,{replace:t});break}}catch{}r();break}case`reload`:window.location.reload();break;case`channel_message`:this.#w(e);break;case`js_exec`:this.#x(e);break;default:console.error(`Unexpected message:`,e)}}async#b(e){try{let t=await fetch(e.url,{method:e.method||`GET`,headers:{...e.headers||{},...e.body!=null&&!(`content-type`in(e.headers||{}))?{"content-type":`application/json`}:{}},body:e.body==null?void 0:typeof e.body==`string`?e.body:JSON.stringify(e.body),credentials:e.credentials||`include`}),n={};t.headers.forEach((e,t)=>{n[t]=e});let r=null;r=(t.headers.get(`content-type`)||``).includes(`application/json`)?await t.json().catch(()=>null):await t.text().catch(()=>null);let i={type:`api_result`,id:e.id,ok:t.ok,status:t.status,headers:n,body:r};this.sendMessage(i)}catch(t){let n={type:`api_result`,id:e.id,ok:!1,status:0,headers:{},body:{error:String(t)}};this.sendMessage(n)}}invokeCallback(e,t,n){this.sendMessage({type:`callback`,path:e,callback:t,args:n.map(U)})}#x(e){let t=this.#e.get(e.path);if(!t){this.#S(e.id,void 0,null);return}t.onJsExec(e)}sendJsResult(e,t,n){this.#S(e,t,n)}#S(e,t,n){let r={type:`js_result`,id:e,result:t,error:n};this.sendMessage(r)}acquireChannel(e){let t=this.#C(e);return t.refCount+=1,t.bridge}releaseChannel(e){let t=this.#i.get(e);t&&(t.refCount=Math.max(0,t.refCount-1),t.refCount===0&&(t.bridge.dispose(new $(`Channel released`)),this.sendMessage({type:`channel_message`,channel:e,event:`__close__`,payload:{reason:`refcount_zero`}}),this.#i.delete(e)))}#C(e){let t=this.#i.get(e);return t||(t={bridge:new Vt(this,e),refCount:0},this.#i.set(e,t)),t}#w(e){let t=this.#C(e.channel);t.bridge.handleServerMessage(e)&&t.refCount===0&&this.#i.delete(e.channel)}#T(){for(let e of this.#i.values())e.bridge.handleDisconnect(new $(`Connection lost`))}};function jt(e){return typeof e==`object`&&!!e&&`tag`in e}function q(e){return typeof e==`object`&&!!e&&`t`in e}function J(e){if(e===`$cb`)return null;if(typeof e!=`string`||!e.startsWith(`$cb:`))return;let t=e.slice(4);if(t.length===0)throw Error(`[Pulse] Invalid callback placeholder: '$cb:'`);let n=Number(t);if(!Number.isFinite(n)||n<0)throw Error(`[Pulse] Invalid callback debounce delay: ${e}`);return n}var Y=class{#e;#t;#n;#r;#i;constructor(e,t,n={}){this.#e=e,this.#t=t,this.#n=n,this.#r=new Set,this.#i=new WeakMap}getObject(e){let t=this.#n[e];if(t===void 0)throw Error(`[Pulse] Unknown registry key: ${e}`);return t}#a(e){let t=globalThis[e];if(t===void 0)throw Error(`[Pulse] Unknown identifier in expr: ${e}`);return t}#o(e,t){if(typeof e!=`object`||!e)return e;if(`tag`in e)return this.renderNode(e,``);switch(e.t){case`ref`:return this.getObject(e.key);case`id`:return Object.hasOwn(t,e.name)?t[e.name]:this.#a(e.name);case`lit`:return e.value;case`undef`:return;case`array`:{let n=[];for(let r of e.items)n.push(this.#o(r,t));return n}case`object`:{let n={};for(let[r,i]of Object.entries(e.props))n[r]=this.#o(i,t);return n}case`member`:return this.#o(e.obj,t)?.[e.prop];case`sub`:{let n=this.#o(e.obj,t),r=this.#o(e.key,t);return n?.[r]}case`call`:{let n=this.#o(e.callee,t),r=e.args.map(e=>this.#o(e,t));if(typeof n!=`function`)throw Error(`[Pulse] call callee is not a function`);return n(...r)}case`unary`:{let n=this.#o(e.arg,t);switch(e.op){case`!`:return!n;case`+`:return+n;case`-`:return-n;case`typeof`:return typeof n;case`void`:return;default:throw Error(`[Pulse] Unsupported unary op: ${e.op}`)}}case`binary`:{let n=this.#o(e.left,t),r=this.#o(e.right,t);switch(e.op){case`+`:return n+r;case`-`:return n-r;case`*`:return n*r;case`/`:return n/r;case`%`:return n%r;case`&&`:return n&&r;case`||`:return n||r;case`??`:return n??r;case`**`:return n**r;case`in`:return n in r;case`instanceof`:return n instanceof r;case`===`:return n===r;case`!==`:return n!==r;case`<`:return n<r;case`<=`:return n<=r;case`>`:return n>r;case`>=`:return n>=r;default:throw Error(`[Pulse] Unsupported binary op: ${e.op}`)}}case`ternary`:return this.#o(e.cond,t)?this.#o(e.then,t):this.#o(e.else_,t);case`template`:{let n=``;for(let r of e.parts)typeof r==`string`?n+=r:n+=String(this.#o(r,t));return n}case`arrow`:{let n=e.params;return(...r)=>{let i={...t};for(let e=0;e<n.length;e+=1)i[n[e]]=r[e];return this.#o(e.body,i)}}case`new`:return new(this.#o(e.ctor,t))(...e.args.map(e=>this.#o(e,t)));default:throw Error(`[Pulse] Unknown expr node: ${e.t}`)}}#s(e,t){return e?`${e}.${t}`:t}#c(e){e.timer&&clearTimeout(e.timer),e.timer=null,e.lastArgs=null,e.dueAt=null}#l(e,t){let n=e.lastArgs;this.#c(e),n&&t(n)}#u(e,t,n,r){e.timer&&clearTimeout(e.timer),e.lastArgs=n,e.dueAt=Date.now()+t,e.timer=setTimeout(()=>{this.#l(e,r)},t)}#d(e,t){let n=e.callbacks;if(!n)return;let r=n.get(t);r&&(this.#c(r),this.#r.delete(r),n.delete(t),n.size===0&&(e.callbacks=void 0))}#f(e,t){e.callbacks||=new Map;let n=e.callbacks,r=n.get(t);if(!r){let i=n=>{let r=this.#s(e.path??``,t);this.#e.invokeCallback(this.#t,r,n)};r={fn:(...e)=>{if(r.delayMs==null){i(e);return}let t=e.map(U);this.#u(r,r.delayMs,t,i)},delayMs:null,timer:null,lastArgs:null,dueAt:null},n.set(t,r),this.#r.add(r)}return r}#p(e,t){if(e==null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`)return;if(Array.isArray(e)){for(let n=0;n<e.length;n+=1){let r=t?`${t}.${n}`:String(n);this.#p(e[n],r)}return}if(!a(e))return;let n=e,r=this.#i.get(n),i=r?.path??t,o=r?.callbacks;if(o&&o.size>0){for(let e of o.values())this.#c(e),this.#r.delete(e);o.clear(),r.callbacks=void 0}let s=n.props??{};for(let e of Object.keys(s)){if(e===`children`)continue;let t=s[e];this.#p(t,this.#s(i,e))}let c=this.#_(n);for(let e=0;e<c.length;e+=1){let t=i?`${i}.${e}`:String(e);this.#p(c[e],t)}}#m(e,t,n){let r=this.#f(e,t);return r.delayMs!==n&&(r.delayMs=n),r.fn}#h(e,t,n,r){let i=J(r);return i===void 0?q(r)?this.#o(r,{}):typeof r==`object`&&r&&`tag`in r?this.renderNode(r,this.#s(e,n)):r:this.#m(t,n,i)}#g(e,t){return this.#i.set(e,t),e}clearPendingCallbacks(){for(let e of Array.from(this.#r))this.#c(e)}renderNode(t,n=``){if(t==null||typeof t==`boolean`||typeof t==`number`||typeof t==`string`)return t;if(q(t))return this.#o(t,{});if(jt(t)){let{tag:i,props:a={},children:o=[],eval:s}=t,c;if(typeof i==`string`)if(i.startsWith(`$$`)){let e=i.slice(2);if(c=this.#n[e],!c)throw Error(`[Pulse] Missing component '${e}'`)}else c=i.length>0?i:e;else c=this.#o(i,{});let l={},u,d={path:n};if(s){u=new Set(s),d.eval=u;for(let[e,t]of Object.entries(a)){if(!u.has(e)){l[e]=t;continue}l[e]=this.#h(n,d,e,t)}}else for(let[e,t]of Object.entries(a))l[e]=t;t.key&&(l.key=t.key);let f=[];for(let e=0;e<o.length;e+=1){let t=o[e],r=n?`${n}.${e}`:String(e);f.push(this.renderNode(t,r))}try{return this.#g(r(c,l,...f),d)}catch(e){throw console.error(`[Pulse] Failed to create element:`,t),e}}return process.env.NODE_ENV!==`production`&&console.error(`Unknown VDOM node:`,t),null}init(e){return this.renderNode(e.vdom)}evaluateExpr(e){return this.#o(e,{})}#_(e){let t=e.props?.children;return t==null?[]:Array.isArray(t)?t.slice():[t]}#v(e,t){let n=this.#i.get(e);return n&&this.#i.set(t,n),t}#y(e,t){if(e==null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`)return e;if(Array.isArray(e)){for(let n=0;n<e.length;n+=1){let r=t?`${t}.${n}`:String(n);this.#y(e[n],r)}return e}if(!a(e))return e;let n=e,r=this.#i.get(n);r?r.path=t:this.#i.set(n,{path:t});let i=n.props??{};for(let e of Object.keys(i)){if(e===`children`)continue;let n=i[e];this.#y(n,this.#s(t,e))}let o=this.#_(n);for(let e=0;e<o.length;e+=1){let n=t?`${t}.${e}`:String(e);this.#y(o[e],n)}return e}applyUpdates(e,n){let i=e;for(let e of n){let n=e.path.split(`.`).filter(e=>e.length>0),a=(i,o,s)=>{if(o<n.length){this.#b(i,n,o);let e=i,r=n[o],c=+r,l=s?`${s}.${r}`:r;if(Number.isNaN(c)){let n=e.props??{},i=n[r],s={...n,[r]:a(i,o+1,l)};return this.#v(e,t(e,s))}else{let n=this.#_(e),r=n[c];return n[c]=a(r,o+1,l),this.#v(e,t(e,void 0,...n))}}switch(e.type){case`replace`:return this.#p(i,s),this.renderNode(e.data,e.path);case`update_props`:{this.#b(i,n,o);let a=i,c=a.props??{},l={...c},u=this.#i.get(a),d=u??{},f=d.eval,p=u?.path??s,m=e.data.eval,h=m===void 0?f:m.length===0?void 0:new Set(m),g=m!==void 0&&m.length===0;if(h&&d.callbacks)for(let e of Array.from(d.callbacks.keys()))h.has(e)||this.#d(d,e);if(g&&d.callbacks)for(let e of Array.from(d.callbacks.keys()))delete l[e],this.#d(d,e);if(e.data.remove&&e.data.remove.length>0)for(let t of e.data.remove){let e=c[t];e!==void 0&&this.#p(e,this.#s(p,t)),delete l[t],d.callbacks?.has(t)&&this.#d(d,t)}if(e.data.set)for(let[t,n]of Object.entries(e.data.set)){let e=c[t];e!==void 0&&this.#p(e,this.#s(p,t));let r=h?.has(t)===!0,i=r?J(n):void 0;l[t]=r?this.#h(s,d,t,n):n,i===void 0&&d.callbacks?.has(t)&&this.#d(d,t)}return d.eval=h,d.path=s,(e.data.remove?.length??0)>0?(l.key=a.key,l.ref=a.ref,this.#g(r(a.type,l,...this.#_(a)),d)):this.#g(t(a,l),d)}case`reconciliation`:{this.#b(i,n,o);let r=i,a=this.#_(r),c=[],[l,u]=e.new,[d,f]=e.reuse,p=new Set(l),m=new Set(d),h=new Set(f);for(let t=0;t<a.length;t+=1)if(!(h.has(t)||t<e.N&&!p.has(t)&&!m.has(t))){let e=s?`${s}.${t}`:String(t);this.#p(a[t],e)}let g=-1,_=-1,v=-1,y=-1;l.length>0&&(g=l[0],v=0),d.length>0&&(_=d[0],y=0);for(let t=0;t<e.N;t+=1)if(t===g){let e=u[v],n=s?`${s}.${t}`:String(t);c.push(this.renderNode(e,n)),g=v<l.length-1?l[++v]:-1}else if(t===_){let e=a[f[y]],n=s?`${s}.${t}`:String(t);e=this.#y(e,n),c.push(e),_=y<d.length-1?d[++y]:-1}else c.push(a[t]);return c.length===0&&c.push(null),this.#v(r,t(r,null,...c))}default:throw Error(`[Pulse renderer] Unknown update type: ${e?.type}`)}};i=a(i,0,``)}return i}#b(e,t,n){if(process.env.NODE_ENV!==`production`&&!a(e))throw console.error(`Invalid node:`,e),Error(`Invalid node at path ${t.slice(0,n).join(`.`)}`);return!0}};const X=n(null),Mt=n(null),Z=()=>{let e=s(X);if(!e)throw Error(`usePulseClient must be used within a PulseProvider`);return e},Nt=e=>{let t=s(Mt);if(!t)throw Error(`usePulsePrerender must be used within a PulseProvider`);let n=t.views[e];if(!n)throw Error(`No prerender found for '${e}'`);return n},Q=typeof window<`u`;function Pt({children:e,config:t,prerender:n}){let[r,i]=d(`ok`),a=p(),{directives:o}=n,s=l(()=>new At(t.serverAddress,o,a,t.connectionStatus),[t.serverAddress,a,t.connectionStatus]);c(()=>s.setDirectives(o),[s,o]),c(()=>{if(!Q)return;let e=s.onConnectionChange(e=>{i(e)});return s.connect(),()=>{e(),s.disconnect()}},[s]);let u=(()=>{switch(r){case`connecting`:return`Connecting...`;case`reconnecting`:return`Reconnecting...`;case`error`:return`Failed to connect to the server.`;default:return null}})();return g(X.Provider,{value:s,children:_(Mt.Provider,{value:n,children:[u&&g(`div`,{style:{position:`fixed`,bottom:`20px`,right:`20px`,backgroundColor:r===`error`?`red`:`#666`,color:`white`,padding:`10px`,borderRadius:`5px`,zIndex:1e3},children:u}),e]})})}function Ft({path:e,registry:t}){let n=Z(),r=Nt(e),i=l(()=>new Y(n,e,t),[n,e,t]),[a,o]=d(()=>i.init(r)),[s,p]=d(null),h=f(),_=m(),v=l(()=>{let{"*":e=``,...t}=_,n=new URLSearchParams(h.search),r=h.search.startsWith(`?`)?h.search.slice(1):h.search;return{hash:h.hash.startsWith(`#`)?h.hash.slice(1):h.hash,pathname:h.pathname,query:r,queryParams:Object.fromEntries(n.entries()),pathParams:t,catchall:e.length>0?e.split(`/`):[]}},[h.hash,h.pathname,h.search,JSON.stringify(_)]);c(()=>{if(Q)return n.attach(e,{routeInfo:v,onInit:e=>{o(i.init(e)),p(null)},onUpdate:e=>{o(t=>t==null?t:i.applyUpdates(t,e)),p(null)},onJsExec:e=>{let t,r=null;try{t=i.evaluateExpr(e.expr)}catch(e){r=e instanceof Error?e.message:String(e)}n.sendJsResult(e.id,t,r)},onServerError:p}),()=>{i.clearPendingCallbacks(),n.detach(e)}},[n,i,e]),c(()=>{Q&&n.updateRoute(e,v)},[n,e,v]);let y=u(!1);return c(()=>{y.current?o(i.init(r)):y.current=!0},[r,i]),s?g(It,{error:s}):a}function It({error:e}){return _(`div`,{style:{padding:16,border:`1px solid #e00`,background:`#fff5f5`,color:`#900`,fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace`,whiteSpace:`pre-wrap`},children:[_(`div`,{style:{fontWeight:700,marginBottom:8},children:[`Server Error during `,e.phase]}),e.message&&g(`div`,{children:e.message}),e.stack&&_(`details`,{open:!0,style:{marginTop:8},children:[g(`summary`,{children:`Stack trace`}),g(`pre`,{style:{margin:0},children:e.stack})]})]})}var $=class extends Error{constructor(e){super(e),this.name=`PulseChannelResetError`}};function Lt(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID().replace(/-/g,``):Math.random().toString(16).slice(2)+Math.random().toString(16).slice(2)}function Rt(e){if(e instanceof Error)return e.message;if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}function zt(e){return typeof e.responseTo==`string`}function Bt(e){return typeof e.event==`string`}var Vt=class{handlers=new Map;pending=new Map;backlog=[];closed=!1;constructor(e,t){this.client=e,this.id=t}emit(e,t){this.ensureOpen(),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t})}request(e,t){this.ensureOpen();let n=Lt();return new Promise((r,i)=>{this.pending.set(n,{resolve:r,reject:i}),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t,requestId:n})})}on(e,t){this.ensureOpen();let n=this.handlers.get(e);return n||(n=new Set,this.handlers.set(e,n)),n.add(t),this.flushBacklog(e),()=>{let n=this.handlers.get(e);n&&(n.delete(t),n.size===0&&this.handlers.delete(e))}}handleServerMessage(e){return zt(e)?(this.resolvePending(e),this.closed):this.closed?!0:Bt(e)?e.event===`__close__`?(this.close(new $(`Channel closed by server`)),!0):(e.requestId?this.dispatchRequest(e):this.dispatchEvent(e),this.closed):this.closed}handleDisconnect(e){this.close(e)}dispose(e){this.close(e)}ensureOpen(){if(this.closed)throw new $(`Channel is closed`)}flushBacklog(e){if(this.backlog.length===0)return;let t=[];for(let n of this.backlog)n.event===e?this.dispatchEvent(n):t.push(n);this.backlog=t}dispatchEvent(e){let t=this.handlers.get(e.event);if(!t||t.size===0){this.backlog.push(e);return}for(let n of t)try{let t=n(e.payload);t&&typeof t.then==`function`&&t.catch(e=>{console.error(`Pulse channel handler error`,e)})}catch(e){console.error(`Pulse channel handler error`,e)}}async dispatchRequest(e){let t=this.handlers.get(e.event),n,r;if(t&&t.size>0)for(let i of t)try{let t=i(e.payload);if(n=await Promise.resolve(t),n!==void 0)break}catch(e){r=e;break}if(r){this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,error:Rt(r)});return}this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,payload:n})}resolvePending(e){let t=e.responseTo?this.pending.get(e.responseTo):void 0;t&&(this.pending.delete(e.responseTo),e.error!==void 0&&e.error!==null?t.reject(new $(String(e.error))):t.resolve(e.payload))}close(e){if(!this.closed){this.closed=!0;for(let t of this.pending.values())t.reject(e);this.pending.clear(),this.handlers.clear(),this.backlog=[]}}};function Ht(e){let t=Z(),n=l(()=>{if(!e)throw Error(`usePulseChannel requires a non-empty channelId`);return t.acquireChannel(e)},[t,e]);return c(()=>()=>{t.releaseChannel(e)},[t,e]),n}const Ut=i(function({onSubmit:e,action:t,...n},r){return g(`form`,{...n,action:t,ref:r,onSubmit:o(n=>Wt({event:n,action:t,onSubmit:e}),[t,e])})});async function Wt({event:e,action:t,onSubmit:n,formData:r,force:i}){if(n?.(e),!i&&e.defaultPrevented)return;let a=e.currentTarget;e.preventDefault();let o=e.nativeEvent;r||=new FormData(a,o.submitter);let s=new URL(t,window.location.href);try{await fetch(s,{method:`POST`,credentials:`include`,body:r})}catch(e){if(process.env.NODE_ENV!==`production`)console.error(`[Pulse] Form submission failed`,e);else throw e}}function Gt({params:e,request:t}){let{"*":n=``,...r}=e,i=new URL(t.url),a=i.search.startsWith(`?`)?i.search.slice(1):i.search;return{hash:i.hash.startsWith(`#`)?i.hash.slice(1):i.hash,pathname:i.pathname,query:a,queryParams:Object.fromEntries(i.searchParams.entries()),pathParams:r,catchall:n.length>1?n.split(`/`):[]}}export{$ as PulseChannelResetError,Ut as PulseForm,Pt as PulseProvider,Ft as PulseView,Y as VDOMRenderer,G as deserialize,Gt as extractServerRouteInfo,W as serialize,Wt as submitForm,Ht as usePulseChannel,Z as usePulseClient};
|
|
1
|
+
import{Fragment as e,cloneElement as t,createContext as n,createElement as r,forwardRef as i,isValidElement as a,useCallback as o,useContext as s,useEffect as c,useMemo as l,useRef as u,useState as d}from"react";import{useLocation as f,useNavigate as p,useParams as m}from"react-router";import{io as h}from"socket.io-client";import{jsx as g,jsxs as _}from"react/jsx-runtime";function v(){function e(e,t){return n=>{let r={};for(let t of e)r[t]=n[t];if(t)for(let e in t){let i=t[e];r[e]=i(n)}return r}}return e}const y=e=>e.tagName.toLowerCase(),b=[`id`,`className`,`tagName`,`localName`,`clientHeight`,`clientLeft`,`clientTop`,`clientWidth`,`scrollHeight`,`scrollLeft`,`scrollTop`,`scrollWidth`,`slot`],x=[`autofocus`,`tabIndex`,`nonce`],ee=[`accessKey`,`accessKeyLabel`,`autocapitalize`,`dir`,`draggable`,`hidden`,`inert`,`lang`,`offsetHeight`,`offsetLeft`,`offsetTop`,`offsetWidth`,`popover`,`spellcheck`,`title`,`translate`,`writingSuggestions`,`contentEditable`,`enterKeyHint`,`isContentEditable`,`inputMode`],S=v()(b,{tagName:y}),te=v()(x),ne=v()(ee);function C(e){return{...S(e),...te(e),...ne(e)}}function w(e,t){let n=v()(e,t);return e=>({...C(e),...n(e)})}const re=w([`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`search`,`target`,`download`,`rel`,`hreflang`,`type`,`username`,`ping`,`referrerPolicy`,`text`]),ie=w([`alt`,`coords`,`download`,`hash`,`host`,`hostname`,`href`,`origin`,`password`,`pathname`,`port`,`protocol`,`rel`,`search`,`shape`,`target`,`username`,`ping`,`referrerPolicy`]),T=w([`autoplay`,`controls`,`crossOrigin`,`currentSrc`,`currentTime`,`defaultMuted`,`defaultPlaybackRate`,`duration`,`ended`,`loop`,`muted`,`networkState`,`paused`,`playbackRate`,`preload`,`readyState`,`seeking`,`src`,`volume`,`preservesPitch`]),ae=e=>T(e),oe=w([`disabled`,`name`,`type`,`value`,`formAction`,`formEnctype`,`formMethod`,`formNoValidate`,`formTarget`,`popoverTargetAction`]),se=w([`value`]),ce=w([`height`,`src`,`type`,`width`,`align`,`name`]),le=w([`disabled`,`name`,`type`,`validationMessage`,`willValidate`]),ue=w([`acceptCharset`,`action`,`autocomplete`,`encoding`,`enctype`,`length`,`method`,`name`,`noValidate`,`target`,`rel`]),de=w([`allow`,`allowFullscreen`,`height`,`name`,`referrerPolicy`,`src`,`srcdoc`,`width`,`align`,`frameBorder`,`longDesc`,`marginHeight`,`marginWidth`,`scrolling`,`sandbox`]),fe=w([`alt`,`crossOrigin`,`decoding`,`height`,`isMap`,`loading`,`naturalHeight`,`naturalWidth`,`referrerPolicy`,`sizes`,`src`,`srcset`,`useMap`,`width`,`align`,`border`,`complete`,`hspace`,`longDesc`,`lowsrc`,`name`,`vspace`,`x`,`y`,`fetchPriority`]),pe=w(`accept.alt.autocomplete.checked.defaultChecked.defaultValue.dirName.disabled.height.indeterminate.max.maxLength.min.minLength.multiple.name.pattern.placeholder.readOnly.required.selectionDirection.selectionEnd.selectionStart.size.src.step.type.value.valueAsNumber.width.align.capture.formAction.formEnctype.formMethod.formNoValidate.formTarget.useMap.validationMessage.willValidate.popoverTargetAction`.split(`.`),{valueAsNumber:e=>{let t=e.valueAsNumber;return Number.isFinite(t)?t:null}}),me=w([`htmlFor`]),he=w([`value`,`type`]),ge=w([`as`,`crossOrigin`,`disabled`,`fetchPriority`,`href`,`hreflang`,`imageSizes`,`imageSrcset`,`integrity`,`media`,`referrerPolicy`,`rel`,`type`,`charset`,`rev`,`target`,`sizes`]),_e=w([`name`]),ve=w([`high`,`low`,`max`,`min`,`optimum`,`value`]),E=w([`cite`,`dateTime`]),ye=w([`reversed`,`start`,`type`,`compact`]),be=w([`data`,`height`,`name`,`type`,`useMap`,`width`,`validationMessage`,`willValidate`,`align`,`archive`,`border`,`code`,`codeBase`,`codeType`,`declare`,`hspace`,`standby`,`vspace`]),xe=w([`disabled`,`label`]),Se=w([`defaultSelected`,`disabled`,`index`,`label`,`selected`,`text`,`value`]),Ce=w([`defaultValue`,`name`,`type`,`value`,`htmlFor`,`validationMessage`,`willValidate`]),we=w([`max`,`position`,`value`]),Te=w([`cite`]),Ee=e=>C(e),De=v()([`async`,`crossOrigin`,`defer`,`fetchPriority`,`integrity`,`noModule`,`referrerPolicy`,`src`,`text`,`type`,`charset`],{event:e=>e.event,htmlFor:e=>e.htmlFor}),Oe=e=>({...C(e),...De(e)}),ke=w([`autocomplete`,`disabled`,`length`,`multiple`,`name`,`required`,`selectedIndex`,`size`,`type`,`value`,`validationMessage`,`willValidate`]),Ae=w([`name`]),je=w([`height`,`media`,`sizes`,`src`,`srcset`,`type`,`width`]),Me=w([`align`]),D=w([`abbr`,`cellIndex`,`colSpan`,`headers`,`rowSpan`,`scope`,`align`,`axis`,`bgColor`,`ch`,`chOff`,`height`,`noWrap`,`vAlign`,`width`]),O=w([`span`,`align`,`ch`,`chOff`,`vAlign`,`width`]),Ne=w([`align`,`bgColor`,`border`,`cellPadding`,`cellSpacing`,`frame`,`rules`,`summary`,`width`]),Pe=w([`rowIndex`,`sectionRowIndex`,`align`,`bgColor`,`ch`,`chOff`,`vAlign`]),k=w([`align`,`ch`,`chOff`,`vAlign`]),Fe=e=>C(e),Ie=w([`autocomplete`,`cols`,`defaultValue`,`dirName`,`disabled`,`maxLength`,`minLength`,`name`,`placeholder`,`readOnly`,`required`,`rows`,`selectionDirection`,`selectionEnd`,`selectionStart`,`value`,`wrap`,`textLength`,`validationMessage`,`willValidate`]),Le=w([`dateTime`]),Re=w([`default`,`kind`,`label`,`readyState`,`src`,`srclang`]),ze=v()([`height`,`poster`,`videoHeight`,`videoWidth`,`width`,`playsInline`]),Be=e=>({...T(e),...ze(e)}),Ve=w([`clear`]),He=w([`href`,`target`]),Ue=w([`aLink`,`background`,`bgColor`,`link`,`text`,`vLink`]),We=w([`compact`]),Ge=w([`open`]),Ke=w([`open`,`returnValue`]),qe=w([`align`]),Je=e=>C(e),A=w([`align`]),Ye=w([`align`,`color`,`noShade`,`size`,`width`]),Xe=w([`version`]),Ze=e=>C(e),Qe=w([`content`,`httpEquiv`,`name`,`scheme`]),$e=w([`align`]),et=e=>C(e),tt=w([`width`]),nt=e=>C(e),rt=w([`media`,`type`,`disabled`]),it=w([`text`]),at=w([`compact`,`type`]);function j(e){return{...S(e),...te(e)}}function M(e,t){let n=v()(e,t);return e=>({...j(e),...n(e)})}const N={A:re,AREA:ie,AUDIO:ae,BASE:He,BLOCKQUOTE:Te,Q:Te,BODY:Ue,BR:Ve,BUTTON:oe,CANVAS:C,CAPTION:Me,CITE:Ee,COL:O,COLGROUP:O,DATA:se,DETAILS:Ge,DIALOG:Ke,DIV:qe,DL:We,EMBED:ce,FIELDSET:le,FORM:ue,H1:A,H2:A,H3:A,H4:A,H5:A,H6:A,HEAD:Je,HR:Ye,HTML:Xe,IFRAME:de,IMG:fe,INPUT:pe,LABEL:me,LI:he,LINK:ge,MAP:_e,MENU:Ze,META:Qe,METER:ve,INS:E,DEL:E,OBJECT:be,OL:ye,OPTGROUP:xe,OPTION:Se,OUTPUT:Ce,P:$e,PICTURE:et,PRE:tt,PROGRESS:we,SCRIPT:Oe,SELECT:ke,SLOT:Ae,SOURCE:je,SPAN:nt,STYLE:rt,TABLE:Ne,TBODY:k,THEAD:k,TFOOT:k,TD:D,TH:D,TEMPLATE:Fe,TEXTAREA:Ie,TIME:Le,TITLE:it,TR:Pe,TRACK:Re,UL:at,VIDEO:Be,SVG:M([`x`,`y`,`width`,`height`,`currentScale`,`currentTranslate`]),CIRCLE:M([`cx`,`cy`,`r`]),ELLIPSE:M([`cx`,`cy`,`rx`,`ry`]),LINE:M([`x1`,`y1`,`x2`,`y2`]),PATH:M([`pathLength`]),RECT:M([`x`,`y`,`width`,`height`,`rx`,`ry`]),POLYGON:M([`points`]),POLYLINE:M([`points`]),TEXT:M([`x`,`y`,`dx`,`dy`,`rotate`,`textLength`,`lengthAdjust`]),TSPAN:M([`x`,`y`,`dx`,`dy`,`rotate`,`textLength`,`lengthAdjust`]),IMAGE:M([`x`,`y`,`width`,`height`,`href`,`preserveAspectRatio`,`crossOrigin`]),USE:M([`x`,`y`,`width`,`height`,`href`]),DEFS:M([]),G:M([]),LINEARGRADIENT:M([`x1`,`y1`,`x2`,`y2`,`gradientUnits`,`gradientTransform`,`spreadMethod`]),RADIALGRADIENT:M([`cx`,`cy`,`r`,`fx`,`fy`,`fr`,`gradientUnits`,`gradientTransform`,`spreadMethod`]),STOP:M([`offset`]),PATTERN:M([`x`,`y`,`width`,`height`,`patternUnits`,`patternContentUnits`,`patternTransform`,`preserveAspectRatio`,`href`]),CLIPPATH:M([`clipPathUnits`]),MASK:M([`x`,`y`,`width`,`height`,`maskUnits`,`maskContentUnits`])};function ot(e){let t=N[e.tagName.toUpperCase()];if(t)return t(e);throw Error(`Unexpected HTML element tag: ${e.tagName} (update .web/custom/serialize.ts)`)}function st(e){let t=N[e.tagName.toUpperCase()];return t?t(e):j(e)}function P(e){return e instanceof HTMLElement?ot(e):e instanceof SVGElement?st(e):S(e)}const ct=e=>P(e.target),F=e=>e.relatedTarget?P(e.relatedTarget):null;function I(e,t){return v()(e,{target:ct,...t||{}})}const L=[`target`,`bubbles`,`cancelable`,`defaultPrevented`,`eventPhase`,`isTrusted`,`timeStamp`,`type`],R=[...L,`detail`],z=[...R,`altKey`,`button`,`buttons`,`clientX`,`clientY`,`ctrlKey`,`metaKey`,`movementX`,`movementY`,`pageX`,`pageY`,`screenX`,`screenY`,`shiftKey`],lt=[...z,`pointerId`,`pressure`,`tangentialPressure`,`tiltX`,`tiltY`,`twist`,`width`,`height`,`pointerType`,`isPrimary`],ut=I(L),dt=I(R),ft=I(z,{relatedTarget:F}),pt=I(L,{clipboardData:e=>V(e.clipboardData)}),mt=I([...L,`data`]),ht=I(z,{relatedTarget:F,dataTransfer:e=>V(e.dataTransfer)}),gt=I(lt,{relatedTarget:F}),_t=I(L,{relatedTarget:F}),vt=I(L),yt=I(L),bt=I(L),xt=I([...R,`altKey`,`ctrlKey`,`code`,`key`,`locale`,`location`,`metaKey`,`repeat`,`shiftKey`]),St=I([...R,`altKey`,`ctrlKey`,`metaKey`,`shiftKey`,`changedTouches`,`targetTouches`,`touches`],{changedTouches:e=>B(e.changedTouches),targetTouches:e=>B(e.targetTouches),touches:e=>B(e.touches)}),Ct=I([...z,`deltaMode`,`deltaX`,`deltaY`,`deltaZ`],{relatedTarget:F}),wt=I([...L,`animationName`,`elapsedTime`,`pseudoElement`]),Tt=I([...L,`oldState`,`newState`]),Et=I([...L,`elapsedTime`,`propertyName`,`pseudoElement`]);function B(e){return Array.from(e).map(e=>({target:P(e.target),identifier:e.identifier,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY,pageX:e.pageX,pageY:e.pageY}))}function V(e){if(!e)return null;let t=[];if(e.items)for(let n=0;n<e.items.length;n++){let r=e.items[n];t.push({kind:r.kind,type:r.type})}return{drop_effect:e.dropEffect,effect_allowed:e.effectAllowed,items:t,types:Array.from(e.types||[])}}const H={};function U(e,t,n){for(let r of t)e[r]=n}U(H,[`pointerdown`,`pointermove`,`pointerup`,`pointercancel`,`gotpointercapture`,`lostpointercapture`,`pointerenter`,`pointerleave`,`pointerover`,`pointerout`],gt),U(H,[`click`,`contextmenu`,`dblclick`,`mousedown`,`mouseenter`,`mouseleave`,`mousemove`,`mouseout`,`mouseover`,`mouseup`],ft),U(H,[`drag`,`dragend`,`dragenter`,`dragexit`,`dragleave`,`dragover`,`dragstart`,`drop`],ht),U(H,[`keydown`,`keypress`,`keyup`],xt),U(H,[`focus`,`blur`],_t),U(H,[`change`,`input`],bt),U(H,[`invalid`],yt),U(H,[`reset`,`submit`],vt),U(H,[`copy`,`cut`,`paste`],pt),U(H,[`compositionend`,`compositionstart`,`compositionupdate`],mt),U(H,[`touchcancel`,`touchend`,`touchmove`,`touchstart`],St),U(H,[`scroll`],dt),U(H,[`wheel`],Ct),U(H,[`animationstart`,`animationend`,`animationiteration`],wt),U(H,[`transitionend`],Et),U(H,[`toggle`],Tt);function W(e){if(e&&typeof e==`object`&&`nativeEvent`in e&&typeof e.isDefaultPrevented==`function`){let t=e;if(typeof t.type!=`string`)return e;let n=H[t.type.toLowerCase()];return n?n(t):ut(t)}return e}function G(e){let t=new Map,n=[],r=[],i=[],a=[],o=0;function s(e,c){if(e==null||typeof e==`string`||typeof e==`boolean`)return e;if(typeof e==`number`){if(Number.isNaN(e))return null;if(!Number.isFinite(e)){let t=e>0?`Infinity`:`-Infinity`,n=c?` in '${c}'`:``;throw Error(`Cannot serialize ${t}${n}. NaN and Infinity are not supported because they cannot be serialized to JSON.`)}return e}let l=o++,u=t.get(e);if(u!==void 0)return n.push(l),u;if(t.set(e,l),e instanceof Date)return r.push(l),e.toISOString();if(Array.isArray(e)){let t=e.length,n=Array(t);for(let r=0;r<t;r++)n[r]=s(e[r],c);return n}if(e instanceof Map){a.push(l);let t={};for(let[n,r]of e.entries())t[String(n)]=s(r,String(n));return t}if(e instanceof Set){i.push(l);let t=e.size,n=Array(t),r=0;for(let t of e)n[r]=s(t,c),r+=1;return n}if(typeof e==`object`){let t={},n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t[i]=s(e[i],i)}return t}throw Error(`Unsupported value in serialization: ${e}`)}let c=s(e);return[[n,r,i,a],c]}function K(e,t){let[[n,r,i,a],o]=e,s=new Set(n),c=new Set(r),l=new Set(i),u=new Set(a),d=[];function f(e){let n=d.length;if(s.has(n))return d.push(null),d[e];if(c.has(n)){if(typeof e!=`string`)throw Error(`Date payload must be an ISO string`);let t=Ot(e);if(t){let[e,n,r]=t,i=new Date(Date.UTC(e,n-1,r));return d.push(i),i}if(q(e))throw Error(`Invalid date literal: ${e}`);let n=new Date(e);return d.push(n),n}if(e==null||typeof e==`number`||typeof e==`string`||typeof e==`boolean`)return t?.coerceNullsToUndefined?e??void 0:e;if(Array.isArray(e)){if(l.has(n)){let t=new Set;d.push(t);for(let n=0;n<e.length;n++)t.add(f(e[n]));return t}let t=e.length,r=Array(t);d.push(r);for(let n=0;n<t;n++)r[n]=f(e[n]);return r}if(typeof e==`object`){if(u.has(n)){let t=new Map;d.push(t);let n=Object.keys(e);for(let r=0;r<n.length;r++){let i=n[r];t.set(i,f(e[i]))}return t}let t={};d.push(t);let r=Object.keys(e);for(let n=0;n<r.length;n++){let i=r[n];t[i]=f(e[i])}return t}throw Error(`Unsupported value in deserialization: ${e}`)}return f(o)}const Dt=/^\d{4}-\d{2}-\d{2}$/;function q(e){return Dt.test(e)}function Ot(e){if(!q(e))return null;let[t,n,r]=e.split(`-`),i=Number(t),a=Number(n),o=Number(r);if(!Number.isInteger(i)||!Number.isInteger(a)||!Number.isInteger(o)||a<1||a>12||o<1||o>31)return null;let s=new Date(Date.UTC(i,a-1,o));return s.getUTCFullYear()!==i||s.getUTCMonth()!==a-1||s.getUTCDate()!==o?null:[i,a,o]}var kt=class{#e;#t=null;#n;#r=new Set;#i=new Map;#a;#o;#s;#c;#l=!1;#u=null;#d=null;#f=`ok`;constructor(e,t,n,r){this.#a=e,this.#s=t,this.#o=n,this.#t=null,this.#e=new Map,this.#n=[],this.#c=r}setDirectives(e){this.#s=e}isConnected(){return this.#t?.connected??!1}#p(){this.#u&&=(clearTimeout(this.#u),null),this.#d&&=(clearTimeout(this.#d),null)}#m(e){this.#p(),this.#f=e,this.#v(e)}#h(){this.#l=!0,this.#m(`ok`)}#g(){this.#m(`ok`),this.#u=setTimeout(()=>{this.#m(`connecting`),this.#d=setTimeout(()=>{this.#m(`error`)},this.#c.initialErrorDelay)},this.#c.initialConnectingDelay)}#_(){this.#m(`reconnecting`),this.#d=setTimeout(()=>{this.#m(`error`)},this.#c.reconnectErrorDelay)}async connect(){if(!this.#t)return this.#l||this.#g(),new Promise((e,t)=>{let n=h(this.#a,{transports:[`websocket`,`webtransport`],auth:this.#s.socketio?.auth,extraHeaders:this.#s.socketio?.headers});this.#t=n,n.on(`connect`,()=>{console.log(`[SocketIOTransport] Connected:`,this.#t?.id);for(let[e,t]of this.#e)n.emit(`message`,G({type:`attach`,path:e,routeInfo:t.routeInfo}));for(let e of this.#n)e.type===`attach`&&this.#e.has(e.path)||e.type!==`update`&&n.emit(`message`,G(e));this.#n=[],this.#h(),e()}),n.on(`connect_error`,e=>{console.error(`[SocketIOTransport] Connection failed:`,e),this.#_(),t(e)}),n.on(`disconnect`,()=>{console.log(`[SocketIOTransport] Disconnected`),this.#T(),this.#_()}),n.on(`message`,e=>this.#y(K(e,{coerceNullsToUndefined:!0})))})}onConnectionChange(e){return this.#r.add(e),e(this.#f),()=>{this.#r.delete(e)}}#v(e){for(let t of this.#r)t(e)}sendMessage(e){this.isConnected()?this.#t.emit(`message`,G(e)):this.#n.push(e)}attach(e,t){if(this.#e.has(e))throw Error(`Path ${e} is already attached`);this.#e.set(e,t),this.sendMessage({type:`attach`,path:e,routeInfo:t.routeInfo})}updateRoute(e,t){let n=this.#e.get(e);n&&(n.routeInfo=t,this.sendMessage({type:`update`,path:e,routeInfo:t}))}detach(e){this.sendMessage({type:`detach`,path:e}),this.#e.delete(e)}disconnect(){this.#p(),this.#t?.disconnect(),this.#t=null,this.#n=[],this.#r.clear(),this.#e.clear();for(let{bridge:e}of this.#i.values())e.dispose(new $(`Client disconnected`));this.#i.clear(),this.#f=`ok`,this.#l=!1}#y(e){switch(e.type){case`vdom_init`:{let t=this.#e.get(e.path);if(!t)return;t.onInit(e);break}case`vdom_update`:{let t=this.#e.get(e.path);if(!t)return;t.onUpdate(e.ops);break}case`server_error`:{let t=this.#e.get(e.path);if(!t)return;t.onServerError(e.error);break}case`api_call`:this.#b(e);break;case`navigate_to`:{let t=!!e.replace,n=e.path||``;n.startsWith(`//`)&&(n=`${window.location.protocol}${n}`);let r=()=>t?window.location.replace(n):window.location.assign(n);if(e.hard){r();break}if(!/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(n)){this.#o(n,{replace:t});break}if(/^https?:\/\//.test(n))try{let e=new URL(n);if(e.origin===window.location.origin){this.#o(`${e.pathname}${e.search}${e.hash}`,{replace:t});break}}catch{}r();break}case`reload`:window.location.reload();break;case`channel_message`:this.#w(e);break;case`js_exec`:this.#x(e);break;default:console.error(`Unexpected message:`,e)}}async#b(e){try{let t=await fetch(e.url,{method:e.method||`GET`,headers:{...e.headers||{},...e.body!=null&&!(`content-type`in(e.headers||{}))?{"content-type":`application/json`}:{}},body:e.body==null?void 0:typeof e.body==`string`?e.body:JSON.stringify(e.body),credentials:e.credentials||`include`}),n={};t.headers.forEach((e,t)=>{n[t]=e});let r=null;r=(t.headers.get(`content-type`)||``).includes(`application/json`)?await t.json().catch(()=>null):await t.text().catch(()=>null);let i={type:`api_result`,id:e.id,ok:t.ok,status:t.status,headers:n,body:r};this.sendMessage(i)}catch(t){let n={type:`api_result`,id:e.id,ok:!1,status:0,headers:{},body:{error:String(t)}};this.sendMessage(n)}}invokeCallback(e,t,n){this.sendMessage({type:`callback`,path:e,callback:t,args:n.map(W)})}#x(e){let t=this.#e.get(e.path);if(!t){this.#S(e.id,void 0,null);return}t.onJsExec(e)}sendJsResult(e,t,n){this.#S(e,t,n)}#S(e,t,n){let r={type:`js_result`,id:e,result:t,error:n};this.sendMessage(r)}acquireChannel(e){let t=this.#C(e);return t.refCount+=1,t.bridge}releaseChannel(e){let t=this.#i.get(e);t&&(t.refCount=Math.max(0,t.refCount-1),t.refCount===0&&(t.bridge.dispose(new $(`Channel released`)),this.sendMessage({type:`channel_message`,channel:e,event:`__close__`,payload:{reason:`refcount_zero`}}),this.#i.delete(e)))}#C(e){let t=this.#i.get(e);return t||(t={bridge:new rn(this,e),refCount:0},this.#i.set(e,t)),t}#w(e){let t=this.#C(e.channel);t.bridge.handleServerMessage(e)&&t.refCount===0&&this.#i.delete(e.channel)}#T(){for(let e of this.#i.values())e.bridge.handleDisconnect(new $(`Connection lost`))}_ensureChannelEntry(e){return this.#C(e)}};const At={className:`class`,htmlFor:`for`,tabIndex:`tabindex`},jt=/^[A-Za-z][A-Za-z0-9_:\-\.]*$/,Mt=new Set([`value`,`checked`,`disabled`,`readOnly`,`selectedIndex`,`selectionStart`,`selectionEnd`,`selectionDirection`,`scrollTop`,`scrollLeft`,`scrollHeight`,`scrollWidth`,`clientWidth`,`clientHeight`,`offsetWidth`,`offsetHeight`,`innerText`,`textContent`,`className`,`id`,`name`,`type`,`tabIndex`]),Nt=new Set([`value`,`checked`,`disabled`,`readOnly`,`selectedIndex`,`selectionStart`,`selectionEnd`,`selectionDirection`,`scrollTop`,`scrollLeft`,`className`,`id`,`name`,`type`,`tabIndex`]);function Pt(e){return typeof e==`object`&&!!e}function Ft(e){return At[e]??e}function J(e){if(typeof e!=`string`)throw Error(`ref attribute name must be a string`);let t=e.trim();if(!t)throw Error(`ref attribute name must be non-empty`);let n=Ft(t);if(!jt.test(n))throw Error(`invalid attribute name: ${n}`);if(n.toLowerCase().startsWith(`on`))throw Error(`ref attribute name cannot start with 'on'`);return n}function It(e,t){if(typeof e!=`string`)throw Error(`ref property name must be a string`);let n=e.trim();if(!n)throw Error(`ref property name must be non-empty`);if(!Mt.has(n))throw Error(`unsupported ref property: ${n}`);if(t&&!Nt.has(n))throw Error(`ref property is read-only: ${n}`);return n}function Y(e){if(!e||typeof e.getAttribute!=`function`)throw Error(`ref is not bound to a DOM element`);return e}function Lt(e){if(!e||e.style===void 0)throw Error(`ref is not bound to an HTML element`);return e}function Rt(e){if(!e||typeof e!=`object`)return;let t={};return typeof e.top==`number`&&(t.top=e.top),typeof e.left==`number`&&(t.left=e.left),typeof e.behavior==`string`&&(t.behavior=e.behavior),Object.keys(t).length>0?t:void 0}function zt(e){if(!e||typeof e!=`object`)return;let t={};return typeof e.behavior==`string`&&(t.behavior=e.behavior),typeof e.block==`string`&&(t.block=e.block),typeof e.inline==`string`&&(t.inline=e.inline),Object.keys(t).length>0?t:void 0}function Bt(e){if(e==null)return null;if(typeof e==`string`)return e;if(typeof e==`number`)return String(e);throw Error(`style values must be strings or numbers`)}function Vt(e){if(!Pt(e))return{refId:null,op:null,payload:null};let t=e.refId,n=e.op;return{refId:t==null?null:String(t),op:typeof n==`string`?n:null,payload:e.payload}}function Ht(e){return typeof e==`object`&&!!e&&`__pulse_ref__`in e}var Ut=class{#e;#t=null;#n=null;#r=new Map;#i=[];constructor(e){this.#e=e}getCallback(e,t){this.#a(e);let n=this.#r.get(t);return n||(n={node:null,callback:e=>{this.#s(t,e??null)}},this.#r.set(t,n)),n.callback}dispose(){this.#o()}#a(e){if(this.#t){if(this.#n!==e)throw Error(`[Pulse] Ref channel changed unexpectedly`);return}let t=this.#e(e);this.#t=t,this.#n=e,this.#i.push(t.on(`ref:call`,e=>{this.#c(e)}),t.on(`ref:request`,e=>this.#l(e)))}#o(){for(let e of this.#i)e();this.#i=[],this.#r.clear(),this.#t=null,this.#n=null}#s(e,t){let n=this.#r.get(e);if(!n||n.node===t)return;n.node=t;let r=this.#t;r&&(t?r.emit(`ref:mounted`,{refId:e}):r.emit(`ref:unmounted`,{refId:e}))}#c(e){let t=Vt(e);if(!(!t.refId||!t.op))try{this.#u(t.refId,t.op,t.payload,!1)}catch(e){console.error(`[Pulse] Ref call failed:`,e)}}#l(e){let t=Vt(e);if(!t.op)throw Error(`ref request missing op`);if(!t.refId)throw Error(`ref request missing refId`);return this.#u(t.refId,t.op,t.payload,!0)}#u(e,t,n,r){let i=this.#r.get(e)?.node;if(!i){let e=`ref is not mounted`;if(r)throw Error(e);return console.warn(`[Pulse] ${e}`),null}switch(t){case`focus`:if(typeof i.focus==`function`)if(n&&typeof n==`object`&&`preventScroll`in n){let e=!!n.preventScroll;try{i.focus({preventScroll:e})}catch{i.focus()}}else i.focus();return null;case`blur`:return typeof i.blur==`function`&&i.blur(),null;case`click`:return typeof i.click==`function`&&i.click(),null;case`select`:if(typeof i.select==`function`)i.select();else throw Error(`select() not supported on this element`);return null;case`scrollIntoView`:{if(typeof i.scrollIntoView!=`function`)throw Error(`scrollIntoView() not supported on this element`);let e=zt(n)??void 0;return i.scrollIntoView(e),null}case`scrollTo`:{if(typeof i.scrollTo!=`function`)throw Error(`scrollTo() not supported on this element`);let e=Rt(n);return i.scrollTo(e??void 0),null}case`scrollBy`:{if(typeof i.scrollBy!=`function`)throw Error(`scrollBy() not supported on this element`);let e=Rt(n);return i.scrollBy(e??void 0),null}case`submit`:if(typeof i.submit!=`function`)throw Error(`submit() not supported on this element`);return i.submit(),null;case`reset`:if(typeof i.reset!=`function`)throw Error(`reset() not supported on this element`);return i.reset(),null;case`setSelectionRange`:{if(typeof i.setSelectionRange!=`function`)throw Error(`setSelectionRange() not supported on this element`);if(!n||typeof n!=`object`)throw Error(`setSelectionRange() requires payload`);let e=n.start,t=n.end,r=n.direction;if(typeof e!=`number`||typeof t!=`number`)throw Error(`setSelectionRange() requires numeric start/end`);return i.setSelectionRange(e,t,r??void 0),null}case`measure`:{if(typeof i.getBoundingClientRect!=`function`)throw Error(`measure() not supported on this element`);let e=i.getBoundingClientRect();return{x:e.x,y:e.y,width:e.width,height:e.height,top:e.top,right:e.right,bottom:e.bottom,left:e.left}}case`getValue`:return`value`in i?i.value:`textContent`in i?i.textContent:null;case`setValue`:{let e=n?.value;return`value`in i?(i.value=e,i.value):`textContent`in i?(i.textContent=e==null?``:String(e),i.textContent):null}case`getText`:return`textContent`in i?i.textContent:null;case`setText`:{let e=n?.text;if(typeof e!=`string`)throw Error(`setText() requires a string payload`);return`textContent`in i?(i.textContent=e,i.textContent):null}case`getAttr`:{let e=J(n?.name);return Y(i).getAttribute(e)}case`setAttr`:{let e=J(n?.name),t=Y(i),r=n?.value;return r==null?t.removeAttribute(e):t.setAttribute(e,String(r)),t.getAttribute(e)}case`removeAttr`:{let e=J(n?.name);return Y(i).removeAttribute(e),null}case`getProp`:{let e=It(n?.name,!1);if(!(e in i))throw Error(`ref property not supported on element: ${e}`);return i[e]}case`setProp`:{let e=It(n?.name,!0);if(!(e in i))throw Error(`ref property not supported on element: ${e}`);return i[e]=n?.value,i[e]}case`setStyle`:{let e=Lt(i),t=n?.styles;if(!t||typeof t!=`object`)throw Error(`setStyle() requires a styles object`);for(let[n,r]of Object.entries(t)){if(!n)throw Error(`style key must be non-empty`);let t=Bt(r);if(n.includes(`-`)){t==null?e.style.removeProperty(n):e.style.setProperty(n,t);continue}t==null?e.style[n]=``:e.style[n]=t}return null}default:throw Error(`Unsupported ref op: ${t}`)}}};function Wt(e){return typeof e==`object`&&!!e&&`tag`in e}function X(e){return typeof e==`object`&&!!e&&`t`in e}function Gt(e){if(e===`$cb`)return null;if(typeof e!=`string`||!e.startsWith(`$cb:`))return;let t=e.slice(4);if(t.length===0)throw Error(`[Pulse] Invalid callback placeholder: '$cb:'`);let n=Number(t);if(!Number.isFinite(n)||n<0)throw Error(`[Pulse] Invalid callback debounce delay: ${e}`);return n}var Kt=class{#e;#t;#n;#r;#i;#a;constructor(e,t,n={}){this.#e=e,this.#t=t,this.#n=n,this.#i=new Set,this.#a=new WeakMap,this.#r=new Ut(e=>this.#e._ensureChannelEntry(e).bridge)}getObject(e){let t=this.#n[e];if(t===void 0)throw Error(`[Pulse] Unknown registry key: ${e}`);return t}#o(e){let t=globalThis[e];if(t===void 0)throw Error(`[Pulse] Unknown identifier in expr: ${e}`);return t}#s(e,t){if(typeof e!=`object`||!e)return e;if(`tag`in e)return this.renderNode(e,``);switch(e.t){case`ref`:return this.getObject(e.key);case`id`:return Object.hasOwn(t,e.name)?t[e.name]:this.#o(e.name);case`lit`:return e.value;case`undef`:return;case`array`:{let n=[];for(let r of e.items)n.push(this.#s(r,t));return n}case`object`:{let n={};for(let[r,i]of Object.entries(e.props))n[r]=this.#s(i,t);return n}case`member`:return this.#s(e.obj,t)?.[e.prop];case`sub`:{let n=this.#s(e.obj,t),r=this.#s(e.key,t);return n?.[r]}case`call`:{let n=this.#s(e.callee,t),r=e.args.map(e=>this.#s(e,t));if(typeof n!=`function`)throw Error(`[Pulse] call callee is not a function`);return n(...r)}case`unary`:{let n=this.#s(e.arg,t);switch(e.op){case`!`:return!n;case`+`:return+n;case`-`:return-n;case`typeof`:return typeof n;case`void`:return;default:throw Error(`[Pulse] Unsupported unary op: ${e.op}`)}}case`binary`:{let n=this.#s(e.left,t),r=this.#s(e.right,t);switch(e.op){case`+`:return n+r;case`-`:return n-r;case`*`:return n*r;case`/`:return n/r;case`%`:return n%r;case`&&`:return n&&r;case`||`:return n||r;case`??`:return n??r;case`**`:return n**r;case`in`:return n in r;case`instanceof`:return n instanceof r;case`===`:return n===r;case`!==`:return n!==r;case`<`:return n<r;case`<=`:return n<=r;case`>`:return n>r;case`>=`:return n>=r;default:throw Error(`[Pulse] Unsupported binary op: ${e.op}`)}}case`ternary`:return this.#s(e.cond,t)?this.#s(e.then,t):this.#s(e.else_,t);case`template`:{let n=``;for(let r of e.parts)typeof r==`string`?n+=r:n+=String(this.#s(r,t));return n}case`arrow`:{let n=e.params;return(...r)=>{let i={...t};for(let e=0;e<n.length;e+=1)i[n[e]]=r[e];return this.#s(e.body,i)}}case`new`:return new(this.#s(e.ctor,t))(...e.args.map(e=>this.#s(e,t)));default:throw Error(`[Pulse] Unknown expr node: ${e.t}`)}}#c(e,t){return e?`${e}.${t}`:t}#l(e){e.timer&&clearTimeout(e.timer),e.timer=null,e.lastArgs=null,e.dueAt=null}#u(e,t){let n=e.lastArgs;this.#l(e),n&&t(n)}#d(e,t,n,r){e.timer&&clearTimeout(e.timer),e.lastArgs=n,e.dueAt=Date.now()+t,e.timer=setTimeout(()=>{this.#u(e,r)},t)}#f(e,t){let n=e.callbacks;if(!n)return;let r=n.get(t);r&&(this.#l(r),this.#i.delete(r),n.delete(t),n.size===0&&(e.callbacks=void 0))}#p(e,t){e.callbacks||=new Map;let n=e.callbacks,r=n.get(t);if(!r){let i=n=>{let r=this.#c(e.path??``,t);this.#e.invokeCallback(this.#t,r,n)};r={fn:(...e)=>{if(r.delayMs==null){i(e);return}let t=e.map(W);this.#d(r,r.delayMs,t,i)},delayMs:null,timer:null,lastArgs:null,dueAt:null},n.set(t,r),this.#i.add(r)}return r}#m(e,t){if(e==null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`)return;if(Array.isArray(e)){for(let n=0;n<e.length;n+=1){let r=t?`${t}.${n}`:String(n);this.#m(e[n],r)}return}if(!a(e))return;let n=e,r=this.#a.get(n),i=r?.path??t,o=r?.callbacks;if(o&&o.size>0){for(let e of o.values())this.#l(e),this.#i.delete(e);o.clear(),r.callbacks=void 0}let s=n.props??{};for(let e of Object.keys(s)){if(e===`children`)continue;let t=s[e];this.#m(t,this.#c(i,e))}let c=this.#v(n);for(let e=0;e<c.length;e+=1){let t=i?`${i}.${e}`:String(e);this.#m(c[e],t)}}#h(e,t,n){let r=this.#p(e,t);return r.delayMs!==n&&(r.delayMs=n),r.fn}#g(e,t,n,r){let i=Gt(r);if(i!==void 0)return this.#h(t,n,i);if(Ht(r)){let e=r.__pulse_ref__;return this.#r.getCallback(e.channelId,e.refId)}return X(r)?this.#s(r,{}):typeof r==`object`&&r&&`tag`in r?this.renderNode(r,this.#c(e,n)):r}#_(e,t){return this.#a.set(e,t),e}clearPendingCallbacks(){for(let e of Array.from(this.#i))this.#l(e)}renderNode(t,n=``){if(t==null||typeof t==`boolean`||typeof t==`number`||typeof t==`string`)return t;if(X(t))return this.#s(t,{});if(Wt(t)){let{tag:i,props:a={},children:o=[],eval:s}=t,c;if(typeof i==`string`)if(i.startsWith(`$$`)){let e=i.slice(2);if(c=this.#n[e],!c)throw Error(`[Pulse] Missing component '${e}'`)}else c=i.length>0?i:e;else c=this.#s(i,{});let l={},u,d={path:n};if(s){u=new Set(s),d.eval=u;for(let[e,t]of Object.entries(a)){if(!u.has(e)){l[e]=t;continue}l[e]=this.#g(n,d,e,t)}}else for(let[e,t]of Object.entries(a))l[e]=t;t.key&&(l.key=t.key);let f=[];for(let e=0;e<o.length;e+=1){let t=o[e],r=n?`${n}.${e}`:String(e);f.push(this.renderNode(t,r))}try{return this.#_(r(c,l,...f),d)}catch(e){throw console.error(`[Pulse] Failed to create element:`,t),e}}return process.env.NODE_ENV!==`production`&&console.error(`Unknown VDOM node:`,t),null}init(e){return this.renderNode(e.vdom)}dispose(){this.#r.dispose()}evaluateExpr(e){return this.#s(e,{})}#v(e){let t=e.props?.children;return t==null?[]:Array.isArray(t)?t.slice():[t]}#y(e,t){let n=this.#a.get(e);return n&&this.#a.set(t,n),t}#b(e,t){if(e==null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`)return e;if(Array.isArray(e)){for(let n=0;n<e.length;n+=1){let r=t?`${t}.${n}`:String(n);this.#b(e[n],r)}return e}if(!a(e))return e;let n=e,r=this.#a.get(n);r?r.path=t:this.#a.set(n,{path:t});let i=n.props??{};for(let e of Object.keys(i)){if(e===`children`)continue;let n=i[e];this.#b(n,this.#c(t,e))}let o=this.#v(n);for(let e=0;e<o.length;e+=1){let n=t?`${t}.${e}`:String(e);this.#b(o[e],n)}return e}applyUpdates(e,n){let i=e;for(let e of n){let n=e.path.split(`.`).filter(e=>e.length>0),a=(i,o,s)=>{if(o<n.length){this.#x(i,n,o);let e=i,r=n[o],c=+r,l=s?`${s}.${r}`:r;if(Number.isNaN(c)){let n=e.props??{},i=n[r],s={...n,[r]:a(i,o+1,l)};return this.#y(e,t(e,s))}else{let n=this.#v(e),r=n[c];return n[c]=a(r,o+1,l),this.#y(e,t(e,void 0,...n))}}switch(e.type){case`replace`:return this.#m(i,s),this.renderNode(e.data,e.path);case`update_props`:{this.#x(i,n,o);let a=i,c=a.props??{},l={...c},u=this.#a.get(a),d=u??{},f=d.eval,p=u?.path??s,m=e.data.eval,h=m===void 0?f:m.length===0?void 0:new Set(m),g=m!==void 0&&m.length===0;if(h&&d.callbacks)for(let e of Array.from(d.callbacks.keys()))h.has(e)||this.#f(d,e);if(g&&d.callbacks)for(let e of Array.from(d.callbacks.keys()))delete l[e],this.#f(d,e);let _=e.data.remove??[];if(_.length>0)for(let e of _){let t=c[e];t!==void 0&&this.#m(t,this.#c(p,e)),delete l[e],d.callbacks?.has(e)&&this.#f(d,e)}if(e.data.set)for(let[t,n]of Object.entries(e.data.set)){let e=c[t];e!==void 0&&this.#m(e,this.#c(p,t));let r=h?.has(t)===!0,i=r?Gt(n):void 0;l[t]=r?this.#g(s,d,t,n):n,i===void 0&&d.callbacks?.has(t)&&this.#f(d,t)}d.eval=h,d.path=s;let v=_.length>0,y=_.includes(`ref`),b=Object.prototype.hasOwnProperty.call(l,`ref`),x=Object.prototype.hasOwnProperty.call(c,`ref`)?c.ref:void 0,ee=a.ref??x,S=b?l.ref:y?void 0:ee;return v?(l.key=a.key,!y&&!b&&S!==void 0&&(l.ref=S),this.#_(r(a.type,l,...this.#v(a)),d)):this.#_(t(a,l),d)}case`reconciliation`:{this.#x(i,n,o);let r=i,a=this.#v(r),c=[],[l,u]=e.new,[d,f]=e.reuse,p=new Set(l),m=new Set(d),h=new Set(f);for(let t=0;t<a.length;t+=1)if(!(h.has(t)||t<e.N&&!p.has(t)&&!m.has(t))){let e=s?`${s}.${t}`:String(t);this.#m(a[t],e)}let g=-1,_=-1,v=-1,y=-1;l.length>0&&(g=l[0],v=0),d.length>0&&(_=d[0],y=0);for(let t=0;t<e.N;t+=1)if(t===g){let e=u[v],n=s?`${s}.${t}`:String(t);c.push(this.renderNode(e,n)),g=v<l.length-1?l[++v]:-1}else if(t===_){let e=a[f[y]],n=s?`${s}.${t}`:String(t);e=this.#b(e,n),c.push(e),_=y<d.length-1?d[++y]:-1}else c.push(a[t]);return c.length===0&&c.push(null),this.#y(r,t(r,null,...c))}default:throw Error(`[Pulse renderer] Unknown update type: ${e?.type}`)}};i=a(i,0,``)}return i}#x(e,t,n){if(process.env.NODE_ENV!==`production`&&!a(e))throw console.error(`Invalid node:`,e),Error(`Invalid node at path ${t.slice(0,n).join(`.`)}`);return!0}};const qt=n(null),Jt=n(null),Z=()=>{let e=s(qt);if(!e)throw Error(`usePulseClient must be used within a PulseProvider`);return e},Yt=e=>{let t=s(Jt);if(!t)throw Error(`usePulsePrerender must be used within a PulseProvider`);let n=t.views[e];if(!n)throw Error(`No prerender found for '${e}'`);return n},Q=typeof window<`u`;function Xt({children:e,config:t,prerender:n}){let[r,i]=d(`ok`),a=p(),{directives:o}=n,s=l(()=>new kt(t.serverAddress,o,a,t.connectionStatus),[t.serverAddress,a,t.connectionStatus]);c(()=>s.setDirectives(o),[s,o]),c(()=>{if(!Q)return;let e=s.onConnectionChange(e=>{i(e)});return s.connect(),()=>{e(),s.disconnect()}},[s]);let u=(()=>{switch(r){case`connecting`:return`Connecting...`;case`reconnecting`:return`Reconnecting...`;case`error`:return`Failed to connect to the server.`;default:return null}})();return g(qt.Provider,{value:s,children:_(Jt.Provider,{value:n,children:[u&&g(`div`,{style:{position:`fixed`,bottom:`20px`,right:`20px`,backgroundColor:r===`error`?`red`:`#666`,color:`white`,padding:`10px`,borderRadius:`5px`,zIndex:1e3},children:u}),e]})})}function Zt({path:e,registry:t}){let n=Z(),r=Yt(e),i=l(()=>new Kt(n,e,t),[n,e,t]),[a,o]=d(()=>i.init(r)),[s,p]=d(null),h=f(),_=m(),v=l(()=>{let{"*":e=``,...t}=_,n=new URLSearchParams(h.search),r=h.search.startsWith(`?`)?h.search.slice(1):h.search;return{hash:h.hash.startsWith(`#`)?h.hash.slice(1):h.hash,pathname:h.pathname,query:r,queryParams:Object.fromEntries(n.entries()),pathParams:t,catchall:e.length>0?e.split(`/`):[]}},[h.hash,h.pathname,h.search,JSON.stringify(_)]);c(()=>{if(Q)return n.attach(e,{routeInfo:v,onInit:e=>{o(i.init(e)),p(null)},onUpdate:e=>{o(t=>t==null?t:i.applyUpdates(t,e)),p(null)},onJsExec:e=>{let t,r=null;try{t=i.evaluateExpr(e.expr)}catch(e){r=e instanceof Error?e.message:String(e)}n.sendJsResult(e.id,t,r)},onServerError:p}),()=>{i.clearPendingCallbacks(),i.dispose(),n.detach(e)}},[n,i,e]),c(()=>{Q&&n.updateRoute(e,v)},[n,e,v]);let y=u(!1);return c(()=>{y.current?o(i.init(r)):y.current=!0},[r,i]),s?g(Qt,{error:s}):a}function Qt({error:e}){return _(`div`,{style:{padding:16,border:`1px solid #e00`,background:`#fff5f5`,color:`#900`,fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace`,whiteSpace:`pre-wrap`},children:[_(`div`,{style:{fontWeight:700,marginBottom:8},children:[`Server Error during `,e.phase]}),e.message&&g(`div`,{children:e.message}),e.stack&&_(`details`,{open:!0,style:{marginTop:8},children:[g(`summary`,{children:`Stack trace`}),g(`pre`,{style:{margin:0},children:e.stack})]})]})}var $=class extends Error{constructor(e){super(e),this.name=`PulseChannelResetError`}};function $t(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID().replace(/-/g,``):Math.random().toString(16).slice(2)+Math.random().toString(16).slice(2)}function en(e){if(e instanceof Error)return e.message;if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}function tn(e){return typeof e.responseTo==`string`}function nn(e){return typeof e.event==`string`}var rn=class{handlers=new Map;pending=new Map;backlog=[];closed=!1;constructor(e,t){this.client=e,this.id=t}emit(e,t){this.ensureOpen(),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t})}request(e,t){this.ensureOpen();let n=$t();return new Promise((r,i)=>{this.pending.set(n,{resolve:r,reject:i}),this.client.sendMessage({type:`channel_message`,channel:this.id,event:e,payload:t,requestId:n})})}on(e,t){this.ensureOpen();let n=this.handlers.get(e);return n||(n=new Set,this.handlers.set(e,n)),n.add(t),this.flushBacklog(e),()=>{let n=this.handlers.get(e);n&&(n.delete(t),n.size===0&&this.handlers.delete(e))}}handleServerMessage(e){return tn(e)?(this.resolvePending(e),this.closed):this.closed?!0:nn(e)?e.event===`__close__`?(this.close(new $(`Channel closed by server`)),!0):(e.requestId?this.dispatchRequest(e):this.dispatchEvent(e),this.closed):this.closed}handleDisconnect(e){this.close(e)}dispose(e){this.close(e)}ensureOpen(){if(this.closed)throw new $(`Channel is closed`)}flushBacklog(e){if(this.backlog.length===0)return;let t=[];for(let n of this.backlog)n.event===e?this.dispatchEvent(n):t.push(n);this.backlog=t}dispatchEvent(e){let t=this.handlers.get(e.event);if(!t||t.size===0){this.backlog.push(e);return}for(let n of t)try{let t=n(e.payload);t&&typeof t.then==`function`&&t.catch(e=>{console.error(`Pulse channel handler error`,e)})}catch(e){console.error(`Pulse channel handler error`,e)}}async dispatchRequest(e){let t=this.handlers.get(e.event),n,r;if(t&&t.size>0)for(let i of t)try{let t=i(e.payload);if(n=await Promise.resolve(t),n!==void 0)break}catch(e){r=e;break}if(r){this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,error:en(r)});return}this.client.sendMessage({type:`channel_message`,channel:this.id,event:void 0,responseTo:e.requestId,payload:n})}resolvePending(e){let t=e.responseTo?this.pending.get(e.responseTo):void 0;t&&(this.pending.delete(e.responseTo),e.error!==void 0&&e.error!==null?t.reject(new $(String(e.error))):t.resolve(e.payload))}close(e){if(!this.closed){this.closed=!0;for(let t of this.pending.values())t.reject(e);this.pending.clear(),this.handlers.clear(),this.backlog=[]}}};function an(e){let t=Z(),n=l(()=>{if(!e)throw Error(`usePulseChannel requires a non-empty channelId`);return t.acquireChannel(e)},[t,e]);return c(()=>()=>{t.releaseChannel(e)},[t,e]),n}const on=i(function({onSubmit:e,action:t,...n},r){return g(`form`,{...n,action:t,ref:r,onSubmit:o(n=>sn({event:n,action:t,onSubmit:e}),[t,e])})});async function sn({event:e,action:t,onSubmit:n,formData:r,force:i}){if(n?.(e),!i&&e.defaultPrevented)return;let a=e.currentTarget;e.preventDefault();let o=e.nativeEvent;r||=new FormData(a,o.submitter);let s=new URL(t,window.location.href);try{await fetch(s,{method:`POST`,credentials:`include`,body:r})}catch(e){if(process.env.NODE_ENV!==`production`)console.error(`[Pulse] Form submission failed`,e);else throw e}}function cn({params:e,request:t}){let{"*":n=``,...r}=e,i=new URL(t.url),a=i.search.startsWith(`?`)?i.search.slice(1):i.search;return{hash:i.hash.startsWith(`#`)?i.hash.slice(1):i.hash,pathname:i.pathname,query:a,queryParams:Object.fromEntries(i.searchParams.entries()),pathParams:r,catchall:n.length>1?n.split(`/`):[]}}export{$ as PulseChannelResetError,on as PulseForm,Xt as PulseProvider,Zt as PulseView,Kt as VDOMRenderer,K as deserialize,cn as extractServerRouteInfo,G as serialize,sn as submitForm,an as usePulseChannel,Z as usePulseClient};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["out: any","formExtractor","elementExtractors: Record<string, (elt: any) => object>","eventExtractorMap: { [key: string]: (evt: any) => object }","refs: number[]","dates: number[]","sets: number[]","maps: number[]","process","rec: Record<string, any>","objects: Array<any>","dt","result","keys","result: Record<string, any>","#url","#directives","#frameworkNavigate","#socket","#activeViews","#messageQueue","#connectionStatusConfig","#connectingTimeout","#errorTimeout","#clearTimeouts","#currentStatus","#notifyConnectionListeners","#hasConnectedOnce","#setStatus","#setInitialConnectionStatus","#handleConnected","#handleDisconnected","#handleTransportDisconnect","#handleServerMessage","#connectionListeners","#channels","#performApiCall","#routeChannelMessage","#handleJsExec","headersObj: Record<string, string>","body: any","reply: ClientApiResultMessage","#sendJsResult","msg: ClientJsResultMessage","#ensureChannelEntry","#client","#path","#registry","#callbackEntries","#metaMap","#resolveIdentifier","out: unknown[]","#evalExpr","out: Record<string, unknown>","nextEnv: Env","#clearPending","#firePending","#propPath","#scheduleDebounced","#dropCallbacksInSubtree","#ensureChildrenArray","#ensureCallbackEntry","#getCallback","component: React.ComponentType<any> | string","REF_PREFIX","newProps: Record<string, any>","evalSet: Set<string> | undefined","meta: ElementMeta","#transformEvalProp","renderedChildren: ReactNode[]","#rememberMeta","#rebindCallbacksInSubtree","newTree: ReactNode","#assertIsElement","#cloneWithMeta","nextProps: Record<string, any>","nextEval: Set<string> | undefined","#dropCallback","nextChildren: ReactNode[]","result: any","error: string | null","client: PulseSocketIOClient","id: string","remaining: ServerChannelRequestMessage[]","response: any","error: any","PulseForm"],"sources":["../src/serialize/extractor.ts","../src/serialize/elements.ts","../src/serialize/events.ts","../src/serialize/serializer.ts","../src/client.tsx","../src/vdom.ts","../src/renderer.tsx","../src/pulse.tsx","../src/channel.ts","../src/form.tsx","../src/helpers.ts"],"sourcesContent":["type Simplify<T> = { [K in keyof T]: T[K] } & {};\n\nexport function createExtractor<T extends object>() {\n\tfunction _createExtractor<\n\t\tconst K extends readonly (keyof T)[],\n\t\tC extends Partial<Record<K[number] | string, (src: T) => any>>,\n\t>(keys: K, computed?: C) {\n\t\treturn (\n\t\t\tsrc: T,\n\t\t): Simplify<\n\t\t\tPick<T, K[number]> & {\n\t\t\t\t[P in keyof C]-?: C[P] extends (...args: any) => infer R ? R : never;\n\t\t\t}\n\t\t> => {\n\t\t\tconst out: any = {};\n\t\t\tfor (const key of keys) {\n\t\t\t\tout[key as string] = (src as any)[key as string];\n\t\t\t}\n\t\t\tif (computed) {\n\t\t\t\tfor (const key in computed) {\n\t\t\t\t\tconst fn = computed[key]!;\n\t\t\t\t\tout[key] = fn(src);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out;\n\t\t};\n\t}\n\treturn _createExtractor;\n}\n","import { createExtractor } from \"./extractor\";\n\n// Base extractors (camelCase) similar to events.ts style\nconst lowerTagName = (e: Element) => e.tagName.toLowerCase();\n\nconst ELEMENT_KEYS = [\n\t\"id\",\n\t\"className\",\n\t\"tagName\",\n\t\"localName\",\n\t\"clientHeight\",\n\t\"clientLeft\",\n\t\"clientTop\",\n\t\"clientWidth\",\n\t\"scrollHeight\",\n\t\"scrollLeft\",\n\t\"scrollTop\",\n\t\"scrollWidth\",\n\t\"slot\",\n] as const satisfies readonly (keyof Element)[];\n\nconst HTML_OR_SVG_KEYS = [\n\t\"autofocus\",\n\t\"tabIndex\",\n\t\"nonce\",\n] as const satisfies readonly (keyof HTMLOrSVGElement)[];\n\nconst HTML_ELEMENT_BASE_KEYS = [\n\t\"accessKey\",\n\t\"accessKeyLabel\",\n\t\"autocapitalize\",\n\t\"dir\",\n\t\"draggable\",\n\t\"hidden\",\n\t\"inert\",\n\t\"lang\",\n\t\"offsetHeight\",\n\t\"offsetLeft\",\n\t\"offsetTop\",\n\t\"offsetWidth\",\n\t\"popover\",\n\t\"spellcheck\",\n\t\"title\",\n\t\"translate\",\n\t\"writingSuggestions\",\n\t\"contentEditable\",\n\t\"enterKeyHint\",\n\t\"isContentEditable\",\n\t\"inputMode\",\n] as const satisfies readonly (keyof HTMLElement)[];\n\nconst extractElementBase = createExtractor<Element>()(ELEMENT_KEYS, {\n\ttagName: lowerTagName,\n});\n\nconst extractHTMLOrSVGElement = createExtractor<HTMLOrSVGElement>()(HTML_OR_SVG_KEYS);\n\nconst extractHTMLElementBaseOnly = createExtractor<HTMLElement>()(HTML_ELEMENT_BASE_KEYS);\n\nfunction extractHTMLElementBase(elt: HTMLElement) {\n\treturn {\n\t\t...extractElementBase(elt),\n\t\t...extractHTMLOrSVGElement(elt as HTMLOrSVGElement),\n\t\t...extractHTMLElementBaseOnly(elt),\n\t};\n}\n\n// Helper to compose per-element extractors with the shared base\nfunction withBase<T extends HTMLElement>(\n\tkeys: readonly (keyof T)[],\n\tcomputed?: Partial<Record<string, (src: T) => any>>,\n) {\n\tconst only = createExtractor<T>()(keys, computed as any);\n\treturn (elt: T) => ({ ...extractHTMLElementBase(elt), ...only(elt) });\n}\n\nconst HTML_ANCHOR_KEYS = [\n\t\"hash\",\n\t\"host\",\n\t\"hostname\",\n\t\"href\",\n\t\"origin\",\n\t\"password\",\n\t\"pathname\",\n\t\"port\",\n\t\"protocol\",\n\t\"search\",\n\t\"target\",\n\t\"download\",\n\t\"rel\",\n\t\"hreflang\",\n\t\"type\",\n\t\"username\",\n\t\"ping\",\n\t\"referrerPolicy\",\n\t\"text\",\n] as const satisfies readonly (keyof HTMLAnchorElement)[];\nconst anchorExtractor = withBase<HTMLAnchorElement>(HTML_ANCHOR_KEYS);\n\nconst HTML_AREA_KEYS = [\n\t\"alt\",\n\t\"coords\",\n\t\"download\",\n\t\"hash\",\n\t\"host\",\n\t\"hostname\",\n\t\"href\",\n\t\"origin\",\n\t\"password\",\n\t\"pathname\",\n\t\"port\",\n\t\"protocol\",\n\t\"rel\",\n\t\"search\",\n\t\"shape\",\n\t\"target\",\n\t\"username\",\n\t\"ping\",\n\t\"referrerPolicy\",\n] as const satisfies readonly (keyof HTMLAreaElement)[];\nconst areaExtractor = withBase<HTMLAreaElement>(HTML_AREA_KEYS);\n\nconst HTML_MEDIA_KEYS = [\n\t\"autoplay\",\n\t\"controls\",\n\t\"crossOrigin\",\n\t\"currentSrc\",\n\t\"currentTime\",\n\t\"defaultMuted\",\n\t\"defaultPlaybackRate\",\n\t\"duration\",\n\t\"ended\",\n\t\"loop\",\n\t\"muted\",\n\t\"networkState\",\n\t\"paused\",\n\t\"playbackRate\",\n\t\"preload\",\n\t\"readyState\",\n\t\"seeking\",\n\t\"src\",\n\t\"volume\",\n\t\"preservesPitch\",\n] as const satisfies readonly (keyof HTMLMediaElement)[];\nconst mediaExtractor = withBase<HTMLMediaElement>(HTML_MEDIA_KEYS);\n\nconst audioExtractor = (elt: HTMLAudioElement) => mediaExtractor(elt);\n\nconst HTML_BUTTON_KEYS = [\n\t\"disabled\",\n\t\"name\",\n\t\"type\",\n\t\"value\",\n\t\"formAction\",\n\t\"formEnctype\",\n\t\"formMethod\",\n\t\"formNoValidate\",\n\t\"formTarget\",\n\t\"popoverTargetAction\",\n] as const satisfies readonly (keyof HTMLButtonElement)[];\nconst buttonExtractor = withBase<HTMLButtonElement>(HTML_BUTTON_KEYS);\n\nconst HTML_DATA_KEYS = [\"value\"] as const satisfies readonly (keyof HTMLDataElement)[];\nconst dataExtractor = withBase<HTMLDataElement>(HTML_DATA_KEYS);\n\nconst HTML_EMBED_KEYS = [\n\t\"height\",\n\t\"src\",\n\t\"type\",\n\t\"width\",\n\t\"align\",\n\t\"name\",\n] as const satisfies readonly (keyof HTMLEmbedElement)[];\nconst embedExtractor = withBase<HTMLEmbedElement>(HTML_EMBED_KEYS);\n\nconst HTML_FIELDSET_KEYS = [\n\t\"disabled\",\n\t\"name\",\n\t\"type\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLFieldSetElement)[];\nconst fieldsetExtractor = withBase<HTMLFieldSetElement>(HTML_FIELDSET_KEYS);\n\nconst HTML_FORM_KEYS = [\n\t\"acceptCharset\",\n\t\"action\",\n\t\"autocomplete\",\n\t\"encoding\",\n\t\"enctype\",\n\t\"length\",\n\t\"method\",\n\t\"name\",\n\t\"noValidate\",\n\t\"target\",\n\t\"rel\",\n] as const satisfies readonly (keyof HTMLFormElement)[];\nconst formExtractor = withBase<HTMLFormElement>(HTML_FORM_KEYS);\n\nconst HTML_IFRAME_KEYS = [\n\t\"allow\",\n\t\"allowFullscreen\",\n\t\"height\",\n\t\"name\",\n\t\"referrerPolicy\",\n\t\"src\",\n\t\"srcdoc\",\n\t\"width\",\n\t\"align\",\n\t\"frameBorder\",\n\t\"longDesc\",\n\t\"marginHeight\",\n\t\"marginWidth\",\n\t\"scrolling\",\n\t\"sandbox\",\n] as const satisfies readonly (keyof HTMLIFrameElement)[];\nconst iframeExtractor = withBase<HTMLIFrameElement>(HTML_IFRAME_KEYS);\n\nconst HTML_IMAGE_KEYS = [\n\t\"alt\",\n\t\"crossOrigin\",\n\t\"decoding\",\n\t\"height\",\n\t\"isMap\",\n\t\"loading\",\n\t\"naturalHeight\",\n\t\"naturalWidth\",\n\t\"referrerPolicy\",\n\t\"sizes\",\n\t\"src\",\n\t\"srcset\",\n\t\"useMap\",\n\t\"width\",\n\t\"align\",\n\t\"border\",\n\t\"complete\",\n\t\"hspace\",\n\t\"longDesc\",\n\t\"lowsrc\",\n\t\"name\",\n\t\"vspace\",\n\t\"x\",\n\t\"y\",\n\t\"fetchPriority\",\n] as const satisfies readonly (keyof HTMLImageElement)[];\nconst imageExtractor = withBase<HTMLImageElement>(HTML_IMAGE_KEYS);\n\nconst HTML_INPUT_KEYS = [\n\t\"accept\",\n\t\"alt\",\n\t\"autocomplete\",\n\t\"checked\",\n\t\"defaultChecked\",\n\t\"defaultValue\",\n\t\"dirName\",\n\t\"disabled\",\n\t\"height\",\n\t\"indeterminate\",\n\t\"max\",\n\t\"maxLength\",\n\t\"min\",\n\t\"minLength\",\n\t\"multiple\",\n\t\"name\",\n\t\"pattern\",\n\t\"placeholder\",\n\t\"readOnly\",\n\t\"required\",\n\t\"selectionDirection\",\n\t\"selectionEnd\",\n\t\"selectionStart\",\n\t\"size\",\n\t\"src\",\n\t\"step\",\n\t\"type\",\n\t\"value\",\n\t\"valueAsNumber\",\n\t\"width\",\n\t\"align\",\n\t\"capture\",\n\t\"formAction\",\n\t\"formEnctype\",\n\t\"formMethod\",\n\t\"formNoValidate\",\n\t\"formTarget\",\n\t\"useMap\",\n\t\"validationMessage\",\n\t\"willValidate\",\n\t\"popoverTargetAction\",\n] as const satisfies readonly (keyof HTMLInputElement)[];\nconst inputExtractor = withBase<HTMLInputElement>(HTML_INPUT_KEYS, {\n\tvalueAsNumber: (elt) => {\n\t\tconst value = elt.valueAsNumber;\n\t\treturn Number.isFinite(value) ? value : null;\n\t},\n});\n\nconst HTML_LABEL_KEYS = [\"htmlFor\"] as const satisfies readonly (keyof HTMLLabelElement)[];\nconst labelExtractor = withBase<HTMLLabelElement>(HTML_LABEL_KEYS);\n\nconst HTML_LI_KEYS = [\"value\", \"type\"] as const satisfies readonly (keyof HTMLLIElement)[];\nconst liExtractor = withBase<HTMLLIElement>(HTML_LI_KEYS);\n\nconst HTML_LINK_KEYS = [\n\t\"as\",\n\t\"crossOrigin\",\n\t\"disabled\",\n\t\"fetchPriority\",\n\t\"href\",\n\t\"hreflang\",\n\t\"imageSizes\",\n\t\"imageSrcset\",\n\t\"integrity\",\n\t\"media\",\n\t\"referrerPolicy\",\n\t\"rel\",\n\t\"type\",\n\t\"charset\",\n\t\"rev\",\n\t\"target\",\n\t\"sizes\",\n] as const satisfies readonly (keyof HTMLLinkElement)[];\nconst linkExtractor = withBase<HTMLLinkElement>(HTML_LINK_KEYS);\n\nconst HTML_MAP_KEYS = [\"name\"] as const satisfies readonly (keyof HTMLMapElement)[];\nconst mapExtractor = withBase<HTMLMapElement>(HTML_MAP_KEYS);\n\nconst HTML_METER_KEYS = [\n\t\"high\",\n\t\"low\",\n\t\"max\",\n\t\"min\",\n\t\"optimum\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLMeterElement)[];\nconst meterExtractor = withBase<HTMLMeterElement>(HTML_METER_KEYS);\n\nconst HTML_MOD_KEYS = [\"cite\", \"dateTime\"] as const satisfies readonly (keyof HTMLModElement)[];\nconst modExtractor = withBase<HTMLModElement>(HTML_MOD_KEYS);\n\nconst HTML_OL_KEYS = [\n\t\"reversed\",\n\t\"start\",\n\t\"type\",\n\t\"compact\",\n] as const satisfies readonly (keyof HTMLOListElement)[];\nconst olistExtractor = withBase<HTMLOListElement>(HTML_OL_KEYS);\n\nconst HTML_OBJECT_KEYS = [\n\t\"data\",\n\t\"height\",\n\t\"name\",\n\t\"type\",\n\t\"useMap\",\n\t\"width\",\n\t\"validationMessage\",\n\t\"willValidate\",\n\t\"align\",\n\t\"archive\",\n\t\"border\",\n\t\"code\",\n\t\"codeBase\",\n\t\"codeType\",\n\t\"declare\",\n\t\"hspace\",\n\t\"standby\",\n\t\"vspace\",\n] as const satisfies readonly (keyof HTMLObjectElement)[];\nconst objectExtractor = withBase<HTMLObjectElement>(HTML_OBJECT_KEYS);\n\nconst HTML_OPTGROUP_KEYS = [\n\t\"disabled\",\n\t\"label\",\n] as const satisfies readonly (keyof HTMLOptGroupElement)[];\nconst optgroupExtractor = withBase<HTMLOptGroupElement>(HTML_OPTGROUP_KEYS);\n\nconst HTML_OPTION_KEYS = [\n\t\"defaultSelected\",\n\t\"disabled\",\n\t\"index\",\n\t\"label\",\n\t\"selected\",\n\t\"text\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLOptionElement)[];\nconst optionExtractor = withBase<HTMLOptionElement>(HTML_OPTION_KEYS);\n\nconst HTML_OUTPUT_KEYS = [\n\t\"defaultValue\",\n\t\"name\",\n\t\"type\",\n\t\"value\",\n\t\"htmlFor\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLOutputElement)[];\nconst outputExtractor = withBase<HTMLOutputElement>(HTML_OUTPUT_KEYS);\n\nconst HTML_PROGRESS_KEYS = [\n\t\"max\",\n\t\"position\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLProgressElement)[];\nconst progressExtractor = withBase<HTMLProgressElement>(HTML_PROGRESS_KEYS);\n\nconst HTML_QUOTE_KEYS = [\"cite\"] as const satisfies readonly (keyof HTMLQuoteElement)[];\nconst quoteExtractor = withBase<HTMLQuoteElement>(HTML_QUOTE_KEYS);\n\nconst citeExtractor = (elt: HTMLElement) => extractHTMLElementBase(elt);\n\nconst HTML_SCRIPT_KEYS = [\n\t\"async\",\n\t\"crossOrigin\",\n\t\"defer\",\n\t\"fetchPriority\",\n\t\"integrity\",\n\t\"noModule\",\n\t\"referrerPolicy\",\n\t\"src\",\n\t\"text\",\n\t\"type\",\n\t\"charset\",\n] as const satisfies readonly (keyof HTMLScriptElement)[];\nconst extractHTMLScriptOnly = createExtractor<HTMLScriptElement>()(HTML_SCRIPT_KEYS, {\n\tevent: (s) => (s as any).event,\n\thtmlFor: (s) => (s as any).htmlFor,\n});\nconst scriptExtractor = (elt: HTMLScriptElement) => ({\n\t...extractHTMLElementBase(elt),\n\t...extractHTMLScriptOnly(elt),\n});\n\nconst HTML_SELECT_KEYS = [\n\t\"autocomplete\",\n\t\"disabled\",\n\t\"length\",\n\t\"multiple\",\n\t\"name\",\n\t\"required\",\n\t\"selectedIndex\",\n\t\"size\",\n\t\"type\",\n\t\"value\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLSelectElement)[];\nconst selectExtractor = withBase<HTMLSelectElement>(HTML_SELECT_KEYS);\n\nconst HTML_SLOT_KEYS = [\"name\"] as const satisfies readonly (keyof HTMLSlotElement)[];\nconst slotExtractor = withBase<HTMLSlotElement>(HTML_SLOT_KEYS);\n\nconst HTML_SOURCE_KEYS = [\n\t\"height\",\n\t\"media\",\n\t\"sizes\",\n\t\"src\",\n\t\"srcset\",\n\t\"type\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLSourceElement)[];\nconst sourceExtractor = withBase<HTMLSourceElement>(HTML_SOURCE_KEYS);\n\nconst HTML_TABLE_CAPTION_KEYS = [\n\t\"align\",\n] as const satisfies readonly (keyof HTMLTableCaptionElement)[];\nconst tableCaptionExtractor = withBase<HTMLTableCaptionElement>(HTML_TABLE_CAPTION_KEYS);\n\nconst HTML_TABLE_CELL_KEYS = [\n\t\"abbr\",\n\t\"cellIndex\",\n\t\"colSpan\",\n\t\"headers\",\n\t\"rowSpan\",\n\t\"scope\",\n\t\"align\",\n\t\"axis\",\n\t\"bgColor\",\n\t\"ch\",\n\t\"chOff\",\n\t\"height\",\n\t\"noWrap\",\n\t\"vAlign\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableCellElement)[];\nconst tableCellExtractor = withBase<HTMLTableCellElement>(HTML_TABLE_CELL_KEYS);\n\nconst HTML_TABLE_COL_KEYS = [\n\t\"span\",\n\t\"align\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableColElement)[];\nconst tableColExtractor = withBase<HTMLTableColElement>(HTML_TABLE_COL_KEYS);\n\nconst HTML_TABLE_KEYS = [\n\t\"align\",\n\t\"bgColor\",\n\t\"border\",\n\t\"cellPadding\",\n\t\"cellSpacing\",\n\t\"frame\",\n\t\"rules\",\n\t\"summary\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableElement)[];\nconst tableExtractor = withBase<HTMLTableElement>(HTML_TABLE_KEYS);\n\nconst HTML_TR_KEYS = [\n\t\"rowIndex\",\n\t\"sectionRowIndex\",\n\t\"align\",\n\t\"bgColor\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n] as const satisfies readonly (keyof HTMLTableRowElement)[];\nconst tableRowExtractor = withBase<HTMLTableRowElement>(HTML_TR_KEYS);\n\nconst HTML_TSECTION_KEYS = [\n\t\"align\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n] as const satisfies readonly (keyof HTMLTableSectionElement)[];\nconst tableSectionExtractor = withBase<HTMLTableSectionElement>(HTML_TSECTION_KEYS);\n\nconst templateExtractor = (elt: HTMLTemplateElement) => extractHTMLElementBase(elt);\n\nconst HTML_TEXTAREA_KEYS = [\n\t\"autocomplete\",\n\t\"cols\",\n\t\"defaultValue\",\n\t\"dirName\",\n\t\"disabled\",\n\t\"maxLength\",\n\t\"minLength\",\n\t\"name\",\n\t\"placeholder\",\n\t\"readOnly\",\n\t\"required\",\n\t\"rows\",\n\t\"selectionDirection\",\n\t\"selectionEnd\",\n\t\"selectionStart\",\n\t\"value\",\n\t\"wrap\",\n\t\"textLength\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLTextAreaElement)[];\nconst textareaExtractor = withBase<HTMLTextAreaElement>(HTML_TEXTAREA_KEYS);\n\nconst HTML_TIME_KEYS = [\"dateTime\"] as const satisfies readonly (keyof HTMLTimeElement)[];\nconst timeExtractor = withBase<HTMLTimeElement>(HTML_TIME_KEYS);\n\nconst HTML_TRACK_KEYS = [\n\t\"default\",\n\t\"kind\",\n\t\"label\",\n\t\"readyState\",\n\t\"src\",\n\t\"srclang\",\n] as const satisfies readonly (keyof HTMLTrackElement)[];\nconst trackExtractor = withBase<HTMLTrackElement>(HTML_TRACK_KEYS);\n\nconst HTML_VIDEO_KEYS = [\n\t\"height\",\n\t\"poster\",\n\t\"videoHeight\",\n\t\"videoWidth\",\n\t\"width\",\n\t\"playsInline\",\n] as const satisfies readonly (keyof HTMLVideoElement)[];\nconst extractHTMLVideoOnly = createExtractor<HTMLVideoElement>()(HTML_VIDEO_KEYS);\nconst videoExtractor = (elt: HTMLVideoElement) => ({\n\t...mediaExtractor(elt),\n\t...extractHTMLVideoOnly(elt),\n});\n\nconst HTML_BR_KEYS = [\"clear\"] as const satisfies readonly (keyof HTMLBRElement)[];\nconst brExtractor = withBase<HTMLBRElement>(HTML_BR_KEYS);\n\nconst HTML_BASE_KEYS = [\"href\", \"target\"] as const satisfies readonly (keyof HTMLBaseElement)[];\nconst baseExtractor = withBase<HTMLBaseElement>(HTML_BASE_KEYS);\n\nconst HTML_BODY_KEYS = [\n\t\"aLink\",\n\t\"background\",\n\t\"bgColor\",\n\t\"link\",\n\t\"text\",\n\t\"vLink\",\n] as const satisfies readonly (keyof HTMLBodyElement)[];\nconst bodyExtractor = withBase<HTMLBodyElement>(HTML_BODY_KEYS);\n\nconst HTML_DLIST_KEYS = [\"compact\"] as const satisfies readonly (keyof HTMLDListElement)[];\nconst dlistExtractor = withBase<HTMLDListElement>(HTML_DLIST_KEYS);\n\nconst HTML_DETAILS_KEYS = [\"open\"] as const satisfies readonly (keyof HTMLDetailsElement)[];\nconst detailsExtractor = withBase<HTMLDetailsElement>(HTML_DETAILS_KEYS);\n\nconst HTML_DIALOG_KEYS = [\n\t\"open\",\n\t\"returnValue\",\n] as const satisfies readonly (keyof HTMLDialogElement)[];\nconst dialogExtractor = withBase<HTMLDialogElement>(HTML_DIALOG_KEYS);\n\nconst HTML_DIV_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLDivElement)[];\nconst divExtractor = withBase<HTMLDivElement>(HTML_DIV_KEYS);\n\nconst headExtractor = (elt: HTMLHeadElement) => extractHTMLElementBase(elt);\n\nconst HTML_HEADING_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLHeadingElement)[];\nconst headingExtractor = withBase<HTMLHeadingElement>(HTML_HEADING_KEYS);\n\nconst HTML_HR_KEYS = [\n\t\"align\",\n\t\"color\",\n\t\"noShade\",\n\t\"size\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLHRElement)[];\nconst hrExtractor = withBase<HTMLHRElement>(HTML_HR_KEYS);\n\nconst HTML_HTML_KEYS = [\"version\"] as const satisfies readonly (keyof HTMLHtmlElement)[];\nconst htmlExtractor = withBase<HTMLHtmlElement>(HTML_HTML_KEYS);\n\nconst menuExtractor = (elt: HTMLMenuElement) => extractHTMLElementBase(elt);\n\nconst HTML_META_KEYS = [\n\t\"content\",\n\t\"httpEquiv\",\n\t\"name\",\n\t\"scheme\",\n] as const satisfies readonly (keyof HTMLMetaElement)[];\nconst metaExtractor = withBase<HTMLMetaElement>(HTML_META_KEYS);\n\nconst HTML_P_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLParagraphElement)[];\nconst paragraphExtractor = withBase<HTMLParagraphElement>(HTML_P_KEYS);\n\nconst pictureExtractor = (elt: HTMLPictureElement) => extractHTMLElementBase(elt);\n\nconst HTML_PRE_KEYS = [\"width\"] as const satisfies readonly (keyof HTMLPreElement)[];\nconst preExtractor = withBase<HTMLPreElement>(HTML_PRE_KEYS);\n\nconst spanExtractor = (elt: HTMLSpanElement) => extractHTMLElementBase(elt);\n\nconst HTML_STYLE_KEYS = [\n\t\"media\",\n\t\"type\",\n\t\"disabled\",\n] as const satisfies readonly (keyof HTMLStyleElement)[];\nconst styleExtractor = withBase<HTMLStyleElement>(HTML_STYLE_KEYS);\n\nconst HTML_TITLE_KEYS = [\"text\"] as const satisfies readonly (keyof HTMLTitleElement)[];\nconst titleExtractor = withBase<HTMLTitleElement>(HTML_TITLE_KEYS);\n\nconst HTML_UL_KEYS = [\"compact\", \"type\"] as const satisfies readonly (keyof HTMLUListElement)[];\nconst ulistExtractor = withBase<HTMLUListElement>(HTML_UL_KEYS);\n\n// SVG element extractors\nfunction extractSVGElementBase(elt: SVGElement) {\n\treturn {\n\t\t...extractElementBase(elt),\n\t\t...extractHTMLOrSVGElement(elt as HTMLOrSVGElement),\n\t};\n}\n\n// Helper to compose per-SVG-element extractors with the shared base\nfunction withSVGBase<T extends SVGElement>(\n\tkeys: readonly (keyof T)[],\n\tcomputed?: Partial<Record<string, (src: T) => any>>,\n) {\n\tconst only = createExtractor<T>()(keys, computed as any);\n\treturn (elt: T) => ({ ...extractSVGElementBase(elt), ...only(elt) });\n}\n\nconst SVG_SVG_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"currentScale\",\n\t\"currentTranslate\",\n] as const satisfies readonly (keyof SVGSVGElement)[];\nconst svgExtractor = withSVGBase<SVGSVGElement>(SVG_SVG_KEYS);\n\nconst SVG_CIRCLE_KEYS = [\"cx\", \"cy\", \"r\"] as const satisfies readonly (keyof SVGCircleElement)[];\nconst circleExtractor = withSVGBase<SVGCircleElement>(SVG_CIRCLE_KEYS);\n\nconst SVG_ELLIPSE_KEYS = [\n\t\"cx\",\n\t\"cy\",\n\t\"rx\",\n\t\"ry\",\n] as const satisfies readonly (keyof SVGEllipseElement)[];\nconst ellipseExtractor = withSVGBase<SVGEllipseElement>(SVG_ELLIPSE_KEYS);\n\nconst SVG_LINE_KEYS = [\"x1\", \"y1\", \"x2\", \"y2\"] as const satisfies readonly (keyof SVGLineElement)[];\nconst lineExtractor = withSVGBase<SVGLineElement>(SVG_LINE_KEYS);\n\nconst SVG_PATH_KEYS = [\"pathLength\"] as const satisfies readonly (keyof SVGPathElement)[];\nconst pathExtractor = withSVGBase<SVGPathElement>(SVG_PATH_KEYS);\n\nconst SVG_RECT_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"rx\",\n\t\"ry\",\n] as const satisfies readonly (keyof SVGRectElement)[];\nconst rectExtractor = withSVGBase<SVGRectElement>(SVG_RECT_KEYS);\n\nconst SVG_POLYGON_KEYS = [\"points\"] as const satisfies readonly (keyof SVGPolygonElement)[];\nconst polygonExtractor = withSVGBase<SVGPolygonElement>(SVG_POLYGON_KEYS);\n\nconst SVG_POLYLINE_KEYS = [\"points\"] as const satisfies readonly (keyof SVGPolylineElement)[];\nconst polylineExtractor = withSVGBase<SVGPolylineElement>(SVG_POLYLINE_KEYS);\n\nconst SVG_TEXT_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"dx\",\n\t\"dy\",\n\t\"rotate\",\n\t\"textLength\",\n\t\"lengthAdjust\",\n] as const satisfies readonly (keyof SVGTextElement)[];\nconst textExtractor = withSVGBase<SVGTextElement>(SVG_TEXT_KEYS);\n\nconst SVG_TSPAN_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"dx\",\n\t\"dy\",\n\t\"rotate\",\n\t\"textLength\",\n\t\"lengthAdjust\",\n] as const satisfies readonly (keyof SVGTSpanElement)[];\nconst tspanExtractor = withSVGBase<SVGTSpanElement>(SVG_TSPAN_KEYS);\n\nconst SVG_IMAGE_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"href\",\n\t\"preserveAspectRatio\",\n\t\"crossOrigin\",\n] as const satisfies readonly (keyof SVGImageElement)[];\nconst svgImageExtractor = withSVGBase<SVGImageElement>(SVG_IMAGE_KEYS);\n\nconst SVG_USE_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"href\",\n] as const satisfies readonly (keyof SVGUseElement)[];\nconst useExtractor = withSVGBase<SVGUseElement>(SVG_USE_KEYS);\n\nconst SVG_DEFS_KEYS = [] as const satisfies readonly (keyof SVGDefsElement)[];\nconst defsExtractor = withSVGBase<SVGDefsElement>(SVG_DEFS_KEYS);\n\nconst SVG_GROUP_KEYS = [] as const satisfies readonly (keyof SVGGElement)[];\nconst gExtractor = withSVGBase<SVGGElement>(SVG_GROUP_KEYS);\n\nconst SVG_LINEAR_GRADIENT_KEYS = [\n\t\"x1\",\n\t\"y1\",\n\t\"x2\",\n\t\"y2\",\n\t\"gradientUnits\",\n\t\"gradientTransform\",\n\t\"spreadMethod\",\n] as const satisfies readonly (keyof SVGLinearGradientElement)[];\nconst linearGradientExtractor = withSVGBase<SVGLinearGradientElement>(SVG_LINEAR_GRADIENT_KEYS);\n\nconst SVG_RADIAL_GRADIENT_KEYS = [\n\t\"cx\",\n\t\"cy\",\n\t\"r\",\n\t\"fx\",\n\t\"fy\",\n\t\"fr\",\n\t\"gradientUnits\",\n\t\"gradientTransform\",\n\t\"spreadMethod\",\n] as const satisfies readonly (keyof SVGRadialGradientElement)[];\nconst radialGradientExtractor = withSVGBase<SVGRadialGradientElement>(SVG_RADIAL_GRADIENT_KEYS);\n\nconst SVG_STOP_KEYS = [\"offset\"] as const satisfies readonly (keyof SVGStopElement)[];\nconst stopExtractor = withSVGBase<SVGStopElement>(SVG_STOP_KEYS);\n\nconst SVG_PATTERN_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"patternUnits\",\n\t\"patternContentUnits\",\n\t\"patternTransform\",\n\t\"preserveAspectRatio\",\n\t\"href\",\n] as const satisfies readonly (keyof SVGPatternElement)[];\nconst patternExtractor = withSVGBase<SVGPatternElement>(SVG_PATTERN_KEYS);\n\nconst SVG_CLIP_PATH_KEYS = [\n\t\"clipPathUnits\",\n] as const satisfies readonly (keyof SVGClipPathElement)[];\nconst clipPathExtractor = withSVGBase<SVGClipPathElement>(SVG_CLIP_PATH_KEYS);\n\nconst SVG_MASK_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"maskUnits\",\n\t\"maskContentUnits\",\n] as const satisfies readonly (keyof SVGMaskElement)[];\nconst maskExtractor = withSVGBase<SVGMaskElement>(SVG_MASK_KEYS);\n\n// Map of tagName -> extractor (concise, like events.ts)\nconst elementExtractors: Record<string, (elt: any) => object> = {\n\tA: anchorExtractor,\n\tAREA: areaExtractor,\n\tAUDIO: audioExtractor,\n\tBASE: baseExtractor,\n\tBLOCKQUOTE: quoteExtractor,\n\tQ: quoteExtractor,\n\tBODY: bodyExtractor,\n\tBR: brExtractor,\n\tBUTTON: buttonExtractor,\n\tCANVAS: extractHTMLElementBase,\n\tCAPTION: tableCaptionExtractor,\n\tCITE: citeExtractor,\n\tCOL: tableColExtractor,\n\tCOLGROUP: tableColExtractor,\n\tDATA: dataExtractor,\n\tDETAILS: detailsExtractor,\n\tDIALOG: dialogExtractor,\n\tDIV: divExtractor,\n\tDL: dlistExtractor,\n\tEMBED: embedExtractor,\n\tFIELDSET: fieldsetExtractor,\n\tFORM: formExtractor,\n\tH1: headingExtractor,\n\tH2: headingExtractor,\n\tH3: headingExtractor,\n\tH4: headingExtractor,\n\tH5: headingExtractor,\n\tH6: headingExtractor,\n\tHEAD: headExtractor,\n\tHR: hrExtractor,\n\tHTML: htmlExtractor,\n\tIFRAME: iframeExtractor,\n\tIMG: imageExtractor,\n\tINPUT: inputExtractor,\n\tLABEL: labelExtractor,\n\tLI: liExtractor,\n\tLINK: linkExtractor,\n\tMAP: mapExtractor,\n\tMENU: menuExtractor,\n\tMETA: metaExtractor,\n\tMETER: meterExtractor,\n\tINS: modExtractor,\n\tDEL: modExtractor,\n\tOBJECT: objectExtractor,\n\tOL: olistExtractor,\n\tOPTGROUP: optgroupExtractor,\n\tOPTION: optionExtractor,\n\tOUTPUT: outputExtractor,\n\tP: paragraphExtractor,\n\tPICTURE: pictureExtractor,\n\tPRE: preExtractor,\n\tPROGRESS: progressExtractor,\n\tSCRIPT: scriptExtractor,\n\tSELECT: selectExtractor,\n\tSLOT: slotExtractor,\n\tSOURCE: sourceExtractor,\n\tSPAN: spanExtractor,\n\tSTYLE: styleExtractor,\n\tTABLE: tableExtractor,\n\tTBODY: tableSectionExtractor,\n\tTHEAD: tableSectionExtractor,\n\tTFOOT: tableSectionExtractor,\n\tTD: tableCellExtractor,\n\tTH: tableCellExtractor,\n\tTEMPLATE: templateExtractor,\n\tTEXTAREA: textareaExtractor,\n\tTIME: timeExtractor,\n\tTITLE: titleExtractor,\n\tTR: tableRowExtractor,\n\tTRACK: trackExtractor,\n\tUL: ulistExtractor,\n\tVIDEO: videoExtractor,\n\t// SVG elements\n\tSVG: svgExtractor,\n\tCIRCLE: circleExtractor,\n\tELLIPSE: ellipseExtractor,\n\tLINE: lineExtractor,\n\tPATH: pathExtractor,\n\tRECT: rectExtractor,\n\tPOLYGON: polygonExtractor,\n\tPOLYLINE: polylineExtractor,\n\tTEXT: textExtractor,\n\tTSPAN: tspanExtractor,\n\tIMAGE: svgImageExtractor,\n\tUSE: useExtractor,\n\tDEFS: defsExtractor,\n\tG: gExtractor,\n\tLINEARGRADIENT: linearGradientExtractor,\n\tRADIALGRADIENT: radialGradientExtractor,\n\tSTOP: stopExtractor,\n\tPATTERN: patternExtractor,\n\tCLIPPATH: clipPathExtractor,\n\tMASK: maskExtractor,\n};\n\nexport function extractHTMLElement(elt: HTMLElement): object {\n\tconst tagName = elt.tagName.toUpperCase();\n\n\tconst extractor = elementExtractors[tagName];\n\tif (extractor) {\n\t\treturn extractor(elt);\n\t}\n\tthrow new Error(`Unexpected HTML element tag: ${elt.tagName} (update .web/custom/serialize.ts)`);\n}\n\nexport function extractSVGElement(elt: SVGElement): object {\n\tconst tagName = elt.tagName.toUpperCase();\n\n\tconst extractor = elementExtractors[tagName];\n\tif (extractor) {\n\t\treturn extractor(elt);\n\t}\n\t// Fallback to base SVG element extractor for unknown SVG elements\n\treturn extractSVGElementBase(elt);\n}\n\nexport function extractElement(elt: Element): object {\n\tif (elt instanceof HTMLElement) {\n\t\treturn extractHTMLElement(elt);\n\t}\n\tif (elt instanceof SVGElement) {\n\t\treturn extractSVGElement(elt);\n\t}\n\t// Fallback for other Element types - use base element extractor\n\treturn extractElementBase(elt);\n}\n","/* === IMPORTANT === */\n\nimport type { MouseEvent, PointerEvent, SyntheticEvent, UIEvent } from \"react\";\nimport { extractElement } from \"./elements\";\nimport { createExtractor } from \"./extractor\";\n\n// Reusable computed mappers (helps bundlers/minifiers share references)\nconst mapTarget = (e: { target: EventTarget | null }) => extractElement(e.target as Element);\nconst mapRelated = (e: { relatedTarget: EventTarget | null }) =>\n\te.relatedTarget ? extractElement(e.relatedTarget as Element) : null;\n\nfunction makeExtractor<K extends readonly any[]>(\n\tkeys: K,\n\tcomputed?: Record<string, (evt: any) => any>,\n) {\n\treturn createExtractor<any>()(\n\t\tkeys as any,\n\t\t{\n\t\t\ttarget: mapTarget,\n\t\t\t...(computed || {}),\n\t\t} as any,\n\t);\n}\n\nconst SYNTHETIC_KEYS = [\n\t\"target\",\n\t\"bubbles\",\n\t\"cancelable\",\n\t\"defaultPrevented\",\n\t\"eventPhase\",\n\t\"isTrusted\",\n\t\"timeStamp\",\n\t\"type\",\n] as const satisfies readonly (keyof SyntheticEvent)[];\n\nconst UI_KEYS = [...SYNTHETIC_KEYS, \"detail\"] as const satisfies readonly (keyof UIEvent)[];\n\nconst MOUSE_KEYS = [\n\t...UI_KEYS,\n\t\"altKey\",\n\t\"button\",\n\t\"buttons\",\n\t\"clientX\",\n\t\"clientY\",\n\t\"ctrlKey\",\n\t\"metaKey\",\n\t\"movementX\",\n\t\"movementY\",\n\t\"pageX\",\n\t\"pageY\",\n\t\"screenX\",\n\t\"screenY\",\n\t\"shiftKey\",\n] as const satisfies readonly (keyof MouseEvent)[];\n\nconst POINTER_KEYS = [\n\t...MOUSE_KEYS,\n\t\"pointerId\",\n\t\"pressure\",\n\t\"tangentialPressure\",\n\t\"tiltX\",\n\t\"tiltY\",\n\t\"twist\",\n\t\"width\",\n\t\"height\",\n\t\"pointerType\",\n\t\"isPrimary\",\n] as const satisfies readonly (keyof PointerEvent)[];\n\nconst syntheticExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst uiExtractor = makeExtractor(UI_KEYS);\n\nconst mouseExtractor = makeExtractor(MOUSE_KEYS, { relatedTarget: mapRelated });\n\nconst clipboardExtractor = makeExtractor(SYNTHETIC_KEYS, {\n\tclipboardData: (e) => extractDataTransfer(e.clipboardData),\n});\n\nconst compositionExtractor = makeExtractor([...SYNTHETIC_KEYS, \"data\"] as const);\n\nconst dragExtractor = makeExtractor(MOUSE_KEYS, {\n\trelatedTarget: mapRelated,\n\tdataTransfer: (e) => extractDataTransfer(e.dataTransfer),\n});\n\nconst pointerExtractor = makeExtractor(POINTER_KEYS, {\n\trelatedTarget: mapRelated,\n});\n\nconst focusExtractor = makeExtractor(SYNTHETIC_KEYS, {\n\trelatedTarget: mapRelated,\n});\n\nconst formExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst invalidExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst changeExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst keyboardExtractor = makeExtractor([\n\t...UI_KEYS,\n\t\"altKey\",\n\t\"ctrlKey\",\n\t\"code\",\n\t\"key\",\n\t\"locale\",\n\t\"location\",\n\t\"metaKey\",\n\t\"repeat\",\n\t\"shiftKey\",\n] as const);\n\nconst touchExtractor = makeExtractor(\n\t[\n\t\t...UI_KEYS,\n\t\t\"altKey\",\n\t\t\"ctrlKey\",\n\t\t\"metaKey\",\n\t\t\"shiftKey\",\n\t\t\"changedTouches\",\n\t\t\"targetTouches\",\n\t\t\"touches\",\n\t] as const,\n\t{\n\t\tchangedTouches: (e) => mapTouchList(e.changedTouches),\n\t\ttargetTouches: (e) => mapTouchList(e.targetTouches),\n\t\ttouches: (e) => mapTouchList(e.touches),\n\t},\n);\n\nconst wheelExtractor = makeExtractor(\n\t[...MOUSE_KEYS, \"deltaMode\", \"deltaX\", \"deltaY\", \"deltaZ\"] as const,\n\t{\n\t\trelatedTarget: mapRelated,\n\t},\n);\n\nconst animationExtractor = makeExtractor([\n\t...SYNTHETIC_KEYS,\n\t\"animationName\",\n\t\"elapsedTime\",\n\t\"pseudoElement\",\n] as const);\n\nconst toggleExtractor = makeExtractor([...SYNTHETIC_KEYS, \"oldState\", \"newState\"] as const);\n\nconst transitionExtractor = makeExtractor([\n\t...SYNTHETIC_KEYS,\n\t\"elapsedTime\",\n\t\"propertyName\",\n\t\"pseudoElement\",\n] as const);\n\nfunction mapTouchList(list: any): any[] {\n\treturn Array.from(list as ArrayLike<any>).map((touch: any) => ({\n\t\ttarget: extractElement(touch.target as Element),\n\t\tidentifier: touch.identifier,\n\t\tscreenX: touch.screenX,\n\t\tscreenY: touch.screenY,\n\t\tclientX: touch.clientX,\n\t\tclientY: touch.clientY,\n\t\tpageX: touch.pageX,\n\t\tpageY: touch.pageY,\n\t}));\n}\n\n// Helper function to extract DataTransfer properties\nfunction extractDataTransfer(dt: DataTransfer | null): object | null {\n\tif (!dt) {\n\t\treturn null;\n\t}\n\tconst items = [];\n\tif (dt.items) {\n\t\tfor (let i = 0; i < dt.items.length; i++) {\n\t\t\tconst item = dt.items[i]!;\n\t\t\titems.push({\n\t\t\t\tkind: item.kind,\n\t\t\t\ttype: item.type,\n\t\t\t});\n\t\t}\n\t}\n\treturn {\n\t\tdrop_effect: dt.dropEffect,\n\t\teffect_allowed: dt.effectAllowed,\n\t\titems: items,\n\t\ttypes: Array.from(dt.types || []),\n\t};\n}\n\nconst eventExtractorMap: { [key: string]: (evt: any) => object } = {};\n\nfunction add(map: Record<string, any>, names: readonly string[], fn: any) {\n\tfor (const n of names) map[n] = fn;\n}\n\nadd(\n\teventExtractorMap,\n\t[\n\t\t\"pointerdown\",\n\t\t\"pointermove\",\n\t\t\"pointerup\",\n\t\t\"pointercancel\",\n\t\t\"gotpointercapture\",\n\t\t\"lostpointercapture\",\n\t\t\"pointerenter\",\n\t\t\"pointerleave\",\n\t\t\"pointerover\",\n\t\t\"pointerout\",\n\t],\n\tpointerExtractor,\n);\n\nadd(\n\teventExtractorMap,\n\t[\n\t\t\"click\",\n\t\t\"contextmenu\",\n\t\t\"dblclick\",\n\t\t\"mousedown\",\n\t\t\"mouseenter\",\n\t\t\"mouseleave\",\n\t\t\"mousemove\",\n\t\t\"mouseout\",\n\t\t\"mouseover\",\n\t\t\"mouseup\",\n\t],\n\tmouseExtractor,\n);\n\nadd(\n\teventExtractorMap,\n\t[\"drag\", \"dragend\", \"dragenter\", \"dragexit\", \"dragleave\", \"dragover\", \"dragstart\", \"drop\"],\n\tdragExtractor,\n);\n\nadd(eventExtractorMap, [\"keydown\", \"keypress\", \"keyup\"], keyboardExtractor);\nadd(eventExtractorMap, [\"focus\", \"blur\"], focusExtractor);\nadd(eventExtractorMap, [\"change\", \"input\"], changeExtractor);\nadd(eventExtractorMap, [\"invalid\"], invalidExtractor);\nadd(eventExtractorMap, [\"reset\", \"submit\"], formExtractor);\nadd(eventExtractorMap, [\"copy\", \"cut\", \"paste\"], clipboardExtractor);\nadd(\n\teventExtractorMap,\n\t[\"compositionend\", \"compositionstart\", \"compositionupdate\"],\n\tcompositionExtractor,\n);\nadd(eventExtractorMap, [\"touchcancel\", \"touchend\", \"touchmove\", \"touchstart\"], touchExtractor);\nadd(eventExtractorMap, [\"scroll\"], uiExtractor);\nadd(eventExtractorMap, [\"wheel\"], wheelExtractor);\nadd(\n\teventExtractorMap,\n\t[\"animationstart\", \"animationend\", \"animationiteration\"],\n\tanimationExtractor,\n);\nadd(eventExtractorMap, [\"transitionend\"], transitionExtractor);\nadd(eventExtractorMap, [\"toggle\"], toggleExtractor);\n\nexport function extractEvent(value: any): any {\n\t// Duck-typing for React's SyntheticEvent.\n\t// We check for properties that are unique to synthetic events.\n\tif (\n\t\tvalue &&\n\t\ttypeof value === \"object\" &&\n\t\t\"nativeEvent\" in value &&\n\t\ttypeof value.isDefaultPrevented === \"function\"\n\t) {\n\t\tconst evt = value as SyntheticEvent;\n\t\t// The `type` property is crucial for the lookup.\n\t\tif (typeof evt.type !== \"string\") {\n\t\t\treturn value;\n\t\t}\n\n\t\tconst extractor = eventExtractorMap[evt.type.toLowerCase()];\n\t\tif (extractor) {\n\t\t\treturn extractor(evt);\n\t\t}\n\n\t\t// Fallback for unknown event types: minimal synthetic extractor\n\t\treturn syntheticExtractor(evt);\n\t}\n\n\t// If it's not a duck-typed event, return it as is.\n\treturn value;\n}\n","export type Primitive = number | string | boolean | null | undefined;\nexport type JSON<T> = T | Array<JSON<T>> | { [K: string]: JSON<T> };\nexport type PlainJSON = JSON<Primitive>;\nexport type Serializable = any;\n\nexport type Serialized = [[number[], number[], number[], number[]], PlainJSON];\n\nexport function serialize(data: Serializable): Serialized {\n\tconst seen = new Map<any, number>();\n\tconst refs: number[] = [];\n\tconst dates: number[] = [];\n\tconst sets: number[] = [];\n\tconst maps: number[] = [];\n\n\t// Single global counter - increments once per node visit\n\tlet globalIndex = 0;\n\n\tfunction process(value: Serializable, context?: string): PlainJSON {\n\t\tif (value == null || typeof value === \"string\" || typeof value === \"boolean\") {\n\t\t\treturn value;\n\t\t}\n\n\t\tif (typeof value === \"number\") {\n\t\t\tif (Number.isNaN(value)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!Number.isFinite(value)) {\n\t\t\t\tconst kind = value > 0 ? \"Infinity\" : \"-Infinity\";\n\t\t\t\tconst ctx = context ? ` in '${context}'` : \"\";\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot serialize ${kind}${ctx}. NaN and Infinity are not supported because they cannot be serialized to JSON.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\n\t\tconst idx = globalIndex++;\n\t\tconst prevRef = seen.get(value);\n\t\tif (prevRef !== undefined) {\n\t\t\t// Make sure to push the current index, but use the ref's index as the value!\n\t\t\trefs.push(idx);\n\t\t\treturn prevRef;\n\t\t}\n\n\t\tseen.set(value, idx);\n\n\t\tif (value instanceof Date) {\n\t\t\tdates.push(idx);\n\t\t\treturn value.toISOString();\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tconst length = value.length;\n\t\t\tconst result = new Array(length);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tresult[i] = process(value[i], context);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tif (value instanceof Map) {\n\t\t\tmaps.push(idx);\n\t\t\tconst rec: Record<string, any> = {};\n\t\t\tfor (const [key, entry] of value.entries()) {\n\t\t\t\trec[String(key)] = process(entry, String(key));\n\t\t\t}\n\t\t\treturn rec;\n\t\t}\n\n\t\tif (value instanceof Set) {\n\t\t\tsets.push(idx);\n\t\t\tconst size = value.size;\n\t\t\tconst result = new Array(size);\n\t\t\tlet i = 0;\n\t\t\tfor (const entry of value) {\n\t\t\t\tresult[i] = process(entry, context);\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tif (typeof value === \"object\") {\n\t\t\tconst rec: Record<string, any> = {};\n\t\t\tconst keys = Object.keys(value);\n\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\tconst key = keys[i];\n\t\t\t\trec[key] = process(value[key], key);\n\t\t\t}\n\t\t\treturn rec;\n\t\t}\n\n\t\tthrow new Error(`Unsupported value in serialization: ${value}`);\n\t}\n\n\tconst payload = process(data);\n\treturn [[refs, dates, sets, maps], payload];\n}\n\nexport interface DeserializationOptions {\n\tcoerceNullsToUndefined?: boolean;\n}\n\nexport function deserialize<Data extends Serializable = Serializable>(\n\tpayload: Serialized,\n\toptions?: DeserializationOptions,\n): Data {\n\tconst [[refsA, datesA, setsA, mapsA], data] = payload;\n\n\tconst refs = new Set(refsA);\n\tconst dates = new Set(datesA);\n\tconst sets = new Set(setsA);\n\tconst maps = new Set(mapsA);\n\n\tconst objects: Array<any> = [];\n\n\tfunction reconstruct(value: PlainJSON): any {\n\t\tconst idx = objects.length;\n\t\tif (refs.has(idx)) {\n\t\t\t// We increment the counter on refs during serialization. We're never\n\t\t\t// going to use this entry, so we can just push null.\n\t\t\tobjects.push(null);\n\t\t\treturn objects[value as number];\n\t\t}\n\n\t\tif (dates.has(idx)) {\n\t\t\tif (typeof value !== \"string\") {\n\t\t\t\tthrow new Error(\"Date payload must be an ISO string\");\n\t\t\t}\n\t\t\tconst literal = parseDateLiteral(value);\n\t\t\tif (literal) {\n\t\t\t\tconst [y, m, d] = literal;\n\t\t\t\tconst dt = new Date(Date.UTC(y, m - 1, d));\n\t\t\t\tobjects.push(dt);\n\t\t\t\treturn dt;\n\t\t\t}\n\t\t\tif (isDateLiteral(value)) {\n\t\t\t\tthrow new Error(`Invalid date literal: ${value}`);\n\t\t\t}\n\t\t\tconst dt = new Date(value);\n\t\t\tobjects.push(dt);\n\t\t\treturn dt;\n\t\t}\n\n\t\tif (\n\t\t\tvalue == null ||\n\t\t\ttypeof value === \"number\" ||\n\t\t\ttypeof value === \"string\" ||\n\t\t\ttypeof value === \"boolean\"\n\t\t) {\n\t\t\tif (options?.coerceNullsToUndefined) {\n\t\t\t\treturn value ?? undefined;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tif (sets.has(idx)) {\n\t\t\t\tconst result = new Set();\n\t\t\t\tobjects.push(result);\n\t\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\t\tresult.add(reconstruct(value[i]));\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tconst length = value.length;\n\t\t\tconst arr = new Array(length);\n\t\t\tobjects.push(arr);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tarr[i] = reconstruct(value[i]);\n\t\t\t}\n\t\t\treturn arr;\n\t\t}\n\n\t\tif (typeof value === \"object\") {\n\t\t\tif (maps.has(idx)) {\n\t\t\t\tconst result = new Map<string, any>();\n\t\t\t\tobjects.push(result);\n\t\t\t\tconst keys = Object.keys(value);\n\t\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\t\tconst key = keys[i];\n\t\t\t\t\tresult.set(key, reconstruct(value[key]));\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tconst result: Record<string, any> = {};\n\t\t\tobjects.push(result);\n\t\t\tconst keys = Object.keys(value);\n\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\tconst key = keys[i];\n\t\t\t\tresult[key] = reconstruct(value[key]);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tthrow new Error(`Unsupported value in deserialization: ${value}`);\n\t}\n\n\treturn reconstruct(data);\n}\n\nconst DATE_LITERAL_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction isDateLiteral(value: string): boolean {\n\treturn DATE_LITERAL_RE.test(value);\n}\n\nfunction parseDateLiteral(value: string): [number, number, number] | null {\n\tif (!isDateLiteral(value)) {\n\t\treturn null;\n\t}\n\tconst [yStr, mStr, dStr] = value.split(\"-\");\n\tconst y = Number(yStr);\n\tconst m = Number(mStr);\n\tconst d = Number(dStr);\n\tif (!Number.isInteger(y) || !Number.isInteger(m) || !Number.isInteger(d)) {\n\t\treturn null;\n\t}\n\tif (m < 1 || m > 12 || d < 1 || d > 31) {\n\t\treturn null;\n\t}\n\tconst dt = new Date(Date.UTC(y, m - 1, d));\n\tif (\n\t\tdt.getUTCFullYear() !== y ||\n\t\tdt.getUTCMonth() !== m - 1 ||\n\t\tdt.getUTCDate() !== d\n\t) {\n\t\treturn null;\n\t}\n\treturn [y, m, d];\n}\n","import type { NavigateFunction } from \"react-router\";\nimport { io, type Socket } from \"socket.io-client\";\nimport { ChannelBridge, PulseChannelResetError } from \"./channel\";\nimport type { RouteInfo } from \"./helpers\";\nimport type {\n\tClientApiResultMessage,\n\tClientJsResultMessage,\n\tClientMessage,\n\tServerApiCallMessage,\n\tServerChannelMessage,\n\tServerError,\n\tServerJsExecMessage,\n\tServerMessage,\n} from \"./messages\";\nimport type { PulsePrerenderView } from \"./pulse\";\nimport { extractEvent } from \"./serialize/events\";\nimport { deserialize, serialize } from \"./serialize/serializer\";\nimport type { VDOMUpdate } from \"./vdom\";\n\nexport interface SocketIODirectives {\n\theaders?: Record<string, string>;\n\tauth?: Record<string, string>;\n}\nexport interface Directives {\n\theaders?: Record<string, string>;\n\tsocketio?: SocketIODirectives;\n}\nexport interface MountedView {\n\trouteInfo: RouteInfo;\n\tonInit: (view: PulsePrerenderView) => void;\n\tonUpdate: (ops: VDOMUpdate[]) => void;\n\tonJsExec: (msg: ServerJsExecMessage) => void;\n\tonServerError: (error: ServerError) => void;\n}\nexport type ConnectionStatus = \"ok\" | \"connecting\" | \"reconnecting\" | \"error\";\nexport type ConnectionStatusListener = (status: ConnectionStatus) => void;\n\nexport interface PulseClient {\n\t// Connection management\n\tconnect(): Promise<void>;\n\tdisconnect(): void;\n\tisConnected(): boolean;\n\tonConnectionChange(listener: ConnectionStatusListener): () => void;\n\t// Messages\n\tupdateRoute(path: string, routeInfo: RouteInfo): void;\n\tinvokeCallback(path: string, callback: string, args: any[]): void;\n\t// VDOM subscription\n\tattach(path: string, view: MountedView): void;\n\tdetach(path: string): void;\n}\n\nexport class PulseSocketIOClient {\n\t#activeViews: Map<string, MountedView>;\n\t#socket: Socket | null = null;\n\t#messageQueue: ClientMessage[];\n\t#connectionListeners: Set<ConnectionStatusListener> = new Set();\n\t#channels: Map<string, { bridge: ChannelBridge; refCount: number }> = new Map();\n\t#url: string;\n\t#frameworkNavigate: NavigateFunction;\n\t#directives: Directives;\n\t#connectionStatusConfig: {\n\t\tinitialConnectingDelay: number;\n\t\tinitialErrorDelay: number;\n\t\treconnectErrorDelay: number;\n\t};\n\t#hasConnectedOnce: boolean = false;\n\t#connectingTimeout: ReturnType<typeof setTimeout> | null = null;\n\t#errorTimeout: ReturnType<typeof setTimeout> | null = null;\n\t#currentStatus: ConnectionStatus = \"ok\";\n\n\tconstructor(\n\t\turl: string,\n\t\tdirectives: Directives,\n\t\tframeworkNavigate: NavigateFunction,\n\t\tconnectionStatusConfig: {\n\t\t\tinitialConnectingDelay: number;\n\t\t\tinitialErrorDelay: number;\n\t\t\treconnectErrorDelay: number;\n\t\t},\n\t) {\n\t\tthis.#url = url;\n\t\tthis.#directives = directives;\n\t\tthis.#frameworkNavigate = frameworkNavigate;\n\t\tthis.#socket = null;\n\t\tthis.#activeViews = new Map();\n\t\tthis.#messageQueue = [];\n\t\tthis.#connectionStatusConfig = connectionStatusConfig;\n\t}\n\tpublic setDirectives(directives: Directives) {\n\t\tthis.#directives = directives;\n\t}\n\tpublic isConnected(): boolean {\n\t\treturn this.#socket?.connected ?? false;\n\t}\n\n\t#clearTimeouts(): void {\n\t\tif (this.#connectingTimeout) {\n\t\t\tclearTimeout(this.#connectingTimeout);\n\t\t\tthis.#connectingTimeout = null;\n\t\t}\n\t\tif (this.#errorTimeout) {\n\t\t\tclearTimeout(this.#errorTimeout);\n\t\t\tthis.#errorTimeout = null;\n\t\t}\n\t}\n\n\t#setStatus(status: ConnectionStatus): void {\n\t\tthis.#clearTimeouts();\n\t\tthis.#currentStatus = status;\n\t\tthis.#notifyConnectionListeners(status);\n\t}\n\n\t#handleConnected(): void {\n\t\tthis.#hasConnectedOnce = true;\n\t\tthis.#setStatus(\"ok\");\n\t}\n\n\t#setInitialConnectionStatus(): void {\n\t\t// Initial connection attempt - start with no message, then show connecting after delay\n\t\tthis.#setStatus(\"ok\");\n\t\tthis.#connectingTimeout = setTimeout(() => {\n\t\t\tthis.#setStatus(\"connecting\");\n\t\t\tthis.#errorTimeout = setTimeout(() => {\n\t\t\t\tthis.#setStatus(\"error\");\n\t\t\t}, this.#connectionStatusConfig.initialErrorDelay);\n\t\t}, this.#connectionStatusConfig.initialConnectingDelay);\n\t}\n\n\t#handleDisconnected(): void {\n\t\t// Reconnection after losing connection - show reconnecting immediately\n\t\tthis.#setStatus(\"reconnecting\");\n\t\tthis.#errorTimeout = setTimeout(() => {\n\t\t\tthis.#setStatus(\"error\");\n\t\t}, this.#connectionStatusConfig.reconnectErrorDelay);\n\t}\n\n\tpublic async connect(): Promise<void> {\n\t\tif (this.#socket) {\n\t\t\treturn;\n\t\t}\n\t\t// Start timing logic for connection attempt\n\t\tif (!this.#hasConnectedOnce) {\n\t\t\tthis.#setInitialConnectionStatus();\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst socket = io(this.#url, {\n\t\t\t\ttransports: [\"websocket\", \"webtransport\"],\n\t\t\t\tauth: this.#directives.socketio?.auth,\n\t\t\t\textraHeaders: this.#directives.socketio?.headers,\n\t\t\t});\n\t\t\tthis.#socket = socket;\n\n\t\t\tsocket.on(\"connect\", () => {\n\t\t\t\tconsole.log(\"[SocketIOTransport] Connected:\", this.#socket?.id);\n\t\t\t\t// Send attach for all active views on connect/reconnect\n\t\t\t\tfor (const [path, route] of this.#activeViews) {\n\t\t\t\t\tsocket.emit(\n\t\t\t\t\t\t\"message\",\n\t\t\t\t\t\tserialize({\n\t\t\t\t\t\t\ttype: \"attach\",\n\t\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\t\trouteInfo: route.routeInfo,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tfor (const payload of this.#messageQueue) {\n\t\t\t\t\t// Already sent above\n\t\t\t\t\tif (payload.type === \"attach\" && this.#activeViews.has(payload.path)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t// We're reattaching all the routes, so no need to send update\n\t\t\t\t\tif (payload.type === \"update\") {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tsocket.emit(\"message\", serialize(payload));\n\t\t\t\t}\n\t\t\t\tthis.#messageQueue = [];\n\n\t\t\t\tthis.#handleConnected();\n\t\t\t\tresolve();\n\t\t\t});\n\n\t\t\tsocket.on(\"connect_error\", (err) => {\n\t\t\t\tconsole.error(\"[SocketIOTransport] Connection failed:\", err);\n\t\t\t\tthis.#handleDisconnected();\n\t\t\t\treject(err);\n\t\t\t});\n\n\t\t\tsocket.on(\"disconnect\", () => {\n\t\t\t\tconsole.log(\"[SocketIOTransport] Disconnected\");\n\t\t\t\tthis.#handleTransportDisconnect();\n\t\t\t\tthis.#handleDisconnected();\n\t\t\t});\n\n\t\t\t// Wrap in an arrow function to avoid losing the `this` reference\n\t\t\tsocket.on(\"message\", (data) =>\n\t\t\t\tthis.#handleServerMessage(deserialize(data, { coerceNullsToUndefined: true })),\n\t\t\t);\n\t\t});\n\t}\n\n\tonConnectionChange(listener: ConnectionStatusListener): () => void {\n\t\tthis.#connectionListeners.add(listener);\n\t\t// Notify immediately with current status\n\t\tlistener(this.#currentStatus);\n\t\treturn () => {\n\t\t\tthis.#connectionListeners.delete(listener);\n\t\t};\n\t}\n\n\t#notifyConnectionListeners(status: ConnectionStatus): void {\n\t\tfor (const listener of this.#connectionListeners) {\n\t\t\tlistener(status);\n\t\t}\n\t}\n\n\tpublic sendMessage(payload: ClientMessage) {\n\t\tif (this.isConnected()) {\n\t\t\t// console.log(\"[SocketIOTransport] Sending:\", payload);\n\t\t\tthis.#socket!.emit(\"message\", serialize(payload as any));\n\t\t} else {\n\t\t\t// console.log(\"[SocketIOTransport] Queuing message:\", payload);\n\t\t\tthis.#messageQueue.push(payload);\n\t\t}\n\t}\n\n\tpublic attach(path: string, view: MountedView) {\n\t\tif (this.#activeViews.has(path)) {\n\t\t\tthrow new Error(`Path ${path} is already attached`);\n\t\t}\n\t\tthis.#activeViews.set(path, view);\n\t\tvoid this.sendMessage({\n\t\t\ttype: \"attach\",\n\t\t\tpath,\n\t\t\trouteInfo: view.routeInfo,\n\t\t});\n\t}\n\n\tpublic updateRoute(path: string, routeInfo: RouteInfo) {\n\t\tconst view = this.#activeViews.get(path);\n\t\tif (view) {\n\t\t\tview.routeInfo = routeInfo;\n\t\t\tthis.sendMessage({\n\t\t\t\ttype: \"update\",\n\t\t\t\tpath,\n\t\t\t\trouteInfo,\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic detach(path: string) {\n\t\tvoid this.sendMessage({ type: \"detach\", path });\n\t\tthis.#activeViews.delete(path);\n\t}\n\n\tpublic disconnect() {\n\t\tthis.#clearTimeouts();\n\t\tthis.#socket?.disconnect();\n\t\tthis.#socket = null;\n\t\tthis.#messageQueue = [];\n\t\tthis.#connectionListeners.clear();\n\t\tthis.#activeViews.clear();\n\t\tfor (const { bridge } of this.#channels.values()) {\n\t\t\tbridge.dispose(new PulseChannelResetError(\"Client disconnected\"));\n\t\t}\n\t\tthis.#channels.clear();\n\t\tthis.#currentStatus = \"ok\";\n\t\tthis.#hasConnectedOnce = false;\n\t}\n\n\t#handleServerMessage(message: ServerMessage) {\n\t\t// console.log(\"[PulseClient] Received message:\", message);\n\t\tswitch (message.type) {\n\t\t\tcase \"vdom_init\": {\n\t\t\t\tconst route = this.#activeViews.get(message.path);\n\t\t\t\t// Ignore messages for paths that are not mounted\n\t\t\t\tif (!route) return;\n\t\t\t\troute.onInit(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"vdom_update\": {\n\t\t\t\tconst route = this.#activeViews.get(message.path);\n\t\t\t\tif (!route) return; // Not an active path; discard\n\t\t\t\troute.onUpdate(message.ops);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"server_error\": {\n\t\t\t\tconst route = this.#activeViews.get(message.path);\n\t\t\t\tif (!route) return; // discard for inactive paths\n\t\t\t\troute.onServerError(message.error);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"api_call\": {\n\t\t\t\tvoid this.#performApiCall(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"navigate_to\": {\n\t\t\t\tconst replace = !!message.replace;\n\t\t\t\tlet dest = message.path || \"\";\n\t\t\t\tif (dest.startsWith(\"//\")) dest = `${window.location.protocol}${dest}`;\n\n\t\t\t\tconst hardNav = () =>\n\t\t\t\t\treplace ? window.location.replace(dest) : window.location.assign(dest);\n\n\t\t\t\tif (message.hard) {\n\t\t\t\t\thardNav();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// No scheme = relative path → SPA\n\t\t\t\tif (!/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(dest)) {\n\t\t\t\t\tthis.#frameworkNavigate(dest, { replace });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Same-origin http(s) → SPA\n\t\t\t\tif (/^https?:\\/\\//.test(dest)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst url = new URL(dest);\n\t\t\t\t\t\tif (url.origin === window.location.origin) {\n\t\t\t\t\t\t\tthis.#frameworkNavigate(`${url.pathname}${url.search}${url.hash}`, { replace });\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {}\n\t\t\t\t}\n\n\t\t\t\t// External URL or other scheme (mailto:, tel:, etc.)\n\t\t\t\thardNav();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"reload\": {\n\t\t\t\twindow.location.reload();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"channel_message\": {\n\t\t\t\tthis.#routeChannelMessage(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"js_exec\": {\n\t\t\t\tthis.#handleJsExec(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconsole.error(\"Unexpected message:\", message);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync #performApiCall(msg: ServerApiCallMessage) {\n\t\ttry {\n\t\t\tconst res = await fetch(msg.url, {\n\t\t\t\tmethod: msg.method || \"GET\",\n\t\t\t\theaders: {\n\t\t\t\t\t...(msg.headers || {}),\n\t\t\t\t\t...(msg.body != null && !(\"content-type\" in (msg.headers || {}))\n\t\t\t\t\t\t? { \"content-type\": \"application/json\" }\n\t\t\t\t\t\t: {}),\n\t\t\t\t},\n\t\t\t\tbody:\n\t\t\t\t\tmsg.body != null\n\t\t\t\t\t\t? typeof msg.body === \"string\"\n\t\t\t\t\t\t\t? msg.body\n\t\t\t\t\t\t\t: JSON.stringify(msg.body)\n\t\t\t\t\t\t: undefined,\n\t\t\t\tcredentials: msg.credentials || \"include\",\n\t\t\t});\n\t\t\tconst headersObj: Record<string, string> = {};\n\t\t\tres.headers.forEach((v, k) => {\n\t\t\t\theadersObj[k] = v;\n\t\t\t});\n\t\t\tlet body: any = null;\n\t\t\tconst ct = res.headers.get(\"content-type\") || \"\";\n\t\t\tif (ct.includes(\"application/json\")) {\n\t\t\t\tbody = await res.json().catch(() => null);\n\t\t\t} else {\n\t\t\t\tbody = await res.text().catch(() => null);\n\t\t\t}\n\t\t\tconst reply: ClientApiResultMessage = {\n\t\t\t\ttype: \"api_result\",\n\t\t\t\tid: msg.id,\n\t\t\t\tok: res.ok,\n\t\t\t\tstatus: res.status,\n\t\t\t\theaders: headersObj,\n\t\t\t\tbody,\n\t\t\t};\n\t\t\tthis.sendMessage(reply);\n\t\t} catch (err) {\n\t\t\tconst reply: ClientApiResultMessage = {\n\t\t\t\ttype: \"api_result\",\n\t\t\t\tid: msg.id,\n\t\t\t\tok: false,\n\t\t\t\tstatus: 0,\n\t\t\t\theaders: {},\n\t\t\t\tbody: { error: String(err) },\n\t\t\t};\n\t\t\tthis.sendMessage(reply);\n\t\t}\n\t}\n\n\tpublic invokeCallback(path: string, callback: string, args: any[]) {\n\t\tthis.sendMessage({\n\t\t\ttype: \"callback\",\n\t\t\tpath,\n\t\t\tcallback,\n\t\t\targs: args.map(extractEvent),\n\t\t});\n\t}\n\n\t#handleJsExec(message: ServerJsExecMessage) {\n\t\tconst view = this.#activeViews.get(message.path);\n\t\tif (!view) {\n\t\t\t// View unmounted before the message arrived - send result back to unblock\n\t\t\t// the server-side future (which is likely already cancelled anyway).\n\t\t\tthis.#sendJsResult(message.id, undefined, null);\n\t\t\treturn;\n\t\t}\n\t\tview.onJsExec(message);\n\t}\n\n\tpublic sendJsResult(id: string, result: any, error: string | null) {\n\t\tthis.#sendJsResult(id, result, error);\n\t}\n\n\t#sendJsResult(id: string, result: any, error: string | null) {\n\t\tconst msg: ClientJsResultMessage = {\n\t\t\ttype: \"js_result\",\n\t\t\tid,\n\t\t\tresult,\n\t\t\terror,\n\t\t};\n\t\tthis.sendMessage(msg);\n\t}\n\n\tpublic acquireChannel(id: string): ChannelBridge {\n\t\tconst entry = this.#ensureChannelEntry(id);\n\t\tentry.refCount += 1;\n\t\treturn entry.bridge;\n\t}\n\n\tpublic releaseChannel(id: string): void {\n\t\tconst entry = this.#channels.get(id);\n\t\tif (!entry) {\n\t\t\treturn;\n\t\t}\n\t\tentry.refCount = Math.max(0, entry.refCount - 1);\n\t\tif (entry.refCount === 0) {\n\t\t\tentry.bridge.dispose(new PulseChannelResetError(\"Channel released\"));\n\t\t\tthis.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: id,\n\t\t\t\tevent: \"__close__\",\n\t\t\t\tpayload: { reason: \"refcount_zero\" },\n\t\t\t});\n\t\t\tthis.#channels.delete(id);\n\t\t}\n\t}\n\n\t#ensureChannelEntry(id: string): {\n\t\tbridge: ChannelBridge;\n\t\trefCount: number;\n\t} {\n\t\tlet entry = this.#channels.get(id);\n\t\tif (!entry) {\n\t\t\tentry = {\n\t\t\t\tbridge: new ChannelBridge(this, id),\n\t\t\t\trefCount: 0,\n\t\t\t};\n\t\t\tthis.#channels.set(id, entry);\n\t\t}\n\t\treturn entry;\n\t}\n\n\t#routeChannelMessage(message: ServerChannelMessage): void {\n\t\tconst entry = this.#ensureChannelEntry(message.channel);\n\t\tconst closed = entry.bridge.handleServerMessage(message);\n\t\tif (closed && entry.refCount === 0) {\n\t\t\tthis.#channels.delete(message.channel);\n\t\t}\n\t}\n\n\t#handleTransportDisconnect(): void {\n\t\tfor (const entry of this.#channels.values()) {\n\t\t\tentry.bridge.handleDisconnect(new PulseChannelResetError(\"Connection lost\"));\n\t\t}\n\t}\n}\n","// =============================================================================\n// VDOM (structural expressions + eval-keyed props)\n// =============================================================================\n\nexport const FRAGMENT_TAG = \"\";\nexport const MOUNT_POINT_PREFIX = \"$$\";\n\n// Unified registry: mount-point key -> React component (or any registry object).\nexport type ComponentRegistry = Record<string, any>;\n\n// -----------------------------------------------------------------------------\n// JSON types\n// -----------------------------------------------------------------------------\n\nexport type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonValue[] | { [k: string]: JsonValue };\n\n// -----------------------------------------------------------------------------\n// Expression tree (client-evaluable)\n// -----------------------------------------------------------------------------\n\nexport type VDOMExpr =\n\t| RegistryRefExpr\n\t| IdentifierExpr\n\t| LiteralExpr\n\t| UndefinedExpr\n\t| ArrayExpr\n\t| ObjectExpr\n\t| MemberExpr\n\t| SubscriptExpr\n\t| CallExpr\n\t| UnaryExpr\n\t| BinaryExpr\n\t| TernaryExpr\n\t| TemplateExpr\n\t| ArrowExpr\n\t| NewExpr;\n\nexport interface RegistryRefExpr {\n\tt: \"ref\";\n\tkey: string;\n}\n\nexport interface IdentifierExpr {\n\tt: \"id\";\n\tname: string;\n}\n\nexport interface LiteralExpr {\n\tt: \"lit\";\n\tvalue: JsonPrimitive;\n}\n\nexport interface UndefinedExpr {\n\tt: \"undef\";\n}\n\nexport interface ArrayExpr {\n\tt: \"array\";\n\titems: VDOMNode[];\n}\n\nexport interface ObjectExpr {\n\tt: \"object\";\n\tprops: Record<string, VDOMNode>;\n}\n\nexport interface MemberExpr {\n\tt: \"member\";\n\tobj: VDOMNode;\n\tprop: string;\n}\n\nexport interface SubscriptExpr {\n\tt: \"sub\";\n\tobj: VDOMNode;\n\tkey: VDOMNode;\n}\n\nexport interface CallExpr {\n\tt: \"call\";\n\tcallee: VDOMNode;\n\targs: VDOMNode[];\n}\n\nexport interface UnaryExpr {\n\tt: \"unary\";\n\top: string;\n\targ: VDOMNode;\n}\n\nexport interface BinaryExpr {\n\tt: \"binary\";\n\top: string;\n\tleft: VDOMNode;\n\tright: VDOMNode;\n}\n\nexport interface TernaryExpr {\n\tt: \"ternary\";\n\tcond: VDOMNode;\n\tthen: VDOMNode;\n\telse_: VDOMNode;\n}\n\nexport interface TemplateExpr {\n\tt: \"template\";\n\tparts: Array<string | VDOMNode>;\n}\n\nexport interface ArrowExpr {\n\tt: \"arrow\";\n\tparams: string[];\n\tbody: VDOMNode;\n}\n\nexport interface NewExpr {\n\tt: \"new\";\n\tctor: VDOMNode;\n\targs: VDOMNode[];\n}\n\n// -----------------------------------------------------------------------------\n// VDOM tree\n// -----------------------------------------------------------------------------\n\nexport type CallbackPlaceholder = \"$cb\" | `$cb:${number}`;\n\nexport type VDOMPropValue = JsonValue | VDOMExpr | VDOMElement | CallbackPlaceholder;\n\nexport interface VDOMElement {\n\ttag: string | VDOMExpr;\n\tkey?: string;\n\tprops?: Record<string, VDOMPropValue>;\n\tchildren?: VDOMNode[];\n\t// Prop keys that should be interpreted (expr / render-prop subtree / callback binding).\n\t// When absent, props are treated as plain JSON.\n\teval?: string[];\n}\n\nexport type VDOMNode = JsonPrimitive | VDOMElement | VDOMExpr;\nexport type VDOM = VDOMNode;\n\nexport function isElementNode(node: VDOMNode): node is VDOMElement {\n\treturn typeof node === \"object\" && node !== null && \"tag\" in node;\n}\n\nexport function isExprNode(node: unknown): node is VDOMExpr {\n\treturn typeof node === \"object\" && node !== null && \"t\" in (node as any);\n}\n\nexport function isMountPointNode(node: VDOMNode): node is VDOMElement {\n\treturn (\n\t\tisElementNode(node) &&\n\t\ttypeof node.tag === \"string\" &&\n\t\tnode.tag.startsWith(MOUNT_POINT_PREFIX) &&\n\t\tnode.tag !== FRAGMENT_TAG\n\t);\n}\n\n// -----------------------------------------------------------------------------\n// Updates\n// -----------------------------------------------------------------------------\n\nexport interface VDOMUpdateBase {\n\ttype: string;\n\tpath: string;\n}\n\nexport interface ReplaceUpdate extends VDOMUpdateBase {\n\ttype: \"replace\";\n\tdata: VDOM;\n}\n\nexport interface UpdatePropsUpdate extends VDOMUpdateBase {\n\ttype: \"update_props\";\n\tdata: {\n\t\tset?: Record<string, VDOMPropValue>;\n\t\tremove?: string[];\n\t\t// Replace the eval list for this element.\n\t\t// - absent/undefined: keep previous\n\t\t// - []: clear\n\t\teval?: string[];\n\t};\n}\n\nexport interface ReconciliationUpdate {\n\ttype: \"reconciliation\";\n\tpath: string;\n\tN: number;\n\tnew: [number[], VDOM[]];\n\treuse: [number[], number[]];\n}\n\nexport type VDOMUpdate = ReplaceUpdate | UpdatePropsUpdate | ReconciliationUpdate;\n","import {\n\ttype ComponentType,\n\tcloneElement,\n\tcreateElement,\n\tFragment,\n\tisValidElement,\n\ttype ReactElement,\n\ttype ReactNode,\n} from \"react\";\nimport type { PulseSocketIOClient } from \"./client\";\nimport type { PulsePrerenderView } from \"./pulse\";\nimport { extractEvent } from \"./serialize/events\";\nimport type {\n\tComponentRegistry,\n\tJsonValue,\n\tVDOM,\n\tVDOMNode,\n\tVDOMPropValue,\n\tVDOMUpdate,\n} from \"./vdom\";\nimport { isElementNode, isExprNode, MOUNT_POINT_PREFIX as REF_PREFIX } from \"./vdom\";\n\ntype Env = Record<string, unknown>;\n\ntype CallbackDelay = number | null;\n\ntype CallbackEntry = {\n\tfn: (...args: any[]) => void;\n\tdelayMs: CallbackDelay;\n\ttimer: ReturnType<typeof setTimeout> | null;\n\tlastArgs: any[] | null;\n\tdueAt: number | null;\n};\n\nfunction parseCallbackPlaceholder(value: unknown): CallbackDelay | undefined {\n\tif (value === \"$cb\") return null;\n\tif (typeof value !== \"string\" || !value.startsWith(\"$cb:\")) return undefined;\n\tconst raw = value.slice(4);\n\tif (raw.length === 0) {\n\t\tthrow new Error(\"[Pulse] Invalid callback placeholder: '$cb:'\");\n\t}\n\tconst delay = Number(raw);\n\tif (!Number.isFinite(delay) || delay < 0) {\n\t\tthrow new Error(`[Pulse] Invalid callback debounce delay: ${value}`);\n\t}\n\treturn delay;\n}\n\ntype ElementMeta = {\n\teval?: Set<string>;\n\tpath?: string;\n\tcallbacks?: Map<string, CallbackEntry>;\n};\n\nexport class VDOMRenderer {\n\t#client: PulseSocketIOClient;\n\t#path: string;\n\t#registry: ComponentRegistry;\n\n\t// Track callback entries for teardown.\n\t#callbackEntries: Set<CallbackEntry>;\n\n\t// Track eval keys + callback entries per ReactElement (not real props).\n\t#metaMap: WeakMap<ReactElement, ElementMeta>;\n\n\tconstructor(client: PulseSocketIOClient, path: string, registry: ComponentRegistry = {}) {\n\t\tthis.#client = client;\n\t\tthis.#path = path;\n\t\tthis.#registry = registry;\n\t\tthis.#callbackEntries = new Set();\n\t\tthis.#metaMap = new WeakMap();\n\t}\n\n\tgetObject(key: string): unknown {\n\t\tconst obj = (this.#registry as any)[key];\n\t\tif (obj === undefined) {\n\t\t\tthrow new Error(`[Pulse] Unknown registry key: ${key}`);\n\t\t}\n\t\treturn obj;\n\t}\n\n\t#resolveIdentifier(name: string): unknown {\n\t\tconst v = (globalThis as any)[name];\n\t\tif (v === undefined) {\n\t\t\tthrow new Error(`[Pulse] Unknown identifier in expr: ${name}`);\n\t\t}\n\t\treturn v;\n\t}\n\n\t#evalExpr(expr: VDOMNode, env: Env): unknown {\n\t\t// Handle primitives directly (wire format optimization)\n\t\tif (expr === null || typeof expr !== \"object\") {\n\t\t\treturn expr;\n\t\t}\n\t\t// Handle VDOMElement (has \"tag\" instead of \"t\")\n\t\tif (\"tag\" in expr) {\n\t\t\treturn this.renderNode(expr, \"\");\n\t\t}\n\t\tswitch (expr.t) {\n\t\t\tcase \"ref\":\n\t\t\t\treturn this.getObject(expr.key);\n\t\t\tcase \"id\":\n\t\t\t\tif (Object.hasOwn(env, expr.name)) return env[expr.name];\n\t\t\t\treturn this.#resolveIdentifier(expr.name);\n\t\t\tcase \"lit\":\n\t\t\t\treturn expr.value;\n\t\t\tcase \"undef\":\n\t\t\t\treturn undefined;\n\t\t\tcase \"array\": {\n\t\t\t\tconst out: unknown[] = [];\n\t\t\t\tfor (const it of expr.items) {\n\t\t\t\t\tout.push(this.#evalExpr(it, env));\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t}\n\t\t\tcase \"object\": {\n\t\t\t\tconst out: Record<string, unknown> = {};\n\t\t\t\tfor (const [k, vexpr] of Object.entries(expr.props)) {\n\t\t\t\t\tout[k] = this.#evalExpr(vexpr, env);\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t}\n\t\t\tcase \"member\": {\n\t\t\t\tconst obj = this.#evalExpr(expr.obj, env) as any;\n\t\t\t\treturn obj?.[expr.prop];\n\t\t\t}\n\t\t\tcase \"sub\": {\n\t\t\t\tconst obj = this.#evalExpr(expr.obj, env) as any;\n\t\t\t\tconst key = this.#evalExpr(expr.key, env) as any;\n\t\t\t\treturn obj?.[key];\n\t\t\t}\n\t\t\tcase \"call\": {\n\t\t\t\tconst fn = this.#evalExpr(expr.callee, env) as any;\n\t\t\t\tconst args = expr.args.map((a) => this.#evalExpr(a, env));\n\t\t\t\tif (typeof fn !== \"function\") throw new Error(\"[Pulse] call callee is not a function\");\n\t\t\t\treturn fn(...args);\n\t\t\t}\n\t\t\tcase \"unary\": {\n\t\t\t\tconst v = this.#evalExpr(expr.arg, env) as any;\n\t\t\t\tswitch (expr.op) {\n\t\t\t\t\tcase \"!\":\n\t\t\t\t\t\treturn !v;\n\t\t\t\t\tcase \"+\":\n\t\t\t\t\t\treturn +v;\n\t\t\t\t\tcase \"-\":\n\t\t\t\t\t\treturn -v;\n\t\t\t\t\tcase \"typeof\":\n\t\t\t\t\t\treturn typeof v;\n\t\t\t\t\tcase \"void\":\n\t\t\t\t\t\treturn void v;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`[Pulse] Unsupported unary op: ${expr.op}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase \"binary\": {\n\t\t\t\tconst l = this.#evalExpr(expr.left, env) as any;\n\t\t\t\tconst r = this.#evalExpr(expr.right, env) as any;\n\t\t\t\tswitch (expr.op) {\n\t\t\t\t\tcase \"+\":\n\t\t\t\t\t\treturn l + r;\n\t\t\t\t\tcase \"-\":\n\t\t\t\t\t\treturn l - r;\n\t\t\t\t\tcase \"*\":\n\t\t\t\t\t\treturn l * r;\n\t\t\t\t\tcase \"/\":\n\t\t\t\t\t\treturn l / r;\n\t\t\t\t\tcase \"%\":\n\t\t\t\t\t\treturn l % r;\n\t\t\t\t\tcase \"&&\":\n\t\t\t\t\t\treturn l && r;\n\t\t\t\t\tcase \"||\":\n\t\t\t\t\t\treturn l || r;\n\t\t\t\t\tcase \"??\":\n\t\t\t\t\t\treturn l ?? r;\n\t\t\t\t\tcase \"**\":\n\t\t\t\t\t\treturn l ** r;\n\t\t\t\t\tcase \"in\":\n\t\t\t\t\t\treturn l in r;\n\t\t\t\t\tcase \"instanceof\":\n\t\t\t\t\t\treturn l instanceof r;\n\t\t\t\t\tcase \"===\":\n\t\t\t\t\t\treturn l === r;\n\t\t\t\t\tcase \"!==\":\n\t\t\t\t\t\treturn l !== r;\n\t\t\t\t\tcase \"<\":\n\t\t\t\t\t\treturn l < r;\n\t\t\t\t\tcase \"<=\":\n\t\t\t\t\t\treturn l <= r;\n\t\t\t\t\tcase \">\":\n\t\t\t\t\t\treturn l > r;\n\t\t\t\t\tcase \">=\":\n\t\t\t\t\t\treturn l >= r;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`[Pulse] Unsupported binary op: ${expr.op}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase \"ternary\":\n\t\t\t\treturn this.#evalExpr(expr.cond, env)\n\t\t\t\t\t? this.#evalExpr(expr.then, env)\n\t\t\t\t\t: this.#evalExpr(expr.else_, env);\n\t\t\tcase \"template\": {\n\t\t\t\tlet s = \"\";\n\t\t\t\tfor (const part of expr.parts) {\n\t\t\t\t\tif (typeof part === \"string\") s += part;\n\t\t\t\t\telse s += String(this.#evalExpr(part, env));\n\t\t\t\t}\n\t\t\t\treturn s;\n\t\t\t}\n\t\t\tcase \"arrow\": {\n\t\t\t\tconst params = expr.params;\n\t\t\t\treturn (...args: unknown[]) => {\n\t\t\t\t\tconst nextEnv: Env = { ...env };\n\t\t\t\t\tfor (let i = 0; i < params.length; i += 1) nextEnv[params[i]!] = args[i];\n\t\t\t\t\treturn this.#evalExpr(expr.body, nextEnv);\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"new\": {\n\t\t\t\tconst Ctor = this.#evalExpr(expr.ctor, env) as any;\n\t\t\t\tconst args = expr.args.map((a) => this.#evalExpr(a, env));\n\t\t\t\treturn new Ctor(...args);\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`[Pulse] Unknown expr node: ${(expr as any).t}`);\n\t\t}\n\t}\n\n\t#propPath(path: string, prop: string) {\n\t\treturn path ? `${path}.${prop}` : prop;\n\t}\n\n\t#clearPending(entry: CallbackEntry) {\n\t\tif (entry.timer) {\n\t\t\tclearTimeout(entry.timer);\n\t\t}\n\t\tentry.timer = null;\n\t\tentry.lastArgs = null;\n\t\tentry.dueAt = null;\n\t}\n\n\t#firePending(entry: CallbackEntry, fire: (args: any[]) => void) {\n\t\tconst args = entry.lastArgs;\n\t\tthis.#clearPending(entry);\n\t\tif (!args) return;\n\t\tfire(args);\n\t}\n\n\t#scheduleDebounced(\n\t\tentry: CallbackEntry,\n\t\tdelayMs: number,\n\t\targs: any[],\n\t\tfire: (args: any[]) => void,\n\t) {\n\t\tif (entry.timer) clearTimeout(entry.timer);\n\t\tentry.lastArgs = args;\n\t\tentry.dueAt = Date.now() + delayMs;\n\t\tentry.timer = setTimeout(() => {\n\t\t\tthis.#firePending(entry, fire);\n\t\t}, delayMs);\n\t}\n\n\t#dropCallback(meta: ElementMeta, prop: string) {\n\t\tconst callbacks = meta.callbacks;\n\t\tif (!callbacks) return;\n\t\tconst entry = callbacks.get(prop);\n\t\tif (!entry) return;\n\t\tthis.#clearPending(entry);\n\t\tthis.#callbackEntries.delete(entry);\n\t\tcallbacks.delete(prop);\n\t\tif (callbacks.size === 0) {\n\t\t\tmeta.callbacks = undefined;\n\t\t}\n\t}\n\n\t#ensureCallbackEntry(meta: ElementMeta, prop: string): CallbackEntry {\n\t\tif (!meta.callbacks) {\n\t\t\tmeta.callbacks = new Map();\n\t\t}\n\t\tconst callbacks = meta.callbacks;\n\t\tlet entry = callbacks.get(prop);\n\t\tif (!entry) {\n\t\t\tconst fire = (args: any[]) => {\n\t\t\t\tconst key = this.#propPath(meta.path ?? \"\", prop);\n\t\t\t\tthis.#client.invokeCallback(this.#path, key, args);\n\t\t\t};\n\t\t\tentry = {\n\t\t\t\tfn: (...args: any[]) => {\n\t\t\t\t\tif (entry!.delayMs == null) {\n\t\t\t\t\t\tfire(args);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst callArgs = args.map(extractEvent);\n\t\t\t\t\tthis.#scheduleDebounced(entry!, entry!.delayMs, callArgs, fire);\n\t\t\t\t},\n\t\t\t\tdelayMs: null,\n\t\t\t\ttimer: null,\n\t\t\t\tlastArgs: null,\n\t\t\t\tdueAt: null,\n\t\t\t};\n\t\t\tcallbacks.set(prop, entry);\n\t\t\tthis.#callbackEntries.add(entry);\n\t\t}\n\t\treturn entry;\n\t}\n\n\t#dropCallbacksInSubtree(node: ReactNode, path: string) {\n\t\tif (node == null || typeof node === \"boolean\" || typeof node === \"number\" || typeof node === \"string\") {\n\t\t\treturn;\n\t\t}\n\t\tif (Array.isArray(node)) {\n\t\t\tfor (let i = 0; i < node.length; i += 1) {\n\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\tthis.#dropCallbacksInSubtree(node[i], childPath);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (!isValidElement(node)) return;\n\t\tconst element = node as ReactElement<Record<string, any> | null>;\n\t\tconst meta = this.#metaMap.get(element);\n\t\tconst basePath = meta?.path ?? path;\n\t\tconst callbacks = meta?.callbacks;\n\t\tif (callbacks && callbacks.size > 0) {\n\t\t\tfor (const entry of callbacks.values()) {\n\t\t\t\tthis.#clearPending(entry);\n\t\t\t\tthis.#callbackEntries.delete(entry);\n\t\t\t}\n\t\t\tcallbacks.clear();\n\t\t\tmeta!.callbacks = undefined;\n\t\t}\n\t\tconst baseProps = (element.props ?? {}) as Record<string, any>;\n\t\tfor (const key of Object.keys(baseProps)) {\n\t\t\tif (key === \"children\") continue;\n\t\t\tconst v = baseProps[key];\n\t\t\tthis.#dropCallbacksInSubtree(v, this.#propPath(basePath, key));\n\t\t}\n\t\tconst children = this.#ensureChildrenArray(element);\n\t\tfor (let i = 0; i < children.length; i += 1) {\n\t\t\tconst childPath = basePath ? `${basePath}.${i}` : String(i);\n\t\t\tthis.#dropCallbacksInSubtree(children[i], childPath);\n\t\t}\n\t}\n\n\t#getCallback(meta: ElementMeta, prop: string, delayMs: CallbackDelay) {\n\t\tconst entry = this.#ensureCallbackEntry(meta, prop);\n\t\tif (entry.delayMs !== delayMs) {\n\t\t\tentry.delayMs = delayMs;\n\t\t}\n\t\treturn entry.fn;\n\t}\n\n\t#transformEvalProp(path: string, meta: ElementMeta, prop: string, value: VDOMPropValue) {\n\t\tconst cbDelay = parseCallbackPlaceholder(value);\n\t\tif (cbDelay !== undefined) return this.#getCallback(meta, prop, cbDelay);\n\t\tif (isExprNode(value)) return this.#evalExpr(value, {});\n\t\tif (typeof value === \"object\" && value !== null && \"tag\" in value) {\n\t\t\t// Render-prop subtree; traverse as a prop path segment (non-numeric).\n\t\t\treturn this.renderNode(value as VDOMNode, this.#propPath(path, prop));\n\t\t}\n\t\t// Eval-marked but still JSON => pass through.\n\t\treturn value as JsonValue;\n\t}\n\n\t#rememberMeta(el: ReactElement, meta: ElementMeta) {\n\t\tthis.#metaMap.set(el, meta);\n\t\treturn el;\n\t}\n\n\tclearPendingCallbacks() {\n\t\tfor (const entry of Array.from(this.#callbackEntries)) {\n\t\t\tthis.#clearPending(entry);\n\t\t}\n\t\t// Keep entries so StrictMode cleanup (no real unmount) can still cancel\n\t\t// future debounced calls on the reused renderer instance.\n\t}\n\n\trenderNode(node: VDOMNode, currentPath = \"\"): ReactNode {\n\t\t// primitives\n\t\tif (node == null || typeof node === \"boolean\" || typeof node === \"number\") return node;\n\t\tif (typeof node === \"string\") return node;\n\n\t\t// expr\n\t\tif (isExprNode(node)) return this.#evalExpr(node, {}) as ReactNode;\n\n\t\t// element\n\t\tif (isElementNode(node)) {\n\t\t\tconst { tag, props = {}, children = [], eval: evalKeys } = node;\n\t\t\t// 1. Resolve component\n\t\t\tlet component: React.ComponentType<any> | string;\n\t\t\tif (typeof tag === \"string\") {\n\t\t\t\tif (tag.startsWith(REF_PREFIX)) {\n\t\t\t\t\tconst key = tag.slice(REF_PREFIX.length);\n\t\t\t\t\tcomponent = this.#registry[key] as React.ComponentType<any>;\n\n\t\t\t\t\tif (!component) {\n\t\t\t\t\t\tthrow new Error(`[Pulse] Missing component '${key}'`);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcomponent = tag.length > 0 ? tag : Fragment;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcomponent = this.#evalExpr(tag, {}) as any;\n\t\t\t}\n\t\t\t// 2. Build props\n\t\t\tconst newProps: Record<string, any> = {};\n\t\t\tlet evalSet: Set<string> | undefined;\n\t\t\tconst meta: ElementMeta = { path: currentPath };\n\t\t\tif (!evalKeys) {\n\t\t\t\t// Hot path: no eval -> props are plain JSON; copy as-is.\n\t\t\t\tfor (const [propName, propValue] of Object.entries(props)) {\n\t\t\t\t\tnewProps[propName] = propValue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tevalSet = new Set(evalKeys);\n\t\t\t\tmeta.eval = evalSet;\n\t\t\t\tfor (const [propName, propValue] of Object.entries(props)) {\n\t\t\t\t\tif (!evalSet.has(propName)) {\n\t\t\t\t\t\tnewProps[propName] = propValue;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tnewProps[propName] = this.#transformEvalProp(\n\t\t\t\t\t\tcurrentPath,\n\t\t\t\t\t\tmeta,\n\t\t\t\t\t\tpropName,\n\t\t\t\t\t\tpropValue,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (node.key) newProps.key = node.key;\n\n\t\t\t// 3. Render children\n\t\t\tconst renderedChildren: ReactNode[] = [];\n\t\t\tfor (let i = 0; i < children.length; i += 1) {\n\t\t\t\tconst child = children[i]!;\n\t\t\t\tconst childPath = currentPath ? `${currentPath}.${i}` : String(i);\n\t\t\t\trenderedChildren.push(this.renderNode(child, childPath));\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\treturn this.#rememberMeta(\n\t\t\t\t\tcreateElement(component, newProps, ...renderedChildren),\n\t\t\t\t\tmeta,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"[Pulse] Failed to create element:\", node)\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\tif (process.env.NODE_ENV !== \"production\") {\n\t\t\tconsole.error(\"Unknown VDOM node:\", node);\n\t\t}\n\t\treturn null;\n\t}\n\n\tinit(view: PulsePrerenderView & { vdom: VDOM }): ReactNode {\n\t\treturn this.renderNode(view.vdom);\n\t}\n\n\t/**\n\t * Evaluate a VDOMNode expression (for run_js support).\n\t */\n\tevaluateExpr(expr: VDOMNode): unknown {\n\t\treturn this.#evalExpr(expr, {});\n\t}\n\n\t#ensureChildrenArray(el: ReactElement): ReactNode[] {\n\t\tconst children = (el.props as any)?.children as ReactNode | undefined;\n\t\tif (children == null) return [];\n\t\treturn Array.isArray(children) ? children.slice() : [children];\n\t}\n\n\t#cloneWithMeta(prev: ReactElement, next: ReactElement) {\n\t\tconst meta = this.#metaMap.get(prev);\n\t\tif (meta) this.#metaMap.set(next, meta);\n\t\treturn next;\n\t}\n\n\t// Update paths within a subtree after a move so callbacks resolve correctly.\n\t#rebindCallbacksInSubtree(node: ReactNode, path: string): ReactNode {\n\t\tif (node == null || typeof node === \"boolean\" || typeof node === \"number\" || typeof node === \"string\") {\n\t\t\treturn node;\n\t\t}\n\t\tif (Array.isArray(node)) {\n\t\t\tfor (let i = 0; i < node.length; i += 1) {\n\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\tthis.#rebindCallbacksInSubtree(node[i], childPath);\n\t\t\t}\n\t\t\treturn node;\n\t\t}\n\t\tif (!isValidElement(node)) return node;\n\t\tconst element = node as ReactElement<Record<string, any> | null>;\n\t\tconst meta = this.#metaMap.get(element);\n\t\tif (meta) {\n\t\t\tmeta.path = path;\n\t\t} else {\n\t\t\tthis.#metaMap.set(element, { path });\n\t\t}\n\n\t\tconst baseProps = (element.props ?? {}) as Record<string, any>;\n\t\tfor (const key of Object.keys(baseProps)) {\n\t\t\tif (key === \"children\") continue;\n\t\t\tconst v = baseProps[key];\n\t\t\tthis.#rebindCallbacksInSubtree(v, this.#propPath(path, key));\n\t\t}\n\n\t\tconst children = this.#ensureChildrenArray(element);\n\t\tfor (let i = 0; i < children.length; i += 1) {\n\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\tthis.#rebindCallbacksInSubtree(children[i], childPath);\n\t\t}\n\n\t\treturn node;\n\t}\n\n\tapplyUpdates(initialTree: ReactNode, updates: VDOMUpdate[]): ReactNode {\n\t\tlet newTree: ReactNode = initialTree;\n\t\tfor (const update of updates) {\n\t\t\tconst parts = update.path.split(\".\").filter((s) => s.length > 0);\n\n\t\t\tconst descend = (node: ReactNode, depth: number, path: string): ReactNode => {\n\t\t\t\tif (depth < parts.length) {\n\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\tconst element = node as ReactElement<Record<string, any> | null>;\n\t\t\t\t\tconst childKey = parts[depth]!;\n\t\t\t\t\tconst childIdx = +childKey;\n\t\t\t\t\tconst childPath = path ? `${path}.${childKey}` : childKey;\n\t\t\t\t\tif (!Number.isNaN(childIdx)) {\n\t\t\t\t\t\tconst childrenArr = this.#ensureChildrenArray(element);\n\t\t\t\t\t\tconst child = childrenArr[childIdx];\n\t\t\t\t\t\tchildrenArr[childIdx] = descend(child, depth + 1, childPath) as any;\n\t\t\t\t\t\treturn this.#cloneWithMeta(element, cloneElement(element, undefined, ...childrenArr));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst baseProps = (element.props ?? {}) as Record<string, any>;\n\t\t\t\t\t\tconst child = baseProps[childKey];\n\t\t\t\t\t\tconst props = { ...baseProps, [childKey]: descend(child, depth + 1, childPath) };\n\t\t\t\t\t\treturn this.#cloneWithMeta(element, cloneElement(element, props));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tswitch (update.type) {\n\t\t\t\t\tcase \"replace\":\n\t\t\t\t\t\tthis.#dropCallbacksInSubtree(node, path);\n\t\t\t\t\t\treturn this.renderNode(update.data, update.path);\n\n\t\t\t\t\tcase \"update_props\": {\n\t\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\t\tconst element = node as ReactElement;\n\t\t\t\t\t\tconst currentProps = (element.props ?? {}) as Record<string, any>;\n\t\t\t\t\t\tconst nextProps: Record<string, any> = { ...currentProps };\n\n\t\t\t\t\t\tconst prevMeta = this.#metaMap.get(element);\n\t\t\t\t\t\tconst meta: ElementMeta = prevMeta ?? {};\n\t\t\t\t\t\tconst prevEval = meta.eval;\n\t\t\t\t\t\tconst prevPath = prevMeta?.path ?? path;\n\t\t\t\t\t\tconst evalPatch = update.data.eval;\n\t\t\t\t\t\tconst nextEval: Set<string> | undefined =\n\t\t\t\t\t\t\tevalPatch === undefined\n\t\t\t\t\t\t\t\t? prevEval\n\t\t\t\t\t\t\t\t: evalPatch.length === 0\n\t\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t\t: new Set(evalPatch);\n\t\t\t\t\t\tconst evalCleared = evalPatch !== undefined && evalPatch.length === 0;\n\n\t\t\t\t\t\t// Drop callbacks that are no longer eval-bound.\n\t\t\t\t\t\tif (nextEval && meta.callbacks) {\n\t\t\t\t\t\t\tfor (const k of Array.from(meta.callbacks.keys())) {\n\t\t\t\t\t\t\t\tif (!nextEval.has(k)) {\n\t\t\t\t\t\t\t\t\tthis.#dropCallback(meta, k);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (evalCleared && meta.callbacks) {\n\t\t\t\t\t\t\tfor (const k of Array.from(meta.callbacks.keys())) {\n\t\t\t\t\t\t\t\tdelete nextProps[k];\n\t\t\t\t\t\t\t\tthis.#dropCallback(meta, k);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (update.data.remove && update.data.remove.length > 0) {\n\t\t\t\t\t\t\tfor (const key of update.data.remove) {\n\t\t\t\t\t\t\t\tconst removedValue = currentProps[key];\n\t\t\t\t\t\t\t\tif (removedValue !== undefined) {\n\t\t\t\t\t\t\t\t\tthis.#dropCallbacksInSubtree(removedValue, this.#propPath(prevPath, key));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tdelete nextProps[key];\n\t\t\t\t\t\t\t\tif (meta.callbacks?.has(key)) {\n\t\t\t\t\t\t\t\t\tthis.#dropCallback(meta, key);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (update.data.set) {\n\t\t\t\t\t\t\tfor (const [k, v] of Object.entries(update.data.set)) {\n\t\t\t\t\t\t\t\tconst prevValue = currentProps[k];\n\t\t\t\t\t\t\t\tif (prevValue !== undefined) {\n\t\t\t\t\t\t\t\t\tthis.#dropCallbacksInSubtree(prevValue, this.#propPath(prevPath, k));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Only interpret eval-marked keys; otherwise treat as JSON.\n\t\t\t\t\t\t\t\tconst isEval = nextEval?.has(k) === true;\n\t\t\t\t\t\t\t\tconst cbDelay = isEval ? parseCallbackPlaceholder(v) : undefined;\n\t\t\t\t\t\t\t\tnextProps[k] = isEval\n\t\t\t\t\t\t\t\t\t? this.#transformEvalProp(path, meta, k, v as any)\n\t\t\t\t\t\t\t\t\t: (v as any);\n\t\t\t\t\t\t\t\tif (cbDelay === undefined && meta.callbacks?.has(k)) {\n\t\t\t\t\t\t\t\t\tthis.#dropCallback(meta, k);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmeta.eval = nextEval;\n\t\t\t\t\t\tmeta.path = path;\n\n\t\t\t\t\t\tconst removedSomething = (update.data.remove?.length ?? 0) > 0;\n\t\t\t\t\t\tif (removedSomething) {\n\t\t\t\t\t\t\tnextProps.key = (element as any).key;\n\t\t\t\t\t\t\tnextProps.ref = (element as any).ref;\n\t\t\t\t\t\t\treturn this.#rememberMeta(\n\t\t\t\t\t\t\t\tcreateElement(element.type, nextProps, ...this.#ensureChildrenArray(element)),\n\t\t\t\t\t\t\t\tmeta,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn this.#rememberMeta(cloneElement(element, nextProps), meta);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcase \"reconciliation\": {\n\t\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\t\tconst element = node as ReactElement;\n\t\t\t\t\t\tconst prevChildren = this.#ensureChildrenArray(element);\n\t\t\t\t\t\tconst nextChildren: ReactNode[] = [];\n\n\t\t\t\t\t\tconst [newIndices, newContents] = update.new;\n\t\t\t\t\t\tconst [reuseIndices, reuseSources] = update.reuse;\n\t\t\t\t\t\tconst newIndexSet = new Set(newIndices);\n\t\t\t\t\t\tconst reuseIndexSet = new Set(reuseIndices);\n\t\t\t\t\t\tconst reuseSourceSet = new Set(reuseSources);\n\t\t\t\t\t\tfor (let i = 0; i < prevChildren.length; i += 1) {\n\t\t\t\t\t\t\tconst reused =\n\t\t\t\t\t\t\t\treuseSourceSet.has(i) ||\n\t\t\t\t\t\t\t\t(i < update.N && !newIndexSet.has(i) && !reuseIndexSet.has(i));\n\t\t\t\t\t\t\tif (!reused) {\n\t\t\t\t\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\t\t\t\t\tthis.#dropCallbacksInSubtree(prevChildren[i], childPath);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet nextNew = -1,\n\t\t\t\t\t\t\tnextReuse = -1,\n\t\t\t\t\t\t\tnewIdx = -1,\n\t\t\t\t\t\t\treuseIdx = -1;\n\t\t\t\t\t\tif (newIndices.length > 0) {\n\t\t\t\t\t\t\tnextNew = newIndices[0]!;\n\t\t\t\t\t\t\tnewIdx = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (reuseIndices.length > 0) {\n\t\t\t\t\t\t\tnextReuse = reuseIndices[0]!;\n\t\t\t\t\t\t\treuseIdx = 0;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (let i = 0; i < update.N; i += 1) {\n\t\t\t\t\t\t\tif (i === nextNew) {\n\t\t\t\t\t\t\t\tconst contents = newContents[newIdx]!;\n\t\t\t\t\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\t\t\t\t\tnextChildren.push(this.renderNode(contents, childPath));\n\t\t\t\t\t\t\t\tnextNew = newIdx < newIndices.length - 1 ? newIndices[++newIdx]! : -1;\n\t\t\t\t\t\t\t} else if (i === nextReuse) {\n\t\t\t\t\t\t\t\tconst srcIdx = reuseSources[reuseIdx]!;\n\t\t\t\t\t\t\t\tlet src = prevChildren[srcIdx];\n\t\t\t\t\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\t\t\t\t\t// If the node moved, callbacks inside need new paths.\n\t\t\t\t\t\t\t\tsrc = this.#rebindCallbacksInSubtree(src, childPath);\n\t\t\t\t\t\t\t\tnextChildren.push(src);\n\t\t\t\t\t\t\t\tnextReuse = reuseIdx < reuseIndices.length - 1 ? reuseIndices[++reuseIdx]! : -1;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tnextChildren.push(prevChildren[i]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (nextChildren.length === 0) {\n\t\t\t\t\t\t\tnextChildren.push(null);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn this.#cloneWithMeta(\n\t\t\t\t\t\t\telement,\n\t\t\t\t\t\t\tcloneElement(element, null!, ...nextChildren),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`[Pulse renderer] Unknown update type: ${(update as any)?.type}`);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tnewTree = descend(newTree, 0, \"\");\n\t\t}\n\t\treturn newTree;\n\t}\n\n\t#assertIsElement(node: ReactNode, parts: string[], depth: number): node is ReactElement {\n\t\tif (process.env.NODE_ENV !== \"production\" && !isValidElement(node)) {\n\t\t\tconsole.error(\"Invalid node:\", node);\n\t\t\tthrow new Error(`Invalid node at path ${parts.slice(0, depth).join(\".\")}`);\n\t\t}\n\t\treturn true;\n\t}\n}\n","import {\n\tcreateContext,\n\ttype ReactNode,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { useLocation, useNavigate, useParams } from \"react-router\";\nimport { type ConnectionStatus, type Directives, PulseSocketIOClient } from \"./client\";\nimport type { RouteInfo } from \"./helpers\";\nimport type { ServerError } from \"./messages\";\nimport { VDOMRenderer } from \"./renderer\";\nimport type { VDOM } from \"./vdom\";\n\n// =================================================================\n// Types\n// =================================================================\n\nexport interface ConnectionStatusConfig {\n\tinitialConnectingDelay: number;\n\tinitialErrorDelay: number;\n\treconnectErrorDelay: number;\n}\n\nexport interface PulseConfig {\n\tserverAddress: string;\n\tconnectionStatus: ConnectionStatusConfig;\n\tapiPrefix: string;\n}\n\nexport type PulsePrerenderView = {\n\tvdom: VDOM;\n};\n\nexport type PulsePrerender = {\n\tviews: Record<string, PulsePrerenderView>;\n\tdirectives: Directives;\n};\n// =================================================================\n// Context and Hooks\n// =================================================================\n\n// Context for the client, provided by PulseProvider\nconst PulseClientContext = createContext<PulseSocketIOClient | null>(null);\nconst PulsePrerenderContext = createContext<PulsePrerender | null>(null);\n\nexport const usePulseClient = () => {\n\tconst client = useContext(PulseClientContext);\n\tif (!client) {\n\t\tthrow new Error(\"usePulseClient must be used within a PulseProvider\");\n\t}\n\treturn client;\n};\n\nexport const usePulsePrerender = (path: string) => {\n\tconst ctx = useContext(PulsePrerenderContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"usePulsePrerender must be used within a PulseProvider\");\n\t}\n\tconst view = ctx.views[path];\n\tif (!view) {\n\t\tthrow new Error(`No prerender found for '${path}'`);\n\t}\n\treturn view;\n};\n\n// =================================================================\n// Provider\n// =================================================================\n\nexport interface PulseProviderProps {\n\tchildren: ReactNode;\n\tconfig: PulseConfig;\n\tprerender: PulsePrerender;\n}\n\nconst inBrowser = typeof window !== \"undefined\";\n\nexport function PulseProvider({ children, config, prerender }: PulseProviderProps) {\n\tconst [status, setStatus] = useState<ConnectionStatus>(\"ok\");\n\tconst rrNavigate = useNavigate();\n\tconst { directives } = prerender;\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: another useEffect syncs the directives without recreating the client\n\tconst client = useMemo(() => {\n\t\treturn new PulseSocketIOClient(\n\t\t\tconfig.serverAddress,\n\t\t\tdirectives,\n\t\t\trrNavigate,\n\t\t\tconfig.connectionStatus,\n\t\t);\n\t}, [config.serverAddress, rrNavigate, config.connectionStatus]);\n\tuseEffect(() => client.setDirectives(directives), [client, directives]);\n\n\tuseEffect(() => {\n\t\tif (!inBrowser) return;\n\n\t\tconst handleConnectionChange = (newStatus: ConnectionStatus) => {\n\t\t\tsetStatus(newStatus);\n\t\t};\n\n\t\tconst unsubscribe = client.onConnectionChange(handleConnectionChange);\n\n\t\t// Start connection attempt\n\t\tclient.connect();\n\n\t\treturn () => {\n\t\t\tunsubscribe();\n\t\t\tclient.disconnect();\n\t\t};\n\t}, [client]);\n\n\tconst getStatusMessage = () => {\n\t\tswitch (status) {\n\t\t\tcase \"connecting\":\n\t\t\t\treturn \"Connecting...\";\n\t\t\tcase \"reconnecting\":\n\t\t\t\treturn \"Reconnecting...\";\n\t\t\tcase \"error\":\n\t\t\t\treturn \"Failed to connect to the server.\";\n\t\t\t// \"ok\" falls through to default\n\t\t\tdefault:\n\t\t\t\treturn null;\n\t\t}\n\t};\n\n\tconst statusMessage = getStatusMessage();\n\n\treturn (\n\t\t<PulseClientContext.Provider value={client}>\n\t\t\t<PulsePrerenderContext.Provider value={prerender}>\n\t\t\t\t{statusMessage && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tposition: \"fixed\",\n\t\t\t\t\t\t\tbottom: \"20px\",\n\t\t\t\t\t\t\tright: \"20px\",\n\t\t\t\t\t\t\tbackgroundColor: status === \"error\" ? \"red\" : \"#666\",\n\t\t\t\t\t\t\tcolor: \"white\",\n\t\t\t\t\t\t\tpadding: \"10px\",\n\t\t\t\t\t\t\tborderRadius: \"5px\",\n\t\t\t\t\t\t\tzIndex: 1000,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{statusMessage}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{children}\n\t\t\t</PulsePrerenderContext.Provider>\n\t\t</PulseClientContext.Provider>\n\t);\n}\n\n// =================================================================\n// View\n// =================================================================\n\nexport interface PulseViewProps {\n\tpath: string;\n\tregistry: Record<string, unknown>;\n}\n\nexport function PulseView({ path, registry }: PulseViewProps) {\n\tconst client = usePulseClient();\n\tconst initialView = usePulsePrerender(path);\n\tconst renderer = useMemo(\n\t\t() => new VDOMRenderer(client, path, registry),\n\t\t[client, path, registry],\n\t);\n\tconst [tree, setTree] = useState<ReactNode>(() => renderer.init(initialView));\n\tconst [serverError, setServerError] = useState<ServerError | null>(null);\n\n\tconst location = useLocation();\n\tconst params = useParams();\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: using hacky deep equality for params\n\tconst routeInfo = useMemo(() => {\n\t\tconst { \"*\": catchall = \"\", ...pathParams } = params;\n\t\tconst queryParams = new URLSearchParams(location.search);\n\t\tconst query = location.search.startsWith(\"?\")\n\t\t\t? location.search.slice(1)\n\t\t\t: location.search;\n\t\tconst hash = location.hash.startsWith(\"#\")\n\t\t\t? location.hash.slice(1)\n\t\t\t: location.hash;\n\t\treturn {\n\t\t\thash,\n\t\t\tpathname: location.pathname,\n\t\t\tquery,\n\t\t\tqueryParams: Object.fromEntries(queryParams.entries()),\n\t\t\tpathParams,\n\t\t\tcatchall: catchall.length > 0 ? catchall.split(\"/\") : [],\n\t\t} satisfies RouteInfo;\n\t}, [location.hash, location.pathname, location.search, JSON.stringify(params)]);\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: We don't want to detach on navigation, so another useEffect syncs the routeInfo on navigation.\n\tuseEffect(() => {\n\t\tif (inBrowser) {\n\t\t\tclient.attach(path, {\n\t\t\t\trouteInfo,\n\t\t\t\tonInit: (view) => {\n\t\t\t\t\tsetTree(renderer.init(view));\n\t\t\t\t\tsetServerError(null);\n\t\t\t\t},\n\t\t\t\tonUpdate: (ops) => {\n\t\t\t\t\tsetTree((prev) => (prev == null ? prev : renderer.applyUpdates(prev, ops)));\n\t\t\t\t\tsetServerError(null);\n\t\t\t\t},\n\t\t\t\tonJsExec: (msg) => {\n\t\t\t\t\tlet result: any;\n\t\t\t\t\tlet error: string | null = null;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresult = renderer.evaluateExpr(msg.expr);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\terror = e instanceof Error ? e.message : String(e);\n\t\t\t\t\t}\n\t\t\t\t\tclient.sendJsResult(msg.id, result, error);\n\t\t\t\t},\n\t\t\t\tonServerError: setServerError,\n\t\t\t\t});\n\t\t\t\treturn () => {\n\t\t\t\t\trenderer.clearPendingCallbacks();\n\t\t\t\t\tclient.detach(path);\n\t\t\t\t};\n\t\t\t}\n\t\t// routeInfo is NOT included here on purpose\n\t}, [client, renderer, path]);\n\n\tuseEffect(() => {\n\t\tif (inBrowser) {\n\t\t\tclient.updateRoute(path, routeInfo);\n\t\t}\n\t}, [client, path, routeInfo]);\n\t// Hack for our current prerendering setup on client-side navigation. Will be improved soon\n\tconst hasRendered = useRef(false);\n\tuseEffect(() => {\n\t\t// First rendering pass, no need to update the tree\n\t\tif (!hasRendered.current) {\n\t\t\thasRendered.current = true;\n\t\t}\n\t\t// 2nd+ rendering pass. Happens when a route stays mounted on navigation.\n\t\telse {\n\t\t\tsetTree(renderer.init(initialView));\n\t\t}\n\t\t// Note: Do NOT reset hasRendered in cleanup. The cleanup runs when effect \n\t\t// deps change and at least once on mount with strict mode,\n\t\t// not just on unmount, which would cause subsequent runs to skip setTree.\n\t}, [initialView, renderer]);\n\n\tif (serverError) {\n\t\treturn <ServerErrorPopup error={serverError} />;\n\t}\n\n\treturn tree;\n}\n\nfunction ServerErrorPopup({ error }: { error: ServerError }) {\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tpadding: 16,\n\t\t\t\tborder: \"1px solid #e00\",\n\t\t\t\tbackground: \"#fff5f5\",\n\t\t\t\tcolor: \"#900\",\n\t\t\t\tfontFamily:\n\t\t\t\t\t'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n\t\t\t\twhiteSpace: \"pre-wrap\",\n\t\t\t}}\n\t\t>\n\t\t\t<div style={{ fontWeight: 700, marginBottom: 8 }}>Server Error during {error.phase}</div>\n\t\t\t{error.message && <div>{error.message}</div>}\n\t\t\t{error.stack && (\n\t\t\t\t<details open style={{ marginTop: 8 }}>\n\t\t\t\t\t<summary>Stack trace</summary>\n\t\t\t\t\t<pre style={{ margin: 0 }}>{error.stack}</pre>\n\t\t\t\t</details>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { useEffect, useMemo } from \"react\";\nimport type { PulseSocketIOClient } from \"./client\";\nimport type {\n\tServerChannelMessage,\n\tServerChannelRequestMessage,\n\tServerChannelResponseMessage,\n} from \"./messages\";\nimport { usePulseClient } from \"./pulse\";\n\nexport class PulseChannelResetError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PulseChannelResetError\";\n\t}\n}\n\nexport type ChannelEventHandler = (payload: any) => any | Promise<any>;\n\ninterface PendingRequest {\n\tresolve: (value: any) => void;\n\treject: (error: any) => void;\n}\n\nfunction randomId(): string {\n\tif (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n\t\treturn crypto.randomUUID().replace(/-/g, \"\");\n\t}\n\treturn Math.random().toString(16).slice(2) + Math.random().toString(16).slice(2);\n}\n\nfunction formatError(error: unknown): string {\n\tif (error instanceof Error) return error.message;\n\tif (typeof error === \"string\") return error;\n\ttry {\n\t\treturn JSON.stringify(error);\n\t} catch {\n\t\treturn String(error);\n\t}\n}\n\nfunction isServerResponseMessage(\n\tmessage: ServerChannelMessage,\n): message is ServerChannelResponseMessage {\n\treturn typeof (message as ServerChannelResponseMessage).responseTo === \"string\";\n}\n\nfunction isServerRequestMessage(\n\tmessage: ServerChannelMessage,\n): message is ServerChannelRequestMessage {\n\treturn typeof (message as ServerChannelRequestMessage).event === \"string\";\n}\n\nexport class ChannelBridge {\n\tprivate handlers = new Map<string, Set<ChannelEventHandler>>();\n\tprivate pending = new Map<string, PendingRequest>();\n\tprivate backlog: ServerChannelRequestMessage[] = [];\n\tprivate closed = false;\n\n\tconstructor(\n\t\tprivate client: PulseSocketIOClient,\n\t\tpublic readonly id: string,\n\t) {}\n\n\temit(event: string, payload?: any): void {\n\t\tthis.ensureOpen();\n\t\tthis.client.sendMessage({\n\t\t\ttype: \"channel_message\",\n\t\t\tchannel: this.id,\n\t\t\tevent,\n\t\t\tpayload,\n\t\t});\n\t}\n\n\trequest(event: string, payload?: any): Promise<any> {\n\t\tthis.ensureOpen();\n\t\tconst requestId = randomId();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.pending.set(requestId, { resolve, reject });\n\t\t\tthis.client.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: this.id,\n\t\t\t\tevent,\n\t\t\t\tpayload,\n\t\t\t\trequestId,\n\t\t\t});\n\t\t});\n\t}\n\n\ton(event: string, handler: ChannelEventHandler): () => void {\n\t\tthis.ensureOpen();\n\t\tlet bucket = this.handlers.get(event);\n\t\tif (!bucket) {\n\t\t\tbucket = new Set();\n\t\t\tthis.handlers.set(event, bucket);\n\t\t}\n\t\tbucket.add(handler);\n\t\tthis.flushBacklog(event);\n\t\treturn () => {\n\t\t\tconst set = this.handlers.get(event);\n\t\t\tif (!set) return;\n\t\t\tset.delete(handler);\n\t\t\tif (set.size === 0) {\n\t\t\t\tthis.handlers.delete(event);\n\t\t\t}\n\t\t};\n\t}\n\n\thandleServerMessage(message: ServerChannelMessage): boolean {\n\t\tif (isServerResponseMessage(message)) {\n\t\t\tthis.resolvePending(message);\n\t\t\treturn this.closed;\n\t\t}\n\t\tif (this.closed) {\n\t\t\treturn true;\n\t\t}\n\t\tif (!isServerRequestMessage(message)) {\n\t\t\treturn this.closed;\n\t\t}\n\n\t\tif (message.event === \"__close__\") {\n\t\t\tthis.close(new PulseChannelResetError(\"Channel closed by server\"));\n\t\t\treturn true;\n\t\t}\n\t\tif (message.requestId) {\n\t\t\tvoid this.dispatchRequest(\n\t\t\t\tmessage as ServerChannelRequestMessage & {\n\t\t\t\t\trequestId: string;\n\t\t\t\t},\n\t\t\t);\n\t\t} else {\n\t\t\tthis.dispatchEvent(message);\n\t\t}\n\t\treturn this.closed;\n\t}\n\n\thandleDisconnect(reason: PulseChannelResetError): void {\n\t\tthis.close(reason);\n\t}\n\n\tdispose(reason: PulseChannelResetError): void {\n\t\tthis.close(reason);\n\t}\n\n\tprivate ensureOpen(): void {\n\t\tif (this.closed) {\n\t\t\tthrow new PulseChannelResetError(\"Channel is closed\");\n\t\t}\n\t}\n\n\tprivate flushBacklog(event: string): void {\n\t\tif (this.backlog.length === 0) return;\n\t\tconst remaining: ServerChannelRequestMessage[] = [];\n\t\tfor (const item of this.backlog) {\n\t\t\tif (item.event === event) {\n\t\t\t\tthis.dispatchEvent(item);\n\t\t\t} else {\n\t\t\t\tremaining.push(item);\n\t\t\t}\n\t\t}\n\t\tthis.backlog = remaining;\n\t}\n\n\tprivate dispatchEvent(message: ServerChannelRequestMessage): void {\n\t\tconst handlers = this.handlers.get(message.event);\n\t\tif (!handlers || handlers.size === 0) {\n\t\t\tthis.backlog.push(message);\n\t\t\treturn;\n\t\t}\n\t\tfor (const handler of handlers) {\n\t\t\ttry {\n\t\t\t\tconst result = handler(message.payload);\n\t\t\t\tif (result && typeof (result as Promise<any>).then === \"function\") {\n\t\t\t\t\tvoid (result as Promise<any>).catch((err) => {\n\t\t\t\t\t\tconsole.error(\"Pulse channel handler error\", err);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"Pulse channel handler error\", err);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async dispatchRequest(\n\t\tmessage: ServerChannelRequestMessage & { requestId: string },\n\t): Promise<void> {\n\t\tconst handlers = this.handlers.get(message.event);\n\t\tlet response: any;\n\t\tlet error: any;\n\t\tif (handlers && handlers.size > 0) {\n\t\t\tfor (const handler of handlers) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = handler(message.payload);\n\t\t\t\t\tresponse = await Promise.resolve(result);\n\t\t\t\t\tif (response !== undefined) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\terror = err;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (error) {\n\t\t\tthis.client.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: this.id,\n\t\t\t\tevent: undefined,\n\t\t\t\tresponseTo: message.requestId,\n\t\t\t\terror: formatError(error),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tthis.client.sendMessage({\n\t\t\ttype: \"channel_message\",\n\t\t\tchannel: this.id,\n\t\t\tevent: undefined,\n\t\t\tresponseTo: message.requestId,\n\t\t\tpayload: response,\n\t\t});\n\t}\n\n\tprivate resolvePending(message: ServerChannelResponseMessage): void {\n\t\tconst entry = message.responseTo ? this.pending.get(message.responseTo) : undefined;\n\t\tif (!entry) {\n\t\t\treturn;\n\t\t}\n\t\tthis.pending.delete(message.responseTo!);\n\t\tif (message.error !== undefined && message.error !== null) {\n\t\t\tentry.reject(new PulseChannelResetError(String(message.error)));\n\t\t} else {\n\t\t\tentry.resolve(message.payload);\n\t\t}\n\t}\n\n\tprivate close(reason: PulseChannelResetError): void {\n\t\tif (this.closed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.closed = true;\n\t\tfor (const request of this.pending.values()) {\n\t\t\trequest.reject(reason);\n\t\t}\n\t\tthis.pending.clear();\n\t\tthis.handlers.clear();\n\t\tthis.backlog = [];\n\t\t// No-op: owning client manages registry lifecycle.\n\t}\n}\n\nexport function usePulseChannel(channelId: string): ChannelBridge {\n\tconst client = usePulseClient();\n\tconst bridge = useMemo(() => {\n\t\tif (!channelId) {\n\t\t\tthrow new Error(\"usePulseChannel requires a non-empty channelId\");\n\t\t}\n\t\treturn client.acquireChannel(channelId);\n\t}, [client, channelId]);\n\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tclient.releaseChannel(channelId);\n\t\t};\n\t}, [client, channelId]);\n\n\treturn bridge;\n}\n","import { type ComponentPropsWithoutRef, type FormEvent, forwardRef, useCallback } from \"react\";\n\nexport type PulseFormProps = ComponentPropsWithoutRef<\"form\"> & {\n\taction: string;\n};\n\n/**\n * PulseForm intercepts native form submissions and sends them through fetch so the\n * surrounding Pulse view stays mounted. Server-side handlers are still invoked via\n * the form action endpoint and reactive updates propagate over the socket.\n */\nexport const PulseForm = forwardRef<HTMLFormElement, PulseFormProps>(function PulseForm(\n\t{ onSubmit, action, ...rest },\n\tref,\n) {\n\treturn (\n\t\t<form\n\t\t\t{...rest}\n\t\t\taction={action}\n\t\t\tref={ref}\n\t\t\tonSubmit={useCallback(\n\t\t\t\t(event: FormEvent<HTMLFormElement>) => submitForm({ event, action, onSubmit }),\n\t\t\t\t[action, onSubmit],\n\t\t\t)}\n\t\t/>\n\t);\n});\n\ninterface SubmitForm {\n\tevent: FormEvent<HTMLFormElement>;\n\taction: string;\n\tonSubmit?: PulseFormProps[\"onSubmit\"];\n\tformData?: FormData;\n\tforce?: boolean;\n}\n\nexport async function submitForm({ event, action, onSubmit, formData, force }: SubmitForm) {\n\tonSubmit?.(event);\n\tif (!force && event.defaultPrevented) {\n\t\treturn;\n\t}\n\tconst form = event.currentTarget;\n\tevent.preventDefault();\n\tconst nativeEvent = event.nativeEvent as SubmitEvent;\n\tif (!formData) {\n\t\tformData = new FormData(form, nativeEvent.submitter);\n\t}\n\tconst url = new URL(action, window.location.href);\n\ttry {\n\t\tawait fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\t// Required for our hosting scenarios of same host + different ports or 2 subdomains\n\t\t\tcredentials: \"include\",\n\t\t\tbody: formData,\n\t\t});\n\t} catch (err) {\n\t\tif (process.env.NODE_ENV !== \"production\") {\n\t\t\tconsole.error(\"[Pulse] Form submission failed\", err);\n\t\t} else {\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n","import type { LoaderFunctionArgs } from \"react-router\";\n\nexport interface RouteInfo {\n\tpathname: string;\n\thash: string;\n\tquery: string;\n\tqueryParams: Record<string, string>;\n\tpathParams: Record<string, string | undefined>;\n\tcatchall: string[];\n}\n\nexport function extractServerRouteInfo({ params, request }: LoaderFunctionArgs) {\n\tconst { \"*\": catchall = \"\", ...pathParams } = params;\n\tconst parsedUrl = new URL(request.url);\n\tconst query = parsedUrl.search.startsWith(\"?\")\n\t\t? parsedUrl.search.slice(1)\n\t\t: parsedUrl.search;\n\tconst hash = parsedUrl.hash.startsWith(\"#\")\n\t\t? parsedUrl.hash.slice(1)\n\t\t: parsedUrl.hash;\n\n\treturn {\n\t\thash,\n\t\tpathname: parsedUrl.pathname,\n\t\tquery,\n\t\tqueryParams: Object.fromEntries(parsedUrl.searchParams.entries()),\n\t\tpathParams,\n\t\tcatchall: catchall.length > 1 ? catchall.split(\"/\") : [],\n\t} satisfies RouteInfo;\n}\n"],"mappings":"uXAEA,SAAgB,GAAoC,CACnD,SAAS,EAGP,EAAS,EAAc,CACxB,MACC,IAKI,CACJ,IAAMA,EAAW,EAAE,CACnB,IAAK,IAAM,KAAO,EACjB,EAAI,GAAkB,EAAY,GAEnC,GAAI,EACH,IAAK,IAAM,KAAO,EAAU,CAC3B,IAAM,EAAK,EAAS,GACpB,EAAI,GAAO,EAAG,EAAI,CAGpB,OAAO,GAGT,OAAO,ECxBR,MAAM,EAAgB,GAAe,EAAE,QAAQ,aAAa,CAEtD,GAAe,CACpB,KACA,YACA,UACA,YACA,eACA,aACA,YACA,cACA,eACA,aACA,YACA,cACA,OACA,CAEK,GAAmB,CACxB,YACA,WACA,QACA,CAEK,GAAyB,CAC9B,YACA,iBACA,iBACA,MACA,YACA,SACA,QACA,OACA,eACA,aACA,YACA,cACA,UACA,aACA,QACA,YACA,qBACA,kBACA,eACA,oBACA,YACA,CAEK,EAAqB,GAA0B,CAAC,GAAc,CACnE,QAAS,EACT,CAAC,CAEI,EAA0B,GAAmC,CAAC,GAAiB,CAE/E,GAA6B,GAA8B,CAAC,GAAuB,CAEzF,SAAS,EAAuB,EAAkB,CACjD,MAAO,CACN,GAAG,EAAmB,EAAI,CAC1B,GAAG,EAAwB,EAAwB,CACnD,GAAG,GAA2B,EAAI,CAClC,CAIF,SAAS,EACR,EACA,EACC,CACD,IAAM,EAAO,GAAoB,CAAC,EAAM,EAAgB,CACxD,MAAQ,KAAY,CAAE,GAAG,EAAuB,EAAI,CAAE,GAAG,EAAK,EAAI,CAAE,EAwBrE,MAAM,GAAkB,EArBC,CACxB,OACA,OACA,WACA,OACA,SACA,WACA,WACA,OACA,WACA,SACA,SACA,WACA,MACA,WACA,OACA,WACA,OACA,iBACA,OACA,CACoE,CAuB/D,GAAgB,EArBC,CACtB,MACA,SACA,WACA,OACA,OACA,WACA,OACA,SACA,WACA,WACA,OACA,WACA,MACA,SACA,QACA,SACA,WACA,OACA,iBACA,CAC8D,CAwBzD,EAAiB,EAtBC,CACvB,WACA,WACA,cACA,aACA,cACA,eACA,sBACA,WACA,QACA,OACA,QACA,eACA,SACA,eACA,UACA,aACA,UACA,MACA,SACA,iBACA,CACiE,CAE5D,GAAkB,GAA0B,EAAe,EAAI,CAc/D,GAAkB,EAZC,CACxB,WACA,OACA,OACA,QACA,aACA,cACA,aACA,iBACA,aACA,sBACA,CACoE,CAG/D,GAAgB,EADC,CAAC,QAAQ,CAC+B,CAUzD,GAAiB,EARC,CACvB,SACA,MACA,OACA,QACA,QACA,OACA,CACiE,CAS5D,GAAoB,EAPC,CAC1B,WACA,OACA,OACA,oBACA,eACA,CAC0E,CAerEC,GAAgB,EAbC,CACtB,gBACA,SACA,eACA,WACA,UACA,SACA,SACA,OACA,aACA,SACA,MACA,CAC8D,CAmBzD,GAAkB,EAjBC,CACxB,QACA,kBACA,SACA,OACA,iBACA,MACA,SACA,QACA,QACA,cACA,WACA,eACA,cACA,YACA,UACA,CACoE,CA6B/D,GAAiB,EA3BC,CACvB,MACA,cACA,WACA,SACA,QACA,UACA,gBACA,eACA,iBACA,QACA,MACA,SACA,SACA,QACA,QACA,SACA,WACA,SACA,WACA,SACA,OACA,SACA,IACA,IACA,gBACA,CACiE,CA6C5D,GAAiB,EA3CC,8ZA0CvB,CACkE,CAClE,cAAgB,GAAQ,CACvB,IAAM,EAAQ,EAAI,cAClB,OAAO,OAAO,SAAS,EAAM,CAAG,EAAQ,MAEzC,CAAC,CAGI,GAAiB,EADC,CAAC,UAAU,CAC+B,CAG5D,GAAc,EADC,CAAC,QAAS,OAAO,CACmB,CAqBnD,GAAgB,EAnBC,CACtB,KACA,cACA,WACA,gBACA,OACA,WACA,aACA,cACA,YACA,QACA,iBACA,MACA,OACA,UACA,MACA,SACA,QACA,CAC8D,CAGzD,GAAe,EADC,CAAC,OAAO,CAC8B,CAUtD,GAAiB,EARC,CACvB,OACA,MACA,MACA,MACA,UACA,QACA,CACiE,CAG5D,EAAe,EADC,CAAC,OAAQ,WAAW,CACkB,CAQtD,GAAiB,EANF,CACpB,WACA,QACA,OACA,UACA,CAC8D,CAsBzD,GAAkB,EApBC,CACxB,OACA,SACA,OACA,OACA,SACA,QACA,oBACA,eACA,QACA,UACA,SACA,OACA,WACA,WACA,UACA,SACA,UACA,SACA,CACoE,CAM/D,GAAoB,EAJC,CAC1B,WACA,QACA,CAC0E,CAWrE,GAAkB,EATC,CACxB,kBACA,WACA,QACA,QACA,WACA,OACA,QACA,CACoE,CAW/D,GAAkB,EATC,CACxB,eACA,OACA,OACA,QACA,UACA,oBACA,eACA,CACoE,CAO/D,GAAoB,EALC,CAC1B,MACA,WACA,QACA,CAC0E,CAGrE,EAAiB,EADC,CAAC,OAAO,CACkC,CAE5D,GAAiB,GAAqB,EAAuB,EAAI,CAejE,GAAwB,GAAoC,CAbzC,CACxB,QACA,cACA,QACA,gBACA,YACA,WACA,iBACA,MACA,OACA,OACA,UACA,CACoF,CACpF,MAAQ,GAAO,EAAU,MACzB,QAAU,GAAO,EAAU,QAC3B,CAAC,CACI,GAAmB,IAA4B,CACpD,GAAG,EAAuB,EAAI,CAC9B,GAAG,GAAsB,EAAI,CAC7B,EAgBK,GAAkB,EAdC,CACxB,eACA,WACA,SACA,WACA,OACA,WACA,gBACA,OACA,OACA,QACA,oBACA,eACA,CACoE,CAG/D,GAAgB,EADC,CAAC,OAAO,CACgC,CAWzD,GAAkB,EATC,CACxB,SACA,QACA,QACA,MACA,SACA,OACA,QACA,CACoE,CAK/D,GAAwB,EAHE,CAC/B,QACA,CACuF,CAmBlF,EAAqB,EAjBE,CAC5B,OACA,YACA,UACA,UACA,UACA,QACA,QACA,OACA,UACA,KACA,QACA,SACA,SACA,SACA,QACA,CAC8E,CAUzE,EAAoB,EARE,CAC3B,OACA,QACA,KACA,QACA,SACA,QACA,CAC2E,CAatE,GAAiB,EAXC,CACvB,QACA,UACA,SACA,cACA,cACA,QACA,QACA,UACA,QACA,CACiE,CAW5D,GAAoB,EATL,CACpB,WACA,kBACA,QACA,UACA,KACA,QACA,SACA,CACoE,CAQ/D,EAAwB,EANH,CAC1B,QACA,KACA,QACA,SACA,CACkF,CAE7E,GAAqB,GAA6B,EAAuB,EAAI,CAwB7E,GAAoB,EAtBC,CAC1B,eACA,OACA,eACA,UACA,WACA,YACA,YACA,OA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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["out: any","formExtractor","elementExtractors: Record<string, (elt: any) => object>","eventExtractorMap: { [key: string]: (evt: any) => object }","refs: number[]","dates: number[]","sets: number[]","maps: number[]","process","rec: Record<string, any>","objects: Array<any>","dt","result","keys","result: Record<string, any>","#url","#directives","#frameworkNavigate","#socket","#activeViews","#messageQueue","#connectionStatusConfig","#connectingTimeout","#errorTimeout","#clearTimeouts","#currentStatus","#notifyConnectionListeners","#hasConnectedOnce","#setStatus","#setInitialConnectionStatus","#handleConnected","#handleDisconnected","#handleTransportDisconnect","#handleServerMessage","#connectionListeners","#channels","#performApiCall","#routeChannelMessage","#handleJsExec","headersObj: Record<string, string>","body: any","reply: ClientApiResultMessage","#sendJsResult","msg: ClientJsResultMessage","#ensureChannelEntry","ATTR_ALIASES: Record<string, string>","options: ScrollToOptions","options: ScrollIntoViewOptions","#getBridge","#ensureChannel","#entries","#setNode","#teardown","#bridge","#channelId","#cleanup","#handleCall","#handleRequest","#perform","#client","#path","#registry","#callbackEntries","#metaMap","#refRegistry","#resolveIdentifier","out: unknown[]","#evalExpr","out: Record<string, unknown>","nextEnv: Env","#clearPending","#firePending","#propPath","#scheduleDebounced","#dropCallbacksInSubtree","#ensureChildrenArray","#ensureCallbackEntry","#getCallback","component: React.ComponentType<any> | string","REF_PREFIX","newProps: Record<string, any>","evalSet: Set<string> | undefined","meta: ElementMeta","#transformEvalProp","renderedChildren: ReactNode[]","#rememberMeta","#rebindCallbacksInSubtree","newTree: ReactNode","#assertIsElement","#cloneWithMeta","nextProps: Record<string, any>","nextEval: Set<string> | undefined","#dropCallback","nextChildren: ReactNode[]","result: any","error: string | null","client: PulseSocketIOClient","id: string","remaining: ServerChannelRequestMessage[]","response: any","error: any","PulseForm"],"sources":["../src/serialize/extractor.ts","../src/serialize/elements.ts","../src/serialize/events.ts","../src/serialize/serializer.ts","../src/client.tsx","../src/ref.tsx","../src/vdom.ts","../src/renderer.tsx","../src/pulse.tsx","../src/channel.ts","../src/form.tsx","../src/helpers.ts"],"sourcesContent":["type Simplify<T> = { [K in keyof T]: T[K] } & {};\n\nexport function createExtractor<T extends object>() {\n\tfunction _createExtractor<\n\t\tconst K extends readonly (keyof T)[],\n\t\tC extends Partial<Record<K[number] | string, (src: T) => any>>,\n\t>(keys: K, computed?: C) {\n\t\treturn (\n\t\t\tsrc: T,\n\t\t): Simplify<\n\t\t\tPick<T, K[number]> & {\n\t\t\t\t[P in keyof C]-?: C[P] extends (...args: any) => infer R ? R : never;\n\t\t\t}\n\t\t> => {\n\t\t\tconst out: any = {};\n\t\t\tfor (const key of keys) {\n\t\t\t\tout[key as string] = (src as any)[key as string];\n\t\t\t}\n\t\t\tif (computed) {\n\t\t\t\tfor (const key in computed) {\n\t\t\t\t\tconst fn = computed[key]!;\n\t\t\t\t\tout[key] = fn(src);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out;\n\t\t};\n\t}\n\treturn _createExtractor;\n}\n","import { createExtractor } from \"./extractor\";\n\n// Base extractors (camelCase) similar to events.ts style\nconst lowerTagName = (e: Element) => e.tagName.toLowerCase();\n\nconst ELEMENT_KEYS = [\n\t\"id\",\n\t\"className\",\n\t\"tagName\",\n\t\"localName\",\n\t\"clientHeight\",\n\t\"clientLeft\",\n\t\"clientTop\",\n\t\"clientWidth\",\n\t\"scrollHeight\",\n\t\"scrollLeft\",\n\t\"scrollTop\",\n\t\"scrollWidth\",\n\t\"slot\",\n] as const satisfies readonly (keyof Element)[];\n\nconst HTML_OR_SVG_KEYS = [\n\t\"autofocus\",\n\t\"tabIndex\",\n\t\"nonce\",\n] as const satisfies readonly (keyof HTMLOrSVGElement)[];\n\nconst HTML_ELEMENT_BASE_KEYS = [\n\t\"accessKey\",\n\t\"accessKeyLabel\",\n\t\"autocapitalize\",\n\t\"dir\",\n\t\"draggable\",\n\t\"hidden\",\n\t\"inert\",\n\t\"lang\",\n\t\"offsetHeight\",\n\t\"offsetLeft\",\n\t\"offsetTop\",\n\t\"offsetWidth\",\n\t\"popover\",\n\t\"spellcheck\",\n\t\"title\",\n\t\"translate\",\n\t\"writingSuggestions\",\n\t\"contentEditable\",\n\t\"enterKeyHint\",\n\t\"isContentEditable\",\n\t\"inputMode\",\n] as const satisfies readonly (keyof HTMLElement)[];\n\nconst extractElementBase = createExtractor<Element>()(ELEMENT_KEYS, {\n\ttagName: lowerTagName,\n});\n\nconst extractHTMLOrSVGElement = createExtractor<HTMLOrSVGElement>()(HTML_OR_SVG_KEYS);\n\nconst extractHTMLElementBaseOnly = createExtractor<HTMLElement>()(HTML_ELEMENT_BASE_KEYS);\n\nfunction extractHTMLElementBase(elt: HTMLElement) {\n\treturn {\n\t\t...extractElementBase(elt),\n\t\t...extractHTMLOrSVGElement(elt as HTMLOrSVGElement),\n\t\t...extractHTMLElementBaseOnly(elt),\n\t};\n}\n\n// Helper to compose per-element extractors with the shared base\nfunction withBase<T extends HTMLElement>(\n\tkeys: readonly (keyof T)[],\n\tcomputed?: Partial<Record<string, (src: T) => any>>,\n) {\n\tconst only = createExtractor<T>()(keys, computed as any);\n\treturn (elt: T) => ({ ...extractHTMLElementBase(elt), ...only(elt) });\n}\n\nconst HTML_ANCHOR_KEYS = [\n\t\"hash\",\n\t\"host\",\n\t\"hostname\",\n\t\"href\",\n\t\"origin\",\n\t\"password\",\n\t\"pathname\",\n\t\"port\",\n\t\"protocol\",\n\t\"search\",\n\t\"target\",\n\t\"download\",\n\t\"rel\",\n\t\"hreflang\",\n\t\"type\",\n\t\"username\",\n\t\"ping\",\n\t\"referrerPolicy\",\n\t\"text\",\n] as const satisfies readonly (keyof HTMLAnchorElement)[];\nconst anchorExtractor = withBase<HTMLAnchorElement>(HTML_ANCHOR_KEYS);\n\nconst HTML_AREA_KEYS = [\n\t\"alt\",\n\t\"coords\",\n\t\"download\",\n\t\"hash\",\n\t\"host\",\n\t\"hostname\",\n\t\"href\",\n\t\"origin\",\n\t\"password\",\n\t\"pathname\",\n\t\"port\",\n\t\"protocol\",\n\t\"rel\",\n\t\"search\",\n\t\"shape\",\n\t\"target\",\n\t\"username\",\n\t\"ping\",\n\t\"referrerPolicy\",\n] as const satisfies readonly (keyof HTMLAreaElement)[];\nconst areaExtractor = withBase<HTMLAreaElement>(HTML_AREA_KEYS);\n\nconst HTML_MEDIA_KEYS = [\n\t\"autoplay\",\n\t\"controls\",\n\t\"crossOrigin\",\n\t\"currentSrc\",\n\t\"currentTime\",\n\t\"defaultMuted\",\n\t\"defaultPlaybackRate\",\n\t\"duration\",\n\t\"ended\",\n\t\"loop\",\n\t\"muted\",\n\t\"networkState\",\n\t\"paused\",\n\t\"playbackRate\",\n\t\"preload\",\n\t\"readyState\",\n\t\"seeking\",\n\t\"src\",\n\t\"volume\",\n\t\"preservesPitch\",\n] as const satisfies readonly (keyof HTMLMediaElement)[];\nconst mediaExtractor = withBase<HTMLMediaElement>(HTML_MEDIA_KEYS);\n\nconst audioExtractor = (elt: HTMLAudioElement) => mediaExtractor(elt);\n\nconst HTML_BUTTON_KEYS = [\n\t\"disabled\",\n\t\"name\",\n\t\"type\",\n\t\"value\",\n\t\"formAction\",\n\t\"formEnctype\",\n\t\"formMethod\",\n\t\"formNoValidate\",\n\t\"formTarget\",\n\t\"popoverTargetAction\",\n] as const satisfies readonly (keyof HTMLButtonElement)[];\nconst buttonExtractor = withBase<HTMLButtonElement>(HTML_BUTTON_KEYS);\n\nconst HTML_DATA_KEYS = [\"value\"] as const satisfies readonly (keyof HTMLDataElement)[];\nconst dataExtractor = withBase<HTMLDataElement>(HTML_DATA_KEYS);\n\nconst HTML_EMBED_KEYS = [\n\t\"height\",\n\t\"src\",\n\t\"type\",\n\t\"width\",\n\t\"align\",\n\t\"name\",\n] as const satisfies readonly (keyof HTMLEmbedElement)[];\nconst embedExtractor = withBase<HTMLEmbedElement>(HTML_EMBED_KEYS);\n\nconst HTML_FIELDSET_KEYS = [\n\t\"disabled\",\n\t\"name\",\n\t\"type\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLFieldSetElement)[];\nconst fieldsetExtractor = withBase<HTMLFieldSetElement>(HTML_FIELDSET_KEYS);\n\nconst HTML_FORM_KEYS = [\n\t\"acceptCharset\",\n\t\"action\",\n\t\"autocomplete\",\n\t\"encoding\",\n\t\"enctype\",\n\t\"length\",\n\t\"method\",\n\t\"name\",\n\t\"noValidate\",\n\t\"target\",\n\t\"rel\",\n] as const satisfies readonly (keyof HTMLFormElement)[];\nconst formExtractor = withBase<HTMLFormElement>(HTML_FORM_KEYS);\n\nconst HTML_IFRAME_KEYS = [\n\t\"allow\",\n\t\"allowFullscreen\",\n\t\"height\",\n\t\"name\",\n\t\"referrerPolicy\",\n\t\"src\",\n\t\"srcdoc\",\n\t\"width\",\n\t\"align\",\n\t\"frameBorder\",\n\t\"longDesc\",\n\t\"marginHeight\",\n\t\"marginWidth\",\n\t\"scrolling\",\n\t\"sandbox\",\n] as const satisfies readonly (keyof HTMLIFrameElement)[];\nconst iframeExtractor = withBase<HTMLIFrameElement>(HTML_IFRAME_KEYS);\n\nconst HTML_IMAGE_KEYS = [\n\t\"alt\",\n\t\"crossOrigin\",\n\t\"decoding\",\n\t\"height\",\n\t\"isMap\",\n\t\"loading\",\n\t\"naturalHeight\",\n\t\"naturalWidth\",\n\t\"referrerPolicy\",\n\t\"sizes\",\n\t\"src\",\n\t\"srcset\",\n\t\"useMap\",\n\t\"width\",\n\t\"align\",\n\t\"border\",\n\t\"complete\",\n\t\"hspace\",\n\t\"longDesc\",\n\t\"lowsrc\",\n\t\"name\",\n\t\"vspace\",\n\t\"x\",\n\t\"y\",\n\t\"fetchPriority\",\n] as const satisfies readonly (keyof HTMLImageElement)[];\nconst imageExtractor = withBase<HTMLImageElement>(HTML_IMAGE_KEYS);\n\nconst HTML_INPUT_KEYS = [\n\t\"accept\",\n\t\"alt\",\n\t\"autocomplete\",\n\t\"checked\",\n\t\"defaultChecked\",\n\t\"defaultValue\",\n\t\"dirName\",\n\t\"disabled\",\n\t\"height\",\n\t\"indeterminate\",\n\t\"max\",\n\t\"maxLength\",\n\t\"min\",\n\t\"minLength\",\n\t\"multiple\",\n\t\"name\",\n\t\"pattern\",\n\t\"placeholder\",\n\t\"readOnly\",\n\t\"required\",\n\t\"selectionDirection\",\n\t\"selectionEnd\",\n\t\"selectionStart\",\n\t\"size\",\n\t\"src\",\n\t\"step\",\n\t\"type\",\n\t\"value\",\n\t\"valueAsNumber\",\n\t\"width\",\n\t\"align\",\n\t\"capture\",\n\t\"formAction\",\n\t\"formEnctype\",\n\t\"formMethod\",\n\t\"formNoValidate\",\n\t\"formTarget\",\n\t\"useMap\",\n\t\"validationMessage\",\n\t\"willValidate\",\n\t\"popoverTargetAction\",\n] as const satisfies readonly (keyof HTMLInputElement)[];\nconst inputExtractor = withBase<HTMLInputElement>(HTML_INPUT_KEYS, {\n\tvalueAsNumber: (elt) => {\n\t\tconst value = elt.valueAsNumber;\n\t\treturn Number.isFinite(value) ? value : null;\n\t},\n});\n\nconst HTML_LABEL_KEYS = [\"htmlFor\"] as const satisfies readonly (keyof HTMLLabelElement)[];\nconst labelExtractor = withBase<HTMLLabelElement>(HTML_LABEL_KEYS);\n\nconst HTML_LI_KEYS = [\"value\", \"type\"] as const satisfies readonly (keyof HTMLLIElement)[];\nconst liExtractor = withBase<HTMLLIElement>(HTML_LI_KEYS);\n\nconst HTML_LINK_KEYS = [\n\t\"as\",\n\t\"crossOrigin\",\n\t\"disabled\",\n\t\"fetchPriority\",\n\t\"href\",\n\t\"hreflang\",\n\t\"imageSizes\",\n\t\"imageSrcset\",\n\t\"integrity\",\n\t\"media\",\n\t\"referrerPolicy\",\n\t\"rel\",\n\t\"type\",\n\t\"charset\",\n\t\"rev\",\n\t\"target\",\n\t\"sizes\",\n] as const satisfies readonly (keyof HTMLLinkElement)[];\nconst linkExtractor = withBase<HTMLLinkElement>(HTML_LINK_KEYS);\n\nconst HTML_MAP_KEYS = [\"name\"] as const satisfies readonly (keyof HTMLMapElement)[];\nconst mapExtractor = withBase<HTMLMapElement>(HTML_MAP_KEYS);\n\nconst HTML_METER_KEYS = [\n\t\"high\",\n\t\"low\",\n\t\"max\",\n\t\"min\",\n\t\"optimum\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLMeterElement)[];\nconst meterExtractor = withBase<HTMLMeterElement>(HTML_METER_KEYS);\n\nconst HTML_MOD_KEYS = [\"cite\", \"dateTime\"] as const satisfies readonly (keyof HTMLModElement)[];\nconst modExtractor = withBase<HTMLModElement>(HTML_MOD_KEYS);\n\nconst HTML_OL_KEYS = [\n\t\"reversed\",\n\t\"start\",\n\t\"type\",\n\t\"compact\",\n] as const satisfies readonly (keyof HTMLOListElement)[];\nconst olistExtractor = withBase<HTMLOListElement>(HTML_OL_KEYS);\n\nconst HTML_OBJECT_KEYS = [\n\t\"data\",\n\t\"height\",\n\t\"name\",\n\t\"type\",\n\t\"useMap\",\n\t\"width\",\n\t\"validationMessage\",\n\t\"willValidate\",\n\t\"align\",\n\t\"archive\",\n\t\"border\",\n\t\"code\",\n\t\"codeBase\",\n\t\"codeType\",\n\t\"declare\",\n\t\"hspace\",\n\t\"standby\",\n\t\"vspace\",\n] as const satisfies readonly (keyof HTMLObjectElement)[];\nconst objectExtractor = withBase<HTMLObjectElement>(HTML_OBJECT_KEYS);\n\nconst HTML_OPTGROUP_KEYS = [\n\t\"disabled\",\n\t\"label\",\n] as const satisfies readonly (keyof HTMLOptGroupElement)[];\nconst optgroupExtractor = withBase<HTMLOptGroupElement>(HTML_OPTGROUP_KEYS);\n\nconst HTML_OPTION_KEYS = [\n\t\"defaultSelected\",\n\t\"disabled\",\n\t\"index\",\n\t\"label\",\n\t\"selected\",\n\t\"text\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLOptionElement)[];\nconst optionExtractor = withBase<HTMLOptionElement>(HTML_OPTION_KEYS);\n\nconst HTML_OUTPUT_KEYS = [\n\t\"defaultValue\",\n\t\"name\",\n\t\"type\",\n\t\"value\",\n\t\"htmlFor\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLOutputElement)[];\nconst outputExtractor = withBase<HTMLOutputElement>(HTML_OUTPUT_KEYS);\n\nconst HTML_PROGRESS_KEYS = [\n\t\"max\",\n\t\"position\",\n\t\"value\",\n] as const satisfies readonly (keyof HTMLProgressElement)[];\nconst progressExtractor = withBase<HTMLProgressElement>(HTML_PROGRESS_KEYS);\n\nconst HTML_QUOTE_KEYS = [\"cite\"] as const satisfies readonly (keyof HTMLQuoteElement)[];\nconst quoteExtractor = withBase<HTMLQuoteElement>(HTML_QUOTE_KEYS);\n\nconst citeExtractor = (elt: HTMLElement) => extractHTMLElementBase(elt);\n\nconst HTML_SCRIPT_KEYS = [\n\t\"async\",\n\t\"crossOrigin\",\n\t\"defer\",\n\t\"fetchPriority\",\n\t\"integrity\",\n\t\"noModule\",\n\t\"referrerPolicy\",\n\t\"src\",\n\t\"text\",\n\t\"type\",\n\t\"charset\",\n] as const satisfies readonly (keyof HTMLScriptElement)[];\nconst extractHTMLScriptOnly = createExtractor<HTMLScriptElement>()(HTML_SCRIPT_KEYS, {\n\tevent: (s) => (s as any).event,\n\thtmlFor: (s) => (s as any).htmlFor,\n});\nconst scriptExtractor = (elt: HTMLScriptElement) => ({\n\t...extractHTMLElementBase(elt),\n\t...extractHTMLScriptOnly(elt),\n});\n\nconst HTML_SELECT_KEYS = [\n\t\"autocomplete\",\n\t\"disabled\",\n\t\"length\",\n\t\"multiple\",\n\t\"name\",\n\t\"required\",\n\t\"selectedIndex\",\n\t\"size\",\n\t\"type\",\n\t\"value\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLSelectElement)[];\nconst selectExtractor = withBase<HTMLSelectElement>(HTML_SELECT_KEYS);\n\nconst HTML_SLOT_KEYS = [\"name\"] as const satisfies readonly (keyof HTMLSlotElement)[];\nconst slotExtractor = withBase<HTMLSlotElement>(HTML_SLOT_KEYS);\n\nconst HTML_SOURCE_KEYS = [\n\t\"height\",\n\t\"media\",\n\t\"sizes\",\n\t\"src\",\n\t\"srcset\",\n\t\"type\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLSourceElement)[];\nconst sourceExtractor = withBase<HTMLSourceElement>(HTML_SOURCE_KEYS);\n\nconst HTML_TABLE_CAPTION_KEYS = [\n\t\"align\",\n] as const satisfies readonly (keyof HTMLTableCaptionElement)[];\nconst tableCaptionExtractor = withBase<HTMLTableCaptionElement>(HTML_TABLE_CAPTION_KEYS);\n\nconst HTML_TABLE_CELL_KEYS = [\n\t\"abbr\",\n\t\"cellIndex\",\n\t\"colSpan\",\n\t\"headers\",\n\t\"rowSpan\",\n\t\"scope\",\n\t\"align\",\n\t\"axis\",\n\t\"bgColor\",\n\t\"ch\",\n\t\"chOff\",\n\t\"height\",\n\t\"noWrap\",\n\t\"vAlign\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableCellElement)[];\nconst tableCellExtractor = withBase<HTMLTableCellElement>(HTML_TABLE_CELL_KEYS);\n\nconst HTML_TABLE_COL_KEYS = [\n\t\"span\",\n\t\"align\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableColElement)[];\nconst tableColExtractor = withBase<HTMLTableColElement>(HTML_TABLE_COL_KEYS);\n\nconst HTML_TABLE_KEYS = [\n\t\"align\",\n\t\"bgColor\",\n\t\"border\",\n\t\"cellPadding\",\n\t\"cellSpacing\",\n\t\"frame\",\n\t\"rules\",\n\t\"summary\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLTableElement)[];\nconst tableExtractor = withBase<HTMLTableElement>(HTML_TABLE_KEYS);\n\nconst HTML_TR_KEYS = [\n\t\"rowIndex\",\n\t\"sectionRowIndex\",\n\t\"align\",\n\t\"bgColor\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n] as const satisfies readonly (keyof HTMLTableRowElement)[];\nconst tableRowExtractor = withBase<HTMLTableRowElement>(HTML_TR_KEYS);\n\nconst HTML_TSECTION_KEYS = [\n\t\"align\",\n\t\"ch\",\n\t\"chOff\",\n\t\"vAlign\",\n] as const satisfies readonly (keyof HTMLTableSectionElement)[];\nconst tableSectionExtractor = withBase<HTMLTableSectionElement>(HTML_TSECTION_KEYS);\n\nconst templateExtractor = (elt: HTMLTemplateElement) => extractHTMLElementBase(elt);\n\nconst HTML_TEXTAREA_KEYS = [\n\t\"autocomplete\",\n\t\"cols\",\n\t\"defaultValue\",\n\t\"dirName\",\n\t\"disabled\",\n\t\"maxLength\",\n\t\"minLength\",\n\t\"name\",\n\t\"placeholder\",\n\t\"readOnly\",\n\t\"required\",\n\t\"rows\",\n\t\"selectionDirection\",\n\t\"selectionEnd\",\n\t\"selectionStart\",\n\t\"value\",\n\t\"wrap\",\n\t\"textLength\",\n\t\"validationMessage\",\n\t\"willValidate\",\n] as const satisfies readonly (keyof HTMLTextAreaElement)[];\nconst textareaExtractor = withBase<HTMLTextAreaElement>(HTML_TEXTAREA_KEYS);\n\nconst HTML_TIME_KEYS = [\"dateTime\"] as const satisfies readonly (keyof HTMLTimeElement)[];\nconst timeExtractor = withBase<HTMLTimeElement>(HTML_TIME_KEYS);\n\nconst HTML_TRACK_KEYS = [\n\t\"default\",\n\t\"kind\",\n\t\"label\",\n\t\"readyState\",\n\t\"src\",\n\t\"srclang\",\n] as const satisfies readonly (keyof HTMLTrackElement)[];\nconst trackExtractor = withBase<HTMLTrackElement>(HTML_TRACK_KEYS);\n\nconst HTML_VIDEO_KEYS = [\n\t\"height\",\n\t\"poster\",\n\t\"videoHeight\",\n\t\"videoWidth\",\n\t\"width\",\n\t\"playsInline\",\n] as const satisfies readonly (keyof HTMLVideoElement)[];\nconst extractHTMLVideoOnly = createExtractor<HTMLVideoElement>()(HTML_VIDEO_KEYS);\nconst videoExtractor = (elt: HTMLVideoElement) => ({\n\t...mediaExtractor(elt),\n\t...extractHTMLVideoOnly(elt),\n});\n\nconst HTML_BR_KEYS = [\"clear\"] as const satisfies readonly (keyof HTMLBRElement)[];\nconst brExtractor = withBase<HTMLBRElement>(HTML_BR_KEYS);\n\nconst HTML_BASE_KEYS = [\"href\", \"target\"] as const satisfies readonly (keyof HTMLBaseElement)[];\nconst baseExtractor = withBase<HTMLBaseElement>(HTML_BASE_KEYS);\n\nconst HTML_BODY_KEYS = [\n\t\"aLink\",\n\t\"background\",\n\t\"bgColor\",\n\t\"link\",\n\t\"text\",\n\t\"vLink\",\n] as const satisfies readonly (keyof HTMLBodyElement)[];\nconst bodyExtractor = withBase<HTMLBodyElement>(HTML_BODY_KEYS);\n\nconst HTML_DLIST_KEYS = [\"compact\"] as const satisfies readonly (keyof HTMLDListElement)[];\nconst dlistExtractor = withBase<HTMLDListElement>(HTML_DLIST_KEYS);\n\nconst HTML_DETAILS_KEYS = [\"open\"] as const satisfies readonly (keyof HTMLDetailsElement)[];\nconst detailsExtractor = withBase<HTMLDetailsElement>(HTML_DETAILS_KEYS);\n\nconst HTML_DIALOG_KEYS = [\n\t\"open\",\n\t\"returnValue\",\n] as const satisfies readonly (keyof HTMLDialogElement)[];\nconst dialogExtractor = withBase<HTMLDialogElement>(HTML_DIALOG_KEYS);\n\nconst HTML_DIV_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLDivElement)[];\nconst divExtractor = withBase<HTMLDivElement>(HTML_DIV_KEYS);\n\nconst headExtractor = (elt: HTMLHeadElement) => extractHTMLElementBase(elt);\n\nconst HTML_HEADING_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLHeadingElement)[];\nconst headingExtractor = withBase<HTMLHeadingElement>(HTML_HEADING_KEYS);\n\nconst HTML_HR_KEYS = [\n\t\"align\",\n\t\"color\",\n\t\"noShade\",\n\t\"size\",\n\t\"width\",\n] as const satisfies readonly (keyof HTMLHRElement)[];\nconst hrExtractor = withBase<HTMLHRElement>(HTML_HR_KEYS);\n\nconst HTML_HTML_KEYS = [\"version\"] as const satisfies readonly (keyof HTMLHtmlElement)[];\nconst htmlExtractor = withBase<HTMLHtmlElement>(HTML_HTML_KEYS);\n\nconst menuExtractor = (elt: HTMLMenuElement) => extractHTMLElementBase(elt);\n\nconst HTML_META_KEYS = [\n\t\"content\",\n\t\"httpEquiv\",\n\t\"name\",\n\t\"scheme\",\n] as const satisfies readonly (keyof HTMLMetaElement)[];\nconst metaExtractor = withBase<HTMLMetaElement>(HTML_META_KEYS);\n\nconst HTML_P_KEYS = [\"align\"] as const satisfies readonly (keyof HTMLParagraphElement)[];\nconst paragraphExtractor = withBase<HTMLParagraphElement>(HTML_P_KEYS);\n\nconst pictureExtractor = (elt: HTMLPictureElement) => extractHTMLElementBase(elt);\n\nconst HTML_PRE_KEYS = [\"width\"] as const satisfies readonly (keyof HTMLPreElement)[];\nconst preExtractor = withBase<HTMLPreElement>(HTML_PRE_KEYS);\n\nconst spanExtractor = (elt: HTMLSpanElement) => extractHTMLElementBase(elt);\n\nconst HTML_STYLE_KEYS = [\n\t\"media\",\n\t\"type\",\n\t\"disabled\",\n] as const satisfies readonly (keyof HTMLStyleElement)[];\nconst styleExtractor = withBase<HTMLStyleElement>(HTML_STYLE_KEYS);\n\nconst HTML_TITLE_KEYS = [\"text\"] as const satisfies readonly (keyof HTMLTitleElement)[];\nconst titleExtractor = withBase<HTMLTitleElement>(HTML_TITLE_KEYS);\n\nconst HTML_UL_KEYS = [\"compact\", \"type\"] as const satisfies readonly (keyof HTMLUListElement)[];\nconst ulistExtractor = withBase<HTMLUListElement>(HTML_UL_KEYS);\n\n// SVG element extractors\nfunction extractSVGElementBase(elt: SVGElement) {\n\treturn {\n\t\t...extractElementBase(elt),\n\t\t...extractHTMLOrSVGElement(elt as HTMLOrSVGElement),\n\t};\n}\n\n// Helper to compose per-SVG-element extractors with the shared base\nfunction withSVGBase<T extends SVGElement>(\n\tkeys: readonly (keyof T)[],\n\tcomputed?: Partial<Record<string, (src: T) => any>>,\n) {\n\tconst only = createExtractor<T>()(keys, computed as any);\n\treturn (elt: T) => ({ ...extractSVGElementBase(elt), ...only(elt) });\n}\n\nconst SVG_SVG_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"currentScale\",\n\t\"currentTranslate\",\n] as const satisfies readonly (keyof SVGSVGElement)[];\nconst svgExtractor = withSVGBase<SVGSVGElement>(SVG_SVG_KEYS);\n\nconst SVG_CIRCLE_KEYS = [\"cx\", \"cy\", \"r\"] as const satisfies readonly (keyof SVGCircleElement)[];\nconst circleExtractor = withSVGBase<SVGCircleElement>(SVG_CIRCLE_KEYS);\n\nconst SVG_ELLIPSE_KEYS = [\n\t\"cx\",\n\t\"cy\",\n\t\"rx\",\n\t\"ry\",\n] as const satisfies readonly (keyof SVGEllipseElement)[];\nconst ellipseExtractor = withSVGBase<SVGEllipseElement>(SVG_ELLIPSE_KEYS);\n\nconst SVG_LINE_KEYS = [\"x1\", \"y1\", \"x2\", \"y2\"] as const satisfies readonly (keyof SVGLineElement)[];\nconst lineExtractor = withSVGBase<SVGLineElement>(SVG_LINE_KEYS);\n\nconst SVG_PATH_KEYS = [\"pathLength\"] as const satisfies readonly (keyof SVGPathElement)[];\nconst pathExtractor = withSVGBase<SVGPathElement>(SVG_PATH_KEYS);\n\nconst SVG_RECT_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"rx\",\n\t\"ry\",\n] as const satisfies readonly (keyof SVGRectElement)[];\nconst rectExtractor = withSVGBase<SVGRectElement>(SVG_RECT_KEYS);\n\nconst SVG_POLYGON_KEYS = [\"points\"] as const satisfies readonly (keyof SVGPolygonElement)[];\nconst polygonExtractor = withSVGBase<SVGPolygonElement>(SVG_POLYGON_KEYS);\n\nconst SVG_POLYLINE_KEYS = [\"points\"] as const satisfies readonly (keyof SVGPolylineElement)[];\nconst polylineExtractor = withSVGBase<SVGPolylineElement>(SVG_POLYLINE_KEYS);\n\nconst SVG_TEXT_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"dx\",\n\t\"dy\",\n\t\"rotate\",\n\t\"textLength\",\n\t\"lengthAdjust\",\n] as const satisfies readonly (keyof SVGTextElement)[];\nconst textExtractor = withSVGBase<SVGTextElement>(SVG_TEXT_KEYS);\n\nconst SVG_TSPAN_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"dx\",\n\t\"dy\",\n\t\"rotate\",\n\t\"textLength\",\n\t\"lengthAdjust\",\n] as const satisfies readonly (keyof SVGTSpanElement)[];\nconst tspanExtractor = withSVGBase<SVGTSpanElement>(SVG_TSPAN_KEYS);\n\nconst SVG_IMAGE_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"href\",\n\t\"preserveAspectRatio\",\n\t\"crossOrigin\",\n] as const satisfies readonly (keyof SVGImageElement)[];\nconst svgImageExtractor = withSVGBase<SVGImageElement>(SVG_IMAGE_KEYS);\n\nconst SVG_USE_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"href\",\n] as const satisfies readonly (keyof SVGUseElement)[];\nconst useExtractor = withSVGBase<SVGUseElement>(SVG_USE_KEYS);\n\nconst SVG_DEFS_KEYS = [] as const satisfies readonly (keyof SVGDefsElement)[];\nconst defsExtractor = withSVGBase<SVGDefsElement>(SVG_DEFS_KEYS);\n\nconst SVG_GROUP_KEYS = [] as const satisfies readonly (keyof SVGGElement)[];\nconst gExtractor = withSVGBase<SVGGElement>(SVG_GROUP_KEYS);\n\nconst SVG_LINEAR_GRADIENT_KEYS = [\n\t\"x1\",\n\t\"y1\",\n\t\"x2\",\n\t\"y2\",\n\t\"gradientUnits\",\n\t\"gradientTransform\",\n\t\"spreadMethod\",\n] as const satisfies readonly (keyof SVGLinearGradientElement)[];\nconst linearGradientExtractor = withSVGBase<SVGLinearGradientElement>(SVG_LINEAR_GRADIENT_KEYS);\n\nconst SVG_RADIAL_GRADIENT_KEYS = [\n\t\"cx\",\n\t\"cy\",\n\t\"r\",\n\t\"fx\",\n\t\"fy\",\n\t\"fr\",\n\t\"gradientUnits\",\n\t\"gradientTransform\",\n\t\"spreadMethod\",\n] as const satisfies readonly (keyof SVGRadialGradientElement)[];\nconst radialGradientExtractor = withSVGBase<SVGRadialGradientElement>(SVG_RADIAL_GRADIENT_KEYS);\n\nconst SVG_STOP_KEYS = [\"offset\"] as const satisfies readonly (keyof SVGStopElement)[];\nconst stopExtractor = withSVGBase<SVGStopElement>(SVG_STOP_KEYS);\n\nconst SVG_PATTERN_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"patternUnits\",\n\t\"patternContentUnits\",\n\t\"patternTransform\",\n\t\"preserveAspectRatio\",\n\t\"href\",\n] as const satisfies readonly (keyof SVGPatternElement)[];\nconst patternExtractor = withSVGBase<SVGPatternElement>(SVG_PATTERN_KEYS);\n\nconst SVG_CLIP_PATH_KEYS = [\n\t\"clipPathUnits\",\n] as const satisfies readonly (keyof SVGClipPathElement)[];\nconst clipPathExtractor = withSVGBase<SVGClipPathElement>(SVG_CLIP_PATH_KEYS);\n\nconst SVG_MASK_KEYS = [\n\t\"x\",\n\t\"y\",\n\t\"width\",\n\t\"height\",\n\t\"maskUnits\",\n\t\"maskContentUnits\",\n] as const satisfies readonly (keyof SVGMaskElement)[];\nconst maskExtractor = withSVGBase<SVGMaskElement>(SVG_MASK_KEYS);\n\n// Map of tagName -> extractor (concise, like events.ts)\nconst elementExtractors: Record<string, (elt: any) => object> = {\n\tA: anchorExtractor,\n\tAREA: areaExtractor,\n\tAUDIO: audioExtractor,\n\tBASE: baseExtractor,\n\tBLOCKQUOTE: quoteExtractor,\n\tQ: quoteExtractor,\n\tBODY: bodyExtractor,\n\tBR: brExtractor,\n\tBUTTON: buttonExtractor,\n\tCANVAS: extractHTMLElementBase,\n\tCAPTION: tableCaptionExtractor,\n\tCITE: citeExtractor,\n\tCOL: tableColExtractor,\n\tCOLGROUP: tableColExtractor,\n\tDATA: dataExtractor,\n\tDETAILS: detailsExtractor,\n\tDIALOG: dialogExtractor,\n\tDIV: divExtractor,\n\tDL: dlistExtractor,\n\tEMBED: embedExtractor,\n\tFIELDSET: fieldsetExtractor,\n\tFORM: formExtractor,\n\tH1: headingExtractor,\n\tH2: headingExtractor,\n\tH3: headingExtractor,\n\tH4: headingExtractor,\n\tH5: headingExtractor,\n\tH6: headingExtractor,\n\tHEAD: headExtractor,\n\tHR: hrExtractor,\n\tHTML: htmlExtractor,\n\tIFRAME: iframeExtractor,\n\tIMG: imageExtractor,\n\tINPUT: inputExtractor,\n\tLABEL: labelExtractor,\n\tLI: liExtractor,\n\tLINK: linkExtractor,\n\tMAP: mapExtractor,\n\tMENU: menuExtractor,\n\tMETA: metaExtractor,\n\tMETER: meterExtractor,\n\tINS: modExtractor,\n\tDEL: modExtractor,\n\tOBJECT: objectExtractor,\n\tOL: olistExtractor,\n\tOPTGROUP: optgroupExtractor,\n\tOPTION: optionExtractor,\n\tOUTPUT: outputExtractor,\n\tP: paragraphExtractor,\n\tPICTURE: pictureExtractor,\n\tPRE: preExtractor,\n\tPROGRESS: progressExtractor,\n\tSCRIPT: scriptExtractor,\n\tSELECT: selectExtractor,\n\tSLOT: slotExtractor,\n\tSOURCE: sourceExtractor,\n\tSPAN: spanExtractor,\n\tSTYLE: styleExtractor,\n\tTABLE: tableExtractor,\n\tTBODY: tableSectionExtractor,\n\tTHEAD: tableSectionExtractor,\n\tTFOOT: tableSectionExtractor,\n\tTD: tableCellExtractor,\n\tTH: tableCellExtractor,\n\tTEMPLATE: templateExtractor,\n\tTEXTAREA: textareaExtractor,\n\tTIME: timeExtractor,\n\tTITLE: titleExtractor,\n\tTR: tableRowExtractor,\n\tTRACK: trackExtractor,\n\tUL: ulistExtractor,\n\tVIDEO: videoExtractor,\n\t// SVG elements\n\tSVG: svgExtractor,\n\tCIRCLE: circleExtractor,\n\tELLIPSE: ellipseExtractor,\n\tLINE: lineExtractor,\n\tPATH: pathExtractor,\n\tRECT: rectExtractor,\n\tPOLYGON: polygonExtractor,\n\tPOLYLINE: polylineExtractor,\n\tTEXT: textExtractor,\n\tTSPAN: tspanExtractor,\n\tIMAGE: svgImageExtractor,\n\tUSE: useExtractor,\n\tDEFS: defsExtractor,\n\tG: gExtractor,\n\tLINEARGRADIENT: linearGradientExtractor,\n\tRADIALGRADIENT: radialGradientExtractor,\n\tSTOP: stopExtractor,\n\tPATTERN: patternExtractor,\n\tCLIPPATH: clipPathExtractor,\n\tMASK: maskExtractor,\n};\n\nexport function extractHTMLElement(elt: HTMLElement): object {\n\tconst tagName = elt.tagName.toUpperCase();\n\n\tconst extractor = elementExtractors[tagName];\n\tif (extractor) {\n\t\treturn extractor(elt);\n\t}\n\tthrow new Error(`Unexpected HTML element tag: ${elt.tagName} (update .web/custom/serialize.ts)`);\n}\n\nexport function extractSVGElement(elt: SVGElement): object {\n\tconst tagName = elt.tagName.toUpperCase();\n\n\tconst extractor = elementExtractors[tagName];\n\tif (extractor) {\n\t\treturn extractor(elt);\n\t}\n\t// Fallback to base SVG element extractor for unknown SVG elements\n\treturn extractSVGElementBase(elt);\n}\n\nexport function extractElement(elt: Element): object {\n\tif (elt instanceof HTMLElement) {\n\t\treturn extractHTMLElement(elt);\n\t}\n\tif (elt instanceof SVGElement) {\n\t\treturn extractSVGElement(elt);\n\t}\n\t// Fallback for other Element types - use base element extractor\n\treturn extractElementBase(elt);\n}\n","/* === IMPORTANT === */\n\nimport type { MouseEvent, PointerEvent, SyntheticEvent, UIEvent } from \"react\";\nimport { extractElement } from \"./elements\";\nimport { createExtractor } from \"./extractor\";\n\n// Reusable computed mappers (helps bundlers/minifiers share references)\nconst mapTarget = (e: { target: EventTarget | null }) => extractElement(e.target as Element);\nconst mapRelated = (e: { relatedTarget: EventTarget | null }) =>\n\te.relatedTarget ? extractElement(e.relatedTarget as Element) : null;\n\nfunction makeExtractor<K extends readonly any[]>(\n\tkeys: K,\n\tcomputed?: Record<string, (evt: any) => any>,\n) {\n\treturn createExtractor<any>()(\n\t\tkeys as any,\n\t\t{\n\t\t\ttarget: mapTarget,\n\t\t\t...(computed || {}),\n\t\t} as any,\n\t);\n}\n\nconst SYNTHETIC_KEYS = [\n\t\"target\",\n\t\"bubbles\",\n\t\"cancelable\",\n\t\"defaultPrevented\",\n\t\"eventPhase\",\n\t\"isTrusted\",\n\t\"timeStamp\",\n\t\"type\",\n] as const satisfies readonly (keyof SyntheticEvent)[];\n\nconst UI_KEYS = [...SYNTHETIC_KEYS, \"detail\"] as const satisfies readonly (keyof UIEvent)[];\n\nconst MOUSE_KEYS = [\n\t...UI_KEYS,\n\t\"altKey\",\n\t\"button\",\n\t\"buttons\",\n\t\"clientX\",\n\t\"clientY\",\n\t\"ctrlKey\",\n\t\"metaKey\",\n\t\"movementX\",\n\t\"movementY\",\n\t\"pageX\",\n\t\"pageY\",\n\t\"screenX\",\n\t\"screenY\",\n\t\"shiftKey\",\n] as const satisfies readonly (keyof MouseEvent)[];\n\nconst POINTER_KEYS = [\n\t...MOUSE_KEYS,\n\t\"pointerId\",\n\t\"pressure\",\n\t\"tangentialPressure\",\n\t\"tiltX\",\n\t\"tiltY\",\n\t\"twist\",\n\t\"width\",\n\t\"height\",\n\t\"pointerType\",\n\t\"isPrimary\",\n] as const satisfies readonly (keyof PointerEvent)[];\n\nconst syntheticExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst uiExtractor = makeExtractor(UI_KEYS);\n\nconst mouseExtractor = makeExtractor(MOUSE_KEYS, { relatedTarget: mapRelated });\n\nconst clipboardExtractor = makeExtractor(SYNTHETIC_KEYS, {\n\tclipboardData: (e) => extractDataTransfer(e.clipboardData),\n});\n\nconst compositionExtractor = makeExtractor([...SYNTHETIC_KEYS, \"data\"] as const);\n\nconst dragExtractor = makeExtractor(MOUSE_KEYS, {\n\trelatedTarget: mapRelated,\n\tdataTransfer: (e) => extractDataTransfer(e.dataTransfer),\n});\n\nconst pointerExtractor = makeExtractor(POINTER_KEYS, {\n\trelatedTarget: mapRelated,\n});\n\nconst focusExtractor = makeExtractor(SYNTHETIC_KEYS, {\n\trelatedTarget: mapRelated,\n});\n\nconst formExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst invalidExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst changeExtractor = makeExtractor(SYNTHETIC_KEYS);\n\nconst keyboardExtractor = makeExtractor([\n\t...UI_KEYS,\n\t\"altKey\",\n\t\"ctrlKey\",\n\t\"code\",\n\t\"key\",\n\t\"locale\",\n\t\"location\",\n\t\"metaKey\",\n\t\"repeat\",\n\t\"shiftKey\",\n] as const);\n\nconst touchExtractor = makeExtractor(\n\t[\n\t\t...UI_KEYS,\n\t\t\"altKey\",\n\t\t\"ctrlKey\",\n\t\t\"metaKey\",\n\t\t\"shiftKey\",\n\t\t\"changedTouches\",\n\t\t\"targetTouches\",\n\t\t\"touches\",\n\t] as const,\n\t{\n\t\tchangedTouches: (e) => mapTouchList(e.changedTouches),\n\t\ttargetTouches: (e) => mapTouchList(e.targetTouches),\n\t\ttouches: (e) => mapTouchList(e.touches),\n\t},\n);\n\nconst wheelExtractor = makeExtractor(\n\t[...MOUSE_KEYS, \"deltaMode\", \"deltaX\", \"deltaY\", \"deltaZ\"] as const,\n\t{\n\t\trelatedTarget: mapRelated,\n\t},\n);\n\nconst animationExtractor = makeExtractor([\n\t...SYNTHETIC_KEYS,\n\t\"animationName\",\n\t\"elapsedTime\",\n\t\"pseudoElement\",\n] as const);\n\nconst toggleExtractor = makeExtractor([...SYNTHETIC_KEYS, \"oldState\", \"newState\"] as const);\n\nconst transitionExtractor = makeExtractor([\n\t...SYNTHETIC_KEYS,\n\t\"elapsedTime\",\n\t\"propertyName\",\n\t\"pseudoElement\",\n] as const);\n\nfunction mapTouchList(list: any): any[] {\n\treturn Array.from(list as ArrayLike<any>).map((touch: any) => ({\n\t\ttarget: extractElement(touch.target as Element),\n\t\tidentifier: touch.identifier,\n\t\tscreenX: touch.screenX,\n\t\tscreenY: touch.screenY,\n\t\tclientX: touch.clientX,\n\t\tclientY: touch.clientY,\n\t\tpageX: touch.pageX,\n\t\tpageY: touch.pageY,\n\t}));\n}\n\n// Helper function to extract DataTransfer properties\nfunction extractDataTransfer(dt: DataTransfer | null): object | null {\n\tif (!dt) {\n\t\treturn null;\n\t}\n\tconst items = [];\n\tif (dt.items) {\n\t\tfor (let i = 0; i < dt.items.length; i++) {\n\t\t\tconst item = dt.items[i]!;\n\t\t\titems.push({\n\t\t\t\tkind: item.kind,\n\t\t\t\ttype: item.type,\n\t\t\t});\n\t\t}\n\t}\n\treturn {\n\t\tdrop_effect: dt.dropEffect,\n\t\teffect_allowed: dt.effectAllowed,\n\t\titems: items,\n\t\ttypes: Array.from(dt.types || []),\n\t};\n}\n\nconst eventExtractorMap: { [key: string]: (evt: any) => object } = {};\n\nfunction add(map: Record<string, any>, names: readonly string[], fn: any) {\n\tfor (const n of names) map[n] = fn;\n}\n\nadd(\n\teventExtractorMap,\n\t[\n\t\t\"pointerdown\",\n\t\t\"pointermove\",\n\t\t\"pointerup\",\n\t\t\"pointercancel\",\n\t\t\"gotpointercapture\",\n\t\t\"lostpointercapture\",\n\t\t\"pointerenter\",\n\t\t\"pointerleave\",\n\t\t\"pointerover\",\n\t\t\"pointerout\",\n\t],\n\tpointerExtractor,\n);\n\nadd(\n\teventExtractorMap,\n\t[\n\t\t\"click\",\n\t\t\"contextmenu\",\n\t\t\"dblclick\",\n\t\t\"mousedown\",\n\t\t\"mouseenter\",\n\t\t\"mouseleave\",\n\t\t\"mousemove\",\n\t\t\"mouseout\",\n\t\t\"mouseover\",\n\t\t\"mouseup\",\n\t],\n\tmouseExtractor,\n);\n\nadd(\n\teventExtractorMap,\n\t[\"drag\", \"dragend\", \"dragenter\", \"dragexit\", \"dragleave\", \"dragover\", \"dragstart\", \"drop\"],\n\tdragExtractor,\n);\n\nadd(eventExtractorMap, [\"keydown\", \"keypress\", \"keyup\"], keyboardExtractor);\nadd(eventExtractorMap, [\"focus\", \"blur\"], focusExtractor);\nadd(eventExtractorMap, [\"change\", \"input\"], changeExtractor);\nadd(eventExtractorMap, [\"invalid\"], invalidExtractor);\nadd(eventExtractorMap, [\"reset\", \"submit\"], formExtractor);\nadd(eventExtractorMap, [\"copy\", \"cut\", \"paste\"], clipboardExtractor);\nadd(\n\teventExtractorMap,\n\t[\"compositionend\", \"compositionstart\", \"compositionupdate\"],\n\tcompositionExtractor,\n);\nadd(eventExtractorMap, [\"touchcancel\", \"touchend\", \"touchmove\", \"touchstart\"], touchExtractor);\nadd(eventExtractorMap, [\"scroll\"], uiExtractor);\nadd(eventExtractorMap, [\"wheel\"], wheelExtractor);\nadd(\n\teventExtractorMap,\n\t[\"animationstart\", \"animationend\", \"animationiteration\"],\n\tanimationExtractor,\n);\nadd(eventExtractorMap, [\"transitionend\"], transitionExtractor);\nadd(eventExtractorMap, [\"toggle\"], toggleExtractor);\n\nexport function extractEvent(value: any): any {\n\t// Duck-typing for React's SyntheticEvent.\n\t// We check for properties that are unique to synthetic events.\n\tif (\n\t\tvalue &&\n\t\ttypeof value === \"object\" &&\n\t\t\"nativeEvent\" in value &&\n\t\ttypeof value.isDefaultPrevented === \"function\"\n\t) {\n\t\tconst evt = value as SyntheticEvent;\n\t\t// The `type` property is crucial for the lookup.\n\t\tif (typeof evt.type !== \"string\") {\n\t\t\treturn value;\n\t\t}\n\n\t\tconst extractor = eventExtractorMap[evt.type.toLowerCase()];\n\t\tif (extractor) {\n\t\t\treturn extractor(evt);\n\t\t}\n\n\t\t// Fallback for unknown event types: minimal synthetic extractor\n\t\treturn syntheticExtractor(evt);\n\t}\n\n\t// If it's not a duck-typed event, return it as is.\n\treturn value;\n}\n","export type Primitive = number | string | boolean | null | undefined;\nexport type JSON<T> = T | Array<JSON<T>> | { [K: string]: JSON<T> };\nexport type PlainJSON = JSON<Primitive>;\nexport type Serializable = any;\n\nexport type Serialized = [[number[], number[], number[], number[]], PlainJSON];\n\nexport function serialize(data: Serializable): Serialized {\n\tconst seen = new Map<any, number>();\n\tconst refs: number[] = [];\n\tconst dates: number[] = [];\n\tconst sets: number[] = [];\n\tconst maps: number[] = [];\n\n\t// Single global counter - increments once per node visit\n\tlet globalIndex = 0;\n\n\tfunction process(value: Serializable, context?: string): PlainJSON {\n\t\tif (value == null || typeof value === \"string\" || typeof value === \"boolean\") {\n\t\t\treturn value;\n\t\t}\n\n\t\tif (typeof value === \"number\") {\n\t\t\tif (Number.isNaN(value)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!Number.isFinite(value)) {\n\t\t\t\tconst kind = value > 0 ? \"Infinity\" : \"-Infinity\";\n\t\t\t\tconst ctx = context ? ` in '${context}'` : \"\";\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot serialize ${kind}${ctx}. NaN and Infinity are not supported because they cannot be serialized to JSON.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\n\t\tconst idx = globalIndex++;\n\t\tconst prevRef = seen.get(value);\n\t\tif (prevRef !== undefined) {\n\t\t\t// Make sure to push the current index, but use the ref's index as the value!\n\t\t\trefs.push(idx);\n\t\t\treturn prevRef;\n\t\t}\n\n\t\tseen.set(value, idx);\n\n\t\tif (value instanceof Date) {\n\t\t\tdates.push(idx);\n\t\t\treturn value.toISOString();\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tconst length = value.length;\n\t\t\tconst result = new Array(length);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tresult[i] = process(value[i], context);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tif (value instanceof Map) {\n\t\t\tmaps.push(idx);\n\t\t\tconst rec: Record<string, any> = {};\n\t\t\tfor (const [key, entry] of value.entries()) {\n\t\t\t\trec[String(key)] = process(entry, String(key));\n\t\t\t}\n\t\t\treturn rec;\n\t\t}\n\n\t\tif (value instanceof Set) {\n\t\t\tsets.push(idx);\n\t\t\tconst size = value.size;\n\t\t\tconst result = new Array(size);\n\t\t\tlet i = 0;\n\t\t\tfor (const entry of value) {\n\t\t\t\tresult[i] = process(entry, context);\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tif (typeof value === \"object\") {\n\t\t\tconst rec: Record<string, any> = {};\n\t\t\tconst keys = Object.keys(value);\n\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\tconst key = keys[i];\n\t\t\t\trec[key] = process(value[key], key);\n\t\t\t}\n\t\t\treturn rec;\n\t\t}\n\n\t\tthrow new Error(`Unsupported value in serialization: ${value}`);\n\t}\n\n\tconst payload = process(data);\n\treturn [[refs, dates, sets, maps], payload];\n}\n\nexport interface DeserializationOptions {\n\tcoerceNullsToUndefined?: boolean;\n}\n\nexport function deserialize<Data extends Serializable = Serializable>(\n\tpayload: Serialized,\n\toptions?: DeserializationOptions,\n): Data {\n\tconst [[refsA, datesA, setsA, mapsA], data] = payload;\n\n\tconst refs = new Set(refsA);\n\tconst dates = new Set(datesA);\n\tconst sets = new Set(setsA);\n\tconst maps = new Set(mapsA);\n\n\tconst objects: Array<any> = [];\n\n\tfunction reconstruct(value: PlainJSON): any {\n\t\tconst idx = objects.length;\n\t\tif (refs.has(idx)) {\n\t\t\t// We increment the counter on refs during serialization. We're never\n\t\t\t// going to use this entry, so we can just push null.\n\t\t\tobjects.push(null);\n\t\t\treturn objects[value as number];\n\t\t}\n\n\t\tif (dates.has(idx)) {\n\t\t\tif (typeof value !== \"string\") {\n\t\t\t\tthrow new Error(\"Date payload must be an ISO string\");\n\t\t\t}\n\t\t\tconst literal = parseDateLiteral(value);\n\t\t\tif (literal) {\n\t\t\t\tconst [y, m, d] = literal;\n\t\t\t\tconst dt = new Date(Date.UTC(y, m - 1, d));\n\t\t\t\tobjects.push(dt);\n\t\t\t\treturn dt;\n\t\t\t}\n\t\t\tif (isDateLiteral(value)) {\n\t\t\t\tthrow new Error(`Invalid date literal: ${value}`);\n\t\t\t}\n\t\t\tconst dt = new Date(value);\n\t\t\tobjects.push(dt);\n\t\t\treturn dt;\n\t\t}\n\n\t\tif (\n\t\t\tvalue == null ||\n\t\t\ttypeof value === \"number\" ||\n\t\t\ttypeof value === \"string\" ||\n\t\t\ttypeof value === \"boolean\"\n\t\t) {\n\t\t\tif (options?.coerceNullsToUndefined) {\n\t\t\t\treturn value ?? undefined;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tif (sets.has(idx)) {\n\t\t\t\tconst result = new Set();\n\t\t\t\tobjects.push(result);\n\t\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\t\tresult.add(reconstruct(value[i]));\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tconst length = value.length;\n\t\t\tconst arr = new Array(length);\n\t\t\tobjects.push(arr);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tarr[i] = reconstruct(value[i]);\n\t\t\t}\n\t\t\treturn arr;\n\t\t}\n\n\t\tif (typeof value === \"object\") {\n\t\t\tif (maps.has(idx)) {\n\t\t\t\tconst result = new Map<string, any>();\n\t\t\t\tobjects.push(result);\n\t\t\t\tconst keys = Object.keys(value);\n\t\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\t\tconst key = keys[i];\n\t\t\t\t\tresult.set(key, reconstruct(value[key]));\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tconst result: Record<string, any> = {};\n\t\t\tobjects.push(result);\n\t\t\tconst keys = Object.keys(value);\n\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\tconst key = keys[i];\n\t\t\t\tresult[key] = reconstruct(value[key]);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tthrow new Error(`Unsupported value in deserialization: ${value}`);\n\t}\n\n\treturn reconstruct(data);\n}\n\nconst DATE_LITERAL_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction isDateLiteral(value: string): boolean {\n\treturn DATE_LITERAL_RE.test(value);\n}\n\nfunction parseDateLiteral(value: string): [number, number, number] | null {\n\tif (!isDateLiteral(value)) {\n\t\treturn null;\n\t}\n\tconst [yStr, mStr, dStr] = value.split(\"-\");\n\tconst y = Number(yStr);\n\tconst m = Number(mStr);\n\tconst d = Number(dStr);\n\tif (!Number.isInteger(y) || !Number.isInteger(m) || !Number.isInteger(d)) {\n\t\treturn null;\n\t}\n\tif (m < 1 || m > 12 || d < 1 || d > 31) {\n\t\treturn null;\n\t}\n\tconst dt = new Date(Date.UTC(y, m - 1, d));\n\tif (\n\t\tdt.getUTCFullYear() !== y ||\n\t\tdt.getUTCMonth() !== m - 1 ||\n\t\tdt.getUTCDate() !== d\n\t) {\n\t\treturn null;\n\t}\n\treturn [y, m, d];\n}\n","import type { NavigateFunction } from \"react-router\";\nimport { io, type Socket } from \"socket.io-client\";\nimport { ChannelBridge, PulseChannelResetError } from \"./channel\";\nimport type { RouteInfo } from \"./helpers\";\nimport type {\n\tClientApiResultMessage,\n\tClientJsResultMessage,\n\tClientMessage,\n\tServerApiCallMessage,\n\tServerChannelMessage,\n\tServerError,\n\tServerJsExecMessage,\n\tServerMessage,\n} from \"./messages\";\nimport type { PulsePrerenderView } from \"./pulse\";\nimport { extractEvent } from \"./serialize/events\";\nimport { deserialize, serialize } from \"./serialize/serializer\";\nimport type { VDOMUpdate } from \"./vdom\";\n\n\nexport interface SocketIODirectives {\n\theaders?: Record<string, string>;\n\tauth?: Record<string, string>;\n}\nexport interface Directives {\n\theaders?: Record<string, string>;\n\tsocketio?: SocketIODirectives;\n}\nexport interface MountedView {\n\trouteInfo: RouteInfo;\n\tonInit: (view: PulsePrerenderView) => void;\n\tonUpdate: (ops: VDOMUpdate[]) => void;\n\tonJsExec: (msg: ServerJsExecMessage) => void;\n\tonServerError: (error: ServerError) => void;\n}\nexport type ConnectionStatus = \"ok\" | \"connecting\" | \"reconnecting\" | \"error\";\nexport type ConnectionStatusListener = (status: ConnectionStatus) => void;\n\nexport interface PulseClient {\n\t// Connection management\n\tconnect(): Promise<void>;\n\tdisconnect(): void;\n\tisConnected(): boolean;\n\tonConnectionChange(listener: ConnectionStatusListener): () => void;\n\t// Messages\n\tupdateRoute(path: string, routeInfo: RouteInfo): void;\n\tinvokeCallback(path: string, callback: string, args: any[]): void;\n\t// VDOM subscription\n\tattach(path: string, view: MountedView): void;\n\tdetach(path: string): void;\n}\n\nexport class PulseSocketIOClient {\n\t#activeViews: Map<string, MountedView>;\n\t#socket: Socket | null = null;\n\t#messageQueue: ClientMessage[];\n\t#connectionListeners: Set<ConnectionStatusListener> = new Set();\n\t#channels: Map<string, { bridge: ChannelBridge; refCount: number }> = new Map();\n\t#url: string;\n\t#frameworkNavigate: NavigateFunction;\n\t#directives: Directives;\n\t#connectionStatusConfig: {\n\t\tinitialConnectingDelay: number;\n\t\tinitialErrorDelay: number;\n\t\treconnectErrorDelay: number;\n\t};\n\t#hasConnectedOnce: boolean = false;\n\t#connectingTimeout: ReturnType<typeof setTimeout> | null = null;\n\t#errorTimeout: ReturnType<typeof setTimeout> | null = null;\n\t#currentStatus: ConnectionStatus = \"ok\";\n\n\tconstructor(\n\t\turl: string,\n\t\tdirectives: Directives,\n\t\tframeworkNavigate: NavigateFunction,\n\t\tconnectionStatusConfig: {\n\t\t\tinitialConnectingDelay: number;\n\t\t\tinitialErrorDelay: number;\n\t\t\treconnectErrorDelay: number;\n\t\t},\n\t) {\n\t\tthis.#url = url;\n\t\tthis.#directives = directives;\n\t\tthis.#frameworkNavigate = frameworkNavigate;\n\t\tthis.#socket = null;\n\t\tthis.#activeViews = new Map();\n\t\tthis.#messageQueue = [];\n\t\tthis.#connectionStatusConfig = connectionStatusConfig;\n\t}\n\tpublic setDirectives(directives: Directives) {\n\t\tthis.#directives = directives;\n\t}\n\tpublic isConnected(): boolean {\n\t\treturn this.#socket?.connected ?? false;\n\t}\n\n\t#clearTimeouts(): void {\n\t\tif (this.#connectingTimeout) {\n\t\t\tclearTimeout(this.#connectingTimeout);\n\t\t\tthis.#connectingTimeout = null;\n\t\t}\n\t\tif (this.#errorTimeout) {\n\t\t\tclearTimeout(this.#errorTimeout);\n\t\t\tthis.#errorTimeout = null;\n\t\t}\n\t}\n\n\t#setStatus(status: ConnectionStatus): void {\n\t\tthis.#clearTimeouts();\n\t\tthis.#currentStatus = status;\n\t\tthis.#notifyConnectionListeners(status);\n\t}\n\n\t#handleConnected(): void {\n\t\tthis.#hasConnectedOnce = true;\n\t\tthis.#setStatus(\"ok\");\n\t}\n\n\t#setInitialConnectionStatus(): void {\n\t\t// Initial connection attempt - start with no message, then show connecting after delay\n\t\tthis.#setStatus(\"ok\");\n\t\tthis.#connectingTimeout = setTimeout(() => {\n\t\t\tthis.#setStatus(\"connecting\");\n\t\t\tthis.#errorTimeout = setTimeout(() => {\n\t\t\t\tthis.#setStatus(\"error\");\n\t\t\t}, this.#connectionStatusConfig.initialErrorDelay);\n\t\t}, this.#connectionStatusConfig.initialConnectingDelay);\n\t}\n\n\t#handleDisconnected(): void {\n\t\t// Reconnection after losing connection - show reconnecting immediately\n\t\tthis.#setStatus(\"reconnecting\");\n\t\tthis.#errorTimeout = setTimeout(() => {\n\t\t\tthis.#setStatus(\"error\");\n\t\t}, this.#connectionStatusConfig.reconnectErrorDelay);\n\t}\n\n\tpublic async connect(): Promise<void> {\n\t\tif (this.#socket) {\n\t\t\treturn;\n\t\t}\n\t\t// Start timing logic for connection attempt\n\t\tif (!this.#hasConnectedOnce) {\n\t\t\tthis.#setInitialConnectionStatus();\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst socket = io(this.#url, {\n\t\t\t\ttransports: [\"websocket\", \"webtransport\"],\n\t\t\t\tauth: this.#directives.socketio?.auth,\n\t\t\t\textraHeaders: this.#directives.socketio?.headers,\n\t\t\t});\n\t\t\tthis.#socket = socket;\n\n\t\t\tsocket.on(\"connect\", () => {\n\t\t\t\tconsole.log(\"[SocketIOTransport] Connected:\", this.#socket?.id);\n\t\t\t\t// Send attach for all active views on connect/reconnect\n\t\t\t\tfor (const [path, route] of this.#activeViews) {\n\t\t\t\t\tsocket.emit(\n\t\t\t\t\t\t\"message\",\n\t\t\t\t\t\tserialize({\n\t\t\t\t\t\t\ttype: \"attach\",\n\t\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\t\trouteInfo: route.routeInfo,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tfor (const payload of this.#messageQueue) {\n\t\t\t\t\t// Already sent above\n\t\t\t\t\tif (payload.type === \"attach\" && this.#activeViews.has(payload.path)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t// We're reattaching all the routes, so no need to send update\n\t\t\t\t\tif (payload.type === \"update\") {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tsocket.emit(\"message\", serialize(payload));\n\t\t\t\t}\n\t\t\t\tthis.#messageQueue = [];\n\n\t\t\t\tthis.#handleConnected();\n\t\t\t\tresolve();\n\t\t\t});\n\n\t\t\tsocket.on(\"connect_error\", (err) => {\n\t\t\t\tconsole.error(\"[SocketIOTransport] Connection failed:\", err);\n\t\t\t\tthis.#handleDisconnected();\n\t\t\t\treject(err);\n\t\t\t});\n\n\t\t\tsocket.on(\"disconnect\", () => {\n\t\t\t\tconsole.log(\"[SocketIOTransport] Disconnected\");\n\t\t\t\tthis.#handleTransportDisconnect();\n\t\t\t\tthis.#handleDisconnected();\n\t\t\t});\n\n\t\t\t// Wrap in an arrow function to avoid losing the `this` reference\n\t\t\tsocket.on(\"message\", (data) =>\n\t\t\t\tthis.#handleServerMessage(deserialize(data, { coerceNullsToUndefined: true })),\n\t\t\t);\n\t\t});\n\t}\n\n\tonConnectionChange(listener: ConnectionStatusListener): () => void {\n\t\tthis.#connectionListeners.add(listener);\n\t\t// Notify immediately with current status\n\t\tlistener(this.#currentStatus);\n\t\treturn () => {\n\t\t\tthis.#connectionListeners.delete(listener);\n\t\t};\n\t}\n\n\t#notifyConnectionListeners(status: ConnectionStatus): void {\n\t\tfor (const listener of this.#connectionListeners) {\n\t\t\tlistener(status);\n\t\t}\n\t}\n\n\tpublic sendMessage(payload: ClientMessage) {\n\t\tif (this.isConnected()) {\n\t\t\t// console.log(\"[SocketIOTransport] Sending:\", payload);\n\t\t\tthis.#socket!.emit(\"message\", serialize(payload as any));\n\t\t} else {\n\t\t\t// console.log(\"[SocketIOTransport] Queuing message:\", payload);\n\t\t\tthis.#messageQueue.push(payload);\n\t\t}\n\t}\n\n\tpublic attach(path: string, view: MountedView) {\n\t\tif (this.#activeViews.has(path)) {\n\t\t\tthrow new Error(`Path ${path} is already attached`);\n\t\t}\n\t\tthis.#activeViews.set(path, view);\n\t\tvoid this.sendMessage({\n\t\t\ttype: \"attach\",\n\t\t\tpath,\n\t\t\trouteInfo: view.routeInfo,\n\t\t});\n\t}\n\n\tpublic updateRoute(path: string, routeInfo: RouteInfo) {\n\t\tconst view = this.#activeViews.get(path);\n\t\tif (view) {\n\t\t\tview.routeInfo = routeInfo;\n\t\t\tthis.sendMessage({\n\t\t\t\ttype: \"update\",\n\t\t\t\tpath,\n\t\t\t\trouteInfo,\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic detach(path: string) {\n\t\tvoid this.sendMessage({ type: \"detach\", path });\n\t\tthis.#activeViews.delete(path);\n\t}\n\n\tpublic disconnect() {\n\t\tthis.#clearTimeouts();\n\t\tthis.#socket?.disconnect();\n\t\tthis.#socket = null;\n\t\tthis.#messageQueue = [];\n\t\tthis.#connectionListeners.clear();\n\t\tthis.#activeViews.clear();\n\t\tfor (const { bridge } of this.#channels.values()) {\n\t\t\tbridge.dispose(new PulseChannelResetError(\"Client disconnected\"));\n\t\t}\n\t\tthis.#channels.clear();\n\t\tthis.#currentStatus = \"ok\";\n\t\tthis.#hasConnectedOnce = false;\n\t}\n\n\t#handleServerMessage(message: ServerMessage) {\n\t\t// console.log(\"[PulseClient] Received message:\", message);\n\t\tswitch (message.type) {\n\t\t\tcase \"vdom_init\": {\n\t\t\t\tconst route = this.#activeViews.get(message.path);\n\t\t\t\t// Ignore messages for paths that are not mounted\n\t\t\t\tif (!route) return;\n\t\t\t\troute.onInit(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"vdom_update\": {\n\t\t\t\tconst route = this.#activeViews.get(message.path);\n\t\t\t\tif (!route) return; // Not an active path; discard\n\t\t\t\troute.onUpdate(message.ops);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"server_error\": {\n\t\t\t\tconst route = this.#activeViews.get(message.path);\n\t\t\t\tif (!route) return; // discard for inactive paths\n\t\t\t\troute.onServerError(message.error);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"api_call\": {\n\t\t\t\tvoid this.#performApiCall(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"navigate_to\": {\n\t\t\t\tconst replace = !!message.replace;\n\t\t\t\tlet dest = message.path || \"\";\n\t\t\t\tif (dest.startsWith(\"//\")) dest = `${window.location.protocol}${dest}`;\n\n\t\t\t\tconst hardNav = () =>\n\t\t\t\t\treplace ? window.location.replace(dest) : window.location.assign(dest);\n\n\t\t\t\tif (message.hard) {\n\t\t\t\t\thardNav();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// No scheme = relative path → SPA\n\t\t\t\tif (!/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(dest)) {\n\t\t\t\t\tthis.#frameworkNavigate(dest, { replace });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Same-origin http(s) → SPA\n\t\t\t\tif (/^https?:\\/\\//.test(dest)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst url = new URL(dest);\n\t\t\t\t\t\tif (url.origin === window.location.origin) {\n\t\t\t\t\t\t\tthis.#frameworkNavigate(`${url.pathname}${url.search}${url.hash}`, { replace });\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {}\n\t\t\t\t}\n\n\t\t\t\t// External URL or other scheme (mailto:, tel:, etc.)\n\t\t\t\thardNav();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"reload\": {\n\t\t\t\twindow.location.reload();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"channel_message\": {\n\t\t\t\tthis.#routeChannelMessage(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"js_exec\": {\n\t\t\t\tthis.#handleJsExec(message);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconsole.error(\"Unexpected message:\", message);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync #performApiCall(msg: ServerApiCallMessage) {\n\t\ttry {\n\t\t\tconst res = await fetch(msg.url, {\n\t\t\t\tmethod: msg.method || \"GET\",\n\t\t\t\theaders: {\n\t\t\t\t\t...(msg.headers || {}),\n\t\t\t\t\t...(msg.body != null && !(\"content-type\" in (msg.headers || {}))\n\t\t\t\t\t\t? { \"content-type\": \"application/json\" }\n\t\t\t\t\t\t: {}),\n\t\t\t\t},\n\t\t\t\tbody:\n\t\t\t\t\tmsg.body != null\n\t\t\t\t\t\t? typeof msg.body === \"string\"\n\t\t\t\t\t\t\t? msg.body\n\t\t\t\t\t\t\t: JSON.stringify(msg.body)\n\t\t\t\t\t\t: undefined,\n\t\t\t\tcredentials: msg.credentials || \"include\",\n\t\t\t});\n\t\t\tconst headersObj: Record<string, string> = {};\n\t\t\tres.headers.forEach((v, k) => {\n\t\t\t\theadersObj[k] = v;\n\t\t\t});\n\t\t\tlet body: any = null;\n\t\t\tconst ct = res.headers.get(\"content-type\") || \"\";\n\t\t\tif (ct.includes(\"application/json\")) {\n\t\t\t\tbody = await res.json().catch(() => null);\n\t\t\t} else {\n\t\t\t\tbody = await res.text().catch(() => null);\n\t\t\t}\n\t\t\tconst reply: ClientApiResultMessage = {\n\t\t\t\ttype: \"api_result\",\n\t\t\t\tid: msg.id,\n\t\t\t\tok: res.ok,\n\t\t\t\tstatus: res.status,\n\t\t\t\theaders: headersObj,\n\t\t\t\tbody,\n\t\t\t};\n\t\t\tthis.sendMessage(reply);\n\t\t} catch (err) {\n\t\t\tconst reply: ClientApiResultMessage = {\n\t\t\t\ttype: \"api_result\",\n\t\t\t\tid: msg.id,\n\t\t\t\tok: false,\n\t\t\t\tstatus: 0,\n\t\t\t\theaders: {},\n\t\t\t\tbody: { error: String(err) },\n\t\t\t};\n\t\t\tthis.sendMessage(reply);\n\t\t}\n\t}\n\n\tpublic invokeCallback(path: string, callback: string, args: any[]) {\n\t\tthis.sendMessage({\n\t\t\ttype: \"callback\",\n\t\t\tpath,\n\t\t\tcallback,\n\t\t\targs: args.map(extractEvent),\n\t\t});\n\t}\n\n\t#handleJsExec(message: ServerJsExecMessage) {\n\t\tconst view = this.#activeViews.get(message.path);\n\t\tif (!view) {\n\t\t\t// View unmounted before the message arrived - send result back to unblock\n\t\t\t// the server-side future (which is likely already cancelled anyway).\n\t\t\tthis.#sendJsResult(message.id, undefined, null);\n\t\t\treturn;\n\t\t}\n\t\tview.onJsExec(message);\n\t}\n\n\tpublic sendJsResult(id: string, result: any, error: string | null) {\n\t\tthis.#sendJsResult(id, result, error);\n\t}\n\n\t#sendJsResult(id: string, result: any, error: string | null) {\n\t\tconst msg: ClientJsResultMessage = {\n\t\t\ttype: \"js_result\",\n\t\t\tid,\n\t\t\tresult,\n\t\t\terror,\n\t\t};\n\t\tthis.sendMessage(msg);\n\t}\n\n\tpublic acquireChannel(id: string): ChannelBridge {\n\t\tconst entry = this.#ensureChannelEntry(id);\n\t\tentry.refCount += 1;\n\t\treturn entry.bridge;\n\t}\n\n\tpublic releaseChannel(id: string): void {\n\t\tconst entry = this.#channels.get(id);\n\t\tif (!entry) {\n\t\t\treturn;\n\t\t}\n\t\tentry.refCount = Math.max(0, entry.refCount - 1);\n\t\tif (entry.refCount === 0) {\n\t\t\tentry.bridge.dispose(new PulseChannelResetError(\"Channel released\"));\n\t\t\tthis.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: id,\n\t\t\t\tevent: \"__close__\",\n\t\t\t\tpayload: { reason: \"refcount_zero\" },\n\t\t\t});\n\t\t\tthis.#channels.delete(id);\n\t\t}\n\t}\n\n\t#ensureChannelEntry(id: string): {\n\t\tbridge: ChannelBridge;\n\t\trefCount: number;\n\t} {\n\t\tlet entry = this.#channels.get(id);\n\t\tif (!entry) {\n\t\t\tentry = {\n\t\t\t\tbridge: new ChannelBridge(this, id),\n\t\t\t\trefCount: 0,\n\t\t\t};\n\t\t\tthis.#channels.set(id, entry);\n\t\t}\n\t\treturn entry;\n\t}\n\n\t#routeChannelMessage(message: ServerChannelMessage): void {\n\t\tconst entry = this.#ensureChannelEntry(message.channel);\n\t\tconst closed = entry.bridge.handleServerMessage(message);\n\t\tif (closed && entry.refCount === 0) {\n\t\t\tthis.#channels.delete(message.channel);\n\t\t}\n\t}\n\n\t#handleTransportDisconnect(): void {\n\t\tfor (const entry of this.#channels.values()) {\n\t\t\tentry.bridge.handleDisconnect(new PulseChannelResetError(\"Connection lost\"));\n\t\t}\n\t}\n\n\t_ensureChannelEntry(id: string): {\n\t\tbridge: ChannelBridge;\n\t\trefCount: number;\n\t} {\n\t\treturn this.#ensureChannelEntry(id);\n\t}\n}\n","import type { ChannelBridge } from \"./channel\";\nimport type { PulseRefSpec } from \"./vdom\";\n\ntype RefPayload = {\n\trefId?: string;\n\top?: string;\n\tpayload?: any;\n};\n\ntype RefOpResult = any;\n\ntype RefEntry = {\n\tnode: any;\n\tcallback: (node: any) => void;\n};\n\ntype ChannelBridgeProvider = (channelId: string) => ChannelBridge;\n\nconst ATTR_ALIASES: Record<string, string> = {\n\tclassName: \"class\",\n\thtmlFor: \"for\",\n\ttabIndex: \"tabindex\",\n};\n\nconst ATTR_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_:\\-\\.]*$/;\n\nconst GETTABLE_PROPS = new Set([\n\t\"value\",\n\t\"checked\",\n\t\"disabled\",\n\t\"readOnly\",\n\t\"selectedIndex\",\n\t\"selectionStart\",\n\t\"selectionEnd\",\n\t\"selectionDirection\",\n\t\"scrollTop\",\n\t\"scrollLeft\",\n\t\"scrollHeight\",\n\t\"scrollWidth\",\n\t\"clientWidth\",\n\t\"clientHeight\",\n\t\"offsetWidth\",\n\t\"offsetHeight\",\n\t\"innerText\",\n\t\"textContent\",\n\t\"className\",\n\t\"id\",\n\t\"name\",\n\t\"type\",\n\t\"tabIndex\",\n]);\n\nconst SETTABLE_PROPS = new Set([\n\t\"value\",\n\t\"checked\",\n\t\"disabled\",\n\t\"readOnly\",\n\t\"selectedIndex\",\n\t\"selectionStart\",\n\t\"selectionEnd\",\n\t\"selectionDirection\",\n\t\"scrollTop\",\n\t\"scrollLeft\",\n\t\"className\",\n\t\"id\",\n\t\"name\",\n\t\"type\",\n\t\"tabIndex\",\n]);\n\nfunction isRefPayload(value: unknown): value is RefPayload {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction normalizeAttrName(name: string): string {\n\treturn ATTR_ALIASES[name] ?? name;\n}\n\nfunction ensureAttrName(value: unknown): string {\n\tif (typeof value !== \"string\") {\n\t\tthrow new Error(\"ref attribute name must be a string\");\n\t}\n\tconst trimmed = value.trim();\n\tif (!trimmed) {\n\t\tthrow new Error(\"ref attribute name must be non-empty\");\n\t}\n\tconst normalized = normalizeAttrName(trimmed);\n\tif (!ATTR_NAME_PATTERN.test(normalized)) {\n\t\tthrow new Error(`invalid attribute name: ${normalized}`);\n\t}\n\tif (normalized.toLowerCase().startsWith(\"on\")) {\n\t\tthrow new Error(\"ref attribute name cannot start with 'on'\");\n\t}\n\treturn normalized;\n}\n\nfunction ensurePropName(value: unknown, settable: boolean): string {\n\tif (typeof value !== \"string\") {\n\t\tthrow new Error(\"ref property name must be a string\");\n\t}\n\tconst trimmed = value.trim();\n\tif (!trimmed) {\n\t\tthrow new Error(\"ref property name must be non-empty\");\n\t}\n\tif (!GETTABLE_PROPS.has(trimmed)) {\n\t\tthrow new Error(`unsupported ref property: ${trimmed}`);\n\t}\n\tif (settable && !SETTABLE_PROPS.has(trimmed)) {\n\t\tthrow new Error(`ref property is read-only: ${trimmed}`);\n\t}\n\treturn trimmed;\n}\n\nfunction ensureElement(node: any): Element {\n\tif (!node || typeof node.getAttribute !== \"function\") {\n\t\tthrow new Error(\"ref is not bound to a DOM element\");\n\t}\n\treturn node as Element;\n}\n\nfunction ensureHTMLElement(node: any): HTMLElement {\n\tif (!node || typeof (node as HTMLElement).style === \"undefined\") {\n\t\tthrow new Error(\"ref is not bound to an HTML element\");\n\t}\n\treturn node as HTMLElement;\n}\n\nfunction parseScrollOptions(payload: any): ScrollToOptions | undefined {\n\tif (!payload || typeof payload !== \"object\") return undefined;\n\tconst options: ScrollToOptions = {};\n\tif (typeof payload.top === \"number\") options.top = payload.top;\n\tif (typeof payload.left === \"number\") options.left = payload.left;\n\tif (typeof payload.behavior === \"string\") {\n\t\toptions.behavior = payload.behavior as ScrollBehavior;\n\t}\n\treturn Object.keys(options).length > 0 ? options : undefined;\n}\n\nfunction parseScrollIntoViewOptions(payload: any): ScrollIntoViewOptions | undefined {\n\tif (!payload || typeof payload !== \"object\") return undefined;\n\tconst options: ScrollIntoViewOptions = {};\n\tif (typeof payload.behavior === \"string\") {\n\t\toptions.behavior = payload.behavior as ScrollBehavior;\n\t}\n\tif (typeof payload.block === \"string\") {\n\t\toptions.block = payload.block as ScrollLogicalPosition;\n\t}\n\tif (typeof payload.inline === \"string\") {\n\t\toptions.inline = payload.inline as ScrollLogicalPosition;\n\t}\n\treturn Object.keys(options).length > 0 ? options : undefined;\n}\n\nfunction normalizeStyleValue(value: unknown): string | null {\n\tif (value == null) return null;\n\tif (typeof value === \"string\") return value;\n\tif (typeof value === \"number\") return String(value);\n\tthrow new Error(\"style values must be strings or numbers\");\n}\n\nfunction parseRefPayload(payload: unknown): {\n\trefId: string | null;\n\top: string | null;\n\tpayload: any;\n} {\n\tif (!isRefPayload(payload)) {\n\t\treturn { refId: null, op: null, payload: null };\n\t}\n\tconst refId = payload.refId;\n\tconst op = payload.op;\n\treturn {\n\t\trefId: refId == null ? null : String(refId),\n\t\top: typeof op === \"string\" ? op : null,\n\t\tpayload: payload.payload,\n\t};\n}\n\nexport function isPulseRefSpec(v: unknown): v is PulseRefSpec {\n\treturn typeof v === \"object\" && v !== null && \"__pulse_ref__\" in (v as any);\n}\n\nexport class RefRegistry {\n\t#getBridge: ChannelBridgeProvider;\n\t#bridge: ChannelBridge | null = null;\n\t#channelId: string | null = null;\n\t#entries: Map<string, RefEntry> = new Map();\n\t#cleanup: Array<() => void> = [];\n\n\tconstructor(getBridge: ChannelBridgeProvider) {\n\t\tthis.#getBridge = getBridge;\n\t}\n\n\tgetCallback(channelId: string, refId: string): (node: any) => void {\n\t\tthis.#ensureChannel(channelId);\n\t\tlet entry = this.#entries.get(refId);\n\t\tif (!entry) {\n\t\t\tconst callback = (node: any) => {\n\t\t\t\tthis.#setNode(refId, node ?? null);\n\t\t\t};\n\t\t\tentry = { node: null, callback };\n\t\t\tthis.#entries.set(refId, entry);\n\t\t}\n\t\treturn entry.callback;\n\t}\n\n\tdispose(): void {\n\t\tthis.#teardown();\n\t}\n\n\t#ensureChannel(channelId: string): void {\n\t\tif (this.#bridge) {\n\t\t\tif (this.#channelId !== channelId) {\n\t\t\t\tthrow new Error(\"[Pulse] Ref channel changed unexpectedly\");\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tconst bridge = this.#getBridge(channelId);\n\t\tthis.#bridge = bridge;\n\t\tthis.#channelId = channelId;\n\t\tthis.#cleanup.push(\n\t\t\tbridge.on(\"ref:call\", (payload) => {\n\t\t\t\tthis.#handleCall(payload);\n\t\t\t}),\n\t\t\tbridge.on(\"ref:request\", (payload) => {\n\t\t\t\treturn this.#handleRequest(payload);\n\t\t\t}),\n\t\t);\n\t}\n\n\t#teardown(): void {\n\t\tfor (const fn of this.#cleanup) fn();\n\t\tthis.#cleanup = [];\n\t\tthis.#entries.clear();\n\t\tthis.#bridge = null;\n\t\tthis.#channelId = null;\n\t}\n\n\t#setNode(refId: string, node: any): void {\n\t\tconst entry = this.#entries.get(refId);\n\t\tif (!entry) return;\n\t\tif (entry.node === node) return;\n\t\tentry.node = node;\n\t\tconst bridge = this.#bridge;\n\t\tif (!bridge) return;\n\t\tif (node) {\n\t\t\tbridge.emit(\"ref:mounted\", { refId });\n\t\t} else {\n\t\t\tbridge.emit(\"ref:unmounted\", { refId });\n\t\t}\n\t}\n\n\t#handleCall(payload: unknown): void {\n\t\tconst parsed = parseRefPayload(payload);\n\t\tif (!parsed.refId || !parsed.op) return;\n\t\ttry {\n\t\t\tthis.#perform(parsed.refId, parsed.op, parsed.payload, false);\n\t\t} catch (err) {\n\t\t\tconsole.error(\"[Pulse] Ref call failed:\", err);\n\t\t}\n\t}\n\n\t#handleRequest(payload: unknown): RefOpResult {\n\t\tconst parsed = parseRefPayload(payload);\n\t\tif (!parsed.op) {\n\t\t\tthrow new Error(\"ref request missing op\");\n\t\t}\n\t\tif (!parsed.refId) {\n\t\t\tthrow new Error(\"ref request missing refId\");\n\t\t}\n\t\treturn this.#perform(parsed.refId, parsed.op, parsed.payload, true);\n\t}\n\n\t#perform(refId: string, op: string, payload: any, needsResult: boolean): RefOpResult {\n\t\tconst entry = this.#entries.get(refId);\n\t\tconst node = entry?.node as any;\n\t\tif (!node) {\n\t\t\tconst msg = \"ref is not mounted\";\n\t\t\tif (needsResult) throw new Error(msg);\n\t\t\tconsole.warn(`[Pulse] ${msg}`);\n\t\t\treturn null;\n\t\t}\n\n\t\tswitch (op) {\n\t\t\tcase \"focus\":\n\t\t\t\tif (typeof node.focus === \"function\") {\n\t\t\t\t\tif (payload && typeof payload === \"object\" && \"preventScroll\" in payload) {\n\t\t\t\t\t\tconst preventScroll = Boolean((payload as any).preventScroll);\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tnode.focus({ preventScroll });\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tnode.focus();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode.focus();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\tcase \"blur\":\n\t\t\t\tif (typeof node.blur === \"function\") node.blur();\n\t\t\t\treturn null;\n\t\t\tcase \"click\":\n\t\t\t\tif (typeof node.click === \"function\") node.click();\n\t\t\t\treturn null;\n\t\t\tcase \"select\":\n\t\t\t\tif (typeof node.select === \"function\") node.select();\n\t\t\t\telse throw new Error(\"select() not supported on this element\");\n\t\t\t\treturn null;\n\t\t\tcase \"scrollIntoView\": {\n\t\t\t\tif (typeof node.scrollIntoView !== \"function\") {\n\t\t\t\t\tthrow new Error(\"scrollIntoView() not supported on this element\");\n\t\t\t\t}\n\t\t\t\tconst options = parseScrollIntoViewOptions(payload) ?? undefined;\n\t\t\t\tnode.scrollIntoView(options);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"scrollTo\": {\n\t\t\t\tif (typeof node.scrollTo !== \"function\") {\n\t\t\t\t\tthrow new Error(\"scrollTo() not supported on this element\");\n\t\t\t\t}\n\t\t\t\tconst options = parseScrollOptions(payload);\n\t\t\t\tnode.scrollTo(options ?? undefined);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"scrollBy\": {\n\t\t\t\tif (typeof node.scrollBy !== \"function\") {\n\t\t\t\t\tthrow new Error(\"scrollBy() not supported on this element\");\n\t\t\t\t}\n\t\t\t\tconst options = parseScrollOptions(payload);\n\t\t\t\tnode.scrollBy(options ?? undefined);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"submit\": {\n\t\t\t\tif (typeof node.submit !== \"function\") {\n\t\t\t\t\tthrow new Error(\"submit() not supported on this element\");\n\t\t\t\t}\n\t\t\t\tnode.submit();\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"reset\": {\n\t\t\t\tif (typeof node.reset !== \"function\") {\n\t\t\t\t\tthrow new Error(\"reset() not supported on this element\");\n\t\t\t\t}\n\t\t\t\tnode.reset();\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"setSelectionRange\": {\n\t\t\t\tif (typeof node.setSelectionRange !== \"function\") {\n\t\t\t\t\tthrow new Error(\"setSelectionRange() not supported on this element\");\n\t\t\t\t}\n\t\t\t\tif (!payload || typeof payload !== \"object\") {\n\t\t\t\t\tthrow new Error(\"setSelectionRange() requires payload\");\n\t\t\t\t}\n\t\t\t\tconst start = (payload as any).start;\n\t\t\t\tconst end = (payload as any).end;\n\t\t\t\tconst direction = (payload as any).direction;\n\t\t\t\tif (typeof start !== \"number\" || typeof end !== \"number\") {\n\t\t\t\t\tthrow new Error(\"setSelectionRange() requires numeric start/end\");\n\t\t\t\t}\n\t\t\t\tnode.setSelectionRange(start, end, direction ?? undefined);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"measure\": {\n\t\t\t\tif (typeof node.getBoundingClientRect !== \"function\") {\n\t\t\t\t\tthrow new Error(\"measure() not supported on this element\");\n\t\t\t\t}\n\t\t\t\tconst rect = node.getBoundingClientRect();\n\t\t\t\treturn {\n\t\t\t\t\tx: rect.x,\n\t\t\t\t\ty: rect.y,\n\t\t\t\t\twidth: rect.width,\n\t\t\t\t\theight: rect.height,\n\t\t\t\t\ttop: rect.top,\n\t\t\t\t\tright: rect.right,\n\t\t\t\t\tbottom: rect.bottom,\n\t\t\t\t\tleft: rect.left,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"getValue\": {\n\t\t\t\tif (\"value\" in node) return (node as any).value;\n\t\t\t\tif (\"textContent\" in node) return (node as any).textContent;\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"setValue\": {\n\t\t\t\tconst value = payload?.value;\n\t\t\t\tif (\"value\" in node) {\n\t\t\t\t\t(node as any).value = value;\n\t\t\t\t\treturn (node as any).value;\n\t\t\t\t}\n\t\t\t\tif (\"textContent\" in node) {\n\t\t\t\t\t(node as any).textContent = value == null ? \"\" : String(value);\n\t\t\t\t\treturn (node as any).textContent;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"getText\": {\n\t\t\t\tif (\"textContent\" in node) return (node as any).textContent;\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"setText\": {\n\t\t\t\tconst text = payload?.text;\n\t\t\t\tif (typeof text !== \"string\") {\n\t\t\t\t\tthrow new Error(\"setText() requires a string payload\");\n\t\t\t\t}\n\t\t\t\tif (\"textContent\" in node) {\n\t\t\t\t\t(node as any).textContent = text;\n\t\t\t\t\treturn (node as any).textContent;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"getAttr\": {\n\t\t\t\tconst name = ensureAttrName(payload?.name);\n\t\t\t\tconst el = ensureElement(node);\n\t\t\t\treturn el.getAttribute(name);\n\t\t\t}\n\t\t\tcase \"setAttr\": {\n\t\t\t\tconst name = ensureAttrName(payload?.name);\n\t\t\t\tconst el = ensureElement(node);\n\t\t\t\tconst value = payload?.value;\n\t\t\t\tif (value == null) {\n\t\t\t\t\tel.removeAttribute(name);\n\t\t\t\t} else {\n\t\t\t\t\tel.setAttribute(name, String(value));\n\t\t\t\t}\n\t\t\t\treturn el.getAttribute(name);\n\t\t\t}\n\t\t\tcase \"removeAttr\": {\n\t\t\t\tconst name = ensureAttrName(payload?.name);\n\t\t\t\tconst el = ensureElement(node);\n\t\t\t\tel.removeAttribute(name);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"getProp\": {\n\t\t\t\tconst name = ensurePropName(payload?.name, false);\n\t\t\t\tif (!(name in node)) {\n\t\t\t\t\tthrow new Error(`ref property not supported on element: ${name}`);\n\t\t\t\t}\n\t\t\t\treturn (node as any)[name];\n\t\t\t}\n\t\t\tcase \"setProp\": {\n\t\t\t\tconst name = ensurePropName(payload?.name, true);\n\t\t\t\tif (!(name in node)) {\n\t\t\t\t\tthrow new Error(`ref property not supported on element: ${name}`);\n\t\t\t\t}\n\t\t\t\t(node as any)[name] = payload?.value;\n\t\t\t\treturn (node as any)[name];\n\t\t\t}\n\t\t\tcase \"setStyle\": {\n\t\t\t\tconst el = ensureHTMLElement(node);\n\t\t\t\tconst styles = payload?.styles;\n\t\t\t\tif (!styles || typeof styles !== \"object\") {\n\t\t\t\t\tthrow new Error(\"setStyle() requires a styles object\");\n\t\t\t\t}\n\t\t\t\tfor (const [rawKey, rawValue] of Object.entries(styles)) {\n\t\t\t\t\tif (!rawKey) {\n\t\t\t\t\t\tthrow new Error(\"style key must be non-empty\");\n\t\t\t\t\t}\n\t\t\t\t\tconst value = normalizeStyleValue(rawValue);\n\t\t\t\t\tif (rawKey.includes(\"-\")) {\n\t\t\t\t\t\tif (value == null) {\n\t\t\t\t\t\t\tel.style.removeProperty(rawKey);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tel.style.setProperty(rawKey, value);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (value == null) {\n\t\t\t\t\t\t(el.style as any)[rawKey] = \"\";\n\t\t\t\t\t} else {\n\t\t\t\t\t\t(el.style as any)[rawKey] = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported ref op: ${op}`);\n\t\t}\n\t}\n}\n","// =============================================================================\n// VDOM (structural expressions + eval-keyed props)\n// =============================================================================\n\nexport const FRAGMENT_TAG = \"\";\nexport const MOUNT_POINT_PREFIX = \"$$\";\n\n// Unified registry: mount-point key -> React component (or any registry object).\nexport type ComponentRegistry = Record<string, any>;\n\n// -----------------------------------------------------------------------------\n// JSON types\n// -----------------------------------------------------------------------------\n\nexport type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonValue[] | { [k: string]: JsonValue };\n\n// -----------------------------------------------------------------------------\n// Expression tree (client-evaluable)\n// -----------------------------------------------------------------------------\n\nexport type VDOMExpr =\n\t| RegistryRefExpr\n\t| IdentifierExpr\n\t| LiteralExpr\n\t| UndefinedExpr\n\t| ArrayExpr\n\t| ObjectExpr\n\t| MemberExpr\n\t| SubscriptExpr\n\t| CallExpr\n\t| UnaryExpr\n\t| BinaryExpr\n\t| TernaryExpr\n\t| TemplateExpr\n\t| ArrowExpr\n\t| NewExpr;\n\nexport interface RegistryRefExpr {\n\tt: \"ref\";\n\tkey: string;\n}\n\nexport interface IdentifierExpr {\n\tt: \"id\";\n\tname: string;\n}\n\nexport interface LiteralExpr {\n\tt: \"lit\";\n\tvalue: JsonPrimitive;\n}\n\nexport interface UndefinedExpr {\n\tt: \"undef\";\n}\n\nexport interface ArrayExpr {\n\tt: \"array\";\n\titems: VDOMNode[];\n}\n\nexport interface ObjectExpr {\n\tt: \"object\";\n\tprops: Record<string, VDOMNode>;\n}\n\nexport interface MemberExpr {\n\tt: \"member\";\n\tobj: VDOMNode;\n\tprop: string;\n}\n\nexport interface SubscriptExpr {\n\tt: \"sub\";\n\tobj: VDOMNode;\n\tkey: VDOMNode;\n}\n\nexport interface CallExpr {\n\tt: \"call\";\n\tcallee: VDOMNode;\n\targs: VDOMNode[];\n}\n\nexport interface UnaryExpr {\n\tt: \"unary\";\n\top: string;\n\targ: VDOMNode;\n}\n\nexport interface BinaryExpr {\n\tt: \"binary\";\n\top: string;\n\tleft: VDOMNode;\n\tright: VDOMNode;\n}\n\nexport interface TernaryExpr {\n\tt: \"ternary\";\n\tcond: VDOMNode;\n\tthen: VDOMNode;\n\telse_: VDOMNode;\n}\n\nexport interface TemplateExpr {\n\tt: \"template\";\n\tparts: Array<string | VDOMNode>;\n}\n\nexport interface ArrowExpr {\n\tt: \"arrow\";\n\tparams: string[];\n\tbody: VDOMNode;\n}\n\nexport interface NewExpr {\n\tt: \"new\";\n\tctor: VDOMNode;\n\targs: VDOMNode[];\n}\n\n// -----------------------------------------------------------------------------\n// VDOM tree\n// -----------------------------------------------------------------------------\n\nexport type CallbackPlaceholder = \"$cb\" | `$cb:${number}`;\n\nexport interface PulseRefPayload {\n\tchannelId: string;\n\trefId: string;\n}\n\nexport interface PulseRefSpec {\n\t__pulse_ref__: PulseRefPayload;\n}\n\nexport type VDOMPropValue =\n\t| JsonValue\n\t| VDOMExpr\n\t| VDOMElement\n\t| CallbackPlaceholder\n\t| PulseRefSpec;\n\nexport interface VDOMElement {\n\ttag: string | VDOMExpr;\n\tkey?: string;\n\tprops?: Record<string, VDOMPropValue>;\n\tchildren?: VDOMNode[];\n\t// Prop keys that should be interpreted (expr / render-prop subtree / callback binding).\n\t// When absent, props are treated as plain JSON.\n\teval?: string[];\n}\n\nexport type VDOMNode = JsonPrimitive | VDOMElement | VDOMExpr;\nexport type VDOM = VDOMNode;\n\nexport function isElementNode(node: VDOMNode): node is VDOMElement {\n\treturn typeof node === \"object\" && node !== null && \"tag\" in node;\n}\n\nexport function isExprNode(node: unknown): node is VDOMExpr {\n\treturn typeof node === \"object\" && node !== null && \"t\" in (node as any);\n}\n\nexport function isMountPointNode(node: VDOMNode): node is VDOMElement {\n\treturn (\n\t\tisElementNode(node) &&\n\t\ttypeof node.tag === \"string\" &&\n\t\tnode.tag.startsWith(MOUNT_POINT_PREFIX) &&\n\t\tnode.tag !== FRAGMENT_TAG\n\t);\n}\n\n// -----------------------------------------------------------------------------\n// Updates\n// -----------------------------------------------------------------------------\n\nexport interface VDOMUpdateBase {\n\ttype: string;\n\tpath: string;\n}\n\nexport interface ReplaceUpdate extends VDOMUpdateBase {\n\ttype: \"replace\";\n\tdata: VDOM;\n}\n\nexport interface UpdatePropsUpdate extends VDOMUpdateBase {\n\ttype: \"update_props\";\n\tdata: {\n\t\tset?: Record<string, VDOMPropValue>;\n\t\tremove?: string[];\n\t\t// Replace the eval list for this element.\n\t\t// - absent/undefined: keep previous\n\t\t// - []: clear\n\t\teval?: string[];\n\t};\n}\n\nexport interface ReconciliationUpdate {\n\ttype: \"reconciliation\";\n\tpath: string;\n\tN: number;\n\tnew: [number[], VDOM[]];\n\treuse: [number[], number[]];\n}\n\nexport type VDOMUpdate = ReplaceUpdate | UpdatePropsUpdate | ReconciliationUpdate;\n","import {\n\ttype ComponentType,\n\tcloneElement,\n\tcreateElement,\n\tFragment,\n\tisValidElement,\n\ttype ReactElement,\n\ttype ReactNode,\n} from \"react\";\nimport type { PulseSocketIOClient } from \"./client\";\nimport type { PulsePrerenderView } from \"./pulse\";\nimport { isPulseRefSpec, RefRegistry } from \"./ref\";\nimport { extractEvent } from \"./serialize/events\";\nimport type {\n\tComponentRegistry,\n\tJsonValue,\n\tVDOM,\n\tVDOMNode,\n\tVDOMPropValue,\n\tVDOMUpdate,\n} from \"./vdom\";\nimport { isElementNode, isExprNode, MOUNT_POINT_PREFIX as REF_PREFIX } from \"./vdom\";\n\ntype Env = Record<string, unknown>;\n\ntype CallbackDelay = number | null;\n\ntype CallbackEntry = {\n\tfn: (...args: any[]) => void;\n\tdelayMs: CallbackDelay;\n\ttimer: ReturnType<typeof setTimeout> | null;\n\tlastArgs: any[] | null;\n\tdueAt: number | null;\n};\n\nfunction parseCallbackPlaceholder(value: unknown): CallbackDelay | undefined {\n\tif (value === \"$cb\") return null;\n\tif (typeof value !== \"string\" || !value.startsWith(\"$cb:\")) return undefined;\n\tconst raw = value.slice(4);\n\tif (raw.length === 0) {\n\t\tthrow new Error(\"[Pulse] Invalid callback placeholder: '$cb:'\");\n\t}\n\tconst delay = Number(raw);\n\tif (!Number.isFinite(delay) || delay < 0) {\n\t\tthrow new Error(`[Pulse] Invalid callback debounce delay: ${value}`);\n\t}\n\treturn delay;\n}\n\ntype ElementMeta = {\n\teval?: Set<string>;\n\tpath?: string;\n\tcallbacks?: Map<string, CallbackEntry>;\n};\n\nexport class VDOMRenderer {\n\t#client: PulseSocketIOClient;\n\t#path: string;\n\t#registry: ComponentRegistry;\n\t#refRegistry: RefRegistry;\n\n\t// Track callback entries for teardown.\n\t#callbackEntries: Set<CallbackEntry>;\n\n\t// Track eval keys + callback entries per ReactElement (not real props).\n\t#metaMap: WeakMap<ReactElement, ElementMeta>;\n\n\tconstructor(client: PulseSocketIOClient, path: string, registry: ComponentRegistry = {}) {\n\t\tthis.#client = client;\n\t\tthis.#path = path;\n\t\tthis.#registry = registry;\n\t\tthis.#callbackEntries = new Set();\n\t\tthis.#metaMap = new WeakMap();\n\t\tthis.#refRegistry = new RefRegistry((channelId) => {\n\t\t\treturn this.#client._ensureChannelEntry(channelId).bridge;\n\t\t});\n\t}\n\n\tgetObject(key: string): unknown {\n\t\tconst obj = (this.#registry as any)[key];\n\t\tif (obj === undefined) {\n\t\t\tthrow new Error(`[Pulse] Unknown registry key: ${key}`);\n\t\t}\n\t\treturn obj;\n\t}\n\n\t#resolveIdentifier(name: string): unknown {\n\t\tconst v = (globalThis as any)[name];\n\t\tif (v === undefined) {\n\t\t\tthrow new Error(`[Pulse] Unknown identifier in expr: ${name}`);\n\t\t}\n\t\treturn v;\n\t}\n\n\t#evalExpr(expr: VDOMNode, env: Env): unknown {\n\t\t// Handle primitives directly (wire format optimization)\n\t\tif (expr === null || typeof expr !== \"object\") {\n\t\t\treturn expr;\n\t\t}\n\t\t// Handle VDOMElement (has \"tag\" instead of \"t\")\n\t\tif (\"tag\" in expr) {\n\t\t\treturn this.renderNode(expr, \"\");\n\t\t}\n\t\tswitch (expr.t) {\n\t\t\tcase \"ref\":\n\t\t\t\treturn this.getObject(expr.key);\n\t\t\tcase \"id\":\n\t\t\t\tif (Object.hasOwn(env, expr.name)) return env[expr.name];\n\t\t\t\treturn this.#resolveIdentifier(expr.name);\n\t\t\tcase \"lit\":\n\t\t\t\treturn expr.value;\n\t\t\tcase \"undef\":\n\t\t\t\treturn undefined;\n\t\t\tcase \"array\": {\n\t\t\t\tconst out: unknown[] = [];\n\t\t\t\tfor (const it of expr.items) {\n\t\t\t\t\tout.push(this.#evalExpr(it, env));\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t}\n\t\t\tcase \"object\": {\n\t\t\t\tconst out: Record<string, unknown> = {};\n\t\t\t\tfor (const [k, vexpr] of Object.entries(expr.props)) {\n\t\t\t\t\tout[k] = this.#evalExpr(vexpr, env);\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t}\n\t\t\tcase \"member\": {\n\t\t\t\tconst obj = this.#evalExpr(expr.obj, env) as any;\n\t\t\t\treturn obj?.[expr.prop];\n\t\t\t}\n\t\t\tcase \"sub\": {\n\t\t\t\tconst obj = this.#evalExpr(expr.obj, env) as any;\n\t\t\t\tconst key = this.#evalExpr(expr.key, env) as any;\n\t\t\t\treturn obj?.[key];\n\t\t\t}\n\t\t\tcase \"call\": {\n\t\t\t\tconst fn = this.#evalExpr(expr.callee, env) as any;\n\t\t\t\tconst args = expr.args.map((a) => this.#evalExpr(a, env));\n\t\t\t\tif (typeof fn !== \"function\") throw new Error(\"[Pulse] call callee is not a function\");\n\t\t\t\treturn fn(...args);\n\t\t\t}\n\t\t\tcase \"unary\": {\n\t\t\t\tconst v = this.#evalExpr(expr.arg, env) as any;\n\t\t\t\tswitch (expr.op) {\n\t\t\t\t\tcase \"!\":\n\t\t\t\t\t\treturn !v;\n\t\t\t\t\tcase \"+\":\n\t\t\t\t\t\treturn +v;\n\t\t\t\t\tcase \"-\":\n\t\t\t\t\t\treturn -v;\n\t\t\t\t\tcase \"typeof\":\n\t\t\t\t\t\treturn typeof v;\n\t\t\t\t\tcase \"void\":\n\t\t\t\t\t\treturn void v;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`[Pulse] Unsupported unary op: ${expr.op}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase \"binary\": {\n\t\t\t\tconst l = this.#evalExpr(expr.left, env) as any;\n\t\t\t\tconst r = this.#evalExpr(expr.right, env) as any;\n\t\t\t\tswitch (expr.op) {\n\t\t\t\t\tcase \"+\":\n\t\t\t\t\t\treturn l + r;\n\t\t\t\t\tcase \"-\":\n\t\t\t\t\t\treturn l - r;\n\t\t\t\t\tcase \"*\":\n\t\t\t\t\t\treturn l * r;\n\t\t\t\t\tcase \"/\":\n\t\t\t\t\t\treturn l / r;\n\t\t\t\t\tcase \"%\":\n\t\t\t\t\t\treturn l % r;\n\t\t\t\t\tcase \"&&\":\n\t\t\t\t\t\treturn l && r;\n\t\t\t\t\tcase \"||\":\n\t\t\t\t\t\treturn l || r;\n\t\t\t\t\tcase \"??\":\n\t\t\t\t\t\treturn l ?? r;\n\t\t\t\t\tcase \"**\":\n\t\t\t\t\t\treturn l ** r;\n\t\t\t\t\tcase \"in\":\n\t\t\t\t\t\treturn l in r;\n\t\t\t\t\tcase \"instanceof\":\n\t\t\t\t\t\treturn l instanceof r;\n\t\t\t\t\tcase \"===\":\n\t\t\t\t\t\treturn l === r;\n\t\t\t\t\tcase \"!==\":\n\t\t\t\t\t\treturn l !== r;\n\t\t\t\t\tcase \"<\":\n\t\t\t\t\t\treturn l < r;\n\t\t\t\t\tcase \"<=\":\n\t\t\t\t\t\treturn l <= r;\n\t\t\t\t\tcase \">\":\n\t\t\t\t\t\treturn l > r;\n\t\t\t\t\tcase \">=\":\n\t\t\t\t\t\treturn l >= r;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`[Pulse] Unsupported binary op: ${expr.op}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase \"ternary\":\n\t\t\t\treturn this.#evalExpr(expr.cond, env)\n\t\t\t\t\t? this.#evalExpr(expr.then, env)\n\t\t\t\t\t: this.#evalExpr(expr.else_, env);\n\t\t\tcase \"template\": {\n\t\t\t\tlet s = \"\";\n\t\t\t\tfor (const part of expr.parts) {\n\t\t\t\t\tif (typeof part === \"string\") s += part;\n\t\t\t\t\telse s += String(this.#evalExpr(part, env));\n\t\t\t\t}\n\t\t\t\treturn s;\n\t\t\t}\n\t\t\tcase \"arrow\": {\n\t\t\t\tconst params = expr.params;\n\t\t\t\treturn (...args: unknown[]) => {\n\t\t\t\t\tconst nextEnv: Env = { ...env };\n\t\t\t\t\tfor (let i = 0; i < params.length; i += 1) nextEnv[params[i]!] = args[i];\n\t\t\t\t\treturn this.#evalExpr(expr.body, nextEnv);\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"new\": {\n\t\t\t\tconst Ctor = this.#evalExpr(expr.ctor, env) as any;\n\t\t\t\tconst args = expr.args.map((a) => this.#evalExpr(a, env));\n\t\t\t\treturn new Ctor(...args);\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`[Pulse] Unknown expr node: ${(expr as any).t}`);\n\t\t}\n\t}\n\n\t#propPath(path: string, prop: string) {\n\t\treturn path ? `${path}.${prop}` : prop;\n\t}\n\n\t#clearPending(entry: CallbackEntry) {\n\t\tif (entry.timer) {\n\t\t\tclearTimeout(entry.timer);\n\t\t}\n\t\tentry.timer = null;\n\t\tentry.lastArgs = null;\n\t\tentry.dueAt = null;\n\t}\n\n\t#firePending(entry: CallbackEntry, fire: (args: any[]) => void) {\n\t\tconst args = entry.lastArgs;\n\t\tthis.#clearPending(entry);\n\t\tif (!args) return;\n\t\tfire(args);\n\t}\n\n\t#scheduleDebounced(\n\t\tentry: CallbackEntry,\n\t\tdelayMs: number,\n\t\targs: any[],\n\t\tfire: (args: any[]) => void,\n\t) {\n\t\tif (entry.timer) clearTimeout(entry.timer);\n\t\tentry.lastArgs = args;\n\t\tentry.dueAt = Date.now() + delayMs;\n\t\tentry.timer = setTimeout(() => {\n\t\t\tthis.#firePending(entry, fire);\n\t\t}, delayMs);\n\t}\n\n\t#dropCallback(meta: ElementMeta, prop: string) {\n\t\tconst callbacks = meta.callbacks;\n\t\tif (!callbacks) return;\n\t\tconst entry = callbacks.get(prop);\n\t\tif (!entry) return;\n\t\tthis.#clearPending(entry);\n\t\tthis.#callbackEntries.delete(entry);\n\t\tcallbacks.delete(prop);\n\t\tif (callbacks.size === 0) {\n\t\t\tmeta.callbacks = undefined;\n\t\t}\n\t}\n\n\t#ensureCallbackEntry(meta: ElementMeta, prop: string): CallbackEntry {\n\t\tif (!meta.callbacks) {\n\t\t\tmeta.callbacks = new Map();\n\t\t}\n\t\tconst callbacks = meta.callbacks;\n\t\tlet entry = callbacks.get(prop);\n\t\tif (!entry) {\n\t\t\tconst fire = (args: any[]) => {\n\t\t\t\tconst key = this.#propPath(meta.path ?? \"\", prop);\n\t\t\t\tthis.#client.invokeCallback(this.#path, key, args);\n\t\t\t};\n\t\t\tentry = {\n\t\t\t\tfn: (...args: any[]) => {\n\t\t\t\t\tif (entry!.delayMs == null) {\n\t\t\t\t\t\tfire(args);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst callArgs = args.map(extractEvent);\n\t\t\t\t\tthis.#scheduleDebounced(entry!, entry!.delayMs, callArgs, fire);\n\t\t\t\t},\n\t\t\t\tdelayMs: null,\n\t\t\t\ttimer: null,\n\t\t\t\tlastArgs: null,\n\t\t\t\tdueAt: null,\n\t\t\t};\n\t\t\tcallbacks.set(prop, entry);\n\t\t\tthis.#callbackEntries.add(entry);\n\t\t}\n\t\treturn entry;\n\t}\n\n\t#dropCallbacksInSubtree(node: ReactNode, path: string) {\n\t\tif (node == null || typeof node === \"boolean\" || typeof node === \"number\" || typeof node === \"string\") {\n\t\t\treturn;\n\t\t}\n\t\tif (Array.isArray(node)) {\n\t\t\tfor (let i = 0; i < node.length; i += 1) {\n\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\tthis.#dropCallbacksInSubtree(node[i], childPath);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (!isValidElement(node)) return;\n\t\tconst element = node as ReactElement<Record<string, any> | null>;\n\t\tconst meta = this.#metaMap.get(element);\n\t\tconst basePath = meta?.path ?? path;\n\t\tconst callbacks = meta?.callbacks;\n\t\tif (callbacks && callbacks.size > 0) {\n\t\t\tfor (const entry of callbacks.values()) {\n\t\t\t\tthis.#clearPending(entry);\n\t\t\t\tthis.#callbackEntries.delete(entry);\n\t\t\t}\n\t\t\tcallbacks.clear();\n\t\t\tmeta!.callbacks = undefined;\n\t\t}\n\t\tconst baseProps = (element.props ?? {}) as Record<string, any>;\n\t\tfor (const key of Object.keys(baseProps)) {\n\t\t\tif (key === \"children\") continue;\n\t\t\tconst v = baseProps[key];\n\t\t\tthis.#dropCallbacksInSubtree(v, this.#propPath(basePath, key));\n\t\t}\n\t\tconst children = this.#ensureChildrenArray(element);\n\t\tfor (let i = 0; i < children.length; i += 1) {\n\t\t\tconst childPath = basePath ? `${basePath}.${i}` : String(i);\n\t\t\tthis.#dropCallbacksInSubtree(children[i], childPath);\n\t\t}\n\t}\n\n\t#getCallback(meta: ElementMeta, prop: string, delayMs: CallbackDelay) {\n\t\tconst entry = this.#ensureCallbackEntry(meta, prop);\n\t\tif (entry.delayMs !== delayMs) {\n\t\t\tentry.delayMs = delayMs;\n\t\t}\n\t\treturn entry.fn;\n\t}\n\n\t#transformEvalProp(path: string, meta: ElementMeta, prop: string, value: VDOMPropValue) {\n\t\tconst cbDelay = parseCallbackPlaceholder(value);\n\t\tif (cbDelay !== undefined) return this.#getCallback(meta, prop, cbDelay);\n\t\tif (isPulseRefSpec(value)) {\n\t\t\tconst payload = value.__pulse_ref__;\n\t\t\treturn this.#refRegistry.getCallback(payload.channelId, payload.refId);\n\t\t}\n\t\tif (isExprNode(value)) return this.#evalExpr(value, {});\n\t\tif (typeof value === \"object\" && value !== null && \"tag\" in value) {\n\t\t\t// Render-prop subtree; traverse as a prop path segment (non-numeric).\n\t\t\treturn this.renderNode(value as VDOMNode, this.#propPath(path, prop));\n\t\t}\n\t\t// Eval-marked but still JSON => pass through.\n\t\treturn value as JsonValue;\n\t}\n\n\t#rememberMeta(el: ReactElement, meta: ElementMeta) {\n\t\tthis.#metaMap.set(el, meta);\n\t\treturn el;\n\t}\n\n\tclearPendingCallbacks() {\n\t\tfor (const entry of Array.from(this.#callbackEntries)) {\n\t\t\tthis.#clearPending(entry);\n\t\t}\n\t\t// Keep entries so StrictMode cleanup (no real unmount) can still cancel\n\t\t// future debounced calls on the reused renderer instance.\n\t}\n\n\trenderNode(node: VDOMNode, currentPath = \"\"): ReactNode {\n\t\t// primitives\n\t\tif (node == null || typeof node === \"boolean\" || typeof node === \"number\") return node;\n\t\tif (typeof node === \"string\") return node;\n\n\t\t// expr\n\t\tif (isExprNode(node)) return this.#evalExpr(node, {}) as ReactNode;\n\n\t\t// element\n\t\tif (isElementNode(node)) {\n\t\t\tconst { tag, props = {}, children = [], eval: evalKeys } = node;\n\t\t\t// 1. Resolve component\n\t\t\tlet component: React.ComponentType<any> | string;\n\t\t\tif (typeof tag === \"string\") {\n\t\t\t\tif (tag.startsWith(REF_PREFIX)) {\n\t\t\t\t\tconst key = tag.slice(REF_PREFIX.length);\n\t\t\t\t\tcomponent = this.#registry[key] as React.ComponentType<any>;\n\n\t\t\t\t\tif (!component) {\n\t\t\t\t\t\tthrow new Error(`[Pulse] Missing component '${key}'`);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcomponent = tag.length > 0 ? tag : Fragment;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcomponent = this.#evalExpr(tag, {}) as any;\n\t\t\t}\n\t\t\t// 2. Build props\n\t\t\tconst newProps: Record<string, any> = {};\n\t\t\tlet evalSet: Set<string> | undefined;\n\t\t\tconst meta: ElementMeta = { path: currentPath };\n\t\t\tif (!evalKeys) {\n\t\t\t\t// Hot path: no eval -> props are plain JSON; copy as-is.\n\t\t\t\tfor (const [propName, propValue] of Object.entries(props)) {\n\t\t\t\t\tnewProps[propName] = propValue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tevalSet = new Set(evalKeys);\n\t\t\t\tmeta.eval = evalSet;\n\t\t\t\tfor (const [propName, propValue] of Object.entries(props)) {\n\t\t\t\t\tif (!evalSet.has(propName)) {\n\t\t\t\t\t\tnewProps[propName] = propValue;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tnewProps[propName] = this.#transformEvalProp(\n\t\t\t\t\t\tcurrentPath,\n\t\t\t\t\t\tmeta,\n\t\t\t\t\t\tpropName,\n\t\t\t\t\t\tpropValue,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (node.key) newProps.key = node.key;\n\n\t\t\t// 3. Render children\n\t\t\tconst renderedChildren: ReactNode[] = [];\n\t\t\tfor (let i = 0; i < children.length; i += 1) {\n\t\t\t\tconst child = children[i]!;\n\t\t\t\tconst childPath = currentPath ? `${currentPath}.${i}` : String(i);\n\t\t\t\trenderedChildren.push(this.renderNode(child, childPath));\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\treturn this.#rememberMeta(\n\t\t\t\t\tcreateElement(component, newProps, ...renderedChildren),\n\t\t\t\t\tmeta,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"[Pulse] Failed to create element:\", node)\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\tif (process.env.NODE_ENV !== \"production\") {\n\t\t\tconsole.error(\"Unknown VDOM node:\", node);\n\t\t}\n\t\treturn null;\n\t}\n\n\tinit(view: PulsePrerenderView & { vdom: VDOM }): ReactNode {\n\t\treturn this.renderNode(view.vdom);\n\t}\n\n\tdispose(): void {\n\t\tthis.#refRegistry.dispose();\n\t}\n\n\t/**\n\t * Evaluate a VDOMNode expression (for run_js support).\n\t */\n\tevaluateExpr(expr: VDOMNode): unknown {\n\t\treturn this.#evalExpr(expr, {});\n\t}\n\n\t#ensureChildrenArray(el: ReactElement): ReactNode[] {\n\t\tconst children = (el.props as any)?.children as ReactNode | undefined;\n\t\tif (children == null) return [];\n\t\treturn Array.isArray(children) ? children.slice() : [children];\n\t}\n\n\t#cloneWithMeta(prev: ReactElement, next: ReactElement) {\n\t\tconst meta = this.#metaMap.get(prev);\n\t\tif (meta) this.#metaMap.set(next, meta);\n\t\treturn next;\n\t}\n\n\t// Update paths within a subtree after a move so callbacks resolve correctly.\n\t#rebindCallbacksInSubtree(node: ReactNode, path: string): ReactNode {\n\t\tif (node == null || typeof node === \"boolean\" || typeof node === \"number\" || typeof node === \"string\") {\n\t\t\treturn node;\n\t\t}\n\t\tif (Array.isArray(node)) {\n\t\t\tfor (let i = 0; i < node.length; i += 1) {\n\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\tthis.#rebindCallbacksInSubtree(node[i], childPath);\n\t\t\t}\n\t\t\treturn node;\n\t\t}\n\t\tif (!isValidElement(node)) return node;\n\t\tconst element = node as ReactElement<Record<string, any> | null>;\n\t\tconst meta = this.#metaMap.get(element);\n\t\tif (meta) {\n\t\t\tmeta.path = path;\n\t\t} else {\n\t\t\tthis.#metaMap.set(element, { path });\n\t\t}\n\n\t\tconst baseProps = (element.props ?? {}) as Record<string, any>;\n\t\tfor (const key of Object.keys(baseProps)) {\n\t\t\tif (key === \"children\") continue;\n\t\t\tconst v = baseProps[key];\n\t\t\tthis.#rebindCallbacksInSubtree(v, this.#propPath(path, key));\n\t\t}\n\n\t\tconst children = this.#ensureChildrenArray(element);\n\t\tfor (let i = 0; i < children.length; i += 1) {\n\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\tthis.#rebindCallbacksInSubtree(children[i], childPath);\n\t\t}\n\n\t\treturn node;\n\t}\n\n\tapplyUpdates(initialTree: ReactNode, updates: VDOMUpdate[]): ReactNode {\n\t\tlet newTree: ReactNode = initialTree;\n\t\tfor (const update of updates) {\n\t\t\tconst parts = update.path.split(\".\").filter((s) => s.length > 0);\n\n\t\t\tconst descend = (node: ReactNode, depth: number, path: string): ReactNode => {\n\t\t\t\tif (depth < parts.length) {\n\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\tconst element = node as ReactElement<Record<string, any> | null>;\n\t\t\t\t\tconst childKey = parts[depth]!;\n\t\t\t\t\tconst childIdx = +childKey;\n\t\t\t\t\tconst childPath = path ? `${path}.${childKey}` : childKey;\n\t\t\t\t\tif (!Number.isNaN(childIdx)) {\n\t\t\t\t\t\tconst childrenArr = this.#ensureChildrenArray(element);\n\t\t\t\t\t\tconst child = childrenArr[childIdx];\n\t\t\t\t\t\tchildrenArr[childIdx] = descend(child, depth + 1, childPath) as any;\n\t\t\t\t\t\treturn this.#cloneWithMeta(element, cloneElement(element, undefined, ...childrenArr));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst baseProps = (element.props ?? {}) as Record<string, any>;\n\t\t\t\t\t\tconst child = baseProps[childKey];\n\t\t\t\t\t\tconst props = { ...baseProps, [childKey]: descend(child, depth + 1, childPath) };\n\t\t\t\t\t\treturn this.#cloneWithMeta(element, cloneElement(element, props));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tswitch (update.type) {\n\t\t\t\t\tcase \"replace\":\n\t\t\t\t\t\tthis.#dropCallbacksInSubtree(node, path);\n\t\t\t\t\t\treturn this.renderNode(update.data, update.path);\n\n\t\t\t\t\tcase \"update_props\": {\n\t\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\t\tconst element = node as ReactElement;\n\t\t\t\t\t\tconst currentProps = (element.props ?? {}) as Record<string, any>;\n\t\t\t\t\t\tconst nextProps: Record<string, any> = { ...currentProps };\n\n\t\t\t\t\t\tconst prevMeta = this.#metaMap.get(element);\n\t\t\t\t\t\tconst meta: ElementMeta = prevMeta ?? {};\n\t\t\t\t\t\tconst prevEval = meta.eval;\n\t\t\t\t\t\tconst prevPath = prevMeta?.path ?? path;\n\t\t\t\t\t\tconst evalPatch = update.data.eval;\n\t\t\t\t\t\tconst nextEval: Set<string> | undefined =\n\t\t\t\t\t\t\tevalPatch === undefined\n\t\t\t\t\t\t\t\t? prevEval\n\t\t\t\t\t\t\t\t: evalPatch.length === 0\n\t\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t\t: new Set(evalPatch);\n\t\t\t\t\t\tconst evalCleared = evalPatch !== undefined && evalPatch.length === 0;\n\n\t\t\t\t\t\t// Drop callbacks that are no longer eval-bound.\n\t\t\t\t\t\tif (nextEval && meta.callbacks) {\n\t\t\t\t\t\t\tfor (const k of Array.from(meta.callbacks.keys())) {\n\t\t\t\t\t\t\t\tif (!nextEval.has(k)) {\n\t\t\t\t\t\t\t\t\tthis.#dropCallback(meta, k);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (evalCleared && meta.callbacks) {\n\t\t\t\t\t\t\tfor (const k of Array.from(meta.callbacks.keys())) {\n\t\t\t\t\t\t\t\tdelete nextProps[k];\n\t\t\t\t\t\t\t\tthis.#dropCallback(meta, k);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst removedKeys = update.data.remove ?? [];\n\t\t\t\t\t\tif (removedKeys.length > 0) {\n\t\t\t\t\t\t\tfor (const key of removedKeys) {\n\t\t\t\t\t\t\t\tconst removedValue = currentProps[key];\n\t\t\t\t\t\t\t\tif (removedValue !== undefined) {\n\t\t\t\t\t\t\t\t\tthis.#dropCallbacksInSubtree(removedValue, this.#propPath(prevPath, key));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tdelete nextProps[key];\n\t\t\t\t\t\t\t\tif (meta.callbacks?.has(key)) {\n\t\t\t\t\t\t\t\t\tthis.#dropCallback(meta, key);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (update.data.set) {\n\t\t\t\t\t\t\tfor (const [k, v] of Object.entries(update.data.set)) {\n\t\t\t\t\t\t\t\tconst prevValue = currentProps[k];\n\t\t\t\t\t\t\t\tif (prevValue !== undefined) {\n\t\t\t\t\t\t\t\t\tthis.#dropCallbacksInSubtree(prevValue, this.#propPath(prevPath, k));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Only interpret eval-marked keys; otherwise treat as JSON.\n\t\t\t\t\t\t\t\tconst isEval = nextEval?.has(k) === true;\n\t\t\t\t\t\t\t\tconst cbDelay = isEval ? parseCallbackPlaceholder(v) : undefined;\n\t\t\t\t\t\t\t\tnextProps[k] = isEval\n\t\t\t\t\t\t\t\t\t? this.#transformEvalProp(path, meta, k, v as any)\n\t\t\t\t\t\t\t\t\t: (v as any);\n\t\t\t\t\t\t\t\tif (cbDelay === undefined && meta.callbacks?.has(k)) {\n\t\t\t\t\t\t\t\t\tthis.#dropCallback(meta, k);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmeta.eval = nextEval;\n\t\t\t\t\t\tmeta.path = path;\n\n\t\t\t\t\t\tconst removedSomething = removedKeys.length > 0;\n\t\t\t\t\t\tconst refRemoved = removedKeys.includes(\"ref\");\n\t\t\t\t\t\tconst hasNextRef = Object.prototype.hasOwnProperty.call(nextProps, \"ref\");\n\t\t\t\t\t\tconst propsHasRef = Object.prototype.hasOwnProperty.call(currentProps, \"ref\");\n\t\t\t\t\t\tconst propsRef = propsHasRef ? currentProps.ref : undefined;\n\t\t\t\t\t\tconst existingRef = (element as any).ref ?? propsRef;\n\t\t\t\t\t\tconst nextRef = hasNextRef ? nextProps.ref : refRemoved ? undefined : existingRef;\n\t\t\t\t\t\tif (removedSomething) {\n\t\t\t\t\t\t\tnextProps.key = (element as any).key;\n\t\t\t\t\t\t\tif (!refRemoved && !hasNextRef && nextRef !== undefined) {\n\t\t\t\t\t\t\t\tnextProps.ref = nextRef;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn this.#rememberMeta(\n\t\t\t\t\t\t\t\tcreateElement(element.type, nextProps, ...this.#ensureChildrenArray(element)),\n\t\t\t\t\t\t\t\tmeta,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn this.#rememberMeta(cloneElement(element, nextProps), meta);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcase \"reconciliation\": {\n\t\t\t\t\t\tthis.#assertIsElement(node, parts, depth);\n\t\t\t\t\t\tconst element = node as ReactElement;\n\t\t\t\t\t\tconst prevChildren = this.#ensureChildrenArray(element);\n\t\t\t\t\t\tconst nextChildren: ReactNode[] = [];\n\n\t\t\t\t\t\tconst [newIndices, newContents] = update.new;\n\t\t\t\t\t\tconst [reuseIndices, reuseSources] = update.reuse;\n\t\t\t\t\t\tconst newIndexSet = new Set(newIndices);\n\t\t\t\t\t\tconst reuseIndexSet = new Set(reuseIndices);\n\t\t\t\t\t\tconst reuseSourceSet = new Set(reuseSources);\n\t\t\t\t\t\tfor (let i = 0; i < prevChildren.length; i += 1) {\n\t\t\t\t\t\t\tconst reused =\n\t\t\t\t\t\t\t\treuseSourceSet.has(i) ||\n\t\t\t\t\t\t\t\t(i < update.N && !newIndexSet.has(i) && !reuseIndexSet.has(i));\n\t\t\t\t\t\t\tif (!reused) {\n\t\t\t\t\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\t\t\t\t\tthis.#dropCallbacksInSubtree(prevChildren[i], childPath);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet nextNew = -1,\n\t\t\t\t\t\t\tnextReuse = -1,\n\t\t\t\t\t\t\tnewIdx = -1,\n\t\t\t\t\t\t\treuseIdx = -1;\n\t\t\t\t\t\tif (newIndices.length > 0) {\n\t\t\t\t\t\t\tnextNew = newIndices[0]!;\n\t\t\t\t\t\t\tnewIdx = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (reuseIndices.length > 0) {\n\t\t\t\t\t\t\tnextReuse = reuseIndices[0]!;\n\t\t\t\t\t\t\treuseIdx = 0;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (let i = 0; i < update.N; i += 1) {\n\t\t\t\t\t\t\tif (i === nextNew) {\n\t\t\t\t\t\t\t\tconst contents = newContents[newIdx]!;\n\t\t\t\t\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\t\t\t\t\tnextChildren.push(this.renderNode(contents, childPath));\n\t\t\t\t\t\t\t\tnextNew = newIdx < newIndices.length - 1 ? newIndices[++newIdx]! : -1;\n\t\t\t\t\t\t\t} else if (i === nextReuse) {\n\t\t\t\t\t\t\t\tconst srcIdx = reuseSources[reuseIdx]!;\n\t\t\t\t\t\t\t\tlet src = prevChildren[srcIdx];\n\t\t\t\t\t\t\t\tconst childPath = path ? `${path}.${i}` : String(i);\n\t\t\t\t\t\t\t\t// If the node moved, callbacks inside need new paths.\n\t\t\t\t\t\t\t\tsrc = this.#rebindCallbacksInSubtree(src, childPath);\n\t\t\t\t\t\t\t\tnextChildren.push(src);\n\t\t\t\t\t\t\t\tnextReuse = reuseIdx < reuseIndices.length - 1 ? reuseIndices[++reuseIdx]! : -1;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tnextChildren.push(prevChildren[i]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (nextChildren.length === 0) {\n\t\t\t\t\t\t\tnextChildren.push(null);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn this.#cloneWithMeta(\n\t\t\t\t\t\t\telement,\n\t\t\t\t\t\t\tcloneElement(element, null!, ...nextChildren),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`[Pulse renderer] Unknown update type: ${(update as any)?.type}`);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tnewTree = descend(newTree, 0, \"\");\n\t\t}\n\t\treturn newTree;\n\t}\n\n\t#assertIsElement(node: ReactNode, parts: string[], depth: number): node is ReactElement {\n\t\tif (process.env.NODE_ENV !== \"production\" && !isValidElement(node)) {\n\t\t\tconsole.error(\"Invalid node:\", node);\n\t\t\tthrow new Error(`Invalid node at path ${parts.slice(0, depth).join(\".\")}`);\n\t\t}\n\t\treturn true;\n\t}\n}\n","import {\n\tcreateContext,\n\ttype ReactNode,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { useLocation, useNavigate, useParams } from \"react-router\";\nimport { type ConnectionStatus, type Directives, PulseSocketIOClient } from \"./client\";\nimport type { RouteInfo } from \"./helpers\";\nimport type { ServerError } from \"./messages\";\nimport { VDOMRenderer } from \"./renderer\";\nimport type { VDOM } from \"./vdom\";\n\n// =================================================================\n// Types\n// =================================================================\n\nexport interface ConnectionStatusConfig {\n\tinitialConnectingDelay: number;\n\tinitialErrorDelay: number;\n\treconnectErrorDelay: number;\n}\n\nexport interface PulseConfig {\n\tserverAddress: string;\n\tconnectionStatus: ConnectionStatusConfig;\n\tapiPrefix: string;\n}\n\nexport type PulsePrerenderView = {\n\tvdom: VDOM;\n};\n\nexport type PulsePrerender = {\n\tviews: Record<string, PulsePrerenderView>;\n\tdirectives: Directives;\n};\n// =================================================================\n// Context and Hooks\n// =================================================================\n\n// Context for the client, provided by PulseProvider\nconst PulseClientContext = createContext<PulseSocketIOClient | null>(null);\nconst PulsePrerenderContext = createContext<PulsePrerender | null>(null);\n\nexport const usePulseClient = () => {\n\tconst client = useContext(PulseClientContext);\n\tif (!client) {\n\t\tthrow new Error(\"usePulseClient must be used within a PulseProvider\");\n\t}\n\treturn client;\n};\n\nexport const usePulsePrerender = (path: string) => {\n\tconst ctx = useContext(PulsePrerenderContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"usePulsePrerender must be used within a PulseProvider\");\n\t}\n\tconst view = ctx.views[path];\n\tif (!view) {\n\t\tthrow new Error(`No prerender found for '${path}'`);\n\t}\n\treturn view;\n};\n\n// =================================================================\n// Provider\n// =================================================================\n\nexport interface PulseProviderProps {\n\tchildren: ReactNode;\n\tconfig: PulseConfig;\n\tprerender: PulsePrerender;\n}\n\nconst inBrowser = typeof window !== \"undefined\";\n\nexport function PulseProvider({ children, config, prerender }: PulseProviderProps) {\n\tconst [status, setStatus] = useState<ConnectionStatus>(\"ok\");\n\tconst rrNavigate = useNavigate();\n\tconst { directives } = prerender;\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: another useEffect syncs the directives without recreating the client\n\tconst client = useMemo(() => {\n\t\treturn new PulseSocketIOClient(\n\t\t\tconfig.serverAddress,\n\t\t\tdirectives,\n\t\t\trrNavigate,\n\t\t\tconfig.connectionStatus,\n\t\t);\n\t}, [config.serverAddress, rrNavigate, config.connectionStatus]);\n\tuseEffect(() => client.setDirectives(directives), [client, directives]);\n\n\tuseEffect(() => {\n\t\tif (!inBrowser) return;\n\n\t\tconst handleConnectionChange = (newStatus: ConnectionStatus) => {\n\t\t\tsetStatus(newStatus);\n\t\t};\n\n\t\tconst unsubscribe = client.onConnectionChange(handleConnectionChange);\n\n\t\t// Start connection attempt\n\t\tclient.connect();\n\n\t\treturn () => {\n\t\t\tunsubscribe();\n\t\t\tclient.disconnect();\n\t\t};\n\t}, [client]);\n\n\tconst getStatusMessage = () => {\n\t\tswitch (status) {\n\t\t\tcase \"connecting\":\n\t\t\t\treturn \"Connecting...\";\n\t\t\tcase \"reconnecting\":\n\t\t\t\treturn \"Reconnecting...\";\n\t\t\tcase \"error\":\n\t\t\t\treturn \"Failed to connect to the server.\";\n\t\t\t// \"ok\" falls through to default\n\t\t\tdefault:\n\t\t\t\treturn null;\n\t\t}\n\t};\n\n\tconst statusMessage = getStatusMessage();\n\n\treturn (\n\t\t<PulseClientContext.Provider value={client}>\n\t\t\t<PulsePrerenderContext.Provider value={prerender}>\n\t\t\t\t{statusMessage && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tposition: \"fixed\",\n\t\t\t\t\t\t\tbottom: \"20px\",\n\t\t\t\t\t\t\tright: \"20px\",\n\t\t\t\t\t\t\tbackgroundColor: status === \"error\" ? \"red\" : \"#666\",\n\t\t\t\t\t\t\tcolor: \"white\",\n\t\t\t\t\t\t\tpadding: \"10px\",\n\t\t\t\t\t\t\tborderRadius: \"5px\",\n\t\t\t\t\t\t\tzIndex: 1000,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{statusMessage}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{children}\n\t\t\t</PulsePrerenderContext.Provider>\n\t\t</PulseClientContext.Provider>\n\t);\n}\n\n// =================================================================\n// View\n// =================================================================\n\nexport interface PulseViewProps {\n\tpath: string;\n\tregistry: Record<string, unknown>;\n}\n\nexport function PulseView({ path, registry }: PulseViewProps) {\n\tconst client = usePulseClient();\n\tconst initialView = usePulsePrerender(path);\n\tconst renderer = useMemo(\n\t\t() => new VDOMRenderer(client, path, registry),\n\t\t[client, path, registry],\n\t);\n\tconst [tree, setTree] = useState<ReactNode>(() => renderer.init(initialView));\n\tconst [serverError, setServerError] = useState<ServerError | null>(null);\n\n\tconst location = useLocation();\n\tconst params = useParams();\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: using hacky deep equality for params\n\tconst routeInfo = useMemo(() => {\n\t\tconst { \"*\": catchall = \"\", ...pathParams } = params;\n\t\tconst queryParams = new URLSearchParams(location.search);\n\t\tconst query = location.search.startsWith(\"?\")\n\t\t\t? location.search.slice(1)\n\t\t\t: location.search;\n\t\tconst hash = location.hash.startsWith(\"#\")\n\t\t\t? location.hash.slice(1)\n\t\t\t: location.hash;\n\t\treturn {\n\t\t\thash,\n\t\t\tpathname: location.pathname,\n\t\t\tquery,\n\t\t\tqueryParams: Object.fromEntries(queryParams.entries()),\n\t\t\tpathParams,\n\t\t\tcatchall: catchall.length > 0 ? catchall.split(\"/\") : [],\n\t\t} satisfies RouteInfo;\n\t}, [location.hash, location.pathname, location.search, JSON.stringify(params)]);\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: We don't want to detach on navigation, so another useEffect syncs the routeInfo on navigation.\n\tuseEffect(() => {\n\t\tif (inBrowser) {\n\t\t\tclient.attach(path, {\n\t\t\t\trouteInfo,\n\t\t\t\tonInit: (view) => {\n\t\t\t\t\tsetTree(renderer.init(view));\n\t\t\t\t\tsetServerError(null);\n\t\t\t\t},\n\t\t\t\tonUpdate: (ops) => {\n\t\t\t\t\tsetTree((prev) => (prev == null ? prev : renderer.applyUpdates(prev, ops)));\n\t\t\t\t\tsetServerError(null);\n\t\t\t\t},\n\t\t\t\tonJsExec: (msg) => {\n\t\t\t\t\tlet result: any;\n\t\t\t\t\tlet error: string | null = null;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresult = renderer.evaluateExpr(msg.expr);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\terror = e instanceof Error ? e.message : String(e);\n\t\t\t\t\t}\n\t\t\t\t\tclient.sendJsResult(msg.id, result, error);\n\t\t\t\t},\n\t\t\t\tonServerError: setServerError,\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\trenderer.clearPendingCallbacks();\n\t\t\t\trenderer.dispose();\n\t\t\t\tclient.detach(path);\n\t\t\t};\n\t\t}\n\t\t// routeInfo is NOT included here on purpose\n\t}, [client, renderer, path]);\n\n\tuseEffect(() => {\n\t\tif (inBrowser) {\n\t\t\tclient.updateRoute(path, routeInfo);\n\t\t}\n\t}, [client, path, routeInfo]);\n\t// Hack for our current prerendering setup on client-side navigation. Will be improved soon\n\tconst hasRendered = useRef(false);\n\tuseEffect(() => {\n\t\t// First rendering pass, no need to update the tree\n\t\tif (!hasRendered.current) {\n\t\t\thasRendered.current = true;\n\t\t}\n\t\t// 2nd+ rendering pass. Happens when a route stays mounted on navigation.\n\t\telse {\n\t\t\tsetTree(renderer.init(initialView));\n\t\t}\n\t\t// Note: Do NOT reset hasRendered in cleanup. The cleanup runs when effect \n\t\t// deps change and at least once on mount with strict mode,\n\t\t// not just on unmount, which would cause subsequent runs to skip setTree.\n\t}, [initialView, renderer]);\n\n\tif (serverError) {\n\t\treturn <ServerErrorPopup error={serverError} />;\n\t}\n\n\treturn tree;\n}\n\nfunction ServerErrorPopup({ error }: { error: ServerError }) {\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tpadding: 16,\n\t\t\t\tborder: \"1px solid #e00\",\n\t\t\t\tbackground: \"#fff5f5\",\n\t\t\t\tcolor: \"#900\",\n\t\t\t\tfontFamily:\n\t\t\t\t\t'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n\t\t\t\twhiteSpace: \"pre-wrap\",\n\t\t\t}}\n\t\t>\n\t\t\t<div style={{ fontWeight: 700, marginBottom: 8 }}>Server Error during {error.phase}</div>\n\t\t\t{error.message && <div>{error.message}</div>}\n\t\t\t{error.stack && (\n\t\t\t\t<details open style={{ marginTop: 8 }}>\n\t\t\t\t\t<summary>Stack trace</summary>\n\t\t\t\t\t<pre style={{ margin: 0 }}>{error.stack}</pre>\n\t\t\t\t</details>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { useEffect, useMemo } from \"react\";\nimport type { PulseSocketIOClient } from \"./client\";\nimport type {\n\tServerChannelMessage,\n\tServerChannelRequestMessage,\n\tServerChannelResponseMessage,\n} from \"./messages\";\nimport { usePulseClient } from \"./pulse\";\n\nexport class PulseChannelResetError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PulseChannelResetError\";\n\t}\n}\n\nexport type ChannelEventHandler = (payload: any) => any | Promise<any>;\n\ninterface PendingRequest {\n\tresolve: (value: any) => void;\n\treject: (error: any) => void;\n}\n\nfunction randomId(): string {\n\tif (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n\t\treturn crypto.randomUUID().replace(/-/g, \"\");\n\t}\n\treturn Math.random().toString(16).slice(2) + Math.random().toString(16).slice(2);\n}\n\nfunction formatError(error: unknown): string {\n\tif (error instanceof Error) return error.message;\n\tif (typeof error === \"string\") return error;\n\ttry {\n\t\treturn JSON.stringify(error);\n\t} catch {\n\t\treturn String(error);\n\t}\n}\n\nfunction isServerResponseMessage(\n\tmessage: ServerChannelMessage,\n): message is ServerChannelResponseMessage {\n\treturn typeof (message as ServerChannelResponseMessage).responseTo === \"string\";\n}\n\nfunction isServerRequestMessage(\n\tmessage: ServerChannelMessage,\n): message is ServerChannelRequestMessage {\n\treturn typeof (message as ServerChannelRequestMessage).event === \"string\";\n}\n\nexport class ChannelBridge {\n\tprivate handlers = new Map<string, Set<ChannelEventHandler>>();\n\tprivate pending = new Map<string, PendingRequest>();\n\tprivate backlog: ServerChannelRequestMessage[] = [];\n\tprivate closed = false;\n\n\tconstructor(\n\t\tprivate client: PulseSocketIOClient,\n\t\tpublic readonly id: string,\n\t) {}\n\n\temit(event: string, payload?: any): void {\n\t\tthis.ensureOpen();\n\t\tthis.client.sendMessage({\n\t\t\ttype: \"channel_message\",\n\t\t\tchannel: this.id,\n\t\t\tevent,\n\t\t\tpayload,\n\t\t});\n\t}\n\n\trequest(event: string, payload?: any): Promise<any> {\n\t\tthis.ensureOpen();\n\t\tconst requestId = randomId();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.pending.set(requestId, { resolve, reject });\n\t\t\tthis.client.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: this.id,\n\t\t\t\tevent,\n\t\t\t\tpayload,\n\t\t\t\trequestId,\n\t\t\t});\n\t\t});\n\t}\n\n\ton(event: string, handler: ChannelEventHandler): () => void {\n\t\tthis.ensureOpen();\n\t\tlet bucket = this.handlers.get(event);\n\t\tif (!bucket) {\n\t\t\tbucket = new Set();\n\t\t\tthis.handlers.set(event, bucket);\n\t\t}\n\t\tbucket.add(handler);\n\t\tthis.flushBacklog(event);\n\t\treturn () => {\n\t\t\tconst set = this.handlers.get(event);\n\t\t\tif (!set) return;\n\t\t\tset.delete(handler);\n\t\t\tif (set.size === 0) {\n\t\t\t\tthis.handlers.delete(event);\n\t\t\t}\n\t\t};\n\t}\n\n\thandleServerMessage(message: ServerChannelMessage): boolean {\n\t\tif (isServerResponseMessage(message)) {\n\t\t\tthis.resolvePending(message);\n\t\t\treturn this.closed;\n\t\t}\n\t\tif (this.closed) {\n\t\t\treturn true;\n\t\t}\n\t\tif (!isServerRequestMessage(message)) {\n\t\t\treturn this.closed;\n\t\t}\n\n\t\tif (message.event === \"__close__\") {\n\t\t\tthis.close(new PulseChannelResetError(\"Channel closed by server\"));\n\t\t\treturn true;\n\t\t}\n\t\tif (message.requestId) {\n\t\t\tvoid this.dispatchRequest(\n\t\t\t\tmessage as ServerChannelRequestMessage & {\n\t\t\t\t\trequestId: string;\n\t\t\t\t},\n\t\t\t);\n\t\t} else {\n\t\t\tthis.dispatchEvent(message);\n\t\t}\n\t\treturn this.closed;\n\t}\n\n\thandleDisconnect(reason: PulseChannelResetError): void {\n\t\tthis.close(reason);\n\t}\n\n\tdispose(reason: PulseChannelResetError): void {\n\t\tthis.close(reason);\n\t}\n\n\tprivate ensureOpen(): void {\n\t\tif (this.closed) {\n\t\t\tthrow new PulseChannelResetError(\"Channel is closed\");\n\t\t}\n\t}\n\n\tprivate flushBacklog(event: string): void {\n\t\tif (this.backlog.length === 0) return;\n\t\tconst remaining: ServerChannelRequestMessage[] = [];\n\t\tfor (const item of this.backlog) {\n\t\t\tif (item.event === event) {\n\t\t\t\tthis.dispatchEvent(item);\n\t\t\t} else {\n\t\t\t\tremaining.push(item);\n\t\t\t}\n\t\t}\n\t\tthis.backlog = remaining;\n\t}\n\n\tprivate dispatchEvent(message: ServerChannelRequestMessage): void {\n\t\tconst handlers = this.handlers.get(message.event);\n\t\tif (!handlers || handlers.size === 0) {\n\t\t\tthis.backlog.push(message);\n\t\t\treturn;\n\t\t}\n\t\tfor (const handler of handlers) {\n\t\t\ttry {\n\t\t\t\tconst result = handler(message.payload);\n\t\t\t\tif (result && typeof (result as Promise<any>).then === \"function\") {\n\t\t\t\t\tvoid (result as Promise<any>).catch((err) => {\n\t\t\t\t\t\tconsole.error(\"Pulse channel handler error\", err);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"Pulse channel handler error\", err);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async dispatchRequest(\n\t\tmessage: ServerChannelRequestMessage & { requestId: string },\n\t): Promise<void> {\n\t\tconst handlers = this.handlers.get(message.event);\n\t\tlet response: any;\n\t\tlet error: any;\n\t\tif (handlers && handlers.size > 0) {\n\t\t\tfor (const handler of handlers) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = handler(message.payload);\n\t\t\t\t\tresponse = await Promise.resolve(result);\n\t\t\t\t\tif (response !== undefined) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\terror = err;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (error) {\n\t\t\tthis.client.sendMessage({\n\t\t\t\ttype: \"channel_message\",\n\t\t\t\tchannel: this.id,\n\t\t\t\tevent: undefined,\n\t\t\t\tresponseTo: message.requestId,\n\t\t\t\terror: formatError(error),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tthis.client.sendMessage({\n\t\t\ttype: \"channel_message\",\n\t\t\tchannel: this.id,\n\t\t\tevent: undefined,\n\t\t\tresponseTo: message.requestId,\n\t\t\tpayload: response,\n\t\t});\n\t}\n\n\tprivate resolvePending(message: ServerChannelResponseMessage): void {\n\t\tconst entry = message.responseTo ? this.pending.get(message.responseTo) : undefined;\n\t\tif (!entry) {\n\t\t\treturn;\n\t\t}\n\t\tthis.pending.delete(message.responseTo!);\n\t\tif (message.error !== undefined && message.error !== null) {\n\t\t\tentry.reject(new PulseChannelResetError(String(message.error)));\n\t\t} else {\n\t\t\tentry.resolve(message.payload);\n\t\t}\n\t}\n\n\tprivate close(reason: PulseChannelResetError): void {\n\t\tif (this.closed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.closed = true;\n\t\tfor (const request of this.pending.values()) {\n\t\t\trequest.reject(reason);\n\t\t}\n\t\tthis.pending.clear();\n\t\tthis.handlers.clear();\n\t\tthis.backlog = [];\n\t\t// No-op: owning client manages registry lifecycle.\n\t}\n}\n\nexport function usePulseChannel(channelId: string): ChannelBridge {\n\tconst client = usePulseClient();\n\tconst bridge = useMemo(() => {\n\t\tif (!channelId) {\n\t\t\tthrow new Error(\"usePulseChannel requires a non-empty channelId\");\n\t\t}\n\t\treturn client.acquireChannel(channelId);\n\t}, [client, channelId]);\n\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tclient.releaseChannel(channelId);\n\t\t};\n\t}, [client, channelId]);\n\n\treturn bridge;\n}\n","import { type ComponentPropsWithoutRef, type FormEvent, forwardRef, useCallback } from \"react\";\n\nexport type PulseFormProps = ComponentPropsWithoutRef<\"form\"> & {\n\taction: string;\n};\n\n/**\n * PulseForm intercepts native form submissions and sends them through fetch so the\n * surrounding Pulse view stays mounted. Server-side handlers are still invoked via\n * the form action endpoint and reactive updates propagate over the socket.\n */\nexport const PulseForm = forwardRef<HTMLFormElement, PulseFormProps>(function PulseForm(\n\t{ onSubmit, action, ...rest },\n\tref,\n) {\n\treturn (\n\t\t<form\n\t\t\t{...rest}\n\t\t\taction={action}\n\t\t\tref={ref}\n\t\t\tonSubmit={useCallback(\n\t\t\t\t(event: FormEvent<HTMLFormElement>) => submitForm({ event, action, onSubmit }),\n\t\t\t\t[action, onSubmit],\n\t\t\t)}\n\t\t/>\n\t);\n});\n\ninterface SubmitForm {\n\tevent: FormEvent<HTMLFormElement>;\n\taction: string;\n\tonSubmit?: PulseFormProps[\"onSubmit\"];\n\tformData?: FormData;\n\tforce?: boolean;\n}\n\nexport async function submitForm({ event, action, onSubmit, formData, force }: SubmitForm) {\n\tonSubmit?.(event);\n\tif (!force && event.defaultPrevented) {\n\t\treturn;\n\t}\n\tconst form = event.currentTarget;\n\tevent.preventDefault();\n\tconst nativeEvent = event.nativeEvent as SubmitEvent;\n\tif (!formData) {\n\t\tformData = new FormData(form, nativeEvent.submitter);\n\t}\n\tconst url = new URL(action, window.location.href);\n\ttry {\n\t\tawait fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\t// Required for our hosting scenarios of same host + different ports or 2 subdomains\n\t\t\tcredentials: \"include\",\n\t\t\tbody: formData,\n\t\t});\n\t} catch (err) {\n\t\tif (process.env.NODE_ENV !== \"production\") {\n\t\t\tconsole.error(\"[Pulse] Form submission failed\", err);\n\t\t} else {\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n","import type { LoaderFunctionArgs } from \"react-router\";\n\nexport interface RouteInfo {\n\tpathname: string;\n\thash: string;\n\tquery: string;\n\tqueryParams: Record<string, string>;\n\tpathParams: Record<string, string | undefined>;\n\tcatchall: string[];\n}\n\nexport function extractServerRouteInfo({ params, request }: LoaderFunctionArgs) {\n\tconst { \"*\": catchall = \"\", ...pathParams } = params;\n\tconst parsedUrl = new URL(request.url);\n\tconst query = parsedUrl.search.startsWith(\"?\")\n\t\t? parsedUrl.search.slice(1)\n\t\t: parsedUrl.search;\n\tconst hash = parsedUrl.hash.startsWith(\"#\")\n\t\t? parsedUrl.hash.slice(1)\n\t\t: parsedUrl.hash;\n\n\treturn {\n\t\thash,\n\t\tpathname: parsedUrl.pathname,\n\t\tquery,\n\t\tqueryParams: Object.fromEntries(parsedUrl.searchParams.entries()),\n\t\tpathParams,\n\t\tcatchall: catchall.length > 1 ? catchall.split(\"/\") : [],\n\t} satisfies RouteInfo;\n}\n"],"mappings":"uXAEA,SAAgB,GAAoC,CACnD,SAAS,EAGP,EAAS,EAAc,CACxB,MACC,IAKI,CACJ,IAAMA,EAAW,EAAE,CACnB,IAAK,IAAM,KAAO,EACjB,EAAI,GAAkB,EAAY,GAEnC,GAAI,EACH,IAAK,IAAM,KAAO,EAAU,CAC3B,IAAM,EAAK,EAAS,GACpB,EAAI,GAAO,EAAG,EAAI,CAGpB,OAAO,GAGT,OAAO,ECxBR,MAAM,EAAgB,GAAe,EAAE,QAAQ,aAAa,CAEtD,EAAe,CACpB,KACA,YACA,UACA,YACA,eACA,aACA,YACA,cACA,eACA,aACA,YACA,cACA,OACA,CAEK,EAAmB,CACxB,YACA,WACA,QACA,CAEK,GAAyB,CAC9B,YACA,iBACA,iBACA,MACA,YACA,SACA,QACA,OACA,eACA,aACA,YACA,cACA,UACA,aACA,QACA,YACA,qBACA,kBACA,eACA,oBACA,YACA,CAEK,EAAqB,GAA0B,CAAC,EAAc,CACnE,QAAS,EACT,CAAC,CAEI,GAA0B,GAAmC,CAAC,EAAiB,CAE/E,GAA6B,GAA8B,CAAC,GAAuB,CAEzF,SAAS,EAAuB,EAAkB,CACjD,MAAO,CACN,GAAG,EAAmB,EAAI,CAC1B,GAAG,GAAwB,EAAwB,CACnD,GAAG,GAA2B,EAAI,CAClC,CAIF,SAAS,EACR,EACA,EACC,CACD,IAAM,EAAO,GAAoB,CAAC,EAAM,EAAgB,CACxD,MAAQ,KAAY,CAAE,GAAG,EAAuB,EAAI,CAAE,GAAG,EAAK,EAAI,CAAE,EAwBrE,MAAM,GAAkB,EArBC,CACxB,OACA,OACA,WACA,OACA,SACA,WACA,WACA,OACA,WACA,SACA,SACA,WACA,MACA,WACA,OACA,WACA,OACA,iBACA,OACA,CACoE,CAuB/D,GAAgB,EArBC,CACtB,MACA,SACA,WACA,OACA,OACA,WACA,OACA,SACA,WACA,WACA,OACA,WACA,MACA,SACA,QACA,SACA,WACA,OACA,iBACA,CAC8D,CAwBzD,EAAiB,EAtBC,CACvB,WACA,WACA,cACA,aACA,cACA,eACA,sBACA,WACA,QACA,OACA,QACA,eACA,SACA,eACA,UACA,aACA,UACA,MACA,SACA,iBACA,CACiE,CAE5D,GAAkB,GAA0B,EAAe,EAAI,CAc/D,GAAkB,EAZC,CACxB,WACA,OACA,OACA,QACA,aACA,cACA,aACA,iBACA,aACA,sBACA,CACoE,CAG/D,GAAgB,EADC,CAAC,QAAQ,CAC+B,CAUzD,GAAiB,EARC,CACvB,SACA,MACA,OACA,QACA,QACA,OACA,CACiE,CAS5D,GAAoB,EAPC,CAC1B,WACA,OACA,OACA,oBACA,eACA,CAC0E,CAerEC,GAAgB,EAbC,CACtB,gBACA,SACA,eACA,WACA,UACA,SACA,SACA,OACA,aACA,SACA,MACA,CAC8D,CAmBzD,GAAkB,EAjBC,CACxB,QACA,kBACA,SACA,OACA,iBACA,MACA,SACA,QACA,QACA,cACA,WACA,eACA,cACA,YACA,UACA,CACoE,CA6B/D,GAAiB,EA3BC,CACvB,MACA,cACA,WACA,SACA,QACA,UACA,gBACA,eACA,iBACA,QACA,MACA,SACA,SACA,QACA,QACA,SACA,WACA,SACA,WACA,SACA,OACA,SACA,IACA,IACA,gBACA,CACiE,CA6C5D,GAAiB,EA3CC,8ZA0CvB,CACkE,CAClE,cAAgB,GAAQ,CACvB,IAAM,EAAQ,EAAI,cAClB,OAAO,OAAO,SAAS,EAAM,CAAG,EAAQ,MAEzC,CAAC,CAGI,GAAiB,EADC,CAAC,UAAU,CAC+B,CAG5D,GAAc,EADC,CAAC,QAAS,OAAO,CACmB,CAqBnD,GAAgB,EAnBC,CACtB,KACA,cACA,WACA,gBACA,OACA,WACA,aACA,cACA,YACA,QACA,iBACA,MACA,OACA,UACA,MACA,SACA,QACA,CAC8D,CAGzD,GAAe,EADC,CAAC,OAAO,CAC8B,CAUtD,GAAiB,EARC,CACvB,OACA,MACA,MACA,MACA,UACA,QACA,CACiE,CAG5D,EAAe,EADC,CAAC,OAAQ,WAAW,CACkB,CAQtD,GAAiB,EANF,CACpB,WACA,QACA,OACA,UACA,CAC8D,CAsBzD,GAAkB,EApBC,CACxB,OACA,SACA,OACA,OACA,SACA,QACA,oBACA,eACA,QACA,UACA,SACA,OACA,WACA,WACA,UACA,SACA,UACA,SACA,CACoE,CAM/D,GAAoB,EAJC,CAC1B,WACA,QACA,CAC0E,CAWrE,GAAkB,EATC,CACxB,kBACA,WACA,QACA,QACA,WACA,OACA,QACA,CACoE,CAW/D,GAAkB,EATC,CACxB,eACA,OACA,OACA,QACA,UACA,oBACA,eACA,CACoE,CAO/D,GAAoB,EALC,CAC1B,MACA,WACA,QACA,CAC0E,CAGrE,GAAiB,EADC,CAAC,OAAO,CACkC,CAE5D,GAAiB,GAAqB,EAAuB,EAAI,CAejE,GAAwB,GAAoC,CAbzC,CACxB,QACA,cACA,QACA,gBACA,YACA,WACA,iBACA,MACA,OACA,OACA,UACA,CACoF,CACpF,MAAQ,GAAO,EAAU,MACzB,QAAU,GAAO,EAAU,QAC3B,CAAC,CACI,GAAmB,IAA4B,CACpD,GAAG,EAAuB,EAAI,CAC9B,GAAG,GAAsB,EAAI,CAC7B,EAgBK,GAAkB,EAdC,CACxB,eACA,WACA,SACA,WACA,OACA,WACA,gBACA,OACA,OACA,QACA,oBACA,eACA,CACoE,CAG/D,GAAgB,EADC,CAAC,OAAO,CACgC,CAWzD,GAAkB,EATC,CACxB,SACA,QACA,QACA,MACA,SACA,OACA,QACA,CACoE,CAK/D,GAAwB,EAHE,CAC/B,QACA,CACuF,CAmBlF,EAAqB,EAjBE,CAC5B,OACA,YACA,UACA,UACA,UACA,QACA,QACA,OACA,UACA,KACA,QACA,SACA,SACA,SACA,QACA,CAC8E,CAUzE,EAAoB,EARE,CAC3B,OACA,QACA,KACA,QACA,SACA,QACA,CAC2E,CAatE,GAAiB,EAXC,CACvB,QACA,UACA,SACA,cACA,cACA,QACA,QACA,UACA,QACA,CACiE,CAW5D,GAAoB,EATL,CACpB,WACA,kBACA,QACA,UACA,KACA,QACA,SACA,CACoE,CAQ/D,EAAwB,EANH,CAC1B,QACA,KACA,QACA,SACA,CACkF,CAE7E,GAAqB,GAA6B,EAAuB,EAAI,CAwB7E,GAAoB,EAtBC,CAC1B,eACA,OACA,eACA,UACA,WACA,YACA,YACA,OA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"}
|