@vcp-dev/site-edit-bridge 0.4.0 → 0.4.3

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.
@@ -1,5 +1,6 @@
1
1
  import type { SiteEditRenderDocument, SiteEditRenderEntry } from "@vcp-dev/contracts";
2
- import { type SiteEditBridgeClient, type SiteEditBridge } from "./client.js";
2
+ import { type SiteEditBridgeClient, type SiteEditBridge, type SiteEditBridgeConnectionStatus, type SiteEditBridgeConnectionState } from "./client.js";
3
+ import { type SiteEditFrameRuntimeBridgeStatus, type SiteEditFrameRuntimeRequestBody } from "./window-message.js";
3
4
  declare global {
4
5
  interface Window {
5
6
  __VCP_SITE_EDIT__?: SiteEditBridge;
@@ -13,10 +14,12 @@ declare global {
13
14
  }
14
15
  }
15
16
  export declare const VCP_SITE_EDIT_ROUTE_READY_EVENT = "vcp-site-edit:route-ready";
17
+ export declare const VCP_SITE_EDIT_BRIDGE_STATUS_EVENT = "vcp-site-edit:bridge-status";
16
18
  export type SiteEditRouteReadyDetail = {
17
19
  routeId: string;
18
20
  version: number;
19
21
  };
22
+ export type SiteEditBridgeStatusDetail = SiteEditFrameRuntimeBridgeStatus;
20
23
  export type SiteEditAutoBootstrapOptions = {
21
24
  explicit_ws_url?: string;
22
25
  basePath?: string;
@@ -36,7 +39,12 @@ export type SiteEditRuntimeVersions = {
36
39
  export type SiteEditBootstrapClient = SiteEditBridgeClient & {
37
40
  connect(): Promise<void>;
38
41
  disconnect(): void;
42
+ getConnectionState?: () => SiteEditBridgeConnectionState;
43
+ subscribeConnectionStatus?: (listener: (status: SiteEditBridgeConnectionStatus) => void) => () => void;
39
44
  };
45
+ type BridgeFrameRuntimeRequestBody = Extract<SiteEditFrameRuntimeRequestBody, {
46
+ kind: "bridge-get-document" | "bridge-ensure-document-version" | "bridge-get-object-summary" | "bridge-get-object-edit-context" | "bridge-get-class-name-source" | "bridge-get-source-tree" | "bridge-get-source-file" | "bridge-resolve-source-location" | "bridge-execute" | "bridge-undo" | "bridge-redo" | "bridge-subscribe" | "bridge-unsubscribe";
47
+ }>;
40
48
  export declare function resolveSiteEditRouteId(pathname: string, basePath?: string): string;
41
49
  export declare function resolveSiteEditWebSocketUrl(windowLike: Pick<Window, "location">, options?: {
42
50
  explicit_ws_url?: string;
@@ -46,6 +54,9 @@ export declare function resolveSiteEditWebSocketUrl(windowLike: Pick<Window, "lo
46
54
  }): string;
47
55
  export declare function startSiteEditAutoBootstrap(windowLike?: Window & typeof globalThis, options?: SiteEditAutoBootstrapOptions): Promise<void>;
48
56
  export declare function startSiteEditFrameRuntime(windowLike?: Window & typeof globalThis, options?: {
57
+ expectedSessionKey?: string;
49
58
  getCurrentDocument?: () => SiteEditRenderDocument | null;
50
59
  getDocumentEntry?: (key: string) => SiteEditRenderEntry | null;
60
+ onBridgeRequestError?: (error: unknown, request: BridgeFrameRuntimeRequestBody) => void;
51
61
  }): () => void;
62
+ export {};
@@ -1 +1 @@
1
- function de(e){if(!Ve(e))return e;let t=new Map,n=r=>{let o=t.get(r);if(o)return o;let s=e.nodes[r];if(!s)throw new Error(`Missing compact document node ${r}`);let i=e.tokens[s.token];if(typeof i!="string")throw new Error(`Missing compact document token ${s.token}`);let u=`${s.parent===null?"":n(s.parent)}${i}`;return t.set(r,u),u};return{siteId:e.siteId,snapshotId:e.snapshotId,routeId:e.routeId,version:e.version,rootKeys:e.rootKeyNodeIds.map(n),entries:e.entries.map(r=>({key:n(r.keyNodeId),tag:r.tag,label:r.label,parentKey:r.parentKeyNodeId===null?null:n(r.parentKeyNodeId),childKeys:r.childKeyNodeIds.map(n),operationSummary:r.operationSummary}))}}function Ve(e){return typeof e=="object"&&e!==null&&"encoding"in e&&e.encoding==="segment-trie-v1"}var U=class e{constructor(){}static parseMessage(t,n={}){let r=JSON.parse(t);if(!e.isMessage(r,n))throw new Error("Invalid site edit bridge message");return r}static stringifyMessage(t){return JSON.stringify(t)}static extractRequestInfo(t){if(typeof t=="object"&&t!==null&&"payload"in t&&typeof t.payload=="object"&&t.payload!==null){let n=t.payload,r=typeof n.id=="string"?n.id:"unknown",o=e.isRequestKind(n.kind)?n.kind:"get-document";return{id:r,kind:o}}return{id:"unknown",kind:"get-document"}}static isRequestKind(t){return t==="get-document"||t==="get-object-summary"||t==="get-object-edit-context"||t==="get-class-name-source"||t==="execute"||t==="undo"||t==="redo"}static isMessage(t,n={}){return!M(t)||typeof t.type!="string"?!1:t.type==="request"?e.isRequestPayload(t.payload,n):t.type==="response"||t.type==="error"?M(t.payload)&&typeof t.payload.id=="string":t.type==="event"?M(t.payload)&&M(t.payload.event):!1}static isRequestPayload(t,n={}){if(!M(t)||typeof t.id!="string"||!e.isRequestKind(t.kind))return!1;switch(t.kind){case"get-document":return typeof t.routeId=="string";case"get-object-summary":case"get-object-edit-context":case"get-class-name-source":return typeof t.key=="string"&&(t.routeId===void 0||typeof t.routeId=="string");case"execute":return je(t.request)&&(n.validateOperationRequest?.(t.request)??!0);case"undo":case"redo":return!0}}};function M(e){return typeof e=="object"&&e!==null}function je(e){return M(e)&&typeof e.id=="string"&&typeof e.siteId=="string"&&typeof e.baseSnapshotId=="string"&&(e.routeId===void 0||typeof e.routeId=="string")&&typeof e.kind=="string"&&M(e.target)&&typeof e.documentVersion=="number"&&Number.isInteger(e.documentVersion)&&e.documentVersion>=0&&M(e.params)}var We="vcp:designer:trace",Ue="designer_trace",pe="__VCP_DESIGNER_TRACE__";var $e=/(authorization|cookie|token|secret|providerTrace|headers?|sourceCode|rawSource|fullSource)/i;function Ye(e=globalThis){let t=e;try{if(t.localStorage?.getItem(We)==="1")return!0}catch{}try{let n=t.location?.search??"";return new URLSearchParams(n).get(Ue)==="1"}catch{return!1}}function K(e,t={},n=globalThis){if(!Ye(n))return;let r={type:e,timestamp:Date.now(),payload:Ge(t)},o=n,s=o[pe]??[];s.push(r),s.length>200&&s.splice(0,s.length-200),o[pe]=s;let i=n.console?.debug;typeof i=="function"&&i.call(n.console,"[designer-trace]",r)}function Ge(e){return ee(e,0)}function ee(e,t){if(t>4)return"[truncated]";if(Array.isArray(e))return e.map(r=>ee(r,t+1));if(!e||typeof e!="object")return e;let n={};for(let[r,o]of Object.entries(e)){if($e.test(r)){n[r]="[redacted]";continue}n[r]=ee(o,t+1)}return n}var H=class{constructor(t){this.options=t,this.socket=null,this.sequence=0,this.pending=new Map,this.listeners=new Set}connect(){return this.socket?Promise.resolve():new Promise((t,n)=>{let r=this.createSocket(this.options.url);this.socket=r,r.onopen=()=>t(),r.onerror=o=>{n(o instanceof Error?o:new Error("WebSocket failed"))},r.onmessage=o=>this.handleMessage(o.data),r.onclose=()=>{this.rejectAll(new Error("WebSocket closed")),this.socket=null}})}disconnect(){this.socket?.close(),this.socket=null,this.rejectAll(new Error("WebSocket disconnected"))}getDocument(t){return this.request("get-document",{routeId:t})}getObjectSummary(t,n){return this.request("get-object-summary",{key:t,routeId:n})}getObjectEditContext(t,n){return this.request("get-object-edit-context",{key:t,routeId:n})}getClassNameSource(t,n){return this.request("get-class-name-source",{key:t,routeId:n})}execute(t){return this.request("execute",{request:t})}undo(){return this.request("undo",{})}redo(){return this.request("redo",{})}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}request(t,n){let r=this.socket;if(!r)return Promise.reject(new Error("WebSocket is not connected"));let o=`${t}-${this.sequence+=1}`,s=we(o,t,n);return K("bridge.request",{id:o,kind:t,routeId:typeof n.routeId=="string"?n.routeId:null,key:typeof n.key=="string"?n.key:null,operationKind:fe(n.request,"kind"),documentVersion:fe(n.request,"documentVersion")}),new Promise((i,u)=>{this.pending.set(o,{kind:t,resolve:d=>i(d),reject:u}),r.send(U.stringifyMessage(s))})}handleMessage(t){let n=U.parseMessage(t);if(n.type==="event"){for(let o of this.listeners)o(n.payload.event);return}if(n.type!=="response"&&n.type!=="error")return;let r=this.pending.get(n.payload.id);if(r){if(this.pending.delete(n.payload.id),n.type==="error"){K("bridge.response",{id:n.payload.id,kind:r.kind,ok:!1}),r.reject(new Error(n.payload.message));return}K("bridge.response",{id:n.payload.id,kind:r.kind,ok:!0,resultVersion:Xe(n.payload.result)}),r.resolve(r.kind==="get-document"?{...n.payload.result,data:de(n.payload.result.data)}:n.payload.result)}}rejectAll(t){for(let n of this.pending.values())n.reject(t);this.pending.clear()}createSocket(t){if(this.options.createSocket)return this.options.createSocket(t);if(typeof WebSocket>"u")throw new Error("Site edit preview bridge requires WebSocket");return new WebSocket(t)}};function fe(e,t){if(!e||typeof e!="object")return null;let r=e[t];return typeof r=="string"||typeof r=="number"?r:null}function Xe(e){if(!e||typeof e!="object")return null;let t=e,n=t.data?.resultVersion??t.data?.version??null;return typeof n=="number"?n:null}function me(e){return new te(e)}var te=class{constructor(t){this.params=t,this.refreshInFlight=null,this.currentDocument=t.initialDocument,this.summaryCache=new Map(Object.entries(t.initialDetails??{}).map(([n,r])=>[n,ze(r)])),this.editContextCache=new Map(Object.entries(t.initialDetails??{}).map(([n,r])=>[n,Je(r)]))}async getDocument(t){if(t!==this.params.routeId)throw new Error(`Site edit bridge is bound to route ${this.params.routeId}, received ${t}`);return He(this.currentDocument)&&(this.currentDocument=await this.refreshSnapshot(void 0,"get-document")),{ok:!0,data:this.currentDocument}}async ensureDocumentVersion(t,n){if(t!==this.params.routeId)throw new Error(`Site edit bridge is bound to route ${this.params.routeId}, received ${t}`);let r=await this.refreshSnapshot(n,"ensure-version");if(r.version<n)throw new Error(`Document refresh returned version ${r.version}, expected at least ${n}`);return{ok:!0,data:r}}async getObjectSummary(t,n){let r=this.summaryCache.get(t);if(r)return{ok:!0,data:r};let o=await this.params.client.getObjectSummary(t,n??this.params.routeId);return this.summaryCache.set(t,o.data),o}async getObjectEditContext(t,n){let r=this.editContextCache.get(t);if(r)return{ok:!0,data:r};let o=await this.params.client.getObjectEditContext(t,n??this.params.routeId);return this.editContextCache.set(t,o.data),o}async getClassNameSource(t,n){return this.params.client.getClassNameSource(t,n??this.params.routeId)}async execute(t){return this.params.client.execute(t.target.kind==="node"&&!t.routeId?{...t,routeId:this.params.routeId}:t)}async undo(){return this.params.client.undo()}async redo(){return this.params.client.redo()}subscribe(t){return this.params.client.subscribe(n=>{if(n.type==="site-edit.document.changed"&&n.routeId===this.params.routeId){this.refreshSnapshot(n.version,"event").catch(()=>{}).finally(()=>t(n));return}t(n)})}async refreshSnapshot(t,n="ensure-version"){if(typeof t=="number"&&this.currentDocument.version>=t)return K("bridge.document-refresh",{routeId:this.params.routeId,minVersion:t,currentVersion:this.currentDocument.version,deduped:!0,skipped:!0,source:n}),this.currentDocument;if(this.refreshInFlight){K("bridge.document-refresh",{routeId:this.params.routeId,minVersion:t,currentVersion:this.currentDocument.version,deduped:!0,source:n});let o=await this.refreshInFlight;if(typeof t!="number"||o.version>=t||this.currentDocument.version>=t)return this.currentDocument}K("bridge.document-refresh",{routeId:this.params.routeId,minVersion:t,currentVersion:this.currentDocument.version,deduped:!1,source:n});let r=this.params.client.getDocument(this.params.routeId).then(o=>(this.currentDocument=o.data,this.clearObjectCaches(),this.currentDocument));this.refreshInFlight=r;try{return await r}finally{this.refreshInFlight===r&&(this.refreshInFlight=null)}}clearObjectCaches(){this.summaryCache.clear(),this.editContextCache.clear()}};function He(e){return e.version===0&&e.rootKeys.length===0}function we(e,t,n){switch(t){case"get-document":return{type:"request",payload:{id:e,kind:t,routeId:String(n.routeId)}};case"get-object-summary":return{type:"request",payload:{id:e,kind:t,key:String(n.key),routeId:typeof n.routeId=="string"?n.routeId:void 0}};case"get-object-edit-context":return{type:"request",payload:{id:e,kind:t,key:String(n.key),routeId:typeof n.routeId=="string"?n.routeId:void 0}};case"get-class-name-source":return{type:"request",payload:{id:e,kind:t,key:String(n.key),routeId:typeof n.routeId=="string"?n.routeId:void 0}};case"execute":return{type:"request",payload:{id:e,kind:t,request:n.request}};case"undo":case"redo":return{type:"request",payload:{id:e,kind:t}}}}function ze(e){return{key:e.key,tag:e.tag,label:e.label,capabilities:{constraints:e.capabilities.constraints},isOpaque:e.isOpaque,provenanceChain:e.provenanceChain?{editMode:e.provenanceChain.editMode,diagnostics:e.provenanceChain.diagnostics}:void 0,ancestors:e.ancestors}}function Je(e){return{key:e.key,componentName:e.componentName,sourceFile:e.sourceFile,capabilities:e.capabilities,writeTarget:e.writeTarget,effectiveWriteTarget:e.effectiveWriteTarget,provenanceChain:e.provenanceChain,componentSemantic:e.componentSemantic,textSegments:e.textSegments,boundaryKind:e.boundaryKind,children:e.children,siblings:e.siblings}}var he="vcp-window-message";function Qe(e){return{source:he,version:1,namespace:e.namespace,channel:e.channel,...e.sessionKey?{sessionKey:e.sessionKey}:{},body:e.body}}function Ze(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.source===he&&t.version===1&&typeof t.namespace=="string"&&typeof t.channel=="string"&&"body"in t}var ye="site-edit",ge="frame-runtime";function $(e,t={}){return Qe({namespace:ye,channel:ge,sessionKey:t.sessionKey,body:e})}function be(e){return!Ze(e)||e.namespace!==ye||e.channel!==ge?!1:typeof e.body?.type=="string"}var oe="vcp-site-edit:route-ready",Le=1e3,et="data-vcp-ui-component",Te="data-vcp-theme-preview",Ee="::repeat-item#",w="components/ui",tt=new Set(["article","aside","div","footer","form","header","li","main","nav","ol","section","select","table","tbody","tfoot","thead","tr","ul"]),nt=new Set(["a","button","em","h1","h2","h3","h4","h5","h6","label","p","small","span","strong"]);function rt(e,t=""){let n=mt(t),r=n&&(e===n||e.startsWith(`${n}/`))?e.slice(n.length)||"/":e,o=r.startsWith("/")?r:`/${r}`;return o==="/"?"/":o.replace(/\/+$/,"")}function ot(e,t){if(e.__VCP_SITE_EDIT_VERSION_LOGGED__)return;let n=e.console?.info;typeof n=="function"&&(e.__VCP_SITE_EDIT_VERSION_LOGGED__=!0,n.call(e.console,"[VCP Site Edit] runtime loaded",{bridge:t.versions?.bridge??"unknown",contracts:t.versions?.contracts??"unknown",documentVersion:t.documentVersion,engine:t.versions?.engine??"unknown",routeId:t.routeId}))}function st(e,t={}){let n=s=>{if(!t.bridge_session_key)return s;let i=new URL(s,e.location.href);return i.searchParams.set("vcp_bridge_key",t.bridge_session_key),i.toString()};if(t.explicit_ws_url){if(t.explicit_ws_url.startsWith("/")){let s=e.location.protocol==="https:"?"wss:":"ws:";return n(`${s}//${e.location.host}${t.explicit_ws_url}`)}return n(t.explicit_ws_url)}let r=e.location.protocol==="https:"?"wss:":"ws:",o=t.port?`${e.location.hostname}:${t.port}`:e.location.host;return n(`${r}//${o}${t.path??"/__vcp/site-edit/bridge"}`)}async function pn(e=window,t={}){if(e.__VCP_SITE_EDIT_AUTO_BOOTSTRAP__?.started)return;let n={activeClient:null,cleanupFrameRuntime:(()=>{}),retryTimer:void 0,routeSequence:0,currentDocument:null,currentEntriesByKey:new Map,unsubscribeDocument:void 0,unbindRouteChange:void 0};n.cleanupFrameRuntime=ut(e,{getCurrentDocument:()=>n.currentDocument,getDocumentEntry:a=>n.currentEntriesByKey.get(a)??null});let r=t.create_client??(a=>new H({url:a})),o=t.schedule_after_navigation??pt,s=st(e,{explicit_ws_url:t.explicit_ws_url,port:t.ws_port,path:t.wsPath||"/__vcp/site-edit/bridge",bridge_session_key:t.bridge_session_key}),i=()=>{n.retryTimer&&(e.clearTimeout(n.retryTimer),n.retryTimer=void 0)},u=a=>{n.currentDocument=a,n.currentEntriesByKey=new Map((a?.entries??[]).map(R=>[R.key,R]))},d=async(a,R)=>{let E=e.__VCP_SITE_EDIT__;if(!E)return null;let b=await E.getDocument(a);return R!==n.routeSequence||a!==e.__VCP_SITE_EDIT_AUTO_BOOTSTRAP__?.routeId||u(b.data),b.data},y=()=>{n.unsubscribeDocument?.(),n.unsubscribeDocument=void 0,u(null),delete e.__VCP_SITE_EDIT__,n.activeClient?.disconnect(),n.activeClient=null},m=async()=>{let a=rt(e.location.pathname,t.basePath||"");if(a===e.__VCP_SITE_EDIT_AUTO_BOOTSTRAP__?.routeId&&e.__VCP_SITE_EDIT__)return;let R=n.routeSequence+=1;i(),y();let E=r(s);try{if(await E.connect(),R!==n.routeSequence){E.disconnect();return}e.__VCP_SITE_EDIT__=me({routeId:a,client:E,initialDocument:it(a)}),n.activeClient=E,n.unsubscribeDocument=e.__VCP_SITE_EDIT__.subscribe(N=>{N.type==="site-edit.document.changed"&&N.routeId===a&&d(a,R).catch(()=>{})}),e.__VCP_SITE_EDIT_AUTO_BOOTSTRAP__.routeId=a;let b=await d(a,R);ot(e,{documentVersion:b?.version??0,routeId:a,versions:t.runtime_versions}),ft(e,{routeId:a,version:b?.version??0})}catch(b){throw E.disconnect(),b}},v=()=>{i(),n.retryTimer=e.setTimeout(()=>{m().catch(()=>v())},Le)},_=()=>{o(()=>{m().catch(()=>v())})};if(e.__VCP_SITE_EDIT_AUTO_BOOTSTRAP__={started:!0,syncRoute:m,cleanup:()=>{i(),n.routeSequence+=1,n.unbindRouteChange?.(),n.cleanupFrameRuntime(),y(),delete e.__VCP_SITE_EDIT_AUTO_BOOTSTRAP__}},n.unbindRouteChange=dt(e,_),t.defer_initial_sync){_();return}await m()}function it(e){return{siteId:"preview",snapshotId:"preview",routeId:e,version:0,rootKeys:[],entries:[]}}function ut(e=window,t={}){let n=null,r=null,o=null,s=null,i=null,u=null,d=new Map,y=()=>{n?.(),n=null},m=()=>{r?.(),r=null,o?.(),o=null},v=(I,l,c)=>{let x=s?.sessionKey!==I||s?.sourceWindow!==l||s?.targetOrigin!==c;s={sessionKey:I,sourceWindow:l,targetOrigin:c},x&&(u=null)},_=()=>{for(let I of d.values())I();d.clear()},a=I=>{i=I.routeId==="/"?null:I;let l=`${I.routeId}:${I.version}`;u!==l&&(o?.(),o=null,E({kind:"route-ready",payload:{routeId:I.routeId,version:I.version}}),s&&(u=l))},R=()=>{i&&a(i)},E=I=>{s&&s.sourceWindow.postMessage($({type:"event",...I},{sessionKey:s.sessionKey}),s.targetOrigin)},b=(I,l,c,x)=>{let S=Q(e.document,l.clientX,l.clientY),T=S?D(S,c==="full"?P(e.document,S,t.getCurrentDocument?.()??null):ve(e.document,S,t.getCurrentDocument?.()??null),t.getDocumentEntry,c):null;x&&T&&(I==="pointer-click"||I==="pointer-double-click")&&(x.preventDefault(),x.stopPropagation(),typeof x.stopImmediatePropagation=="function"&&x.stopImmediatePropagation()),E({kind:I,payload:{clientX:l.clientX,clientY:l.clientY,buttons:Number(l.buttons??0),hit:T}})},N=(I,l,c)=>{m(),s={sessionKey:I,sourceWindow:l,targetOrigin:c};let x=Jt(e.document),S=null,T=null,f=()=>{T=null;let p=S;S=null,p&&b("pointer-move",p,"summary")},k=p=>{S={clientX:Number(p.clientX),clientY:Number(p.clientY),buttons:Number(p.buttons)},T===null&&(T=Ce(e,f))},F=p=>{b("pointer-down",{clientX:Number(p.clientX),clientY:Number(p.clientY),buttons:Number(p.buttons)},"full",p)},B=p=>{b("pointer-up",{clientX:Number(p.clientX),clientY:Number(p.clientY),buttons:Number(p.buttons)},"summary",p)},A=p=>{b("pointer-cancel",{clientX:Number(p.clientX),clientY:Number(p.clientY),buttons:Number(p.buttons)},"summary",p)},q=p=>{b("pointer-click",{clientX:Number(p.clientX),clientY:Number(p.clientY),buttons:Number(p.buttons)},"full",p)},j=p=>{b("pointer-double-click",{clientX:Number(p.clientX),clientY:Number(p.clientY),buttons:Number(p.buttons)},"full",p)},W=()=>{E({kind:"scroll",payload:{metrics:J(e)}})};e.document.addEventListener("pointerdown",F,!0),e.document.addEventListener("pointermove",k,{passive:!0,capture:!0}),e.document.addEventListener("pointerup",B,!0),e.document.addEventListener("pointercancel",A,!0),e.document.addEventListener("click",q,!0),e.document.addEventListener("dblclick",j,!0),e.addEventListener("scroll",W,{passive:!0}),r=()=>{T!==null&&(Ne(e,T),T=null),S=null,x(),e.document.removeEventListener("pointerdown",F,!0),e.document.removeEventListener("pointermove",k,!0),e.document.removeEventListener("pointerup",B,!0),e.document.removeEventListener("pointercancel",A,!0),e.document.removeEventListener("click",q,!0),e.document.removeEventListener("dblclick",j,!0),e.removeEventListener("scroll",W)}},ae=I=>{let l=I.detail;l?.routeId&&a(l)},le=I=>{let l=I.data;if(!be(l)||l.body.type!=="request"||l.body.kind!=="apply-node-patch"&&l.body.kind!=="get-hit-by-ref"&&l.body.kind!=="get-path-by-ref"&&l.body.kind!=="get-scroll-metrics"&&l.body.kind!=="scroll-to"&&l.body.kind!=="scroll-by"&&l.body.kind!=="set-interaction-mode"&&l.body.kind!=="set-theme-override"&&l.body.kind!=="clear-theme-override"&&l.body.kind!=="get-theme-variables"&&l.body.kind!=="compute-drop-target-at-point"&&l.body.kind!=="observe-node-bounds"&&l.body.kind!=="clear-node-bounds-observer"&&l.body.kind!=="start-text-edit-at-point"&&l.body.kind!=="hit-test-at-point"&&!Ie(l.body))return;let c=l.body,x=typeof l.sessionKey=="string"?l.sessionKey:null,S=I.source,T=I.origin;if(!x||!T||!S||typeof S.postMessage!="function"||s&&(s.sessionKey!==x||s.sourceWindow!==S||s.targetOrigin!==T))return;v(x,S,T),R();let f=k=>{let F=typeof c.id=="string"?c.id:"unknown";S.postMessage($({id:F,...k},{sessionKey:x}),T)};try{if(Ie(c)){ct({message:c,sendEvent:h=>{S.postMessage($({type:"event",...h},{sessionKey:x}),T)},sendResponse:f,subscriptions:d,getCurrentDocument:t.getCurrentDocument,windowLike:e});return}if(c.kind==="apply-node-patch"){let h=V(e.document,c.payload.ref,t.getCurrentDocument?.()??null);if(!h){f({type:"response",ok:!1,error:"No editable element found for patch target"});return}let g=c.payload.preview,C=g?qt(g.sessionId,c.payload.ref):null;if(C&&g){let X=Y.get(C)??-1;if(g.revision<X){f({type:"response",ok:!0,result:{applied:!1,appliedRevision:g.revision,stale:!0,latestRevision:X}});return}if(g.revision===X){f({type:"response",ok:!0,result:{applied:!1,appliedRevision:g.revision,duplicate:!0,latestRevision:X}});return}}if(Ft(h,c.payload.patch),C&&g&&Kt(C,g.revision),g?.responseDetail==="none"){f({type:"response",ok:!0,result:{applied:!0,appliedRevision:g.revision}});return}f({type:"response",ok:!0,result:D(h,P(e.document,h,t.getCurrentDocument?.()??null),t.getDocumentEntry,g?.responseDetail??"full")});return}if(c.kind==="get-hit-by-ref"){let h=V(e.document,c.payload.ref,t.getCurrentDocument?.()??null);if(!h){f({type:"response",ok:!1,error:"No editable element found for hit target"});return}f({type:"response",ok:!0,result:D(h,P(e.document,h,t.getCurrentDocument?.()??null),t.getDocumentEntry,"full")});return}if(c.kind==="get-path-by-ref"){let h=V(e.document,c.payload.ref,t.getCurrentDocument?.()??null);if(!h){f({type:"response",ok:!1,error:"No editable element found for path target"});return}let g=[],C=h;for(;C;)C.getAttribute("data-vcp-edit-key")&&g.push(D(C,P(e.document,C,t.getCurrentDocument?.()??null),t.getDocumentEntry,"full")),C=C.parentElement;f({type:"response",ok:!0,result:g.reverse()});return}if(c.kind==="get-scroll-metrics"){f({type:"response",ok:!0,result:J(e)});return}if(c.kind==="scroll-to"){let h=Number(c.payload.x),g=Number(c.payload.y);if(!Number.isFinite(h)||!Number.isFinite(g)){f({type:"response",ok:!1,error:"Invalid scroll position"});return}e.scrollTo({left:h,top:g}),f({type:"response",ok:!0,result:J(e)});return}if(c.kind==="scroll-by"){let h=Number(c.payload.deltaX),g=Number(c.payload.deltaY);if(!Number.isFinite(h)||!Number.isFinite(g)){f({type:"response",ok:!1,error:"Invalid scroll delta"});return}e.scrollBy({left:h,top:g}),f({type:"response",ok:!0,result:{...J(e),scrolled:!0}});return}if(c.kind==="set-interaction-mode"){c.payload.enabled?N(x,S,T):s?.sourceWindow===S&&s.targetOrigin===T&&s.sessionKey===x&&m(),f({type:"response",ok:!0,result:{interactionEnabled:c.payload.enabled}});return}if(c.kind==="set-theme-override"){Bt(e.document,c.payload),f({type:"response",ok:!0,result:{themeOverrideApplied:!0}});return}if(c.kind==="clear-theme-override"){Vt(e.document),f({type:"response",ok:!0,result:{themeOverrideCleared:!0}});return}if(c.kind==="get-theme-variables"){f({type:"response",ok:!0,result:jt(e.document,c.payload.names)});return}if(c.kind==="compute-drop-target-at-point"){let h=Number(c.payload?.x),g=Number(c.payload?.y);if(!Number.isFinite(h)||!Number.isFinite(g)){f({type:"response",ok:!1,error:"Invalid drop target point"});return}f({type:"response",ok:!0,result:Dt(e,h,g,c.payload.dragKind,c.payload.movingRef,t.getCurrentDocument?.()??null,t.getDocumentEntry)});return}if(c.kind==="observe-node-bounds"){let h=c.payload.ref;if(!h){f({type:"response",ok:!1,error:"Missing bounds observer target"});return}let g=V(e.document,h,t.getCurrentDocument?.()??null);if(!g){f({type:"response",ok:!1,error:"No editable element found for bounds observer target"});return}o?.(),o=Nt(e,g,h,t.getDocumentEntry,C=>E({kind:"node-bounds-change",payload:{hit:C}})),f({type:"response",ok:!0,result:{observing:!0}}),E({kind:"node-bounds-change",payload:{hit:D(g,h,t.getDocumentEntry,"summary")}});return}if(c.kind==="clear-node-bounds-observer"){o?.(),o=null,f({type:"response",ok:!0,result:{cleared:!0}});return}if(c.kind!=="hit-test-at-point"&&c.kind!=="start-text-edit-at-point")return;let k=Number(c.payload?.x),F=Number(c.payload?.y);if(!Number.isFinite(k)||!Number.isFinite(F)){f({type:"response",ok:!1,error:"Invalid text edit point"});return}let B=c.kind==="hit-test-at-point"?Q(e.document,k,F):yt(e.document,k,F,t.getCurrentDocument?.()??null,t.getDocumentEntry);if(!B){f({type:"response",ok:!1,error:c.kind==="hit-test-at-point"?"No editable element at point":"No editable text element at point"});return}let A=c.kind==="start-text-edit-at-point"?B:null,q=c.kind==="hit-test-at-point"?B:A.element,j=c.payload.detailLevel??"full",W=j==="full"?P(e.document,q,t.getCurrentDocument?.()??null):ve(e.document,q,t.getCurrentDocument?.()??null),p=A&&typeof A.textSegmentIndex=="number"?{...W,textSegmentIndex:A.textSegmentIndex}:W,Be=D(q,p,t.getDocumentEntry,j);if(c.kind==="hit-test-at-point"){f({type:"response",ok:!0,result:Be});return}y(),n=Yt(e,q,p,h=>{S.postMessage($({type:"event",...h},{sessionKey:x}),T)},A?{textNode:A.textNode}:void 0),f({type:"response",ok:!0,result:{ref:p}})}catch(k){f({type:"response",ok:!1,error:k instanceof Error?k.message:"Failed to start text edit"})}};return e.addEventListener("message",le),e.addEventListener(oe,ae),()=>{y(),m(),s=null,_(),e.removeEventListener("message",le),e.removeEventListener(oe,ae)}}function Ie(e){let t=e.kind;return t==="bridge-get-document"||t==="bridge-ensure-document-version"||t==="bridge-get-object-summary"||t==="bridge-get-object-edit-context"||t==="bridge-get-class-name-source"||t==="bridge-execute"||t==="bridge-undo"||t==="bridge-redo"||t==="bridge-subscribe"||t==="bridge-unsubscribe"}async function ct({message:e,sendEvent:t,sendResponse:n,subscriptions:r,getCurrentDocument:o,windowLike:s}){let i=s.__VCP_SITE_EDIT__;if(!i){n({type:"response",ok:!1,error:"Site edit bridge is not ready in preview frame"});return}try{switch(e.kind){case"bridge-get-document":n({type:"response",ok:!0,result:await i.getDocument(e.payload.routeId)});return;case"bridge-ensure-document-version":if(!Number.isFinite(Number(e.payload.minVersion))){n({type:"response",ok:!1,error:"Invalid document version"});return}n({type:"response",ok:!0,result:i.ensureDocumentVersion?await i.ensureDocumentVersion(e.payload.routeId,Number(e.payload.minVersion)):await i.getDocument(e.payload.routeId)});return;case"bridge-get-object-summary":n({type:"response",ok:!0,result:await i.getObjectSummary(e.payload.key,e.payload.routeId)});return;case"bridge-get-object-edit-context":n({type:"response",ok:!0,result:await i.getObjectEditContext(e.payload.key,e.payload.routeId)});return;case"bridge-get-class-name-source":{let u=await i.getClassNameSource(e.payload.key,e.payload.routeId);n({type:"response",ok:!0,result:at(u,e.payload.key,s.document,o?.()??null)});return}case"bridge-execute":n({type:"response",ok:!0,result:await i.execute(e.payload.request)});return;case"bridge-undo":n({type:"response",ok:!0,result:await i.undo()});return;case"bridge-redo":n({type:"response",ok:!0,result:await i.redo()});return;case"bridge-subscribe":{let u=e.payload.subscriptionId;r.get(u)?.();let d=i.subscribe(y=>{t({kind:"bridge-event",payload:{event:y,subscriptionId:u}})});r.set(u,d),n({type:"response",ok:!0,result:{subscribed:!0}});return}case"bridge-unsubscribe":{let u=e.payload.subscriptionId;r.get(u)?.(),r.delete(u),n({type:"response",ok:!0,result:{unsubscribed:!0}});return}}}catch(u){n({type:"response",ok:!1,error:u instanceof Error?u.message:"Site edit bridge request failed"})}}function at(e,t,n,r){if(!e.ok||!e.data.styleContext)return e;let o=V(n,{key:t},r),s=o?lt(o):null;return s?{...e,data:{...e.data,styleContext:{...e.data.styleContext,computedStyle:{...e.data.styleContext.computedStyle??{},...s}}}}:e}function lt(e){let t=e.ownerDocument.defaultView;if(!t)return null;let n=t.getComputedStyle(e);return{color:n.color,backgroundColor:n.backgroundColor,borderColor:n.borderColor}}function dt(e,t){let n=e.history.pushState,r=e.history.replaceState,o=()=>t();return e.history.pushState=function(...i){let u=n.apply(this,i);return t(),u},e.history.replaceState=function(...i){let u=r.apply(this,i);return t(),u},e.addEventListener("popstate",o),()=>{e.history.pushState=n,e.history.replaceState=r,e.removeEventListener("popstate",o)}}function pt(e){if(typeof requestAnimationFrame=="function"){requestAnimationFrame(()=>requestAnimationFrame(e));return}setTimeout(e,0)}function Ce(e,t){return typeof e.requestAnimationFrame=="function"?e.requestAnimationFrame(t):e.setTimeout(t,0)}function Ne(e,t){if(typeof e.cancelAnimationFrame=="function"){e.cancelAnimationFrame(t);return}e.clearTimeout(t)}function ft(e,t){e.dispatchEvent(new CustomEvent(oe,{detail:t}))}function mt(e){let t=e.trim();return!t||t==="/"?"":(t.startsWith("/")?t:`/${t}`).replace(/\/+$/,"")}function ue(e){return tt.has(De(e))}function ht(e){return nt.has(De(e))}function ke(e){return e.operationSummary?{canUpdateText:e.operationSummary.canUpdateText,canInsertChild:e.operationSummary.canInsertChild,canMove:e.operationSummary.canMove,canRemove:e.operationSummary.canRemove}:e.fallbackMode!=="preview"?{canUpdateText:!1,canInsertChild:!1,canMove:!1,canRemove:!1}:{canUpdateText:ht(e.tagName),canInsertChild:ue(e.tagName),canMove:!1,canRemove:!1}}function De(e){return e?.trim().toLowerCase()??""}function yt(e,t,n,r,o){let s=Q(e,t,n),i=Oe(s);if(!i)return null;let u=i.getAttribute("data-vcp-edit-key")??"",d=P(e,i,r),y=o?.(d.key)??o?.(u);if(!ke({operationSummary:y?.operationSummary,tagName:i.tagName,fallbackMode:"preview"}).canUpdateText)return null;if((y?.childKeys.length??0)===0)return{element:i};let v=gt(e,t,n,i);if(!v)return null;let _=Et(i,v);return _===null?null:{element:i,textNode:v,textSegmentIndex:_}}function gt(e,t,n,r){let o=bt(e,t,n);return!o||o.parentElement!==r?null:o}function bt(e,t,n){let r=e,s=r.caretPositionFromPoint?.(t,n)?.offsetNode??null;if(se(s))return s;let u=r.caretRangeFromPoint?.(t,n)?.startContainer??null;return se(u)?u:null}function Et(e,t){let n=0;for(let r of Array.from(e.childNodes))if(!(!se(r)||(r.textContent??"").trim().length===0)){if(r===t)return n;n+=1}return null}function se(e){return e?.nodeType===3}function Q(e,t,n){let r=typeof e.elementsFromPoint=="function"?e.elementsFromPoint(t,n):[e.elementFromPoint(t,n)].filter(Boolean);for(let o of r){let s=Oe(o);if(s)return s}return null}function Oe(e){let t=e,n=null;for(;t;){let r=t.getAttribute("data-vcp-edit-key")??"";if(r){if(ce(t))return n??t;!It(r)&&!n&&(n=t)}t=t.parentElement}return n}function ce(e){return e.getAttribute(et)!==null}function It(e){return vt(e.split("::")[0]??"")}function vt(e){if(!e)return!1;let t=St(e);return t===w||t.startsWith(`${w}/`)||t.includes(`/${w}/`)||t.endsWith(`/${w}`)}function St(e){let n=(e.split("?")[0]??e).replace(/\\/g,"/").replace(/^\.\//,""),r=[];for(let o of n.split("/"))if(!(!o||o===".")){if(o===".."){r.pop();continue}r.push(o)}return r.join("/")}function P(e,t,n){let r=t.getAttribute("data-vcp-edit-key")??"",o=Ae(Array.from(e.querySelectorAll(`[data-vcp-edit-key="${Ke(r)}"]`)));if(o.length<=1)return{key:Se(n,r,0)};let s=o.indexOf(t);return s>=0?{key:Se(n,r,s),instanceIndex:s,instanceCount:o.length}:{key:r}}function ve(e,t,n){return P(e,t,n)}function V(e,t,n){let r=Z(t.key)??t.key,o=Ae(Array.from(e.querySelectorAll(`[data-vcp-edit-key="${Ke(r)}"]`)));if(o.length===0)return null;let s=typeof t.instanceIndex=="number"&&t.instanceIndex>=0&&t.instanceIndex<o.length?t.instanceIndex:null,i=(Z(t.key)??t.key)!==t.key;if(s!==null&&!i)return o[s]??null;let u=_t(n,t.key);return u!==null&&u>=0&&u<o.length?o[u]??null:s!==null?o[s]??null:o[0]??null}function Se(e,t,n){return Pe(e,t)[n]?.key??t}function _t(e,t){let n=Z(t);if(!n)return null;let o=Pe(e,n).findIndex(s=>s.key===t);return o>=0?o:null}function Pe(e,t){return(e?.entries??[]).filter(n=>(Z(n.key)??n.key)===t)}var Rt=2,xt=4;function Ae(e){return[...e].sort((t,n)=>{if(t===n)return 0;let r=typeof t.compareDocumentPosition=="function"?t.compareDocumentPosition(n):0;return(r&xt)!==0?-1:(r&Rt)!==0?1:0})}function Z(e){if(typeof e!="string"||e.length===0)return e??null;let t=e;for(;;){let n=t.lastIndexOf(Ee);if(n<0)break;let r=Number(t.slice(n+Ee.length));if(!Number.isInteger(r)||r<0)return e;t=t.slice(0,n)}return t}function Tt(e){let n=e.ownerDocument?.defaultView?.getComputedStyle(e),r=o=>{let s=Number.parseFloat(o??"");return Number.isFinite(s)&&s>0?s:0};return{marginTop:r(n?.marginTop),marginRight:r(n?.marginRight),marginBottom:r(n?.marginBottom),marginLeft:r(n?.marginLeft),paddingTop:r(n?.paddingTop),paddingRight:r(n?.paddingRight),paddingBottom:r(n?.paddingBottom),paddingLeft:r(n?.paddingLeft),borderTopWidth:r(n?.borderTopWidth),borderRightWidth:r(n?.borderRightWidth),borderBottomWidth:r(n?.borderBottomWidth),borderLeftWidth:r(n?.borderLeftWidth),columnGap:r(n?.columnGap),rowGap:r(n?.rowGap)}}function Ct(e){return Array.from(e.children).filter(t=>typeof t.getBoundingClientRect=="function").map(t=>ie(t.getBoundingClientRect())).filter(t=>t.width>0&&t.height>0)}function D(e,t,n,r="full"){let o=e.getBoundingClientRect(),s=n?.(t.key)??null,i=e.tagName.toLowerCase(),u=L(e),d=r==="full"?{textPreview:e.textContent?.trim().slice(0,80),dataset:Object.fromEntries(Object.entries(e.dataset).map(([a,R])=>[a,R??""])),attributes:Object.fromEntries(e.getAttributeNames().map(a=>[a,e.getAttribute(a)??""]))}:{},y=ke({operationSummary:s?.operationSummary,tagName:i,fallbackMode:"preview"}),m=ce(e),v=!!(s&&/^[A-Z]/.test(s.tag)),_=!s||!v;return{ref:t,key:t.key,detailLevel:r,tagName:i,...s?{sourceKind:v?"component-call":"jsx"}:{},...v&&s?.tag?{componentName:s.tag}:{},...s?.parentKey?{parentKey:s.parentKey}:{},...d,runtimeFlags:{selectable:!0,movable:y.canMove,removable:y.canRemove,textEditable:y.canUpdateText,container:m?!1:(s?.childKeys.length??0)>0||y.canInsertChild||_&&ue(i)},layout:u,rect:{top:o.top,left:o.left,width:o.width,height:o.height},childRects:Ct(e),spacing:Tt(e)}}function Nt(e,t,n,r,o){let s=ie(t.getBoundingClientRect()),i=null,u=()=>{i===null&&(i=Ce(e,d))},d=()=>{if(i=null,"isConnected"in t&&!t.isConnected)return;let a=ie(t.getBoundingClientRect());kt(s,a)&&(s=a,o(D(t,n,r,"summary")))},y=e.ResizeObserver,m=typeof y=="function"?new y(u):null;m?.observe(t);let v=e.MutationObserver,_=typeof v=="function"?new v(u):null;return _?.observe(e.document.documentElement,{attributes:!0,childList:!0,characterData:!0,subtree:!0}),e.document.addEventListener("load",u,!0),()=>{i!==null&&(Ne(e,i),i=null),m?.disconnect(),_?.disconnect(),e.document.removeEventListener("load",u,!0)}}function ie(e){return{top:e.top,left:e.left,width:e.width,height:e.height}}function kt(e,t){return Math.abs(e.top-t.top)>.5||Math.abs(e.left-t.left)>.5||Math.abs(e.width-t.width)>.5||Math.abs(e.height-t.height)>.5}function Dt(e,t,n,r,o,s,i){let u=e.document,d=Q(u,t,n);if(!d)return{anchorHit:null,targetParentHit:null,relation:"none",rejectionReason:"no-editable-hit"};let y=o?V(u,o,s):null;if(y&&xe(d,y))return z(u,d,"self-or-descendant",s,i);let m=null,v=!1,_=d,a=d.parentElement;for(;a;){if(a.getAttribute("data-vcp-edit-key")){if(y&&xe(a,y))return z(u,d,"self-or-descendant",s,i);let E=_e(a,r,i);if(E==="accept"){m={child:_,targetParent:a};break}E==="blocked"&&(v=!0),_=a}a=a.parentElement}let R=_e(d,r,i);if(R==="accept"){if(m){let E=Re(m.child,m.targetParent,t,n,"edge");if(E)return ne(u,m.child,m.targetParent,E,s,i)}return ne(u,d,d,Ot(d,t,n),s,i)}if(m){let E=Re(m.child,m.targetParent,t,n,"nearest");return ne(u,m.child,m.targetParent,E??"after",s,i)}return R==="blocked"||v?z(u,d,"operation-boundary-blocked",s,i):z(u,d,"no-accepting-parent",s,i)}function z(e,t,n,r,o){return{anchorHit:D(t,P(e,t,r),o,"summary"),targetParentHit:null,relation:"none",rejectionReason:n}}function ne(e,t,n,r,o,s){let i=D(t,P(e,t,o),s,"summary"),u=D(n,P(e,n,o),s,"summary"),d=L(n).indicatorOrientation,y=r==="append"||r==="prepend"?Pt(n.getBoundingClientRect(),d,r):At(t.getBoundingClientRect(),d,r);return{anchorHit:i,targetParentHit:u,relation:r,indicatorOrientation:d,indicatorBounds:y}}function _e(e,t,n){if(ce(e))return"not-container";let r=e.getAttribute("data-vcp-edit-key")??"",o=n?.(r)??null;if(o)return o.operationSummary.canInsertChild===!0?"accept":o.childKeys.length>0?"blocked":"not-container";let s=e.tagName.toLowerCase();return ue(s)?"accept":"not-container"}function Re(e,t,n,r,o){let s=L(t).indicatorOrientation,i=e.getBoundingClientRect(),u=s==="vertical"?i.width>0?(n-i.left)/i.width:.5:i.height>0?(r-i.top)/i.height:.5;return o==="edge"&&u>=.25&&u<=.75?null:u<.5?"before":"after"}function Ot(e,t,n){let r=L(e).indicatorOrientation,o=e.getBoundingClientRect();return(r==="vertical"?o.width>0?(t-o.left)/o.width:.5:o.height>0?(n-o.top)/o.height:.5)<.5?"prepend":"append"}function L(e){let n=e.ownerDocument?.defaultView?.getComputedStyle(e),r=n?.display??"",o=n?.flexDirection,s=n?.gridAutoFlow,i="horizontal";return r==="flex"||r==="inline-flex"?i=(o??"row").startsWith("row")?"vertical":"horizontal":(r==="grid"||r==="inline-grid")&&(i=(s??"row").includes("column")?"vertical":"horizontal"),{display:r,...o?{flexDirection:o}:{},...s?{gridAutoFlow:s}:{},indicatorOrientation:i}}function Pt(e,t,n){if(t==="vertical")return{left:n==="prepend"?e.left:e.left+e.width-3,top:e.top,width:3,height:e.height};let r=n==="prepend"?e.top:e.top+e.height-3;return{left:e.left,top:r,width:e.width,height:3}}function At(e,t,n){if(t==="vertical")return{left:n==="before"?e.left:e.left+e.width-3,top:e.top,width:3,height:e.height};let r=n==="before"?e.top:e.top+e.height-3;return{left:e.left,top:r,width:e.width,height:3}}function xe(e,t){let n=e;for(;n;){if(n===t)return!0;n=n.parentElement}return!1}function J(e){let t=e.document.documentElement,n=e.document.body;return{scrollX:O(e.scrollX),scrollY:O(e.scrollY),scrollWidth:Math.max(O(t?.scrollWidth),O(n?.scrollWidth),O(e.innerWidth)),scrollHeight:Math.max(O(t?.scrollHeight),O(n?.scrollHeight),O(e.innerHeight)),viewportWidth:O(e.innerWidth),viewportHeight:O(e.innerHeight)}}function Ft(e,t){Object.entries(t.attributes??{}).forEach(([n,r])=>{if(r===null){e.removeAttribute(n);return}e.setAttribute(n,r)}),typeof t.className=="string"&&(e.className=t.className),Object.entries(t.style??{}).forEach(([n,r])=>{let o=e.style,s=n.replace(/[A-Z]/g,i=>`-${i.toLowerCase()}`);if(r==null||r===""){o.removeProperty(s);return}o.setProperty(s,String(r))})}var Mt=500,Y=new Map;function qt(e,t){return`${e}:${t.key}:${t.instanceIndex??""}`}function Kt(e,t){if(Y.size>=Mt){let n=Y.keys().next().value;n&&Y.delete(n)}Y.set(e,t)}var G=new Set;function Bt(e,t){let n=e.documentElement?.style,r=new Set;for(let[o,s]of Object.entries(t.variables??{}))o.startsWith("--")&&(r.add(o),n?.setProperty(o,s));for(let o of G)r.has(o)||n?.removeProperty(o);G.clear();for(let o of r)G.add(o);$t(e,t.stylesheets??[])}function Vt(e){let t=e.documentElement?.style;for(let n of G)t?.removeProperty(n);G.clear();for(let n of qe(e))n.remove()}function jt(e,t){let n=Array.from(new Set(t.filter(i=>typeof i=="string"&&i.startsWith("--"))));if(n.length===0)return{};let r=e.documentElement,o=r?e.defaultView?.getComputedStyle(r):null,s={};for(let i of n){let u=Fe(o,i);u&&(s[i]=u)}return s}function Fe(e,t,n=new Set){if(!e||n.has(t))return null;n.add(t);let r=e.getPropertyValue(t).trim();return Me(e,r,n)}function Me(e,t,n){if(!t)return null;let r=Wt(t);if(!r)return t;let o=Fe(e,r.name,n);return o||(r.fallback?Me(e,r.fallback,n)??r.fallback:null)}function Wt(e){let t=e.trim();if(!t.startsWith("var(")||!t.endsWith(")"))return null;let n=t.slice(4,-1).trim(),r=Ut(n),o=r>=0?n.slice(0,r).trim():n;if(!o.startsWith("--"))return null;let s=r>=0?n.slice(r+1).trim():null;return{name:o,fallback:s||null}}function Ut(e){let t=0;for(let n=0;n<e.length;n+=1){let r=e[n];if(r==="("){t+=1;continue}if(r===")"){t=Math.max(0,t-1);continue}if(r===","&&t===0)return n}return-1}function $t(e,t){let n=new Set(t.filter(s=>typeof s=="string"&&s.length>0)),r=new Map;for(let s of qe(e)){let i=s.getAttribute("href")??"";if(!n.has(i)||r.has(i)){s.remove();continue}r.set(i,s)}let o=e.head;if(o)for(let s of n){if(r.has(s))continue;let i=e.createElement("link");i.setAttribute("rel","stylesheet"),i.setAttribute(Te,"true"),i.setAttribute("href",s),o.appendChild(i)}}function qe(e){return Array.from(e.querySelectorAll(`link[${Te}]`))}function Yt(e,t,n,r,o={}){let s=o.textNode?Gt(e.document,o.textNode):null;if(o.textNode&&!s)throw new Error("Failed to prepare text segment editor");let i=s?.element??t,u=i.textContent??"",d=Xt(i),y=!1,m=()=>{e.document.removeEventListener("pointerdown",_,!0),i.removeEventListener("keydown",a),i.removeEventListener("blur",R),i.removeEventListener("input",E),wt(i,d)},v=b=>{if(y)return;y=!0;let N=i.textContent??"";if(m(),b==="cancel"){s?.restore(u),s||(t.textContent=u),r({kind:"text-edit-cancel",payload:{ref:n}});return}if(s?.restore(N),b==="commit"&&N!==u){r({kind:"text-edit-commit",payload:{ref:n,value:N}});return}r({kind:"text-edit-exit",payload:{ref:n}})};function _(b){let N=b.target;N&&i.contains(N)||v("commit")}function a(b){if(b.key==="Escape"){b.preventDefault(),v("cancel");return}b.key==="Enter"&&(b.metaKey||b.ctrlKey)&&(b.preventDefault(),v("commit"))}function R(){v("commit")}function E(){r({kind:"text-edit-input",payload:{ref:n,hit:D(t,n,void 0,"full")}})}return Ht(i),e.document.addEventListener("pointerdown",_,!0),i.addEventListener("keydown",a),i.addEventListener("blur",R),i.addEventListener("input",E),Qt(i),Zt(i,e.document),m}function Gt(e,t){let n=t.parentNode;if(!n)return null;let r=e.createElement("span");return r.setAttribute("data-vcp-text-segment-editor","true"),r.textContent=t.textContent??"",n.replaceChild(r,t),{element:r,restore(o){t.nodeValue=o,r.parentNode&&r.parentNode.replaceChild(t,r)}}}function Xt(e){return{contentEditable:e.getAttribute("contenteditable"),spellcheck:e.getAttribute("spellcheck"),marker:e.getAttribute("data-vcp-edit-text-editing"),cursor:e.style.cursor,userSelect:e.style.userSelect}}function Ht(e){zt(e.ownerDocument),e.setAttribute("contenteditable","plaintext-only"),e.setAttribute("spellcheck","false"),e.setAttribute("data-vcp-edit-text-editing","true"),e.style.cursor="text",e.style.userSelect="text"}function wt(e,t){re(e,"contenteditable",t.contentEditable),re(e,"spellcheck",t.spellcheck),re(e,"data-vcp-edit-text-editing",t.marker),e.style.cursor=t.cursor,e.style.userSelect=t.userSelect}function zt(e){if(e.getElementById("vcp-text-edit-base-style"))return;let t=e.createElement("style");t.id="vcp-text-edit-base-style",t.textContent='[data-vcp-edit-text-editing="true"]{outline:0!important;outline-offset:0!important;}',e.head.appendChild(t)}function re(e,t,n){if(n===null){e.removeAttribute(t);return}e.setAttribute(t,n)}function Jt(e){let t=[e.documentElement,e.body].filter(r=>!!r?.style),n=t.map(r=>({element:r,userSelect:r.style.userSelect}));for(let r of t)r.style.userSelect="none";return()=>{for(let r of n)r.element.style.userSelect=r.userSelect}}function Qt(e){try{e.focus({preventScroll:!0})}catch{e.focus()}}function Zt(e,t){let n=t.createRange();n.selectNodeContents(e);let r=t.getSelection?.();r?.removeAllRanges(),r?.addRange(n)}function Ke(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function O(e){let t=Number(e);return Number.isFinite(t)?t:0}export{oe as VCP_SITE_EDIT_ROUTE_READY_EVENT,rt as resolveSiteEditRouteId,st as resolveSiteEditWebSocketUrl,pn as startSiteEditAutoBootstrap,ut as startSiteEditFrameRuntime};
1
+ function ke(e){if(!ct(e))return e;let t=new Map,n=r=>{let o=t.get(r);if(o)return o;let s=e.nodes[r];if(!s)throw new Error(`Missing compact document node ${r}`);let i=e.tokens[s.token];if(typeof i!="string")throw new Error(`Missing compact document token ${s.token}`);let c=`${s.parent===null?"":n(s.parent)}${i}`;return t.set(r,c),c};return{siteId:e.siteId,snapshotId:e.snapshotId,routeId:e.routeId,version:e.version,rootKeys:e.rootKeyNodeIds.map(n),entries:e.entries.map(r=>({key:n(r.keyNodeId),tag:r.tag,label:r.label,parentKey:r.parentKeyNodeId===null?null:n(r.parentKeyNodeId),childKeys:r.childKeyNodeIds.map(n),operationSummary:r.operationSummary}))}}function ct(e){return typeof e=="object"&&e!==null&&"encoding"in e&&e.encoding==="segment-trie-v1"}var Y=class e{constructor(){}static parseMessage(t,n={}){let r=JSON.parse(t);if(!e.isMessage(r,n))throw new Error("Invalid site edit bridge message");return r}static stringifyMessage(t){return JSON.stringify(t)}static extractRequestInfo(t){if(typeof t=="object"&&t!==null&&"payload"in t&&typeof t.payload=="object"&&t.payload!==null){let n=t.payload,r=typeof n.id=="string"?n.id:"unknown",o=e.isRequestKind(n.kind)?n.kind:"get-document";return{id:r,kind:o}}return{id:"unknown",kind:"get-document"}}static isRequestKind(t){return t==="get-document"||t==="get-object-summary"||t==="get-object-edit-context"||t==="get-class-name-source"||t==="get-source-tree"||t==="get-source-file"||t==="resolve-source-location"||t==="execute"||t==="undo"||t==="redo"}static isMessage(t,n={}){return!B(t)||typeof t.type!="string"?!1:t.type==="request"?e.isRequestPayload(t.payload,n):t.type==="response"||t.type==="error"?B(t.payload)&&typeof t.payload.id=="string":t.type==="event"?B(t.payload)&&B(t.payload.event):t.type==="auth"?B(t.payload)&&typeof t.payload.key=="string":t.type==="auth-ok"?B(t.payload)&&t.payload.ok===!0:!1}static isRequestPayload(t,n={}){if(!B(t)||typeof t.id!="string"||!e.isRequestKind(t.kind))return!1;switch(t.kind){case"get-document":return typeof t.routeId=="string";case"get-object-summary":case"get-object-edit-context":case"get-class-name-source":case"resolve-source-location":return typeof t.key=="string"&&(t.routeId===void 0||typeof t.routeId=="string");case"get-source-tree":return!0;case"get-source-file":return typeof t.path=="string";case"execute":return ut(t.request)&&(n.validateOperationRequest?.(t.request)??!0);case"undo":case"redo":return!0}}};function B(e){return typeof e=="object"&&e!==null}function ut(e){return B(e)&&typeof e.id=="string"&&typeof e.siteId=="string"&&typeof e.baseSnapshotId=="string"&&(e.routeId===void 0||typeof e.routeId=="string")&&typeof e.kind=="string"&&B(e.target)&&typeof e.documentVersion=="number"&&Number.isInteger(e.documentVersion)&&e.documentVersion>=0&&B(e.params)}var at="vcp:designer:trace",lt="designer_trace",Pe="__VCP_DESIGNER_TRACE__";var dt=/(authorization|cookie|token|secret|providerTrace|headers?|sourceCode|rawSource|fullSource)/i;function pt(e=globalThis){let t=e;try{if(t.localStorage?.getItem(at)==="1")return!0}catch{}try{let n=t.location?.search??"";return new URLSearchParams(n).get(lt)==="1"}catch{return!1}}function U(e,t={},n=globalThis){if(!pt(n))return;let r={type:e,timestamp:Date.now(),payload:ft(t)},o=n,s=o[Pe]??[];s.push(r),s.length>200&&s.splice(0,s.length-200),o[Pe]=s;let i=n.console?.debug;typeof i=="function"&&i.call(n.console,"[designer-trace]",r)}function ft(e){return me(e,0)}function me(e,t){if(t>4)return"[truncated]";if(Array.isArray(e))return e.map(r=>me(r,t+1));if(!e||typeof e!="object")return e;let n={};for(let[r,o]of Object.entries(e)){if(dt.test(r)){n[r]="[redacted]";continue}n[r]=me(o,t+1)}return n}var ie=class{constructor(t){this.options=t,this.socket=null,this.connectPromise=null,this.connectAttempt=null,this.connectionState="idle",this.intentionalClose=!1,this.sequence=0,this.pending=new Map,this.listeners=new Set,this.connectionStatusListeners=new Set}connect(){return this.socket?.readyState===he&&this.connectionState==="open"?(this.setConnectionState("open"),Promise.resolve()):this.connectPromise?this.connectPromise:(this.intentionalClose=!1,this.setConnectionState("connecting"),this.connectPromise=new Promise((t,n)=>{let r;try{r=this.createSocket(this.options.url)}catch(c){let u=L(c,"WebSocket failed");this.socket=null,this.connectAttempt=null,this.connectPromise=null,this.setConnectionState("failed",u.message),n(u);return}let o={socket:r,settled:!1,reject:n};this.connectAttempt=o,this.socket=r;let s=()=>{this.socket!==r||this.connectAttempt!==o||(o.settled=!0,this.connectAttempt=null,this.connectPromise=null,this.setConnectionState("open"),t())},i=(c,u)=>{this.cleanupSocket(r,c,u)};r.onopen=()=>{if(!(this.socket!==r||this.connectAttempt!==o)){if(this.options.authKey){try{r.send(Y.stringifyMessage({type:"auth",payload:{key:this.options.authKey}}))}catch(c){i(L(c,"WebSocket auth failed"),"failed")}return}s()}},r.onerror=c=>{if(this.socket!==r)return;let u=L(c,"WebSocket failed");i(u,"failed")},r.onmessage=c=>{if(this.socket===r){if(this.options.authKey&&this.connectAttempt===o&&!o.settled){this.handleAuthHandshakeMessage(c.data,r,o,()=>{s()});return}this.handleMessage(c.data)}},r.onclose=()=>{if(this.socket!==r)return;let c=this.intentionalClose,u=new Error(c?"WebSocket disconnected":"WebSocket closed");i(u,c?"closed":"failed")}}),this.connectPromise)}disconnect(){this.intentionalClose=!0,this.setConnectionState("closing");let t=this.socket;if(!t){this.rejectAll(new Error("WebSocket disconnected")),this.connectAttempt=null,this.connectPromise=null,this.setConnectionState("closed");return}this.cleanupSocket(t,new Error("WebSocket disconnected"),"closed")}getConnectionState(){return this.connectionState}subscribeConnectionStatus(t){return this.connectionStatusListeners.add(t),t({state:this.connectionState}),()=>{this.connectionStatusListeners.delete(t)}}getDocument(t){return this.request("get-document",{routeId:t})}getObjectSummary(t,n){return this.request("get-object-summary",{key:t,routeId:n})}getObjectEditContext(t,n){return this.request("get-object-edit-context",{key:t,routeId:n})}getClassNameSource(t,n){return this.request("get-class-name-source",{key:t,routeId:n})}getSourceTree(){return this.request("get-source-tree",{})}getSourceFile(t){return this.request("get-source-file",t)}resolveSourceLocation(t){return this.request("resolve-source-location",t)}execute(t){return this.request("execute",{request:t})}undo(){return this.request("undo",{})}redo(){return this.request("redo",{})}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}request(t,n){let r=this.socket;if(!r||r.readyState!==he||this.connectionState!=="open")return Promise.reject(new Error(`WebSocket is not open (state: ${this.connectionState}, readyState: ${r?.readyState??"none"})`));let o=`${t}-${this.sequence+=1}`,s=Et(o,t,n);return U("bridge.request",{id:o,kind:t,routeId:typeof n.routeId=="string"?n.routeId:null,key:typeof n.key=="string"?n.key:null,operationKind:Ae(n.request,"kind"),documentVersion:Ae(n.request,"documentVersion")}),new Promise((i,c)=>{let u=this.resolveRequestTimeoutMs(t),g=u>0?setTimeout(()=>{let f=this.pending.get(o);f&&(this.pending.delete(o),U("bridge.response",{id:o,kind:t,ok:!1,timedOut:!0}),f.reject(new Error(`Bridge request timed out after ${u}ms: ${t}`)))},u):null;g?.unref?.(),this.pending.set(o,{kind:t,timeout:g,resolve:f=>i(f),reject:c});try{r.send(Y.stringifyMessage(s))}catch(f){let S=L(f,"WebSocket send failed");this.clearPendingRequest(o),c(S),this.cleanupSocket(r,S,"failed")}})}handleAuthHandshakeMessage(t,n,r,o){try{if(Y.parseMessage(t).type==="auth-ok"){o();return}throw new Error("Bridge authentication failed")}catch(s){let i=L(s,"Bridge authentication failed");this.connectAttempt===r&&this.cleanupSocket(n,i,"failed")}}handleMessage(t){let n=Y.parseMessage(t);if(n.type==="event"){for(let o of this.listeners)o(n.payload.event);return}if(n.type!=="response"&&n.type!=="error")return;let r=this.pending.get(n.payload.id);if(r){if(this.clearPendingRequest(n.payload.id),n.type==="error"){U("bridge.response",{id:n.payload.id,kind:r.kind,ok:!1}),r.reject(new Error(n.payload.message));return}U("bridge.response",{id:n.payload.id,kind:r.kind,ok:!0,resultVersion:yt(n.payload.result)}),r.resolve(r.kind==="get-document"?{...n.payload.result,data:ke(n.payload.result.data)}:n.payload.result)}}rejectAll(t){for(let[n,r]of[...this.pending])this.clearPendingRequest(n),r.reject(t)}clearPendingRequest(t){let n=this.pending.get(t);n&&(n.timeout&&clearTimeout(n.timeout),this.pending.delete(t))}resolveRequestTimeoutMs(t){let n=this.options.requestTimeoutMsByKind?.[t];return typeof n=="number"?Math.max(0,n):typeof this.options.requestTimeoutMs=="number"?Math.max(0,this.options.requestTimeoutMs):gt[t]??ht}cleanupSocket(t,n,r){if(this.socket===t&&(this.socket=null),this.connectAttempt?.socket===t){let o=this.connectAttempt;this.connectAttempt=null,o.settled||(o.settled=!0,o.reject(n))}this.connectPromise=null,this.rejectAll(n),this.setConnectionState(r,n.message),t.onopen=null,t.onmessage=null,t.onerror=null,t.onclose=null;try{(t.readyState===mt||t.readyState===he)&&t.close()}catch{}}setConnectionState(t,n){if(this.connectionState===t&&!n)return;this.connectionState=t;let r={state:t,...n?{message:n}:{}};this.options.onConnectionStatus?.(r);for(let o of this.connectionStatusListeners)o(r)}createSocket(t){if(this.options.createSocket)return this.options.createSocket(t);if(typeof WebSocket>"u")throw new Error("Site edit preview bridge requires WebSocket");return new WebSocket(t)}},mt=0,he=1,ht=15e3,gt={"get-source-tree":1e4,"get-source-file":1e4,"resolve-source-location":1e4,execute:6e4,undo:2e4,redo:2e4};function L(e,t){return e instanceof Error?e:new Error(t)}function Ae(e,t){if(!e||typeof e!="object")return null;let r=e[t];return typeof r=="string"||typeof r=="number"?r:null}function yt(e){if(!e||typeof e!="object")return null;let t=e,n=t.data?.resultVersion??t.data?.version??null;return typeof n=="number"?n:null}function Oe(e){return new ge(e)}var ge=class{constructor(t){this.params=t,this.refreshInFlight=null,this.currentDocument=t.initialDocument,this.summaryCache=new Map(Object.entries(t.initialDetails??{}).map(([n,r])=>[n,St(r)])),this.editContextCache=new Map(Object.entries(t.initialDetails??{}).map(([n,r])=>[n,It(r)]))}async getDocument(t){if(t!==this.params.routeId)throw new Error(`Site edit bridge is bound to route ${this.params.routeId}, received ${t}`);return bt(this.currentDocument)&&(this.currentDocument=await this.refreshSnapshot(void 0,"get-document")),{ok:!0,data:this.currentDocument}}async ensureDocumentVersion(t,n){if(t!==this.params.routeId)throw new Error(`Site edit bridge is bound to route ${this.params.routeId}, received ${t}`);let r=await this.refreshSnapshot(n,"ensure-version");if(r.version<n)throw new Error(`Document refresh returned version ${r.version}, expected at least ${n}`);return{ok:!0,data:r}}async getObjectSummary(t,n){let r=this.summaryCache.get(t);if(r)return{ok:!0,data:r};let o=await this.params.client.getObjectSummary(t,n??this.params.routeId);return this.summaryCache.set(t,o.data),o}async getObjectEditContext(t,n){let r=this.editContextCache.get(t);if(r)return{ok:!0,data:r};let o=await this.params.client.getObjectEditContext(t,n??this.params.routeId);return this.editContextCache.set(t,o.data),o}async getClassNameSource(t,n){return this.params.client.getClassNameSource(t,n??this.params.routeId)}async getSourceTree(){return this.params.client.getSourceTree()}async getSourceFile(t){return this.params.client.getSourceFile(t)}async resolveSourceLocation(t){return this.params.client.resolveSourceLocation({...t,routeId:t.routeId??this.params.routeId})}async execute(t){return this.params.client.execute(t.target.kind==="node"&&!t.routeId?{...t,routeId:this.params.routeId}:t)}async undo(){return this.params.client.undo()}async redo(){return this.params.client.redo()}subscribe(t){return this.params.client.subscribe(n=>{if(n.type==="site-edit.document.changed"&&n.routeId===this.params.routeId){this.refreshSnapshot(n.version,"event").catch(()=>{}).finally(()=>t(n));return}t(n)})}async refreshSnapshot(t,n="ensure-version"){if(typeof t=="number"&&this.currentDocument.version>=t)return U("bridge.document-refresh",{routeId:this.params.routeId,minVersion:t,currentVersion:this.currentDocument.version,deduped:!0,skipped:!0,source:n}),this.currentDocument;if(this.refreshInFlight){U("bridge.document-refresh",{routeId:this.params.routeId,minVersion:t,currentVersion:this.currentDocument.version,deduped:!0,source:n});let o=await this.refreshInFlight;if(typeof t!="number"||o.version>=t||this.currentDocument.version>=t)return this.currentDocument}U("bridge.document-refresh",{routeId:this.params.routeId,minVersion:t,currentVersion:this.currentDocument.version,deduped:!1,source:n});let r=this.params.client.getDocument(this.params.routeId).then(o=>(this.currentDocument=o.data,this.clearObjectCaches(),this.currentDocument));this.refreshInFlight=r;try{return await r}finally{this.refreshInFlight===r&&(this.refreshInFlight=null)}}clearObjectCaches(){this.summaryCache.clear(),this.editContextCache.clear()}};function bt(e){return e.version===0&&e.rootKeys.length===0}function Et(e,t,n){switch(t){case"get-document":return{type:"request",payload:{id:e,kind:t,routeId:String(n.routeId)}};case"get-object-summary":return{type:"request",payload:{id:e,kind:t,key:String(n.key),routeId:typeof n.routeId=="string"?n.routeId:void 0}};case"get-object-edit-context":return{type:"request",payload:{id:e,kind:t,key:String(n.key),routeId:typeof n.routeId=="string"?n.routeId:void 0}};case"get-class-name-source":return{type:"request",payload:{id:e,kind:t,key:String(n.key),routeId:typeof n.routeId=="string"?n.routeId:void 0}};case"get-source-tree":return{type:"request",payload:{id:e,kind:t}};case"get-source-file":return{type:"request",payload:{id:e,kind:t,path:String(n.path)}};case"resolve-source-location":return{type:"request",payload:{id:e,kind:t,key:String(n.key),routeId:typeof n.routeId=="string"?n.routeId:void 0}};case"execute":return{type:"request",payload:{id:e,kind:t,request:n.request}};case"undo":case"redo":return{type:"request",payload:{id:e,kind:t}}}}function St(e){return{key:e.key,tag:e.tag,label:e.label,capabilities:{constraints:e.capabilities.constraints},isOpaque:e.isOpaque,provenanceChain:e.provenanceChain?{editMode:e.provenanceChain.editMode,diagnostics:e.provenanceChain.diagnostics}:void 0,ancestors:e.ancestors}}function It(e){return{key:e.key,componentName:e.componentName,sourceFile:e.sourceFile,capabilities:e.capabilities,writeTarget:e.writeTarget,effectiveWriteTarget:e.effectiveWriteTarget,provenanceChain:e.provenanceChain,componentSemantic:e.componentSemantic,textSegments:e.textSegments,boundaryKind:e.boundaryKind,children:e.children,siblings:e.siblings}}var qe="vcp-window-message";function vt(e){return{source:qe,version:1,namespace:e.namespace,channel:e.channel,...e.sessionKey?{sessionKey:e.sessionKey}:{},body:e.body}}function _t(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.source===qe&&t.version===1&&typeof t.namespace=="string"&&typeof t.channel=="string"&&"body"in t}var Me="site-edit",Fe="frame-runtime";function ee(e,t={}){return vt({namespace:Me,channel:Fe,sessionKey:t.sessionKey,body:e})}function Be(e){return!_t(e)||e.namespace!==Me||e.channel!==Fe?!1:typeof e.body?.type=="string"}var Ee="vcp-site-edit:route-ready",Se="vcp-site-edit:bridge-status",Ke=1e3,Ct="data-vcp-ui-component",ze="data-vcp-theme-preview",We="::repeat-item#",ce="components/ui",Rt=new Set(["article","aside","div","footer","form","header","li","main","nav","ol","section","select","table","tbody","tfoot","thead","tr","ul"]),Tt=new Set(["a","button","em","h1","h2","h3","h4","h5","h6","label","p","small","span","strong"]);function ue(e,t=""){let n=jt(t),r=n&&(e===n||e.startsWith(`${n}/`))?e.slice(n.length)||"/":e,o=r.startsWith("/")?r:`/${r}`;return o==="/"?"/":o.replace(/\/+$/,"")}function xt(e,t){if(e.__VCP_SITE_EDIT_VERSION_LOGGED__)return;let n=e.console?.info;typeof n=="function"&&(e.__VCP_SITE_EDIT_VERSION_LOGGED__=!0,n.call(e.console,"[VCP Site Edit] runtime loaded",{bridge:t.versions?.bridge??"unknown",contracts:t.versions?.contracts??"unknown",documentVersion:t.documentVersion,engine:t.versions?.engine??"unknown",routeId:t.routeId}))}function Dt(e,t={}){if(t.explicit_ws_url)return t.explicit_ws_url.startsWith("/")?`${e.location.protocol==="https:"?"wss:":"ws:"}//${e.location.host}${t.explicit_ws_url}`:t.explicit_ws_url;let n=e.location.protocol==="https:"?"wss:":"ws:",r=t.port?`${e.location.hostname}:${t.port}`:e.location.host;return`${n}//${r}${t.path??"/__vcp/site-edit/bridge"}`}async function Vn(e=window,t={}){if(e.__VCP_SITE_EDIT_AUTO_BOOTSTRAP__?.started)return;let n={activeClient:null,cleanupFrameRuntime:(()=>{}),retryTimer:void 0,routeSequence:0,currentDocument:null,currentEntriesByKey:new Map,unsubscribeDocument:void 0,unsubscribeConnectionStatus:void 0,unbindRouteChange:void 0},r=t.create_client??(p=>new ie({url:p,authKey:t.bridge_session_key})),o=t.schedule_after_navigation??Mt,s=Dt(e,{explicit_ws_url:t.explicit_ws_url,port:t.ws_port,path:t.wsPath||"/__vcp/site-edit/bridge"}),i=()=>{n.retryTimer&&(e.clearTimeout(n.retryTimer),n.retryTimer=void 0)},c=p=>{Bt(e,p)},u=p=>{n.currentDocument=p,n.currentEntriesByKey=new Map((p?.entries??[]).map(h=>[h.key,h]))},g=()=>{n.unsubscribeConnectionStatus?.(),n.unsubscribeConnectionStatus=void 0,n.unsubscribeDocument?.(),n.unsubscribeDocument=void 0},f=(p,h)=>h===n.routeSequence&&p===ue(e.location.pathname,t.basePath||""),S=async(p,h)=>{let _=e.__VCP_SITE_EDIT__;if(!_)return null;let C=await _.getDocument(p);return f(p,h)&&u(C.data),C.data},v=()=>{g(),u(null),delete e.__VCP_SITE_EDIT__;let p=n.activeClient;n.activeClient=null,p?.disconnect()},I=p=>p===e.__VCP_SITE_EDIT_AUTO_BOOTSTRAP__?.routeId&&!!e.__VCP_SITE_EDIT__&&!!(n.currentDocument&&Wt(n.currentDocument,p))&&Kt(n.activeClient),P=p=>Math.min(Ke*2**Math.max(0,p),8e3),k=(p,h,_)=>{i();let C=P(_);c({state:"reconnecting",routeId:p,attempt:_,retryInMs:C,messageKey:"studio.status.previewBridgeConnecting"}),n.retryTimer=e.setTimeout(()=>{h===n.routeSequence&&H(_+1).catch(O=>{let T=ue(e.location.pathname,t.basePath||"");if(p===T){if(ae(O)){c({state:"reload-required",routeId:p,attempt:_,messageKey:"studio.errors.previewBridgeReloadRequired"});return}k(p,n.routeSequence,_+1)}})},C)},N=(p,h,_)=>{if(!f(p,h)||n.activeClient===null)return;let C=n.activeClient;g(),u(null),delete e.__VCP_SITE_EDIT__,n.activeClient=null,C?.disconnect(),k(p,h,0)},F=p=>{let h=ue(e.location.pathname,t.basePath||""),_=n.routeSequence;if(!(!f(h,_)||n.activeClient===null)){if(ae(p)){v(),i(),c({state:"reload-required",routeId:h,attempt:0,messageKey:"studio.errors.previewBridgeReloadRequired"});return}Je(p)&&N(h,_,{state:"failed",message:_e(p,"Site edit bridge request failed")})}};n.cleanupFrameRuntime=kt(e,{getCurrentDocument:()=>n.currentDocument,getDocumentEntry:p=>n.currentEntriesByKey.get(p)??null,onBridgeRequestError:p=>{F(p)}});let X=async()=>H(0),H=async p=>{let h=ue(e.location.pathname,t.basePath||"");if(I(h))return;let _=n.routeSequence+=1;i(),v(),c({state:p>0?"reconnecting":"connecting",routeId:h,attempt:p,messageKey:p>0?"studio.status.previewBridgeConnecting":"studio.status.previewLoading"});let C=r(s),O=!1;n.activeClient=C,n.unsubscribeConnectionStatus=C.subscribeConnectionStatus?.(T=>{O&&(T.state==="closed"||T.state==="failed")&&N(h,_,T)});try{if(await C.connect(),!f(h,_)){C.disconnect();return}e.__VCP_SITE_EDIT__=Oe({routeId:h,client:C,initialDocument:Nt(h)}),n.activeClient=C,n.unsubscribeDocument=e.__VCP_SITE_EDIT__.subscribe(oe=>{oe.type==="site-edit.document.changed"&&oe.routeId===h&&S(h,_).catch(()=>{})}),e.__VCP_SITE_EDIT_AUTO_BOOTSTRAP__.routeId=h;let T=await S(h,_);if(!f(h,_)){C.disconnect();return}O=!0,c({state:"ready",routeId:h,attempt:p,messageKey:"studio.status.previewReady"}),xt(e,{documentVersion:T?.version??0,routeId:h,versions:t.runtime_versions}),Ft(e,{routeId:h,version:T?.version??0})}catch(T){if(g(),n.activeClient===C&&(n.activeClient=null),C.disconnect(),u(null),delete e.__VCP_SITE_EDIT__,!f(h,_))return;throw c({state:ae(T)?"reload-required":"failed",routeId:h,attempt:p,messageKey:ae(T)?"studio.errors.previewBridgeReloadRequired":"studio.errors.previewBridgeDisconnected"}),T}},J=()=>{i(),n.retryTimer=e.setTimeout(()=>{H(1).catch(()=>J())},Ke)},w=()=>{o(()=>{X().catch(()=>J())})};if(e.__VCP_SITE_EDIT_AUTO_BOOTSTRAP__={started:!0,syncRoute:X,cleanup:()=>{i(),n.routeSequence+=1,n.unbindRouteChange?.(),n.cleanupFrameRuntime(),v(),delete e.__VCP_SITE_EDIT_AUTO_BOOTSTRAP__}},n.unbindRouteChange=qt(e,w),t.defer_initial_sync){w();return}await X()}function Nt(e){return{siteId:"preview",snapshotId:"preview",routeId:e,version:0,rootKeys:[],entries:[]}}function kt(e=window,t={}){let n=null,r=null,o=null,s=null,i=null,c=null,u=null,g=null,f=new Map,S=typeof t.expectedSessionKey=="string"&&t.expectedSessionKey.length>0?t.expectedSessionKey:null,v=()=>{n?.(),n=null},I=()=>{r?.(),r=null,o?.(),o=null},P=(d,l,a)=>{let x=s?.sessionKey!==d||s?.sourceWindow!==l||s?.targetOrigin!==a;s={sessionKey:d,sourceWindow:l,targetOrigin:a},x&&(u=null,g=null)},k=(d,l)=>{let a=e.parent&&e.parent!==e?e.parent:null;return!a||l!==a?!1:!S||d===S},N=()=>{for(let d of f.values())d();f.clear()},F=d=>JSON.stringify([d.routeId,d.version]),X=()=>!c||c.state==="ready",H=d=>JSON.stringify([d.state,d.routeId??null,d.attempt??null,d.retryInMs??null,d.messageKey??null]),J=d=>{if(!X())return;let l=F(d);u!==l&&(o?.(),o=null,O({kind:"route-ready",payload:{routeId:d.routeId,version:d.version}}),s&&(u=l))},w=d=>{let l=H(d);g!==l&&(d.state!=="ready"&&(u=null,i=null),O({kind:"bridge-status",payload:d}),s&&(g=l))},p=d=>{i=d,J(d)},h=d=>{c=d,w(d)},_=()=>{i&&J(i)},C=()=>{c&&w(c)},O=d=>{s&&s.sourceWindow.postMessage(ee({type:"event",...d},{sessionKey:s.sessionKey}),s.targetOrigin)},T=(d,l,a,x)=>{let R=pe(e.document,l.clientX,l.clientY,t.getCurrentDocument?.()??null),D=R?M(R,a==="full"?W(e.document,R,t.getCurrentDocument?.()??null):je(e.document,R,t.getCurrentDocument?.()??null),t.getDocumentEntry,a):null;x&&D&&(d==="pointer-click"||d==="pointer-double-click")&&(x.preventDefault(),x.stopPropagation(),typeof x.stopImmediatePropagation=="function"&&x.stopImmediatePropagation()),O({kind:d,payload:{clientX:l.clientX,clientY:l.clientY,buttons:Number(l.buttons??0),hit:D}})},oe=(d,l,a)=>{I(),s={sessionKey:d,sourceWindow:l,targetOrigin:a};let x=Rn(e.document),R=null,D=null,y=()=>{D=null;let m=R;R=null,m&&T("pointer-move",m,"summary")},q=m=>{R={clientX:Number(m.clientX),clientY:Number(m.clientY),buttons:Number(m.buttons)},D===null&&(D=Xe(e,y))},j=m=>{T("pointer-down",{clientX:Number(m.clientX),clientY:Number(m.clientY),buttons:Number(m.buttons)},"full",m)},G=m=>{T("pointer-up",{clientX:Number(m.clientX),clientY:Number(m.clientY),buttons:Number(m.buttons)},"summary",m)},V=m=>{T("pointer-cancel",{clientX:Number(m.clientX),clientY:Number(m.clientY),buttons:Number(m.buttons)},"summary",m)},$=m=>{T("pointer-click",{clientX:Number(m.clientX),clientY:Number(m.clientY),buttons:Number(m.buttons)},"full",m)},Q=m=>{T("pointer-double-click",{clientX:Number(m.clientX),clientY:Number(m.clientY),buttons:Number(m.buttons)},"full",m)},Z=()=>{O({kind:"scroll",payload:{metrics:de(e)}})};e.document.addEventListener("pointerdown",j,!0),e.document.addEventListener("pointermove",q,{passive:!0,capture:!0}),e.document.addEventListener("pointerup",G,!0),e.document.addEventListener("pointercancel",V,!0),e.document.addEventListener("click",$,!0),e.document.addEventListener("dblclick",Q,!0),e.addEventListener("scroll",Z,{passive:!0}),r=()=>{D!==null&&(He(e,D),D=null),R=null,x(),e.document.removeEventListener("pointerdown",j,!0),e.document.removeEventListener("pointermove",q,!0),e.document.removeEventListener("pointerup",G,!0),e.document.removeEventListener("pointercancel",V,!0),e.document.removeEventListener("click",$,!0),e.document.removeEventListener("dblclick",Q,!0),e.removeEventListener("scroll",Z)}},xe=d=>{let l=d.detail;l?.routeId&&p(l)},De=d=>{let l=d.detail;l?.state&&h(l)},Ne=d=>{let l=d.data;if(!Be(l)||l.body.type!=="request"||l.body.kind!=="apply-node-patch"&&l.body.kind!=="get-hit-by-ref"&&l.body.kind!=="get-path-by-ref"&&l.body.kind!=="get-scroll-metrics"&&l.body.kind!=="scroll-to"&&l.body.kind!=="scroll-by"&&l.body.kind!=="set-interaction-mode"&&l.body.kind!=="set-theme-override"&&l.body.kind!=="clear-theme-override"&&l.body.kind!=="get-theme-variables"&&l.body.kind!=="compute-drop-target-at-point"&&l.body.kind!=="observe-node-bounds"&&l.body.kind!=="clear-node-bounds-observer"&&l.body.kind!=="start-text-edit-at-point"&&l.body.kind!=="hit-test-at-point"&&!Ve(l.body))return;let a=l.body,x=typeof l.sessionKey=="string"?l.sessionKey:null,R=d.source,D=d.origin;if(!x||!D||!R||typeof R.postMessage!="function"||!k(x,R))return;if(s){if(s.sourceWindow!==R||s.targetOrigin!==D)return;s.sessionKey!==x&&(v(),I(),N(),s=null)}P(x,R,D),C(),_();let y=q=>{let j=typeof a.id=="string"?a.id:"unknown";R.postMessage(ee({id:j,...q},{sessionKey:x}),D)};try{if(Ve(a)){Pt({message:a,sendEvent:b=>{R.postMessage(ee({type:"event",...b},{sessionKey:x}),D)},sendResponse:y,subscriptions:f,getCurrentDocument:t.getCurrentDocument,onBridgeRequestError:t.onBridgeRequestError,windowLike:e});return}if(a.kind==="apply-node-patch"){let b=z(e.document,a.payload.ref,t.getCurrentDocument?.()??null);if(!b){y({type:"response",ok:!1,error:"No editable element found for patch target"});return}let E=a.payload.preview,A=E?dn(E.sessionId,a.payload.ref):null;if(A&&E){let se=te.get(A)??-1;if(E.revision<se){y({type:"response",ok:!0,result:{applied:!1,appliedRevision:E.revision,stale:!0,latestRevision:se}});return}if(E.revision===se){y({type:"response",ok:!0,result:{applied:!1,appliedRevision:E.revision,duplicate:!0,latestRevision:se}});return}}if(an(b,a.payload.patch),A&&E&&pn(A,E.revision),E?.responseDetail==="none"){y({type:"response",ok:!0,result:{applied:!0,appliedRevision:E.revision}});return}y({type:"response",ok:!0,result:M(b,W(e.document,b,t.getCurrentDocument?.()??null),t.getDocumentEntry,E?.responseDetail??"full")});return}if(a.kind==="get-hit-by-ref"){let b=z(e.document,a.payload.ref,t.getCurrentDocument?.()??null);if(!b){y({type:"response",ok:!1,error:"No editable element found for hit target"});return}y({type:"response",ok:!0,result:M(b,W(e.document,b,t.getCurrentDocument?.()??null),t.getDocumentEntry,"full")});return}if(a.kind==="get-path-by-ref"){let b=z(e.document,a.payload.ref,t.getCurrentDocument?.()??null);if(!b){y({type:"response",ok:!1,error:"No editable element found for path target"});return}let E=[],A=b;for(;A;)A.getAttribute("data-vcp-edit-key")&&E.push(M(A,W(e.document,A,t.getCurrentDocument?.()??null),t.getDocumentEntry,"full")),A=A.parentElement;y({type:"response",ok:!0,result:E.reverse()});return}if(a.kind==="get-scroll-metrics"){y({type:"response",ok:!0,result:de(e)});return}if(a.kind==="scroll-to"){let b=Number(a.payload.x),E=Number(a.payload.y);if(!Number.isFinite(b)||!Number.isFinite(E)){y({type:"response",ok:!1,error:"Invalid scroll position"});return}e.scrollTo({left:b,top:E}),y({type:"response",ok:!0,result:de(e)});return}if(a.kind==="scroll-by"){let b=Number(a.payload.deltaX),E=Number(a.payload.deltaY);if(!Number.isFinite(b)||!Number.isFinite(E)){y({type:"response",ok:!1,error:"Invalid scroll delta"});return}e.scrollBy({left:b,top:E}),y({type:"response",ok:!0,result:{...de(e),scrolled:!0}});return}if(a.kind==="set-interaction-mode"){a.payload.enabled?oe(x,R,D):s?.sourceWindow===R&&s.targetOrigin===D&&s.sessionKey===x&&I(),y({type:"response",ok:!0,result:{interactionEnabled:a.payload.enabled}});return}if(a.kind==="set-theme-override"){fn(e.document,a.payload),y({type:"response",ok:!0,result:{themeOverrideApplied:!0}});return}if(a.kind==="clear-theme-override"){mn(e.document),y({type:"response",ok:!0,result:{themeOverrideCleared:!0}});return}if(a.kind==="get-theme-variables"){y({type:"response",ok:!0,result:hn(e.document,a.payload.names)});return}if(a.kind==="compute-drop-target-at-point"){let b=Number(a.payload?.x),E=Number(a.payload?.y);if(!Number.isFinite(b)||!Number.isFinite(E)){y({type:"response",ok:!1,error:"Invalid drop target point"});return}y({type:"response",ok:!0,result:on(e,b,E,a.payload.dragKind,a.payload.movingRef,t.getCurrentDocument?.()??null,t.getDocumentEntry)});return}if(a.kind==="observe-node-bounds"){let b=a.payload.ref;if(!b){y({type:"response",ok:!1,error:"Missing bounds observer target"});return}let E=z(e.document,b,t.getCurrentDocument?.()??null);if(!E){y({type:"response",ok:!1,error:"No editable element found for bounds observer target"});return}o?.(),o=nn(e,E,b,t.getDocumentEntry,A=>O({kind:"node-bounds-change",payload:{hit:A}})),y({type:"response",ok:!0,result:{observing:!0}}),O({kind:"node-bounds-change",payload:{hit:M(E,b,t.getDocumentEntry,"summary")}});return}if(a.kind==="clear-node-bounds-observer"){o?.(),o=null,y({type:"response",ok:!0,result:{cleared:!0}});return}if(a.kind!=="hit-test-at-point"&&a.kind!=="start-text-edit-at-point")return;let q=Number(a.payload?.x),j=Number(a.payload?.y);if(!Number.isFinite(q)||!Number.isFinite(j)){y({type:"response",ok:!1,error:"Invalid text edit point"});return}let G=a.kind==="hit-test-at-point"?pe(e.document,q,j,t.getCurrentDocument?.()??null):$t(e.document,q,j,t.getCurrentDocument?.()??null,t.getDocumentEntry);if(!G){y({type:"response",ok:!1,error:a.kind==="hit-test-at-point"?"No editable element at point":"No editable text element at point"});return}let V=a.kind==="start-text-edit-at-point"?G:null,$=a.kind==="hit-test-at-point"?G:V.element,Q=a.payload.detailLevel??"full",Z=Q==="full"?W(e.document,$,t.getCurrentDocument?.()??null):je(e.document,$,t.getCurrentDocument?.()??null),m=V&&typeof V.textSegmentIndex=="number"?{...Z,textSegmentIndex:V.textSegmentIndex}:Z,it=M($,m,t.getDocumentEntry,Q);if(a.kind==="hit-test-at-point"){y({type:"response",ok:!0,result:it});return}v(),n=En(e,$,m,b=>{R.postMessage(ee({type:"event",...b},{sessionKey:x}),D)},V?{textNode:V.textNode}:void 0),y({type:"response",ok:!0,result:{ref:m}})}catch(q){y({type:"response",ok:!1,error:q instanceof Error?q.message:"Failed to start text edit"})}};return e.addEventListener("message",Ne),e.addEventListener(Ee,xe),e.addEventListener(Se,De),()=>{v(),I(),s=null,N(),e.removeEventListener("message",Ne),e.removeEventListener(Ee,xe),e.removeEventListener(Se,De)}}function Ve(e){let t=e.kind;return t==="bridge-get-document"||t==="bridge-ensure-document-version"||t==="bridge-get-object-summary"||t==="bridge-get-object-edit-context"||t==="bridge-get-class-name-source"||t==="bridge-get-source-tree"||t==="bridge-get-source-file"||t==="bridge-resolve-source-location"||t==="bridge-execute"||t==="bridge-undo"||t==="bridge-redo"||t==="bridge-subscribe"||t==="bridge-unsubscribe"}async function Pt({message:e,sendEvent:t,sendResponse:n,subscriptions:r,getCurrentDocument:o,onBridgeRequestError:s,windowLike:i}){let c=i.__VCP_SITE_EDIT__;if(!c){n({type:"response",ok:!1,error:"Site edit bridge is not ready in preview frame"});return}try{switch(e.kind){case"bridge-get-document":n({type:"response",ok:!0,result:await c.getDocument(e.payload.routeId)});return;case"bridge-ensure-document-version":if(!Number.isFinite(Number(e.payload.minVersion))){n({type:"response",ok:!1,error:"Invalid document version"});return}n({type:"response",ok:!0,result:c.ensureDocumentVersion?await c.ensureDocumentVersion(e.payload.routeId,Number(e.payload.minVersion)):await c.getDocument(e.payload.routeId)});return;case"bridge-get-object-summary":n({type:"response",ok:!0,result:await c.getObjectSummary(e.payload.key,e.payload.routeId)});return;case"bridge-get-object-edit-context":n({type:"response",ok:!0,result:await c.getObjectEditContext(e.payload.key,e.payload.routeId)});return;case"bridge-get-class-name-source":{let u=await c.getClassNameSource(e.payload.key,e.payload.routeId);n({type:"response",ok:!0,result:At(u,e.payload.key,i.document,o?.()??null)});return}case"bridge-get-source-tree":n({type:"response",ok:!0,result:await c.getSourceTree()});return;case"bridge-get-source-file":n({type:"response",ok:!0,result:await c.getSourceFile({path:e.payload.path})});return;case"bridge-resolve-source-location":n({type:"response",ok:!0,result:await c.resolveSourceLocation({key:e.payload.key,routeId:e.payload.routeId})});return;case"bridge-execute":n({type:"response",ok:!0,result:await c.execute(e.payload.request)});return;case"bridge-undo":n({type:"response",ok:!0,result:await c.undo()});return;case"bridge-redo":n({type:"response",ok:!0,result:await c.redo()});return;case"bridge-subscribe":{let u=e.payload.subscriptionId;r.get(u)?.();let g=c.subscribe(f=>{t({kind:"bridge-event",payload:{event:f,subscriptionId:u}})});r.set(u,g),n({type:"response",ok:!0,result:{subscribed:!0}});return}case"bridge-unsubscribe":{let u=e.payload.subscriptionId;r.get(u)?.(),r.delete(u),n({type:"response",ok:!0,result:{unsubscribed:!0}});return}}}catch(u){s?.(u,e),n({type:"response",ok:!1,error:Vt(u)})}}function At(e,t,n,r){if(!e.ok||!e.data.styleContext)return e;let o=z(n,{key:t},r),s=o?Ot(o):null;return s?{...e,data:{...e.data,styleContext:{...e.data.styleContext,computedStyle:{...e.data.styleContext.computedStyle??{},...s}}}}:e}function Ot(e){let t=e.ownerDocument.defaultView;if(!t)return null;let n=t.getComputedStyle(e);return{color:n.color,backgroundColor:n.backgroundColor,borderColor:n.borderColor}}function qt(e,t){let n=e.history.pushState,r=e.history.replaceState,o=()=>t();return e.history.pushState=function(...i){let c=n.apply(this,i);return t(),c},e.history.replaceState=function(...i){let c=r.apply(this,i);return t(),c},e.addEventListener("popstate",o),()=>{e.history.pushState=n,e.history.replaceState=r,e.removeEventListener("popstate",o)}}function Mt(e){if(typeof requestAnimationFrame=="function"){requestAnimationFrame(()=>requestAnimationFrame(e));return}setTimeout(e,0)}function Xe(e,t){return typeof e.requestAnimationFrame=="function"?e.requestAnimationFrame(t):e.setTimeout(t,0)}function He(e,t){if(typeof e.cancelAnimationFrame=="function"){e.cancelAnimationFrame(t);return}e.clearTimeout(t)}function Ft(e,t){e.dispatchEvent(new CustomEvent(Ee,{detail:t}))}function Bt(e,t){e.dispatchEvent(new CustomEvent(Se,{detail:t}))}function Kt(e){return e?e.getConnectionState?e.getConnectionState()==="open":!0:!1}function Wt(e,t){return e.routeId===t}function _e(e,t){return e instanceof Error&&e.message?e.message:typeof e=="string"&&e?e:t}function Je(e){let t=_e(e,"");return/websocket|readyState|not open|disconnected|bridge request timed out|network|econnreset|broken pipe|socket closed/i.test(t)}function Vt(e){let t=_e(e,"Site edit bridge request failed");return/bridge request timed out/i.test(t)?"Site edit bridge request timed out":Je(t)?"Site edit bridge disconnected":t}function ae(e){let t=e instanceof Error?e.message:typeof e=="string"?e:"";return/bridge key|session|unauthorized|forbidden|expired/i.test(t)}function jt(e){let t=e.trim();return!t||t==="/"?"":(t.startsWith("/")?t:`/${t}`).replace(/\/+$/,"")}function Ce(e){return Rt.has(Qe(e))}function Ut(e){return Tt.has(Qe(e))}function we(e){return e.operationSummary?{canUpdateText:e.operationSummary.canUpdateText,canInsertChild:e.operationSummary.canInsertChild,canMove:e.operationSummary.canMove,canRemove:e.operationSummary.canRemove}:e.fallbackMode!=="preview"?{canUpdateText:!1,canInsertChild:!1,canMove:!1,canRemove:!1}:{canUpdateText:Ut(e.tagName),canInsertChild:Ce(e.tagName),canMove:!1,canRemove:!1}}function Qe(e){return e?.trim().toLowerCase()??""}function $t(e,t,n,r,o){let s=pe(e,t,n,r),i=Ze(s);if(!i)return null;let c=i.getAttribute("data-vcp-edit-key")??"",u=W(e,i,r),g=o?.(u.key)??o?.(c);if(!we({operationSummary:g?.operationSummary,tagName:i.tagName,fallbackMode:"preview"}).canUpdateText)return null;if((g?.childKeys.length??0)===0)return{element:i};let S=Yt(e,t,n,i);if(!S)return null;let v=zt(i,S);return v===null?null:{element:i,textNode:S,textSegmentIndex:v}}function Yt(e,t,n,r){let o=Gt(e,t,n);return!o||o.parentElement!==r?null:o}function Gt(e,t,n){let r=e,s=r.caretPositionFromPoint?.(t,n)?.offsetNode??null;if(Ie(s))return s;let c=r.caretRangeFromPoint?.(t,n)?.startContainer??null;return Ie(c)?c:null}function zt(e,t){let n=0;for(let r of Array.from(e.childNodes))if(!(!Ie(r)||(r.textContent??"").trim().length===0)){if(r===t)return n;n+=1}return null}function Ie(e){return e?.nodeType===3}function pe(e,t,n,r=null){let o=typeof e.elementsFromPoint=="function"?e.elementsFromPoint(t,n):[e.elementFromPoint(t,n)].filter(Boolean);for(let s of o){let i=Ze(s),c=i?.getAttribute("data-vcp-edit-key")??"";if(i&&Qt(i,r,c))return i}return null}function Ze(e){let t=e,n=null;for(;t;){let r=t.getAttribute("data-vcp-edit-key")??"";if(r){if(Re(t))return n??t;!Xt(r)&&!n&&(n=t)}t=t.parentElement}return n}function Re(e){return e.getAttribute(Ct)!==null}function Xt(e){return Ht(e.split("::")[0]??"")}function Ht(e){if(!e)return!1;let t=Jt(e);return t===ce||t.startsWith(`${ce}/`)||t.includes(`/${ce}/`)||t.endsWith(`/${ce}`)}function Jt(e){let n=(e.split("?")[0]??e).replace(/\\/g,"/").replace(/^\.\//,""),r=[];for(let o of n.split("/"))if(!(!o||o===".")){if(o===".."){r.pop();continue}r.push(o)}return r.join("/")}function W(e,t,n){let r=t.getAttribute("data-vcp-edit-key")??"",o=Le(tt(Array.from(e.querySelectorAll(`[data-vcp-edit-key="${st(r)}"]`))),n,r);if(o.length<=1)return{key:Ue(n,r,0)};let s=o.indexOf(t);return s>=0?{key:Ue(n,r,s),instanceIndex:s,instanceCount:o.length}:{key:r}}function je(e,t,n){return W(e,t,n)}function z(e,t,n){let r=re(t.key)??t.key,o=Le(tt(Array.from(e.querySelectorAll(`[data-vcp-edit-key="${st(r)}"]`))),n,t.key);if(o.length===0)return null;let s=typeof t.instanceIndex=="number"&&t.instanceIndex>=0&&t.instanceIndex<o.length?t.instanceIndex:null,i=(re(t.key)??t.key)!==t.key;if(s!==null&&!i)return o[s]??null;let c=wt(n,t.key);return c!==null&&c>=0&&c<o.length?o[c]??null:s!==null?o[s]??null:o[0]??null}function Ue(e,t,n){return Te(e,t)[n]?.key??t}function wt(e,t){let n=re(t);if(!n)return null;let o=Te(e,n).findIndex(s=>s.key===t);return o>=0?o:null}function Te(e,t){return(e?.entries??[]).filter(n=>(re(n.key)??n.key)===t)}function Le(e,t,n){let r=et(t,n);return r?e.filter(o=>o.tagName.toLowerCase()===r):e}function Qt(e,t,n){let r=et(t,n);return!r||e.tagName.toLowerCase()===r}function et(e,t){let n=re(t)??t,o=(e?.entries.find(s=>s.key===t)??Te(e,n)[0])?.tag.trim();return!o||o!==o.toLowerCase()?null:o}var Zt=2,Lt=4;function tt(e){return[...e].sort((t,n)=>{if(t===n)return 0;let r=typeof t.compareDocumentPosition=="function"?t.compareDocumentPosition(n):0;return(r&Lt)!==0?-1:(r&Zt)!==0?1:0})}function re(e){if(typeof e!="string"||e.length===0)return e??null;let t=e;for(;;){let n=t.lastIndexOf(We);if(n<0)break;let r=Number(t.slice(n+We.length));if(!Number.isInteger(r)||r<0)return e;t=t.slice(0,n)}return t}function en(e){let n=e.ownerDocument?.defaultView?.getComputedStyle(e),r=o=>{let s=Number.parseFloat(o??"");return Number.isFinite(s)&&s>0?s:0};return{marginTop:r(n?.marginTop),marginRight:r(n?.marginRight),marginBottom:r(n?.marginBottom),marginLeft:r(n?.marginLeft),paddingTop:r(n?.paddingTop),paddingRight:r(n?.paddingRight),paddingBottom:r(n?.paddingBottom),paddingLeft:r(n?.paddingLeft),borderTopWidth:r(n?.borderTopWidth),borderRightWidth:r(n?.borderRightWidth),borderBottomWidth:r(n?.borderBottomWidth),borderLeftWidth:r(n?.borderLeftWidth),columnGap:r(n?.columnGap),rowGap:r(n?.rowGap)}}function tn(e){return Array.from(e.children).filter(t=>typeof t.getBoundingClientRect=="function").map(t=>ve(t.getBoundingClientRect())).filter(t=>t.width>0&&t.height>0)}function M(e,t,n,r="full"){let o=e.getBoundingClientRect(),s=n?.(t.key)??null,i=e.tagName.toLowerCase(),c=fe(e),u=r==="full"?{textPreview:e.textContent?.trim().slice(0,80),dataset:Object.fromEntries(Object.entries(e.dataset).map(([I,P])=>[I,P??""])),attributes:Object.fromEntries(e.getAttributeNames().map(I=>[I,e.getAttribute(I)??""]))}:{},g=we({operationSummary:s?.operationSummary,tagName:i,fallbackMode:"preview"}),f=Re(e),S=!!(s&&/^[A-Z]/.test(s.tag)),v=!s||!S;return{ref:t,key:t.key,detailLevel:r,tagName:i,...s?{sourceKind:S?"component-call":"jsx"}:{},...S&&s?.tag?{componentName:s.tag}:{},...s?.parentKey?{parentKey:s.parentKey}:{},...u,runtimeFlags:{selectable:!0,movable:g.canMove,removable:g.canRemove,textEditable:g.canUpdateText,container:f?!1:(s?.childKeys.length??0)>0||g.canInsertChild||v&&Ce(i)},layout:c,rect:{top:o.top,left:o.left,width:o.width,height:o.height},childRects:tn(e),spacing:en(e)}}function nn(e,t,n,r,o){let s=ve(t.getBoundingClientRect()),i=null,c=()=>{i===null&&(i=Xe(e,u))},u=()=>{if(i=null,"isConnected"in t&&!t.isConnected)return;let P=ve(t.getBoundingClientRect());rn(s,P)&&(s=P,o(M(t,n,r,"summary")))},g=e.ResizeObserver,f=typeof g=="function"?new g(c):null;f?.observe(t);let S=e.MutationObserver,v=typeof S=="function"?new S(c):null;v?.observe(e.document.documentElement,{attributes:!0,childList:!0,characterData:!0,subtree:!0}),e.addEventListener("resize",c,{passive:!0});let I=e.visualViewport;return I?.addEventListener?.("resize",c,{passive:!0}),e.document.addEventListener("load",c,!0),()=>{i!==null&&(He(e,i),i=null),f?.disconnect(),v?.disconnect(),e.removeEventListener("resize",c),I?.removeEventListener?.("resize",c),e.document.removeEventListener("load",c,!0)}}function ve(e){return{top:e.top,left:e.left,width:e.width,height:e.height}}function rn(e,t){return Math.abs(e.top-t.top)>.5||Math.abs(e.left-t.left)>.5||Math.abs(e.width-t.width)>.5||Math.abs(e.height-t.height)>.5}function on(e,t,n,r,o,s,i){let c=e.document,u=pe(c,t,n,s);if(!u)return{anchorHit:null,targetParentHit:null,relation:"none",rejectionReason:"no-editable-hit"};let g=o?z(c,o,s):null;if(g&&Ge(u,g))return le(c,u,"self-or-descendant",s,i);let f=null,S=!1,v=u,I=u.parentElement;for(;I;){if(I.getAttribute("data-vcp-edit-key")){if(g&&Ge(I,g))return le(c,u,"self-or-descendant",s,i);let k=$e(I,r,i);if(k==="accept"){f={child:v,targetParent:I};break}k==="blocked"&&(S=!0),v=I}I=I.parentElement}let P=$e(u,r,i);if(P==="accept"){if(f){let k=Ye(f.child,f.targetParent,t,n,"edge");if(k)return ye(c,f.child,f.targetParent,k,s,i)}return ye(c,u,u,sn(u,t,n),s,i)}if(f){let k=Ye(f.child,f.targetParent,t,n,"nearest");return ye(c,f.child,f.targetParent,k??"after",s,i)}return P==="blocked"||S?le(c,u,"operation-boundary-blocked",s,i):le(c,u,"no-accepting-parent",s,i)}function le(e,t,n,r,o){return{anchorHit:M(t,W(e,t,r),o,"summary"),targetParentHit:null,relation:"none",rejectionReason:n}}function ye(e,t,n,r,o,s){let i=M(t,W(e,t,o),s,"summary"),c=M(n,W(e,n,o),s,"summary"),u=fe(n).indicatorOrientation,g=r==="append"||r==="prepend"?cn(n.getBoundingClientRect(),u,r):un(t.getBoundingClientRect(),u,r);return{anchorHit:i,targetParentHit:c,relation:r,indicatorOrientation:u,indicatorBounds:g}}function $e(e,t,n){if(Re(e))return"not-container";let r=e.getAttribute("data-vcp-edit-key")??"",o=n?.(r)??null;if(o)return o.operationSummary.canInsertChild===!0?"accept":o.childKeys.length>0?"blocked":"not-container";let s=e.tagName.toLowerCase();return Ce(s)?"accept":"not-container"}function Ye(e,t,n,r,o){let s=fe(t).indicatorOrientation,i=e.getBoundingClientRect(),c=s==="vertical"?i.width>0?(n-i.left)/i.width:.5:i.height>0?(r-i.top)/i.height:.5;return o==="edge"&&c>=.25&&c<=.75?null:c<.5?"before":"after"}function sn(e,t,n){let r=fe(e).indicatorOrientation,o=e.getBoundingClientRect();return(r==="vertical"?o.width>0?(t-o.left)/o.width:.5:o.height>0?(n-o.top)/o.height:.5)<.5?"prepend":"append"}function fe(e){let n=e.ownerDocument?.defaultView?.getComputedStyle(e),r=n?.display??"",o=n?.flexDirection,s=n?.gridAutoFlow,i="horizontal";return r==="flex"||r==="inline-flex"?i=(o??"row").startsWith("row")?"vertical":"horizontal":(r==="grid"||r==="inline-grid")&&(i=(s??"row").includes("column")?"vertical":"horizontal"),{display:r,...o?{flexDirection:o}:{},...s?{gridAutoFlow:s}:{},indicatorOrientation:i}}function cn(e,t,n){if(t==="vertical")return{left:n==="prepend"?e.left:e.left+e.width-3,top:e.top,width:3,height:e.height};let r=n==="prepend"?e.top:e.top+e.height-3;return{left:e.left,top:r,width:e.width,height:3}}function un(e,t,n){if(t==="vertical")return{left:n==="before"?e.left:e.left+e.width-3,top:e.top,width:3,height:e.height};let r=n==="before"?e.top:e.top+e.height-3;return{left:e.left,top:r,width:e.width,height:3}}function Ge(e,t){let n=e;for(;n;){if(n===t)return!0;n=n.parentElement}return!1}function de(e){let t=e.document.documentElement,n=e.document.body;return{scrollX:K(e.scrollX),scrollY:K(e.scrollY),scrollWidth:Math.max(K(t?.scrollWidth),K(n?.scrollWidth),K(e.innerWidth)),scrollHeight:Math.max(K(t?.scrollHeight),K(n?.scrollHeight),K(e.innerHeight)),viewportWidth:K(e.innerWidth),viewportHeight:K(e.innerHeight)}}function an(e,t){Object.entries(t.attributes??{}).forEach(([r,o])=>{if(o===null){e.removeAttribute(r);return}e.setAttribute(r,o)}),typeof t.className=="string"&&(e.className=t.className);let n=new Set(t.styleDeclarations?.map(r=>r.property)??[]);Object.entries(t.style??{}).forEach(([r,o])=>{if(n.has(r))return;let s=e.style,i=r.replace(/[A-Z]/g,c=>`-${c.toLowerCase()}`);if(o==null||o===""){s.removeProperty(i);return}s.setProperty(i,String(o))}),t.styleDeclarations?.forEach(r=>{let o=e.style,s=r.property.replace(/[A-Z]/g,c=>`-${c.toLowerCase()}`),i=r.value;if(i==null||i===""){o.removeProperty(s);return}o.setProperty(s,String(i),r.priority)})}var ln=500,te=new Map;function dn(e,t){return`${e}:${t.key}:${t.instanceIndex??""}`}function pn(e,t){if(te.size>=ln){let n=te.keys().next().value;n&&te.delete(n)}te.set(e,t)}var ne=new Set;function fn(e,t){let n=e.documentElement?.style,r=new Set;for(let[o,s]of Object.entries(t.variables??{}))o.startsWith("--")&&(r.add(o),n?.setProperty(o,s));for(let o of ne)r.has(o)||n?.removeProperty(o);ne.clear();for(let o of r)ne.add(o);bn(e,t.stylesheets??[])}function mn(e){let t=e.documentElement?.style;for(let n of ne)t?.removeProperty(n);ne.clear();for(let n of ot(e))n.remove()}function hn(e,t){let n=Array.from(new Set(t.filter(i=>typeof i=="string"&&i.startsWith("--"))));if(n.length===0)return{};let r=e.documentElement,o=r?e.defaultView?.getComputedStyle(r):null,s={};for(let i of n){let c=nt(o,i);c&&(s[i]=c)}return s}function nt(e,t,n=new Set){if(!e||n.has(t))return null;n.add(t);let r=e.getPropertyValue(t).trim();return rt(e,r,n)}function rt(e,t,n){if(!t)return null;let r=gn(t);if(!r)return t;let o=nt(e,r.name,n);return o||(r.fallback?rt(e,r.fallback,n)??r.fallback:null)}function gn(e){let t=e.trim();if(!t.startsWith("var(")||!t.endsWith(")"))return null;let n=t.slice(4,-1).trim(),r=yn(n),o=r>=0?n.slice(0,r).trim():n;if(!o.startsWith("--"))return null;let s=r>=0?n.slice(r+1).trim():null;return{name:o,fallback:s||null}}function yn(e){let t=0;for(let n=0;n<e.length;n+=1){let r=e[n];if(r==="("){t+=1;continue}if(r===")"){t=Math.max(0,t-1);continue}if(r===","&&t===0)return n}return-1}function bn(e,t){let n=new Set(t.filter(s=>typeof s=="string"&&s.length>0)),r=new Map;for(let s of ot(e)){let i=s.getAttribute("href")??"";if(!n.has(i)||r.has(i)){s.remove();continue}r.set(i,s)}let o=e.head;if(o)for(let s of n){if(r.has(s))continue;let i=e.createElement("link");i.setAttribute("rel","stylesheet"),i.setAttribute(ze,"true"),i.setAttribute("href",s),o.appendChild(i)}}function ot(e){return Array.from(e.querySelectorAll(`link[${ze}]`))}function En(e,t,n,r,o={}){let s=o.textNode?Sn(e.document,o.textNode):null;if(o.textNode&&!s)throw new Error("Failed to prepare text segment editor");let i=s?.element??t,c=i.textContent??"",u=In(i),g=!1,f=()=>{e.document.removeEventListener("pointerdown",v,!0),i.removeEventListener("keydown",I),i.removeEventListener("blur",P),i.removeEventListener("input",k),_n(i,u)},S=N=>{if(g)return;g=!0;let F=i.textContent??"";if(f(),N==="cancel"){s?.restore(c),s||(t.textContent=c),r({kind:"text-edit-cancel",payload:{ref:n}});return}if(s?.restore(F),N==="commit"&&F!==c){r({kind:"text-edit-commit",payload:{ref:n,value:F}});return}r({kind:"text-edit-exit",payload:{ref:n}})};function v(N){let F=N.target;F&&i.contains(F)||S("commit")}function I(N){if(N.key==="Escape"){N.preventDefault(),S("cancel");return}N.key==="Enter"&&(N.metaKey||N.ctrlKey)&&(N.preventDefault(),S("commit"))}function P(){S("commit")}function k(){r({kind:"text-edit-input",payload:{ref:n,hit:M(t,n,void 0,"full")}})}return vn(i),e.document.addEventListener("pointerdown",v,!0),i.addEventListener("keydown",I),i.addEventListener("blur",P),i.addEventListener("input",k),Tn(i),xn(i,e.document),f}function Sn(e,t){let n=t.parentNode;if(!n)return null;let r=e.createElement("span");return r.setAttribute("data-vcp-text-segment-editor","true"),r.textContent=t.textContent??"",n.replaceChild(r,t),{element:r,restore(o){t.nodeValue=o,r.parentNode&&r.parentNode.replaceChild(t,r)}}}function In(e){return{contentEditable:e.getAttribute("contenteditable"),spellcheck:e.getAttribute("spellcheck"),marker:e.getAttribute("data-vcp-edit-text-editing"),cursor:e.style.cursor,userSelect:e.style.userSelect}}function vn(e){Cn(e.ownerDocument),e.setAttribute("contenteditable","plaintext-only"),e.setAttribute("spellcheck","false"),e.setAttribute("data-vcp-edit-text-editing","true"),e.style.cursor="text",e.style.userSelect="text"}function _n(e,t){be(e,"contenteditable",t.contentEditable),be(e,"spellcheck",t.spellcheck),be(e,"data-vcp-edit-text-editing",t.marker),e.style.cursor=t.cursor,e.style.userSelect=t.userSelect}function Cn(e){if(e.getElementById("vcp-text-edit-base-style"))return;let t=e.createElement("style");t.id="vcp-text-edit-base-style",t.textContent='[data-vcp-edit-text-editing="true"]{outline:0!important;outline-offset:0!important;}',e.head.appendChild(t)}function be(e,t,n){if(n===null){e.removeAttribute(t);return}e.setAttribute(t,n)}function Rn(e){let t=[e.documentElement,e.body].filter(r=>!!r?.style),n=t.map(r=>({element:r,userSelect:r.style.userSelect}));for(let r of t)r.style.userSelect="none";return()=>{for(let r of n)r.element.style.userSelect=r.userSelect}}function Tn(e){try{e.focus({preventScroll:!0})}catch{e.focus()}}function xn(e,t){let n=t.createRange();n.selectNodeContents(e);let r=t.getSelection?.();r?.removeAllRanges(),r?.addRange(n)}function st(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function K(e){let t=Number(e);return Number.isFinite(t)?t:0}export{Se as VCP_SITE_EDIT_BRIDGE_STATUS_EVENT,Ee as VCP_SITE_EDIT_ROUTE_READY_EVENT,ue as resolveSiteEditRouteId,Dt as resolveSiteEditWebSocketUrl,Vn as startSiteEditAutoBootstrap,kt as startSiteEditFrameRuntime};
package/dist/client.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { SiteEditCommandSuccess, SiteEditEvent, SiteEditGetClassNameSourceCommandResult, SiteEditObjectDetail, SiteEditObjectEditContext, SiteEditObjectSummary, SiteEditOperationCommandResult, SiteEditOperationRequest, SiteEditRenderDocument } from "@vcp-dev/contracts";
1
+ import type { SiteEditCommandSuccess, SiteEditEvent, SiteEditGetClassNameSourceCommandResult, SiteEditObjectDetail, SiteEditObjectEditContext, SiteEditObjectSummary, SiteEditOperationCommandResult, SiteEditOperationRequest, SiteEditRenderDocument, SiteEditResolveSourceLocationInput, SiteEditSourceFileResponse, SiteEditSourceLocation, SiteEditSourceTreeResponse } from "@vcp-dev/contracts";
2
+ import { type SiteEditBridgeRequestKind } from "./protocol.js";
2
3
  export type SiteEditBrowserSocketLike = {
3
4
  readonly readyState: number;
4
5
  onopen: (() => void) | null;
@@ -10,12 +11,22 @@ export type SiteEditBrowserSocketLike = {
10
11
  send(data: string): void;
11
12
  close(): void;
12
13
  };
14
+ export type SiteEditBridgeConnectionState = "idle" | "connecting" | "open" | "closing" | "closed" | "failed";
15
+ export type SiteEditBridgeConnectionStatus = {
16
+ state: SiteEditBridgeConnectionState;
17
+ message?: string;
18
+ };
13
19
  export type SiteEditBridgeClient = {
14
20
  getDocument(routeId: string): Promise<SiteEditCommandSuccess<SiteEditRenderDocument>>;
15
21
  ensureDocumentVersion?(routeId: string, minVersion: number): Promise<SiteEditCommandSuccess<SiteEditRenderDocument>>;
16
22
  getObjectSummary(key: string, routeId?: string): Promise<SiteEditCommandSuccess<SiteEditObjectSummary>>;
17
23
  getObjectEditContext(key: string, routeId?: string): Promise<SiteEditCommandSuccess<SiteEditObjectEditContext>>;
18
24
  getClassNameSource(key: string, routeId?: string): Promise<SiteEditGetClassNameSourceCommandResult>;
25
+ getSourceTree(): Promise<SiteEditCommandSuccess<SiteEditSourceTreeResponse>>;
26
+ getSourceFile(input: {
27
+ path: string;
28
+ }): Promise<SiteEditCommandSuccess<SiteEditSourceFileResponse>>;
29
+ resolveSourceLocation(input: SiteEditResolveSourceLocationInput): Promise<SiteEditCommandSuccess<SiteEditSourceLocation>>;
19
30
  execute(request: SiteEditOperationRequest): Promise<SiteEditOperationCommandResult>;
20
31
  undo(): Promise<SiteEditOperationCommandResult>;
21
32
  redo(): Promise<SiteEditOperationCommandResult>;
@@ -24,15 +35,25 @@ export type SiteEditBridgeClient = {
24
35
  export declare class SiteEditWebSocketClient implements SiteEditBridgeClient {
25
36
  private readonly options;
26
37
  private socket;
38
+ private connectPromise;
39
+ private connectAttempt;
40
+ private connectionState;
41
+ private intentionalClose;
27
42
  private sequence;
28
43
  private readonly pending;
29
44
  private readonly listeners;
30
45
  constructor(options: {
31
46
  url: string;
47
+ authKey?: string;
32
48
  createSocket?: (url: string) => SiteEditBrowserSocketLike;
49
+ onConnectionStatus?: (status: SiteEditBridgeConnectionStatus) => void;
50
+ requestTimeoutMs?: number;
51
+ requestTimeoutMsByKind?: Partial<Record<SiteEditBridgeRequestKind, number>>;
33
52
  });
34
53
  connect(): Promise<void>;
35
54
  disconnect(): void;
55
+ getConnectionState(): SiteEditBridgeConnectionState;
56
+ subscribeConnectionStatus(listener: (status: SiteEditBridgeConnectionStatus) => void): () => void;
36
57
  getDocument(routeId: string): Promise<SiteEditCommandSuccess<{
37
58
  siteId: string;
38
59
  snapshotId: string;
@@ -186,13 +207,65 @@ export declare class SiteEditWebSocketClient implements SiteEditBridgeClient {
186
207
  componentSemantic?: Record<string, unknown> | undefined;
187
208
  }>>;
188
209
  getClassNameSource(key: string, routeId?: string): Promise<SiteEditGetClassNameSourceCommandResult>;
210
+ getSourceTree(): Promise<SiteEditCommandSuccess<{
211
+ nodes: import("@vcp-dev/contracts").SiteEditSourceTreeNode[];
212
+ totalFiles: number;
213
+ defaultPath?: string | undefined;
214
+ truncated?: {
215
+ reasons: ("max-files" | "max-depth" | "max-total-bytes")[];
216
+ maxFiles: number;
217
+ maxDepth: number;
218
+ maxTotalBytes: number;
219
+ } | undefined;
220
+ }>>;
221
+ getSourceFile(input: {
222
+ path: string;
223
+ }): Promise<SiteEditCommandSuccess<{
224
+ path: string;
225
+ sizeBytes: number;
226
+ kind: "text";
227
+ language: string;
228
+ readonly: boolean;
229
+ content: string;
230
+ contentHash?: string | undefined;
231
+ } | {
232
+ path: string;
233
+ sizeBytes: number;
234
+ kind: "binary";
235
+ language: null;
236
+ readonly: true;
237
+ mimeType: string;
238
+ contentHash?: string | undefined;
239
+ contentBase64?: string | undefined;
240
+ previewUnavailableReason?: "too-large" | "unsupported-mime" | "bytes-unavailable" | undefined;
241
+ }>>;
242
+ resolveSourceLocation(input: SiteEditResolveSourceLocationInput): Promise<SiteEditCommandSuccess<{
243
+ key: string;
244
+ sourceFile: string;
245
+ componentName: string;
246
+ openingElementRange: {
247
+ startLine: number;
248
+ startColumn: number;
249
+ endLine: number;
250
+ endColumn: number;
251
+ };
252
+ structuralPath: string;
253
+ routeId?: string | undefined;
254
+ textPreview?: string | undefined;
255
+ }>>;
189
256
  execute(request: SiteEditOperationRequest): Promise<SiteEditOperationCommandResult>;
190
257
  undo(): Promise<SiteEditOperationCommandResult>;
191
258
  redo(): Promise<SiteEditOperationCommandResult>;
192
259
  subscribe(listener: (event: SiteEditEvent) => void): () => void;
193
260
  private request;
261
+ private handleAuthHandshakeMessage;
194
262
  private handleMessage;
195
263
  private rejectAll;
264
+ private clearPendingRequest;
265
+ private resolveRequestTimeoutMs;
266
+ private readonly connectionStatusListeners;
267
+ private cleanupSocket;
268
+ private setConnectionState;
196
269
  private createSocket;
197
270
  }
198
271
  export type SiteEditBridge = SiteEditBridgeClient;
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- function f(r){if(!b(r))return r;let e=new Map,t=n=>{let s=e.get(n);if(s)return s;let o=r.nodes[n];if(!o)throw new Error(`Missing compact document node ${n}`);let c=r.tokens[o.token];if(typeof c!="string")throw new Error(`Missing compact document token ${o.token}`);let d=`${o.parent===null?"":t(o.parent)}${c}`;return e.set(n,d),d};return{siteId:r.siteId,snapshotId:r.snapshotId,routeId:r.routeId,version:r.version,rootKeys:r.rootKeyNodeIds.map(t),entries:r.entries.map(n=>({key:t(n.keyNodeId),tag:n.tag,label:n.label,parentKey:n.parentKeyNodeId===null?null:t(n.parentKeyNodeId),childKeys:n.childKeyNodeIds.map(t),operationSummary:n.operationSummary}))}}function b(r){return typeof r=="object"&&r!==null&&"encoding"in r&&r.encoding==="segment-trie-v1"}var a=class r{constructor(){}static parseMessage(e,t={}){let n=JSON.parse(e);if(!r.isMessage(n,t))throw new Error("Invalid site edit bridge message");return n}static stringifyMessage(e){return JSON.stringify(e)}static extractRequestInfo(e){if(typeof e=="object"&&e!==null&&"payload"in e&&typeof e.payload=="object"&&e.payload!==null){let t=e.payload,n=typeof t.id=="string"?t.id:"unknown",s=r.isRequestKind(t.kind)?t.kind:"get-document";return{id:n,kind:s}}return{id:"unknown",kind:"get-document"}}static isRequestKind(e){return e==="get-document"||e==="get-object-summary"||e==="get-object-edit-context"||e==="get-class-name-source"||e==="execute"||e==="undo"||e==="redo"}static isMessage(e,t={}){return!i(e)||typeof e.type!="string"?!1:e.type==="request"?r.isRequestPayload(e.payload,t):e.type==="response"||e.type==="error"?i(e.payload)&&typeof e.payload.id=="string":e.type==="event"?i(e.payload)&&i(e.payload.event):!1}static isRequestPayload(e,t={}){if(!i(e)||typeof e.id!="string"||!r.isRequestKind(e.kind))return!1;switch(e.kind){case"get-document":return typeof e.routeId=="string";case"get-object-summary":case"get-object-edit-context":case"get-class-name-source":return typeof e.key=="string"&&(e.routeId===void 0||typeof e.routeId=="string");case"execute":return I(e.request)&&(t.validateOperationRequest?.(e.request)??!0);case"undo":case"redo":return!0}}};function i(r){return typeof r=="object"&&r!==null}function I(r){return i(r)&&typeof r.id=="string"&&typeof r.siteId=="string"&&typeof r.baseSnapshotId=="string"&&(r.routeId===void 0||typeof r.routeId=="string")&&typeof r.kind=="string"&&i(r.target)&&typeof r.documentVersion=="number"&&Number.isInteger(r.documentVersion)&&r.documentVersion>=0&&i(r.params)}var k="vcp:designer:trace",w="designer_trace",g="__VCP_DESIGNER_TRACE__";var q=/(authorization|cookie|token|secret|providerTrace|headers?|sourceCode|rawSource|fullSource)/i;function x(r=globalThis){let e=r;try{if(e.localStorage?.getItem(k)==="1")return!0}catch{}try{let t=e.location?.search??"";return new URLSearchParams(t).get(w)==="1"}catch{return!1}}function u(r,e={},t=globalThis){if(!x(t))return;let n={type:r,timestamp:Date.now(),payload:E(e)},s=t,o=s[g]??[];o.push(n),o.length>200&&o.splice(0,o.length-200),s[g]=o;let c=t.console?.debug;typeof c=="function"&&c.call(t.console,"[designer-trace]",n)}function E(r){return h(r,0)}function h(r,e){if(e>4)return"[truncated]";if(Array.isArray(r))return r.map(n=>h(n,e+1));if(!r||typeof r!="object")return r;let t={};for(let[n,s]of Object.entries(r)){if(q.test(n)){t[n]="[redacted]";continue}t[n]=h(s,e+1)}return t}var l=class{constructor(e){this.options=e,this.socket=null,this.sequence=0,this.pending=new Map,this.listeners=new Set}connect(){return this.socket?Promise.resolve():new Promise((e,t)=>{let n=this.createSocket(this.options.url);this.socket=n,n.onopen=()=>e(),n.onerror=s=>{t(s instanceof Error?s:new Error("WebSocket failed"))},n.onmessage=s=>this.handleMessage(s.data),n.onclose=()=>{this.rejectAll(new Error("WebSocket closed")),this.socket=null}})}disconnect(){this.socket?.close(),this.socket=null,this.rejectAll(new Error("WebSocket disconnected"))}getDocument(e){return this.request("get-document",{routeId:e})}getObjectSummary(e,t){return this.request("get-object-summary",{key:e,routeId:t})}getObjectEditContext(e,t){return this.request("get-object-edit-context",{key:e,routeId:t})}getClassNameSource(e,t){return this.request("get-class-name-source",{key:e,routeId:t})}execute(e){return this.request("execute",{request:e})}undo(){return this.request("undo",{})}redo(){return this.request("redo",{})}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}request(e,t){let n=this.socket;if(!n)return Promise.reject(new Error("WebSocket is not connected"));let s=`${e}-${this.sequence+=1}`,o=C(s,e,t);return u("bridge.request",{id:s,kind:e,routeId:typeof t.routeId=="string"?t.routeId:null,key:typeof t.key=="string"?t.key:null,operationKind:m(t.request,"kind"),documentVersion:m(t.request,"documentVersion")}),new Promise((c,d)=>{this.pending.set(s,{kind:e,resolve:y=>c(y),reject:d}),n.send(a.stringifyMessage(o))})}handleMessage(e){let t=a.parseMessage(e);if(t.type==="event"){for(let s of this.listeners)s(t.payload.event);return}if(t.type!=="response"&&t.type!=="error")return;let n=this.pending.get(t.payload.id);if(n){if(this.pending.delete(t.payload.id),t.type==="error"){u("bridge.response",{id:t.payload.id,kind:n.kind,ok:!1}),n.reject(new Error(t.payload.message));return}u("bridge.response",{id:t.payload.id,kind:n.kind,ok:!0,resultVersion:S(t.payload.result)}),n.resolve(n.kind==="get-document"?{...t.payload.result,data:f(t.payload.result.data)}:t.payload.result)}}rejectAll(e){for(let t of this.pending.values())t.reject(e);this.pending.clear()}createSocket(e){if(this.options.createSocket)return this.options.createSocket(e);if(typeof WebSocket>"u")throw new Error("Site edit preview bridge requires WebSocket");return new WebSocket(e)}};function m(r,e){if(!r||typeof r!="object")return null;let n=r[e];return typeof n=="string"||typeof n=="number"?n:null}function S(r){if(!r||typeof r!="object")return null;let e=r,t=e.data?.resultVersion??e.data?.version??null;return typeof t=="number"?t:null}function A(r){return new p(r)}var p=class{constructor(e){this.params=e,this.refreshInFlight=null,this.currentDocument=e.initialDocument,this.summaryCache=new Map(Object.entries(e.initialDetails??{}).map(([t,n])=>[t,j(n)])),this.editContextCache=new Map(Object.entries(e.initialDetails??{}).map(([t,n])=>[t,D(n)]))}async getDocument(e){if(e!==this.params.routeId)throw new Error(`Site edit bridge is bound to route ${this.params.routeId}, received ${e}`);return R(this.currentDocument)&&(this.currentDocument=await this.refreshSnapshot(void 0,"get-document")),{ok:!0,data:this.currentDocument}}async ensureDocumentVersion(e,t){if(e!==this.params.routeId)throw new Error(`Site edit bridge is bound to route ${this.params.routeId}, received ${e}`);let n=await this.refreshSnapshot(t,"ensure-version");if(n.version<t)throw new Error(`Document refresh returned version ${n.version}, expected at least ${t}`);return{ok:!0,data:n}}async getObjectSummary(e,t){let n=this.summaryCache.get(e);if(n)return{ok:!0,data:n};let s=await this.params.client.getObjectSummary(e,t??this.params.routeId);return this.summaryCache.set(e,s.data),s}async getObjectEditContext(e,t){let n=this.editContextCache.get(e);if(n)return{ok:!0,data:n};let s=await this.params.client.getObjectEditContext(e,t??this.params.routeId);return this.editContextCache.set(e,s.data),s}async getClassNameSource(e,t){return this.params.client.getClassNameSource(e,t??this.params.routeId)}async execute(e){return this.params.client.execute(e.target.kind==="node"&&!e.routeId?{...e,routeId:this.params.routeId}:e)}async undo(){return this.params.client.undo()}async redo(){return this.params.client.redo()}subscribe(e){return this.params.client.subscribe(t=>{if(t.type==="site-edit.document.changed"&&t.routeId===this.params.routeId){this.refreshSnapshot(t.version,"event").catch(()=>{}).finally(()=>e(t));return}e(t)})}async refreshSnapshot(e,t="ensure-version"){if(typeof e=="number"&&this.currentDocument.version>=e)return u("bridge.document-refresh",{routeId:this.params.routeId,minVersion:e,currentVersion:this.currentDocument.version,deduped:!0,skipped:!0,source:t}),this.currentDocument;if(this.refreshInFlight){u("bridge.document-refresh",{routeId:this.params.routeId,minVersion:e,currentVersion:this.currentDocument.version,deduped:!0,source:t});let s=await this.refreshInFlight;if(typeof e!="number"||s.version>=e||this.currentDocument.version>=e)return this.currentDocument}u("bridge.document-refresh",{routeId:this.params.routeId,minVersion:e,currentVersion:this.currentDocument.version,deduped:!1,source:t});let n=this.params.client.getDocument(this.params.routeId).then(s=>(this.currentDocument=s.data,this.clearObjectCaches(),this.currentDocument));this.refreshInFlight=n;try{return await n}finally{this.refreshInFlight===n&&(this.refreshInFlight=null)}}clearObjectCaches(){this.summaryCache.clear(),this.editContextCache.clear()}};function R(r){return r.version===0&&r.rootKeys.length===0}function C(r,e,t){switch(e){case"get-document":return{type:"request",payload:{id:r,kind:e,routeId:String(t.routeId)}};case"get-object-summary":return{type:"request",payload:{id:r,kind:e,key:String(t.key),routeId:typeof t.routeId=="string"?t.routeId:void 0}};case"get-object-edit-context":return{type:"request",payload:{id:r,kind:e,key:String(t.key),routeId:typeof t.routeId=="string"?t.routeId:void 0}};case"get-class-name-source":return{type:"request",payload:{id:r,kind:e,key:String(t.key),routeId:typeof t.routeId=="string"?t.routeId:void 0}};case"execute":return{type:"request",payload:{id:r,kind:e,request:t.request}};case"undo":case"redo":return{type:"request",payload:{id:r,kind:e}}}}function j(r){return{key:r.key,tag:r.tag,label:r.label,capabilities:{constraints:r.capabilities.constraints},isOpaque:r.isOpaque,provenanceChain:r.provenanceChain?{editMode:r.provenanceChain.editMode,diagnostics:r.provenanceChain.diagnostics}:void 0,ancestors:r.ancestors}}function D(r){return{key:r.key,componentName:r.componentName,sourceFile:r.sourceFile,capabilities:r.capabilities,writeTarget:r.writeTarget,effectiveWriteTarget:r.effectiveWriteTarget,provenanceChain:r.provenanceChain,componentSemantic:r.componentSemantic,textSegments:r.textSegments,boundaryKind:r.boundaryKind,children:r.children,siblings:r.siblings}}export{l as SiteEditWebSocketClient,A as createSiteEditBridge};
1
+ function I(n){if(!E(n))return n;let e=new Map,t=s=>{let r=e.get(s);if(r)return r;let o=n.nodes[s];if(!o)throw new Error(`Missing compact document node ${s}`);let c=n.tokens[o.token];if(typeof c!="string")throw new Error(`Missing compact document token ${o.token}`);let i=`${o.parent===null?"":t(o.parent)}${c}`;return e.set(s,i),i};return{siteId:n.siteId,snapshotId:n.snapshotId,routeId:n.routeId,version:n.version,rootKeys:n.rootKeyNodeIds.map(t),entries:n.entries.map(s=>({key:t(s.keyNodeId),tag:s.tag,label:s.label,parentKey:s.parentKeyNodeId===null?null:t(s.parentKeyNodeId),childKeys:s.childKeyNodeIds.map(t),operationSummary:s.operationSummary}))}}function E(n){return typeof n=="object"&&n!==null&&"encoding"in n&&n.encoding==="segment-trie-v1"}var h=class n{constructor(){}static parseMessage(e,t={}){let s=JSON.parse(e);if(!n.isMessage(s,t))throw new Error("Invalid site edit bridge message");return s}static stringifyMessage(e){return JSON.stringify(e)}static extractRequestInfo(e){if(typeof e=="object"&&e!==null&&"payload"in e&&typeof e.payload=="object"&&e.payload!==null){let t=e.payload,s=typeof t.id=="string"?t.id:"unknown",r=n.isRequestKind(t.kind)?t.kind:"get-document";return{id:s,kind:r}}return{id:"unknown",kind:"get-document"}}static isRequestKind(e){return e==="get-document"||e==="get-object-summary"||e==="get-object-edit-context"||e==="get-class-name-source"||e==="get-source-tree"||e==="get-source-file"||e==="resolve-source-location"||e==="execute"||e==="undo"||e==="redo"}static isMessage(e,t={}){return!a(e)||typeof e.type!="string"?!1:e.type==="request"?n.isRequestPayload(e.payload,t):e.type==="response"||e.type==="error"?a(e.payload)&&typeof e.payload.id=="string":e.type==="event"?a(e.payload)&&a(e.payload.event):e.type==="auth"?a(e.payload)&&typeof e.payload.key=="string":e.type==="auth-ok"?a(e.payload)&&e.payload.ok===!0:!1}static isRequestPayload(e,t={}){if(!a(e)||typeof e.id!="string"||!n.isRequestKind(e.kind))return!1;switch(e.kind){case"get-document":return typeof e.routeId=="string";case"get-object-summary":case"get-object-edit-context":case"get-class-name-source":case"resolve-source-location":return typeof e.key=="string"&&(e.routeId===void 0||typeof e.routeId=="string");case"get-source-tree":return!0;case"get-source-file":return typeof e.path=="string";case"execute":return q(e.request)&&(t.validateOperationRequest?.(e.request)??!0);case"undo":case"redo":return!0}}};function a(n){return typeof n=="object"&&n!==null}function q(n){return a(n)&&typeof n.id=="string"&&typeof n.siteId=="string"&&typeof n.baseSnapshotId=="string"&&(n.routeId===void 0||typeof n.routeId=="string")&&typeof n.kind=="string"&&a(n.target)&&typeof n.documentVersion=="number"&&Number.isInteger(n.documentVersion)&&n.documentVersion>=0&&a(n.params)}var x="vcp:designer:trace",C="designer_trace",S="__VCP_DESIGNER_TRACE__";var R=/(authorization|cookie|token|secret|providerTrace|headers?|sourceCode|rawSource|fullSource)/i;function T(n=globalThis){let e=n;try{if(e.localStorage?.getItem(x)==="1")return!0}catch{}try{let t=e.location?.search??"";return new URLSearchParams(t).get(C)==="1"}catch{return!1}}function d(n,e={},t=globalThis){if(!T(t))return;let s={type:n,timestamp:Date.now(),payload:D(e)},r=t,o=r[S]??[];o.push(s),o.length>200&&o.splice(0,o.length-200),r[S]=o;let c=t.console?.debug;typeof c=="function"&&c.call(t.console,"[designer-trace]",s)}function D(n){return f(n,0)}function f(n,e){if(e>4)return"[truncated]";if(Array.isArray(n))return n.map(s=>f(s,e+1));if(!n||typeof n!="object")return n;let t={};for(let[s,r]of Object.entries(n)){if(R.test(s)){t[s]="[redacted]";continue}t[s]=f(r,e+1)}return t}var k=class{constructor(e){this.options=e,this.socket=null,this.connectPromise=null,this.connectAttempt=null,this.connectionState="idle",this.intentionalClose=!1,this.sequence=0,this.pending=new Map,this.listeners=new Set,this.connectionStatusListeners=new Set}connect(){return this.socket?.readyState===g&&this.connectionState==="open"?(this.setConnectionState("open"),Promise.resolve()):this.connectPromise?this.connectPromise:(this.intentionalClose=!1,this.setConnectionState("connecting"),this.connectPromise=new Promise((e,t)=>{let s;try{s=this.createSocket(this.options.url)}catch(i){let u=l(i,"WebSocket failed");this.socket=null,this.connectAttempt=null,this.connectPromise=null,this.setConnectionState("failed",u.message),t(u);return}let r={socket:s,settled:!1,reject:t};this.connectAttempt=r,this.socket=s;let o=()=>{this.socket!==s||this.connectAttempt!==r||(r.settled=!0,this.connectAttempt=null,this.connectPromise=null,this.setConnectionState("open"),e())},c=(i,u)=>{this.cleanupSocket(s,i,u)};s.onopen=()=>{if(!(this.socket!==s||this.connectAttempt!==r)){if(this.options.authKey){try{s.send(h.stringifyMessage({type:"auth",payload:{key:this.options.authKey}}))}catch(i){c(l(i,"WebSocket auth failed"),"failed")}return}o()}},s.onerror=i=>{if(this.socket!==s)return;let u=l(i,"WebSocket failed");c(u,"failed")},s.onmessage=i=>{if(this.socket===s){if(this.options.authKey&&this.connectAttempt===r&&!r.settled){this.handleAuthHandshakeMessage(i.data,s,r,()=>{o()});return}this.handleMessage(i.data)}},s.onclose=()=>{if(this.socket!==s)return;let i=this.intentionalClose,u=new Error(i?"WebSocket disconnected":"WebSocket closed");c(u,i?"closed":"failed")}}),this.connectPromise)}disconnect(){this.intentionalClose=!0,this.setConnectionState("closing");let e=this.socket;if(!e){this.rejectAll(new Error("WebSocket disconnected")),this.connectAttempt=null,this.connectPromise=null,this.setConnectionState("closed");return}this.cleanupSocket(e,new Error("WebSocket disconnected"),"closed")}getConnectionState(){return this.connectionState}subscribeConnectionStatus(e){return this.connectionStatusListeners.add(e),e({state:this.connectionState}),()=>{this.connectionStatusListeners.delete(e)}}getDocument(e){return this.request("get-document",{routeId:e})}getObjectSummary(e,t){return this.request("get-object-summary",{key:e,routeId:t})}getObjectEditContext(e,t){return this.request("get-object-edit-context",{key:e,routeId:t})}getClassNameSource(e,t){return this.request("get-class-name-source",{key:e,routeId:t})}getSourceTree(){return this.request("get-source-tree",{})}getSourceFile(e){return this.request("get-source-file",e)}resolveSourceLocation(e){return this.request("resolve-source-location",e)}execute(e){return this.request("execute",{request:e})}undo(){return this.request("undo",{})}redo(){return this.request("redo",{})}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}request(e,t){let s=this.socket;if(!s||s.readyState!==g||this.connectionState!=="open")return Promise.reject(new Error(`WebSocket is not open (state: ${this.connectionState}, readyState: ${s?.readyState??"none"})`));let r=`${e}-${this.sequence+=1}`,o=A(r,e,t);return d("bridge.request",{id:r,kind:e,routeId:typeof t.routeId=="string"?t.routeId:null,key:typeof t.key=="string"?t.key:null,operationKind:w(t.request,"kind"),documentVersion:w(t.request,"documentVersion")}),new Promise((c,i)=>{let u=this.resolveRequestTimeoutMs(e),y=u>0?setTimeout(()=>{let p=this.pending.get(r);p&&(this.pending.delete(r),d("bridge.response",{id:r,kind:e,ok:!1,timedOut:!0}),p.reject(new Error(`Bridge request timed out after ${u}ms: ${e}`)))},u):null;y?.unref?.(),this.pending.set(r,{kind:e,timeout:y,resolve:p=>c(p),reject:i});try{s.send(h.stringifyMessage(o))}catch(p){let b=l(p,"WebSocket send failed");this.clearPendingRequest(r),i(b),this.cleanupSocket(s,b,"failed")}})}handleAuthHandshakeMessage(e,t,s,r){try{if(h.parseMessage(e).type==="auth-ok"){r();return}throw new Error("Bridge authentication failed")}catch(o){let c=l(o,"Bridge authentication failed");this.connectAttempt===s&&this.cleanupSocket(t,c,"failed")}}handleMessage(e){let t=h.parseMessage(e);if(t.type==="event"){for(let r of this.listeners)r(t.payload.event);return}if(t.type!=="response"&&t.type!=="error")return;let s=this.pending.get(t.payload.id);if(s){if(this.clearPendingRequest(t.payload.id),t.type==="error"){d("bridge.response",{id:t.payload.id,kind:s.kind,ok:!1}),s.reject(new Error(t.payload.message));return}d("bridge.response",{id:t.payload.id,kind:s.kind,ok:!0,resultVersion:j(t.payload.result)}),s.resolve(s.kind==="get-document"?{...t.payload.result,data:I(t.payload.result.data)}:t.payload.result)}}rejectAll(e){for(let[t,s]of[...this.pending])this.clearPendingRequest(t),s.reject(e)}clearPendingRequest(e){let t=this.pending.get(e);t&&(t.timeout&&clearTimeout(t.timeout),this.pending.delete(e))}resolveRequestTimeoutMs(e){let t=this.options.requestTimeoutMsByKind?.[e];return typeof t=="number"?Math.max(0,t):typeof this.options.requestTimeoutMs=="number"?Math.max(0,this.options.requestTimeoutMs):O[e]??_}cleanupSocket(e,t,s){if(this.socket===e&&(this.socket=null),this.connectAttempt?.socket===e){let r=this.connectAttempt;this.connectAttempt=null,r.settled||(r.settled=!0,r.reject(t))}this.connectPromise=null,this.rejectAll(t),this.setConnectionState(s,t.message),e.onopen=null,e.onmessage=null,e.onerror=null,e.onclose=null;try{(e.readyState===M||e.readyState===g)&&e.close()}catch{}}setConnectionState(e,t){if(this.connectionState===e&&!t)return;this.connectionState=e;let s={state:e,...t?{message:t}:{}};this.options.onConnectionStatus?.(s);for(let r of this.connectionStatusListeners)r(s)}createSocket(e){if(this.options.createSocket)return this.options.createSocket(e);if(typeof WebSocket>"u")throw new Error("Site edit preview bridge requires WebSocket");return new WebSocket(e)}},M=0,g=1,_=15e3,O={"get-source-tree":1e4,"get-source-file":1e4,"resolve-source-location":1e4,execute:6e4,undo:2e4,redo:2e4};function l(n,e){return n instanceof Error?n:new Error(e)}function w(n,e){if(!n||typeof n!="object")return null;let s=n[e];return typeof s=="string"||typeof s=="number"?s:null}function j(n){if(!n||typeof n!="object")return null;let e=n,t=e.data?.resultVersion??e.data?.version??null;return typeof t=="number"?t:null}function Q(n){return new m(n)}var m=class{constructor(e){this.params=e,this.refreshInFlight=null,this.currentDocument=e.initialDocument,this.summaryCache=new Map(Object.entries(e.initialDetails??{}).map(([t,s])=>[t,N(s)])),this.editContextCache=new Map(Object.entries(e.initialDetails??{}).map(([t,s])=>[t,P(s)]))}async getDocument(e){if(e!==this.params.routeId)throw new Error(`Site edit bridge is bound to route ${this.params.routeId}, received ${e}`);return K(this.currentDocument)&&(this.currentDocument=await this.refreshSnapshot(void 0,"get-document")),{ok:!0,data:this.currentDocument}}async ensureDocumentVersion(e,t){if(e!==this.params.routeId)throw new Error(`Site edit bridge is bound to route ${this.params.routeId}, received ${e}`);let s=await this.refreshSnapshot(t,"ensure-version");if(s.version<t)throw new Error(`Document refresh returned version ${s.version}, expected at least ${t}`);return{ok:!0,data:s}}async getObjectSummary(e,t){let s=this.summaryCache.get(e);if(s)return{ok:!0,data:s};let r=await this.params.client.getObjectSummary(e,t??this.params.routeId);return this.summaryCache.set(e,r.data),r}async getObjectEditContext(e,t){let s=this.editContextCache.get(e);if(s)return{ok:!0,data:s};let r=await this.params.client.getObjectEditContext(e,t??this.params.routeId);return this.editContextCache.set(e,r.data),r}async getClassNameSource(e,t){return this.params.client.getClassNameSource(e,t??this.params.routeId)}async getSourceTree(){return this.params.client.getSourceTree()}async getSourceFile(e){return this.params.client.getSourceFile(e)}async resolveSourceLocation(e){return this.params.client.resolveSourceLocation({...e,routeId:e.routeId??this.params.routeId})}async execute(e){return this.params.client.execute(e.target.kind==="node"&&!e.routeId?{...e,routeId:this.params.routeId}:e)}async undo(){return this.params.client.undo()}async redo(){return this.params.client.redo()}subscribe(e){return this.params.client.subscribe(t=>{if(t.type==="site-edit.document.changed"&&t.routeId===this.params.routeId){this.refreshSnapshot(t.version,"event").catch(()=>{}).finally(()=>e(t));return}e(t)})}async refreshSnapshot(e,t="ensure-version"){if(typeof e=="number"&&this.currentDocument.version>=e)return d("bridge.document-refresh",{routeId:this.params.routeId,minVersion:e,currentVersion:this.currentDocument.version,deduped:!0,skipped:!0,source:t}),this.currentDocument;if(this.refreshInFlight){d("bridge.document-refresh",{routeId:this.params.routeId,minVersion:e,currentVersion:this.currentDocument.version,deduped:!0,source:t});let r=await this.refreshInFlight;if(typeof e!="number"||r.version>=e||this.currentDocument.version>=e)return this.currentDocument}d("bridge.document-refresh",{routeId:this.params.routeId,minVersion:e,currentVersion:this.currentDocument.version,deduped:!1,source:t});let s=this.params.client.getDocument(this.params.routeId).then(r=>(this.currentDocument=r.data,this.clearObjectCaches(),this.currentDocument));this.refreshInFlight=s;try{return await s}finally{this.refreshInFlight===s&&(this.refreshInFlight=null)}}clearObjectCaches(){this.summaryCache.clear(),this.editContextCache.clear()}};function K(n){return n.version===0&&n.rootKeys.length===0}function A(n,e,t){switch(e){case"get-document":return{type:"request",payload:{id:n,kind:e,routeId:String(t.routeId)}};case"get-object-summary":return{type:"request",payload:{id:n,kind:e,key:String(t.key),routeId:typeof t.routeId=="string"?t.routeId:void 0}};case"get-object-edit-context":return{type:"request",payload:{id:n,kind:e,key:String(t.key),routeId:typeof t.routeId=="string"?t.routeId:void 0}};case"get-class-name-source":return{type:"request",payload:{id:n,kind:e,key:String(t.key),routeId:typeof t.routeId=="string"?t.routeId:void 0}};case"get-source-tree":return{type:"request",payload:{id:n,kind:e}};case"get-source-file":return{type:"request",payload:{id:n,kind:e,path:String(t.path)}};case"resolve-source-location":return{type:"request",payload:{id:n,kind:e,key:String(t.key),routeId:typeof t.routeId=="string"?t.routeId:void 0}};case"execute":return{type:"request",payload:{id:n,kind:e,request:t.request}};case"undo":case"redo":return{type:"request",payload:{id:n,kind:e}}}}function N(n){return{key:n.key,tag:n.tag,label:n.label,capabilities:{constraints:n.capabilities.constraints},isOpaque:n.isOpaque,provenanceChain:n.provenanceChain?{editMode:n.provenanceChain.editMode,diagnostics:n.provenanceChain.diagnostics}:void 0,ancestors:n.ancestors}}function P(n){return{key:n.key,componentName:n.componentName,sourceFile:n.sourceFile,capabilities:n.capabilities,writeTarget:n.writeTarget,effectiveWriteTarget:n.effectiveWriteTarget,provenanceChain:n.provenanceChain,componentSemantic:n.componentSemantic,textSegments:n.textSegments,boundaryKind:n.boundaryKind,children:n.children,siblings:n.siblings}}export{k as SiteEditWebSocketClient,Q as createSiteEditBridge};