rari 0.10.16 → 0.10.17

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/client.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import{i as e,t}from"./navigate-DPJioMXn.mjs";import{a as n,c as r,d as i,f as a,g as o,h as s,i as c,l,m as u,n as d,o as f,p,r as m,s as h,t as g,u as _}from"./runtime-client-Bg4V1Ksp.mjs";import{Component as v,useEffect as y,useLayoutEffect as b,useRef as x,useState as S}from"react";import{Fragment as C,jsx as w,jsxs as T}from"react/jsx-runtime";function E(e,t,n={}){let r=null,i=0,a=0,o=null,s=null,{leading:c=!1,trailing:l=!0,maxWait:u}=n;function d(t){let n=o,r=s;return o=null,s=null,a=t,e.apply(r,n)}function f(e){let n=e-i,r=e-a;return i===0||n>=t||n<0||u!==void 0&&r>=u}function p(){let e=Date.now();if(f(e))return h(e);let n=e-i,o=e-a,s=t-n,c=u===void 0?1/0:u-o,l=Math.min(s,c);r=setTimeout(p,l)}function m(e){return a=e,r=setTimeout(p,t),c?d(e):void 0}function h(e){if(r=null,l&&o)return d(e);o=null,s=null}function g(){r!==null&&clearTimeout(r),a=0,o=null,i=0,s=null,r=null}function _(){return r===null?void 0:h(Date.now())}function v(){return r!==null}function y(...e){let n=Date.now(),a=f(n);if(o=e,s=this,i=n,a){if(r===null)return m(i);if(u!==void 0)return r=setTimeout(p,t),d(i)}r===null&&(r=setTimeout(p,t))}return y.cancel=g,y.flush=_,y.pending=v,y}function D(e,t){if(e instanceof Error&&e.name===`AbortError`)return{type:`abort`,message:`Navigation was cancelled`,originalError:e,url:t,timestamp:Date.now(),retryable:!1};if(e instanceof Error&&e.message.includes(`timeout`))return{type:`timeout`,message:`Navigation request timed out`,originalError:e,url:t,timestamp:Date.now(),retryable:!0};if(e instanceof Error&&`status`in e){let n=e.status;return n===404?{type:`not-found`,message:`Page not found`,originalError:e,statusCode:n,url:t,timestamp:Date.now(),retryable:!1}:n>=500?{type:`server-error`,message:`Server error: ${n}`,originalError:e,statusCode:n,url:t,timestamp:Date.now(),retryable:!0}:{type:`fetch-error`,message:`HTTP error: ${n}`,originalError:e,statusCode:n,url:t,timestamp:Date.now(),retryable:n>=500}}return e instanceof TypeError&&e.message.includes(`fetch`)?{type:`network-error`,message:`Network error - check your connection`,originalError:e,url:t,timestamp:Date.now(),retryable:!0}:e instanceof SyntaxError||e instanceof Error&&e.message.includes(`parse`)?{type:`parse-error`,message:`Failed to parse server response`,originalError:e instanceof Error?e:void 0,url:t,timestamp:Date.now(),retryable:!1}:{type:`fetch-error`,message:e instanceof Error?e.message:`Unknown error occurred`,originalError:e instanceof Error?e:void 0,url:t,timestamp:Date.now(),retryable:!1}}var O=class{options;retryCount;constructor(e={}){this.options={timeout:e.timeout??1e4,maxRetries:e.maxRetries??3,onError:e.onError??(()=>{}),onRetry:e.onRetry??(()=>{})},this.retryCount=new Map}handleError(e,t){let n=D(e,t);return this.options.onError(n),console.error(`[rari] Navigation:`,n.type,n.message,{url:n.url,statusCode:n.statusCode,retryable:n.retryable}),typeof window<`u`&&window.dispatchEvent(new CustomEvent(`rari:navigation-error`,{detail:n})),n}canRetry(e,t){return e.retryable?(this.retryCount.get(t)??0)<this.options.maxRetries:!1}incrementRetry(e){let t=(this.retryCount.get(e)??0)+1;return this.retryCount.set(e,t),this.options.onRetry(t,{type:`fetch-error`,message:`Retry attempt ${t}`,url:e,timestamp:Date.now(),retryable:!0}),t}resetRetry(e){this.retryCount.delete(e)}getRetryCount(e){return this.retryCount.get(e)??0}clearRetries(){this.retryCount.clear()}};const k=/(^\/+)|(\/+$)/g;function A(e){let t=e.replace(k,``);return t?t.split(`/`):[]}function j(e,t,n){let r=A(n),i={},a=0;for(let e=0;e<t.length;e++){let n=t[e];if(a>=r.length){if(n.type===`optional-catch-all`){n.param&&(i[n.param]=[]);continue}return null}switch(n.type){case`static`:if(r[a]!==n.value)return null;a++;break;case`dynamic`:n.param&&(i[n.param]=r[a]),a++;break;case`catch-all`:case`optional-catch-all`:n.param&&(i[n.param]=r.slice(a)),a=r.length;break}}return a===r.length?i:null}function M(e){if(!e||e===`/`)return`/`;let t=e;for(;t.endsWith(`/`)&&t.length>1;)t=t.slice(0,-1);return t.startsWith(`/`)||(t=`/${t}`),t}function N(e,t){try{return new URL(e,t||window.location.origin).origin!==(t||window.location.origin)}catch{return!1}}function P(e){try{let t=new URL(e,window.location.origin);return t.pathname+t.hash}catch{return e}}function F({error:e,onRetry:t,onReload:n,onDismiss:r,retryCount:i=0,maxRetries:a=3}){let o=e.retryable&&i<a;return w(`div`,{style:{position:`fixed`,top:0,left:0,right:0,bottom:0,background:`rgba(0, 0, 0, 0.5)`,display:`flex`,alignItems:`center`,justifyContent:`center`,zIndex:1e4,padding:`20px`},onClick:e=>{e.target===e.currentTarget&&r&&r()},children:T(`div`,{style:{background:`white`,borderRadius:`8px`,padding:`24px`,maxWidth:`500px`,width:`100%`,boxShadow:`0 4px 12px rgba(0, 0, 0, 0.15)`},onClick:e=>e.stopPropagation(),children:[T(`div`,{style:{display:`flex`,alignItems:`center`,gap:`12px`,marginBottom:`16px`},children:[w(`span`,{style:{fontSize:`32px`},children:(()=>{switch(e.type){case`timeout`:return`⏱️`;case`network-error`:return`📡`;case`not-found`:return`🔍`;case`server-error`:return`⚠️`;case`parse-error`:return`📄`;case`abort`:return`🚫`;default:return`❌`}})()}),w(`h2`,{style:{margin:0,fontSize:`20px`,fontWeight:`600`,color:`#1f2937`},children:`Navigation Error`})]}),w(`p`,{style:{margin:`0 0 16px 0`,fontSize:`15px`,lineHeight:`1.5`,color:`#4b5563`},children:(()=>{switch(e.type){case`timeout`:return`The page took too long to load. Please try again.`;case`network-error`:return`Unable to connect to the server. Please check your internet connection.`;case`not-found`:return`The page you're looking for doesn't exist.`;case`server-error`:return`The server encountered an error. Please try again in a moment.`;case`parse-error`:return`Unable to load the page content. Please try reloading.`;case`abort`:return`Navigation was cancelled.`;default:return e.message||`An unexpected error occurred.`}})()}),e.url&&T(`details`,{style:{marginBottom:`16px`,fontSize:`13px`,color:`#6b7280`},children:[w(`summary`,{style:{cursor:`pointer`,userSelect:`none`,marginBottom:`8px`},children:`Technical details`}),T(`div`,{style:{padding:`12px`,background:`#f9fafb`,borderRadius:`4px`,fontFamily:`monospace`,fontSize:`12px`,wordBreak:`break-all`},children:[T(`div`,{style:{marginBottom:`4px`},children:[w(`strong`,{children:`URL:`}),` `,e.url]}),e.statusCode&&T(`div`,{style:{marginBottom:`4px`},children:[w(`strong`,{children:`Status:`}),` `,e.statusCode]}),T(`div`,{style:{marginBottom:`4px`},children:[w(`strong`,{children:`Type:`}),` `,e.type]}),e.originalError&&T(`div`,{children:[w(`strong`,{children:`Error:`}),` `,e.originalError.message]})]})]}),o&&i>0&&T(`div`,{style:{marginBottom:`16px`,padding:`8px 12px`,background:`#fef3c7`,border:`1px solid #fbbf24`,borderRadius:`4px`,fontSize:`13px`,color:`#92400e`},children:[`Retry attempt`,` `,i,` `,`of`,` `,a]}),T(`div`,{style:{display:`flex`,gap:`8px`,flexWrap:`wrap`},children:[o&&t&&w(`button`,{onClick:t,type:`button`,style:{flex:1,minWidth:`120px`,padding:`10px 16px`,background:`#3b82f6`,color:`white`,border:`none`,borderRadius:`6px`,fontSize:`14px`,fontWeight:`500`,cursor:`pointer`,transition:`background 0.2s`},onMouseEnter:e=>{e.currentTarget.style.background=`#2563eb`},onMouseLeave:e=>{e.currentTarget.style.background=`#3b82f6`},children:`Try Again`}),n&&w(`button`,{onClick:n,type:`button`,style:{flex:1,minWidth:`120px`,padding:`10px 16px`,background:`#6b7280`,color:`white`,border:`none`,borderRadius:`6px`,fontSize:`14px`,fontWeight:`500`,cursor:`pointer`,transition:`background 0.2s`},onMouseEnter:e=>{e.currentTarget.style.background=`#4b5563`},onMouseLeave:e=>{e.currentTarget.style.background=`#6b7280`},children:`Reload Page`}),r&&w(`button`,{onClick:r,type:`button`,style:{flex:1,minWidth:`120px`,padding:`10px 16px`,background:`transparent`,color:`#6b7280`,border:`1px solid #d1d5db`,borderRadius:`6px`,fontSize:`14px`,fontWeight:`500`,cursor:`pointer`,transition:`all 0.2s`},onMouseEnter:e=>{e.currentTarget.style.background=`#f9fafb`,e.currentTarget.style.borderColor=`#9ca3af`},onMouseLeave:e=>{e.currentTarget.style.background=`transparent`,e.currentTarget.style.borderColor=`#d1d5db`},children:`Dismiss`})]}),w(`p`,{style:{marginTop:`16px`,marginBottom:0,fontSize:`12px`,color:`#9ca3af`,textAlign:`center`},children:`Your current page is still available below this message`})]})})}const I=new class{cache=new Map;pendingRequests=new Map;async get(e){let t=this.cache.get(e);if(t)return t;let n=this.pendingRequests.get(e);if(n)return n;let r=this.fetchRouteInfo(e);this.pendingRequests.set(e,r);try{let t=await r;return this.cache.set(e,t),t}finally{this.pendingRequests.delete(e)}}async fetchRouteInfo(e){let t={path:e},n=await fetch(`/_rari/route-info`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!n.ok){let e=null;try{e=await n.json()}catch{}throw e?.error?Error(e.error):Error(`Failed to fetch route info: ${n.status} ${n.statusText}`)}let r=n.clone();try{return await n.json()}catch(t){try{let e=await r.text();return JSON.parse(e)}catch(n){throw console.error(`[RouteInfo] Failed to parse response:`,{error:t,parseError:n,path:e}),Error(`Failed to parse route info response`)}}}clear(){this.cache.clear(),this.pendingRequests.clear()}invalidate(e){this.cache.delete(e)}};if(typeof window<`u`){let e=window[`~rari`]||{};window[`~rari`]||(window[`~rari`]=e),e.routeInfoCache=I}var L=class{stateHistory;routeAccessOrder;maxHistorySize;scrollableSelector;constructor(e={}){this.stateHistory=new Map,this.routeAccessOrder=[],this.maxHistorySize=e.maxHistorySize||50,this.scrollableSelector=e.scrollableSelector||`[data-scrollable], .scrollable, [style*="overflow"]`}captureState(e){let t={scrollPositions:this.captureScrollPositions(),formData:this.captureFormData(),focusedElement:this.captureFocusedElement()};return this.storeState(e,t),t}captureScrollPositions(){let e=new Map;try{e.set(`window`,{x:window.scrollX,y:window.scrollY,element:`window`}),document.querySelectorAll(this.scrollableSelector).forEach((t,n)=>{if(t instanceof HTMLElement){let r=t.id||`scrollable-${n}`;(t.scrollHeight>t.clientHeight||t.scrollWidth>t.clientWidth)&&e.set(r,{x:t.scrollLeft,y:t.scrollTop,element:r})}})}catch{}return e}captureFormData(){let e=new Map;try{document.querySelectorAll(`form`).forEach((t,n)=>{let r=t.id||t.name||`form-${n}`,i=new FormData(t);i.entries().next().done||e.set(r,i)})}catch{}return e}captureFocusedElement(){try{let e=document.activeElement;if(e&&e!==document.body){if(e.id)return`#${e.id}`;if((e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)&&e.name)return`[name="${e.name}"]`}}catch{}return null}storeState(e,t){let n=this.routeAccessOrder.indexOf(e);for(n!==-1&&this.routeAccessOrder.splice(n,1),this.routeAccessOrder.push(e),this.stateHistory.set(e,t);this.routeAccessOrder.length>this.maxHistorySize;){let e=this.routeAccessOrder.shift();e&&this.stateHistory.delete(e)}}getHistorySize(){return this.stateHistory.size}hasState(e){return this.stateHistory.has(e)}getState(e){return this.stateHistory.get(e)}clearAll(){this.stateHistory.clear(),this.routeAccessOrder=[]}clearState(e){this.stateHistory.delete(e);let t=this.routeAccessOrder.indexOf(e);t!==-1&&this.routeAccessOrder.splice(t,1)}restoreState(e){let t=this.stateHistory.get(e);if(!t)return!1;let n=!0;return this.restoreScrollPositions(t.scrollPositions)||(n=!1),this.restoreFormData(t.formData)||(n=!1),t.focusedElement&&this.restoreFocus(t.focusedElement),n}restoreScrollPositions(e){let t=!0;try{e.forEach((e,n)=>{try{if(n===`window`)window.scrollTo(e.x,e.y);else{let r=document.getElementById(n)||document.querySelector(`[data-scrollable-id="${n}"]`);r instanceof HTMLElement?(r.scrollLeft=e.x,r.scrollTop=e.y):t=!1}}catch{t=!1}})}catch(e){console.error(`[rari] Router: Failed to restore scroll positions:`,e),t=!1}return t}restoreFormData(e){let t=!0;try{e.forEach((e,n)=>{try{let r=document.getElementById(n)||document.querySelector(`form[name="${n}"]`)||document.querySelectorAll(`form`)[Number.parseInt(n.replace(`form-`,``),10)];r instanceof HTMLFormElement?e.forEach((e,n)=>{try{let t=r.elements.namedItem(n);t instanceof RadioNodeList?t.forEach(t=>{t instanceof HTMLInputElement&&(t.type===`radio`||t.type===`checkbox`?t.checked=t.value===e:t.value=e)}):(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement)&&(t instanceof HTMLInputElement&&(t.type===`checkbox`||t.type===`radio`)?t.checked=t.value===e:t.value=e)}catch{t=!1}}):t=!1}catch{t=!1}})}catch(e){console.error(`[rari] Router: Failed to restore form data:`,e),t=!1}return t}restoreFocus(e){try{let t=document.querySelector(e);t instanceof HTMLElement&&requestAnimationFrame(()=>{try{t.focus()}catch{}})}catch{}}};function R(e){e.title&&(document.title=e.title);let t=(e,t)=>{let n=document.querySelector(e);if(n)t.content&&n.setAttribute(`content`,t.content);else{n=document.createElement(`meta`);for(let[e,r]of Object.entries(t))n.setAttribute(e,r);document.head.appendChild(n)}};if(e.description&&t(`meta[name="description"]`,{name:`description`,content:e.description}),e.keywords&&e.keywords.length>0&&t(`meta[name="keywords"]`,{name:`keywords`,content:e.keywords.join(`, `)}),e.viewport&&t(`meta[name="viewport"]`,{name:`viewport`,content:e.viewport}),e.canonical){let t=document.querySelector(`link[rel="canonical"]`);t||(t=document.createElement(`link`),t.setAttribute(`rel`,`canonical`),document.head.appendChild(t)),t.setAttribute(`href`,e.canonical)}if(e.robots){let n=[];e.robots.index!==void 0&&n.push(e.robots.index?`index`:`noindex`),e.robots.follow!==void 0&&n.push(e.robots.follow?`follow`:`nofollow`),e.robots.nocache&&n.push(`nocache`),n.length>0&&t(`meta[name="robots"]`,{name:`robots`,content:n.join(`, `)})}if(e.openGraph){let n=e.openGraph;if(n.title&&t(`meta[property="og:title"]`,{property:`og:title`,content:n.title}),n.description&&t(`meta[property="og:description"]`,{property:`og:description`,content:n.description}),n.url&&t(`meta[property="og:url"]`,{property:`og:url`,content:n.url}),n.siteName&&t(`meta[property="og:site_name"]`,{property:`og:site_name`,content:n.siteName}),n.type&&t(`meta[property="og:type"]`,{property:`og:type`,content:n.type}),n.images&&n.images.length>0){document.querySelectorAll(`meta[property="og:image"]`).forEach(e=>e.remove());for(let e of n.images){let t=document.createElement(`meta`);t.setAttribute(`property`,`og:image`),t.setAttribute(`content`,e),document.head.appendChild(t)}}}if(e.twitter){let n=e.twitter;if(n.card&&t(`meta[name="twitter:card"]`,{name:`twitter:card`,content:n.card}),n.site&&t(`meta[name="twitter:site"]`,{name:`twitter:site`,content:n.site}),n.creator&&t(`meta[name="twitter:creator"]`,{name:`twitter:creator`,content:n.creator}),n.title&&t(`meta[name="twitter:title"]`,{name:`twitter:title`,content:n.title}),n.description&&t(`meta[name="twitter:description"]`,{name:`twitter:description`,content:n.description}),n.images&&n.images.length>0){document.querySelectorAll(`meta[name="twitter:image"]`).forEach(e=>e.remove());for(let e of n.images){let t=document.createElement(`meta`);t.setAttribute(`name`,`twitter:image`),t.setAttribute(`content`,e),document.head.appendChild(t)}}}}function z({children:n,initialRoute:r,staleWindowMs:i=3e4}){let[a,o]=S(()=>({currentRoute:M(r),navigationId:0,error:null})),s=x(null),c=x(!0),l=x(M(r)),u=x(new O({timeout:1e4,maxRetries:3,onError:e=>{console.error(`[rari] Router: Navigation error:`,e)},onRetry:()=>{}})),d=x(new Map),f=x([]),p=x(new L({maxHistorySize:50})),m=x(null),h=x(i),g=()=>`${Date.now()}-${Math.random().toString(36).substring(2,9)}`,_=()=>{s.current&&=(s.current.abort(),null)},v=()=>{for(let[,e]of d.current.entries())e.abortController.abort();d.current.clear()},D=(e,t)=>{d.current.delete(e),c.current&&a.navigationId===t&&o(e=>({...e}))},k=async e=>I.get(e),A=x(null),z=async(e,t={})=>{if(!e||typeof e!=`string`){console.error(`[rari] Router: Invalid navigation target:`,e);return}let[n,r]=e.includes(`#`)?e.split(`#`):[e,``],i=M(n);if(i===l.current&&!t.replace){if(r){let e=document.getElementById(r);e&&(e.scrollIntoView({behavior:`smooth`,block:`start`}),window.history.pushState(window.history.state,``,`${i}#${r}`))}return}let f=d.current.get(i);if(f)return f.promise;let m=await k(i);v(),_();let h=new AbortController;s.current=h;let y=a.navigationId+1,b=(async()=>{let e=l.current;try{t.historyKey||p.current.captureState(e);let n=t.historyKey||g(),a={route:i,navigationId:y,scrollPosition:{x:window.scrollX,y:window.scrollY},timestamp:Date.now(),key:n},s=r?`${i}#${r}`:i;t.replace?window.history.replaceState(a,``,s):window.history.pushState(a,``,s);let f=window.location.origin+i,_=await fetch(f,{headers:{Accept:`text/x-component`},signal:h.signal});if(!_.ok&&_.status!==404)throw Error(`Failed to fetch: ${_.status}`);let v=new URL(_.url).pathname,b=v===i?i:v;if(v!==i){let e=r?`${v}#${r}`:v;window.history.replaceState({route:v,navigationId:y,scrollPosition:{x:window.scrollX,y:window.scrollY},timestamp:Date.now(),key:t.historyKey||g()},``,e)}if(h.signal.aborted){D(b,y);return}try{let e=_.headers.get(`x-rari-metadata`);if(e){let t=decodeURIComponent(e);R(JSON.parse(t))}}catch{}let x=_.headers.get(`x-render-mode`)===`streaming`,S=m?.segments&&j(``,m.segments,b)||{};if(x&&_.body){let n=_.body.getReader(),r=new TextDecoder,i=``;try{for(;;){let{done:e,value:t}=await n.read();if(e)break;if(h.signal.aborted){await n.cancel(),D(b,y);return}i+=r.decode(t,{stream:!0});let a=i.split(`
2
- `);i=a.pop()||``;for(let e of a)e.trim()&&window.dispatchEvent(new CustomEvent(`rari:rsc-row`,{detail:{rscRow:e}}))}i.trim()&&window.dispatchEvent(new CustomEvent(`rari:rsc-row`,{detail:{rscRow:i}})),window.dispatchEvent(new CustomEvent(`rari:navigate`,{detail:{from:e,to:b,navigationId:y,options:t,routeInfo:{...m,extractedParams:S},abortSignal:h.signal,isStreaming:!0}}))}catch(e){throw console.error(`[rari] Router: Streaming error:`,e),e}}else{let n=await _.text();window.dispatchEvent(new CustomEvent(`rari:navigate`,{detail:{from:e,to:b,navigationId:y,options:t,routeInfo:{...m,extractedParams:S},abortSignal:h.signal,rscWireFormat:n}}))}if(h.signal.aborted){D(b,y);return}c.current&&(l.current=b,o(e=>({...e,currentRoute:b,error:null})),u.current.resetRetry(b),t.historyKey?requestAnimationFrame(()=>{p.current.restoreState(b)}):r&&requestAnimationFrame(()=>{let e=(t=0)=>{let n=document.getElementById(r);n?n.scrollIntoView({behavior:`smooth`,block:`start`}):t<10&&setTimeout(e,50,t+1)};e()})),d.current.delete(i),A.current?.()}catch(t){if(t instanceof Error&&t.name===`AbortError`){D(i,y);return}let n=u.current.handleError(t,i);c.current&&o(e=>({...e,error:n})),d.current.delete(i),window.dispatchEvent(new CustomEvent(`rari:navigate-error`,{detail:{from:e,to:i,error:n,navigationId:y}})),A.current?.()}})();return d.current.set(i,{targetPath:i,navigationId:y,promise:b,abortController:h}),b},B=async()=>{if(f.current.length===0)return;let e=f.current.at(-1);e&&(f.current=[],await z(e.path,e.options))},V=x(z);b(()=>(A.current=B,V.current=z,()=>{A.current=null,V.current=null}));let H=x(null);H.current||=E((e,t)=>{V.current?.(e,t)},50,{leading:!1,trailing:!0,maxWait:200});let U=e=>{if(e.button!==0||e.ctrlKey||e.shiftKey||e.altKey||e.metaKey)return;let t=e.target;for(;t&&t.tagName!==`A`;)t=t.parentElement;if(!t||t.tagName!==`A`)return;let n=t;if(n.target&&n.target!==`_self`||n.hasAttribute(`download`))return;let r=n.getAttribute(`href`);if(!r||N(r))return;if(r.startsWith(`#`)){e.preventDefault();let t=r.slice(1),n=document.getElementById(t);n&&(n.scrollIntoView({behavior:`smooth`,block:`start`}),window.history.pushState(window.history.state,``,r));return}e.preventDefault();let i=P(r);H.current&&H.current(i,{replace:!1})},W=e=>{let t=window.location.pathname,n=e.state;V.current&&V.current(t,{replace:!0,scroll:!1,historyKey:n?.key})},G=()=>{if(a.error&&a.error.url){let e=a.error.url;u.current.incrementRetry(e),z(e,{replace:!1})}},K=()=>{window.location.reload()},q=()=>{o(e=>({...e,error:null}))};y(()=>{let e=window.history.state;if(!e||!e.key){let e={route:a.currentRoute,navigationId:a.navigationId,scrollPosition:{x:window.scrollX,y:window.scrollY},timestamp:Date.now(),key:g()};window.history.replaceState(e,``,window.location.pathname+window.location.search+window.location.hash)}},[]);let J=e=>{if(e.persisted){let e=window.location.pathname;p.current.captureState(e)}},Y=e=>{if(e.persisted){let e=window.location.pathname,t=window.history.state;requestAnimationFrame(()=>{p.current.restoreState(e),t?.scrollPosition&&window.scrollTo(t.scrollPosition.x,t.scrollPosition.y)})}};return y(()=>(document.addEventListener(`click`,U),window.addEventListener(`popstate`,W),window.addEventListener(`pagehide`,J),window.addEventListener(`pageshow`,Y),()=>{document.removeEventListener(`click`,U),window.removeEventListener(`popstate`,W),window.removeEventListener(`pagehide`,J),window.removeEventListener(`pageshow`,Y)}),[]),y(()=>{h.current=i;let e=()=>{document.hidden?m.current=Date.now():m.current!==null&&Date.now()-m.current>h.current&&I.clear()};return document.addEventListener(`visibilitychange`,e),()=>{document.removeEventListener(`visibilitychange`,e)}},[i]),y(()=>(c.current=!0,e((e,t)=>V.current?.(e,t)??Promise.resolve()),()=>{c.current=!1,t(),_(),v(),H.current?.cancel&&H.current.cancel()}),[]),T(C,{children:[n,a.error&&w(F,{error:a.error,onRetry:G,onReload:K,onDismiss:q,retryCount:u.current.getRetryCount(a.error.url||``),maxRetries:3})]})}var B=class extends v{constructor(e){super(e),this.state={hasError:!1,error:null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,t){console.error(`[rari] Layout: Error in layout "${this.props.layoutPath}":`,e,t),this.props.onError&&this.props.onError(e,t),typeof window<`u`&&window.dispatchEvent(new CustomEvent(`rari:layout-error`,{detail:{layoutPath:this.props.layoutPath,error:e,errorInfo:t,timestamp:Date.now()}}))}reset=()=>{this.setState({hasError:!1,error:null})};render(){return this.state.hasError&&this.state.error?this.props.fallback?this.props.fallback(this.state.error,this.reset):T(`div`,{style:{padding:`16px`,margin:`16px 0`,background:`#fee`,border:`1px solid #fcc`,borderRadius:`4px`},children:[w(`h3`,{style:{margin:`0 0 8px 0`,color:`#c00`},children:`Layout Error`}),T(`p`,{style:{margin:`0 0 8px 0`,fontSize:`14px`},children:[`An error occurred in layout:`,` `,w(`code`,{children:this.props.layoutPath})]}),T(`details`,{style:{fontSize:`12px`,marginBottom:`8px`},children:[w(`summary`,{style:{cursor:`pointer`},children:`Error details`}),T(`pre`,{style:{marginTop:`8px`,padding:`8px`,background:`#fff`,border:`1px solid #ddd`,borderRadius:`2px`,overflow:`auto`},children:[this.state.error.message,`
3
- `,this.state.error.stack]})]}),w(`button`,{onClick:this.reset,type:`button`,style:{padding:`6px 12px`,background:`#c00`,color:`white`,border:`none`,borderRadius:`4px`,cursor:`pointer`,fontSize:`14px`},children:`Try Again`})]}):this.props.children}};export{z as ClientRouter,g as DefaultError,d as DefaultLoading,m as ErrorBoundary,c as HttpRuntimeClient,B as LayoutErrorBoundary,n as LoadingSpinner,O as NavigationErrorHandler,F as NavigationErrorOverlay,f as NotFound,L as StatePreserver,_ as clearPropsCache,i as clearPropsCacheForComponent,h as createErrorBoundary,r as createHttpRuntimeClient,l as createLoadingBoundary,a as extractMetadata,p as extractServerProps,u as extractServerPropsWithCache,s as extractStaticParams,o as hasServerSideDataFetching};
1
+ import{i as e,t}from"./navigate-DPJioMXn.mjs";import{a as n,c as r,d as i,f as a,g as o,h as s,i as c,l,m as u,n as d,o as f,p,r as m,s as h,t as g,u as _}from"./runtime-client-Bg4V1Ksp.mjs";import{Component as v,useEffect as y,useLayoutEffect as b,useRef as x,useState as S}from"react";import{Fragment as C,jsx as w,jsxs as T}from"react/jsx-runtime";function E(e,t,n={}){let r=null,i=0,a=0,o=null,s=null,{leading:c=!1,trailing:l=!0,maxWait:u}=n;function d(t){let n=o,r=s;return o=null,s=null,a=t,e.apply(r,n)}function f(e){let n=e-i,r=e-a;return i===0||n>=t||n<0||u!==void 0&&r>=u}function p(){let e=Date.now();if(f(e))return h(e);let n=e-i,o=e-a,s=t-n,c=u===void 0?1/0:u-o,l=Math.min(s,c);r=setTimeout(p,l)}function m(e){return a=e,r=setTimeout(p,t),c?d(e):void 0}function h(e){if(r=null,l&&o)return d(e);o=null,s=null}function g(){r!==null&&clearTimeout(r),a=0,o=null,i=0,s=null,r=null}function _(){return r===null?void 0:h(Date.now())}function v(){return r!==null}function y(...e){let n=Date.now(),a=f(n);if(o=e,s=this,i=n,a){if(r===null)return m(i);if(u!==void 0)return r=setTimeout(p,t),d(i)}r===null&&(r=setTimeout(p,t))}return y.cancel=g,y.flush=_,y.pending=v,y}function D(e,t){if(e instanceof Error&&e.name===`AbortError`)return{type:`abort`,message:`Navigation was cancelled`,originalError:e,url:t,timestamp:Date.now(),retryable:!1};if(e instanceof Error&&e.message.includes(`timeout`))return{type:`timeout`,message:`Navigation request timed out`,originalError:e,url:t,timestamp:Date.now(),retryable:!0};if(e instanceof Error&&`status`in e){let n=e.status;return n===404?{type:`not-found`,message:`Page not found`,originalError:e,statusCode:n,url:t,timestamp:Date.now(),retryable:!1}:n>=500?{type:`server-error`,message:`Server error: ${n}`,originalError:e,statusCode:n,url:t,timestamp:Date.now(),retryable:!0}:{type:`fetch-error`,message:`HTTP error: ${n}`,originalError:e,statusCode:n,url:t,timestamp:Date.now(),retryable:n>=500}}return e instanceof TypeError&&e.message.includes(`fetch`)?{type:`network-error`,message:`Network error - check your connection`,originalError:e,url:t,timestamp:Date.now(),retryable:!0}:e instanceof SyntaxError||e instanceof Error&&e.message.includes(`parse`)?{type:`parse-error`,message:`Failed to parse server response`,originalError:e instanceof Error?e:void 0,url:t,timestamp:Date.now(),retryable:!1}:{type:`fetch-error`,message:e instanceof Error?e.message:`Unknown error occurred`,originalError:e instanceof Error?e:void 0,url:t,timestamp:Date.now(),retryable:!1}}var O=class{options;retryCount;constructor(e={}){this.options={timeout:e.timeout??1e4,maxRetries:e.maxRetries??3,onError:e.onError??(()=>{}),onRetry:e.onRetry??(()=>{})},this.retryCount=new Map}handleError(e,t){let n=D(e,t);return this.options.onError(n),console.error(`[rari] Navigation:`,n.type,n.message,{url:n.url,statusCode:n.statusCode,retryable:n.retryable}),typeof window<`u`&&window.dispatchEvent(new CustomEvent(`rari:navigation-error`,{detail:n})),n}canRetry(e,t){return e.retryable?(this.retryCount.get(t)??0)<this.options.maxRetries:!1}incrementRetry(e){let t=(this.retryCount.get(e)??0)+1;return this.retryCount.set(e,t),this.options.onRetry(t,{type:`fetch-error`,message:`Retry attempt ${t}`,url:e,timestamp:Date.now(),retryable:!0}),t}resetRetry(e){this.retryCount.delete(e)}getRetryCount(e){return this.retryCount.get(e)??0}clearRetries(){this.retryCount.clear()}};const k=/(^\/+)|(\/+$)/g;function A(e){let t=e.replace(k,``);return t?t.split(`/`):[]}function j(e){try{return decodeURIComponent(e)}catch{return null}}function M(e,t,n){let r=A(n),i={},a=0;for(let e=0;e<t.length;e++){let n=t[e];if(a>=r.length){if(n.type===`optional-catch-all`){n.param&&(i[n.param]=[]);continue}return null}switch(n.type){case`static`:if(r[a]!==n.value)return null;a++;break;case`dynamic`:if(n.param){let e=j(r[a]);if(e===null)return null;i[n.param]=e}a++;break;case`catch-all`:case`optional-catch-all`:if(n.param){let e=[];for(let t of r.slice(a)){let n=j(t);if(n===null)return null;e.push(n)}i[n.param]=e}a=r.length;break}}return a===r.length?i:null}function N(e){if(!e||e===`/`)return`/`;let t=e;for(;t.endsWith(`/`)&&t.length>1;)t=t.slice(0,-1);return t.startsWith(`/`)||(t=`/${t}`),t}function P(e,t){try{return new URL(e,t||window.location.origin).origin!==(t||window.location.origin)}catch{return!1}}function F(e){try{let t=new URL(e,window.location.origin);return t.pathname+t.hash}catch{return e}}function I({error:e,onRetry:t,onReload:n,onDismiss:r,retryCount:i=0,maxRetries:a=3}){let o=e.retryable&&i<a;return w(`div`,{style:{position:`fixed`,top:0,left:0,right:0,bottom:0,background:`rgba(0, 0, 0, 0.5)`,display:`flex`,alignItems:`center`,justifyContent:`center`,zIndex:1e4,padding:`20px`},onClick:e=>{e.target===e.currentTarget&&r&&r()},children:T(`div`,{style:{background:`white`,borderRadius:`8px`,padding:`24px`,maxWidth:`500px`,width:`100%`,boxShadow:`0 4px 12px rgba(0, 0, 0, 0.15)`},onClick:e=>e.stopPropagation(),children:[T(`div`,{style:{display:`flex`,alignItems:`center`,gap:`12px`,marginBottom:`16px`},children:[w(`span`,{style:{fontSize:`32px`},children:(()=>{switch(e.type){case`timeout`:return`⏱️`;case`network-error`:return`📡`;case`not-found`:return`🔍`;case`server-error`:return`⚠️`;case`parse-error`:return`📄`;case`abort`:return`🚫`;default:return`❌`}})()}),w(`h2`,{style:{margin:0,fontSize:`20px`,fontWeight:`600`,color:`#1f2937`},children:`Navigation Error`})]}),w(`p`,{style:{margin:`0 0 16px 0`,fontSize:`15px`,lineHeight:`1.5`,color:`#4b5563`},children:(()=>{switch(e.type){case`timeout`:return`The page took too long to load. Please try again.`;case`network-error`:return`Unable to connect to the server. Please check your internet connection.`;case`not-found`:return`The page you're looking for doesn't exist.`;case`server-error`:return`The server encountered an error. Please try again in a moment.`;case`parse-error`:return`Unable to load the page content. Please try reloading.`;case`abort`:return`Navigation was cancelled.`;default:return e.message||`An unexpected error occurred.`}})()}),e.url&&T(`details`,{style:{marginBottom:`16px`,fontSize:`13px`,color:`#6b7280`},children:[w(`summary`,{style:{cursor:`pointer`,userSelect:`none`,marginBottom:`8px`},children:`Technical details`}),T(`div`,{style:{padding:`12px`,background:`#f9fafb`,borderRadius:`4px`,fontFamily:`monospace`,fontSize:`12px`,wordBreak:`break-all`},children:[T(`div`,{style:{marginBottom:`4px`},children:[w(`strong`,{children:`URL:`}),` `,e.url]}),e.statusCode&&T(`div`,{style:{marginBottom:`4px`},children:[w(`strong`,{children:`Status:`}),` `,e.statusCode]}),T(`div`,{style:{marginBottom:`4px`},children:[w(`strong`,{children:`Type:`}),` `,e.type]}),e.originalError&&T(`div`,{children:[w(`strong`,{children:`Error:`}),` `,e.originalError.message]})]})]}),o&&i>0&&T(`div`,{style:{marginBottom:`16px`,padding:`8px 12px`,background:`#fef3c7`,border:`1px solid #fbbf24`,borderRadius:`4px`,fontSize:`13px`,color:`#92400e`},children:[`Retry attempt`,` `,i,` `,`of`,` `,a]}),T(`div`,{style:{display:`flex`,gap:`8px`,flexWrap:`wrap`},children:[o&&t&&w(`button`,{onClick:t,type:`button`,style:{flex:1,minWidth:`120px`,padding:`10px 16px`,background:`#3b82f6`,color:`white`,border:`none`,borderRadius:`6px`,fontSize:`14px`,fontWeight:`500`,cursor:`pointer`,transition:`background 0.2s`},onMouseEnter:e=>{e.currentTarget.style.background=`#2563eb`},onMouseLeave:e=>{e.currentTarget.style.background=`#3b82f6`},children:`Try Again`}),n&&w(`button`,{onClick:n,type:`button`,style:{flex:1,minWidth:`120px`,padding:`10px 16px`,background:`#6b7280`,color:`white`,border:`none`,borderRadius:`6px`,fontSize:`14px`,fontWeight:`500`,cursor:`pointer`,transition:`background 0.2s`},onMouseEnter:e=>{e.currentTarget.style.background=`#4b5563`},onMouseLeave:e=>{e.currentTarget.style.background=`#6b7280`},children:`Reload Page`}),r&&w(`button`,{onClick:r,type:`button`,style:{flex:1,minWidth:`120px`,padding:`10px 16px`,background:`transparent`,color:`#6b7280`,border:`1px solid #d1d5db`,borderRadius:`6px`,fontSize:`14px`,fontWeight:`500`,cursor:`pointer`,transition:`all 0.2s`},onMouseEnter:e=>{e.currentTarget.style.background=`#f9fafb`,e.currentTarget.style.borderColor=`#9ca3af`},onMouseLeave:e=>{e.currentTarget.style.background=`transparent`,e.currentTarget.style.borderColor=`#d1d5db`},children:`Dismiss`})]}),w(`p`,{style:{marginTop:`16px`,marginBottom:0,fontSize:`12px`,color:`#9ca3af`,textAlign:`center`},children:`Your current page is still available below this message`})]})})}const L=new class{cache=new Map;pendingRequests=new Map;async get(e){let t=this.cache.get(e);if(t)return t;let n=this.pendingRequests.get(e);if(n)return n;let r=this.fetchRouteInfo(e);this.pendingRequests.set(e,r);try{let t=await r;return this.cache.set(e,t),t}finally{this.pendingRequests.delete(e)}}async fetchRouteInfo(e){let t={path:e},n=await fetch(`/_rari/route-info`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!n.ok){let e=null;try{e=await n.json()}catch{}throw e?.error?Error(e.error):Error(`Failed to fetch route info: ${n.status} ${n.statusText}`)}let r=n.clone();try{return await n.json()}catch(t){try{let e=await r.text();return JSON.parse(e)}catch(n){throw console.error(`[RouteInfo] Failed to parse response:`,{error:t,parseError:n,path:e}),Error(`Failed to parse route info response`)}}}clear(){this.cache.clear(),this.pendingRequests.clear()}invalidate(e){this.cache.delete(e)}};if(typeof window<`u`){let e=window[`~rari`]||{};window[`~rari`]||(window[`~rari`]=e),e.routeInfoCache=L}var R=class{stateHistory;routeAccessOrder;maxHistorySize;scrollableSelector;constructor(e={}){this.stateHistory=new Map,this.routeAccessOrder=[],this.maxHistorySize=e.maxHistorySize||50,this.scrollableSelector=e.scrollableSelector||`[data-scrollable], .scrollable, [style*="overflow"]`}captureState(e){let t={scrollPositions:this.captureScrollPositions(),formData:this.captureFormData(),focusedElement:this.captureFocusedElement()};return this.storeState(e,t),t}captureScrollPositions(){let e=new Map;try{e.set(`window`,{x:window.scrollX,y:window.scrollY,element:`window`}),document.querySelectorAll(this.scrollableSelector).forEach((t,n)=>{if(t instanceof HTMLElement){let r=t.id||`scrollable-${n}`;(t.scrollHeight>t.clientHeight||t.scrollWidth>t.clientWidth)&&e.set(r,{x:t.scrollLeft,y:t.scrollTop,element:r})}})}catch{}return e}captureFormData(){let e=new Map;try{document.querySelectorAll(`form`).forEach((t,n)=>{let r=t.id||t.name||`form-${n}`,i=new FormData(t);i.entries().next().done||e.set(r,i)})}catch{}return e}captureFocusedElement(){try{let e=document.activeElement;if(e&&e!==document.body){if(e.id)return`#${e.id}`;if((e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)&&e.name)return`[name="${e.name}"]`}}catch{}return null}storeState(e,t){let n=this.routeAccessOrder.indexOf(e);for(n!==-1&&this.routeAccessOrder.splice(n,1),this.routeAccessOrder.push(e),this.stateHistory.set(e,t);this.routeAccessOrder.length>this.maxHistorySize;){let e=this.routeAccessOrder.shift();e&&this.stateHistory.delete(e)}}getHistorySize(){return this.stateHistory.size}hasState(e){return this.stateHistory.has(e)}getState(e){return this.stateHistory.get(e)}clearAll(){this.stateHistory.clear(),this.routeAccessOrder=[]}clearState(e){this.stateHistory.delete(e);let t=this.routeAccessOrder.indexOf(e);t!==-1&&this.routeAccessOrder.splice(t,1)}restoreState(e){let t=this.stateHistory.get(e);if(!t)return!1;let n=!0;return this.restoreScrollPositions(t.scrollPositions)||(n=!1),this.restoreFormData(t.formData)||(n=!1),t.focusedElement&&this.restoreFocus(t.focusedElement),n}restoreScrollPositions(e){let t=!0;try{e.forEach((e,n)=>{try{if(n===`window`)window.scrollTo(e.x,e.y);else{let r=document.getElementById(n)||document.querySelector(`[data-scrollable-id="${n}"]`);r instanceof HTMLElement?(r.scrollLeft=e.x,r.scrollTop=e.y):t=!1}}catch{t=!1}})}catch(e){console.error(`[rari] Router: Failed to restore scroll positions:`,e),t=!1}return t}restoreFormData(e){let t=!0;try{e.forEach((e,n)=>{try{let r=document.getElementById(n)||document.querySelector(`form[name="${n}"]`)||document.querySelectorAll(`form`)[Number.parseInt(n.replace(`form-`,``),10)];r instanceof HTMLFormElement?e.forEach((e,n)=>{try{let t=r.elements.namedItem(n);t instanceof RadioNodeList?t.forEach(t=>{t instanceof HTMLInputElement&&(t.type===`radio`||t.type===`checkbox`?t.checked=t.value===e:t.value=e)}):(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement)&&(t instanceof HTMLInputElement&&(t.type===`checkbox`||t.type===`radio`)?t.checked=t.value===e:t.value=e)}catch{t=!1}}):t=!1}catch{t=!1}})}catch(e){console.error(`[rari] Router: Failed to restore form data:`,e),t=!1}return t}restoreFocus(e){try{let t=document.querySelector(e);t instanceof HTMLElement&&requestAnimationFrame(()=>{try{t.focus()}catch{}})}catch{}}};function z(e){e.title&&(document.title=e.title);let t=(e,t)=>{let n=document.querySelector(e);if(n)t.content&&n.setAttribute(`content`,t.content);else{n=document.createElement(`meta`);for(let[e,r]of Object.entries(t))n.setAttribute(e,r);document.head.appendChild(n)}};if(e.description&&t(`meta[name="description"]`,{name:`description`,content:e.description}),e.keywords&&e.keywords.length>0&&t(`meta[name="keywords"]`,{name:`keywords`,content:e.keywords.join(`, `)}),e.viewport&&t(`meta[name="viewport"]`,{name:`viewport`,content:e.viewport}),e.canonical){let t=document.querySelector(`link[rel="canonical"]`);t||(t=document.createElement(`link`),t.setAttribute(`rel`,`canonical`),document.head.appendChild(t)),t.setAttribute(`href`,e.canonical)}if(e.robots){let n=[];e.robots.index!==void 0&&n.push(e.robots.index?`index`:`noindex`),e.robots.follow!==void 0&&n.push(e.robots.follow?`follow`:`nofollow`),e.robots.nocache&&n.push(`nocache`),n.length>0&&t(`meta[name="robots"]`,{name:`robots`,content:n.join(`, `)})}if(e.openGraph){let n=e.openGraph;if(n.title&&t(`meta[property="og:title"]`,{property:`og:title`,content:n.title}),n.description&&t(`meta[property="og:description"]`,{property:`og:description`,content:n.description}),n.url&&t(`meta[property="og:url"]`,{property:`og:url`,content:n.url}),n.siteName&&t(`meta[property="og:site_name"]`,{property:`og:site_name`,content:n.siteName}),n.type&&t(`meta[property="og:type"]`,{property:`og:type`,content:n.type}),n.images&&n.images.length>0){document.querySelectorAll(`meta[property="og:image"]`).forEach(e=>e.remove());for(let e of n.images){let t=document.createElement(`meta`);t.setAttribute(`property`,`og:image`),t.setAttribute(`content`,e),document.head.appendChild(t)}}}if(e.twitter){let n=e.twitter;if(n.card&&t(`meta[name="twitter:card"]`,{name:`twitter:card`,content:n.card}),n.site&&t(`meta[name="twitter:site"]`,{name:`twitter:site`,content:n.site}),n.creator&&t(`meta[name="twitter:creator"]`,{name:`twitter:creator`,content:n.creator}),n.title&&t(`meta[name="twitter:title"]`,{name:`twitter:title`,content:n.title}),n.description&&t(`meta[name="twitter:description"]`,{name:`twitter:description`,content:n.description}),n.images&&n.images.length>0){document.querySelectorAll(`meta[name="twitter:image"]`).forEach(e=>e.remove());for(let e of n.images){let t=document.createElement(`meta`);t.setAttribute(`name`,`twitter:image`),t.setAttribute(`content`,e),document.head.appendChild(t)}}}}function B({children:n,initialRoute:r,staleWindowMs:i=3e4}){let[a,o]=S(()=>({currentRoute:N(r),navigationId:0,error:null})),s=x(null),c=x(!0),l=x(N(r)),u=x(new O({timeout:1e4,maxRetries:3,onError:e=>{console.error(`[rari] Router: Navigation error:`,e)},onRetry:()=>{}})),d=x(new Map),f=x([]),p=x(new R({maxHistorySize:50})),m=x(null),h=x(i),g=()=>`${Date.now()}-${Math.random().toString(36).substring(2,9)}`,_=()=>{s.current&&=(s.current.abort(),null)},v=()=>{for(let[,e]of d.current.entries())e.abortController.abort();d.current.clear()},D=(e,t)=>{d.current.delete(e),c.current&&a.navigationId===t&&o(e=>({...e}))},k=async e=>L.get(e),A=x(null),j=async(e,t={})=>{if(!e||typeof e!=`string`){console.error(`[rari] Router: Invalid navigation target:`,e);return}let[n,r]=e.includes(`#`)?e.split(`#`):[e,``],i=N(n);if(i===l.current&&!t.replace){if(r){let e=document.getElementById(r);e&&(e.scrollIntoView({behavior:`smooth`,block:`start`}),window.history.pushState(window.history.state,``,`${i}#${r}`))}return}let f=d.current.get(i);if(f)return f.promise;let m=await k(i);v(),_();let h=new AbortController;s.current=h;let y=a.navigationId+1,b=(async()=>{let e=l.current;try{t.historyKey||p.current.captureState(e);let n=t.historyKey||g(),a={route:i,navigationId:y,scrollPosition:{x:window.scrollX,y:window.scrollY},timestamp:Date.now(),key:n},s=r?`${i}#${r}`:i;t.replace?window.history.replaceState(a,``,s):window.history.pushState(a,``,s);let f=window.location.origin+i,_=await fetch(f,{headers:{Accept:`text/x-component`},signal:h.signal});if(!_.ok&&_.status!==404)throw Error(`Failed to fetch: ${_.status}`);let v=new URL(_.url).pathname,b=v===i?i:v;if(v!==i){let e=r?`${v}#${r}`:v;window.history.replaceState({route:v,navigationId:y,scrollPosition:{x:window.scrollX,y:window.scrollY},timestamp:Date.now(),key:t.historyKey||g()},``,e)}if(h.signal.aborted){D(b,y);return}try{let e=_.headers.get(`x-rari-metadata`);if(e){let t=decodeURIComponent(e);z(JSON.parse(t))}}catch{}let x=_.headers.get(`x-render-mode`)===`streaming`,S=m?.segments&&M(``,m.segments,b)||{};if(x&&_.body){let n=_.body.getReader(),r=new TextDecoder,i=``;try{for(;;){let{done:e,value:t}=await n.read();if(e)break;if(h.signal.aborted){await n.cancel(),D(b,y);return}i+=r.decode(t,{stream:!0});let a=i.split(`
2
+ `);i=a.pop()||``;for(let e of a)e.trim()&&window.dispatchEvent(new CustomEvent(`rari:rsc-row`,{detail:{rscRow:e}}))}i.trim()&&window.dispatchEvent(new CustomEvent(`rari:rsc-row`,{detail:{rscRow:i}})),window.dispatchEvent(new CustomEvent(`rari:navigate`,{detail:{from:e,to:b,navigationId:y,options:t,routeInfo:{...m,extractedParams:S},abortSignal:h.signal,isStreaming:!0}}))}catch(e){throw console.error(`[rari] Router: Streaming error:`,e),e}}else{let n=await _.text();window.dispatchEvent(new CustomEvent(`rari:navigate`,{detail:{from:e,to:b,navigationId:y,options:t,routeInfo:{...m,extractedParams:S},abortSignal:h.signal,rscWireFormat:n}}))}if(h.signal.aborted){D(b,y);return}c.current&&(l.current=b,o(e=>({...e,currentRoute:b,error:null})),u.current.resetRetry(b),t.historyKey?requestAnimationFrame(()=>{p.current.restoreState(b)}):r&&requestAnimationFrame(()=>{let e=(t=0)=>{let n=document.getElementById(r);n?n.scrollIntoView({behavior:`smooth`,block:`start`}):t<10&&setTimeout(e,50,t+1)};e()})),d.current.delete(i),A.current?.()}catch(t){if(t instanceof Error&&t.name===`AbortError`){D(i,y);return}let n=u.current.handleError(t,i);c.current&&o(e=>({...e,error:n})),d.current.delete(i),window.dispatchEvent(new CustomEvent(`rari:navigate-error`,{detail:{from:e,to:i,error:n,navigationId:y}})),A.current?.()}})();return d.current.set(i,{targetPath:i,navigationId:y,promise:b,abortController:h}),b},B=async()=>{if(f.current.length===0)return;let e=f.current.at(-1);e&&(f.current=[],await j(e.path,e.options))},V=x(j);b(()=>(A.current=B,V.current=j,()=>{A.current=null,V.current=null}));let H=x(null);H.current||=E((e,t)=>{V.current?.(e,t)},50,{leading:!1,trailing:!0,maxWait:200});let U=e=>{if(e.button!==0||e.ctrlKey||e.shiftKey||e.altKey||e.metaKey)return;let t=e.target;for(;t&&t.tagName!==`A`;)t=t.parentElement;if(!t||t.tagName!==`A`)return;let n=t;if(n.target&&n.target!==`_self`||n.hasAttribute(`download`))return;let r=n.getAttribute(`href`);if(!r||P(r))return;if(r.startsWith(`#`)){e.preventDefault();let t=r.slice(1),n=document.getElementById(t);n&&(n.scrollIntoView({behavior:`smooth`,block:`start`}),window.history.pushState(window.history.state,``,r));return}e.preventDefault();let i=F(r);H.current&&H.current(i,{replace:!1})},W=e=>{let t=window.location.pathname,n=e.state;V.current&&V.current(t,{replace:!0,scroll:!1,historyKey:n?.key})},G=()=>{if(a.error&&a.error.url){let e=a.error.url;u.current.incrementRetry(e),j(e,{replace:!1})}},K=()=>{window.location.reload()},q=()=>{o(e=>({...e,error:null}))};y(()=>{let e=window.history.state;if(!e||!e.key){let e={route:a.currentRoute,navigationId:a.navigationId,scrollPosition:{x:window.scrollX,y:window.scrollY},timestamp:Date.now(),key:g()};window.history.replaceState(e,``,window.location.pathname+window.location.search+window.location.hash)}},[]);let J=e=>{if(e.persisted){let e=window.location.pathname;p.current.captureState(e)}},Y=e=>{if(e.persisted){let e=window.location.pathname,t=window.history.state;requestAnimationFrame(()=>{p.current.restoreState(e),t?.scrollPosition&&window.scrollTo(t.scrollPosition.x,t.scrollPosition.y)})}};return y(()=>(document.addEventListener(`click`,U),window.addEventListener(`popstate`,W),window.addEventListener(`pagehide`,J),window.addEventListener(`pageshow`,Y),()=>{document.removeEventListener(`click`,U),window.removeEventListener(`popstate`,W),window.removeEventListener(`pagehide`,J),window.removeEventListener(`pageshow`,Y)}),[]),y(()=>{h.current=i;let e=()=>{document.hidden?m.current=Date.now():m.current!==null&&Date.now()-m.current>h.current&&L.clear()};return document.addEventListener(`visibilitychange`,e),()=>{document.removeEventListener(`visibilitychange`,e)}},[i]),y(()=>(c.current=!0,e((e,t)=>V.current?.(e,t)??Promise.resolve()),()=>{c.current=!1,t(),_(),v(),H.current?.cancel&&H.current.cancel()}),[]),T(C,{children:[n,a.error&&w(I,{error:a.error,onRetry:G,onReload:K,onDismiss:q,retryCount:u.current.getRetryCount(a.error.url||``),maxRetries:3})]})}var V=class extends v{constructor(e){super(e),this.state={hasError:!1,error:null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,t){console.error(`[rari] Layout: Error in layout "${this.props.layoutPath}":`,e,t),this.props.onError&&this.props.onError(e,t),typeof window<`u`&&window.dispatchEvent(new CustomEvent(`rari:layout-error`,{detail:{layoutPath:this.props.layoutPath,error:e,errorInfo:t,timestamp:Date.now()}}))}reset=()=>{this.setState({hasError:!1,error:null})};render(){return this.state.hasError&&this.state.error?this.props.fallback?this.props.fallback(this.state.error,this.reset):T(`div`,{style:{padding:`16px`,margin:`16px 0`,background:`#fee`,border:`1px solid #fcc`,borderRadius:`4px`},children:[w(`h3`,{style:{margin:`0 0 8px 0`,color:`#c00`},children:`Layout Error`}),T(`p`,{style:{margin:`0 0 8px 0`,fontSize:`14px`},children:[`An error occurred in layout:`,` `,w(`code`,{children:this.props.layoutPath})]}),T(`details`,{style:{fontSize:`12px`,marginBottom:`8px`},children:[w(`summary`,{style:{cursor:`pointer`},children:`Error details`}),T(`pre`,{style:{marginTop:`8px`,padding:`8px`,background:`#fff`,border:`1px solid #ddd`,borderRadius:`2px`,overflow:`auto`},children:[this.state.error.message,`
3
+ `,this.state.error.stack]})]}),w(`button`,{onClick:this.reset,type:`button`,style:{padding:`6px 12px`,background:`#c00`,color:`white`,border:`none`,borderRadius:`4px`,cursor:`pointer`,fontSize:`14px`},children:`Try Again`})]}):this.props.children}};export{B as ClientRouter,g as DefaultError,d as DefaultLoading,m as ErrorBoundary,c as HttpRuntimeClient,V as LayoutErrorBoundary,n as LoadingSpinner,O as NavigationErrorHandler,I as NavigationErrorOverlay,f as NotFound,R as StatePreserver,_ as clearPropsCache,i as clearPropsCacheForComponent,h as createErrorBoundary,r as createHttpRuntimeClient,l as createLoadingBoundary,a as extractMetadata,p as extractServerProps,u as extractServerPropsWithCache,s as extractStaticParams,o as hasServerSideDataFetching};
@@ -0,0 +1,29 @@
1
+ import * as React from "react";
2
+ import { Component, ReactNode } from "react";
3
+
4
+ //#region src/runtime/ErrorBoundaryWrapper.d.ts
5
+ interface ErrorBoundaryWrapperProps {
6
+ errorComponentId: string;
7
+ children: ReactNode;
8
+ }
9
+ interface ErrorBoundaryWrapperState {
10
+ hasError: boolean;
11
+ error: Error | null;
12
+ ErrorComponent: React.ComponentType<{
13
+ error: Error;
14
+ reset: () => void;
15
+ }> | null;
16
+ }
17
+ declare class ErrorBoundaryWrapper extends Component<ErrorBoundaryWrapperProps, ErrorBoundaryWrapperState> {
18
+ private _isMounted;
19
+ private _pendingTimer;
20
+ constructor(props: ErrorBoundaryWrapperProps);
21
+ static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryWrapperState>;
22
+ componentDidMount(): void;
23
+ componentWillUnmount(): void;
24
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
25
+ reset: () => void;
26
+ render(): ReactNode;
27
+ }
28
+ //#endregion
29
+ export { ErrorBoundaryWrapper };
@@ -0,0 +1 @@
1
+ "use client";import{Component as e}from"react";import{jsx as t,jsxs as n}from"react/jsx-runtime";var r=class extends e{_isMounted=!1;_pendingTimer=null;constructor(e){super(e),this.state={hasError:!1,error:null,ErrorComponent:null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidMount(){this._isMounted=!0}componentWillUnmount(){this._isMounted=!1,this._pendingTimer&&=(clearTimeout(this._pendingTimer),null)}componentDidCatch(e,t){console.error(`[rari] Error boundary caught error:`,e,t);let n=this.props.errorComponentId;if(n&&typeof window<`u`){let e=window[`~clientComponents`]?.[n];e&&(e.component&&typeof e.component==`function`?this.setState({ErrorComponent:e.component}):e.loader&&!e.loading&&(e.loading=!0,e.loader().then(t=>{let n=t.default||t;e.component=n,e.registered=!0,e.loading=!1,this.setState({ErrorComponent:n})}).catch(t=>{e.loading=!1,console.error(`[rari] Failed to load error component ${n}:`,t)})))}}reset=()=>{this._pendingTimer&&=(clearTimeout(this._pendingTimer),null),this._pendingTimer=setTimeout(()=>{this._isMounted&&this.setState({hasError:!1,error:null,ErrorComponent:null}),this._pendingTimer=null},50)};render(){if(this.state.hasError&&this.state.error){let{ErrorComponent:e}=this.state;return e?t(e,{error:this.state.error,reset:this.reset}):n(`div`,{style:{padding:`20px`,background:`#fee`,border:`2px solid #f00`},children:[t(`h2`,{children:`Error`}),t(`p`,{children:`Something went wrong.`})]})}return this.props.children}};export{r as ErrorBoundaryWrapper};
package/dist/vite.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import{RariRequest as e}from"./proxy/RariRequest.mjs";import{RariResponse as t}from"./proxy/RariResponse.mjs";import{c as n,d as r,f as i,g as a,h as o,i as s,m as c,p as l,u}from"./runtime-client-Bg4V1Ksp.mjs";import{C as d,E as f,T as p,c as m,d as h,r as g,t as _,u as v,v as y,w as b}from"./regex-constants-DMuIAFub.mjs";import{t as x}from"./routes-DXBE0bwy.mjs";import{a as S,i as C,n as w,o as T,r as E,t as D}from"./constants-DZAg-dr0.mjs";import{t as O}from"./server-build-V7WVXFpd.mjs";import k,{promises as A}from"node:fs";import j from"node:path";import M from"node:process";import{Buffer as ee}from"node:buffer";import{spawn as te}from"node:child_process";import{fileURLToPath as N}from"node:url";import{build as ne}from"rolldown";var re=class extends Response{static json(e,t){let n=new Headers(t?.headers);return n.has(`content-type`)||n.set(`content-type`,`application/json`),new Response(JSON.stringify(e),{...t,headers:n})}static redirect(e,t=307){return new Response(null,{status:t,headers:{location:e}})}static noContent(e){return new Response(null,{...e,status:204})}};function P(e={}){let{root:t=M.cwd(),srcDir:n=`src`,proxyFileName:r=`proxy`,extensions:i=[`.ts`,`.tsx`,`.js`,`.jsx`,`.mts`,`.mjs`],verbose:a=!1}=e,o=null,s=e=>{a&&console.warn(`[rari] Proxy: ${e}`)};async function c(){for(let e of i){let n=`${r}${e}`,i=j.join(t,n);try{return await A.access(i),s(`Found proxy file: ${n}`),{filePath:i,exists:!0,relativePath:n}}catch{}}let e=j.join(t,n);try{await A.access(e);for(let t of i){let i=`${r}${t}`,a=j.join(e,i);try{return await A.access(a),s(`Found proxy file: ${j.join(n,i)}`),{filePath:a,exists:!0,relativePath:j.join(n,i)}}catch{}}}catch{}return null}return{name:`rari:proxy`,async buildStart(){o=await c(),s(o?`Proxy enabled: ${o.relativePath}`:`No proxy file found`)},configureServer(e){o&&(e.watcher.add(o.filePath),e.watcher.on(`change`,t=>{t===o?.filePath&&(s(`Proxy file changed, reloading...`),e.ws.send({type:`custom`,event:`rari:proxy-reload`}))}))},async handleHotUpdate({file:e,server:t}){if(o&&e===o.filePath)return s(`Hot reloading proxy...`),t.ws.send({type:`custom`,event:`rari:proxy-reload`,data:{file:o.relativePath}}),[]}}}const ie=/export\s+const\s+metadata\s*(?::\s*\w+\s*)?=\s*(\{[\s\S]*?\n\})/,ae=/title\s*:\s*['"]([^'"]+)['"]/,oe=/description\s*:\s*['"]([^'"]+)['"]/,se=/keywords\s*:\s*\[([\s\S]*?)\]/,ce={appDir:`src/app`,extensions:[`.tsx`,`.jsx`,`.ts`,`.js`],outDir:`dist`};function F(e){switch(j.basename(e).replace(p,``)){case`page`:return`page`;case`layout`:return`layout`;case`loading`:return`loading`;case`error`:return`error`;case`not-found`:return`not-found`;case`route`:return`route`;default:return null}}function I(e,t){let n=j.relative(t,j.dirname(e));return!n||n===`.`?`/`:`/${n.replace(_,`/`).split(`/`).filter(Boolean).join(`/`)}`}function L(e,t,n){if(t===`page`)return[e];let r=n.filter(t=>t===e||t.startsWith(`${e}/`));return r.length>0?r:[e]}function R(e){try{let t=e.match(ie);if(!t)return null;let n=t[1],r={},i=n.match(ae);i&&(r.title=i[1]);let a=n.match(oe);a&&(r.description=a[1]);let o=n.match(se);o&&(r.keywords=o[1].split(`,`).map(e=>e.trim().replace(d,``)).filter(Boolean));for(let e of[`author`,`viewport`,`themeColor`,`robots`,`openGraph`,`twitter`]){let t=RegExp(`${e}\\s*:\\s*['"]([^'"]+)['"]`,`m`),i=n.match(t);i&&(r[e]=i[1])}return Object.keys(r).length>0?r:null}catch(e){return console.error(`[rari] Router: Failed to extract metadata:`,e),null}}function z(e){let t=[];for(let n of[`GET`,`POST`,`PUT`,`DELETE`,`PATCH`,`HEAD`,`OPTIONS`]){let r=RegExp(`export\\s+(?:async\\s+)?function\\s+${n}\\s*\\(`),i=RegExp(`export\\s+(?:async\\s+)?(?:const|let|var)\\s+${n}\\s*=`);(r.test(e)||i.test(e))&&t.push(n)}return t}async function B(e){try{let t=await fetch(`http://localhost:3000/_rari/hmr`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`invalidate-api-route`,filePath:e})});if(!t.ok){console.error(`[rari] Router: Failed to invalidate API route cache: ${t.statusText}`);return}let n=await t.json();n.success||console.error(`[rari] HMR: Failed to invalidate API route cache: ${n.error||`Unknown error`}`)}catch(e){console.error(`[rari] Router: Failed to notify API route invalidation:`,e)}}function V(e={}){let t={...ce,...e},n=null,r=new Map,i=null,a=new Set,o=e=>[...e].toSorted().join(`|`),s=async e=>{let n=new Set,r=async e=>{try{let i=await A.readdir(e,{withFileTypes:!0});for(let a of i){let i=j.join(e,a.name);a.isDirectory()?await r(i):a.isFile()&&t.extensions.some(e=>a.name.endsWith(e))&&F(i)&&n.add(i)}}catch{}};return await r(e),n},c=async(e,r=!1)=>{let c=j.resolve(e,t.appDir);try{await A.access(c)}catch{return null}try{let l=await s(c),u=o(l);if(!r&&i===u&&n)return n;let{generateAppRouteManifest:d}=await import(`./routes-DXBE0bwy.mjs`).then(e=>e.n),f=await d(c,{extensions:t.extensions}),p=JSON.stringify(f,null,2),m=j.resolve(e,t.outDir);await A.mkdir(m,{recursive:!0});let h=j.join(m,`server`);return await A.mkdir(h,{recursive:!0}),await A.writeFile(j.join(h,`routes.json`),p,`utf-8`),i=u,a.clear(),l.forEach(e=>a.add(e)),p}catch(e){return console.error(`[rari] Router: Failed to generate app routes:`,e),null}},l=e=>{let n=j.resolve(e.config.root,t.appDir);e.watcher.on(`all`,async(r,i)=>{if(i.startsWith(n)&&t.extensions.some(e=>i.endsWith(e)))try{let n=F(i)!==null,o=r===`add`||r===`unlink`,s=n&&!a.has(i);(o||s)&&(await c(e.config.root,!0),i.includes(t.appDir)&&e.ws.send({type:`full-reload`,path:`*`}))}catch(e){console.error(`[rari] Router: Failed to regenerate app routes:`,e)}})},u;return{name:`rari-router`,configResolved(e){u=e.root;let t=e.logger.warn;e.logger.warn=(e,n)=>{typeof e==`string`&&e.includes(`runtime-client`)&&e.includes(`The above dynamic import cannot be analyzed`)||t(e,n)}},async writeBundle(){n=await c(u||M.cwd(),!0)},configureServer(e){l(e)},async handleHotUpdate(e){let{file:i,server:o}=e,s=j.resolve(o.config.root,t.appDir);if(i.startsWith(s)&&t.extensions.some(e=>i.endsWith(e))){let e=F(i);if(e){let t=r.get(i);t&&clearTimeout(t);let l=setTimeout(async()=>{r.delete(i);let t=!a.has(i),l=n;n=await c(o.config.root,t);let u=l!==n,d=I(i,s),f=[d];if(n)try{f=JSON.parse(n).routes.map(e=>e.path)}catch(e){console.error(`[rari] Router: Failed to parse manifest for affected routes:`,e)}let p=L(d,e,f),m,h=!1,g;if(e===`page`||e===`layout`)try{let e=R(await A.readFile(i,`utf-8`));e&&(m=e,h=!0)}catch(e){console.error(`[rari] Router: Failed to extract metadata:`,e)}if(e===`route`)try{g=z(await A.readFile(i,`utf-8`)),await B(j.relative(s,i))}catch(e){console.error(`[rari] Router: Failed to detect HTTP methods:`,e)}let _={fileType:e,filePath:j.relative(o.config.root,i),routePath:d,affectedRoutes:p,manifestUpdated:u,timestamp:Date.now(),metadata:m,metadataChanged:h,methods:g};o.ws.send({type:`custom`,event:`rari:app-router-updated`,data:_})},200);return r.set(i,l),[]}return n=await c(o.config.root),[]}},async closeBundle(){for(let e of r.values())clearTimeout(e);r.clear()}}}var H=class{errorCount=0;maxErrors;resetTimeout;resetTimer=null;lastError=null;constructor(e={}){this.maxErrors=e.maxErrors??5,this.resetTimeout=e.resetTimeout??3e4}recordError(e){this.errorCount++,this.lastError=e,this.resetTimer&&clearTimeout(this.resetTimer),this.resetTimer=setTimeout(()=>{this.reset()},this.resetTimeout),this.errorCount>=this.maxErrors&&this.handleMaxErrorsReached()}reset(){this.errorCount=0,this.lastError=null,this.resetTimer&&=(clearTimeout(this.resetTimer),null)}getErrorCount(){return this.errorCount}getLastError(){return this.lastError}hasReachedMaxErrors(){return this.errorCount>=this.maxErrors}handleMaxErrorsReached(){console.error(`[rari] HMR: Maximum error count (${this.maxErrors}) reached. Consider restarting the dev server if issues persist.`)}dispose(){this.resetTimer&&=(clearTimeout(this.resetTimer),null),this.reset()}},U=class{serverComponentBuilder;rustServerUrl;pendingUpdates=new Map;pendingFiles=new Set;batchTimer=null;DEBOUNCE_DELAY=200;errorHandler;logBatch=[];logBatchTimer=null;LOG_BATCH_DELAY=500;constructor(e,t=3e3){this.serverComponentBuilder=e,this.rustServerUrl=`http://localhost:${t}`,this.errorHandler=new H({maxErrors:5,resetTimeout:3e4})}async handleClientComponentUpdate(e,t){let n=j.relative(M.cwd(),e);try{let r=t.moduleGraph.getModuleById(e);r?(t.moduleGraph.invalidateModule(r),this.errorHandler.reset()):this.queueLog(`warning`,`Client component module not found in graph: ${n}`)}catch(e){let t=e instanceof Error?e.message:String(e);this.queueLog(`error`,`Failed to update client component: ${n} - ${t}`),this.errorHandler.recordError(e instanceof Error?e:Error(t))}}async handleServerComponentUpdate(e,t){this.pendingFiles.add(e);let n=this.pendingUpdates.get(e);n&&(clearTimeout(n),this.pendingUpdates.delete(e)),this.batchTimer&&clearTimeout(this.batchTimer),this.batchTimer=setTimeout(async()=>{let e=[...this.pendingFiles];if(this.pendingFiles.clear(),this.batchTimer=null,e.length===0)return;let n=await Promise.allSettled(e.map(async e=>{let t=j.relative(M.cwd(),e);try{let n=await this.serverComponentBuilder.rebuildComponent(e);if(!n.success)throw Error(n.error||`Build failed`);return await this.notifyRustServer(n.componentId,n.bundlePath),{success:!0,componentId:n.componentId,filePath:e,relativePath:t}}catch(n){return{success:!1,filePath:e,relativePath:t,error:n instanceof Error?n:Error(String(n))}}})),r=[],i=[];if(n.forEach(e=>{e.status===`fulfilled`&&e.value.success?r.push(e.value):e.status===`fulfilled`&&!e.value.success?i.push(e.value):e.status===`rejected`&&i.push({filePath:``,relativePath:`unknown`,error:Error(String(e.reason))})}),r.length>0){let e=Date.now();r.forEach(({componentId:n})=>{t.hot.send(`rari:server-component-updated`,{id:n,t:e})}),this.errorHandler.reset(),t.ws.send({type:`custom`,event:`rari:hmr-error-cleared`,data:{t:e}})}if(i.length>0){let e=Date.now();i.forEach(({relativePath:n,error:r})=>{let i=r.message,a=(r.stack||``).substring(0,500);this.queueLog(`error`,`Failed to rebuild: ${n} - ${i}`),this.errorHandler.recordError(r),t.ws.send({type:`custom`,event:`rari:hmr-error`,data:{msg:i,stack:a,file:n,t:e,count:this.errorHandler.getErrorCount(),max:5}})}),this.errorHandler.hasReachedMaxErrors()&&this.queueLog(`error`,`Maximum error count reached (${this.errorHandler.getErrorCount()}). Consider restarting the dev server if issues persist.`)}},this.DEBOUNCE_DELAY)}async notifyRustServer(e,t){try{let n=await fetch(`${this.rustServerUrl}/_rari/hmr`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`reload-component`,component_id:e,bundle_path:t})});if(!n.ok){let e=await n.text();throw Error(`HTTP ${n.status}: ${e}`)}let r=await n.text(),i;try{i=JSON.parse(r)}catch(e){throw Error(`Failed to parse server response (status ${n.status}): ${e instanceof Error?e.message:String(e)}. Response body: ${r.substring(0,200)}${r.length>200?`...`:``}`)}if(!i||typeof i!=`object`)throw Error(`Invalid server response (status ${n.status}): expected object, got ${typeof i}. Response body: ${r.substring(0,200)}${r.length>200?`...`:``}`);let a=i;if(!a.success)throw Error(a.message||a.error||`Component reload failed`)}catch(e){throw console.error(`[rari] HMR: Failed to notify Rust server:`,e),e}}detectComponentType(e){try{let t=k.readFileSync(e,`utf-8`).split(`
2
2
  `);for(let e of t){let t=e.trim();if(!(!t||t.startsWith(`//`)||t.startsWith(`/*`))){if(t===`'use client'`||t===`"use client"`)return`client`;break}}return`server`}catch{return`unknown`}}queueLog(e,t){this.logBatch.push({type:e,message:t,timestamp:Date.now()}),this.logBatchTimer&&clearTimeout(this.logBatchTimer),this.logBatchTimer=setTimeout(()=>{this.flushLogs()},this.LOG_BATCH_DELAY)}flushLogs(){if(this.logBatch.length===0)return;let e=this.logBatch.reduce((e,t)=>(e[t.type]||(e[t.type]=[]),e[t.type].push(t),e),{});for(let[t,n]of Object.entries(e))if(n.length===1){let e=n[0];this.outputLog(t,e.message)}else{let e=n.map(e=>e.message).join(`
3
- • `);this.outputLog(t,`${n.length} updates:\n • ${e}`)}this.logBatch=[],this.logBatchTimer=null}outputLog(e,t){let n=`[rari] HMR:`;switch(e){case`success`:console.warn(`\x1B[32m${n}\x1B[0m ${t}`);break;case`warning`:console.warn(`\x1B[33m${n}\x1B[0m ${t}`);break;case`error`:console.error(`\x1B[31m${n}\x1B[0m ${t}`);break;default:console.warn(`${n} ${t}`);break}}dispose(){this.logBatchTimer&&(clearTimeout(this.logBatchTimer),this.flushLogs()),this.batchTimer&&=(clearTimeout(this.batchTimer),null);for(let e of this.pendingUpdates.values())clearTimeout(e);this.pendingUpdates.clear(),this.pendingFiles.clear(),this.errorHandler.dispose()}};const W=/import\s+(\w+)\s+from\s+['"]rari\/image['"]/g,G=/import\s+\{[^}]*\b(?:Image\s+as\s+(\w+)|Image)\b[^}]*\}\s+from\s+['"]rari\/image['"]/g,le=/src:\s*["']([^"']+)["']/,ue=/[.*+?^${}()|[\]\\]/g,de=/width:\s*(\d+)/,fe=/quality:\s*(\d+)/,pe=/preload:\s*(true|!0)/,me=/preload:\s*(false|!1)/,he=/<Image\s([^/>]+)\/>/g,ge=/<Image\s([^>]+)>/g,_e=/src=\{?["']([^"']+)["']\}?|src=\{([^}]+)\}/,ve=/width=\{?(\d+)\}?/,ye=/quality=\{?(\d+)\}?/,be=/preload(?:=\{?true\}?)?/,xe=/preload=\{?false\}?/;async function Se(e,t=[]){let n=new Map;async function r(e){if(!k.existsSync(e))return;let t=k.readdirSync(e,{withFileTypes:!0});for(let i of t){let t=j.join(e,i.name);if(i.isDirectory()){if(i.name===`node_modules`||i.name===`dist`)continue;await r(t)}else if(i.isFile()&&p.test(i.name))try{let e=k.readFileSync(t,`utf8`);if(!e.includes(`from 'rari/image'`)&&!e.includes(`from "rari/image"`))continue;await Ce(e,t,n)}catch(e){console.warn(`Failed to read or process file ${t}:`,e)}}}await r(e);for(let e of t)k.existsSync(e)&&await r(e);return{images:[...n.values()]}}async function Ce(e,t,n){try{let r;r=t.endsWith(`.tsx`)?`tsx`:t.endsWith(`.jsx`)?`jsx`:t.endsWith(`.ts`)?`ts`:`js`;let i=`\0virtual:${t}`,a=await ne({input:i,platform:`browser`,write:!1,output:{format:`esm`},moduleTypes:{[`.${r}`]:r},transform:{jsx:`react`},plugins:[{name:`virtual-module`,resolveId(e){return e===i?e:null},load(t){return t===i?{code:e,moduleType:r}:null}}]});if(!a.output||a.output.length===0)throw Error(`Transform produced no output`);let o=a.output[0].code,s=new Set;for(let e of o.matchAll(W))s.add(e[1]);for(let e of o.matchAll(G))e[1]?s.add(e[1]):s.add(`Image`);if(s.size===0)return;for(let e of s){let t=e.replace(ue,`\\$&`),r=RegExp(`React\\.createElement\\(\\s*${t}\\s*,\\s*\\{([^}]+)\\}`,`g`);for(let e of o.matchAll(r)){let t=e[1],r=t.match(le);if(!r)continue;let i=r[1];if(!i.startsWith(`/`)&&!i.startsWith(`http`))continue;let a=t.match(de),o=a?Number.parseInt(a[1],10):void 0,s=t.match(fe),c=s?Number.parseInt(s[1],10):void 0,l=t.match(pe),u=t.match(me),d=!!l&&!u,f=`${i}:${o||`auto`}:${c||75}`;(!n.has(f)||d)&&n.set(f,{src:i,width:o,quality:c,preload:d})}}}catch{we(e,n)}}function we(e,t){for(let n of e.matchAll(he))K(n[1],t);for(let n of e.matchAll(ge))K(n[1],t)}function K(e,t){let n=e.match(_e);if(!n)return;let r=n[1]||n[2];if(!r||r.includes(`{`)||!r.startsWith(`/`)&&!r.startsWith(`http`))return;let i=e.match(ve),a=i?Number.parseInt(i[1],10):void 0,o=e.match(ye),s=o?Number.parseInt(o[1],10):void 0,c=be.test(e)&&!xe.test(e),l=`${r}:${a||`auto`}:${s||75}`;(!t.has(l)||c)&&t.set(l,{src:r,width:a,quality:s,preload:c})}const Te=/import\s+type\s+(\{[^}]+\})\s+from\s+["']\.\.?\/([^"']+)["'];?/g,Ee=/import\s+type\s+(\*\s+as\s+\w+)\s+from\s+["']\.\.?\/([^"']+)["'];?/g,De=/import\s+type\s+(\w+)\s+from\s+["']\.\.?\/([^"']+)["'];?/g,Oe=/import\s+(\{[^}]+\})\s+from\s+["']\.\.?\/([^"']+)["'];?/g,ke=/import\s+(\*\s+as\s+\w+)\s+from\s+["']\.\.?\/([^"']+)["'];?/g,Ae=/import\s+(\w+)\s+from\s+["']\.\.?\/([^"']+)["'];?/g,je=/import\s+["']\.\.?\/([^"']+)["'];?/g,Me=/import\s*(?:\(\s*)?["']([^"']+)["']\)?/g,Ne=/export\s*\{([^}]+)\}/g,Pe=/\s+as\s+/,Fe=/export\s+default\s+(?:function|class)\s+\w+/,Ie=/export\s+default\s+(?:async\s+)?function\s+(\w+)/,q=/export\s+default\s+([^;]+)/,Le=/export\s+(?:async\s+)?(?:const|let|var|function|class)\s+(\w+)/g,Re=/^['"]use client['"];?\s*$/gm,ze=/import\s+["']([^"']+)["']/g,J=/^\s*import\s+(?:(\w+)(?:\s*,\s*\{\s*(?:(\w+(?:\s*,\s*\w+)*)\s*)?\})?|\{\s*(\w+(?:\s*,\s*\w+)*)\s*\})\s+from\s+['"]([./@][^'"]+)['"].*$/,Be=/import\s+\{[^}]*\}\s+from\s+['"]react['"]/,Ve=/import\s+[^,\s]+\s*,\s*\{[^}]*\}\s+from\s+['"]react['"]/,He=/import React(,\s*\{([^}]*)\})?\s+from\s+['"]react['"];?/,Ue=/import\s+["']([^"']+)["']/g,We=/from(\s*)(['"])(?:\.\/|rari\/)react-server-dom-rari-client\.mjs\2/g,Ge=/\bJSX\b/,Y=/^components\//,Ke=/\{([^}]*)\}/,qe={remotePatterns:[],localPatterns:[],deviceSizes:D,imageSizes:E,formats:w,qualityAllowlist:T,minimumCacheTTL:S,maxCacheSize:C};async function X(e){let t=import.meta.url,n=N(t),r=j.dirname(n),i=[j.join(r,`runtime`,e),j.join(r,`../runtime`,e)];for(let e of i)try{let t=await k.promises.readFile(e,`utf-8`);return e.endsWith(`.ts`)&&(t=t.replace(Te,(e,t,n)=>`import type ${t} from "rari/${n}";`),t=t.replace(Ee,(e,t,n)=>`import type ${t} from "rari/${n}";`),t=t.replace(De,(e,t,n)=>`import type ${t} from "rari/${n}";`),t=t.replace(Oe,(e,t,n)=>`import ${t} from "rari/${n}";`),t=t.replace(ke,(e,t,n)=>`import ${t} from "rari/${n}";`),t=t.replace(Ae,(e,t,n)=>`import ${t} from "rari/${n}";`),t=t.replace(je,(e,t)=>`import "rari/${t}";`)),t}catch(t){t.code!==`ENOENT`&&t.code!==`EISDIR`&&console.warn(`[rari] Unexpected error reading ${e}:`,t)}throw Error(`Could not find ${e}. Tried: ${i.join(`, `)}`)}async function Je(){return X(`rsc-client-runtime.mjs`)}async function Ye(e,t){return(await X(`entry-client.mjs`)).replace(`/*! @preserve CLIENT_COMPONENT_IMPORTS_PLACEHOLDER */`,e).replace(`/*! @preserve CLIENT_COMPONENT_REGISTRATIONS_PLACEHOLDER */`,t)}async function Xe(){return X(`react-server-dom-shim.mjs`)}async function Z(e,t){let n=await Se(j.join(e,`src`)),r={...qe,...t.images,preoptimizeManifest:n.images},i=j.join(e,`dist`),a=j.join(i,`server`);k.existsSync(a)||k.mkdirSync(a,{recursive:!0});let o=j.join(a,`image.json`);k.writeFileSync(o,JSON.stringify(r,null,2))}function Q(e,t=[]){let n=new Set;function r(e){if(!k.existsSync(e))return;let t=k.readdirSync(e,{withFileTypes:!0});for(let i of t){let t=j.join(e,i.name);if(i.isDirectory()){if(i.name===`node_modules`)continue;r(t)}else if(i.isFile()&&p.test(i.name))try{let e=k.readFileSync(t,`utf8`);(e.includes(`'use client'`)||e.includes(`"use client"`))&&n.add(t)}catch(e){e?.code!==`ENOENT`&&console.warn(`[rari] Unexpected error during file scan:`,t,e)}}}r(e);for(let e of t)k.existsSync(e)&&r(e);return n}function Ze(e){return e}function $(e={}){let t=new Map,n=new Set,r=new Map,i=null,a=null,o={};function s(e){if(r.has(e))return r.get(e);let t={hasUseServer:!1,hasUseClient:!1},n=e.replace(_,`/`);if(!p.test(n)||!n.includes(`/src/`))return r.set(e,t),t;try{let n=k.readFileSync(e,`utf-8`);t.hasUseServer=n.includes(`'use server'`)||n.includes(`"use server"`),t.hasUseClient=n.includes(`'use client'`)||n.includes(`"use client"`),r.set(e,t)}catch{r.set(e,t)}return t}function c(t){if(t.includes(`node_modules`)||t.includes(`/rari/dist/`)||t.includes(`\\rari\\dist\\`))return!1;let n=e.projectRoot||M.cwd(),r=j.join(n,`index.html`);if(k.existsSync(r))try{let e=k.readFileSync(r,`utf-8`);for(let r of e.matchAll(Me)){let e=r[1];if(e.startsWith(`/src/`)&&j.join(n,e.slice(1))===t)return!1}}catch(e){e?.code!==`ENOENT`&&console.warn(`[rari] Unexpected error reading index.html:`,e)}let i;try{i=k.realpathSync(t)}catch{return!1}try{if(!k.existsSync(i))return!1;let e=k.readFileSync(i,`utf-8`),t=u(e,`use client`);return u(e,`use server`)?!1:!t}catch{return!1}}function l(e){try{let t=[],n=e.matchAll(Ne);for(let e of n){let n=e[1].split(`,`);for(let e of n){let n=e.trim().split(Pe).at(-1)?.trim();n&&t.push(n)}}(Fe.test(e)||m.test(e))&&t.push(`default`);let r=e.matchAll(Le);for(let e of r)e[1]&&t.push(e[1]);return[...new Set(t)]}catch{return[]}}function u(e,t){try{let n=e.split(`
3
+ • `);this.outputLog(t,`${n.length} updates:\n • ${e}`)}this.logBatch=[],this.logBatchTimer=null}outputLog(e,t){let n=`[rari] HMR:`;switch(e){case`success`:console.warn(`\x1B[32m${n}\x1B[0m ${t}`);break;case`warning`:console.warn(`\x1B[33m${n}\x1B[0m ${t}`);break;case`error`:console.error(`\x1B[31m${n}\x1B[0m ${t}`);break;default:console.warn(`${n} ${t}`);break}}dispose(){this.logBatchTimer&&(clearTimeout(this.logBatchTimer),this.flushLogs()),this.batchTimer&&=(clearTimeout(this.batchTimer),null);for(let e of this.pendingUpdates.values())clearTimeout(e);this.pendingUpdates.clear(),this.pendingFiles.clear(),this.errorHandler.dispose()}};const W=/import\s+(\w+)\s+from\s+['"]rari\/image['"]/g,G=/import\s+\{[^}]*\b(?:Image\s+as\s+(\w+)|Image)\b[^}]*\}\s+from\s+['"]rari\/image['"]/g,le=/src:\s*["']([^"']+)["']/,ue=/[.*+?^${}()|[\]\\]/g,de=/width:\s*(\d+)/,fe=/quality:\s*(\d+)/,pe=/preload:\s*(true|!0)/,me=/preload:\s*(false|!1)/,he=/<Image\s([^/>]+)\/>/g,ge=/<Image\s([^>]+)>/g,_e=/src=\{?["']([^"']+)["']\}?|src=\{([^}]+)\}/,ve=/width=\{?(\d+)\}?/,ye=/quality=\{?(\d+)\}?/,be=/preload(?:=\{?true\}?)?/,xe=/preload=\{?false\}?/;async function Se(e,t=[]){let n=new Map;async function r(e){if(!k.existsSync(e))return;let t=k.readdirSync(e,{withFileTypes:!0});for(let i of t){let t=j.join(e,i.name);if(i.isDirectory()){if(i.name===`node_modules`||i.name===`dist`)continue;await r(t)}else if(i.isFile()&&p.test(i.name))try{let e=k.readFileSync(t,`utf8`);if(!e.includes(`from 'rari/image'`)&&!e.includes(`from "rari/image"`))continue;await Ce(e,t,n)}catch(e){console.warn(`Failed to read or process file ${t}:`,e)}}}await r(e);for(let e of t)k.existsSync(e)&&await r(e);return{images:[...n.values()]}}async function Ce(e,t,n){try{let r;r=t.endsWith(`.tsx`)?`tsx`:t.endsWith(`.jsx`)?`jsx`:t.endsWith(`.ts`)?`ts`:`js`;let i=`\0virtual:${t}`,a=await ne({input:i,platform:`browser`,write:!1,output:{format:`esm`},moduleTypes:{[`.${r}`]:r},transform:{jsx:`react`},plugins:[{name:`virtual-module`,resolveId(e){return e===i?e:null},load(t){return t===i?{code:e,moduleType:r}:null}}]});if(!a.output||a.output.length===0)throw Error(`Transform produced no output`);let o=a.output[0].code,s=new Set;for(let e of o.matchAll(W))s.add(e[1]);for(let e of o.matchAll(G))e[1]?s.add(e[1]):s.add(`Image`);if(s.size===0)return;for(let e of s){let t=e.replace(ue,`\\$&`),r=RegExp(`React\\.createElement\\(\\s*${t}\\s*,\\s*\\{([^}]+)\\}`,`g`);for(let e of o.matchAll(r)){let t=e[1],r=t.match(le);if(!r)continue;let i=r[1];if(!i.startsWith(`/`)&&!i.startsWith(`http`))continue;let a=t.match(de),o=a?Number.parseInt(a[1],10):void 0,s=t.match(fe),c=s?Number.parseInt(s[1],10):void 0,l=t.match(pe),u=t.match(me),d=!!l&&!u,f=`${i}:${o||`auto`}:${c||75}`;(!n.has(f)||d)&&n.set(f,{src:i,width:o,quality:c,preload:d})}}}catch{we(e,n)}}function we(e,t){for(let n of e.matchAll(he))K(n[1],t);for(let n of e.matchAll(ge))K(n[1],t)}function K(e,t){let n=e.match(_e);if(!n)return;let r=n[1]||n[2];if(!r||r.includes(`{`)||!r.startsWith(`/`)&&!r.startsWith(`http`))return;let i=e.match(ve),a=i?Number.parseInt(i[1],10):void 0,o=e.match(ye),s=o?Number.parseInt(o[1],10):void 0,c=be.test(e)&&!xe.test(e),l=`${r}:${a||`auto`}:${s||75}`;(!t.has(l)||c)&&t.set(l,{src:r,width:a,quality:s,preload:c})}const Te=/import\s+type\s+(\{[^}]+\})\s+from\s+["']\.\.?\/([^"']+)["'];?/g,Ee=/import\s+type\s+(\*\s+as\s+\w+)\s+from\s+["']\.\.?\/([^"']+)["'];?/g,De=/import\s+type\s+(\w+)\s+from\s+["']\.\.?\/([^"']+)["'];?/g,Oe=/import\s+(\{[^}]+\})\s+from\s+["']\.\.?\/([^"']+)["'];?/g,ke=/import\s+(\*\s+as\s+\w+)\s+from\s+["']\.\.?\/([^"']+)["'];?/g,Ae=/import\s+(\w+)\s+from\s+["']\.\.?\/([^"']+)["'];?/g,je=/import\s+["']\.\.?\/([^"']+)["'];?/g,Me=/import\s*(?:\(\s*)?["']([^"']+)["']\)?/g,Ne=/export\s*\{([^}]+)\}/g,Pe=/\s+as\s+/,Fe=/export\s+default\s+(?:function|class)\s+\w+/,Ie=/export\s+default\s+(?:async\s+)?function\s+(\w+)/,q=/export\s+default\s+([^;]+)/,Le=/export\s+(?:async\s+)?(?:const|let|var|function|class)\s+(\w+)/g,Re=/^['"]use client['"];?\s*$/gm,ze=/import\s+["']([^"']+)["']/g,J=/^\s*import\s+(?:(\w+)(?:\s*,\s*\{\s*(?:(\w+(?:\s*,\s*\w+)*)\s*)?\})?|\{\s*(\w+(?:\s*,\s*\w+)*)\s*\})\s+from\s+['"]([./@][^'"]+)['"].*$/,Be=/import\s+\{[^}]*\}\s+from\s+['"]react['"]/,Ve=/import\s+[^,\s]+\s*,\s*\{[^}]*\}\s+from\s+['"]react['"]/,He=/import React(,\s*\{([^}]*)\})?\s+from\s+['"]react['"];?/,Ue=/import\s+["']([^"']+)["']/g,We=/from(\s*)(['"])(?:\.\/|rari\/)react-server-dom-rari-client\.mjs\2/g,Ge=/\bJSX\b/,Y=/^components\//,Ke=/\{([^}]*)\}/,qe=/^['"]use client['"];?\s*\n/,Je={remotePatterns:[],localPatterns:[],deviceSizes:D,imageSizes:E,formats:w,qualityAllowlist:T,minimumCacheTTL:S,maxCacheSize:C};async function X(e){let t=import.meta.url,n=N(t),r=j.dirname(n),i=[j.join(r,`runtime`,e),j.join(r,`../runtime`,e)];for(let e of i)try{let t=await k.promises.readFile(e,`utf-8`);return e.endsWith(`.ts`)&&(t=t.replace(Te,(e,t,n)=>`import type ${t} from "rari/${n}";`),t=t.replace(Ee,(e,t,n)=>`import type ${t} from "rari/${n}";`),t=t.replace(De,(e,t,n)=>`import type ${t} from "rari/${n}";`),t=t.replace(Oe,(e,t,n)=>`import ${t} from "rari/${n}";`),t=t.replace(ke,(e,t,n)=>`import ${t} from "rari/${n}";`),t=t.replace(Ae,(e,t,n)=>`import ${t} from "rari/${n}";`),t=t.replace(je,(e,t)=>`import "rari/${t}";`)),t}catch(t){t.code!==`ENOENT`&&t.code!==`EISDIR`&&console.warn(`[rari] Unexpected error reading ${e}:`,t)}throw Error(`Could not find ${e}. Tried: ${i.join(`, `)}`)}async function Ye(){return X(`rsc-client-runtime.mjs`)}async function Xe(e,t){return(await X(`entry-client.mjs`)).replace(`/*! @preserve CLIENT_COMPONENT_IMPORTS_PLACEHOLDER */`,e).replace(`/*! @preserve CLIENT_COMPONENT_REGISTRATIONS_PLACEHOLDER */`,t)}async function Ze(){return X(`react-server-dom-shim.mjs`)}async function Z(e,t){let n=await Se(j.join(e,`src`)),r={...Je,...t.images,preoptimizeManifest:n.images},i=j.join(e,`dist`),a=j.join(i,`server`);k.existsSync(a)||k.mkdirSync(a,{recursive:!0});let o=j.join(a,`image.json`);k.writeFileSync(o,JSON.stringify(r,null,2))}function Q(e,t=[]){let n=new Set;function r(e){if(!k.existsSync(e))return;let t=k.readdirSync(e,{withFileTypes:!0});for(let i of t){let t=j.join(e,i.name);if(i.isDirectory()){if(i.name===`node_modules`)continue;r(t)}else if(i.isFile()&&p.test(i.name))try{let e=k.readFileSync(t,`utf8`);(e.includes(`'use client'`)||e.includes(`"use client"`))&&n.add(t)}catch(e){e?.code!==`ENOENT`&&console.warn(`[rari] Unexpected error during file scan:`,t,e)}}}r(e);for(let e of t)k.existsSync(e)&&r(e);return n}function Qe(e){return e}function $(e={}){let t=new Map,n=new Set,r=new Map,i=null,a=null,o={};function s(e){if(r.has(e))return r.get(e);let t={hasUseServer:!1,hasUseClient:!1},n=e.replace(_,`/`);if(!p.test(n)||!n.includes(`/src/`))return r.set(e,t),t;try{let n=k.readFileSync(e,`utf-8`);t.hasUseServer=n.includes(`'use server'`)||n.includes(`"use server"`),t.hasUseClient=n.includes(`'use client'`)||n.includes(`"use client"`),r.set(e,t)}catch{r.set(e,t)}return t}function c(t){if(t.includes(`node_modules`)||t.includes(`/rari/dist/`)||t.includes(`\\rari\\dist\\`))return!1;let n=e.projectRoot||M.cwd(),r=j.join(n,`index.html`);if(k.existsSync(r))try{let e=k.readFileSync(r,`utf-8`);for(let r of e.matchAll(Me)){let e=r[1];if(e.startsWith(`/src/`)&&j.join(n,e.slice(1))===t)return!1}}catch(e){e?.code!==`ENOENT`&&console.warn(`[rari] Unexpected error reading index.html:`,e)}let i;try{i=k.realpathSync(t)}catch{return!1}try{if(!k.existsSync(i))return!1;let e=k.readFileSync(i,`utf-8`),t=u(e,`use client`);return u(e,`use server`)?!1:!t}catch{return!1}}function l(e){try{let t=[],n=e.matchAll(Ne);for(let e of n){let n=e[1].split(`,`);for(let e of n){let n=e.trim().split(Pe).at(-1)?.trim();n&&t.push(n)}}(Fe.test(e)||m.test(e))&&t.push(`default`);let r=e.matchAll(Le);for(let e of r)e[1]&&t.push(e[1]);return[...new Set(t)]}catch{return[]}}function u(e,t){try{let n=e.split(`
4
4
  `);for(let e of n){let n=e.trim();if(!(!n||n.startsWith(`//`)||n.startsWith(`/*`))){if(n===`'${t}'`||n===`"${t}"`||n===`'${t}';`||n===`"${t}";`)return!0;break}}return!1}catch{return!1}}function d(e,t){if(!u(e,`use server`))return e;let n=l(e);if(n.length===0)return e;let r=e;r+=`
5
5
 
6
6
  import {registerServerReference} from "react-server-dom-rari/server";
@@ -42,7 +42,7 @@ const ${t} = registerClientReference(
42
42
  );`;s=s.replace(e,n),l=!0,f=!0}}else if(!v&&c(_)){l=!0,f=!0,m=!0;let e=a;d&&d!==`_`&&h.push(`const ${d} = createServerComponentWrapper('${g}', '${p}');`),s=s.replace(e,``)}}if(l){let e=s.includes(`import React`)||s.match(Be)||s.match(Ve),n=s.includes(`createServerComponentWrapper`),i=``;if(f&&!e&&(i+=`import React from 'react';
43
43
  `),m&&!n&&(i+=`import { createServerComponentWrapper } from 'virtual:rsc-integration.ts';
44
44
  `),h.length>0&&(i+=`${h.join(`
45
- `)}\n`),i&&(s=i+s),!s.includes(`Suspense`)){let e=s.match(He);e&&(e[1]&&!e[2].includes(`Suspense`)?s=s.replace(e[0],e[0].replace(Ke,`{ Suspense, $1 }`)):e[1]||(s=s.replace(e[0],`import React, { Suspense } from 'react';`)))}let a=M.env.NODE_ENV!==`production`,o=s.includes(`</`)||s.includes(`/>`)||Ge.test(s);return!s.includes(`'use client'`)&&!s.includes(`"use client"`)&&o&&a&&(s=`'use client';\n\n${s}`,t.set(r,`client`)),s}return null},async configureServer(n){let r=e.projectRoot||M.cwd(),s=j.join(r,`src`);await Z(r,e);let l=null,u=async()=>{try{let{ServerComponentBuilder:t,scanDirectory:i}=await import(`./server-build-V7WVXFpd.mjs`).then(e=>e.n),s=new t(r,{outDir:`dist`,rscDir:`server`,manifestPath:`server/manifest.json`,serverConfigPath:`server/config.json`,alias:o,csp:e.csp,rateLimit:e.rateLimit,spamBlocker:e.spamBlocker,cacheControl:e.cacheControl});if(l=s,!a&&l){let e=M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3);a=new U(l,e)}let u=j.join(r,`src`),d=[];if(k.existsSync(u)){let e=t=>{let n=k.readdirSync(t,{withFileTypes:!0});for(let r of n){let n=j.join(t,r.name);if(r.isDirectory())e(n);else if(r.isFile()&&p.test(r.name))try{c(n)&&d.push(n)}catch(e){console.error(`[rari] Error checking ${n}:`,e)}}};e(u),i(u,s)}d.length>0&&n.ws.send({type:`custom`,event:`rari:server-components-registry`,data:{serverComponents:d}});let f=await s.getTransformedComponentsForDevelopment(),m=`http://localhost:${M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3)}`;for(let e of f)try{if(e.id.startsWith(`app/`)||e.code.includes(`"use server"`)||e.code.includes(`'use server'`))continue;let t=await fetch(`${m}/_rari/register`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({component_id:e.id,component_code:e.code})});if(!t.ok){let e=await t.text();throw Error(`HTTP ${t.status}: ${e}`)}}catch(t){console.error(`[rari] Runtime: Failed to register component ${e.id}:`,t instanceof Error?t.message:String(t))}}catch(e){console.error(`[rari] Runtime: Component discovery failed:`,e instanceof Error?e.message:String(e))}},d=async()=>{try{let e=`http://localhost:${M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3)}`,t=Q(s,Object.values(o));for(let n of t){let t=j.relative(M.cwd(),n),r=j.basename(n).replace(h,``);try{await fetch(`${e}/_rari/register-client`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({component_id:r,file_path:t,export_name:`default`})})}catch(e){console.error(`[rari] Runtime: Failed to pre-register client component ${r}:`,e)}}}catch(e){console.error(`[rari] Runtime: Failed to pre-register client components:`,e)}},f=async()=>{if(i)return;let{getBinaryPath:e,getInstallationInstructions:t}=await import(`./platform.mjs`),r;try{r=e()}catch(e){console.error(`rari binary not found`),console.error(` ${e.message}`),console.error(t());return}let a=M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3),o=M.env.NODE_ENV===`production`?`production`:`development`,s=n.config.server.port||5173,c=[`--mode`,o,`--port`,a.toString(),`--host`,`127.0.0.1`];i=te(r,c,{stdio:[`ignore`,`pipe`,`pipe`],cwd:M.cwd(),env:{...M.env,RUST_LOG:M.env.RUST_LOG||`error`,RARI_VITE_PORT:s.toString()}}),i.stdout?.on(`data`,e=>{let t=e.toString().trim();t&&console.error(`${t}`)}),i.stderr?.on(`data`,e=>{let t=e.toString().trim();t&&!t.includes(`warning`)&&console.error(`${t}`)}),i.on(`error`,e=>{T=!1,console.error(`Failed to start rari server:`,e.message),e.message.includes(`ENOENT`)&&console.error(` Binary not found. Please ensure rari is properly installed.`)}),i.on(`exit`,(e,t)=>{i=null,T=!1,t?console.error(`rari server stopped by signal ${t}`):e===0?console.error(`rari server stopped successfully`):e&&console.error(`rari server exited with code ${e}`)});let l=!1;for(let e=0;e<20&&(l=await E(),!l);e++)await new Promise(e=>setTimeout(e,500));l?(await d(),await u()):console.error(`Server failed to become ready for component registration`)},m=async t=>{try{if(!c(t))return;let{ServerComponentBuilder:n}=await import(`./server-build-V7WVXFpd.mjs`).then(e=>e.n),i=new n(r,{outDir:`dist`,rscDir:`server`,manifestPath:`server/manifest.json`,serverConfigPath:`server/config.json`,alias:o,csp:e.csp,rateLimit:e.rateLimit,spamBlocker:e.spamBlocker,cacheControl:e.cacheControl});i.addServerComponent(t);let a=await i.getTransformedComponentsForDevelopment();if(a.length===0)return;let s=`http://localhost:${M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3)}`;for(let e of a)try{let t=await fetch(`${s}/_rari/register`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({component_id:e.id,component_code:e.code})});if(!t.ok){let e=await t.text();throw Error(`HTTP ${t.status}: ${e}`)}}catch(t){console.error(`[rari] Failed to register component`,`${e.id}:`,t instanceof Error?t.message:String(t))}}catch(e){console.error(`[rari] Targeted HMR failed for`,`${t}:`,e instanceof Error?e.message:String(e)),setTimeout(u,1e3)}};f().catch(e=>{console.error(`[rari] Failed to start Rust server:`,e)}),n.middlewares.use(async(e,t,n)=>{let r=e.headers.accept;if(r&&r.includes(`text/x-component`)&&e.url&&!e.url.startsWith(`/api`)&&!e.url.startsWith(`/rsc`)&&!e.url.includes(`.`)){if(!T&&!await E()){let e=Date.now();for(;Date.now()-e<1e4&&!await E();)await new Promise(e=>setTimeout(e,100));if(!T){console.error(`[rari] Rust server not ready, cannot proxy RSC request`),t.headersSent||(t.statusCode=503,t.end(`Server not ready`));return}}let n=M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3),r=`http://localhost:${n}${e.url}`;try{let i={};for(let[t,n]of Object.entries(e.headers))typeof n==`string`?i[t]=n:Array.isArray(n)&&(i[t]=n.join(`,`));i.host=`localhost:${n}`,i[`accept-encoding`]=`identity`;let a=await fetch(r,{method:e.method,headers:i});if(t.statusCode=a.status,a.headers.forEach((e,n)=>{n.toLowerCase()!==`content-encoding`&&t.setHeader(n,e)}),a.body){let e=a.body.getReader();try{for(;;){let{done:n,value:r}=await e.read();if(n)break;t.write(ee.from(r))}t.end()}catch(e){console.error(`[rari] Stream error:`,e),t.headersSent||(t.statusCode=500),t.end()}}else t.end();return}catch(e){console.error(`[rari] Failed to proxy RSC request:`,e),t.headersSent||(t.statusCode=500,t.end(`Internal Server Error`));return}}n()}),n.watcher.on(`change`,async e=>{p.test(e)&&t.delete(e),p.test(e)&&e.includes(s)&&(c(e)?(n.ws.send({type:`custom`,event:`rari:register-server-component`,data:{filePath:e}}),await m(e)):setTimeout(u,1e3))}),n.middlewares.use(`/api/vite/hmr-transform`,async(e,t)=>{if(e.method!==`POST`){t.statusCode=405,t.end(`Method Not Allowed`);return}let n=``;e.on(`data`,e=>{n+=e.toString()}),e.on(`end`,async()=>{try{let{filePath:e}=JSON.parse(n);if(!e){t.statusCode=400,t.end(JSON.stringify({error:`filePath is required`}));return}await m(e),t.statusCode=200,t.setHeader(`Content-Type`,`application/json`),t.end(JSON.stringify({success:!0,filePath:e,message:`Component transformation completed`}))}catch(e){t.statusCode=500,t.setHeader(`Content-Type`,`application/json`),t.end(JSON.stringify({success:!1,error:e instanceof Error?e.message:String(e)}))}})}),n.httpServer?.on(`close`,()=>{a&&=(a.dispose(),null),i&&=(i.kill(`SIGTERM`),null),T=!1})},resolveId(e,t){if(e===`virtual:rsc-integration`||e===`virtual:rsc-integration.ts`)return`virtual:rsc-integration.ts`;if(e===`virtual:rari-entry-client`||e===`virtual:rari-entry-client.ts`)return`virtual:rari-entry-client.ts`;if(e===`virtual:react-server-dom-rari-client`||e===`virtual:react-server-dom-rari-client.ts`)return`virtual:react-server-dom-rari-client.ts`;if(e===`virtual:app-router-provider`||e===`virtual:app-router-provider.tsx`)return`virtual:app-router-provider.tsx`;if(e===`./DefaultLoadingIndicator`||e===`./DefaultLoadingIndicator.tsx`)return`virtual:default-loading-indicator.tsx`;if(e===`./LoadingErrorBoundary`||e===`./LoadingErrorBoundary.tsx`)return`virtual:loading-error-boundary.tsx`;if(e===`react-server-dom-rari/server`)return e;if(t&&t.startsWith(`virtual:`)&&e.startsWith(`../`)){let n=import.meta.url,r=N(n),i=j.dirname(r),a=null,o=[j.join(i,`runtime`),j.join(i,`../runtime`)];for(let e of o)if(k.existsSync(e)){a=e;break}if(a){let t=j.join(a,e);if(k.existsSync(t))return t;let n=j.join(a,`../dist`,j.basename(e));if(k.existsSync(n))return n}else console.warn(`[rari] Runtime directory not found, attempting fallback resolution for virtual import.\n Importer: ${t}\n ID: ${e}\n Current Dir: ${i}\n Hint: Runtime lookup failed, trying currentDir as fallback`);let s=j.join(i,e);if(k.existsSync(s))return s;let c=j.join(i,`../dist`,j.basename(e));if(k.existsSync(c))return c}if(M.env.NODE_ENV===`production`)try{let t=j.resolve(e);if(k.existsSync(t)&&c(t))return{id:e,external:!0}}catch(t){t?.code!==`ENOENT`&&console.warn(`[rari] Unexpected error resolving server component:`,e,t)}return null},async load(t){if(p.test(t)){let e=this.environment;if(e&&e.name===`client`)try{let e=k.readFileSync(t,`utf-8`);if(u(e,`use server`))return x(e,t)}catch{}}if(t===`virtual:rari-entry-client.ts`){let e=Q(j.join(M.cwd(),`src`),Object.values(o)),t=new Set([...n,...e]),r=[{path:`rari/image`,exports:[`Image`]}],i=[...t].filter(e=>{try{return u(k.readFileSync(e,`utf-8`),`use client`)}catch{return!1}}).map(e=>{let t=j.relative(M.cwd(),e).replace(_,`/`),n=t.replace(p,``),r=t.startsWith(`..`)?e.replace(_,`/`):t,i=!1,a=``;try{let t=k.readFileSync(e,`utf-8`),n=m.test(t),r=t.match(v);!n&&r&&(i=!0,a=r[1])}catch(t){t?.code!==`ENOENT`&&console.warn(`[rari] Unexpected error reading component for export detection:`,e,t)}let o=r.replace(_,`/`),s=o.startsWith(`/`)||f.test(o)?o:`/${o}`;return` "${r}": {
45
+ `)}\n`),i&&(s=i+s),!s.includes(`Suspense`)){let e=s.match(He);e&&(e[1]&&!e[2].includes(`Suspense`)?s=s.replace(e[0],e[0].replace(Ke,`{ Suspense, $1 }`)):e[1]||(s=s.replace(e[0],`import React, { Suspense } from 'react';`)))}let a=M.env.NODE_ENV!==`production`,o=s.includes(`</`)||s.includes(`/>`)||Ge.test(s);return!s.includes(`'use client'`)&&!s.includes(`"use client"`)&&o&&a&&(s=`'use client';\n\n${s}`,t.set(r,`client`)),s}return null},async configureServer(n){let r=e.projectRoot||M.cwd(),s=j.join(r,`src`);await Z(r,e);let l=null,u=async()=>{try{let{ServerComponentBuilder:t,scanDirectory:i}=await import(`./server-build-V7WVXFpd.mjs`).then(e=>e.n),s=new t(r,{outDir:`dist`,rscDir:`server`,manifestPath:`server/manifest.json`,serverConfigPath:`server/config.json`,alias:o,csp:e.csp,rateLimit:e.rateLimit,spamBlocker:e.spamBlocker,cacheControl:e.cacheControl});if(l=s,!a&&l){let e=M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3);a=new U(l,e)}let u=j.join(r,`src`),d=[];if(k.existsSync(u)){let e=t=>{let n=k.readdirSync(t,{withFileTypes:!0});for(let r of n){let n=j.join(t,r.name);if(r.isDirectory())e(n);else if(r.isFile()&&p.test(r.name))try{c(n)&&d.push(n)}catch(e){console.error(`[rari] Error checking ${n}:`,e)}}};e(u),i(u,s)}d.length>0&&n.ws.send({type:`custom`,event:`rari:server-components-registry`,data:{serverComponents:d}});let f=await s.getTransformedComponentsForDevelopment(),m=`http://localhost:${M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3)}`;for(let e of f)try{if(e.id.startsWith(`app/`)||e.code.includes(`"use server"`)||e.code.includes(`'use server'`))continue;let t=await fetch(`${m}/_rari/register`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({component_id:e.id,component_code:e.code})});if(!t.ok){let e=await t.text();throw Error(`HTTP ${t.status}: ${e}`)}}catch(t){console.error(`[rari] Runtime: Failed to register component ${e.id}:`,t instanceof Error?t.message:String(t))}}catch(e){console.error(`[rari] Runtime: Component discovery failed:`,e instanceof Error?e.message:String(e))}},d=async()=>{try{let e=`http://localhost:${M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3)}`,t=Q(s,Object.values(o));for(let n of t){let t=j.relative(M.cwd(),n),r=j.basename(n).replace(h,``);try{await fetch(`${e}/_rari/register-client`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({component_id:r,file_path:t,export_name:`default`})})}catch(e){console.error(`[rari] Runtime: Failed to pre-register client component ${r}:`,e)}}}catch(e){console.error(`[rari] Runtime: Failed to pre-register client components:`,e)}},f=async()=>{if(i)return;let{getBinaryPath:e,getInstallationInstructions:t}=await import(`./platform.mjs`),r;try{r=e()}catch(e){console.error(`rari binary not found`),console.error(` ${e.message}`),console.error(t());return}let a=M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3),o=M.env.NODE_ENV===`production`?`production`:`development`,s=n.config.server.port||5173,c=[`--mode`,o,`--port`,a.toString(),`--host`,`127.0.0.1`];i=te(r,c,{stdio:[`ignore`,`pipe`,`pipe`],cwd:M.cwd(),env:{...M.env,RUST_LOG:M.env.RUST_LOG||`error`,RARI_VITE_PORT:s.toString()}}),i.stdout?.on(`data`,e=>{let t=e.toString().trim();t&&console.error(`${t}`)}),i.stderr?.on(`data`,e=>{let t=e.toString().trim();t&&!t.includes(`warning`)&&console.error(`${t}`)}),i.on(`error`,e=>{T=!1,console.error(`Failed to start rari server:`,e.message),e.message.includes(`ENOENT`)&&console.error(` Binary not found. Please ensure rari is properly installed.`)}),i.on(`exit`,(e,t)=>{i=null,T=!1,t?console.error(`rari server stopped by signal ${t}`):e===0?console.error(`rari server stopped successfully`):e&&console.error(`rari server exited with code ${e}`)});let l=!1;for(let e=0;e<20&&(l=await E(),!l);e++)await new Promise(e=>setTimeout(e,500));l?(await d(),await u()):console.error(`Server failed to become ready for component registration`)},m=async t=>{try{if(!c(t))return;let{ServerComponentBuilder:n}=await import(`./server-build-V7WVXFpd.mjs`).then(e=>e.n),i=new n(r,{outDir:`dist`,rscDir:`server`,manifestPath:`server/manifest.json`,serverConfigPath:`server/config.json`,alias:o,csp:e.csp,rateLimit:e.rateLimit,spamBlocker:e.spamBlocker,cacheControl:e.cacheControl});i.addServerComponent(t);let a=await i.getTransformedComponentsForDevelopment();if(a.length===0)return;let s=`http://localhost:${M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3)}`;for(let e of a)try{let t=await fetch(`${s}/_rari/register`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({component_id:e.id,component_code:e.code})});if(!t.ok){let e=await t.text();throw Error(`HTTP ${t.status}: ${e}`)}}catch(t){console.error(`[rari] Failed to register component`,`${e.id}:`,t instanceof Error?t.message:String(t))}}catch(e){console.error(`[rari] Targeted HMR failed for`,`${t}:`,e instanceof Error?e.message:String(e)),setTimeout(u,1e3)}};f().catch(e=>{console.error(`[rari] Failed to start Rust server:`,e)}),n.middlewares.use(async(e,t,n)=>{let r=e.headers.accept;if(r&&r.includes(`text/x-component`)&&e.url&&!e.url.startsWith(`/api`)&&!e.url.startsWith(`/rsc`)&&!e.url.includes(`.`)){if(!T&&!await E()){let e=Date.now();for(;Date.now()-e<1e4&&!await E();)await new Promise(e=>setTimeout(e,100));if(!T){console.error(`[rari] Rust server not ready, cannot proxy RSC request`),t.headersSent||(t.statusCode=503,t.end(`Server not ready`));return}}let n=M.env.SERVER_PORT?Number(M.env.SERVER_PORT):Number(M.env.PORT||M.env.RSC_PORT||3e3),r=`http://localhost:${n}${e.url}`;try{let i={};for(let[t,n]of Object.entries(e.headers))typeof n==`string`?i[t]=n:Array.isArray(n)&&(i[t]=n.join(`,`));i.host=`localhost:${n}`,i[`accept-encoding`]=`identity`;let a=await fetch(r,{method:e.method,headers:i});if(t.statusCode=a.status,a.headers.forEach((e,n)=>{n.toLowerCase()!==`content-encoding`&&t.setHeader(n,e)}),a.body){let e=a.body.getReader();try{for(;;){let{done:n,value:r}=await e.read();if(n)break;t.write(ee.from(r))}t.end()}catch(e){console.error(`[rari] Stream error:`,e),t.headersSent||(t.statusCode=500),t.end()}}else t.end();return}catch(e){console.error(`[rari] Failed to proxy RSC request:`,e),t.headersSent||(t.statusCode=500,t.end(`Internal Server Error`));return}}n()}),n.watcher.on(`change`,async e=>{p.test(e)&&t.delete(e),p.test(e)&&e.includes(s)&&(c(e)?(n.ws.send({type:`custom`,event:`rari:register-server-component`,data:{filePath:e}}),await m(e)):setTimeout(u,1e3))}),n.middlewares.use(`/api/vite/hmr-transform`,async(e,t)=>{if(e.method!==`POST`){t.statusCode=405,t.end(`Method Not Allowed`);return}let n=``;e.on(`data`,e=>{n+=e.toString()}),e.on(`end`,async()=>{try{let{filePath:e}=JSON.parse(n);if(!e){t.statusCode=400,t.end(JSON.stringify({error:`filePath is required`}));return}await m(e),t.statusCode=200,t.setHeader(`Content-Type`,`application/json`),t.end(JSON.stringify({success:!0,filePath:e,message:`Component transformation completed`}))}catch(e){t.statusCode=500,t.setHeader(`Content-Type`,`application/json`),t.end(JSON.stringify({success:!1,error:e instanceof Error?e.message:String(e)}))}})}),n.httpServer?.on(`close`,()=>{a&&=(a.dispose(),null),i&&=(i.kill(`SIGTERM`),null),T=!1})},resolveId(e,t){if(e===`virtual:rsc-integration`||e===`virtual:rsc-integration.ts`)return`virtual:rsc-integration.ts`;if(e===`virtual:rari-entry-client`||e===`virtual:rari-entry-client.ts`)return`virtual:rari-entry-client.ts`;if(e===`virtual:react-server-dom-rari-client`||e===`virtual:react-server-dom-rari-client.ts`)return`virtual:react-server-dom-rari-client.ts`;if(e===`virtual:app-router-provider`||e===`virtual:app-router-provider.tsx`)return`virtual:app-router-provider.tsx`;if(e===`virtual:error-boundary-wrapper`||e===`virtual:error-boundary-wrapper.tsx`)return`virtual:error-boundary-wrapper.tsx`;if(e===`./DefaultLoadingIndicator`||e===`./DefaultLoadingIndicator.tsx`)return`virtual:default-loading-indicator.tsx`;if(e===`./LoadingErrorBoundary`||e===`./LoadingErrorBoundary.tsx`)return`virtual:loading-error-boundary.tsx`;if(e===`react-server-dom-rari/server`)return e;if(t&&t.startsWith(`virtual:`)&&e.startsWith(`../`)){let n=import.meta.url,r=N(n),i=j.dirname(r),a=null,o=[j.join(i,`runtime`),j.join(i,`../runtime`)];for(let e of o)if(k.existsSync(e)){a=e;break}if(a){let t=j.join(a,e);if(k.existsSync(t))return t;let n=j.join(a,`../dist`,j.basename(e));if(k.existsSync(n))return n}else console.warn(`[rari] Runtime directory not found, attempting fallback resolution for virtual import.\n Importer: ${t}\n ID: ${e}\n Current Dir: ${i}\n Hint: Runtime lookup failed, trying currentDir as fallback`);let s=j.join(i,e);if(k.existsSync(s))return s;let c=j.join(i,`../dist`,j.basename(e));if(k.existsSync(c))return c}if(M.env.NODE_ENV===`production`)try{let t=j.resolve(e);if(k.existsSync(t)&&c(t))return{id:e,external:!0}}catch(t){t?.code!==`ENOENT`&&console.warn(`[rari] Unexpected error resolving server component:`,e,t)}return null},async load(t){if(p.test(t)){let e=this.environment;if(e&&e.name===`client`)try{let e=k.readFileSync(t,`utf-8`);if(u(e,`use server`))return x(e,t)}catch{}}if(t===`virtual:rari-entry-client.ts`){let e=Q(j.join(M.cwd(),`src`),Object.values(o)),t=new Set([...n,...e]),r=[{path:`rari/image`,exports:[`Image`]},{path:`virtual:error-boundary-wrapper.tsx`,exports:[`ErrorBoundaryWrapper`]}],i=[...t].filter(e=>{try{return u(k.readFileSync(e,`utf-8`),`use client`)}catch{return!1}}).map(e=>{let t=j.relative(M.cwd(),e).replace(_,`/`),n=t.replace(p,``),r=t.startsWith(`..`)?e.replace(_,`/`):t,i=!1,a=``;try{let t=k.readFileSync(e,`utf-8`),n=m.test(t),r=t.match(v);!n&&r&&(i=!0,a=r[1])}catch(t){t?.code!==`ENOENT`&&console.warn(`[rari] Unexpected error reading component for export detection:`,e,t)}let o=r.replace(_,`/`),s=o.startsWith(`/`)||f.test(o)?o:`/${o}`;return` "${r}": {
46
46
  id: "${n}",
47
47
  path: "${r}",
48
48
  type: "client",
@@ -65,7 +65,7 @@ globalThis['~clientComponents']["${e.path}"] = globalThis['~clientComponents']["
65
65
  globalThis['~clientComponents']["${e.path}"].component = ${r};
66
66
  globalThis['~clientComponentPaths'] = globalThis['~clientComponentPaths'] || {};
67
67
  globalThis['~clientComponentPaths']["${e.path}"] = "${n}";`})).join(`
68
- `);return await Ye(a,[`
68
+ `);return await Xe(a,[`
69
69
  const lazyComponentRegistry = {
70
70
  ${i}
71
71
  };
@@ -76,4 +76,78 @@ for (const [path, config] of Object.entries(lazyComponentRegistry)) {
76
76
  globalThis['~clientComponentPaths'][path] = config.id;
77
77
  }
78
78
  `,s].filter(Boolean).join(`
79
- `))}if(t===`react-server-dom-rari/server`)return await Xe();if(t===`virtual:app-router-provider.tsx`){let e=[j.join(M.cwd(),`packages/rari/dist/runtime/AppRouterProvider.mjs`),j.join(M.cwd(),`node_modules/rari/dist/runtime/AppRouterProvider.mjs`)];for(let t of e)if(k.existsSync(t))return k.readFileSync(t,`utf-8`);return`export function AppRouterProvider({ children }) { return children; }`}if(t===`virtual:default-loading-indicator.tsx`){let e=[j.join(M.cwd(),`packages/rari/dist/runtime/DefaultLoadingIndicator.mjs`),j.join(M.cwd(),`node_modules/rari/dist/runtime/DefaultLoadingIndicator.mjs`)];for(let t of e)if(k.existsSync(t))return k.readFileSync(t,`utf-8`);return`export function DefaultLoadingIndicator() { return null; }`}if(t===`virtual:loading-error-boundary.tsx`){let e=[j.join(M.cwd(),`packages/rari/dist/runtime/LoadingErrorBoundary.mjs`),j.join(M.cwd(),`node_modules/rari/dist/runtime/LoadingErrorBoundary.mjs`)];for(let t of e)if(k.existsSync(t))return k.readFileSync(t,`utf-8`);return`export class LoadingErrorBoundary extends React.Component { render() { return this.props.children; } }`}if(t===`virtual:rsc-integration.ts`)return(await Je()).replace(We,(e,t,n)=>`from${t}${n}virtual:react-server-dom-rari-client.ts${n}`);if(t===`virtual:react-server-dom-rari-client.ts`)return await X(`react-server-dom-rari-client.mjs`);if(t.endsWith(`.mjs`)&&k.existsSync(t))try{let n=e.projectRoot||M.cwd(),r=k.realpathSync(t),i=j.relative(n,r),a=!i.startsWith(`..`)&&!j.isAbsolute(i),o=r.includes(`${j.sep}node_modules${j.sep}`),s=r.includes(`${j.sep}packages${j.sep}rari${j.sep}`)||r.includes(`${j.sep}node_modules${j.sep}rari${j.sep}`);return a||o||s?k.readFileSync(t,`utf-8`):(console.warn(`[rari] Refusing to load .mjs file outside project root and node_modules: ${t}`),null)}catch(e){return console.warn(`[rari] Error validating .mjs file path: ${t}`,e),null}},async handleHotUpdate({file:e,server:t}){if(!p.test(e))return;if(e.includes(`/dist/`)||e.includes(`\\dist\\`))return[];let n=a?.detectComponentType(e)||`unknown`,r=e.includes(`/app/`)||e.includes(`\\app\\`),i=e.endsWith(`page.tsx`)||e.endsWith(`page.jsx`),o=e.endsWith(`layout.tsx`)||e.endsWith(`layout.jsx`),s=e.endsWith(`loading.tsx`)||e.endsWith(`loading.jsx`),c=e.endsWith(`error.tsx`)||e.endsWith(`error.jsx`),l=e.endsWith(`not-found.tsx`)||e.endsWith(`not-found.jsx`);if(!(r&&(i||o||s||c||l))&&n!==`client`&&n===`server`)return a&&await a.handleServerComponentUpdate(e,t),[]},transformIndexHtml:{order:`pre`,handler(e){let t=[];for(let n of e.matchAll(Ue)){let e=n[1];e.startsWith(`/src/`)&&t.push(e)}return t.length>0?{html:e,tags:t.map(e=>({tag:`script`,attrs:{type:`module`,src:e},injectTo:`head-prepend`}))}:e}},async writeBundle(){await Z(e.projectRoot||M.cwd(),e)}},O({...e.serverBuild,csp:e.csp,rateLimit:e.rateLimit,spamBlocker:e.spamBlocker,cacheControl:e.cacheControl})];return e.proxy!==!1&&D.push(P(e.proxy||{})),e.router!==!1&&D.push(V(e.router||{})),D}function Qe(e){return{plugins:[$(),...e.plugins||[]],...e}}export{re as ApiResponse,s as HttpRuntimeClient,e as RariRequest,t as RariResponse,u as clearPropsCache,r as clearPropsCacheForComponent,n as createHttpRuntimeClient,Qe as defineRariConfig,Ze as defineRariOptions,i as extractMetadata,l as extractServerProps,c as extractServerPropsWithCache,o as extractStaticParams,x as generateAppRouteManifest,a as hasServerSideDataFetching,$ as rari,P as rariProxy,V as rariRouter};
79
+ `))}if(t===`react-server-dom-rari/server`)return await Ze();if(t===`virtual:app-router-provider.tsx`){let e=[j.join(M.cwd(),`packages/rari/dist/runtime/AppRouterProvider.mjs`),j.join(M.cwd(),`node_modules/rari/dist/runtime/AppRouterProvider.mjs`)];for(let t of e)if(k.existsSync(t))return k.readFileSync(t,`utf-8`);return`export function AppRouterProvider({ children }) { return children; }`}if(t===`virtual:default-loading-indicator.tsx`){let e=[j.join(M.cwd(),`packages/rari/dist/runtime/DefaultLoadingIndicator.mjs`),j.join(M.cwd(),`node_modules/rari/dist/runtime/DefaultLoadingIndicator.mjs`)];for(let t of e)if(k.existsSync(t))return k.readFileSync(t,`utf-8`);return`export function DefaultLoadingIndicator() { return null; }`}if(t===`virtual:loading-error-boundary.tsx`){let e=[j.join(M.cwd(),`packages/rari/dist/runtime/LoadingErrorBoundary.mjs`),j.join(M.cwd(),`node_modules/rari/dist/runtime/LoadingErrorBoundary.mjs`)];for(let t of e)if(k.existsSync(t))return k.readFileSync(t,`utf-8`);return`export class LoadingErrorBoundary extends React.Component { render() { return this.props.children; } }`}if(t===`virtual:error-boundary-wrapper.tsx`){let e=[j.join(M.cwd(),`packages/rari/dist/runtime/ErrorBoundaryWrapper.mjs`),j.join(M.cwd(),`node_modules/rari/dist/runtime/ErrorBoundaryWrapper.mjs`),j.join(M.cwd(),`packages/rari/src/runtime/ErrorBoundaryWrapper.tsx`)];for(let t of e)if(k.existsSync(t)){let e=k.readFileSync(t,`utf-8`);if(!e.includes(`import React`)&&!e.includes(`from "react"`)&&!e.includes(`from 'react'`)){let t=e.match(qe);if(t){let n=t[0];return`
80
+ ${n}import * as React from 'react';\n${e.slice(n.length)}`}return`
81
+ import * as React from 'react';\n${e}`}return e}return`'use client';
82
+ import * as React from 'react';
83
+ export class ErrorBoundaryWrapper extends React.Component {
84
+ constructor(props) {
85
+ super(props);
86
+ this.state = { hasError: false, error: null, ErrorComponent: null };
87
+ this._isMounted = false;
88
+ }
89
+
90
+ componentDidMount() {
91
+ this._isMounted = true;
92
+ }
93
+
94
+ componentWillUnmount() {
95
+ this._isMounted = false;
96
+ }
97
+
98
+ static getDerivedStateFromError(error) {
99
+ return { hasError: true, error };
100
+ }
101
+
102
+ componentDidCatch(error, errorInfo) {
103
+ console.error('[rari] Error boundary caught error:', error, errorInfo);
104
+
105
+ const errorComponentId = this.props.errorComponentId;
106
+ if (errorComponentId && typeof window !== 'undefined') {
107
+ const globalThis = window;
108
+ const componentInfo = globalThis['~clientComponents']?.[errorComponentId];
109
+
110
+ if (componentInfo) {
111
+ if (componentInfo.component && typeof componentInfo.component === 'function') {
112
+ if (this._isMounted) {
113
+ this.setState({ ErrorComponent: componentInfo.component });
114
+ }
115
+ } else if (componentInfo.loader && !componentInfo.loading) {
116
+ componentInfo.loading = true;
117
+ componentInfo.loader()
118
+ .then((module) => {
119
+ const component = module.default || module;
120
+ componentInfo.component = component;
121
+ componentInfo.registered = true;
122
+ componentInfo.loading = false;
123
+ if (this._isMounted) {
124
+ this.setState({ ErrorComponent: component });
125
+ }
126
+ })
127
+ .catch((loadError) => {
128
+ componentInfo.loading = false;
129
+ console.error('[rari] Failed to load error component ' + errorComponentId + ':', loadError);
130
+ });
131
+ }
132
+ }
133
+ }
134
+ }
135
+
136
+ reset = () => {
137
+ this.setState({ hasError: false, error: null, ErrorComponent: null });
138
+ }
139
+
140
+ render() {
141
+ if (this.state.hasError && this.state.error) {
142
+ const ErrorComponent = this.state.ErrorComponent;
143
+ if (ErrorComponent) {
144
+ return React.createElement(ErrorComponent, { error: this.state.error, reset: this.reset });
145
+ }
146
+ return React.createElement('div', { style: { padding: '20px', background: '#fee', border: '2px solid #f00' } },
147
+ React.createElement('h2', null, 'Error'),
148
+ React.createElement('p', null, 'Something went wrong.')
149
+ );
150
+ }
151
+ return this.props.children;
152
+ }
153
+ }`}if(t===`virtual:rsc-integration.ts`)return(await Ye()).replace(We,(e,t,n)=>`from${t}${n}virtual:react-server-dom-rari-client.ts${n}`);if(t===`virtual:react-server-dom-rari-client.ts`)return await X(`react-server-dom-rari-client.mjs`);if(t.endsWith(`.mjs`)&&k.existsSync(t))try{let n=e.projectRoot||M.cwd(),r=k.realpathSync(t),i=j.relative(n,r),a=!i.startsWith(`..`)&&!j.isAbsolute(i),o=r.includes(`${j.sep}node_modules${j.sep}`),s=r.includes(`${j.sep}packages${j.sep}rari${j.sep}`)||r.includes(`${j.sep}node_modules${j.sep}rari${j.sep}`);return a||o||s?k.readFileSync(t,`utf-8`):(console.warn(`[rari] Refusing to load .mjs file outside project root and node_modules: ${t}`),null)}catch(e){return console.warn(`[rari] Error validating .mjs file path: ${t}`,e),null}},async handleHotUpdate({file:e,server:t}){if(!p.test(e))return;if(e.includes(`/dist/`)||e.includes(`\\dist\\`))return[];let n=a?.detectComponentType(e)||`unknown`,r=e.includes(`/app/`)||e.includes(`\\app\\`),i=e.endsWith(`page.tsx`)||e.endsWith(`page.jsx`),o=e.endsWith(`layout.tsx`)||e.endsWith(`layout.jsx`),s=e.endsWith(`loading.tsx`)||e.endsWith(`loading.jsx`),c=e.endsWith(`error.tsx`)||e.endsWith(`error.jsx`),l=e.endsWith(`not-found.tsx`)||e.endsWith(`not-found.jsx`);if(!(r&&(i||o||s||c||l))&&n!==`client`&&n===`server`)return a&&await a.handleServerComponentUpdate(e,t),[]},transformIndexHtml:{order:`pre`,handler(e){let t=[];for(let n of e.matchAll(Ue)){let e=n[1];e.startsWith(`/src/`)&&t.push(e)}return t.length>0?{html:e,tags:t.map(e=>({tag:`script`,attrs:{type:`module`,src:e},injectTo:`head-prepend`}))}:e}},async writeBundle(){await Z(e.projectRoot||M.cwd(),e)}},O({...e.serverBuild,csp:e.csp,rateLimit:e.rateLimit,spamBlocker:e.spamBlocker,cacheControl:e.cacheControl})];return e.proxy!==!1&&D.push(P(e.proxy||{})),e.router!==!1&&D.push(V(e.router||{})),D}function $e(e){return{plugins:[$(),...e.plugins||[]],...e}}export{re as ApiResponse,s as HttpRuntimeClient,e as RariRequest,t as RariResponse,u as clearPropsCache,r as clearPropsCacheForComponent,n as createHttpRuntimeClient,$e as defineRariConfig,Qe as defineRariOptions,i as extractMetadata,l as extractServerProps,c as extractServerPropsWithCache,o as extractStaticParams,x as generateAppRouteManifest,a as hasServerSideDataFetching,$ as rari,P as rariProxy,V as rariRouter};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rari",
3
3
  "type": "module",
4
- "version": "0.10.16",
4
+ "version": "0.10.17",
5
5
  "description": "Runtime Accelerated Rendering Infrastructure (rari)",
6
6
  "author": "Ryan Skinner",
7
7
  "license": "MIT",
@@ -106,17 +106,17 @@
106
106
  "rolldown": "^1.0.0-rc.9"
107
107
  },
108
108
  "optionalDependencies": {
109
- "rari-darwin-arm64": "0.10.16",
110
- "rari-darwin-x64": "0.10.16",
111
- "rari-linux-arm64": "0.10.16",
112
- "rari-linux-x64": "0.10.16",
113
- "rari-win32-x64": "0.10.16"
109
+ "rari-darwin-arm64": "0.10.17",
110
+ "rari-darwin-x64": "0.10.17",
111
+ "rari-linux-arm64": "0.10.17",
112
+ "rari-linux-x64": "0.10.17",
113
+ "rari-win32-x64": "0.10.17"
114
114
  },
115
115
  "devDependencies": {
116
116
  "@types/node": "^25.5.0",
117
117
  "@types/react": "^19.2.14",
118
118
  "@types/react-dom": "^19.2.3",
119
- "@typescript/native-preview": "^7.0.0-dev.20260312.1",
119
+ "@typescript/native-preview": "^7.0.0-dev.20260313.1",
120
120
  "oxlint": "^1.55.0",
121
121
  "tsdown": "^0.20.3",
122
122
  "vite": "^8.0.0",