@popmelt.com/core 0.8.14 → 0.8.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/canvas.mjs CHANGED
@@ -1 +1 @@
1
- import{createRoot as ge}from"react-dom/client";import{createElement as me}from"react";import{useEffect as K,useMemo as le,useReducer as de,useRef as ce,useState as pe}from"react";var z="popmelt-canvas";function M(e){return Math.round(e/24)*24}var k={viewport:{offsetX:0,offsetY:0,scale:1},components:[],selectedId:null,highlightedName:null,dragState:null};function A(){try{let e=localStorage.getItem(z);if(!e)return{};let t=JSON.parse(e);return{components:t.components??[],viewport:t.viewport??k.viewport}}catch{return{}}}function Y(e){try{let t={components:e.components,viewport:e.viewport};localStorage.setItem(z,JSON.stringify(t))}catch{}}function W(e,t){switch(t.type){case"PLACE_COMPONENT":{let o=t.component,r={...o,x:M(o.x),y:M(o.y),width:M(o.width),height:M(o.height)};return{...e,components:[...e.components,r],selectedId:r.id}}case"REMOVE_COMPONENT":return{...e,components:e.components.filter(o=>o.id!==t.id),selectedId:e.selectedId===t.id?null:e.selectedId};case"MOVE_COMPONENT":return{...e,components:e.components.map(o=>o.id===t.id?{...o,x:M(t.x),y:M(t.y)}:o)};case"RESIZE_COMPONENT":return{...e,components:e.components.map(o=>o.id===t.id?{...o,width:Math.max(200,t.width),height:Math.max(150,t.height)}:o)};case"SELECT":return{...e,selectedId:t.id};case"SET_VIEWPORT":return{...e,viewport:t.viewport};case"PAN":return{...e,viewport:{...e.viewport,offsetX:e.viewport.offsetX+t.deltaX,offsetY:e.viewport.offsetY+t.deltaY}};case"START_DRAG":return{...e,dragState:t.dragState};case"END_DRAG":return{...e,dragState:null};case"HIGHLIGHT":return{...e,highlightedName:t.name};default:return e}}function X(e,t,o){return{x:(e-o.offsetX)/o.scale,y:(t-o.offsetY)/o.scale}}import{useCallback as te,useEffect as N,useRef as L}from"react";import{useCallback as R,useRef as G,useState as O}from"react";var ee="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMicgaGVpZ2h0PScxMic+PGRlZnM+PHBhdHRlcm4gaWQ9J2QnIHdpZHRoPSc0JyBoZWlnaHQ9JzQnIHBhdHRlcm5Vbml0cz0ndXNlclNwYWNlT25Vc2UnPjxwYXRoIGQ9J00tMSwxIGwyLC0yIE0wLDQgbDQsLTQgTTMsNSBsMiwtMicgc3Ryb2tlPSdibGFjaycgc3Ryb2tlLXdpZHRoPScuNScvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgd2lkdGg9JzEyJyBoZWlnaHQ9JzEyJyBmaWxsPSd1cmwoI2QpJy8+PC9zdmc+",_={borderWidth:3,borderStyle:"solid",borderImage:`url("${ee}") 4 / 1.9 / 0 round`};import{jsx as x,jsxs as C}from"react/jsx-runtime";function V({component:e,selected:t,highlighted:o,isDragging:r,viewport:b,dispatch:u}){let y=G(null),l=G(null),[i,w]=O(null),[g,d]=O(!1),[n,c]=O(!1),s=e.entry.routes&&e.entry.routes.length>0,a=R(()=>{d(!1),c(!1);try{let h=l.current?.contentWindow?.location.pathname;if(!h)return;let P=new URL(e.iframeUrl).pathname;h!==P&&w(h)}catch{}setTimeout(()=>{try{l.current?.contentDocument?.querySelector("nextjs-portal")&&d(!0)}catch{}},2e3)},[e.iframeUrl]),f=R(h=>{h.stopPropagation(),u({type:"SELECT",id:e.id});let P={type:"move",componentId:e.id,startX:h.clientX,startY:h.clientY,originX:e.x,originY:e.y};u({type:"START_DRAG",dragState:P})},[e.id,e.x,e.y,u]),m=R(h=>{h.stopPropagation(),h.preventDefault(),u({type:"SELECT",id:e.id});let P={type:"resize",componentId:e.id,startX:h.clientX,startY:h.clientY,originW:e.width,originH:e.height};u({type:"START_DRAG",dragState:P})},[e.id,e.width,e.height,u]),v=R(h=>{h.stopPropagation(),u({type:"REMOVE_COMPONENT",id:e.id})},[e.id,u]),E=R(h=>{h.stopPropagation(),u({type:"SELECT",id:e.id})},[e.id,u]),p=1/b.scale,I=t||o,D=3*p,q=4*p;return C("div",{onMouseDown:E,style:{position:"absolute",left:e.x,top:e.y,width:e.width,height:e.height,background:"#ffffff",display:"flex",flexDirection:"column",boxShadow:I?`0 ${2*p}px ${12*p}px rgba(0,0,0,0.12)`:`0 ${p}px ${4*p}px rgba(0,0,0,0.06)`,borderWidth:D,borderStyle:"solid",borderImage:_.borderImage,opacity:I?1:void 0},children:[x("div",{onMouseDown:E,style:{position:"absolute",inset:-(D+q),pointerEvents:"auto"}}),!I&&x("div",{style:{position:"absolute",inset:-D,pointerEvents:"none",background:"rgba(255,255,255,0.75)"}}),C("div",{ref:y,onMouseDown:f,style:{height:28*p,background:g?"#fef2f2":"#f9fafb",display:"flex",alignItems:"center",padding:`0 ${8*p}px`,cursor:"grab",userSelect:"none",borderBottom:`${p}px solid rgba(0,0,0,0.06)`,flexShrink:0,position:"relative"},children:[C("span",{style:{flex:1,fontSize:11*p,fontWeight:600,color:"#1f2937",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontFamily:"inherit",display:"flex",alignItems:"center",gap:4*p},children:[e.entry.name,!s&&x("span",{style:{fontSize:9*p,color:"#d1d5db",fontWeight:400},children:"(no route)"}),g&&x("span",{style:{fontSize:9*p,color:"#ef4444",fontWeight:600},children:"build error"}),i&&C("span",{style:{fontSize:9*p,color:"#f59e0b",fontWeight:400},children:["\u2192 ",i]})]}),C("span",{style:{fontSize:10*p,color:"#9ca3af",marginRight:6*p,whiteSpace:"nowrap",fontFamily:"inherit"},children:[Math.round(e.width),"\xD7",Math.round(e.height)]}),x("button",{onClick:v,style:{background:"none",border:"none",color:"#9ca3af",cursor:"pointer",fontSize:12*p,lineHeight:1,padding:`${2*p}px ${4*p}px`,fontFamily:"inherit"},children:"\u2715"})]}),C("div",{style:{flex:1,position:"relative",overflow:"hidden"},children:[x("iframe",{ref:l,src:e.iframeUrl,onLoad:a,sandbox:"allow-scripts allow-same-origin allow-forms allow-popups allow-modals",style:{width:"100%",height:"100%",border:"none",pointerEvents:r?"none":"auto",background:"#fff"},title:e.entry.name}),g&&!n&&C("div",{style:{position:"absolute",inset:0,background:"#fff",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:24,zIndex:2},children:[x("div",{style:{fontSize:13,color:"#991b1b",fontWeight:600},children:"Build error"}),C("div",{style:{fontSize:11,color:"#6b7280",marginTop:6,textAlign:"center"},children:["This component has unresolvable imports.",x("br",{}),"Other components are not affected."]}),x("button",{onClick:()=>c(!0),style:{marginTop:14,fontSize:11,color:"#6b7280",background:"none",border:"1px solid #e5e7eb",padding:"4px 12px",cursor:"pointer",fontFamily:"inherit"},children:"Show details"})]})]}),x("div",{onMouseDown:m,style:{position:"absolute",right:0,bottom:0,width:14*p,height:14*p,cursor:"nwse-resize",background:"linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.15) 50%)",zIndex:1}})]})}import{jsx as B,jsxs as H}from"react/jsx-runtime";var oe=.1,ne=3,re=.004;function $({state:e,dispatch:t}){let o=L(null),{viewport:r,components:b,selectedId:u,highlightedName:y,dragState:l}=e,i=L({x:0,y:0}),w=L({viewport:r,dispatch:t});w.current={viewport:r,dispatch:t};function g(n,c,s,a,f,m){let v=Math.min(ne,Math.max(oe,a)),E=v/c.scale;s({type:"SET_VIEWPORT",viewport:{scale:v,offsetX:f-(f-c.offsetX)*E,offsetY:m-(m-c.offsetY)*E}})}N(()=>{let n=o.current;if(!n)return;let c=a=>{a.preventDefault();let{viewport:f,dispatch:m}=w.current,v=n.getBoundingClientRect();if(i.current={x:a.clientX-v.left,y:a.clientY-v.top},a.ctrlKey||a.metaKey){let E=1-a.deltaY*re;g(n,f,m,f.scale*E,i.current.x,i.current.y)}else m({type:"PAN",deltaX:-a.deltaX,deltaY:-a.deltaY})},s=a=>{let f=n.getBoundingClientRect();i.current={x:a.clientX-f.left,y:a.clientY-f.top}};return n.addEventListener("wheel",c,{passive:!1}),n.addEventListener("mousemove",s),()=>{n.removeEventListener("wheel",c),n.removeEventListener("mousemove",s)}},[]),N(()=>{let n=o.current;if(!n)return;let c=s=>{if(!s.metaKey&&!s.ctrlKey)return;let{viewport:a,dispatch:f}=w.current,{x:m,y:v}=i.current;s.key==="0"?(s.preventDefault(),g(n,a,f,1,m,v)):s.key==="="||s.key==="+"?(s.preventDefault(),g(n,a,f,a.scale+.25,m,v)):s.key==="-"&&(s.preventDefault(),g(n,a,f,a.scale-.25,m,v))};return window.addEventListener("keydown",c,{capture:!0}),()=>window.removeEventListener("keydown",c,{capture:!0})},[]);let d=te(n=>{n.target!==n.currentTarget&&n.target!==o.current?.firstChild||(t({type:"SELECT",id:null}),t({type:"START_DRAG",dragState:{type:"pan",startX:n.clientX,startY:n.clientY,originOffsetX:r.offsetX,originOffsetY:r.offsetY}}))},[r.offsetX,r.offsetY,t]);return N(()=>{if(!l)return;let n=s=>{let a=s.clientX-l.startX,f=s.clientY-l.startY;switch(l.type){case"pan":t({type:"SET_VIEWPORT",viewport:{...r,offsetX:l.originOffsetX+a,offsetY:l.originOffsetY+f}});break;case"move":t({type:"MOVE_COMPONENT",id:l.componentId,x:l.originX+a/r.scale,y:l.originY+f/r.scale});break;case"resize":{let m=a/r.scale,v=f/r.scale;s.shiftKey&&(Math.abs(m)>Math.abs(v)?v=0:m=0),t({type:"RESIZE_COMPONENT",id:l.componentId,width:l.originW+m,height:l.originH+v});break}}},c=()=>{t({type:"END_DRAG"})};return window.addEventListener("mousemove",n),window.addEventListener("mouseup",c),()=>{window.removeEventListener("mousemove",n),window.removeEventListener("mouseup",c)}},[l,r,t]),H("div",{ref:o,onMouseDown:d,style:{flex:1,overflow:"hidden",position:"relative",background:"#f9fafb",cursor:l?.type==="pan"?"grabbing":"default"},children:[H("div",{style:{transform:`translate(${r.offsetX}px, ${r.offsetY}px) scale(${r.scale})`,transformOrigin:"0 0",position:"absolute",top:0,left:0},children:[B("div",{onMouseDown:d,style:{position:"fixed",top:-1e4,left:-1e4,width:2e4,height:2e4,backgroundImage:"radial-gradient(circle, rgba(0,0,0,0.1) 1px, transparent 1px)",backgroundSize:"24px 24px",pointerEvents:"auto"}}),b.map(n=>B(V,{component:n,selected:n.id===u,highlighted:n.entry.name===y,isDragging:!!l,viewport:r,dispatch:t},n.id))]}),H("div",{style:{position:"absolute",bottom:12,right:12,fontSize:10,color:"#6b7280",background:"#ffffff",padding:"3px 8px",border:"1px solid rgba(0,0,0,0.08)",userSelect:"none",fontFamily:"inherit"},children:[Math.round(r.scale*100),"%"]})]})}import{useCallback as Z,useMemo as ie,useState as J}from"react";function F(e,t){let o=`${e}::${t}`,r=5381;for(let b=0;b<o.length;b++)r=(r<<5)+r+o.charCodeAt(b)&4294967295;return(r>>>0).toString(16).padStart(8,"0")}import{jsx as S,jsxs as T}from"react/jsx-runtime";var ae=Date.now();function Q({manifest:e,viewport:t,dispatch:o,devOrigin:r,selectedName:b,highlightedName:u}){let[y,l]=J(""),i=ie(()=>{if(!e)return new Map;let d=new Map,n=y.toLowerCase();for(let c of e.components){if(n&&!c.name.toLowerCase().includes(n))continue;let s=c.category||"root",a=d.get(s)??[];a.push(c),d.set(s,a)}return d},[e,y]),w=Z(d=>{let n={x:(window.innerWidth-260)/2+260,y:window.innerHeight/2},c=X(n.x,n.y,t),s=400,a=300,f=F(d.filePath,d.name),m=`${r}/popmelt/render/${f}`,v={id:`placed-${++ae}`,entry:d,x:c.x-s/2,y:c.y-a/2,width:s,height:a,iframeUrl:m};o({type:"PLACE_COMPONENT",component:v})},[t,o,r]),g=Z(d=>{o({type:"HIGHLIGHT",name:d})},[o]);return T("div",{style:{width:260,height:"100%",background:"#ffffff",borderRight:"1px solid rgba(0,0,0,0.08)",display:"flex",flexDirection:"column",flexShrink:0,overflow:"hidden"},children:[T("div",{style:{padding:"12px 12px 8px",borderBottom:"1px solid rgba(0,0,0,0.08)"},children:[S("div",{style:{fontSize:11,fontWeight:700,color:"#1f2937",marginBottom:8,letterSpacing:"0.5px",textTransform:"uppercase"},children:"Components"}),S("input",{type:"text",placeholder:"search...",value:y,onChange:d=>l(d.target.value),style:{width:"100%",padding:"5px 8px",fontSize:12,background:"#f9fafb",border:"1px solid rgba(0,0,0,0.1)",borderRadius:0,color:"#1f2937",outline:"none",boxSizing:"border-box",fontFamily:"inherit"}})]}),T("div",{style:{flex:1,overflowY:"auto",overflowX:"hidden",padding:"4px 0"},children:[!e&&S("div",{style:{padding:12,fontSize:11,color:"#9ca3af"},children:"loading..."}),e&&i.size===0&&S("div",{style:{padding:12,fontSize:11,color:"#9ca3af"},children:"no components found"}),[...i.entries()].map(([d,n])=>S(se,{category:d,entries:n,onPlace:w,onHover:g,selectedName:b,highlightedName:u},d))]})]})}function se({category:e,entries:t,onPlace:o,onHover:r,selectedName:b,highlightedName:u}){let[y,l]=J(!1);return T("div",{children:[T("div",{onClick:()=>l(i=>!i),style:{padding:"6px 12px",fontSize:10,fontWeight:700,color:y?"#9ca3af":"#1f2937",textTransform:"uppercase",letterSpacing:"0.5px",cursor:"pointer",userSelect:"none",display:"flex",alignItems:"center",gap:4,transition:"color 0.15s"},children:[S("span",{style:{color:"#9ca3af",fontWeight:400},children:y?"[+]":"[-]"}),e,S("span",{style:{color:"#d1d5db",marginLeft:"auto",fontWeight:400},children:t.length})]}),!y&&t.map(i=>{let w=i.name===b,g=i.name===u,d=w||g;return T("div",{onClick:()=>o(i),onMouseEnter:()=>r(i.name),onMouseLeave:()=>r(null),style:{padding:"5px 12px 5px 24px",cursor:"pointer",borderLeft:d?"2px solid #1f2937":"2px solid transparent",background:d?"#f9fafb":"transparent",transition:"background 0.1s, border-color 0.1s"},children:[S("div",{style:{fontSize:12,color:"#1f2937",fontWeight:600},children:i.name}),S("div",{style:{fontSize:10,color:"#9ca3af",marginTop:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:i.filePath}),i.routes&&i.routes.length>0?S("div",{style:{display:"flex",gap:3,marginTop:3,flexWrap:"wrap"},children:i.routes.map(n=>S("span",{style:{fontSize:9,padding:"1px 4px",background:"#f3f4f6",color:"#6b7280",border:"1px solid rgba(0,0,0,0.06)"},children:n},n))}):S("div",{style:{fontSize:9,color:"#d1d5db",marginTop:3},children:"(no route)"})]},i.name+i.filePath)})]})}import{jsx as U,jsxs as ue}from"react/jsx-runtime";var fe='"JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace';function j({devOrigin:e,bridgeOrigin:t}){let[o,r]=de(W,k,i=>({...i,...A()})),[b,u]=pe(null),y=ce(void 0);K(()=>(clearTimeout(y.current),y.current=setTimeout(()=>Y(o),300),()=>clearTimeout(y.current)),[o.components,o.viewport]);let l=le(()=>o.selectedId?o.components.find(i=>i.id===o.selectedId)?.entry.name??null:null,[o.selectedId,o.components]);return K(()=>{let i=!1;async function w(){try{let g=await fetch(`${t}/canvas/manifest`);if(!g.ok)throw new Error(`HTTP ${g.status}`);let d=await g.json();i||u(d)}catch(g){console.error("[Popmelt Canvas] Failed to load manifest:",g)}}return w(),()=>{i=!0}},[t]),ue("div",{style:{display:"flex",flexDirection:"row",width:"100vw",height:"100vh",fontFamily:fe,color:"#1f2937",background:"#ffffff"},children:[U(Q,{manifest:b,viewport:o.viewport,dispatch:r,devOrigin:e,selectedName:l,highlightedName:o.highlightedName}),U($,{state:o,dispatch:r})]})}function _e(e,t){ge(e).render(me(j,t))}export{_e as mountCanvas};
1
+ import{createRoot as ge}from"react-dom/client";import{createElement as me}from"react";import{useEffect as K,useMemo as le,useReducer as de,useRef as ce,useState as pe}from"react";var z="popmelt-canvas";function M(e){return Math.round(e/24)*24}var k={viewport:{offsetX:0,offsetY:0,scale:1},components:[],selectedId:null,highlightedName:null,dragState:null};function A(){try{let e=localStorage.getItem(z);if(!e)return{};let t=JSON.parse(e);return{components:t.components??[],viewport:t.viewport??k.viewport}}catch{return{}}}function Y(e){try{let t={components:e.components,viewport:e.viewport};localStorage.setItem(z,JSON.stringify(t))}catch{}}function W(e,t){switch(t.type){case"PLACE_COMPONENT":{let o=t.component,r={...o,x:M(o.x),y:M(o.y),width:M(o.width),height:M(o.height)};return{...e,components:[...e.components,r],selectedId:r.id}}case"REMOVE_COMPONENT":return{...e,components:e.components.filter(o=>o.id!==t.id),selectedId:e.selectedId===t.id?null:e.selectedId};case"MOVE_COMPONENT":return{...e,components:e.components.map(o=>o.id===t.id?{...o,x:M(t.x),y:M(t.y)}:o)};case"RESIZE_COMPONENT":return{...e,components:e.components.map(o=>o.id===t.id?{...o,width:Math.max(200,t.width),height:Math.max(150,t.height)}:o)};case"SELECT":return{...e,selectedId:t.id};case"SET_VIEWPORT":return{...e,viewport:t.viewport};case"PAN":return{...e,viewport:{...e.viewport,offsetX:e.viewport.offsetX+t.deltaX,offsetY:e.viewport.offsetY+t.deltaY}};case"START_DRAG":return{...e,dragState:t.dragState};case"END_DRAG":return{...e,dragState:null};case"HIGHLIGHT":return{...e,highlightedName:t.name};default:return e}}function X(e,t,o){return{x:(e-o.offsetX)/o.scale,y:(t-o.offsetY)/o.scale}}import{useCallback as te,useEffect as N,useRef as L}from"react";import{useCallback as R,useRef as G,useState as O}from"react";var ee="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMicgaGVpZ2h0PScxMic+PGRlZnM+PHBhdHRlcm4gaWQ9J2QnIHdpZHRoPSc0JyBoZWlnaHQ9JzQnIHBhdHRlcm5Vbml0cz0ndXNlclNwYWNlT25Vc2UnPjxwYXRoIGQ9J00tMSwxIGwyLC0yIE0wLDQgbDQsLTQgTTMsNSBsMiwtMicgc3Ryb2tlPSdibGFjaycgc3Ryb2tlLXdpZHRoPScuNScvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgd2lkdGg9JzEyJyBoZWlnaHQ9JzEyJyBmaWxsPSd1cmwoI2QpJy8+PC9zdmc+",_={borderWidth:3,borderStyle:"solid",borderImage:`url("${ee}") 4 / 1.9 / 0 round`};import{jsx as x,jsxs as C}from"react/jsx-runtime";function V({component:e,selected:t,highlighted:o,isDragging:r,viewport:b,dispatch:u}){let y=G(null),l=G(null),[i,w]=O(null),[g,d]=O(!1),[n,c]=O(!1),s=e.entry.routes&&e.entry.routes.length>0,a=R(()=>{d(!1),c(!1);try{let h=l.current?.contentWindow?.location.pathname;if(!h)return;let P=new URL(e.iframeUrl).pathname;h!==P&&w(h)}catch{}setTimeout(()=>{try{l.current?.contentDocument?.querySelector("nextjs-portal")&&d(!0)}catch{}},2e3)},[e.iframeUrl]),f=R(h=>{h.stopPropagation(),u({type:"SELECT",id:e.id});let P={type:"move",componentId:e.id,startX:h.clientX,startY:h.clientY,originX:e.x,originY:e.y};u({type:"START_DRAG",dragState:P})},[e.id,e.x,e.y,u]),m=R(h=>{h.stopPropagation(),h.preventDefault(),u({type:"SELECT",id:e.id});let P={type:"resize",componentId:e.id,startX:h.clientX,startY:h.clientY,originW:e.width,originH:e.height};u({type:"START_DRAG",dragState:P})},[e.id,e.width,e.height,u]),v=R(h=>{h.stopPropagation(),u({type:"REMOVE_COMPONENT",id:e.id})},[e.id,u]),E=R(h=>{h.stopPropagation(),u({type:"SELECT",id:e.id})},[e.id,u]),p=1/b.scale,I=t||o,D=3*p,q=4*p;return C("div",{onMouseDown:E,style:{position:"absolute",left:e.x,top:e.y,width:e.width,height:e.height,background:"#ffffff",display:"flex",flexDirection:"column",boxShadow:I?`0 ${2*p}px ${12*p}px rgba(0,0,0,0.12)`:`0 ${p}px ${4*p}px rgba(0,0,0,0.06)`,borderWidth:D,borderStyle:"solid",borderImage:_.borderImage,opacity:I?1:void 0},children:[x("div",{onMouseDown:E,style:{position:"absolute",inset:-(D+q),pointerEvents:"auto"}}),!I&&x("div",{style:{position:"absolute",inset:-D,pointerEvents:"none",background:"rgba(255,255,255,0.75)"}}),C("div",{ref:y,onMouseDown:f,style:{height:28*p,background:g?"#fef2f2":"#f9fafb",display:"flex",alignItems:"center",padding:`0 ${8*p}px`,cursor:"grab",userSelect:"none",borderBottom:`${p}px solid rgba(0,0,0,0.06)`,flexShrink:0,position:"relative"},children:[C("span",{style:{flex:1,fontSize:11*p,fontWeight:600,color:"#1f2937",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontFamily:"inherit",display:"flex",alignItems:"center",gap:4*p},children:[e.entry.name,!s&&x("span",{style:{fontSize:9*p,color:"#d1d5db",fontWeight:400},children:"(no route)"}),g&&x("span",{style:{fontSize:9*p,color:"#ef4444",fontWeight:600},children:"build error"}),i&&C("span",{style:{fontSize:9*p,color:"#f59e0b",fontWeight:400},children:["\u2192 ",i]})]}),C("span",{style:{fontSize:10*p,color:"#9ca3af",marginRight:6*p,whiteSpace:"nowrap",fontFamily:"inherit"},children:[Math.round(e.width),"\xD7",Math.round(e.height)]}),x("button",{onClick:v,style:{background:"none",border:"none",color:"#9ca3af",cursor:"pointer",fontSize:12*p,lineHeight:1,padding:`${2*p}px ${4*p}px`,fontFamily:"inherit"},children:"\u2715"})]}),C("div",{style:{flex:1,position:"relative",overflow:"hidden"},children:[x("iframe",{ref:l,src:e.iframeUrl,onLoad:a,sandbox:"allow-scripts allow-same-origin allow-forms allow-popups allow-modals",style:{width:"100%",height:"100%",border:"none",pointerEvents:r?"none":"auto",background:"#fff"},title:e.entry.name}),g&&!n&&C("div",{style:{position:"absolute",inset:0,background:"#fff",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:24,zIndex:2},children:[x("div",{style:{fontSize:13,color:"#991b1b",fontWeight:600},children:"Build error"}),C("div",{style:{fontSize:11,color:"#6b7280",marginTop:6,textAlign:"center"},children:["This component has unresolvable imports.",x("br",{}),"Other components are not affected."]}),x("button",{onClick:()=>c(!0),style:{marginTop:14,fontSize:11,color:"#6b7280",background:"none",border:"1px solid #e5e7eb",padding:"4px 12px",cursor:"pointer",fontFamily:"inherit"},children:"Show details"})]})]}),x("div",{onMouseDown:m,style:{position:"absolute",right:0,bottom:0,width:14*p,height:14*p,cursor:"nwse-resize",background:"linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.15) 50%)",zIndex:1}})]})}import{jsx as B,jsxs as H}from"react/jsx-runtime";var oe=.1,ne=3,re=.004;function $({state:e,dispatch:t}){let o=L(null),{viewport:r,components:b,selectedId:u,highlightedName:y,dragState:l}=e,i=L({x:0,y:0}),w=L({viewport:r,dispatch:t});w.current={viewport:r,dispatch:t};function g(n,c,s,a,f,m){let v=Math.min(ne,Math.max(oe,a)),E=v/c.scale;s({type:"SET_VIEWPORT",viewport:{scale:v,offsetX:f-(f-c.offsetX)*E,offsetY:m-(m-c.offsetY)*E}})}N(()=>{let n=o.current;if(!n)return;let c=a=>{a.preventDefault();let{viewport:f,dispatch:m}=w.current,v=n.getBoundingClientRect();if(i.current={x:a.clientX-v.left,y:a.clientY-v.top},a.ctrlKey||a.metaKey){let E=1-a.deltaY*re;g(n,f,m,f.scale*E,i.current.x,i.current.y)}else m({type:"PAN",deltaX:-a.deltaX,deltaY:-a.deltaY})},s=a=>{let f=n.getBoundingClientRect();i.current={x:a.clientX-f.left,y:a.clientY-f.top}};return n.addEventListener("wheel",c,{passive:!1}),n.addEventListener("mousemove",s),()=>{n.removeEventListener("wheel",c),n.removeEventListener("mousemove",s)}},[]),N(()=>{let n=o.current;if(!n)return;let c=s=>{if(!s.metaKey&&!s.ctrlKey)return;let{viewport:a,dispatch:f}=w.current,{x:m,y:v}=i.current;s.key==="0"?(s.preventDefault(),g(n,a,f,1,m,v)):s.key==="="||s.key==="+"?(s.preventDefault(),g(n,a,f,a.scale+.25,m,v)):s.key==="-"&&(s.preventDefault(),g(n,a,f,a.scale-.25,m,v))};return window.addEventListener("keydown",c,{capture:!0}),()=>window.removeEventListener("keydown",c,{capture:!0})},[]);let d=te(n=>{n.target!==n.currentTarget&&n.target!==o.current?.firstChild||(t({type:"SELECT",id:null}),t({type:"START_DRAG",dragState:{type:"pan",startX:n.clientX,startY:n.clientY,originOffsetX:r.offsetX,originOffsetY:r.offsetY}}))},[r.offsetX,r.offsetY,t]);return N(()=>{if(!l)return;let n=s=>{let a=s.clientX-l.startX,f=s.clientY-l.startY;switch(l.type){case"pan":t({type:"SET_VIEWPORT",viewport:{...r,offsetX:l.originOffsetX+a,offsetY:l.originOffsetY+f}});break;case"move":t({type:"MOVE_COMPONENT",id:l.componentId,x:l.originX+a/r.scale,y:l.originY+f/r.scale});break;case"resize":{let m=a/r.scale,v=f/r.scale;s.shiftKey&&(Math.abs(m)>Math.abs(v)?v=0:m=0),t({type:"RESIZE_COMPONENT",id:l.componentId,width:l.originW+m,height:l.originH+v});break}}},c=()=>{t({type:"END_DRAG"})};return window.addEventListener("mousemove",n),window.addEventListener("mouseup",c),()=>{window.removeEventListener("mousemove",n),window.removeEventListener("mouseup",c)}},[l,r,t]),H("div",{ref:o,onMouseDown:d,style:{flex:1,overflow:"hidden",position:"relative",background:"#f9fafb",cursor:l?.type==="pan"?"grabbing":"default"},children:[H("div",{style:{transform:`translate(${r.offsetX}px, ${r.offsetY}px) scale(${r.scale})`,transformOrigin:"0 0",position:"absolute",top:0,left:0},children:[B("div",{onMouseDown:d,style:{position:"fixed",top:-1e4,left:-1e4,width:2e4,height:2e4,backgroundImage:"radial-gradient(circle, rgba(0,0,0,0.1) 1px, transparent 1px)",backgroundSize:"24px 24px",pointerEvents:"auto"}}),b.map(n=>B(V,{component:n,selected:n.id===u,highlighted:n.entry.name===y,isDragging:!!l,viewport:r,dispatch:t},n.id))]}),H("div",{style:{position:"absolute",bottom:12,right:12,fontSize:10,color:"#6b7280",background:"#ffffff",padding:"3px 8px",border:"1px solid rgba(0,0,0,0.08)",userSelect:"none",fontFamily:"inherit"},children:[Math.round(r.scale*100),"%"]})]})}import{useCallback as Z,useMemo as ie,useState as J}from"react";function F(e,t){let o=`${e}::${t}`,r=5381;for(let b=0;b<o.length;b++)r=(r<<5)+r+o.charCodeAt(b)&4294967295;return(r>>>0).toString(16).padStart(8,"0")}import{jsx as S,jsxs as T}from"react/jsx-runtime";var ae=Date.now();function Q({manifest:e,viewport:t,dispatch:o,devOrigin:r,selectedName:b,highlightedName:u}){let[y,l]=J(""),i=ie(()=>{if(!e)return new Map;let d=new Map,n=y.toLowerCase();for(let c of e.components){if(n&&!c.name.toLowerCase().includes(n))continue;let s=c.category||"root",a=d.get(s)??[];a.push(c),d.set(s,a)}return d},[e,y]),w=Z(d=>{let n={x:(window.innerWidth-260)/2+260,y:window.innerHeight/2},c=X(n.x,n.y,t),s=400,a=300,f=F(d.filePath,d.name),m=`${r}/popmelt/render/${f}`,v={id:`placed-${++ae}`,entry:d,x:c.x-s/2,y:c.y-a/2,width:s,height:a,iframeUrl:m};o({type:"PLACE_COMPONENT",component:v})},[t,o,r]),g=Z(d=>{o({type:"HIGHLIGHT",name:d})},[o]);return T("div",{style:{width:260,height:"100%",background:"#ffffff",borderRight:"1px solid rgba(0,0,0,0.08)",display:"flex",flexDirection:"column",flexShrink:0,overflow:"hidden"},children:[T("div",{style:{padding:"12px 12px 8px",borderBottom:"1px solid rgba(0,0,0,0.08)"},children:[S("div",{style:{fontSize:11,fontWeight:700,color:"#1f2937",marginBottom:8,letterSpacing:"0.5px",textTransform:"uppercase"},children:"Components"}),S("input",{type:"text",placeholder:"search...",value:y,onChange:d=>l(d.target.value),style:{width:"100%",padding:"5px 8px",fontSize:12,background:"#f9fafb",border:"1px solid rgba(0,0,0,0.1)",borderRadius:0,color:"#1f2937",outline:"none",boxSizing:"border-box",fontFamily:"inherit"}})]}),T("div",{style:{flex:1,overflowY:"auto",overflowX:"hidden",padding:"4px 0"},children:[!e&&S("div",{style:{padding:12,fontSize:11,color:"#9ca3af"},children:"loading..."}),e&&i.size===0&&S("div",{style:{padding:12,fontSize:11,color:"#9ca3af"},children:"no components found"}),[...i.entries()].map(([d,n])=>S(se,{category:d,entries:n,onPlace:w,onHover:g,selectedName:b,highlightedName:u},d))]})]})}function se({category:e,entries:t,onPlace:o,onHover:r,selectedName:b,highlightedName:u}){let[y,l]=J(!1);return T("div",{children:[T("div",{onClick:()=>l(i=>!i),style:{padding:"6px 12px",fontSize:10,fontWeight:700,color:y?"#9ca3af":"#1f2937",textTransform:"uppercase",letterSpacing:"0.5px",cursor:"pointer",userSelect:"none",display:"flex",alignItems:"center",gap:4,transition:"color 0.15s"},children:[S("span",{style:{color:"#9ca3af",fontWeight:400},children:y?"[+]":"[-]"}),e,S("span",{style:{color:"#d1d5db",marginLeft:"auto",fontWeight:400},children:t.length})]}),!y&&t.map(i=>{let w=i.name===b,g=i.name===u,d=w||g;return T("div",{onClick:()=>o(i),onMouseEnter:()=>r(i.name),onMouseLeave:()=>r(null),style:{padding:"5px 12px 5px 24px",cursor:"pointer",borderLeft:d?"2px solid #1f2937":"2px solid transparent",background:d?"#f9fafb":"transparent",transition:"background 0.1s, border-color 0.1s"},children:[S("div",{style:{fontSize:12,color:"#1f2937",fontWeight:600},children:i.name}),S("div",{style:{fontSize:10,color:"#9ca3af",marginTop:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:i.filePath}),i.routes&&i.routes.length>0?S("div",{style:{display:"flex",gap:3,marginTop:3,flexWrap:"wrap"},children:i.routes.map(n=>S("span",{style:{fontSize:9,padding:"1px 4px",background:"#f3f4f6",color:"#6b7280",border:"1px solid rgba(0,0,0,0.06)"},children:n},n))}):S("div",{style:{fontSize:9,color:"#d1d5db",marginTop:3},children:"(no route)"})]},i.name+i.filePath)})]})}import{jsx as U,jsxs as ue}from"react/jsx-runtime";var fe='"JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace';function j({devOrigin:e,bridgeOrigin:t}){let[o,r]=de(W,k,i=>({...i,...A()})),[b,u]=pe(null),y=ce(void 0);K(()=>(clearTimeout(y.current),y.current=setTimeout(()=>Y(o),300),()=>clearTimeout(y.current)),[o.components,o.viewport]);let l=le(()=>o.selectedId?o.components.find(i=>i.id===o.selectedId)?.entry.name??null:null,[o.selectedId,o.components]);return K(()=>{let i=!1;async function w(){try{let g=await fetch(`${t}/canvas/manifest`);if(!g.ok)throw new Error(`HTTP ${g.status}`);let d=await g.json();i||u(d)}catch(g){console.error("[Popmelt Canvas] Failed to load manifest:",g)}}return w(),()=>{i=!0}},[t]),ue("div",{style:{display:"flex",flexDirection:"row",width:"100vw",height:"100dvh",fontFamily:fe,color:"#1f2937",background:"#ffffff"},children:[U(Q,{manifest:b,viewport:o.viewport,dispatch:r,devOrigin:e,selectedName:l,highlightedName:o.highlightedName}),U($,{state:o,dispatch:r})]})}function _e(e,t){ge(e).render(me(j,t))}export{_e as mountCanvas};
@@ -0,0 +1 @@
1
+ import{a as c}from"./chunk-NOHXTT24.mjs";import{request as d}from"http";function u(){let e=process.env.POPMELT_BRIDGE_URL;if(!e)return null;try{let r=new URL(e);return{port:r.port?Number.parseInt(r.port,10):null,projectId:process.env.POPMELT_PROJECT_ID||null,leaseEligible:!1}}catch{return null}}async function h(e,r,n){let t=u();if(e?.bridge===!1||t)return t??{port:null,projectId:null,leaseEligible:!1};try{let{startPopmelt:i}=await import("./server-DDE2RMDV.mjs"),o=r.config?.server?.host,l=o===!0?"0.0.0.0":o||"localhost",s=r.config?.server?.port??n,a=`http://${l==="0.0.0.0"?"localhost":l}:${s}`,p=await i({port:e?.port,projectRoot:e?.projectRoot,devOrigin:a,force:!0,detached:!0,manageLease:!1});return console.log(`[popmelt] bridge ready at http://localhost:${p.port}`),{port:p.port,projectId:p.projectId,leaseEligible:!0}}catch(i){let o=i instanceof Error?i.message:String(i);return console.warn("[popmelt] bridge failed to start:",o),{port:null,projectId:null,leaseEligible:!1}}}async function v(e,r,n=fetch){if(!e.leaseEligible||e.port===null)return null;let t=await c({port:e.port,projectId:e.projectId},n);if(!t)return null;let i=()=>{o()},o=async()=>{process.removeListener("beforeExit",i),await t.release()};return process.once("beforeExit",i),r.httpServer?.once("close",()=>{o()}),{id:t.id,release:o}}function g(e,r,n){if(n.port===null)return null;let t=new URL(r,"http://popmelt.local");if(t.pathname!==e&&!t.pathname.startsWith(`${e}/`))return null;let i=t.pathname.slice(e.length),o=i==="/status"?"/status":`/canvas${i}`,l=new URL(o,`http://localhost:${n.port}`);return t.searchParams.forEach((s,a)=>l.searchParams.append(a,s)),n.projectId&&l.searchParams.set("projectId",n.projectId),l}function b(e,r){return(n,t,i)=>{let o=g(e,n.url||"",r());if(!o)return i();let l=d(o,{method:n.method,headers:{...n.headers,host:o.host}},s=>{t.writeHead(s.statusCode||502,s.headers),s.pipe(t)});l.on("error",()=>{t.writeHead(502,{"Content-Type":"text/plain"}),t.end(`Popmelt bridge not running on port ${r().port}`)}),n.pipe(l)}}function P(e){let r=e.port===null?null:`http://localhost:${e.port}`;return`window.__POPMELT_BRIDGE_URL__=${JSON.stringify(r)};window.__POPMELT_PROJECT_ID__=${JSON.stringify(e.projectId)};`}export{h as a,v as b,b as c,P as d};