rari 0.7.13 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{getBinaryPath as e,getInstallationInstructions as t}from"./platform.mjs";import{existsSync as n,readFileSync as r}from"node:fs";import{resolve as i}from"node:path";import a from"node:process";import{spawn as o}from"node:child_process";const s=!(a.env.NO_COLOR||a.argv.includes(`--no-color`))&&(a.env.FORCE_COLOR||a.argv.includes(`--color`)||a.platform===`win32`||a.stdout?.isTTY&&a.env.TERM!==`dumb`||a.env.CI);function c(e,t,n=e){return r=>{let i=String(r),a=i.indexOf(t,e.length);return~a?e+l(i,t,n,a)+t:e+i+t}}function l(e,t,n,r){let i=``,a=0;do i+=e.substring(a,r)+n,a=r+t.length,r=e.indexOf(t,a);while(~r);return i+e.substring(a)}const u=s?c:()=>String;var d={isColorSupported:s,bold:u(`\x1B[1m`,`\x1B[22m`,`\x1B[22m\x1B[1m`),red:u(`\x1B[31m`,`\x1B[39m`),green:u(`\x1B[32m`,`\x1B[39m`),yellow:u(`\x1B[33m`,`\x1B[39m`),blue:u(`\x1B[34m`,`\x1B[39m`),cyan:u(`\x1B[36m`,`\x1B[39m`),gray:u(`\x1B[90m`,`\x1B[39m`)};function f(){let e=i(a.cwd(),`.env`);if(n(e)){let t=r(e,`utf-8`);for(let e of t.split(`
2
+ import{getBinaryPath as e,getInstallationInstructions as t}from"./platform.mjs";import{existsSync as n,readFileSync as r}from"node:fs";import{resolve as i}from"node:path";import a from"node:process";import{spawn as o}from"node:child_process";const s=!(a.env.NO_COLOR||a.argv.includes(`--no-color`))&&(a.env.FORCE_COLOR||a.argv.includes(`--color`)||a.platform===`win32`||a.stdout?.isTTY&&a.env.TERM!==`dumb`||a.env.CI);function c(e,t,n=e){return r=>{let i=String(r),a=i.indexOf(t,e.length);return~a?e+l(i,t,n,a)+t:e+i+t}}function l(e,t,n,r){let i=``,a=0;do i+=e.substring(a,r)+n,a=r+t.length,r=e.indexOf(t,a);while(~r);return i+e.substring(a)}const u=s?c:()=>String;var d={isColorSupported:s,black:u(`\x1B[30m`,`\x1B[39m`),red:u(`\x1B[31m`,`\x1B[39m`),green:u(`\x1B[32m`,`\x1B[39m`),yellow:u(`\x1B[33m`,`\x1B[39m`),blue:u(`\x1B[34m`,`\x1B[39m`),cyan:u(`\x1B[36m`,`\x1B[39m`),gray:u(`\x1B[90m`,`\x1B[39m`),bold:u(`\x1B[1m`,`\x1B[22m`,`\x1B[22m\x1B[1m`),bgCyan:u(`\x1B[46m`,`\x1B[49m`)};function f(){let e=i(a.cwd(),`.env`);if(n(e)){let t=r(e,`utf-8`);for(let e of t.split(`
3
3
  `)){let t=e.trim();if(!t||t.startsWith(`#`))continue;let n=t.match(/^([^=]+)=(.*)$/);if(n){let[,e,t]=n,r=e.trim(),i=t.trim();(i.startsWith(`"`)&&i.endsWith(`"`)||i.startsWith(`'`)&&i.endsWith(`'`))&&(i=i.slice(1,-1)),a.env[r]||(a.env[r]=i)}}}}f();const[,,p,...m]=a.argv;function h(e){console.warn(`${d.blue(`info`)} ${e}`)}function g(e){console.warn(`${d.green(`✓`)} ${e}`)}function _(e){console.error(`${d.red(`✗`)} ${e}`)}function v(){return!!(a.env.RAILWAY_ENVIRONMENT||a.env.RAILWAY_PROJECT_ID||a.env.RAILWAY_SERVICE_ID)}function y(){return!!(a.env.RENDER||a.env.RENDER_SERVICE_ID||a.env.RENDER_SERVICE_NAME)}function b(){return v()||y()}function x(){return v()?`Railway`:y()?`Render`:`local`}function S(){return{port:a.env.PORT||a.env.RSC_PORT||`3000`,mode:a.env.NODE_ENV||`production`,host:b()?`0.0.0.0`:`127.0.0.1`}}async function C(){let{existsSync:e,rmSync:t}=await import(`node:fs`),{resolve:n}=await import(`node:path`),{spawn:r}=await import(`node:child_process`),i=n(a.cwd(),`dist`);e(i)&&(h(`Cleaning dist folder...`),t(i,{recursive:!0,force:!0})),h(`Type checking...`);let o=r(`npx`,[`tsgo`],{stdio:`inherit`,cwd:a.cwd(),shell:!0});await new Promise((e,t)=>{o.on(`exit`,n=>{n===0?(g(`Type check passed`),e()):(_(`Type check failed with code ${n}`),t(Error(`Type check failed with code ${n}`)))}),o.on(`error`,t)}),h(`Building for production...`);let s=r(`npx`,[`vite`,`build`],{stdio:`inherit`,cwd:a.cwd(),shell:!0});await new Promise((e,t)=>{s.on(`exit`,n=>{n===0?(g(`Build complete`),e()):(_(`Build failed with code ${n}`),t(Error(`Build failed with code ${n}`)))}),s.on(`error`,t)})}async function w(){let{existsSync:e}=await import(`node:fs`),{resolve:t}=await import(`node:path`),{spawn:n}=await import(`node:child_process`);if(!e(t(a.cwd(),`dist`))){h(`First run detected - building project...`);let e=n(`npx`,[`vite`,`build`,`--mode`,`development`],{stdio:`inherit`,cwd:a.cwd(),shell:!0});await new Promise((t,n)=>{e.on(`exit`,e=>{e===0?(g(`Initial build complete`),t()):(_(`Build failed with code ${e}`),n(Error(`Build failed with code ${e}`)))}),e.on(`error`,n)})}h(`Starting Vite dev server...`);let r=n(`npx`,[`vite`],{stdio:`inherit`,cwd:a.cwd(),shell:!0}),i=()=>{h(`Shutting down dev server...`),r.kill(`SIGTERM`)};return a.on(`SIGINT`,i),a.on(`SIGTERM`,i),r.on(`error`,e=>{_(`Failed to start Vite: ${e.message}`),a.exit(1)}),r.on(`exit`,e=>{e!==0&&e!==null&&(_(`Vite exited with code ${e}`),a.exit(e))}),new Promise(()=>{})}async function T(){let n;try{n=e()}catch{_(`Failed to obtain rari binary`),_(t()),a.exit(1)}let{port:r,mode:i,host:s}=S();if(b()){let e=x();h(`${e} environment detected`),h(`Starting rari server for ${e} deployment...`),h(`Mode: ${i}, Host: ${s}, Port: ${r}`),h(`using binary: ${n}`)}let c=o(n,[`--mode`,i,`--port`,r,`--host`,s],{stdio:`inherit`,cwd:a.cwd(),env:{...a.env,RUST_LOG:a.env.RUST_LOG||`error`}}),l=()=>{h(`shutting down...`),c.kill(`SIGTERM`)};return a.on(`SIGINT`,l),a.on(`SIGTERM`,l),c.on(`error`,e=>{_(`Failed to start rari server: ${e.message}`),e.message.includes(`ENOENT`)&&_(`Binary not found. Please ensure rari is properly installed.`),a.exit(1)}),c.on(`exit`,(e,t)=>{t?h(`server stopped by signal ${t}`):e===0?g(`server stopped successfully`):(_(`server exited with code ${e}`),a.exit(e||1))}),new Promise(()=>{})}async function E(){h(`Setting up Railway deployment...`),b()&&(_(`Already running in ${x()} environment. Use "rari start" instead.`),a.exit(1));let{createRailwayDeployment:e}=await import(`./railway-BkeFMLcc.mjs`);await e()}async function D(){h(`Setting up Render deployment...`),b()&&(_(`Already running in ${x()} environment. Use "rari start" instead.`),a.exit(1));let{createRenderDeployment:e}=await import(`./render-B2YpwDlB.mjs`);await e()}async function O(){switch(p){case void 0:case`help`:case`--help`:case`-h`:console.warn(`${d.bold(`rari CLI`)}
4
4
 
5
5
  ${d.bold(`Usage:`)}
package/dist/client.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, T as MetadataResult, _ as GenerateStaticParams, a as LoadingSpinner, b as LoadingEntry, c as createErrorBoundary, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, n as DefaultLoading, o as NotFound, p as AppRouteMatch, r as ErrorBoundary, s as RuntimeClient, t as DefaultError, u as createLoadingBoundary, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry } from "./runtime-client-Cba9SeKX.mjs";
1
+ import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, T as MetadataResult, _ as GenerateStaticParams, a as LoadingSpinner, b as LoadingEntry, c as createErrorBoundary, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, n as DefaultLoading, o as NotFound, p as AppRouteMatch, r as ErrorBoundary, s as RuntimeClient, t as DefaultError, u as createLoadingBoundary, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry } from "./runtime-client-B_mktvP9.mjs";
2
2
  import * as React from "react";
3
3
  import { Component, ErrorInfo, ReactNode } from "react";
4
4
  import * as react_jsx_runtime0 from "react/jsx-runtime";
package/dist/client.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import{a as e,c as t,d as n,f as r,g as i,h as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,s as p,t as m,u as h}from"./runtime-client-B15ZQXrE.mjs";import{Component as g,useEffect as _,useRef as v,useState as y}from"react";import{Fragment as b,jsx as x,jsxs as S}from"react/jsx-runtime";function C(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 w(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 T=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=w(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()}};function E(e){if(!e||e===`/`)return`/`;let t=e.replace(/\/+$/,``);return t.startsWith(`/`)||(t=`/${t}`),t}function D(e,t){try{return new URL(e,t||window.location.origin).origin!==(t||window.location.origin)}catch{return!1}}function O(e){try{let t=new URL(e,window.location.origin);return t.pathname+t.hash}catch{return e}}function k({error:e,onRetry:t,onReload:n,onDismiss:r,retryCount:i=0,maxRetries:a=3}){let o=e.retryable&&i<a;return x(`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:S(`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:[S(`div`,{style:{display:`flex`,alignItems:`center`,gap:`12px`,marginBottom:`16px`},children:[x(`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`❌`}})()}),x(`h2`,{style:{margin:0,fontSize:`20px`,fontWeight:`600`,color:`#1f2937`},children:`Navigation Error`})]}),x(`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&&S(`details`,{style:{marginBottom:`16px`,fontSize:`13px`,color:`#6b7280`},children:[x(`summary`,{style:{cursor:`pointer`,userSelect:`none`,marginBottom:`8px`},children:`Technical details`}),S(`div`,{style:{padding:`12px`,background:`#f9fafb`,borderRadius:`4px`,fontFamily:`monospace`,fontSize:`12px`,wordBreak:`break-all`},children:[S(`div`,{style:{marginBottom:`4px`},children:[x(`strong`,{children:`URL:`}),` `,e.url]}),e.statusCode&&S(`div`,{style:{marginBottom:`4px`},children:[x(`strong`,{children:`Status:`}),` `,e.statusCode]}),S(`div`,{style:{marginBottom:`4px`},children:[x(`strong`,{children:`Type:`}),` `,e.type]}),e.originalError&&S(`div`,{children:[x(`strong`,{children:`Error:`}),` `,e.originalError.message]})]})]}),o&&i>0&&S(`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]}),S(`div`,{style:{display:`flex`,gap:`8px`,flexWrap:`wrap`},children:[o&&t&&x(`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&&x(`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&&x(`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`})]}),x(`p`,{style:{marginTop:`16px`,marginBottom:0,fontSize:`12px`,color:`#9ca3af`,textAlign:`center`},children:`Your current page is still available below this message`})]})})}const A=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=await n.json();throw Error(e.error||`Failed to fetch route info`)}return n.json()}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=A}var j=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);Array.from(i.entries()).length>0&&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 M(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 N({children:e,initialRoute:t}){let[n,r]=y(()=>({currentRoute:E(t),navigationId:0,error:null})),i=v(null),a=v(!0),o=v(E(t)),s=v(new T({timeout:1e4,maxRetries:3,onError:e=>{console.error(`[rari] Router: Navigation error:`,e)},onRetry:()=>{}})),c=v(new Map),l=v([]),u=v(new j({maxHistorySize:50})),d=()=>`${Date.now()}-${Math.random().toString(36).substring(2,9)}`,f=()=>{i.current&&=(i.current.abort(),null)},p=()=>{for(let[,e]of c.current.entries())e.abortController.abort();c.current.clear()},m=(e,t)=>{c.current.delete(e),a.current&&n.navigationId===t&&r(e=>({...e}))},h=async e=>A.get(e),g=v(null),w=async(e,t={})=>{if(!e||typeof e!=`string`){console.error(`[rari] Router: Invalid navigation target:`,e);return}let[l,_]=e.includes(`#`)?e.split(`#`):[e,``],v=E(l);if(v===o.current&&!t.replace){if(_){let e=document.getElementById(_);e&&(e.scrollIntoView({behavior:`smooth`,block:`start`}),window.history.pushState(window.history.state,``,`${v}#${_}`))}return}let y=c.current.get(v);if(y)return y.promise;let b=await h(v);p(),f();let x=new AbortController;i.current=x;let S=n.navigationId+1,C=(async()=>{let e=o.current;try{t.historyKey||u.current.captureState(e);let n=t.historyKey||d(),i={route:v,navigationId:S,scrollPosition:{x:window.scrollX,y:window.scrollY},timestamp:Date.now(),key:n},l=_?`${v}#${_}`:v;t.replace?window.history.replaceState(i,``,l):window.history.pushState(i,``,l);let f=(window.location.origin.includes(`:5173`)?`http://localhost:3000`:window.location.origin)+v,p=await fetch(f,{headers:{Accept:`text/x-component`},signal:x.signal});if(!p.ok)throw Error(`Failed to fetch: ${p.status}`);let h=new URL(p.url).pathname,y=h===v?v:h;if(h!==v){let e=_?`${h}#${_}`:h;window.history.replaceState({route:h,navigationId:S,scrollPosition:{x:window.scrollX,y:window.scrollY},timestamp:Date.now(),key:t.historyKey||d()},``,e)}if(x.signal.aborted){m(y,S);return}try{let e=p.headers.get(`x-rari-metadata`);if(e){let t=decodeURIComponent(e);M(JSON.parse(t))}}catch{}if(p.headers.get(`x-render-mode`)===`streaming`&&p.body){let n=p.body.getReader(),r=new TextDecoder,i=``;try{for(;;){let{done:e,value:t}=await n.read();if(e)break;if(x.signal.aborted){await n.cancel(),m(y,S);return}i+=r.decode(t,{stream:!0});let a=i.split(`
1
+ import{a as e,c as t,d as n,f as r,g as i,h as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,s as p,t as m,u as h}from"./runtime-client-B15ZQXrE.mjs";import{Component as g,useEffect as _,useRef as v,useState as y}from"react";import{Fragment as b,jsx as x,jsxs as S}from"react/jsx-runtime";function C(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 w(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 T=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=w(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()}};function E(e){if(!e||e===`/`)return`/`;let t=e.replace(/\/+$/,``);return t.startsWith(`/`)||(t=`/${t}`),t}function D(e,t){try{return new URL(e,t||window.location.origin).origin!==(t||window.location.origin)}catch{return!1}}function O(e){try{let t=new URL(e,window.location.origin);return t.pathname+t.hash}catch{return e}}function k({error:e,onRetry:t,onReload:n,onDismiss:r,retryCount:i=0,maxRetries:a=3}){let o=e.retryable&&i<a;return x(`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:S(`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:[S(`div`,{style:{display:`flex`,alignItems:`center`,gap:`12px`,marginBottom:`16px`},children:[x(`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`❌`}})()}),x(`h2`,{style:{margin:0,fontSize:`20px`,fontWeight:`600`,color:`#1f2937`},children:`Navigation Error`})]}),x(`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&&S(`details`,{style:{marginBottom:`16px`,fontSize:`13px`,color:`#6b7280`},children:[x(`summary`,{style:{cursor:`pointer`,userSelect:`none`,marginBottom:`8px`},children:`Technical details`}),S(`div`,{style:{padding:`12px`,background:`#f9fafb`,borderRadius:`4px`,fontFamily:`monospace`,fontSize:`12px`,wordBreak:`break-all`},children:[S(`div`,{style:{marginBottom:`4px`},children:[x(`strong`,{children:`URL:`}),` `,e.url]}),e.statusCode&&S(`div`,{style:{marginBottom:`4px`},children:[x(`strong`,{children:`Status:`}),` `,e.statusCode]}),S(`div`,{style:{marginBottom:`4px`},children:[x(`strong`,{children:`Type:`}),` `,e.type]}),e.originalError&&S(`div`,{children:[x(`strong`,{children:`Error:`}),` `,e.originalError.message]})]})]}),o&&i>0&&S(`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]}),S(`div`,{style:{display:`flex`,gap:`8px`,flexWrap:`wrap`},children:[o&&t&&x(`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&&x(`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&&x(`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`})]}),x(`p`,{style:{marginTop:`16px`,marginBottom:0,fontSize:`12px`,color:`#9ca3af`,textAlign:`center`},children:`Your current page is still available below this message`})]})})}const A=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=await n.json();throw Error(e.error||`Failed to fetch route info`)}return n.json()}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=A}var j=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);Array.from(i.entries()).length>0&&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 M(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 N({children:e,initialRoute:t}){let[n,r]=y(()=>({currentRoute:E(t),navigationId:0,error:null})),i=v(null),a=v(!0),o=v(E(t)),s=v(new T({timeout:1e4,maxRetries:3,onError:e=>{console.error(`[rari] Router: Navigation error:`,e)},onRetry:()=>{}})),c=v(new Map),l=v([]),u=v(new j({maxHistorySize:50})),d=()=>`${Date.now()}-${Math.random().toString(36).substring(2,9)}`,f=()=>{i.current&&=(i.current.abort(),null)},p=()=>{for(let[,e]of c.current.entries())e.abortController.abort();c.current.clear()},m=(e,t)=>{c.current.delete(e),a.current&&n.navigationId===t&&r(e=>({...e}))},h=async e=>A.get(e),g=v(null),w=async(e,t={})=>{if(!e||typeof e!=`string`){console.error(`[rari] Router: Invalid navigation target:`,e);return}let[l,_]=e.includes(`#`)?e.split(`#`):[e,``],v=E(l);if(v===o.current&&!t.replace){if(_){let e=document.getElementById(_);e&&(e.scrollIntoView({behavior:`smooth`,block:`start`}),window.history.pushState(window.history.state,``,`${v}#${_}`))}return}let y=c.current.get(v);if(y)return y.promise;let b=await h(v);p(),f();let x=new AbortController;i.current=x;let S=n.navigationId+1,C=(async()=>{let e=o.current;try{t.historyKey||u.current.captureState(e);let n=t.historyKey||d(),i={route:v,navigationId:S,scrollPosition:{x:window.scrollX,y:window.scrollY},timestamp:Date.now(),key:n},l=_?`${v}#${_}`:v;t.replace?window.history.replaceState(i,``,l):window.history.pushState(i,``,l);let f=window.location.origin+v,p=await fetch(f,{headers:{Accept:`text/x-component`},signal:x.signal});if(!p.ok)throw Error(`Failed to fetch: ${p.status}`);let h=new URL(p.url).pathname,y=h===v?v:h;if(h!==v){let e=_?`${h}#${_}`:h;window.history.replaceState({route:h,navigationId:S,scrollPosition:{x:window.scrollX,y:window.scrollY},timestamp:Date.now(),key:t.historyKey||d()},``,e)}if(x.signal.aborted){m(y,S);return}try{let e=p.headers.get(`x-rari-metadata`);if(e){let t=decodeURIComponent(e);M(JSON.parse(t))}}catch{}if(p.headers.get(`x-render-mode`)===`streaming`&&p.body){let n=p.body.getReader(),r=new TextDecoder,i=``;try{for(;;){let{done:e,value:t}=await n.read();if(e)break;if(x.signal.aborted){await n.cancel(),m(y,S);return}i+=r.decode(t,{stream:!0});let a=i.split(`
2
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:y,navigationId:S,options:t,routeInfo:b,abortSignal:x.signal,isStreaming:!0}}))}catch(e){throw console.error(`[rari] Router: Streaming error:`,e),e}}else{let n=await p.text();window.dispatchEvent(new CustomEvent(`rari:navigate`,{detail:{from:e,to:y,navigationId:S,options:t,routeInfo:b,abortSignal:x.signal,rscWireFormat:n}}))}if(x.signal.aborted){m(y,S);return}a.current&&(o.current=y,r(e=>({...e,currentRoute:y,error:null})),s.current.resetRetry(y),t.historyKey?requestAnimationFrame(()=>{u.current.restoreState(y)}):_&&requestAnimationFrame(()=>{let e=(t=0)=>{let n=document.getElementById(_);n?n.scrollIntoView({behavior:`smooth`,block:`start`}):t<10&&setTimeout(()=>e(t+1),50)};e()})),c.current.delete(v),g.current?.()}catch(t){if(t instanceof Error&&t.name===`AbortError`){m(v,S);return}let n=s.current.handleError(t,v);a.current&&r(e=>({...e,error:n})),c.current.delete(v),window.dispatchEvent(new CustomEvent(`rari:navigate-error`,{detail:{from:e,to:v,error:n,navigationId:S}})),g.current?.()}})();return c.current.set(v,{targetPath:v,navigationId:S,promise:C,abortController:x}),C};g.current=async()=>{if(l.current.length===0)return;let e=l.current[l.current.length-1];l.current=[],await w(e.path,e.options)};let N=v(null);N.current||=C((e,t)=>{w(e,t)},50,{leading:!1,trailing:!0,maxWait:200});let P=N.current,F=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&&!D(r)){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(),P(O(r),{replace:!1})}},I=e=>{let t=window.location.pathname,n=e.state;w(t,{replace:!0,scroll:!1,historyKey:n?.key})},L=()=>{if(n.error&&n.error.url){let e=n.error.url;s.current.incrementRetry(e),w(e,{replace:!1})}},R=()=>{window.location.reload()},z=()=>{r(e=>({...e,error:null}))};_(()=>{let e=window.history.state;if(!e||!e.key){let e={route:n.currentRoute,navigationId:n.navigationId,scrollPosition:{x:window.scrollX,y:window.scrollY},timestamp:Date.now(),key:d()};window.history.replaceState(e,``,window.location.pathname+window.location.search)}},[]);let B=e=>{if(e.persisted){let e=window.location.pathname;u.current.captureState(e)}},V=e=>{if(e.persisted){let e=window.location.pathname,t=window.history.state;requestAnimationFrame(()=>{u.current.restoreState(e),t?.scrollPosition&&window.scrollTo(t.scrollPosition.x,t.scrollPosition.y)})}};return _(()=>(document.addEventListener(`click`,F),window.addEventListener(`popstate`,I),window.addEventListener(`pagehide`,B),window.addEventListener(`pageshow`,V),()=>{document.removeEventListener(`click`,F),window.removeEventListener(`popstate`,I),window.removeEventListener(`pagehide`,B),window.removeEventListener(`pageshow`,V),a.current=!1,f(),p(),P.cancel&&P.cancel()}),[]),S(b,{children:[e,n.error&&x(k,{error:n.error,onRetry:L,onReload:R,onDismiss:z,retryCount:s.current.getRetryCount(n.error.url||``),maxRetries:3})]})}var P=class extends g{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):S(`div`,{style:{padding:`16px`,margin:`16px 0`,background:`#fee`,border:`1px solid #fcc`,borderRadius:`4px`},children:[x(`h3`,{style:{margin:`0 0 8px 0`,color:`#c00`},children:`Layout Error`}),S(`p`,{style:{margin:`0 0 8px 0`,fontSize:`14px`},children:[`An error occurred in layout:`,` `,x(`code`,{children:this.props.layoutPath})]}),S(`details`,{style:{fontSize:`12px`,marginBottom:`8px`},children:[x(`summary`,{style:{cursor:`pointer`},children:`Error details`}),S(`pre`,{style:{marginTop:`8px`,padding:`8px`,background:`#fff`,border:`1px solid #ddd`,borderRadius:`2px`,overflow:`auto`},children:[this.state.error.message,`
3
3
  `,this.state.error.stack]})]}),x(`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{N as ClientRouter,m as DefaultError,l as DefaultLoading,f as ErrorBoundary,o as HttpRuntimeClient,P as LayoutErrorBoundary,e as LoadingSpinner,T as NavigationErrorHandler,k as NavigationErrorOverlay,u as NotFound,j as StatePreserver,h as clearPropsCache,n as clearPropsCacheForComponent,p as createErrorBoundary,t as createHttpRuntimeClient,s as createLoadingBoundary,r as extractMetadata,d as extractServerProps,c as extractServerPropsWithCache,a as extractStaticParams,i as hasServerSideDataFetching};
package/dist/index.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, S as PageProps, T as MetadataResult, _ as GenerateStaticParams, b as LoadingEntry, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, p as AppRouteMatch, s as RuntimeClient, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry, y as LayoutProps } from "./runtime-client-Cba9SeKX.mjs";
2
- import { C as ApiRouteHandlers, D as RobotsRule, E as Robots, S as ApiResponse, T as RouteHandler, _ as ProxyResult, a as rari, b as RequestCookies, c as ProxyPluginOptions, d as RariRequest, f as CookieOptions, g as ProxyModule, h as ProxyMatcher, i as defineRariOptions, l as rariProxy, m as ProxyFunction, n as Response, o as rariRouter, p as ProxyConfig, r as defineRariConfig, s as generateAppRouteManifest, t as Request, u as RariResponse, v as RariFetchEvent, w as RouteContext, x as ResponseCookies, y as RariURL } from "./vite-BiJzCvlJ.mjs";
3
- export { ApiResponse, ApiRouteHandlers, AppRouteEntry, AppRouteManifest, AppRouteMatch, CookieOptions, ErrorEntry, ErrorProps, GenerateMetadata, GenerateStaticParams, HttpRuntimeClient, LayoutEntry, LayoutProps, LoadingEntry, MetadataResult, NotFoundEntry, PageProps, ProxyConfig, ProxyFunction, ProxyMatcher, ProxyModule, ProxyPluginOptions, ProxyResult, RariFetchEvent, RariRequest, RariResponse, RariURL, Request, RequestCookies, Response, ResponseCookies, type Robots, type RobotsRule, RouteContext, RouteHandler, RouteSegment, RouteSegmentType, RuntimeClient, ServerPropsResult, StaticParamsResult, clearPropsCache, clearPropsCacheForComponent, createHttpRuntimeClient, defineRariConfig, defineRariOptions, extractMetadata, extractServerProps, extractServerPropsWithCache, extractStaticParams, generateAppRouteManifest, hasServerSideDataFetching, rari, rariProxy, rariRouter };
1
+ import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, S as PageProps, T as MetadataResult, _ as GenerateStaticParams, b as LoadingEntry, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, p as AppRouteMatch, s as RuntimeClient, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry, y as LayoutProps } from "./runtime-client-B_mktvP9.mjs";
2
+ import { A as SitemapImage, C as ApiRouteHandlers, D as RobotsRule, E as Robots, O as Sitemap, S as ApiResponse, T as RouteHandler, _ as ProxyResult, a as rari, b as RequestCookies, c as ProxyPluginOptions, d as RariRequest, f as CookieOptions, g as ProxyModule, h as ProxyMatcher, i as defineRariOptions, j as SitemapVideo, k as SitemapEntry, l as rariProxy, m as ProxyFunction, n as Response, o as rariRouter, p as ProxyConfig, r as defineRariConfig, s as generateAppRouteManifest, t as Request, u as RariResponse, v as RariFetchEvent, w as RouteContext, x as ResponseCookies, y as RariURL } from "./vite-CSUUcRB_.mjs";
3
+ export { ApiResponse, ApiRouteHandlers, AppRouteEntry, AppRouteManifest, AppRouteMatch, CookieOptions, ErrorEntry, ErrorProps, GenerateMetadata, GenerateStaticParams, HttpRuntimeClient, LayoutEntry, LayoutProps, LoadingEntry, MetadataResult, NotFoundEntry, PageProps, ProxyConfig, ProxyFunction, ProxyMatcher, ProxyModule, ProxyPluginOptions, ProxyResult, RariFetchEvent, RariRequest, RariResponse, RariURL, Request, RequestCookies, Response, ResponseCookies, type Robots, type RobotsRule, RouteContext, RouteHandler, RouteSegment, RouteSegmentType, RuntimeClient, ServerPropsResult, type Sitemap, type SitemapEntry, type SitemapImage, type SitemapVideo, StaticParamsResult, clearPropsCache, clearPropsCacheForComponent, createHttpRuntimeClient, defineRariConfig, defineRariOptions, extractMetadata, extractServerProps, extractServerPropsWithCache, extractStaticParams, generateAppRouteManifest, hasServerSideDataFetching, rari, rariProxy, rariRouter };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./vite-Em5wQyBY.mjs";import{t as s}from"./RariRequest-CW-JhbGM.mjs";import{c,d as l,f as u,g as d,h as f,i as p,m,p as h,u as g}from"./runtime-client-B15ZQXrE.mjs";import{t as _}from"./routes-Bq7zysPc.mjs";import"./constants-CD3aqqK8.mjs";import"./server-build-CCcyQm4X.mjs";export{a as ApiResponse,p as HttpRuntimeClient,s as RariRequest,r as RariResponse,g as clearPropsCache,l as clearPropsCacheForComponent,c as createHttpRuntimeClient,o as defineRariConfig,n as defineRariOptions,u as extractMetadata,h as extractServerProps,m as extractServerPropsWithCache,f as extractStaticParams,_ as generateAppRouteManifest,d as hasServerSideDataFetching,i as rari,e as rariProxy,t as rariRouter};
1
+ import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./vite-4UHctC2X.mjs";import{t as s}from"./RariRequest-CW-JhbGM.mjs";import{c,d as l,f as u,g as d,h as f,i as p,m,p as h,u as g}from"./runtime-client-B15ZQXrE.mjs";import{t as _}from"./routes-Bq7zysPc.mjs";import"./constants-CD3aqqK8.mjs";import"./server-build-DzXrtj9Z.mjs";export{a as ApiResponse,p as HttpRuntimeClient,s as RariRequest,r as RariResponse,g as clearPropsCache,l as clearPropsCacheForComponent,c as createHttpRuntimeClient,o as defineRariConfig,n as defineRariOptions,u as extractMetadata,h as extractServerProps,m as extractServerPropsWithCache,f as extractStaticParams,_ as generateAppRouteManifest,d as hasServerSideDataFetching,i as rari,e as rariProxy,t as rariRouter};
@@ -257,7 +257,7 @@ declare class ErrorBoundary extends Component<{
257
257
  error: Error;
258
258
  };
259
259
  componentDidCatch(error: Error, errorInfo: any): void;
260
- render(): React.ReactNode;
260
+ render(): string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
261
261
  }
262
262
  declare function createErrorBoundary(fallback?: (error: Error, reset: () => void) => ReactElement): ({
263
263
  children
@@ -0,0 +1 @@
1
+ import{n as e,r as t,t as n}from"./server-build-DzXrtj9Z.mjs";export{n as ServerComponentBuilder,t as scanDirectory};
@@ -1,4 +1,4 @@
1
- import e from"node:fs";import t from"node:path";import n from"node:process";import{build as r}from"esbuild";function i(e){return`fs.path.os.crypto.util.stream.events.process.buffer.url.querystring.zlib.http.https.net.tls.child_process.cluster.worker_threads.assert.dns.readline.repl.string_decoder.timers.tty.v8.vm.perf_hooks`.split(`.`).includes(e)}var a=class{serverComponents=new Map;serverActions=new Map;options;projectRoot;buildCache=new Map;getComponentCount(){return this.serverComponents.size+this.serverActions.size}constructor(e,r={}){this.projectRoot=e,this.options={outDir:r.outDir||t.join(e,`dist`),serverDir:r.serverDir||`server`,manifestPath:r.manifestPath||`server/manifest.json`,minify:r.minify??n.env.NODE_ENV===`production`,alias:r.alias||{},define:r.define,csp:r.csp,rateLimit:r.rateLimit,spamBlocker:r.spamBlocker}}isServerComponent(t){if(t.includes(`node_modules`))return!1;try{if(!e.existsSync(t))return!1;let n=e.readFileSync(t,`utf-8`).split(`
1
+ import e from"node:fs";import t from"node:path";import n from"node:process";import{build as r}from"esbuild";function i(e){return`fs.path.os.crypto.util.stream.events.process.buffer.url.querystring.zlib.http.https.net.tls.child_process.cluster.worker_threads.assert.dns.readline.repl.string_decoder.timers.tty.v8.vm.perf_hooks`.split(`.`).includes(e)}var a=class{serverComponents=new Map;serverActions=new Map;options;projectRoot;buildCache=new Map;htmlOnlyImports=new Set;getComponentCount(){return this.serverComponents.size+this.serverActions.size}constructor(e,r={}){this.projectRoot=e,this.options={outDir:r.outDir||t.join(e,`dist`),serverDir:r.serverDir||`server`,manifestPath:r.manifestPath||`server/manifest.json`,minify:r.minify??n.env.NODE_ENV===`production`,alias:r.alias||{},define:r.define,csp:r.csp,rateLimit:r.rateLimit,spamBlocker:r.spamBlocker},this.parseHtmlImports()}parseHtmlImports(){let n=t.join(this.projectRoot,`index.html`);if(e.existsSync(n))try{let r=e.readFileSync(n,`utf-8`);for(let e of r.matchAll(/import\s+["']([^"']+)["']/g)){let n=e[1];if(n.startsWith(`/src/`)){let e=t.join(this.projectRoot,n.slice(1));this.htmlOnlyImports.add(e)}}}catch(e){console.warn(`[server-build] Error parsing index.html:`,e)}}isHtmlOnlyImport(e){return this.htmlOnlyImports.has(e)}isServerComponent(t){if(t.includes(`node_modules`)||this.isHtmlOnlyImport(t))return!1;try{if(!e.existsSync(t))return!1;let n=e.readFileSync(t,`utf-8`).split(`
2
2
  `),r=!1,i=!1;for(let e of n){let t=e.trim();if(!(t.startsWith(`//`)||t.startsWith(`/*`)||!t)){if(t===`'use client'`||t===`"use client"`||t===`'use client';`||t===`"use client";`){r=!0;break}if(t===`'use server'`||t===`"use server"`||t===`'use server';`||t===`"use server";`){i=!0;break}if(t)break}}return!r&&!i}catch{return!1}}isClientComponent(t){try{if(!e.existsSync(t))return!1;let n=e.readFileSync(t,`utf-8`),r=[`'use client'`,`"use client"`,`/* @client */`,`// @client`],i=n.trim();return r.some(e=>i.startsWith(e)||n.includes(e))}catch{return!1}}addServerComponent(t){let n=e.readFileSync(t,`utf-8`);if(this.isServerAction(n)){let e=this.extractDependencies(n),r=this.hasNodeImports(n);this.serverActions.set(t,{filePath:t,originalCode:n,dependencies:e,hasNodeImports:r});return}if(!this.isServerComponent(t))return;let r=this.extractDependencies(n),i=this.hasNodeImports(n);this.serverComponents.set(t,{filePath:t,originalCode:n,dependencies:r,hasNodeImports:i})}isServerAction(e){let t=e.split(`
3
3
  `);for(let e of t){let t=e.trim();if(!(t.startsWith(`//`)||t.startsWith(`/*`)||!t)){if(t===`'use server'`||t===`"use server"`||t===`'use server';`||t===`"use server";`)return!0;if(t)break}}return!1}extractDependencies(e){let t=[],n=/import(?:\s+(?:\w+|\{[^}]*\}|\*\s+as\s+\w+)(?:\s*,\s*(?:\w+|\{[^}]*\}|\*\s+as\s+\w+))*\s+from\s+)?['"]([^'"]+)['"]/g,r;for(;r=n.exec(e),r!==null;){let e=r[1];!e.startsWith(`.`)&&!e.startsWith(`/`)&&!e.startsWith(`node:`)&&!this.isNodeBuiltin(e)&&t.push(e)}return Array.from(new Set(t))}isNodeBuiltin(e){return[`fs`,`path`,`os`,`crypto`,`util`,`stream`,`events`,`process`,`buffer`,`url`,`querystring`,`zlib`,`http`,`https`,`net`,`tls`,`child_process`,`cluster`,`worker_threads`].includes(e)}hasNodeImports(e){return e.includes(`from 'node:`)||e.includes(`from "node:`)||e.includes(`from 'fs'`)||e.includes(`from "fs"`)||e.includes(`from 'path'`)||e.includes(`from "path"`)||e.includes(`from 'os'`)||e.includes(`from "os"`)||e.includes(`from 'crypto'`)||e.includes(`from "crypto"`)||e.includes(`from 'util'`)||e.includes(`from "util"`)||e.includes(`from 'stream'`)||e.includes(`from "stream"`)||e.includes(`from 'events'`)||e.includes(`from "events"`)}async getTransformedComponentsForDevelopment(){let e=[];for(let[n,r]of this.serverComponents){let i=t.relative(this.projectRoot,n),a=this.getComponentId(i),o=await this.buildComponentCodeOnly(n,a,r);e.push({id:a,code:o})}for(let[n,r]of this.serverActions){let i=t.relative(this.projectRoot,n),a=this.getComponentId(i),o=await this.buildComponentCodeOnly(n,a,r);e.push({id:a,code:o})}return e}transformComponentImportsToGlobal(n){let r=/import\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g,i=[];for(let a of n.matchAll(r)){let[n,r,o]=a;if(!o.startsWith(`.`)&&!o.startsWith(`@`)&&!o.startsWith(`~`)&&!o.startsWith(`#`))continue;let s=null;if(o.startsWith(`.`)){if(o.includes(`/components/`)){let a=o.match(/\/components\/(\w+)(?:\.tsx?|\.jsx?)?$/);if(a){let o=a[1],s=[t.resolve(this.projectRoot,`src`,`components`,`${o}.tsx`),t.resolve(this.projectRoot,`src`,`components`,`${o}.ts`),t.resolve(this.projectRoot,`src`,`components`,`${o}.jsx`),t.resolve(this.projectRoot,`src`,`components`,`${o}.js`)],c=!1;for(let t of s)if(e.existsSync(t)&&this.isClientComponent(t)){c=!0;break}if(!c)continue;let l=`// Component reference: ${o}
4
4
  const ${r} = (props) => {
@@ -43,15 +43,15 @@ const ${r} = (props) => {
43
43
  function registerClientReference(clientReference, id, exportName) {
44
44
  const key = id + '#' + exportName;
45
45
  const clientProxy = {};
46
- Object.defineProperty(clientProxy, '$typeof', {
46
+ Object.defineProperty(clientProxy, '$$typeof', {
47
47
  value: Symbol.for('react.client.reference'),
48
48
  enumerable: false
49
49
  });
50
- Object.defineProperty(clientProxy, '$id', {
50
+ Object.defineProperty(clientProxy, '$$id', {
51
51
  value: key,
52
52
  enumerable: false
53
53
  });
54
- Object.defineProperty(clientProxy, '$async', {
54
+ Object.defineProperty(clientProxy, '$$async', {
55
55
  value: false,
56
56
  enumerable: false
57
57
  });
@@ -206,4 +206,4 @@ function registerClientReference(clientReference, id, exportName) {
206
206
  }
207
207
 
208
208
  `+r);for(let{original:e,replacement:t}of o)r=r.replace(e,t);return r}resolveImportPath(n,r){let i=n,a=this.options.alias||{};for(let[e,r]of Object.entries(a))if(n.startsWith(`${e}/`)||n===e){let a=n.slice(e.length);i=t.join(r,a);break}t.isAbsolute(i)||(i=t.resolve(t.dirname(r),i));let o=[`.tsx`,`.jsx`,`.ts`,`.js`];for(let t of o){let n=`${i}${t}`;if(e.existsSync(n))return n}if(e.existsSync(i))for(let n of o){let r=t.join(i,`index${n}`);if(e.existsSync(r))return r}return`${i}.tsx`}getComponentId(e){return e.replace(/\\/g,`/`).replace(/\.(tsx?|jsx?)$/,``).replace(/[^\w/-]/g,`_`).replace(/^src\//,``).replace(/^components\//,`components/`)}async rebuildComponent(n){let r=this.getComponentId(t.relative(this.projectRoot,n)),i=await e.promises.readFile(n,`utf-8`),a=this.extractDependencies(i),o={filePath:n,originalCode:i,dependencies:a,hasNodeImports:this.hasNodeImports(i)};this.isServerAction(i)?this.serverActions.set(n,o):this.serverComponents.set(n,o);let s=t.join(this.options.serverDir,`${r}.js`),c=t.join(this.options.outDir,s),l=this.buildCache.get(n),u=(await e.promises.stat(n)).mtimeMs;if(l&&l.timestamp>=u&&JSON.stringify(l.dependencies)===JSON.stringify(a))return await e.promises.writeFile(c,l.code,`utf-8`),await this.updateManifestForComponent(r,n,s),{componentId:r,bundlePath:t.join(this.options.outDir,s),success:!0};let d=t.dirname(c);await e.promises.mkdir(d,{recursive:!0});let f=await this.buildSingleComponent(n,c,o,!0);return this.buildCache.set(n,{code:f,timestamp:Date.now(),dependencies:a}),await this.updateManifestForComponent(r,n,s),{componentId:r,bundlePath:t.join(this.options.outDir,s),success:!0}}manifestCache=null;manifestDirty=!1;async updateManifestForComponent(n,r,i){let a=t.join(this.options.outDir,this.options.manifestPath),o;if(this.manifestCache)o=this.manifestCache;else if(e.existsSync(a)){let t=await e.promises.readFile(a,`utf-8`);o=JSON.parse(t),this.manifestCache=o}else o={components:{},importMap:{imports:{react:`npm:react@19`,"react-dom":`npm:react-dom@19`,"react/jsx-runtime":`npm:react@19/jsx-runtime`,"react/jsx-dev-runtime":`npm:react@19/jsx-dev-runtime`}},version:`1.0.0`,buildTime:new Date().toISOString(),csp:this.options.csp,rateLimit:this.options.rateLimit,spamBlocker:this.options.spamBlocker},this.manifestCache=o;let s=this.serverComponents.get(r)||this.serverActions.get(r),c=t.join(this.options.outDir,i),l=`file://${t.resolve(this.projectRoot,c)}`;if(s)o.components[n]={id:n,filePath:r,relativePath:t.relative(this.projectRoot,r),bundlePath:i,moduleSpecifier:l,dependencies:s.dependencies,hasNodeImports:s.hasNodeImports};else{let a=await e.promises.readFile(r,`utf-8`);o.components[n]={id:n,filePath:r,relativePath:t.relative(this.projectRoot,r),bundlePath:i,moduleSpecifier:l,dependencies:this.extractDependencies(a),hasNodeImports:this.hasNodeImports(a)}}o.importMap||={imports:{react:`npm:react@19`,"react-dom":`npm:react-dom@19`,"react/jsx-runtime":`npm:react@19/jsx-runtime`,"react/jsx-dev-runtime":`npm:react@19/jsx-dev-runtime`}},o.buildTime=new Date().toISOString(),await e.promises.writeFile(a,JSON.stringify(o,null,2),`utf-8`),this.manifestCache=o}clearCache(){this.buildCache.clear(),this.manifestCache=null}async getTransformedComponentCode(n){let r=t.relative(this.projectRoot,n),i=this.getComponentId(r),a=await e.promises.readFile(n,`utf-8`),o={dependencies:this.extractDependencies(a),hasNodeImports:this.hasNodeImports(a)};return await this.buildComponentCodeOnly(n,i,o)}};function o(n,r){let i=e.readdirSync(n,{withFileTypes:!0});for(let a of i){let i=t.join(n,a.name);if(a.isDirectory())o(i,r);else if(a.isFile()&&/\.(?:tsx?|jsx?)$/.test(a.name)){if(/^(?:robots|sitemap)\.(?:tsx?|jsx?)$/.test(a.name))continue;try{if(r.isServerComponent(i))r.addServerComponent(i);else{let t=e.readFileSync(i,`utf-8`).split(`
209
- `),n=!1;for(let e of t){let t=e.trim();if(!(t.startsWith(`//`)||t.startsWith(`/*`)||!t)){if(t===`'use server'`||t===`"use server"`||t===`'use server';`||t===`"use server";`){n=!0;break}if(t)break}}n&&r.addServerComponent(i)}}catch(e){console.warn(`[server-build] Error checking ${i}:`,e instanceof Error?e.message:e)}}}}function s(r={}){let i=null,s,c=!1;return{name:`rari-server-build`,configResolved(e){s=e.root,c=e.command===`serve`;let t={};if(e.resolve?.alias){let n=e.resolve.alias;Array.isArray(n)?n.forEach(e=>{typeof e.find==`string`&&typeof e.replacement==`string`&&(t[e.find]=e.replacement)}):typeof n==`object`&&Object.entries(n).forEach(([e,n])=>{typeof n==`string`&&(t[e]=n)})}i=new a(s,{...r,alias:t})},buildStart(){if(!i)return;let r=n.env.NODE_ENV===`production`,a=[t.join(s,`dist`,`cache`,`og`),t.join(s,`dist`,`cache`,`images`)];r&&a.push(`/tmp/rari-og-cache`,`/tmp/rari-image-cache`);for(let t of a)try{e.existsSync(t)&&e.rmSync(t,{recursive:!0,force:!0})}catch(e){console.warn(`[rari] Failed to clear cache ${t}:`,e)}let c=t.join(s,`src`);e.existsSync(c)&&o(c,i)},async closeBundle(){if(i){await i.buildServerComponents();try{let{generateRobotsFile:e}=await import(`./robots-generator-AcmtuCNy.mjs`);await e({appDir:t.join(s,`src`,`app`),outDir:t.join(s,`dist`),extensions:[`.ts`,`.tsx`,`.js`,`.jsx`]})}catch(e){console.warn(`[rari] Failed to generate robots.txt:`,e)}}},async handleHotUpdate({file:n}){if(!i||!c)return;let r=t.relative(s,n);if(!(!r.startsWith(`src/`)||!r.match(/\.(tsx?|jsx?)$/)))try{if((await e.promises.readFile(n,`utf-8`)).includes(`use client`))return;await i.buildServerComponents()}catch(e){console.error(`[rari] Build: Error rebuilding ${r}:`,e)}}}}export{s as n,o as r,a as t};
209
+ `),n=!1;for(let e of t){let t=e.trim();if(!(t.startsWith(`//`)||t.startsWith(`/*`)||!t)){if(t===`'use server'`||t===`"use server"`||t===`'use server';`||t===`"use server";`){n=!0;break}if(t)break}}n&&r.addServerComponent(i)}}catch(e){console.warn(`[server-build] Error checking ${i}:`,e instanceof Error?e.message:e)}}}}function s(r={}){let i=null,s,c=!1;return{name:`rari-server-build`,configResolved(e){s=e.root,c=e.command===`serve`;let t={};if(e.resolve?.alias){let n=e.resolve.alias;Array.isArray(n)?n.forEach(e=>{typeof e.find==`string`&&typeof e.replacement==`string`&&(t[e.find]=e.replacement)}):typeof n==`object`&&Object.entries(n).forEach(([e,n])=>{typeof n==`string`&&(t[e]=n)})}i=new a(s,{...r,alias:t})},buildStart(){if(!i)return;let r=n.env.NODE_ENV===`production`,a=[t.join(s,`dist`,`cache`,`og`),t.join(s,`dist`,`cache`,`images`)];r&&a.push(`/tmp/rari-og-cache`,`/tmp/rari-image-cache`);for(let t of a)try{e.existsSync(t)&&e.rmSync(t,{recursive:!0,force:!0})}catch(e){console.warn(`[rari] Failed to clear cache ${t}:`,e)}let c=t.join(s,`src`);e.existsSync(c)&&o(c,i)},async closeBundle(){if(i){await i.buildServerComponents();try{let{generateRobotsFile:e}=await import(`./robots-generator-AcmtuCNy.mjs`);await e({appDir:t.join(s,`src`,`app`),outDir:t.join(s,`dist`),extensions:[`.ts`,`.tsx`,`.js`,`.jsx`]})}catch(e){console.warn(`[rari] Failed to generate robots.txt:`,e)}try{let{generateSitemapFiles:e}=await import(`./sitemap-generator-BrVMQEl6.mjs`);await e({appDir:t.join(s,`src`,`app`),outDir:t.join(s,`dist`),extensions:[`.ts`,`.tsx`,`.js`,`.jsx`]})}catch(e){console.warn(`[rari] Failed to generate sitemap:`,e)}}},async handleHotUpdate({file:n}){if(!i||!c)return;let r=t.relative(s,n);if(!(!r.startsWith(`src/`)||!r.match(/\.(tsx?|jsx?)$/)))try{if((await e.promises.readFile(n,`utf-8`)).includes(`use client`))return;await i.buildServerComponents()}catch(e){console.error(`[rari] Build: Error rebuilding ${r}:`,e)}}}}export{s as n,o as r,a as t};
@@ -0,0 +1,4 @@
1
+ import{promises as e}from"node:fs";import t from"node:path";function n(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&apos;`)}function r(e){return(typeof e==`string`?new Date(e):e).toISOString()}function i(e){let t=[];for(let r of e)typeof r==`string`?(t.push(` <image:image>`),t.push(` <image:loc>${n(r)}</image:loc>`),t.push(` </image:image>`)):(t.push(` <image:image>`),t.push(` <image:loc>${n(r.loc)}</image:loc>`),r.title&&t.push(` <image:title>${n(r.title)}</image:title>`),r.caption&&t.push(` <image:caption>${n(r.caption)}</image:caption>`),r.geoLocation&&t.push(` <image:geo_location>${n(r.geoLocation)}</image:geo_location>`),r.license&&t.push(` <image:license>${n(r.license)}</image:license>`),t.push(` </image:image>`));return t.join(`
2
+ `)}function a(e){let t=[];for(let r of e){if(t.push(` <video:video>`),t.push(` <video:title>${n(r.title)}</video:title>`),t.push(` <video:thumbnail_loc>${n(r.thumbnail_loc)}</video:thumbnail_loc>`),t.push(` <video:description>${n(r.description)}</video:description>`),r.content_loc&&t.push(` <video:content_loc>${n(r.content_loc)}</video:content_loc>`),r.player_loc&&t.push(` <video:player_loc>${n(r.player_loc)}</video:player_loc>`),r.duration!==void 0&&t.push(` <video:duration>${r.duration}</video:duration>`),r.expiration_date&&t.push(` <video:expiration_date>${n(r.expiration_date)}</video:expiration_date>`),r.rating!==void 0&&t.push(` <video:rating>${r.rating}</video:rating>`),r.view_count!==void 0&&t.push(` <video:view_count>${r.view_count}</video:view_count>`),r.publication_date&&t.push(` <video:publication_date>${n(r.publication_date)}</video:publication_date>`),r.family_friendly!==void 0&&t.push(` <video:family_friendly>${r.family_friendly?`yes`:`no`}</video:family_friendly>`),r.restriction&&t.push(` <video:restriction relationship="${r.restriction.relationship}">${n(r.restriction.content)}</video:restriction>`),r.platform&&t.push(` <video:platform relationship="${r.platform.relationship}">${n(r.platform.content)}</video:platform>`),r.requires_subscription!==void 0&&t.push(` <video:requires_subscription>${r.requires_subscription?`yes`:`no`}</video:requires_subscription>`),r.uploader){let e=r.uploader.info?` info="${n(r.uploader.info)}"`:``;t.push(` <video:uploader${e}>${n(r.uploader.name)}</video:uploader>`)}if(r.live!==void 0&&t.push(` <video:live>${r.live?`yes`:`no`}</video:live>`),r.tag)for(let e of r.tag)t.push(` <video:tag>${n(e)}</video:tag>`);t.push(` </video:video>`)}return t.join(`
3
+ `)}function o(e){let t=e.some(e=>e.images&&e.images.length>0),o=e.some(e=>e.videos&&e.videos.length>0),s=e.some(e=>e.alternates?.languages),c=[`xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"`];t&&c.push(`xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"`),o&&c.push(`xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"`),s&&c.push(`xmlns:xhtml="http://www.w3.org/1999/xhtml"`);let l=[`<?xml version="1.0" encoding="UTF-8"?>`,`<urlset ${c.join(` `)}>`];for(let t of e){if(l.push(` <url>`),l.push(` <loc>${n(t.url)}</loc>`),t.lastModified&&l.push(` <lastmod>${r(t.lastModified)}</lastmod>`),t.changeFrequency&&l.push(` <changefreq>${t.changeFrequency}</changefreq>`),t.priority!==void 0&&l.push(` <priority>${t.priority}</priority>`),t.alternates?.languages)for(let[e,r]of Object.entries(t.alternates.languages))l.push(` <xhtml:link rel="alternate" hreflang="${n(e)}" href="${n(r)}" />`);t.images&&t.images.length>0&&l.push(i(t.images)),t.videos&&t.videos.length>0&&l.push(a(t.videos)),l.push(` </url>`)}return l.push(`</urlset>`),l.join(`
4
+ `)}async function s(n,r=[`.ts`,`.tsx`,`.js`,`.jsx`]){let i=[],a=t.join(n,`sitemap.xml`);try{return await e.access(a),i.push({type:`static`,path:a}),i}catch{}for(let a of r){let r=t.join(n,`sitemap${a}`);try{return await e.access(r),i.push({type:`dynamic`,path:r}),i}catch{}}return i}async function c(e,t){let n=await import(`file://${e}`);return typeof n.default==`function`?t===void 0?await n.default():await n.default({id:Promise.resolve(t)}):n.default}async function l(n,r,i){let a=await(await import(`esbuild`)).build({entryPoints:[n],bundle:!0,platform:`node`,format:`esm`,write:!1,external:[`rari`],target:`node20`});if(!a.outputFiles||a.outputFiles.length===0)throw Error(`Failed to build sitemap module`);let o=a.outputFiles[0].text,s=i===void 0?`_sitemap_temp.mjs`:`_sitemap_${i}_temp.mjs`,c=t.join(r,s);return await e.writeFile(c,o),c}async function u(n){let{appDir:r,outDir:i,extensions:a}=n,u=await s(r,a);if(u.length===0)return!1;let d=u[0];if(d.type===`static`){let n=t.join(i,`sitemap.xml`);return await e.copyFile(d.path,n),!0}try{let n=await l(d.path,i);try{let r=await import(`file://${n}`);if(typeof r.generateSitemaps==`function`){let a=await r.generateSitemaps();for(let{id:r}of a){let a=o(await c(n,String(r))),s=t.join(i,`sitemap/${r}.xml`);await e.mkdir(t.dirname(s),{recursive:!0}),await e.writeFile(s,a)}}else{let r=o(await c(n)),a=t.join(i,`sitemap.xml`);await e.writeFile(a,r)}return await e.unlink(n),!0}catch(t){console.error(`[rari] Failed to execute sitemap file:`,t);try{await e.unlink(n)}catch{}return!1}}catch(e){return console.error(`[rari] Failed to build sitemap file:`,e),!1}}export{u as generateSitemapFiles};
@@ -1,6 +1,6 @@
1
- import{t as e}from"./chunk-TmZEKRxo.mjs";import{a as t,i as n,n as r,o as i,r as a,t as o}from"./constants-CD3aqqK8.mjs";import{n as s}from"./server-build-CCcyQm4X.mjs";import c,{promises as l}from"node:fs";import u from"node:path";import d from"node:process";import{Buffer as f}from"node:buffer";import{spawn as p}from"node:child_process";import{fileURLToPath as m}from"node:url";import{transformSync as h}from"esbuild";var g=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})}},_=class{cookies;constructor(){this.cookies=new Map}get(e){let t=this.cookies.get(e);if(t)return{name:t.name,value:t.value,path:t.options?.path}}getAll(){return Array.from(this.cookies.values()).map(e=>({name:e.name,value:e.value,path:e.options?.path}))}set(e,t,n){if(typeof e==`string`)this.cookies.set(e,{name:e,value:t,options:n});else{let{name:t,value:n,...r}=e;this.cookies.set(t,{name:t,value:n,options:r})}}delete(e){this.cookies.delete(e)}toSetCookieHeaders(){return Array.from(this.cookies.values()).map(e=>{let t=`${e.name}=${e.value}`;return e.options&&(e.options.path&&(t+=`; Path=${e.options.path}`),e.options.domain&&(t+=`; Domain=${e.options.domain}`),e.options.maxAge&&(t+=`; Max-Age=${e.options.maxAge}`),e.options.expires&&(t+=`; Expires=${e.options.expires.toUTCString()}`),e.options.httpOnly&&(t+=`; HttpOnly`),e.options.secure&&(t+=`; Secure`),e.options.sameSite&&(t+=`; SameSite=${e.options.sameSite}`)),t})}},v=class e extends Response{cookies;constructor(e,t){super(e,t),this.cookies=new _}static next(t){let n=new e(null,{status:200,headers:{"x-rari-proxy-continue":`true`}});return t?.request?.headers&&(t.request.headers instanceof Headers?t.request.headers:new Headers(t.request.headers)).forEach((e,t)=>{n.headers.set(`x-rari-proxy-request-${t}`,e)}),n}static redirect(t,n){return new e(null,{status:n||307,headers:{Location:t.toString()}})}static rewrite(t){return new e(null,{status:200,headers:{"x-rari-proxy-rewrite":t.toString()}})}static json(t,n){return new e(JSON.stringify(t),{...n,headers:{"Content-Type":`application/json`,...n?.headers}})}};function y(e={}){let{root:t=d.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=u.join(t,n);try{return await l.access(i),s(`Found proxy file: ${n}`),{filePath:i,exists:!0,relativePath:n}}catch{}}let e=u.join(t,n);try{await l.access(e);for(let t of i){let i=`${r}${t}`,a=u.join(e,i);try{return await l.access(a),s(`Found proxy file: ${u.join(n,i)}`),{filePath:a,exists:!0,relativePath:u.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 b={appDir:`src/app`,extensions:[`.tsx`,`.jsx`,`.ts`,`.js`],outDir:`dist`};function x(e){switch(u.basename(e).replace(/\.(tsx?|jsx?)$/,``)){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 S(e,t){let n=u.relative(t,u.dirname(e));return!n||n===`.`?`/`:`/${n.replace(/\\/g,`/`).split(`/`).filter(Boolean).join(`/`)}`}function C(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 w(e){try{let t=e.match(/export\s+const\s+metadata\s*(?::\s*\w+\s*)?=\s*(\{[\s\S]*?\n\})/);if(!t)return null;let n=t[1],r={},i=n.match(/title\s*:\s*['"]([^'"]+)['"]/);i&&(r.title=i[1]);let a=n.match(/description\s*:\s*['"]([^'"]+)['"]/);a&&(r.description=a[1]);let o=n.match(/keywords\s*:\s*\[([\s\S]*?)\]/);o&&(r.keywords=o[1].split(`,`).map(e=>e.trim().replace(/['"]/g,``)).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 T(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 E(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 D(e={}){let t={...b,...e},n=null,r=new Map,i=null,a=new Set,o=e=>Array.from(e).sort().join(`|`),s=async e=>{let n=new Set,r=async e=>{try{let i=await l.readdir(e,{withFileTypes:!0});for(let a of i){let i=u.join(e,a.name);a.isDirectory()?await r(i):a.isFile()&&t.extensions.some(e=>a.name.endsWith(e))&&x(i)&&n.add(i)}}catch{}};return await r(e),n},c=async(e,r=!1)=>{let c=u.resolve(e,t.appDir);try{await l.access(c)}catch{return null}try{let d=await s(c),f=o(d);if(!r&&i===f&&n)return n;let{generateAppRouteManifest:p}=await import(`./routes-VWQ7KgNh.mjs`),m=await p(c,{extensions:t.extensions}),h=JSON.stringify(m,null,2),g=u.resolve(e,t.outDir);await l.mkdir(g,{recursive:!0});let _=u.join(g,`server`);return await l.mkdir(_,{recursive:!0}),await l.writeFile(u.join(_,`routes.json`),h,`utf-8`),i=f,a.clear(),d.forEach(e=>a.add(e)),h}catch(e){return console.error(`[rari] Router: Failed to generate app routes:`,e),null}},f=e=>{let n=u.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=x(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)}})},p;return{name:`rari-router`,configResolved(e){p=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(p||d.cwd(),!0)},configureServer(e){f(e)},async handleHotUpdate(e){let{file:i,server:o}=e,s=u.resolve(o.config.root,t.appDir);if(i.startsWith(s)&&t.extensions.some(e=>i.endsWith(e))){let e=x(i);if(e){let t=r.get(i);t&&clearTimeout(t);let d=setTimeout(async()=>{r.delete(i);let t=!a.has(i),d=n;n=await c(o.config.root,t);let f=d!==n,p=S(i,s),m=[p];if(n)try{m=JSON.parse(n).routes.map(e=>e.path)}catch(e){console.error(`[rari] Router: Failed to parse manifest for affected routes:`,e)}let h=C(p,e,m),g,_=!1,v;if(e===`page`||e===`layout`)try{let e=w(await l.readFile(i,`utf-8`));e&&(g=e,_=!0)}catch(e){console.error(`[rari] Router: Failed to extract metadata:`,e)}if(e===`route`)try{v=T(await l.readFile(i,`utf-8`)),await E(u.relative(s,i))}catch(e){console.error(`[rari] Router: Failed to detect HTTP methods:`,e)}let y={fileType:e,filePath:u.relative(o.config.root,i),routePath:p,affectedRoutes:h,manifestUpdated:f,timestamp:Date.now(),metadata:g,metadataChanged:_,methods:v};o.ws.send({type:`custom`,event:`rari:app-router-updated`,data:y})},200);return r.set(i,d),[]}return n=await c(o.config.root),[]}},async closeBundle(){for(let e of r.values())clearTimeout(e);r.clear()}}}var O=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()}},k=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 O({maxErrors:5,resetTimeout:3e4})}async handleClientComponentUpdate(e,t){let n=u.relative(d.cwd(),e),r=Date.now();this.queueLog(`info`,`Client component changed: ${n}`);try{let i=t.moduleGraph.getModuleById(e);if(i){t.moduleGraph.invalidateModule(i);let e=Date.now()-r;this.queueLog(`success`,`Client component updated: ${n} (${e}ms)`),this.errorHandler.reset()}else 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=Array.from(this.pendingFiles);if(this.pendingFiles.clear(),this.batchTimer=null,e.length===0)return;let n=Date.now();if(e.length===1){let t=u.relative(d.cwd(),e[0]);this.queueLog(`info`,`Rebuilding server component: ${t}`)}else this.queueLog(`info`,`Rebuilding ${e.length} server components in batch`);let r=await Promise.allSettled(e.map(async e=>{let t=u.relative(d.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))}}})),i=[],a=[];r.forEach(e=>{e.status===`fulfilled`&&e.value.success?i.push(e.value):e.status===`fulfilled`&&!e.value.success?a.push(e.value):e.status===`rejected`&&a.push({filePath:``,relativePath:`unknown`,error:Error(String(e.reason))})});let o=Date.now()-n;if(i.length>0){let e=Date.now();i.forEach(({componentId:n})=>{t.hot.send(`rari:server-component-updated`,{id:n,t:e})}),i.length===1?this.queueLog(`success`,`Server component updated: ${i[0].relativePath} (${o}ms)`):this.queueLog(`success`,`${i.length} server components updated (${o}ms)`),this.errorHandler.reset(),t.ws.send({type:`custom`,event:`rari:hmr-error-cleared`,data:{t:e}})}if(a.length>0){let e=Date.now();a.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}`)}}catch(e){throw console.error(`[rari] HMR: Failed to notify Rust server:`,e),e}}detectComponentType(e){try{let t=c.readFileSync(e,`utf-8`).split(`
1
+ import{t as e}from"./chunk-TmZEKRxo.mjs";import{a as t,i as n,n as r,o as i,r as a,t as o}from"./constants-CD3aqqK8.mjs";import{n as s}from"./server-build-DzXrtj9Z.mjs";import c,{promises as l}from"node:fs";import u from"node:path";import d from"node:process";import{Buffer as f}from"node:buffer";import{spawn as p}from"node:child_process";import{fileURLToPath as m}from"node:url";import{transformSync as h}from"esbuild";var g=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})}},_=class{cookies;constructor(){this.cookies=new Map}get(e){let t=this.cookies.get(e);if(t)return{name:t.name,value:t.value,path:t.options?.path}}getAll(){return Array.from(this.cookies.values()).map(e=>({name:e.name,value:e.value,path:e.options?.path}))}set(e,t,n){if(typeof e==`string`)this.cookies.set(e,{name:e,value:t,options:n});else{let{name:t,value:n,...r}=e;this.cookies.set(t,{name:t,value:n,options:r})}}delete(e){this.cookies.delete(e)}toSetCookieHeaders(){return Array.from(this.cookies.values()).map(e=>{let t=`${e.name}=${e.value}`;return e.options&&(e.options.path&&(t+=`; Path=${e.options.path}`),e.options.domain&&(t+=`; Domain=${e.options.domain}`),e.options.maxAge&&(t+=`; Max-Age=${e.options.maxAge}`),e.options.expires&&(t+=`; Expires=${e.options.expires.toUTCString()}`),e.options.httpOnly&&(t+=`; HttpOnly`),e.options.secure&&(t+=`; Secure`),e.options.sameSite&&(t+=`; SameSite=${e.options.sameSite}`)),t})}},v=class e extends Response{cookies;constructor(e,t){super(e,t),this.cookies=new _}static next(t){let n=new e(null,{status:200,headers:{"x-rari-proxy-continue":`true`}});return t?.request?.headers&&(t.request.headers instanceof Headers?t.request.headers:new Headers(t.request.headers)).forEach((e,t)=>{n.headers.set(`x-rari-proxy-request-${t}`,e)}),n}static redirect(t,n){return new e(null,{status:n||307,headers:{Location:t.toString()}})}static rewrite(t){return new e(null,{status:200,headers:{"x-rari-proxy-rewrite":t.toString()}})}static json(t,n){return new e(JSON.stringify(t),{...n,headers:{"Content-Type":`application/json`,...n?.headers}})}};function y(e={}){let{root:t=d.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=u.join(t,n);try{return await l.access(i),s(`Found proxy file: ${n}`),{filePath:i,exists:!0,relativePath:n}}catch{}}let e=u.join(t,n);try{await l.access(e);for(let t of i){let i=`${r}${t}`,a=u.join(e,i);try{return await l.access(a),s(`Found proxy file: ${u.join(n,i)}`),{filePath:a,exists:!0,relativePath:u.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 b={appDir:`src/app`,extensions:[`.tsx`,`.jsx`,`.ts`,`.js`],outDir:`dist`};function x(e){switch(u.basename(e).replace(/\.(tsx?|jsx?)$/,``)){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 S(e,t){let n=u.relative(t,u.dirname(e));return!n||n===`.`?`/`:`/${n.replace(/\\/g,`/`).split(`/`).filter(Boolean).join(`/`)}`}function C(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 w(e){try{let t=e.match(/export\s+const\s+metadata\s*(?::\s*\w+\s*)?=\s*(\{[\s\S]*?\n\})/);if(!t)return null;let n=t[1],r={},i=n.match(/title\s*:\s*['"]([^'"]+)['"]/);i&&(r.title=i[1]);let a=n.match(/description\s*:\s*['"]([^'"]+)['"]/);a&&(r.description=a[1]);let o=n.match(/keywords\s*:\s*\[([\s\S]*?)\]/);o&&(r.keywords=o[1].split(`,`).map(e=>e.trim().replace(/['"]/g,``)).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 T(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 E(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 D(e={}){let t={...b,...e},n=null,r=new Map,i=null,a=new Set,o=e=>Array.from(e).sort().join(`|`),s=async e=>{let n=new Set,r=async e=>{try{let i=await l.readdir(e,{withFileTypes:!0});for(let a of i){let i=u.join(e,a.name);a.isDirectory()?await r(i):a.isFile()&&t.extensions.some(e=>a.name.endsWith(e))&&x(i)&&n.add(i)}}catch{}};return await r(e),n},c=async(e,r=!1)=>{let c=u.resolve(e,t.appDir);try{await l.access(c)}catch{return null}try{let d=await s(c),f=o(d);if(!r&&i===f&&n)return n;let{generateAppRouteManifest:p}=await import(`./routes-VWQ7KgNh.mjs`),m=await p(c,{extensions:t.extensions}),h=JSON.stringify(m,null,2),g=u.resolve(e,t.outDir);await l.mkdir(g,{recursive:!0});let _=u.join(g,`server`);return await l.mkdir(_,{recursive:!0}),await l.writeFile(u.join(_,`routes.json`),h,`utf-8`),i=f,a.clear(),d.forEach(e=>a.add(e)),h}catch(e){return console.error(`[rari] Router: Failed to generate app routes:`,e),null}},f=e=>{let n=u.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=x(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)}})},p;return{name:`rari-router`,configResolved(e){p=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(p||d.cwd(),!0)},configureServer(e){f(e)},async handleHotUpdate(e){let{file:i,server:o}=e,s=u.resolve(o.config.root,t.appDir);if(i.startsWith(s)&&t.extensions.some(e=>i.endsWith(e))){let e=x(i);if(e){let t=r.get(i);t&&clearTimeout(t);let d=setTimeout(async()=>{r.delete(i);let t=!a.has(i),d=n;n=await c(o.config.root,t);let f=d!==n,p=S(i,s),m=[p];if(n)try{m=JSON.parse(n).routes.map(e=>e.path)}catch(e){console.error(`[rari] Router: Failed to parse manifest for affected routes:`,e)}let h=C(p,e,m),g,_=!1,v;if(e===`page`||e===`layout`)try{let e=w(await l.readFile(i,`utf-8`));e&&(g=e,_=!0)}catch(e){console.error(`[rari] Router: Failed to extract metadata:`,e)}if(e===`route`)try{v=T(await l.readFile(i,`utf-8`)),await E(u.relative(s,i))}catch(e){console.error(`[rari] Router: Failed to detect HTTP methods:`,e)}let y={fileType:e,filePath:u.relative(o.config.root,i),routePath:p,affectedRoutes:h,manifestUpdated:f,timestamp:Date.now(),metadata:g,metadataChanged:_,methods:v};o.ws.send({type:`custom`,event:`rari:app-router-updated`,data:y})},200);return r.set(i,d),[]}return n=await c(o.config.root),[]}},async closeBundle(){for(let e of r.values())clearTimeout(e);r.clear()}}}var O=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()}},k=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 O({maxErrors:5,resetTimeout:3e4})}async handleClientComponentUpdate(e,t){let n=u.relative(d.cwd(),e),r=Date.now();this.queueLog(`info`,`Client component changed: ${n}`);try{let i=t.moduleGraph.getModuleById(e);if(i){t.moduleGraph.invalidateModule(i);let e=Date.now()-r;this.queueLog(`success`,`Client component updated: ${n} (${e}ms)`),this.errorHandler.reset()}else 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=Array.from(this.pendingFiles);if(this.pendingFiles.clear(),this.batchTimer=null,e.length===0)return;let n=Date.now();if(e.length===1){let t=u.relative(d.cwd(),e[0]);this.queueLog(`info`,`Rebuilding server component: ${t}`)}else this.queueLog(`info`,`Rebuilding ${e.length} server components in batch`);let r=await Promise.allSettled(e.map(async e=>{let t=u.relative(d.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))}}})),i=[],a=[];r.forEach(e=>{e.status===`fulfilled`&&e.value.success?i.push(e.value):e.status===`fulfilled`&&!e.value.success?a.push(e.value):e.status===`rejected`&&a.push({filePath:``,relativePath:`unknown`,error:Error(String(e.reason))})});let o=Date.now()-n;if(i.length>0){let e=Date.now();i.forEach(({componentId:n})=>{t.hot.send(`rari:server-component-updated`,{id:n,t:e})}),i.length===1?this.queueLog(`success`,`Server component updated: ${i[0].relativePath} (${o}ms)`):this.queueLog(`success`,`${i.length} server components updated (${o}ms)`),this.errorHandler.reset(),t.ws.send({type:`custom`,event:`rari:hmr-error-cleared`,data:{t:e}})}if(a.length>0){let e=Date.now();a.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}`)}}catch(e){throw console.error(`[rari] HMR: Failed to notify Rust server:`,e),e}}detectComponentType(e){try{let t=c.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 A={remotePatterns:[],localPatterns:[],deviceSizes:o,imageSizes:a,formats:r,quality:i,minimumCacheTTL:t,maxCacheSize:n};async function j(e){let t=import.meta.url,n=m(t),r=u.dirname(n),i=[u.join(r,`../runtime`,e),u.join(r,`../src/runtime`,e)];for(let e of i)try{return await c.promises.readFile(e,`utf-8`)}catch{}throw Error(`Could not find ${e}. Tried: ${i.join(`, `)}`)}async function M(){return j(`rsc-client-runtime.js`)}async function N(e,t){return(await j(`entry-client.js`)).replace(`// CLIENT_COMPONENT_IMPORTS_PLACEHOLDER`,e).replace(`// CLIENT_COMPONENT_REGISTRATIONS_PLACEHOLDER`,t)}async function P(){return j(`react-server-dom-shim.js`)}function F(e,t=[]){let n=new Set;function r(e){if(!c.existsSync(e))return;let t=c.readdirSync(e,{withFileTypes:!0});for(let i of t){let t=u.join(e,i.name);if(i.isDirectory()){if(i.name===`node_modules`)continue;r(t)}else if(i.isFile()&&/\.(?:tsx?|jsx?)$/.test(i.name))try{let e=c.readFileSync(t,`utf8`);(e.includes(`'use client'`)||e.includes(`"use client"`))&&n.add(t)}catch{}}}r(e);for(let e of t)c.existsSync(e)&&r(e);return n}function I(e){return e}function L(t={}){let n=new Map,r=new Set,i=new Set,a=null,o=new Set,l=null,m={};function g(e){if(e.includes(`node_modules`)||e.includes(`/rari/dist/`)||e.includes(`\\rari\\dist\\`))return!1;let t=e;try{t=c.realpathSync(e)}catch{return!1}try{if(!c.existsSync(t))return!1;let e=c.readFileSync(t,`utf-8`),n=v(e,`use client`);return v(e,`use server`)?!1:!n}catch{return!1}}function _(e){try{let t=h(e,{loader:`tsx`,format:`esm`,target:`esnext`,logLevel:`silent`}).code.match(/export\s*\{([^}]+)\}/);if(!t){let t=e.match(/export\s*\{([^}]+)\}/);if(t){let e=[],n=t[1].split(`,`);for(let t of n){let n=t.trim().split(/\s+as\s+/),r=n[n.length-1].trim();r&&e.push(r)}return e}return[]}let n=[],r=t[1].split(`,`);for(let e of r){let t=e.trim().split(/\s+as\s+/),r=t[t.length-1].trim();r&&n.push(r)}return n}catch{return[]}}function v(e,t){try{let n=h(e,{loader:`tsx`,format:`esm`,target:`esnext`,logLevel:`silent`}).code.trimStart();return RegExp(`^(['"\`])${t.replace(/\s/g,`\\s+`)}\\1\\s*;?`).test(n)}catch{return!1}}function b(e,t){if(!v(e,`use server`))return e;let n=_(e);if(n.length===0)return e;let r=e;r+=`
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 A={remotePatterns:[],localPatterns:[],deviceSizes:o,imageSizes:a,formats:r,quality:i,minimumCacheTTL:t,maxCacheSize:n};async function j(e){let t=import.meta.url,n=m(t),r=u.dirname(n),i=[u.join(r,`../runtime`,e),u.join(r,`../src/runtime`,e)];for(let e of i)try{return await c.promises.readFile(e,`utf-8`)}catch{}throw Error(`Could not find ${e}. Tried: ${i.join(`, `)}`)}async function M(){return j(`rsc-client-runtime.js`)}async function N(e,t){return(await j(`entry-client.js`)).replace(`// CLIENT_COMPONENT_IMPORTS_PLACEHOLDER`,e).replace(`// CLIENT_COMPONENT_REGISTRATIONS_PLACEHOLDER`,t)}async function P(){return j(`react-server-dom-shim.js`)}function F(e,t=[]){let n=new Set;function r(e){if(!c.existsSync(e))return;let t=c.readdirSync(e,{withFileTypes:!0});for(let i of t){let t=u.join(e,i.name);if(i.isDirectory()){if(i.name===`node_modules`)continue;r(t)}else if(i.isFile()&&/\.(?:tsx?|jsx?)$/.test(i.name))try{let e=c.readFileSync(t,`utf8`);(e.includes(`'use client'`)||e.includes(`"use client"`))&&n.add(t)}catch{}}}r(e);for(let e of t)c.existsSync(e)&&r(e);return n}function I(e){return e}function L(t={}){let n=new Map,r=new Set,i=new Set,a=null,o=new Set,l=null,m={};function g(e){if(e.includes(`node_modules`)||e.includes(`/rari/dist/`)||e.includes(`\\rari\\dist\\`))return!1;let n=t.projectRoot||d.cwd(),r=u.join(n,`index.html`);if(c.existsSync(r))try{let t=c.readFileSync(r,`utf-8`);for(let r of t.matchAll(/import\s*(?:\(\s*)?["']([^"']+)["']\)?/g)){let t=r[1];if(t.startsWith(`/src/`)&&u.join(n,t.slice(1))===e)return!1}}catch{}let i=e;try{i=c.realpathSync(e)}catch{return!1}try{if(!c.existsSync(i))return!1;let e=c.readFileSync(i,`utf-8`),t=v(e,`use client`);return v(e,`use server`)?!1:!t}catch{return!1}}function _(e){try{let t=h(e,{loader:`tsx`,format:`esm`,target:`esnext`,logLevel:`silent`}).code.match(/export\s*\{([^}]+)\}/);if(!t){let t=e.match(/export\s*\{([^}]+)\}/);if(t){let e=[],n=t[1].split(`,`);for(let t of n){let n=t.trim().split(/\s+as\s+/),r=n[n.length-1].trim();r&&e.push(r)}return e}return[]}let n=[],r=t[1].split(`,`);for(let e of r){let t=e.trim().split(/\s+as\s+/),r=t[t.length-1].trim();r&&n.push(r)}return n}catch{return[]}}function v(e,t){try{let n=h(e,{loader:`tsx`,format:`esm`,target:`esnext`,logLevel:`silent`}).code.trimStart();return RegExp(`^(['"\`])${t.replace(/\s/g,`\\s+`)}\\1\\s*;?`).test(n)}catch{return!1}}function b(e,t){if(!v(e,`use server`))return e;let n=_(e);if(n.length===0)return e;let r=e;r+=`
4
4
 
5
5
  import {registerServerReference} from "react-server-dom-rari/server";
6
6
  `;for(let i of n)if(i===`default`){let n=e.match(/export\s+default\s+(?:async\s+)?function\s+(\w+)/);if(n){let e=n[1];r+=`
@@ -17,7 +17,7 @@ if (import.meta.hot) {
17
17
  }`,r}function x(e,t){let n=v(e,`use server`),r=g(t);if(n){let n=_(e);if(n.length===0)return``;let r=u.relative(d.cwd(),t).replace(/\\/g,`/`).replace(/\.(tsx?|jsx?)$/,``).replace(/[^\w/-]/g,`_`).replace(/^src\//,``),i=`import { createServerReference } from "rari/runtime/actions";
18
18
  `;for(let e of n)e===`default`?i+=`export default createServerReference("default", ${JSON.stringify(r)}, "default");\n`:i+=`export const ${e} = createServerReference("${e}", ${JSON.stringify(r)}, "${e}");\n`;return i}if(r){let n=_(e);if(n.length===0)return``;let r=u.relative(d.cwd(),t).replace(/\\/g,`/`).replace(/\.(tsx?|jsx?)$/,``).replace(/[^\w/-]/g,`_`).replace(/^src\//,``).replace(/^components\//,``),i=`import { createServerComponentWrapper } from "virtual:rsc-integration";
19
19
  `;for(let e of n)e===`default`?i+=`export default createServerComponentWrapper("${r}", ${JSON.stringify(t)});\n`:i+=`export const ${e} = createServerComponentWrapper("${r}_${e}", ${JSON.stringify(t)});\n`;return i}if(!v(e,`use client`))return e;let i=_(e);if(i.length===0)return``;let a=`import {registerClientReference} from "react-server-dom-rari/server";
20
- `;for(let e of i)e===`default`?(a+=`export default `,a+=`registerClientReference(function() {`,a+=`throw new Error(${JSON.stringify(`Attempted to call the default export of ${t} from the server but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.`)});`):(a+=`export const ${e} = `,a+=`registerClientReference(function() {`,a+=`throw new Error(${JSON.stringify(`Attempted to call ${e}() from the server but ${e} is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.`)});`),a+=`},`,a+=`${JSON.stringify(t)},`,a+=`${JSON.stringify(e)});\n`;return a}function S(e,t){return!v(e,`use client`)||_(e).length===0?e:e.replace(/^['"]use client['"];?\s*$/gm,``)}function C(e,t){let n=e;for(let[t,r]of Object.entries(m))if(e.startsWith(`${t}/`)){n=e.replace(t,r);break}else if(e===t){n=r;break}let r=u.resolve(u.dirname(t),n),i=[`.tsx`,`.jsx`,`.ts`,`.js`];for(let e of i){let t=`${r}${e}`;if(c.existsSync(t))return t}if(c.existsSync(r))for(let e of i){let t=u.join(r,`index${e}`);if(c.existsSync(t))return t}return`${r}.tsx`}function w(e){return(e.split(`/`).pop()||e).replace(/\.[^.]*$/,``)}let T=[{name:`rari`,config(t,{command:n}){t.resolve=t.resolve||{};let r=Array.isArray(t.resolve.dedupe)?t.resolve.dedupe:[],i=[`react`,`react-dom`];t.resolve.dedupe=Array.from(new Set([...r||[],...i]));let a=[];Array.isArray(t.resolve.alias)?a=t.resolve.alias:t.resolve.alias&&typeof t.resolve.alias==`object`&&(a=Object.entries(t.resolve.alias).map(([e,t])=>({find:e,replacement:t})));let o=new Set(a.map(e=>String(e.find)));try{let n=e.resolve(`react`),r=e.resolve(`react-dom/client`),i=e.resolve(`react/jsx-runtime`),s=[];o.has(`react/jsx-runtime`)||s.push({find:`react/jsx-runtime`,replacement:i});try{let t=e.resolve(`react/jsx-dev-runtime`);o.has(`react/jsx-dev-runtime`)||s.push({find:`react/jsx-dev-runtime`,replacement:t})}catch{}o.has(`react`)||s.push({find:`react`,replacement:n}),o.has(`react-dom/client`)||s.push({find:`react-dom/client`,replacement:r}),s.length>0&&(t.resolve.alias=[...a,...s])}catch{}if(t.environments=t.environments||{},t.environments.rsc={resolve:{conditions:[`react-server`,`node`,`import`]},...t.environments.rsc},t.environments.ssr={resolve:{conditions:[`node`,`import`]},...t.environments.ssr},t.environments.client={resolve:{conditions:[`browser`,`import`]},...t.environments.client},t.optimizeDeps=t.optimizeDeps||{},t.optimizeDeps.include=t.optimizeDeps.include||[],t.optimizeDeps.include.includes(`react-dom/server`)||t.optimizeDeps.include.push(`react-dom/server`),n===`build`)for(let e of[`rsc`,`ssr`,`client`]){let n=t.environments[e];n&&n.build&&(n.build.rolldownOptions=n.build.rolldownOptions||{})}t.server=t.server||{},t.server.proxy=t.server.proxy||{};let s=d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3);return t.server.proxy[`/api`]={target:`http://localhost:${s}`,changeOrigin:!0,secure:!1,rewrite:e=>e.replace(/^\/api/,`/api`),ws:!0},t.server.proxy[`/_rari`]={target:`http://localhost:${s}`,changeOrigin:!0,secure:!1,ws:!0},n===`build`&&(t.build=t.build||{},t.build.rolldownOptions=t.build.rolldownOptions||{},t.build.rolldownOptions.input||(t.build.rolldownOptions.input={main:`./index.html`})),t.environments&&t.environments.client&&(t.environments.client.build||(t.environments.client.build={}),t.environments.client.build.rolldownOptions||(t.environments.client.build.rolldownOptions={}),t.environments.client.build.rolldownOptions.input||(t.environments.client.build.rolldownOptions.input={})),t},configResolved(e){let t=new Set([`react`,`react-dom`,`react/jsx-runtime`,`react/jsx-dev-runtime`,`react-dom/client`]);if(e.resolve?.alias){let n=e.resolve.alias;Array.isArray(n)?n.forEach(e=>{typeof e.find==`string`&&typeof e.replacement==`string`&&!t.has(e.find)&&(m[e.find]=e.replacement)}):typeof n==`object`&&Object.entries(n).forEach(([e,n])=>{typeof n==`string`&&!t.has(e)&&(m[e]=n)})}},transform(e,t){if(!/\.(?:tsx?|jsx?)$/.test(t))return null;let a=this.environment;if(v(e,`use client`)){n.set(t,`client`),i.add(t);let r=/^\s*import\s+(?:(\w+)(?:\s*,\s*\{\s*(?:(\w+(?:\s*,\s*\w+)*)\s*)?\})?|\{\s*(\w+(?:\s*,\s*\w+)*)\s*\})\s+from\s+['"]([./@][^'"]+)['"].*$/,a=e.split(`
20
+ `;for(let e of i)e===`default`?(a+=`export default `,a+=`registerClientReference(function() {`,a+=`throw new Error(${JSON.stringify(`Attempted to call the default export of ${t} from the server but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.`)});`):(a+=`export const ${e} = `,a+=`registerClientReference(function() {`,a+=`throw new Error(${JSON.stringify(`Attempted to call ${e}() from the server but ${e} is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.`)});`),a+=`},`,a+=`${JSON.stringify(t)},`,a+=`${JSON.stringify(e)});\n`;return a}function S(e,t){return!v(e,`use client`)||_(e).length===0?e:e.replace(/^['"]use client['"];?\s*$/gm,``)}function C(e,t){let n=e;for(let[t,r]of Object.entries(m))if(e.startsWith(`${t}/`)){n=e.replace(t,r);break}else if(e===t){n=r;break}let r=u.resolve(u.dirname(t),n),i=[`.tsx`,`.jsx`,`.ts`,`.js`];for(let e of i){let t=`${r}${e}`;if(c.existsSync(t))return t}if(c.existsSync(r))for(let e of i){let t=u.join(r,`index${e}`);if(c.existsSync(t))return t}return`${r}.tsx`}function w(e){return(e.split(`/`).pop()||e).replace(/\.[^.]*$/,``)}let T=[{name:`rari`,config(n,{command:r}){if(r===`build`){let e=t.projectRoot||d.cwd(),r=u.join(e,`index.html`);if(c.existsSync(r))try{let e=c.readFileSync(r,`utf-8`),t=/import\s+["']([^"']+)["']/g,i=[];for(let n of e.matchAll(t)){let e=n[1];if(e.startsWith(`/src/`)&&/\.(?:tsx?|jsx?)$/.test(e)){let t=e.slice(1),n=u.basename(t,u.extname(t));i.push({path:t,name:n})}}if(i.length>0){n.build=n.build||{},n.build.rolldownOptions=n.build.rolldownOptions||{};let e=n.build.rolldownOptions.input||{main:`./index.html`},t=typeof e==`string`?{main:e}:Array.isArray(e)?{main:e[0]||`./index.html`}:{...e};i.forEach(({path:e,name:n})=>{t[n]=`./${e}`}),n.build.rolldownOptions.input=t}}catch(e){console.warn(`[rari] Error parsing index.html for build inputs:`,e)}}n.resolve=n.resolve||{};let i=Array.isArray(n.resolve.dedupe)?n.resolve.dedupe:[],a=[`react`,`react-dom`];n.resolve.dedupe=Array.from(new Set([...i||[],...a]));let o=[];Array.isArray(n.resolve.alias)?o=n.resolve.alias:n.resolve.alias&&typeof n.resolve.alias==`object`&&(o=Object.entries(n.resolve.alias).map(([e,t])=>({find:e,replacement:t})));let s=new Set(o.map(e=>String(e.find)));try{let t=e.resolve(`react`),r=e.resolve(`react-dom/client`),i=e.resolve(`react/jsx-runtime`),a=[];s.has(`react/jsx-runtime`)||a.push({find:`react/jsx-runtime`,replacement:i});try{let t=e.resolve(`react/jsx-dev-runtime`);s.has(`react/jsx-dev-runtime`)||a.push({find:`react/jsx-dev-runtime`,replacement:t})}catch{}s.has(`react`)||a.push({find:`react`,replacement:t}),s.has(`react-dom/client`)||a.push({find:`react-dom/client`,replacement:r}),a.length>0&&(n.resolve.alias=[...o,...a])}catch{}if(n.environments=n.environments||{},n.environments.rsc={resolve:{conditions:[`react-server`,`node`,`import`]},...n.environments.rsc},n.environments.ssr={resolve:{conditions:[`node`,`import`]},...n.environments.ssr},n.environments.client={resolve:{conditions:[`browser`,`import`]},...n.environments.client},n.optimizeDeps=n.optimizeDeps||{},n.optimizeDeps.include=n.optimizeDeps.include||[],n.optimizeDeps.include.includes(`react-dom/server`)||n.optimizeDeps.include.push(`react-dom/server`),r===`build`)for(let e of[`rsc`,`ssr`,`client`]){let t=n.environments[e];t&&t.build&&(t.build.rolldownOptions=t.build.rolldownOptions||{})}n.server=n.server||{},n.server.proxy=n.server.proxy||{};let l=d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3);return n.server.proxy[`/api`]={target:`http://localhost:${l}`,changeOrigin:!0,secure:!1,rewrite:e=>e.replace(/^\/api/,`/api`),ws:!0},n.server.proxy[`/_rari`]={target:`http://localhost:${l}`,changeOrigin:!0,secure:!1,ws:!0},r===`build`&&(n.build=n.build||{},n.build.rolldownOptions=n.build.rolldownOptions||{},n.build.rolldownOptions.input||(n.build.rolldownOptions.input={main:`./index.html`})),n.environments&&n.environments.client&&(n.environments.client.build||(n.environments.client.build={}),n.environments.client.build.rolldownOptions||(n.environments.client.build.rolldownOptions={}),n.environments.client.build.rolldownOptions.input||(n.environments.client.build.rolldownOptions.input={})),n},configResolved(e){let t=new Set([`react`,`react-dom`,`react/jsx-runtime`,`react/jsx-dev-runtime`,`react-dom/client`]);if(e.resolve?.alias){let n=e.resolve.alias;Array.isArray(n)?n.forEach(e=>{typeof e.find==`string`&&typeof e.replacement==`string`&&!t.has(e.find)&&(m[e.find]=e.replacement)}):typeof n==`object`&&Object.entries(n).forEach(([e,n])=>{typeof n==`string`&&!t.has(e)&&(m[e]=n)})}},transform(e,t){if(!/\.(?:tsx?|jsx?)$/.test(t))return null;let a=this.environment;if(v(e,`use client`)){n.set(t,`client`),i.add(t);let r=/^\s*import\s+(?:(\w+)(?:\s*,\s*\{\s*(?:(\w+(?:\s*,\s*\w+)*)\s*)?\})?|\{\s*(\w+(?:\s*,\s*\w+)*)\s*\})\s+from\s+['"]([./@][^'"]+)['"].*$/,a=e.split(`
21
21
  `);for(let e of a){let a=e.match(r);if(!a)continue;let o=a[4];if(!o)continue;let s=C(o,t);c.existsSync(s)&&(n.set(s,`client`),i.add(s))}return S(e,t)}if(n.get(t)===`client`||i.has(t))return S(e,t);if(g(t)){if(n.set(t,`server`),r.add(t),a&&(a.name===`rsc`||a.name===`ssr`))return b(e,t);{let n=x(e,t);return n=`// HMR acceptance for server component
22
22
  if (import.meta.hot) {
23
23
  import.meta.hot.accept();
@@ -41,7 +41,7 @@ const ${t} = registerClientReference(
41
41
  );`;u=u.replace(e,n),f=!0,p=!0}}else if(!S&&g(x)){f=!0,p=!0,m=!0,r.add(x);let e=s;d&&d!==`_`&&h.push(`const ${d} = createServerComponentWrapper('${b}', '${y}');`),u=u.replace(e,``)}}if(f){let e=u.includes(`import React`)||u.match(/import\s+\{[^}]*\}\s+from\s+['"]react['"]/)||u.match(/import\s+[^,\s]+\s*,\s*\{[^}]*\}\s+from\s+['"]react['"]/),r=u.includes(`createServerComponentWrapper`),i=``;if(p&&!e&&(i+=`import React from 'react';
42
42
  `),m&&!r&&(i+=`import { createServerComponentWrapper } from 'virtual:rsc-integration';
43
43
  `),h.length>0&&(i+=`${h.join(`
44
- `)}\n`),i&&(u=i+u),!u.includes(`Suspense`)){let e=u.match(/import React(,\s*\{([^}]*)\})?\s+from\s+['"]react['"];?/);e&&(e[1]&&!e[2].includes(`Suspense`)?u=u.replace(e[0],e[0].replace(/\{([^}]*)\}/,`{ Suspense, $1 }`)):e[1]||(u=u.replace(e[0],`import React, { Suspense } from 'react';`)))}let a=d.env.NODE_ENV!==`production`,o=u.includes(`</`)||u.includes(`/>`)||/\bJSX\b/.test(u);return!u.includes(`'use client'`)&&!u.includes(`"use client"`)&&o&&a&&(u=`'use client';\n\n${u}`,n.set(t,`client`)),u}return null},configureServer(e){let r=t.projectRoot||d.cwd(),i=u.join(r,`src`),o={...A,...t.images},s=u.join(r,`dist`),h=u.join(s,`server`);c.existsSync(h)||c.mkdirSync(h,{recursive:!0});let _=u.join(h,`image.json`);c.writeFileSync(_,JSON.stringify(o,null,2));let v=null,y=async()=>{try{let{ServerComponentBuilder:n,scanDirectory:i}=await import(`./server-build-TbcMywTH.mjs`),a=new n(r,{outDir:`dist`,serverDir:`server`,manifestPath:`server/manifest.json`,alias:m,csp:t.csp,rateLimit:t.rateLimit,spamBlocker:t.spamBlocker});if(v=a,!l&&v){let e=d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3);l=new k(v,e)}let o=u.join(r,`src`),s=[];if(c.existsSync(o)){let e=t=>{let n=c.readdirSync(t,{withFileTypes:!0});for(let r of n){let n=u.join(t,r.name);if(r.isDirectory())e(n);else if(r.isFile()&&/\.(?:tsx?|jsx?)$/.test(r.name))try{g(n)&&s.push(n)}catch(e){console.error(`[rari] Error checking ${n}:`,e)}}};e(o),i(o,a)}s.length>0&&e.ws.send({type:`custom`,event:`rari:server-components-registry`,data:{serverComponents:s}});let f=await a.getTransformedComponentsForDevelopment(),p=`http://localhost:${d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.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(`${p}/_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))}},b=async()=>{try{let e=`http://localhost:${d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3)}`,t=F(i,Object.values(m));for(let n of t){let t=u.relative(d.cwd(),n),r=u.basename(n).replace(/\.[^.]+$/,``);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)}},x=async()=>{if(a)return;let{getBinaryPath:t,getInstallationInstructions:n}=await import(`./platform.mjs`),r;try{r=t()}catch(e){console.error(`rari binary not found`),console.error(` ${e.message}`),console.error(n());return}let i=d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3),o=d.env.NODE_ENV===`production`?`production`:`development`,s=e.config.server.port||5173,c=[`--mode`,o,`--port`,i.toString(),`--host`,`127.0.0.1`];a=p(r,c,{stdio:[`ignore`,`pipe`,`pipe`],cwd:d.cwd(),env:{...d.env,RUST_LOG:d.env.RUST_LOG||`error`,RARI_VITE_PORT:s.toString()}}),a.stdout?.on(`data`,e=>{let t=e.toString().trim();t&&console.error(`${t}`)}),a.stderr?.on(`data`,e=>{let t=e.toString().trim();t&&!t.includes(`warning`)&&console.error(`${t}`)}),a.on(`error`,e=>{console.error(`Failed to start rari server:`,e.message),e.message.includes(`ENOENT`)&&console.error(` Binary not found. Please ensure rari is properly installed.`)}),a.on(`exit`,(e,t)=>{a=null,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}`)}),setTimeout(async()=>{try{let e=`http://localhost:${d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3)}`,t=!1;for(let n=0;n<10;n++)try{if((await fetch(`${e}/_rari/health`)).ok){t=!0;break}}catch{await new Promise(e=>setTimeout(e,500))}t?(await b(),await y()):console.error(`Server failed to become ready for component registration`)}catch(e){console.error(`Failed during component registration:`,e)}},1e3)},S=async e=>{try{if(!g(e))return;let{ServerComponentBuilder:n}=await import(`./server-build-TbcMywTH.mjs`),i=new n(r,{outDir:`dist`,serverDir:`server`,manifestPath:`server/manifest.json`,alias:m,csp:t.csp,rateLimit:t.rateLimit,spamBlocker:t.spamBlocker});i.addServerComponent(e);let a=await i.getTransformedComponentsForDevelopment();if(a.length===0)return;let o=`http://localhost:${d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3)}`;for(let e of a)try{let t=await fetch(`${o}/_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(t){console.error(`[rari] Targeted HMR failed for`,`${e}:`,t instanceof Error?t.message:String(t)),setTimeout(y,1e3)}};x(),e.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(`.`)){let n=d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3),r=`http://localhost:${n}${e.url}`;try{let i={};for(let[t,n]of Object.entries(e.headers))n&&typeof n==`string`&&(i[t]=n);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(f.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()}),e.watcher.on(`change`,async t=>{/\.(?:tsx?|jsx?)$/.test(t)&&n.delete(t),/\.(?:tsx?|jsx?)$/.test(t)&&t.includes(i)&&(g(t)?(e.ws.send({type:`custom`,event:`rari:register-server-component`,data:{filePath:t}}),await S(t)):setTimeout(y,1e3))}),e.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 S(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)}))}})}),e.httpServer?.on(`close`,()=>{l&&=(l.dispose(),null),a&&=(a.kill(`SIGTERM`),null)})},resolveId(e){if(e===`virtual:rsc-integration`||e===`virtual:rari-entry-client`||e===`virtual:react-server-dom-rari-client`)return e;if(e===`virtual:app-router-provider`)return`${e}.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===`../router/LoadingComponentRegistry`||e===`../router/LoadingComponentRegistry.ts`)return`virtual:loading-component-registry.ts`;if(e===`react-server-dom-rari/server`)return e;if(d.env.NODE_ENV===`production`)try{let t=u.resolve(e);if(c.existsSync(t)&&g(t))return{id:e,external:!0}}catch{}return null},async load(e){if(e===`virtual:rari-entry-client`){let e=F(u.join(d.cwd(),`src`),Object.values(m)),t=new Set([...i,...e]),n=[{path:`rari/image`,exports:[`Image`]}],r=Array.from(t).filter(e=>{try{let t=c.readFileSync(e,`utf-8`).split(`
44
+ `)}\n`),i&&(u=i+u),!u.includes(`Suspense`)){let e=u.match(/import React(,\s*\{([^}]*)\})?\s+from\s+['"]react['"];?/);e&&(e[1]&&!e[2].includes(`Suspense`)?u=u.replace(e[0],e[0].replace(/\{([^}]*)\}/,`{ Suspense, $1 }`)):e[1]||(u=u.replace(e[0],`import React, { Suspense } from 'react';`)))}let a=d.env.NODE_ENV!==`production`,o=u.includes(`</`)||u.includes(`/>`)||/\bJSX\b/.test(u);return!u.includes(`'use client'`)&&!u.includes(`"use client"`)&&o&&a&&(u=`'use client';\n\n${u}`,n.set(t,`client`)),u}return null},configureServer(e){let r=t.projectRoot||d.cwd(),i=u.join(r,`src`),o={...A,...t.images},s=u.join(r,`dist`),h=u.join(s,`server`);c.existsSync(h)||c.mkdirSync(h,{recursive:!0});let _=u.join(h,`image.json`);c.writeFileSync(_,JSON.stringify(o,null,2));let v=null,y=async()=>{try{let{ServerComponentBuilder:n,scanDirectory:i}=await import(`./server-build-Dn38sarn.mjs`),a=new n(r,{outDir:`dist`,serverDir:`server`,manifestPath:`server/manifest.json`,alias:m,csp:t.csp,rateLimit:t.rateLimit,spamBlocker:t.spamBlocker});if(v=a,!l&&v){let e=d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3);l=new k(v,e)}let o=u.join(r,`src`),s=[];if(c.existsSync(o)){let e=t=>{let n=c.readdirSync(t,{withFileTypes:!0});for(let r of n){let n=u.join(t,r.name);if(r.isDirectory())e(n);else if(r.isFile()&&/\.(?:tsx?|jsx?)$/.test(r.name))try{g(n)&&s.push(n)}catch(e){console.error(`[rari] Error checking ${n}:`,e)}}};e(o),i(o,a)}s.length>0&&e.ws.send({type:`custom`,event:`rari:server-components-registry`,data:{serverComponents:s}});let f=await a.getTransformedComponentsForDevelopment(),p=`http://localhost:${d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.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(`${p}/_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))}},b=async()=>{try{let e=`http://localhost:${d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3)}`,t=F(i,Object.values(m));for(let n of t){let t=u.relative(d.cwd(),n),r=u.basename(n).replace(/\.[^.]+$/,``);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)}},x=async()=>{if(a)return;let{getBinaryPath:t,getInstallationInstructions:n}=await import(`./platform.mjs`),r;try{r=t()}catch(e){console.error(`rari binary not found`),console.error(` ${e.message}`),console.error(n());return}let i=d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3),o=d.env.NODE_ENV===`production`?`production`:`development`,s=e.config.server.port||5173,c=[`--mode`,o,`--port`,i.toString(),`--host`,`127.0.0.1`];a=p(r,c,{stdio:[`ignore`,`pipe`,`pipe`],cwd:d.cwd(),env:{...d.env,RUST_LOG:d.env.RUST_LOG||`error`,RARI_VITE_PORT:s.toString()}}),a.stdout?.on(`data`,e=>{let t=e.toString().trim();t&&console.error(`${t}`)}),a.stderr?.on(`data`,e=>{let t=e.toString().trim();t&&!t.includes(`warning`)&&console.error(`${t}`)}),a.on(`error`,e=>{console.error(`Failed to start rari server:`,e.message),e.message.includes(`ENOENT`)&&console.error(` Binary not found. Please ensure rari is properly installed.`)}),a.on(`exit`,(e,t)=>{a=null,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}`)}),setTimeout(async()=>{try{let e=`http://localhost:${d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3)}`,t=!1;for(let n=0;n<10;n++)try{if((await fetch(`${e}/_rari/health`)).ok){t=!0;break}}catch{await new Promise(e=>setTimeout(e,500))}t?(await b(),await y()):console.error(`Server failed to become ready for component registration`)}catch(e){console.error(`Failed during component registration:`,e)}},1e3)},S=async e=>{try{if(!g(e))return;let{ServerComponentBuilder:n}=await import(`./server-build-Dn38sarn.mjs`),i=new n(r,{outDir:`dist`,serverDir:`server`,manifestPath:`server/manifest.json`,alias:m,csp:t.csp,rateLimit:t.rateLimit,spamBlocker:t.spamBlocker});i.addServerComponent(e);let a=await i.getTransformedComponentsForDevelopment();if(a.length===0)return;let o=`http://localhost:${d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3)}`;for(let e of a)try{let t=await fetch(`${o}/_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(t){console.error(`[rari] Targeted HMR failed for`,`${e}:`,t instanceof Error?t.message:String(t)),setTimeout(y,1e3)}};x(),e.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(`.`)){let n=d.env.SERVER_PORT?Number(d.env.SERVER_PORT):Number(d.env.PORT||d.env.RSC_PORT||3e3),r=`http://localhost:${n}${e.url}`;try{let i={};for(let[t,n]of Object.entries(e.headers))n&&typeof n==`string`&&(i[t]=n);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(f.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()}),e.watcher.on(`change`,async t=>{/\.(?:tsx?|jsx?)$/.test(t)&&n.delete(t),/\.(?:tsx?|jsx?)$/.test(t)&&t.includes(i)&&(g(t)?(e.ws.send({type:`custom`,event:`rari:register-server-component`,data:{filePath:t}}),await S(t)):setTimeout(y,1e3))}),e.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 S(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)}))}})}),e.httpServer?.on(`close`,()=>{l&&=(l.dispose(),null),a&&=(a.kill(`SIGTERM`),null)})},resolveId(e){if(e===`virtual:rsc-integration`||e===`virtual:rari-entry-client`||e===`virtual:react-server-dom-rari-client`)return e;if(e===`virtual:app-router-provider`)return`${e}.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===`../router/LoadingComponentRegistry`||e===`../router/LoadingComponentRegistry.ts`)return`virtual:loading-component-registry.ts`;if(e===`react-server-dom-rari/server`)return e;if(d.env.NODE_ENV===`production`)try{let t=u.resolve(e);if(c.existsSync(t)&&g(t))return{id:e,external:!0}}catch{}return null},async load(e){if(e===`virtual:rari-entry-client`){let e=F(u.join(d.cwd(),`src`),Object.values(m)),t=new Set([...i,...e]),n=[{path:`rari/image`,exports:[`Image`]}],r=Array.from(t).filter(e=>{try{let t=c.readFileSync(e,`utf-8`).split(`
45
45
  `);for(let e of t){let t=e.trim();if(!(!t||t.startsWith(`//`)||t.startsWith(`/*`))){if(t===`'use client'`||t===`"use client"`||t===`'use client';`||t===`"use client";`)return!0;break}}return!1}catch{return!1}}),a=r.map((e,t)=>{let n=u.relative(d.cwd(),e),r=`ClientComponent${t}`;try{let t=c.readFileSync(e,`utf-8`),i=/export\s+default\s+/.test(t),a=t.match(/export\s+(?:function|const|class)\s+(\w+)/);if(!i&&a)return`import { ${a[1]} as ${r} } from '/${n}';`}catch{}return`import ${r} from '/${n}';`}).join(`
46
46
  `),o=r.map((e,t)=>{let n=u.relative(d.cwd(),e),r=`ClientComponent${t}`,i=u.basename(e,u.extname(e));return`
47
47
  globalThis['~clientComponents']["${n}"] = {
@@ -69,4 +69,4 @@ globalThis['~clientComponentPaths'] = globalThis['~clientComponentPaths'] || {};
69
69
  globalThis['~clientComponentPaths']["${e.path}"] = "${n}";`})).join(`
70
70
  `);return await N([a,s].filter(Boolean).join(`
71
71
  `),[o,l].filter(Boolean).join(`
72
- `))}if(e===`react-server-dom-rari/server`)return await P();if(e===`virtual:app-router-provider.tsx`){let e=[u.join(d.cwd(),`packages/rari/src/runtime/AppRouterProvider.tsx`),u.join(d.cwd(),`src/runtime/AppRouterProvider.tsx`),u.join(d.cwd(),`node_modules/rari/src/runtime/AppRouterProvider.tsx`)];for(let t of e)if(c.existsSync(t))return c.readFileSync(t,`utf-8`);return`export function AppRouterProvider({ children }) { return children; }`}if(e===`virtual:default-loading-indicator.tsx`){let e=[u.join(d.cwd(),`packages/rari/src/runtime/DefaultLoadingIndicator.tsx`),u.join(d.cwd(),`src/runtime/DefaultLoadingIndicator.tsx`),u.join(d.cwd(),`node_modules/rari/src/runtime/DefaultLoadingIndicator.tsx`)];for(let t of e)if(c.existsSync(t))return c.readFileSync(t,`utf-8`);return`export function DefaultLoadingIndicator() { return null; }`}if(e===`virtual:loading-error-boundary.tsx`){let e=[u.join(d.cwd(),`packages/rari/src/runtime/LoadingErrorBoundary.tsx`),u.join(d.cwd(),`src/runtime/LoadingErrorBoundary.tsx`),u.join(d.cwd(),`node_modules/rari/src/runtime/LoadingErrorBoundary.tsx`)];for(let t of e)if(c.existsSync(t))return c.readFileSync(t,`utf-8`);return`export class LoadingErrorBoundary extends React.Component { render() { return this.props.children; } }`}if(e===`virtual:loading-component-registry.ts`){let e=[u.join(d.cwd(),`packages/rari/src/router/LoadingComponentRegistry.ts`),u.join(d.cwd(),`src/router/LoadingComponentRegistry.ts`),u.join(d.cwd(),`node_modules/rari/src/router/LoadingComponentRegistry.ts`)];for(let t of e)if(c.existsSync(t))return c.readFileSync(t,`utf-8`);return`export class LoadingComponentRegistry { loadComponent() { return Promise.resolve(null); } }`}if(e===`virtual:rsc-integration`)return await M();if(e===`virtual:react-server-dom-rari-client`)return await j(`react-server-dom-rari-client.js`)},async handleHotUpdate({file:e,server:t}){if(!/\.(?:tsx?|jsx?)$/.test(e))return;if(e.includes(`/dist/`)||e.includes(`\\dist\\`))return[];let n=l?.detectComponentType(e)||`unknown`,r=e.includes(`/app/`)||e.includes(`\\app\\`),i=e.endsWith(`page.tsx`)||e.endsWith(`page.jsx`),a=e.endsWith(`layout.tsx`)||e.endsWith(`layout.jsx`),o=e.endsWith(`loading.tsx`)||e.endsWith(`loading.jsx`),s=e.endsWith(`error.tsx`)||e.endsWith(`error.jsx`),c=e.endsWith(`not-found.tsx`)||e.endsWith(`not-found.jsx`);if(r&&(i||a||o||s||c)){let n=`page`;a?n=`layout`:o?n=`loading`:s?n=`error`:c&&(n=`not-found`),t.hot.send(`rari:app-router-updated`,{type:`rari-hmr`,filePath:e,fileType:n});return}if(n!==`client`&&n===`server`)return l&&await l.handleServerComponentUpdate(e,t),[]},writeBundle(){let e={...A,...t.images},n=t.projectRoot||d.cwd(),r=u.join(n,`dist`),i=u.join(r,`server`);c.existsSync(i)||c.mkdirSync(i,{recursive:!0});let a=u.join(i,`image.json`);c.writeFileSync(a,JSON.stringify(e,null,2))}},s({...t.serverBuild,csp:t.csp,rateLimit:t.rateLimit,spamBlocker:t.spamBlocker})];return t.proxy!==!1&&T.push(y(t.proxy||{})),t.router!==!1&&T.push(D(t.router||{})),T}function R(e){return{plugins:[L(),...e.plugins||[]],...e}}export{y as a,D as i,I as n,v as o,L as r,g as s,R as t};
72
+ `))}if(e===`react-server-dom-rari/server`)return await P();if(e===`virtual:app-router-provider.tsx`){let e=[u.join(d.cwd(),`packages/rari/src/runtime/AppRouterProvider.tsx`),u.join(d.cwd(),`src/runtime/AppRouterProvider.tsx`),u.join(d.cwd(),`node_modules/rari/src/runtime/AppRouterProvider.tsx`)];for(let t of e)if(c.existsSync(t))return c.readFileSync(t,`utf-8`);return`export function AppRouterProvider({ children }) { return children; }`}if(e===`virtual:default-loading-indicator.tsx`){let e=[u.join(d.cwd(),`packages/rari/src/runtime/DefaultLoadingIndicator.tsx`),u.join(d.cwd(),`src/runtime/DefaultLoadingIndicator.tsx`),u.join(d.cwd(),`node_modules/rari/src/runtime/DefaultLoadingIndicator.tsx`)];for(let t of e)if(c.existsSync(t))return c.readFileSync(t,`utf-8`);return`export function DefaultLoadingIndicator() { return null; }`}if(e===`virtual:loading-error-boundary.tsx`){let e=[u.join(d.cwd(),`packages/rari/src/runtime/LoadingErrorBoundary.tsx`),u.join(d.cwd(),`src/runtime/LoadingErrorBoundary.tsx`),u.join(d.cwd(),`node_modules/rari/src/runtime/LoadingErrorBoundary.tsx`)];for(let t of e)if(c.existsSync(t))return c.readFileSync(t,`utf-8`);return`export class LoadingErrorBoundary extends React.Component { render() { return this.props.children; } }`}if(e===`virtual:loading-component-registry.ts`){let e=[u.join(d.cwd(),`packages/rari/src/router/LoadingComponentRegistry.ts`),u.join(d.cwd(),`src/router/LoadingComponentRegistry.ts`),u.join(d.cwd(),`node_modules/rari/src/router/LoadingComponentRegistry.ts`)];for(let t of e)if(c.existsSync(t))return c.readFileSync(t,`utf-8`);return`export class LoadingComponentRegistry { loadComponent() { return Promise.resolve(null); } }`}if(e===`virtual:rsc-integration`)return await M();if(e===`virtual:react-server-dom-rari-client`)return await j(`react-server-dom-rari-client.js`)},async handleHotUpdate({file:e,server:t}){if(!/\.(?:tsx?|jsx?)$/.test(e))return;if(e.includes(`/dist/`)||e.includes(`\\dist\\`))return[];let n=l?.detectComponentType(e)||`unknown`,r=e.includes(`/app/`)||e.includes(`\\app\\`),i=e.endsWith(`page.tsx`)||e.endsWith(`page.jsx`),a=e.endsWith(`layout.tsx`)||e.endsWith(`layout.jsx`),o=e.endsWith(`loading.tsx`)||e.endsWith(`loading.jsx`),s=e.endsWith(`error.tsx`)||e.endsWith(`error.jsx`),c=e.endsWith(`not-found.tsx`)||e.endsWith(`not-found.jsx`);if(r&&(i||a||o||s||c)){let n=`page`;a?n=`layout`:o?n=`loading`:s?n=`error`:c&&(n=`not-found`),t.hot.send(`rari:app-router-updated`,{type:`rari-hmr`,filePath:e,fileType:n});return}if(n!==`client`&&n===`server`)return l&&await l.handleServerComponentUpdate(e,t),[]},transformIndexHtml:{order:`pre`,handler(e){let t=/import\s+["']([^"']+)["']/g,n=[];for(let r of e.matchAll(t)){let e=r[1];e.startsWith(`/src/`)&&n.push(e)}return n.length>0?{html:e,tags:n.map(e=>({tag:`script`,attrs:{type:`module`,src:e},injectTo:`head-prepend`}))}:e}},writeBundle(){let e={...A,...t.images},n=t.projectRoot||d.cwd(),r=u.join(n,`dist`),i=u.join(r,`server`);c.existsSync(i)||c.mkdirSync(i,{recursive:!0});let a=u.join(i,`image.json`);c.writeFileSync(a,JSON.stringify(e,null,2))}},s({...t.serverBuild,csp:t.csp,rateLimit:t.rateLimit,spamBlocker:t.spamBlocker})];return t.proxy!==!1&&T.push(y(t.proxy||{})),t.router!==!1&&T.push(D(t.router||{})),T}function R(e){return{plugins:[L(),...e.plugins||[]],...e}}export{y as a,D as i,I as n,v as o,L as r,g as s,R as t};
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { f as AppRouteManifest } from "./runtime-client-Cba9SeKX.mjs";
2
+ import { f as AppRouteManifest } from "./runtime-client-B_mktvP9.mjs";
3
3
  import * as fs$1 from "node:fs";
4
4
  import { URL as URL$1 } from "node:url";
5
5
  import esbuild from "esbuild";
@@ -30,6 +30,53 @@ interface Robots {
30
30
  sitemap?: string | string[];
31
31
  host?: string;
32
32
  }
33
+ interface SitemapImage {
34
+ loc: string;
35
+ title?: string;
36
+ caption?: string;
37
+ geoLocation?: string;
38
+ license?: string;
39
+ }
40
+ interface SitemapVideo {
41
+ title: string;
42
+ thumbnail_loc: string;
43
+ description: string;
44
+ content_loc?: string;
45
+ player_loc?: string;
46
+ duration?: number;
47
+ expiration_date?: string;
48
+ rating?: number;
49
+ view_count?: number;
50
+ publication_date?: string;
51
+ family_friendly?: boolean;
52
+ restriction?: {
53
+ relationship: 'allow' | 'deny';
54
+ content: string;
55
+ };
56
+ platform?: {
57
+ relationship: 'allow' | 'deny';
58
+ content: string;
59
+ };
60
+ requires_subscription?: boolean;
61
+ uploader?: {
62
+ name: string;
63
+ info?: string;
64
+ };
65
+ live?: boolean;
66
+ tag?: string[];
67
+ }
68
+ interface SitemapEntry {
69
+ url: string;
70
+ lastModified?: string | Date;
71
+ changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
72
+ priority?: number;
73
+ alternates?: {
74
+ languages?: Record<string, string>;
75
+ };
76
+ images?: (string | SitemapImage)[];
77
+ videos?: SitemapVideo[];
78
+ }
79
+ type Sitemap = SitemapEntry[];
33
80
  //#endregion
34
81
  //#region src/api-routes.d.ts
35
82
  interface RouteContext<TParams extends Record<string, string> = Record<string, string>> {
@@ -7616,6 +7663,7 @@ interface ServerBuildOptions {
7616
7663
  fontSrc?: string[];
7617
7664
  connectSrc?: string[];
7618
7665
  defaultSrc?: string[];
7666
+ workerSrc?: string[];
7619
7667
  };
7620
7668
  rateLimit?: {
7621
7669
  enabled?: boolean;
@@ -7665,6 +7713,7 @@ interface RariOptions {
7665
7713
  fontSrc?: string[];
7666
7714
  connectSrc?: string[];
7667
7715
  defaultSrc?: string[];
7716
+ workerSrc?: string[];
7668
7717
  };
7669
7718
  rateLimit?: {
7670
7719
  enabled?: boolean;
@@ -7686,4 +7735,4 @@ declare function defineRariConfig(config: UserConfig & {
7686
7735
  type Request$1 = globalThis.Request;
7687
7736
  type Response$1 = globalThis.Response;
7688
7737
  //#endregion
7689
- export { ApiRouteHandlers as C, RobotsRule as D, Robots as E, ApiResponse as S, RouteHandler as T, ProxyResult as _, rari as a, RequestCookies as b, ProxyPluginOptions as c, RariRequest as d, CookieOptions as f, ProxyModule as g, ProxyMatcher as h, defineRariOptions as i, rariProxy as l, ProxyFunction as m, Response$1 as n, rariRouter as o, ProxyConfig as p, defineRariConfig as r, generateAppRouteManifest as s, Request$1 as t, RariResponse as u, RariFetchEvent as v, RouteContext as w, ResponseCookies as x, RariURL as y };
7738
+ export { SitemapImage as A, ApiRouteHandlers as C, RobotsRule as D, Robots as E, Sitemap as O, ApiResponse as S, RouteHandler as T, ProxyResult as _, rari as a, RequestCookies as b, ProxyPluginOptions as c, RariRequest as d, CookieOptions as f, ProxyModule as g, ProxyMatcher as h, defineRariOptions as i, SitemapVideo as j, SitemapEntry as k, rariProxy as l, ProxyFunction as m, Response$1 as n, rariRouter as o, ProxyConfig as p, defineRariConfig as r, generateAppRouteManifest as s, Request$1 as t, RariResponse as u, RariFetchEvent as v, RouteContext as w, ResponseCookies as x, RariURL as y };
package/dist/vite.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, S as PageProps, T as MetadataResult, _ as GenerateStaticParams, b as LoadingEntry, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, p as AppRouteMatch, s as RuntimeClient, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry, y as LayoutProps } from "./runtime-client-Cba9SeKX.mjs";
2
- import { C as ApiRouteHandlers, D as RobotsRule, E as Robots, S as ApiResponse, T as RouteHandler, _ as ProxyResult, a as rari, b as RequestCookies, c as ProxyPluginOptions, d as RariRequest, f as CookieOptions, g as ProxyModule, h as ProxyMatcher, i as defineRariOptions, l as rariProxy, m as ProxyFunction, n as Response, o as rariRouter, p as ProxyConfig, r as defineRariConfig, s as generateAppRouteManifest, t as Request, u as RariResponse, v as RariFetchEvent, w as RouteContext, x as ResponseCookies, y as RariURL } from "./vite-BiJzCvlJ.mjs";
3
- export { ApiResponse, ApiRouteHandlers, AppRouteEntry, AppRouteManifest, AppRouteMatch, CookieOptions, ErrorEntry, ErrorProps, GenerateMetadata, GenerateStaticParams, HttpRuntimeClient, LayoutEntry, LayoutProps, LoadingEntry, MetadataResult, NotFoundEntry, PageProps, ProxyConfig, ProxyFunction, ProxyMatcher, ProxyModule, ProxyPluginOptions, ProxyResult, RariFetchEvent, RariRequest, RariResponse, RariURL, Request, RequestCookies, Response, ResponseCookies, Robots, RobotsRule, RouteContext, RouteHandler, RouteSegment, RouteSegmentType, RuntimeClient, ServerPropsResult, StaticParamsResult, clearPropsCache, clearPropsCacheForComponent, createHttpRuntimeClient, defineRariConfig, defineRariOptions, extractMetadata, extractServerProps, extractServerPropsWithCache, extractStaticParams, generateAppRouteManifest, hasServerSideDataFetching, rari, rariProxy, rariRouter };
1
+ import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, S as PageProps, T as MetadataResult, _ as GenerateStaticParams, b as LoadingEntry, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, p as AppRouteMatch, s as RuntimeClient, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry, y as LayoutProps } from "./runtime-client-B_mktvP9.mjs";
2
+ import { A as SitemapImage, C as ApiRouteHandlers, D as RobotsRule, E as Robots, O as Sitemap, S as ApiResponse, T as RouteHandler, _ as ProxyResult, a as rari, b as RequestCookies, c as ProxyPluginOptions, d as RariRequest, f as CookieOptions, g as ProxyModule, h as ProxyMatcher, i as defineRariOptions, j as SitemapVideo, k as SitemapEntry, l as rariProxy, m as ProxyFunction, n as Response, o as rariRouter, p as ProxyConfig, r as defineRariConfig, s as generateAppRouteManifest, t as Request, u as RariResponse, v as RariFetchEvent, w as RouteContext, x as ResponseCookies, y as RariURL } from "./vite-CSUUcRB_.mjs";
3
+ export { ApiResponse, ApiRouteHandlers, AppRouteEntry, AppRouteManifest, AppRouteMatch, CookieOptions, ErrorEntry, ErrorProps, GenerateMetadata, GenerateStaticParams, HttpRuntimeClient, LayoutEntry, LayoutProps, LoadingEntry, MetadataResult, NotFoundEntry, PageProps, ProxyConfig, ProxyFunction, ProxyMatcher, ProxyModule, ProxyPluginOptions, ProxyResult, RariFetchEvent, RariRequest, RariResponse, RariURL, Request, RequestCookies, Response, ResponseCookies, Robots, RobotsRule, RouteContext, RouteHandler, RouteSegment, RouteSegmentType, RuntimeClient, ServerPropsResult, Sitemap, SitemapEntry, SitemapImage, SitemapVideo, StaticParamsResult, clearPropsCache, clearPropsCacheForComponent, createHttpRuntimeClient, defineRariConfig, defineRariOptions, extractMetadata, extractServerProps, extractServerPropsWithCache, extractStaticParams, generateAppRouteManifest, hasServerSideDataFetching, rari, rariProxy, rariRouter };
package/dist/vite.mjs CHANGED
@@ -1 +1 @@
1
- import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./vite-Em5wQyBY.mjs";import{t as s}from"./RariRequest-CW-JhbGM.mjs";import{c,d as l,f as u,g as d,h as f,i as p,m,p as h,u as g}from"./runtime-client-B15ZQXrE.mjs";import{t as _}from"./routes-Bq7zysPc.mjs";import"./constants-CD3aqqK8.mjs";import"./server-build-CCcyQm4X.mjs";export{a as ApiResponse,p as HttpRuntimeClient,s as RariRequest,r as RariResponse,g as clearPropsCache,l as clearPropsCacheForComponent,c as createHttpRuntimeClient,o as defineRariConfig,n as defineRariOptions,u as extractMetadata,h as extractServerProps,m as extractServerPropsWithCache,f as extractStaticParams,_ as generateAppRouteManifest,d as hasServerSideDataFetching,i as rari,e as rariProxy,t as rariRouter};
1
+ import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./vite-4UHctC2X.mjs";import{t as s}from"./RariRequest-CW-JhbGM.mjs";import{c,d as l,f as u,g as d,h as f,i as p,m,p as h,u as g}from"./runtime-client-B15ZQXrE.mjs";import{t as _}from"./routes-Bq7zysPc.mjs";import"./constants-CD3aqqK8.mjs";import"./server-build-DzXrtj9Z.mjs";export{a as ApiResponse,p as HttpRuntimeClient,s as RariRequest,r as RariResponse,g as clearPropsCache,l as clearPropsCacheForComponent,c as createHttpRuntimeClient,o as defineRariConfig,n as defineRariOptions,u as extractMetadata,h as extractServerProps,m as extractServerPropsWithCache,f as extractStaticParams,_ as generateAppRouteManifest,d as hasServerSideDataFetching,i as rari,e as rariProxy,t as rariRouter};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rari",
3
3
  "type": "module",
4
- "version": "0.7.13",
4
+ "version": "0.8.0",
5
5
  "description": "Runtime Accelerated Rendering Infrastructure (rari)",
6
6
  "author": "Ryan Skinner",
7
7
  "license": "MIT",
@@ -84,11 +84,11 @@
84
84
  "esbuild": "^0.27.2"
85
85
  },
86
86
  "optionalDependencies": {
87
- "rari-darwin-arm64": "0.7.9",
88
- "rari-darwin-x64": "0.7.9",
89
- "rari-linux-arm64": "0.7.9",
90
- "rari-linux-x64": "0.7.9",
91
- "rari-win32-x64": "0.7.9"
87
+ "rari-darwin-arm64": "0.8.0",
88
+ "rari-darwin-x64": "0.8.0",
89
+ "rari-linux-arm64": "0.8.0",
90
+ "rari-linux-x64": "0.8.0",
91
+ "rari-win32-x64": "0.8.0"
92
92
  },
93
93
  "devDependencies": {
94
94
  "@types/node": "^25.0.10",
package/src/cli.ts CHANGED
@@ -4,8 +4,8 @@ import { spawn } from 'node:child_process'
4
4
  import { existsSync, readFileSync } from 'node:fs'
5
5
  import { resolve } from 'node:path'
6
6
  import process from 'node:process'
7
+ import colors from '@rari/colors'
7
8
  import { getBinaryPath, getInstallationInstructions } from './platform'
8
- import colors from './utils/colors'
9
9
 
10
10
  function loadEnvFile() {
11
11
  const envPath = resolve(process.cwd(), '.env')
@@ -1,7 +1,7 @@
1
1
  import { existsSync, readFileSync, writeFileSync } from 'node:fs'
2
2
  import { join } from 'node:path'
3
3
  import process from 'node:process'
4
- import colors from '../utils/colors'
4
+ import colors from '@rari/colors'
5
5
 
6
6
  function logInfo(message: string) {
7
7
  console.warn(`${colors.blue('info')} ${message}`)
@@ -1,7 +1,7 @@
1
1
  import { existsSync, readFileSync, writeFileSync } from 'node:fs'
2
2
  import { join } from 'node:path'
3
3
  import process from 'node:process'
4
- import colors from '../utils/colors'
4
+ import colors from '@rari/colors'
5
5
 
6
6
  function logInfo(message: string) {
7
7
  console.warn(`${colors.blue('info')} ${message}`)
package/src/index.ts CHANGED
@@ -1,2 +1,2 @@
1
- export type { Robots, RobotsRule } from './types/metadata-route'
1
+ export type { Robots, RobotsRule, Sitemap, SitemapEntry, SitemapImage, SitemapVideo } from './types/metadata-route'
2
2
  export * from './vite'
@@ -352,10 +352,7 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
352
352
  )
353
353
  }
354
354
 
355
- const rariServerUrl = window.location.origin.includes(':5173')
356
- ? 'http://localhost:3000'
357
- : window.location.origin
358
- const fetchUrl = rariServerUrl + targetPath
355
+ const fetchUrl = window.location.origin + targetPath
359
356
 
360
357
  const response = await fetch(fetchUrl, {
361
358
  headers: { Accept: 'text/x-component' },
@@ -0,0 +1,284 @@
1
+ import type { Sitemap, SitemapImage, SitemapVideo } from '../types/metadata-route'
2
+ import { promises as fs } from 'node:fs'
3
+ import path from 'node:path'
4
+
5
+ export interface SitemapGeneratorOptions {
6
+ appDir: string
7
+ outDir: string
8
+ extensions?: string[]
9
+ }
10
+
11
+ export interface SitemapFile {
12
+ type: 'static' | 'dynamic'
13
+ path: string
14
+ id?: string
15
+ }
16
+
17
+ function escapeXml(str: string): string {
18
+ return str
19
+ .replace(/&/g, '&amp;')
20
+ .replace(/</g, '&lt;')
21
+ .replace(/>/g, '&gt;')
22
+ .replace(/"/g, '&quot;')
23
+ .replace(/'/g, '&apos;')
24
+ }
25
+
26
+ function formatDate(date: string | Date): string {
27
+ const d = typeof date === 'string' ? new Date(date) : date
28
+ return d.toISOString()
29
+ }
30
+
31
+ function generateImageXml(images: (string | SitemapImage)[]): string {
32
+ const lines: string[] = []
33
+
34
+ for (const image of images) {
35
+ if (typeof image === 'string') {
36
+ lines.push(' <image:image>')
37
+ lines.push(` <image:loc>${escapeXml(image)}</image:loc>`)
38
+ lines.push(' </image:image>')
39
+ }
40
+ else {
41
+ lines.push(' <image:image>')
42
+ lines.push(` <image:loc>${escapeXml(image.loc)}</image:loc>`)
43
+ if (image.title)
44
+ lines.push(` <image:title>${escapeXml(image.title)}</image:title>`)
45
+ if (image.caption)
46
+ lines.push(` <image:caption>${escapeXml(image.caption)}</image:caption>`)
47
+ if (image.geoLocation)
48
+ lines.push(` <image:geo_location>${escapeXml(image.geoLocation)}</image:geo_location>`)
49
+ if (image.license)
50
+ lines.push(` <image:license>${escapeXml(image.license)}</image:license>`)
51
+ lines.push(' </image:image>')
52
+ }
53
+ }
54
+
55
+ return lines.join('\n')
56
+ }
57
+
58
+ function generateVideoXml(videos: SitemapVideo[]): string {
59
+ const lines: string[] = []
60
+
61
+ for (const video of videos) {
62
+ lines.push(' <video:video>')
63
+ lines.push(` <video:title>${escapeXml(video.title)}</video:title>`)
64
+ lines.push(` <video:thumbnail_loc>${escapeXml(video.thumbnail_loc)}</video:thumbnail_loc>`)
65
+ lines.push(` <video:description>${escapeXml(video.description)}</video:description>`)
66
+
67
+ if (video.content_loc)
68
+ lines.push(` <video:content_loc>${escapeXml(video.content_loc)}</video:content_loc>`)
69
+ if (video.player_loc)
70
+ lines.push(` <video:player_loc>${escapeXml(video.player_loc)}</video:player_loc>`)
71
+ if (video.duration !== undefined)
72
+ lines.push(` <video:duration>${video.duration}</video:duration>`)
73
+ if (video.expiration_date)
74
+ lines.push(` <video:expiration_date>${escapeXml(video.expiration_date)}</video:expiration_date>`)
75
+ if (video.rating !== undefined)
76
+ lines.push(` <video:rating>${video.rating}</video:rating>`)
77
+ if (video.view_count !== undefined)
78
+ lines.push(` <video:view_count>${video.view_count}</video:view_count>`)
79
+ if (video.publication_date)
80
+ lines.push(` <video:publication_date>${escapeXml(video.publication_date)}</video:publication_date>`)
81
+ if (video.family_friendly !== undefined)
82
+ lines.push(` <video:family_friendly>${video.family_friendly ? 'yes' : 'no'}</video:family_friendly>`)
83
+ if (video.restriction)
84
+ lines.push(` <video:restriction relationship="${video.restriction.relationship}">${escapeXml(video.restriction.content)}</video:restriction>`)
85
+ if (video.platform)
86
+ lines.push(` <video:platform relationship="${video.platform.relationship}">${escapeXml(video.platform.content)}</video:platform>`)
87
+ if (video.requires_subscription !== undefined)
88
+ lines.push(` <video:requires_subscription>${video.requires_subscription ? 'yes' : 'no'}</video:requires_subscription>`)
89
+ if (video.uploader) {
90
+ const infoAttr = video.uploader.info ? ` info="${escapeXml(video.uploader.info)}"` : ''
91
+ lines.push(` <video:uploader${infoAttr}>${escapeXml(video.uploader.name)}</video:uploader>`)
92
+ }
93
+ if (video.live !== undefined)
94
+ lines.push(` <video:live>${video.live ? 'yes' : 'no'}</video:live>`)
95
+ if (video.tag) {
96
+ for (const tag of video.tag) {
97
+ lines.push(` <video:tag>${escapeXml(tag)}</video:tag>`)
98
+ }
99
+ }
100
+
101
+ lines.push(' </video:video>')
102
+ }
103
+
104
+ return lines.join('\n')
105
+ }
106
+
107
+ export function generateSitemapXml(sitemap: Sitemap): string {
108
+ const hasImages = sitemap.some(entry => entry.images && entry.images.length > 0)
109
+ const hasVideos = sitemap.some(entry => entry.videos && entry.videos.length > 0)
110
+ const hasAlternates = sitemap.some(entry => entry.alternates?.languages)
111
+
112
+ const namespaces = ['xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"']
113
+ if (hasImages)
114
+ namespaces.push('xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"')
115
+ if (hasVideos)
116
+ namespaces.push('xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"')
117
+ if (hasAlternates)
118
+ namespaces.push('xmlns:xhtml="http://www.w3.org/1999/xhtml"')
119
+
120
+ const lines: string[] = [
121
+ '<?xml version="1.0" encoding="UTF-8"?>',
122
+ `<urlset ${namespaces.join(' ')}>`,
123
+ ]
124
+
125
+ for (const entry of sitemap) {
126
+ lines.push(' <url>')
127
+ lines.push(` <loc>${escapeXml(entry.url)}</loc>`)
128
+
129
+ if (entry.lastModified)
130
+ lines.push(` <lastmod>${formatDate(entry.lastModified)}</lastmod>`)
131
+
132
+ if (entry.changeFrequency)
133
+ lines.push(` <changefreq>${entry.changeFrequency}</changefreq>`)
134
+
135
+ if (entry.priority !== undefined)
136
+ lines.push(` <priority>${entry.priority}</priority>`)
137
+
138
+ if (entry.alternates?.languages) {
139
+ for (const [lang, url] of Object.entries(entry.alternates.languages)) {
140
+ lines.push(` <xhtml:link rel="alternate" hreflang="${escapeXml(lang)}" href="${escapeXml(url)}" />`)
141
+ }
142
+ }
143
+
144
+ if (entry.images && entry.images.length > 0)
145
+ lines.push(generateImageXml(entry.images))
146
+
147
+ if (entry.videos && entry.videos.length > 0)
148
+ lines.push(generateVideoXml(entry.videos))
149
+
150
+ lines.push(' </url>')
151
+ }
152
+
153
+ lines.push('</urlset>')
154
+ return lines.join('\n')
155
+ }
156
+
157
+ export async function findSitemapFiles(
158
+ appDir: string,
159
+ extensions: string[] = ['.ts', '.tsx', '.js', '.jsx'],
160
+ ): Promise<SitemapFile[]> {
161
+ const sitemapFiles: SitemapFile[] = []
162
+
163
+ const staticPath = path.join(appDir, 'sitemap.xml')
164
+ try {
165
+ await fs.access(staticPath)
166
+ sitemapFiles.push({ type: 'static', path: staticPath })
167
+ return sitemapFiles
168
+ }
169
+ catch {}
170
+
171
+ for (const ext of extensions) {
172
+ const dynamicPath = path.join(appDir, `sitemap${ext}`)
173
+ try {
174
+ await fs.access(dynamicPath)
175
+ sitemapFiles.push({ type: 'dynamic', path: dynamicPath })
176
+ return sitemapFiles
177
+ }
178
+ catch {}
179
+ }
180
+
181
+ return sitemapFiles
182
+ }
183
+
184
+ async function executeSitemapModule(
185
+ modulePath: string,
186
+ id?: string,
187
+ ): Promise<Sitemap> {
188
+ const module = await import(`file://${modulePath}`)
189
+
190
+ if (typeof module.default === 'function') {
191
+ const result = id !== undefined
192
+ ? await module.default({ id: Promise.resolve(id) })
193
+ : await module.default()
194
+ return result
195
+ }
196
+
197
+ return module.default
198
+ }
199
+
200
+ async function buildSitemapModule(
201
+ sitemapPath: string,
202
+ outDir: string,
203
+ id?: string,
204
+ ): Promise<string> {
205
+ const esbuild = await import('esbuild')
206
+
207
+ const result = await esbuild.build({
208
+ entryPoints: [sitemapPath],
209
+ bundle: true,
210
+ platform: 'node',
211
+ format: 'esm',
212
+ write: false,
213
+ external: ['rari'],
214
+ target: 'node20',
215
+ })
216
+
217
+ if (!result.outputFiles || result.outputFiles.length === 0)
218
+ throw new Error('Failed to build sitemap module')
219
+
220
+ const code = result.outputFiles[0].text
221
+ const tempFileName = id !== undefined ? `_sitemap_${id}_temp.mjs` : '_sitemap_temp.mjs'
222
+ const tempFile = path.join(outDir, tempFileName)
223
+ await fs.writeFile(tempFile, code)
224
+
225
+ return tempFile
226
+ }
227
+
228
+ export async function generateSitemapFiles(options: SitemapGeneratorOptions): Promise<boolean> {
229
+ const { appDir, outDir, extensions } = options
230
+ const sitemapFiles = await findSitemapFiles(appDir, extensions)
231
+
232
+ if (sitemapFiles.length === 0)
233
+ return false
234
+
235
+ const sitemapFile = sitemapFiles[0]
236
+
237
+ if (sitemapFile.type === 'static') {
238
+ const outputPath = path.join(outDir, 'sitemap.xml')
239
+ await fs.copyFile(sitemapFile.path, outputPath)
240
+ return true
241
+ }
242
+
243
+ try {
244
+ const tempFile = await buildSitemapModule(sitemapFile.path, outDir)
245
+
246
+ try {
247
+ const module = await import(`file://${tempFile}`)
248
+
249
+ if (typeof module.generateSitemaps === 'function') {
250
+ const sitemapIds = await module.generateSitemaps()
251
+
252
+ for (const { id } of sitemapIds) {
253
+ const sitemapData = await executeSitemapModule(tempFile, String(id))
254
+ const content = generateSitemapXml(sitemapData)
255
+ const outputPath = path.join(outDir, `sitemap/${id}.xml`)
256
+
257
+ await fs.mkdir(path.dirname(outputPath), { recursive: true })
258
+ await fs.writeFile(outputPath, content)
259
+ }
260
+ }
261
+ else {
262
+ const sitemapData = await executeSitemapModule(tempFile)
263
+ const content = generateSitemapXml(sitemapData)
264
+ const outputPath = path.join(outDir, 'sitemap.xml')
265
+ await fs.writeFile(outputPath, content)
266
+ }
267
+
268
+ await fs.unlink(tempFile)
269
+ return true
270
+ }
271
+ catch (execError) {
272
+ console.error('[rari] Failed to execute sitemap file:', execError)
273
+ try {
274
+ await fs.unlink(tempFile)
275
+ }
276
+ catch {}
277
+ return false
278
+ }
279
+ }
280
+ catch (buildError) {
281
+ console.error('[rari] Failed to build sitemap file:', buildError)
282
+ return false
283
+ }
284
+ }
@@ -11,4 +11,55 @@ export interface Robots {
11
11
  host?: string
12
12
  }
13
13
 
14
+ export interface SitemapImage {
15
+ loc: string
16
+ title?: string
17
+ caption?: string
18
+ geoLocation?: string
19
+ license?: string
20
+ }
21
+
22
+ export interface SitemapVideo {
23
+ title: string
24
+ thumbnail_loc: string
25
+ description: string
26
+ content_loc?: string
27
+ player_loc?: string
28
+ duration?: number
29
+ expiration_date?: string
30
+ rating?: number
31
+ view_count?: number
32
+ publication_date?: string
33
+ family_friendly?: boolean
34
+ restriction?: {
35
+ relationship: 'allow' | 'deny'
36
+ content: string
37
+ }
38
+ platform?: {
39
+ relationship: 'allow' | 'deny'
40
+ content: string
41
+ }
42
+ requires_subscription?: boolean
43
+ uploader?: {
44
+ name: string
45
+ info?: string
46
+ }
47
+ live?: boolean
48
+ tag?: string[]
49
+ }
50
+
51
+ export interface SitemapEntry {
52
+ url: string
53
+ lastModified?: string | Date
54
+ changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'
55
+ priority?: number
56
+ alternates?: {
57
+ languages?: Record<string, string>
58
+ }
59
+ images?: (string | SitemapImage)[]
60
+ videos?: SitemapVideo[]
61
+ }
62
+
63
+ export type Sitemap = SitemapEntry[]
64
+
14
65
  export type { Robots as MetadataRoute }
package/src/vite/index.ts CHANGED
@@ -51,6 +51,7 @@ interface RariOptions {
51
51
  fontSrc?: string[]
52
52
  connectSrc?: string[]
53
53
  defaultSrc?: string[]
54
+ workerSrc?: string[]
54
55
  }
55
56
  rateLimit?: {
56
57
  enabled?: boolean
@@ -170,6 +171,26 @@ export function rari(options: RariOptions = {}): Plugin[] {
170
171
  if (filePath.includes('node_modules') || (filePath.includes('/rari/dist/') || filePath.includes('\\rari\\dist\\')))
171
172
  return false
172
173
 
174
+ const projectRoot = options.projectRoot || process.cwd()
175
+ const indexHtmlPath = path.join(projectRoot, 'index.html')
176
+
177
+ if (fs.existsSync(indexHtmlPath)) {
178
+ try {
179
+ const htmlContent = fs.readFileSync(indexHtmlPath, 'utf-8')
180
+ const importRegex = /import\s*(?:\(\s*)?["']([^"']+)["']\)?/g
181
+
182
+ for (const match of htmlContent.matchAll(importRegex)) {
183
+ const importPath = match[1]
184
+ if (importPath.startsWith('/src/')) {
185
+ const absolutePath = path.join(projectRoot, importPath.slice(1))
186
+ if (absolutePath === filePath)
187
+ return false
188
+ }
189
+ }
190
+ }
191
+ catch {}
192
+ }
193
+
173
194
  let pathForFsOperations = filePath
174
195
  try {
175
196
  pathForFsOperations = fs.realpathSync(filePath)
@@ -470,6 +491,49 @@ if (import.meta.hot) {
470
491
  name: 'rari',
471
492
 
472
493
  config(config: UserConfig, { command }) {
494
+ if (command === 'build') {
495
+ const projectRoot = options.projectRoot || process.cwd()
496
+ const indexHtmlPath = path.join(projectRoot, 'index.html')
497
+
498
+ if (fs.existsSync(indexHtmlPath)) {
499
+ try {
500
+ const htmlContent = fs.readFileSync(indexHtmlPath, 'utf-8')
501
+ const importRegex = /import\s+["']([^"']+)["']/g
502
+ const htmlImports: Array<{ path: string, name: string }> = []
503
+
504
+ for (const match of htmlContent.matchAll(importRegex)) {
505
+ const importPath = match[1]
506
+ if (importPath.startsWith('/src/') && /\.(?:tsx?|jsx?)$/.test(importPath)) {
507
+ const relativePath = importPath.slice(1)
508
+ const filename = path.basename(relativePath, path.extname(relativePath))
509
+ htmlImports.push({ path: relativePath, name: filename })
510
+ }
511
+ }
512
+
513
+ if (htmlImports.length > 0) {
514
+ config.build = config.build || {}
515
+ config.build.rolldownOptions = config.build.rolldownOptions || {}
516
+
517
+ const existingInput = config.build.rolldownOptions.input || { main: './index.html' }
518
+ const inputObj: Record<string, string> = typeof existingInput === 'string'
519
+ ? { main: existingInput }
520
+ : Array.isArray(existingInput)
521
+ ? { main: existingInput[0] || './index.html' }
522
+ : { ...existingInput }
523
+
524
+ htmlImports.forEach(({ path: importPath, name }) => {
525
+ inputObj[name] = `./${importPath}`
526
+ })
527
+
528
+ config.build.rolldownOptions.input = inputObj
529
+ }
530
+ }
531
+ catch (error) {
532
+ console.warn('[rari] Error parsing index.html for build inputs:', error)
533
+ }
534
+ }
535
+ }
536
+
473
537
  config.resolve = config.resolve || {}
474
538
  const existingDedupe = Array.isArray((config.resolve as any).dedupe)
475
539
  ? ((config.resolve as any).dedupe as string[])
@@ -1662,6 +1726,34 @@ globalThis['~clientComponentPaths']["${ext.path}"] = "${exportName}";`
1662
1726
  return undefined
1663
1727
  },
1664
1728
 
1729
+ transformIndexHtml: {
1730
+ order: 'pre',
1731
+ handler(html) {
1732
+ const importRegex = /import\s+["']([^"']+)["']/g
1733
+ const imports: string[] = []
1734
+
1735
+ for (const match of html.matchAll(importRegex)) {
1736
+ const importPath = match[1]
1737
+ if (importPath.startsWith('/src/'))
1738
+ imports.push(importPath)
1739
+ }
1740
+
1741
+ if (imports.length > 0) {
1742
+ const tags = imports.map(importPath => ({
1743
+ tag: 'script',
1744
+ attrs: {
1745
+ type: 'module',
1746
+ src: importPath,
1747
+ },
1748
+ injectTo: 'head-prepend' as const,
1749
+ }))
1750
+ return { html, tags }
1751
+ }
1752
+
1753
+ return html
1754
+ },
1755
+ },
1756
+
1665
1757
  writeBundle() {
1666
1758
  const imageConfig = {
1667
1759
  ...DEFAULT_IMAGE_CONFIG,
@@ -64,6 +64,7 @@ interface ServerComponentManifest {
64
64
  fontSrc?: string[]
65
65
  connectSrc?: string[]
66
66
  defaultSrc?: string[]
67
+ workerSrc?: string[]
67
68
  }
68
69
  rateLimit?: {
69
70
  enabled?: boolean
@@ -90,6 +91,7 @@ export interface ServerBuildOptions {
90
91
  fontSrc?: string[]
91
92
  connectSrc?: string[]
92
93
  defaultSrc?: string[]
94
+ workerSrc?: string[]
93
95
  }
94
96
  rateLimit?: {
95
97
  enabled?: boolean
@@ -146,6 +148,8 @@ export class ServerComponentBuilder {
146
148
  dependencies: string[]
147
149
  }>()
148
150
 
151
+ private htmlOnlyImports = new Set<string>()
152
+
149
153
  getComponentCount(): number {
150
154
  return this.serverComponents.size + this.serverActions.size
151
155
  }
@@ -163,12 +167,42 @@ export class ServerComponentBuilder {
163
167
  rateLimit: options.rateLimit,
164
168
  spamBlocker: options.spamBlocker,
165
169
  }
170
+
171
+ this.parseHtmlImports()
172
+ }
173
+
174
+ private parseHtmlImports() {
175
+ const indexHtmlPath = path.join(this.projectRoot, 'index.html')
176
+ if (!fs.existsSync(indexHtmlPath))
177
+ return
178
+
179
+ try {
180
+ const htmlContent = fs.readFileSync(indexHtmlPath, 'utf-8')
181
+ const importRegex = /import\s+["']([^"']+)["']/g
182
+ for (const match of htmlContent.matchAll(importRegex)) {
183
+ const importPath = match[1]
184
+ if (importPath.startsWith('/src/')) {
185
+ const absolutePath = path.join(this.projectRoot, importPath.slice(1))
186
+ this.htmlOnlyImports.add(absolutePath)
187
+ }
188
+ }
189
+ }
190
+ catch (error) {
191
+ console.warn('[server-build] Error parsing index.html:', error)
192
+ }
193
+ }
194
+
195
+ private isHtmlOnlyImport(filePath: string): boolean {
196
+ return this.htmlOnlyImports.has(filePath)
166
197
  }
167
198
 
168
199
  isServerComponent(filePath: string): boolean {
169
200
  if (filePath.includes('node_modules'))
170
201
  return false
171
202
 
203
+ if (this.isHtmlOnlyImport(filePath))
204
+ return false
205
+
172
206
  try {
173
207
  if (!fs.existsSync(filePath)) {
174
208
  return false
@@ -1039,15 +1073,15 @@ const ${importName} = (props) => {
1039
1073
  function registerClientReference(clientReference, id, exportName) {
1040
1074
  const key = id + '#' + exportName;
1041
1075
  const clientProxy = {};
1042
- Object.defineProperty(clientProxy, '$typeof', {
1076
+ Object.defineProperty(clientProxy, '$$typeof', {
1043
1077
  value: Symbol.for('react.client.reference'),
1044
1078
  enumerable: false
1045
1079
  });
1046
- Object.defineProperty(clientProxy, '$id', {
1080
+ Object.defineProperty(clientProxy, '$$id', {
1047
1081
  value: key,
1048
1082
  enumerable: false
1049
1083
  });
1050
- Object.defineProperty(clientProxy, '$async', {
1084
+ Object.defineProperty(clientProxy, '$$async', {
1051
1085
  value: false,
1052
1086
  enumerable: false
1053
1087
  });
@@ -1992,6 +2026,18 @@ export function createServerBuildPlugin(
1992
2026
  catch (error) {
1993
2027
  console.warn('[rari] Failed to generate robots.txt:', error)
1994
2028
  }
2029
+
2030
+ try {
2031
+ const { generateSitemapFiles } = await import('../router/sitemap-generator')
2032
+ await generateSitemapFiles({
2033
+ appDir: path.join(projectRoot, 'src', 'app'),
2034
+ outDir: path.join(projectRoot, 'dist'),
2035
+ extensions: ['.ts', '.tsx', '.js', '.jsx'],
2036
+ })
2037
+ }
2038
+ catch (error) {
2039
+ console.warn('[rari] Failed to generate sitemap:', error)
2040
+ }
1995
2041
  }
1996
2042
  },
1997
2043
 
package/src/vite.ts CHANGED
@@ -72,6 +72,6 @@ export { createHttpRuntimeClient, HttpRuntimeClient } from './runtime-client'
72
72
 
73
73
  export type { RuntimeClient } from './runtime-client'
74
74
 
75
- export type { Robots, RobotsRule } from './types/metadata-route'
75
+ export type { Robots, RobotsRule, Sitemap, SitemapEntry, SitemapImage, SitemapVideo } from './types/metadata-route'
76
76
 
77
77
  export { defineRariConfig, defineRariOptions, rari } from './vite/index'
@@ -1 +0,0 @@
1
- import{n as e,r as t,t as n}from"./server-build-CCcyQm4X.mjs";export{n as ServerComponentBuilder,t as scanDirectory};
@@ -1,47 +0,0 @@
1
- import process from 'node:process'
2
-
3
- const isColorSupported
4
- = !(process.env.NO_COLOR || process.argv.includes('--no-color'))
5
- && (
6
- process.env.FORCE_COLOR
7
- || process.argv.includes('--color')
8
- || process.platform === 'win32'
9
- || (process.stdout?.isTTY && process.env.TERM !== 'dumb')
10
- || process.env.CI
11
- )
12
-
13
- function formatter(open: string, close: string, replace = open) {
14
- return (input: string | number) => {
15
- const string = String(input)
16
- const index = string.indexOf(close, open.length)
17
- return ~index
18
- ? open + replaceClose(string, close, replace, index) + close
19
- : open + string + close
20
- }
21
- }
22
-
23
- function replaceClose(string: string, close: string, replace: string, index: number): string {
24
- let result = ''
25
- let cursor = 0
26
- do {
27
- result += string.substring(cursor, index) + replace
28
- cursor = index + close.length
29
- index = string.indexOf(close, cursor)
30
- } while (~index)
31
- return result + string.substring(cursor)
32
- }
33
-
34
- const f = isColorSupported ? formatter : () => String
35
-
36
- const colors = {
37
- isColorSupported,
38
- bold: f('\x1B[1m', '\x1B[22m', '\x1B[22m\x1B[1m'),
39
- red: f('\x1B[31m', '\x1B[39m'),
40
- green: f('\x1B[32m', '\x1B[39m'),
41
- yellow: f('\x1B[33m', '\x1B[39m'),
42
- blue: f('\x1B[34m', '\x1B[39m'),
43
- cyan: f('\x1B[36m', '\x1B[39m'),
44
- gray: f('\x1B[90m', '\x1B[39m'),
45
- }
46
-
47
- export default colors