rari 0.7.11 → 0.7.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +1 -1
- package/dist/server-build-BTHZMYd8.mjs +181 -0
- package/dist/server-build-k25VDgDe.mjs +1 -0
- package/dist/{vite-CnkUNT-E.mjs → vite-D4TzV89n.mjs} +3 -3
- package/dist/vite.mjs +1 -1
- package/package.json +8 -8
- package/src/vite/index.ts +11 -3
- package/src/vite/server-build.ts +354 -41
- package/dist/server-build-CPWsut0H.mjs +0 -1
- package/dist/server-build-Dcu2KENc.mjs +0 -124
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-
|
|
1
|
+
import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./vite-D4TzV89n.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-BTHZMYd8.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};
|
|
@@ -0,0 +1,181 @@
|
|
|
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(`
|
|
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
|
+
`);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
|
+
const ${r} = (props) => {
|
|
5
|
+
let Component = globalThis['~rsc']?.components?.['components/${o}']
|
|
6
|
+
|| globalThis['~rsc']?.modules?.['components/${o}']?.default
|
|
7
|
+
|| globalThis['components/${o}'];
|
|
8
|
+
|
|
9
|
+
if (Component && typeof Component === 'object' && Component.default) {
|
|
10
|
+
Component = Component.default;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (!Component) {
|
|
14
|
+
throw new Error('Component components/${o} not loaded');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (typeof Component !== 'function') {
|
|
18
|
+
throw new Error('Component components/${o} is not a function, got: ' + typeof Component);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return Component(props);
|
|
22
|
+
}`;i.push({original:n,replacement:l})}}continue}let c=this.options.alias||{};for(let[e,n]of Object.entries(c))if(o.startsWith(`${e}/`)||o===e){let r=o.slice(e.length);s=t.join(n,r);break}if(s){let a=s.match(/[/\\]components[/\\](\w+)(?:\.tsx?|\.jsx?)?$/);if(a){let o=a[1],c=t.isAbsolute(s)?s:t.resolve(this.projectRoot,s),l=[c,`${c}.tsx`,`${c}.ts`,`${c}.jsx`,`${c}.js`],u=!1,d=c;for(let t of l)if(e.existsSync(t)){d=t,this.isClientComponent(t)&&(u=!0);break}if(!u)continue;let f=t.relative(this.projectRoot,d).replace(/\\/g,`/`).replace(/\.(tsx?|\.jsx?)$/,``).replace(/[^\w/-]/g,`_`).replace(/^src\//,``),p=`// Component reference: ${o}
|
|
23
|
+
const ${r} = (props) => {
|
|
24
|
+
let Component = globalThis['~rsc']?.components?.['${f}']
|
|
25
|
+
|| globalThis['~rsc']?.modules?.['${f}']?.default
|
|
26
|
+
|| globalThis['${f}'];
|
|
27
|
+
|
|
28
|
+
if (Component && typeof Component === 'object' && Component.default) {
|
|
29
|
+
Component = Component.default;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!Component) {
|
|
33
|
+
throw new Error('Component ${f} not loaded');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (typeof Component !== 'function') {
|
|
37
|
+
throw new Error('Component ${f} is not a function, got: ' + typeof Component);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return Component(props);
|
|
41
|
+
}`;i.push({original:n,replacement:p})}}}let a=n;for(let{original:e,replacement:t}of i)a=a.replace(e,t);return a}isPageComponent(e){return e.includes(`/app/`)||e.includes(`\\app\\`)}async buildComponentCodeOnly(n,a,o){let s=await e.promises.readFile(n,`utf-8`),c=this.transformClientImports(s,n),l=this.isPageComponent(n)?this.transformComponentImportsToGlobal(c):c,u=t.extname(n),d;d=u===`.tsx`?`tsx`:u===`.ts`?`ts`:u===`.jsx`?`jsx`:`js`;try{let a=await r({stdin:{contents:l,resolveDir:t.dirname(n),sourcefile:n,loader:d},bundle:!0,platform:`node`,target:`es2022`,format:`esm`,mainFields:[`module`,`main`],conditions:[`import`,`module`,`default`],jsx:`transform`,jsxFactory:`React.createElement`,jsxFragment:`React.Fragment`,define:{global:`globalThis`,"process.env.NODE_ENV":`"production"`,...this.options.define},loader:{".ts":`ts`,".tsx":`tsx`,".js":`js`,".jsx":`jsx`},resolveExtensions:[`.ts`,`.tsx`,`.js`,`.jsx`],minify:!1,minifyWhitespace:!0,minifyIdentifiers:!0,minifySyntax:!0,sourcemap:!1,metafile:!1,write:!1,plugins:[{name:`resolve-aliases`,setup:n=>{let r=this,i=this.options.alias||{};for(let[a,o]of Object.entries(i)){let i=a.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),s=RegExp(`^${i}(/|$)`);n.onResolve({filter:s},n=>{let i=n.path.slice(a.length),s=t.join(o,i),c=t.isAbsolute(s)?s:t.resolve(n.resolveDir,s);for(let t of[``,`.ts`,`.tsx`,`.js`,`.jsx`]){let i=c+t;if(e.existsSync(i)&&e.statSync(i).isFile()){if(r.isClientComponent(i))return{path:n.path,external:!0};try{let t=e.readFileSync(i,`utf-8`);if(t.includes(`'use server'`)||t.includes(`"use server"`))return{path:n.path,external:!0}}catch{}return{path:i}}}return{path:c}})}}},{name:`replace-react-imports`,setup(e){e.onLoad({filter:/runtime-client.*\.js$/},async e=>{let t=await(await import(`node:fs/promises`)).readFile(e.path,`utf-8`);return t=t.replace(/import\s+React\d*(?:\s*,\s*\{[^}]*\})?\s+from\s+['"]react['"];?/g,`// React is available as globalThis.React`),t=t.replace(/React2/g,`React`),{contents:t,loader:`js`}})}},{name:`hmr-auto-external`,setup:n=>{let r=this;n.onResolve({filter:/.*/},async n=>{if(n.path.includes(`../components/`)||n.path.includes(`./components/`)){let i=t.resolve(n.resolveDir,n.path);for(let t of[``,`.ts`,`.tsx`,`.js`,`.jsx`]){let a=i+t;if(e.existsSync(a)&&e.statSync(a).isFile()&&r.isClientComponent(a))return{path:n.path,namespace:`component-stub`}}}if(n.path===`react`||n.path===`react-dom`||n.path===`react/jsx-runtime`||n.path===`react/jsx-dev-runtime`||n.path.startsWith(`node:`)||i(n.path)||n.path===`rari/image`||n.path.startsWith(`rari/image/`))return{path:n.path,external:!0};if(n.path===`rari/client`)return null;if(n.path.startsWith(`@/actions/`)||n.path.includes(`/actions/`)){let r=t.resolve(n.resolveDir,n.path);for(let t of[``,`.ts`,`.tsx`,`.js`,`.jsx`]){let i=r+t;if(e.existsSync(i)){try{let t=e.readFileSync(i,`utf-8`);if(t.includes(`'use server'`)||t.includes(`"use server"`))return{path:n.path,external:!0}}catch{}break}}}return null}),n.onLoad({filter:/.*/,namespace:`component-stub`},async e=>{let t=e.path.match(/\/components\/(\w+)/);return{contents:`// Component stub for ${t?t[1]:`Unknown`} - replaced by global reference`,loader:`js`}})}},{name:`resolve-server-functions`,setup(n){n.onResolve({filter:/^\.\.?\/.*(functions|actions)/},async n=>{let r=t.resolve(t.dirname(n.importer),n.path);for(let t of[`.ts`,`.js`,`.tsx`,`.jsx`,`/index.ts`,`/index.js`]){let n=r+t;if(e.existsSync(n))return{path:n}}return null})}}]});if(a.outputFiles&&a.outputFiles.length>0)return a.outputFiles[0].text;throw a.errors.length>0?(console.error(`[rari] Build: ESBuild errors:`,a.errors),Error(`ESBuild compilation failed with ${a.errors.length} errors`)):Error(`No output generated from ESBuild`)}catch(e){throw console.error(`[rari] Build: ESBuild failed for ${n}:`,e),e}}async buildServerComponents(){let n=t.join(this.options.outDir,this.options.serverDir);await e.promises.mkdir(n,{recursive:!0});let r={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`},i=this.options.alias||{};for(let[e,n]of Object.entries(i)){let i=t.isAbsolute(n)?n:t.resolve(this.projectRoot,n);r[`${e}/`]=`file://${i}/`}let a={components:{},importMap:{imports:r},version:`1.0.0`,buildTime:new Date().toISOString(),csp:this.options.csp,rateLimit:this.options.rateLimit,spamBlocker:this.options.spamBlocker};for(let[n,r]of this.serverComponents){if(this.isPageComponent(n))continue;let i=t.relative(this.projectRoot,n),o=this.getComponentId(i),s=t.join(this.options.serverDir,`${o}.js`),c=t.join(this.options.outDir,s),l=t.dirname(c);await e.promises.mkdir(l,{recursive:!0}),await this.buildSingleComponent(n,c,r);let u=`file://${t.resolve(this.projectRoot,c)}`;a.components[o]={id:o,filePath:n,relativePath:i,bundlePath:s,moduleSpecifier:u,dependencies:r.dependencies,hasNodeImports:r.hasNodeImports}}for(let[n,r]of this.serverComponents){if(!this.isPageComponent(n))continue;let i=t.relative(this.projectRoot,n),o=this.getComponentId(i),s=t.join(this.options.serverDir,`${o}.js`),c=t.join(this.options.outDir,s),l=t.dirname(c);await e.promises.mkdir(l,{recursive:!0}),await this.buildSingleComponent(n,c,r);let u=`file://${t.resolve(this.projectRoot,c)}`;a.components[o]={id:o,filePath:n,relativePath:i,bundlePath:s,moduleSpecifier:u,dependencies:r.dependencies,hasNodeImports:r.hasNodeImports}}for(let[n,r]of this.serverActions){let i=t.relative(this.projectRoot,n),o=this.getComponentId(i),s=t.join(this.options.serverDir,`${o}.js`),c=t.join(this.options.outDir,s),l=t.dirname(c);await e.promises.mkdir(l,{recursive:!0}),await this.buildSingleComponent(n,c,r);let u=`file://${t.resolve(this.projectRoot,c)}`;a.components[o]={id:o,filePath:n,relativePath:i,bundlePath:s,moduleSpecifier:u,dependencies:r.dependencies,hasNodeImports:r.hasNodeImports}}let o=t.join(this.options.outDir,this.options.manifestPath);return await e.promises.writeFile(o,JSON.stringify(a,null,2),`utf-8`),a}async buildSingleComponent(n,a,o,s=!1){let c=await e.promises.readFile(n,`utf-8`),l=this.transformClientImports(c,n),u=this.isPageComponent(n),d=u?this.transformComponentImportsToGlobal(l):l,f=t.extname(n),p;p=f===`.tsx`?`tsx`:f===`.ts`?`ts`:f===`.jsx`?`jsx`:`js`;try{let o=await r({stdin:{contents:d,resolveDir:t.dirname(n),sourcefile:n,loader:p},bundle:!0,platform:`node`,target:`es2022`,format:`esm`,outfile:a,mainFields:[`module`,`main`],conditions:[`import`,`module`,`default`],jsx:`transform`,jsxFactory:`React.createElement`,jsxFragment:`React.Fragment`,define:{global:`globalThis`,"process.env.NODE_ENV":`"production"`,...this.options.define},loader:{".ts":`ts`,".tsx":`tsx`,".js":`js`,".jsx":`jsx`},resolveExtensions:[`.ts`,`.tsx`,`.js`,`.jsx`],minify:this.options.minify,minifyWhitespace:this.options.minify,minifyIdentifiers:this.options.minify,minifySyntax:this.options.minify,sourcemap:!1,metafile:!1,write:!1,plugins:[{name:`external-server-actions`,setup:n=>{n.onResolve({filter:/.*/},async n=>{if(n.namespace!==`file`&&n.namespace!==``||n.path.startsWith(`node:`)||i(n.path)||n.path===`react`||n.path===`react-dom`||n.path===`react/jsx-runtime`||n.path===`react/jsx-dev-runtime`)return null;let r=null,a=this.options.alias||{};for(let[e,i]of Object.entries(a))if(n.path.startsWith(`${e}/`)||n.path===e){let a=n.path.slice(e.length),o=t.join(i,a);r=t.isAbsolute(o)?o:t.resolve(n.resolveDir,o);break}if(!r&&(n.path.startsWith(`./`)||n.path.startsWith(`../`))&&(r=t.resolve(n.resolveDir,n.path)),r)for(let t of[``,`.ts`,`.tsx`,`.js`,`.jsx`]){let i=r+t;if(e.existsSync(i)&&e.statSync(i).isFile()){try{let t=e.readFileSync(i,`utf-8`).split(`
|
|
42
|
+
`);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{path:n.path,namespace:`server-action-reference`};if(t)break}}}catch{}break}}return null}),n.onLoad({filter:/.*/,namespace:`server-action-reference`},e=>{let n=this.options.alias||{},r=e.path;for(let[i,a]of Object.entries(n))if(e.path.startsWith(`${i}/`)||e.path===i){let n=e.path.slice(i.length),o=t.isAbsolute(a)?t.join(a,n):t.resolve(this.projectRoot,a,n);r=t.relative(this.projectRoot,o);break}return{contents:`export * from "./${r}";`,loader:`js`,resolveDir:this.projectRoot}})}},{name:`use-transformed-server-components`,setup:n=>{if(!u)return;let r=this,i=r.options.alias||{};n.onResolve({filter:/^file:\/\//},t=>{let n=t.path.replace(/^file:\/\//,``);return e.existsSync(n)?{path:n,namespace:`transformed-server-component`}:null}),n.onResolve({filter:/.*/},n=>{let a=null;for(let[e,r]of Object.entries(i))if(n.path.startsWith(`${e}/`)||n.path===e){let i=n.path.slice(e.length),o=t.join(r,i);a=t.isAbsolute(o)?o:t.resolve(n.resolveDir,o);break}if(!a&&(n.path.startsWith(`./`)||n.path.startsWith(`../`))&&(a=t.resolve(n.resolveDir,n.path)),!a||n.resolveDir.includes(`node_modules`))return null;for(let n of[``,`.ts`,`.tsx`,`.js`,`.jsx`]){let i=a+n;if(e.existsSync(i)&&e.statSync(i).isFile()){if(r.isClientComponent(i))return null;let n=t.join(r.projectRoot,`src`);if(!i.startsWith(n))return null;let a=t.relative(n,i),o=t.join(r.projectRoot,`dist`,`server`,a.replace(/\.(tsx?|jsx?)$/,`.js`));if(e.existsSync(o))return{path:o,namespace:`transformed-server-component`};break}}return null}),n.onLoad({filter:/.*/,namespace:`transformed-server-component`},n=>({contents:e.readFileSync(n.path,`utf-8`),loader:`js`,resolveDir:t.dirname(n.path)}))}},{name:`resolve-aliases`,setup:n=>{let r=this,i=this.options.alias||{};for(let[a,o]of Object.entries(i)){let i=a.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),s=RegExp(`^${i}(/|$)`);n.onResolve({filter:s},n=>{let i=n.path.slice(a.length),s=t.join(o,i),c=t.isAbsolute(s)?s:t.resolve(n.resolveDir,s);for(let t of[``,`.ts`,`.tsx`,`.js`,`.jsx`]){let i=c+t;if(e.existsSync(i)&&e.statSync(i).isFile()){if(r.isClientComponent(i))return{path:n.path,namespace:`client-component-reference`};try{let t=e.readFileSync(i,`utf-8`);if(t.includes(`'use server'`)||t.includes(`"use server"`))return{path:n.path,external:!0}}catch{}return{path:i}}}return{path:c}})}n.onLoad({filter:/.*/,namespace:`client-component-reference`},e=>{let n=e.path;for(let[a,o]of Object.entries(i))if(e.path.startsWith(`${a}/`)||e.path===a){let i=e.path.slice(a.length),s=t.isAbsolute(o)?t.join(o,i):t.resolve(r.projectRoot,o,i);n=t.relative(r.projectRoot,s);break}return{contents:`
|
|
43
|
+
function registerClientReference(clientReference, id, exportName) {
|
|
44
|
+
const key = id + '#' + exportName;
|
|
45
|
+
const clientProxy = {};
|
|
46
|
+
Object.defineProperty(clientProxy, '$$typeof', {
|
|
47
|
+
value: Symbol.for('react.client.reference'),
|
|
48
|
+
enumerable: false
|
|
49
|
+
});
|
|
50
|
+
Object.defineProperty(clientProxy, '$$id', {
|
|
51
|
+
value: key,
|
|
52
|
+
enumerable: false
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(clientProxy, '$$async', {
|
|
55
|
+
value: false,
|
|
56
|
+
enumerable: false
|
|
57
|
+
});
|
|
58
|
+
try {
|
|
59
|
+
if (typeof globalThis['~rari']?.bridge !== 'undefined' &&
|
|
60
|
+
typeof globalThis['~rari'].bridge.registerClientReference === 'function') {
|
|
61
|
+
globalThis['~rari'].bridge.registerClientReference(key, id, exportName);
|
|
62
|
+
}
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error('[rari] Build: Failed to register client reference:', error);
|
|
65
|
+
}
|
|
66
|
+
return clientProxy;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default registerClientReference(null, ${JSON.stringify(n)}, "default");
|
|
70
|
+
`,loader:`js`}})}},{name:`replace-react-imports`,setup(e){e.onLoad({filter:/runtime-client.*\.js$/},async e=>{let t=await(await import(`node:fs/promises`)).readFile(e.path,`utf-8`);return t=t.replace(/import\s+React\d*(?:\s*,\s*\{[^}]*\})?\s+from\s+['"]react['"];?/g,`// React is available as globalThis.React`),t=t.replace(/React2/g,`React`),{contents:t,loader:`js`}})}},{name:`auto-external`,setup(e){e.onResolve({filter:/^[^./]/},async e=>e.path===`react`||e.path===`react-dom`||e.path===`react/jsx-runtime`||e.path===`react/jsx-dev-runtime`||e.path.startsWith(`node:`)||i(e.path)||e.path===`rari/image`||e.path.startsWith(`rari/image/`)?{path:e.path,external:!0}:(e.path,null))}},{name:`resolve-server-functions`,setup(n){n.onResolve({filter:/^\.\.?\/.*(functions|actions)/},async n=>{let r=t.resolve(t.dirname(n.importer),n.path);for(let t of[`.ts`,`.js`,`.tsx`,`.jsx`,`/index.ts`,`/index.js`]){let n=r+t;if(e.existsSync(n))return{path:n}}return null})}}]});if(o.outputFiles&&o.outputFiles.length>0){let t=o.outputFiles[0].text;if(t=t.replace(/import\s+\{[^}]*\}\s+from\s+['"]react\/jsx-runtime['"];?\s*/g,`// jsx/jsxs are available as globals
|
|
71
|
+
`),t=t.replace(/import\s+\{[^}]*\}\s+from\s+['"]react\/jsx-dev-runtime['"];?\s*/g,`// jsx/jsxs are available as globals
|
|
72
|
+
`),t=t.replace(/import\s+React\d*(?:\s*,\s*\{[^}]*\})?\s+from\s+['"]react['"];?\s*/g,`// React is available as globalThis.React
|
|
73
|
+
`),t=t.replace(/import\s+\{[^}]*\}\s+from\s+['"]react['"];?\s*/g,`// React is available as globalThis.React
|
|
74
|
+
`),t=t.replace(/import\s*(\{[^}]+\}|\w+)\s*from\s*["']([^"']+)["'];?/g,e=>e),await e.promises.writeFile(a,t,`utf-8`),s)return t}if(o.errors.length>0)throw console.error(`[rari] Build: ESBuild errors:`,o.errors),Error(`ESBuild compilation failed with ${o.errors.length} errors`);o.warnings.length>0&&console.warn(`[rari] Build: ESBuild warnings:`,o.warnings)}catch(e){throw console.error(`[rari] Build: ESBuild failed for ${n}:`,e),e}}createSelfRegisteringModule(e,t){if(e.includes(`Self-registering Production Component`))return e;let n=e,r=null,i=[];if(n=n.replace(/^export\s+default\s+function\s+(\w+)/gm,(e,t)=>(r=t,`function ${t}`)),n=n.replace(/^export\s+default\s+async\s+function\s+(\w+)/gm,(e,t)=>(r=t,`async function ${t}`)),n=n.replace(/^export\s+default\s+(\w+);?\s*$/gm,(e,t)=>(r=t,`// Default export: ${t}`)),n=n.replace(/^export\s*\{\s*(\w+)\s+as\s+default\s*\};?\s*$/gm,(e,t)=>(r=t,`// Default export: ${t}`)),n=n.replace(/^export\s*\{([^}]+)\};?\s*$/gm,(e,a)=>{let o=a.split(`,`).map(e=>e.trim()),s=[];return o.forEach(e=>{if(e.includes(`as default`)){let t=e.replace(`as default`,``).trim();r=t,s.push(`${t} (default)`)}else if(e===`default`){let e=`${t}_default`;n.includes(`var ${e}`)&&(r=e),s.push(`default`)}else i.push(e),s.push(e)}),`// Exports: ${s.join(`, `)}`}),n=n.replace(/^export\s+(?:async\s+)?function\s+(\w+)/gm,(e,t)=>(i.push(t),e.replace(`export `,``))),n=n.replace(/^export\s+(const|let|var)\s+(\w+)/gm,(e,t,n)=>(i.push(n),`${t} ${n}`)),!r){let e=`${t}_default`;n.includes(`var ${e}`)&&(r=e)}return`// Self-registering Production Component: ${t}
|
|
75
|
+
|
|
76
|
+
if (!globalThis["${t}"]) {
|
|
77
|
+
${n}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const moduleKey = "${t}";
|
|
81
|
+
let mainExport = null;
|
|
82
|
+
const exportedFunctions = {};
|
|
83
|
+
|
|
84
|
+
if (!globalThis['~serverFunctions']) globalThis['~serverFunctions'] = {};
|
|
85
|
+
if (!globalThis['~serverFunctions'].all) globalThis['~serverFunctions'].all = {};
|
|
86
|
+
|
|
87
|
+
${i.map(e=>`if (typeof ${e} !== 'undefined') {
|
|
88
|
+
globalThis.${e} = ${e};
|
|
89
|
+
globalThis['~serverFunctions'].all['${e}'] = ${e};
|
|
90
|
+
exportedFunctions['${e}'] = ${e};
|
|
91
|
+
}`).join(`
|
|
92
|
+
`)}
|
|
93
|
+
|
|
94
|
+
${r?`if (typeof ${r} !== 'undefined') {
|
|
95
|
+
mainExport = ${r};
|
|
96
|
+
}`:``}
|
|
97
|
+
|
|
98
|
+
if (mainExport === null && Object.keys(exportedFunctions).length > 0) {
|
|
99
|
+
if (Object.keys(exportedFunctions).length === 1) {
|
|
100
|
+
mainExport = exportedFunctions[Object.keys(exportedFunctions)[0]];
|
|
101
|
+
} else {
|
|
102
|
+
let componentFunction = null;
|
|
103
|
+
let firstFunction = null;
|
|
104
|
+
|
|
105
|
+
for (const [name, value] of Object.entries(exportedFunctions)) {
|
|
106
|
+
if (typeof value === 'function') {
|
|
107
|
+
if (!firstFunction) firstFunction = value;
|
|
108
|
+
if (/^[A-Z]/.test(name)) {
|
|
109
|
+
componentFunction = value;
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
mainExport = componentFunction || firstFunction;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (mainExport !== null) {
|
|
120
|
+
if (!globalThis[moduleKey]) {
|
|
121
|
+
globalThis[moduleKey] = mainExport;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!globalThis['~rsc']) globalThis['~rsc'] = {};
|
|
125
|
+
globalThis['~rsc'].components = globalThis['~rsc'].components || {};
|
|
126
|
+
globalThis['~rsc'].components[moduleKey] = mainExport;
|
|
127
|
+
|
|
128
|
+
globalThis['~rsc'].modules = globalThis['~rsc'].modules || {};
|
|
129
|
+
globalThis['~rsc'].modules[moduleKey] = { default: mainExport, ...exportedFunctions };
|
|
130
|
+
|
|
131
|
+
if (typeof globalThis.RscModuleManager !== 'undefined' && globalThis.RscModuleManager.register) {
|
|
132
|
+
globalThis.RscModuleManager.register(moduleKey, mainExport, exportedFunctions);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error('[rari] Build: Error in self-registration for ${t}:', error);
|
|
137
|
+
}
|
|
138
|
+
}`}transformClientImports(e,n){let r=e,i=/import\s+(?:(\w+)|\{([^}]+)\})\s+from\s+['"]([^'"]+)['"];?\s*$/gm,a,o=[],s=!1,c=[`rari/image`];for(;a=i.exec(e),a!==null;){let[e,r,i,l]=a,u=!1,d=l;if(c.includes(l))u=!0;else{let e=this.resolveImportPath(l,n);this.isClientComponent(e)&&(u=!0,d=t.relative(this.projectRoot,e))}if(u){s=!0;let t=``;r?t=`const ${r} = registerClientReference(
|
|
139
|
+
null,
|
|
140
|
+
${JSON.stringify(d)},
|
|
141
|
+
"default"
|
|
142
|
+
);`:i&&(t=i.split(`,`).map(e=>e.trim()).map(e=>{let[t,n]=e.includes(` as `)?e.split(` as `).map(e=>e.trim()):[e,e];return`const ${n} = registerClientReference(
|
|
143
|
+
null,
|
|
144
|
+
${JSON.stringify(d)},
|
|
145
|
+
${JSON.stringify(t)}
|
|
146
|
+
);`}).join(`
|
|
147
|
+
`)),o.push({original:e,replacement:t})}}s&&(r=`
|
|
148
|
+
function registerClientReference(clientReference, id, exportName) {
|
|
149
|
+
const key = id + '#' + exportName;
|
|
150
|
+
|
|
151
|
+
const clientProxy = {};
|
|
152
|
+
|
|
153
|
+
Object.defineProperty(clientProxy, '$$typeof', {
|
|
154
|
+
value: Symbol.for('react.client.reference'),
|
|
155
|
+
enumerable: false
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
Object.defineProperty(clientProxy, '$$id', {
|
|
159
|
+
value: key,
|
|
160
|
+
enumerable: false
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
Object.defineProperty(clientProxy, '$$async', {
|
|
164
|
+
value: false,
|
|
165
|
+
enumerable: false
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
if (typeof globalThis['~rari']?.bridge !== 'undefined' &&
|
|
170
|
+
typeof globalThis['~rari'].bridge.registerClientReference === 'function') {
|
|
171
|
+
globalThis['~rari'].bridge.registerClientReference(key, id, exportName);
|
|
172
|
+
}
|
|
173
|
+
} catch (error) {
|
|
174
|
+
console.error('[rari] Build: Failed to register client reference with Rust bridge:', error);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return clientProxy;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
`+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(`
|
|
181
|
+
`),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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e,r as t,t as n}from"./server-build-BTHZMYd8.mjs";export{n as ServerComponentBuilder,t as scanDirectory};
|
|
@@ -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-Dcu2KENc.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-BTHZMYd8.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){let
|
|
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+=`
|
|
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+=`
|
|
@@ -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-
|
|
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-k25VDgDe.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-k25VDgDe.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}"] = {
|
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-
|
|
1
|
+
import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./vite-D4TzV89n.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-BTHZMYd8.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.
|
|
4
|
+
"version": "0.7.12",
|
|
5
5
|
"description": "Runtime Accelerated Rendering Infrastructure (rari)",
|
|
6
6
|
"author": "Ryan Skinner",
|
|
7
7
|
"license": "MIT",
|
|
@@ -84,17 +84,17 @@
|
|
|
84
84
|
"esbuild": "^0.27.2"
|
|
85
85
|
},
|
|
86
86
|
"optionalDependencies": {
|
|
87
|
-
"rari-darwin-arm64": "0.7.
|
|
88
|
-
"rari-darwin-x64": "0.7.
|
|
89
|
-
"rari-linux-arm64": "0.7.
|
|
90
|
-
"rari-linux-x64": "0.7.
|
|
91
|
-
"rari-win32-x64": "0.7.
|
|
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"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
94
|
"@types/node": "^25.0.10",
|
|
95
95
|
"@types/react": "^19.2.9",
|
|
96
|
-
"@typescript/native-preview": "^7.0.0-dev.
|
|
97
|
-
"oxlint": "^1.
|
|
96
|
+
"@typescript/native-preview": "^7.0.0-dev.20260126.1",
|
|
97
|
+
"oxlint": "^1.42.0",
|
|
98
98
|
"rolldown-vite": "^7.3.1",
|
|
99
99
|
"tsdown": "^0.20.1"
|
|
100
100
|
},
|
package/src/vite/index.ts
CHANGED
|
@@ -109,7 +109,7 @@ async function loadReactServerDomShim(): Promise<string> {
|
|
|
109
109
|
return loadRuntimeFile('react-server-dom-shim.js')
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
function scanForClientComponents(srcDir: string): Set<string> {
|
|
112
|
+
function scanForClientComponents(srcDir: string, additionalDirs: string[] = []): Set<string> {
|
|
113
113
|
const clientComponents = new Set<string>()
|
|
114
114
|
|
|
115
115
|
function scanDirectory(dir: string) {
|
|
@@ -122,6 +122,8 @@ function scanForClientComponents(srcDir: string): Set<string> {
|
|
|
122
122
|
const fullPath = path.join(dir, entry.name)
|
|
123
123
|
|
|
124
124
|
if (entry.isDirectory()) {
|
|
125
|
+
if (entry.name === 'node_modules')
|
|
126
|
+
continue
|
|
125
127
|
scanDirectory(fullPath)
|
|
126
128
|
}
|
|
127
129
|
else if (entry.isFile() && /\.(?:tsx?|jsx?)$/.test(entry.name)) {
|
|
@@ -140,6 +142,12 @@ function scanForClientComponents(srcDir: string): Set<string> {
|
|
|
140
142
|
}
|
|
141
143
|
|
|
142
144
|
scanDirectory(srcDir)
|
|
145
|
+
|
|
146
|
+
for (const dir of additionalDirs) {
|
|
147
|
+
if (fs.existsSync(dir))
|
|
148
|
+
scanDirectory(dir)
|
|
149
|
+
}
|
|
150
|
+
|
|
143
151
|
return clientComponents
|
|
144
152
|
}
|
|
145
153
|
|
|
@@ -1011,7 +1019,7 @@ const ${componentName} = registerClientReference(
|
|
|
1011
1019
|
: Number(process.env.PORT || process.env.RSC_PORT || 3000)
|
|
1012
1020
|
const baseUrl = `http://localhost:${serverPort}`
|
|
1013
1021
|
|
|
1014
|
-
const clientComponentFiles = scanForClientComponents(srcDir)
|
|
1022
|
+
const clientComponentFiles = scanForClientComponents(srcDir, Object.values(resolvedAlias))
|
|
1015
1023
|
|
|
1016
1024
|
for (const componentPath of clientComponentFiles) {
|
|
1017
1025
|
const relativePath = path.relative(process.cwd(), componentPath)
|
|
@@ -1420,7 +1428,7 @@ const ${componentName} = registerClientReference(
|
|
|
1420
1428
|
async load(id) {
|
|
1421
1429
|
if (id === 'virtual:rari-entry-client') {
|
|
1422
1430
|
const srcDir = path.join(process.cwd(), 'src')
|
|
1423
|
-
const scannedClientComponents = scanForClientComponents(srcDir)
|
|
1431
|
+
const scannedClientComponents = scanForClientComponents(srcDir, Object.values(resolvedAlias))
|
|
1424
1432
|
|
|
1425
1433
|
const allClientComponents = new Set([
|
|
1426
1434
|
...clientComponents,
|
package/src/vite/server-build.ts
CHANGED
|
@@ -377,19 +377,145 @@ export class ServerComponentBuilder {
|
|
|
377
377
|
}
|
|
378
378
|
|
|
379
379
|
private transformComponentImportsToGlobal(code: string): string {
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
380
|
+
const importRegex = /import\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g
|
|
381
|
+
const replacements: Array<{ original: string, replacement: string }> = []
|
|
382
|
+
|
|
383
|
+
for (const match of code.matchAll(importRegex)) {
|
|
384
|
+
const [fullMatch, importName, importPath] = match
|
|
385
|
+
|
|
386
|
+
if (!importPath.startsWith('.') && !importPath.startsWith('@') && !importPath.startsWith('~') && !importPath.startsWith('#'))
|
|
387
|
+
continue
|
|
388
|
+
|
|
389
|
+
let resolvedPath: string | null = null
|
|
390
|
+
|
|
391
|
+
if (importPath.startsWith('.')) {
|
|
392
|
+
if (importPath.includes('/components/')) {
|
|
393
|
+
const componentMatch = importPath.match(/\/components\/(\w+)(?:\.tsx?|\.jsx?)?$/)
|
|
394
|
+
if (componentMatch) {
|
|
395
|
+
const componentName = componentMatch[1]
|
|
396
|
+
|
|
397
|
+
const possiblePaths = [
|
|
398
|
+
path.resolve(this.projectRoot, 'src', 'components', `${componentName}.tsx`),
|
|
399
|
+
path.resolve(this.projectRoot, 'src', 'components', `${componentName}.ts`),
|
|
400
|
+
path.resolve(this.projectRoot, 'src', 'components', `${componentName}.jsx`),
|
|
401
|
+
path.resolve(this.projectRoot, 'src', 'components', `${componentName}.js`),
|
|
402
|
+
]
|
|
403
|
+
|
|
404
|
+
let isClient = false
|
|
405
|
+
for (const possiblePath of possiblePaths) {
|
|
406
|
+
if (fs.existsSync(possiblePath) && this.isClientComponent(possiblePath)) {
|
|
407
|
+
isClient = true
|
|
408
|
+
break
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (!isClient)
|
|
413
|
+
continue
|
|
414
|
+
|
|
415
|
+
const replacement = `// Component reference: ${componentName}
|
|
383
416
|
const ${importName} = (props) => {
|
|
384
|
-
|
|
417
|
+
let Component = globalThis['~rsc']?.components?.['components/${componentName}']
|
|
385
418
|
|| globalThis['~rsc']?.modules?.['components/${componentName}']?.default
|
|
386
419
|
|| globalThis['components/${componentName}'];
|
|
420
|
+
|
|
421
|
+
if (Component && typeof Component === 'object' && Component.default) {
|
|
422
|
+
Component = Component.default;
|
|
423
|
+
}
|
|
424
|
+
|
|
387
425
|
if (!Component) {
|
|
388
426
|
throw new Error('Component components/${componentName} not loaded');
|
|
389
427
|
}
|
|
428
|
+
|
|
429
|
+
if (typeof Component !== 'function') {
|
|
430
|
+
throw new Error('Component components/${componentName} is not a function, got: ' + typeof Component);
|
|
431
|
+
}
|
|
432
|
+
|
|
390
433
|
return Component(props);
|
|
391
434
|
}`
|
|
392
|
-
|
|
435
|
+
replacements.push({ original: fullMatch, replacement })
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
continue
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const aliases = this.options.alias || {}
|
|
442
|
+
for (const [alias, replacement] of Object.entries(aliases)) {
|
|
443
|
+
if (importPath.startsWith(`${alias}/`) || importPath === alias) {
|
|
444
|
+
const relativePath = importPath.slice(alias.length)
|
|
445
|
+
resolvedPath = path.join(replacement, relativePath)
|
|
446
|
+
break
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (resolvedPath) {
|
|
451
|
+
const componentMatch = resolvedPath.match(/[/\\]components[/\\](\w+)(?:\.tsx?|\.jsx?)?$/)
|
|
452
|
+
if (componentMatch) {
|
|
453
|
+
const componentName = componentMatch[1]
|
|
454
|
+
|
|
455
|
+
const absolutePath = path.isAbsolute(resolvedPath)
|
|
456
|
+
? resolvedPath
|
|
457
|
+
: path.resolve(this.projectRoot, resolvedPath)
|
|
458
|
+
|
|
459
|
+
const possiblePaths = [
|
|
460
|
+
absolutePath,
|
|
461
|
+
`${absolutePath}.tsx`,
|
|
462
|
+
`${absolutePath}.ts`,
|
|
463
|
+
`${absolutePath}.jsx`,
|
|
464
|
+
`${absolutePath}.js`,
|
|
465
|
+
]
|
|
466
|
+
|
|
467
|
+
let isClient = false
|
|
468
|
+
let actualPath = absolutePath
|
|
469
|
+
for (const possiblePath of possiblePaths) {
|
|
470
|
+
if (fs.existsSync(possiblePath)) {
|
|
471
|
+
actualPath = possiblePath
|
|
472
|
+
if (this.isClientComponent(possiblePath))
|
|
473
|
+
isClient = true
|
|
474
|
+
break
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
if (!isClient)
|
|
479
|
+
continue
|
|
480
|
+
|
|
481
|
+
const relativeFromRoot = path.relative(this.projectRoot, actualPath)
|
|
482
|
+
const componentId = relativeFromRoot
|
|
483
|
+
.replace(/\\/g, '/')
|
|
484
|
+
.replace(/\.(tsx?|\.jsx?)$/, '')
|
|
485
|
+
.replace(/[^\w/-]/g, '_')
|
|
486
|
+
.replace(/^src\//, '')
|
|
487
|
+
|
|
488
|
+
const replacement = `// Component reference: ${componentName}
|
|
489
|
+
const ${importName} = (props) => {
|
|
490
|
+
let Component = globalThis['~rsc']?.components?.['${componentId}']
|
|
491
|
+
|| globalThis['~rsc']?.modules?.['${componentId}']?.default
|
|
492
|
+
|| globalThis['${componentId}'];
|
|
493
|
+
|
|
494
|
+
if (Component && typeof Component === 'object' && Component.default) {
|
|
495
|
+
Component = Component.default;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (!Component) {
|
|
499
|
+
throw new Error('Component ${componentId} not loaded');
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
if (typeof Component !== 'function') {
|
|
503
|
+
throw new Error('Component ${componentId} is not a function, got: ' + typeof Component);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
return Component(props);
|
|
507
|
+
}`
|
|
508
|
+
replacements.push({ original: fullMatch, replacement })
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
let transformedCode = code
|
|
514
|
+
for (const { original, replacement } of replacements) {
|
|
515
|
+
transformedCode = transformedCode.replace(original, replacement)
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
return transformedCode
|
|
393
519
|
}
|
|
394
520
|
|
|
395
521
|
private isPageComponent(inputPath: string): boolean {
|
|
@@ -466,6 +592,7 @@ const ${importName} = (props) => {
|
|
|
466
592
|
{
|
|
467
593
|
name: 'resolve-aliases',
|
|
468
594
|
setup: (build) => {
|
|
595
|
+
const self = this
|
|
469
596
|
const aliases = this.options.alias || {}
|
|
470
597
|
for (const [alias, replacement] of Object.entries(aliases)) {
|
|
471
598
|
const escapedAlias = alias.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
@@ -479,7 +606,7 @@ const ${importName} = (props) => {
|
|
|
479
606
|
for (const ext of possibleExtensions) {
|
|
480
607
|
const pathWithExt = resolvedPath + ext
|
|
481
608
|
if (fs.existsSync(pathWithExt) && fs.statSync(pathWithExt).isFile()) {
|
|
482
|
-
if (
|
|
609
|
+
if (self.isClientComponent(pathWithExt)) {
|
|
483
610
|
return { path: args.path, external: true }
|
|
484
611
|
}
|
|
485
612
|
|
|
@@ -518,10 +645,20 @@ const ${importName} = (props) => {
|
|
|
518
645
|
},
|
|
519
646
|
{
|
|
520
647
|
name: 'hmr-auto-external',
|
|
521
|
-
setup(build) {
|
|
648
|
+
setup: (build) => {
|
|
649
|
+
const self = this
|
|
522
650
|
build.onResolve({ filter: /.*/ }, async (args) => {
|
|
523
651
|
if (args.path.includes('../components/') || args.path.includes('./components/')) {
|
|
524
|
-
|
|
652
|
+
const resolvedPath = path.resolve(args.resolveDir, args.path)
|
|
653
|
+
const possibleExtensions = ['', '.ts', '.tsx', '.js', '.jsx']
|
|
654
|
+
|
|
655
|
+
for (const ext of possibleExtensions) {
|
|
656
|
+
const pathWithExt = resolvedPath + ext
|
|
657
|
+
if (fs.existsSync(pathWithExt) && fs.statSync(pathWithExt).isFile()) {
|
|
658
|
+
if (self.isClientComponent(pathWithExt))
|
|
659
|
+
return { path: args.path, namespace: 'component-stub' }
|
|
660
|
+
}
|
|
661
|
+
}
|
|
525
662
|
}
|
|
526
663
|
|
|
527
664
|
if (args.path === 'react' || args.path === 'react-dom' || args.path === 'react/jsx-runtime' || args.path === 'react/jsx-dev-runtime')
|
|
@@ -655,6 +792,36 @@ const ${importName} = (props) => {
|
|
|
655
792
|
}
|
|
656
793
|
|
|
657
794
|
for (const [filePath, component] of this.serverComponents) {
|
|
795
|
+
if (this.isPageComponent(filePath))
|
|
796
|
+
continue
|
|
797
|
+
|
|
798
|
+
const relativePath = path.relative(this.projectRoot, filePath)
|
|
799
|
+
const componentId = this.getComponentId(relativePath)
|
|
800
|
+
const bundlePath = path.join(this.options.serverDir, `${componentId}.js`)
|
|
801
|
+
const fullBundlePath = path.join(this.options.outDir, bundlePath)
|
|
802
|
+
|
|
803
|
+
const bundleDir = path.dirname(fullBundlePath)
|
|
804
|
+
await fs.promises.mkdir(bundleDir, { recursive: true })
|
|
805
|
+
|
|
806
|
+
await this.buildSingleComponent(filePath, fullBundlePath, component)
|
|
807
|
+
|
|
808
|
+
const moduleSpecifier = `file://${path.resolve(this.projectRoot, fullBundlePath)}`
|
|
809
|
+
|
|
810
|
+
manifest.components[componentId] = {
|
|
811
|
+
id: componentId,
|
|
812
|
+
filePath,
|
|
813
|
+
relativePath,
|
|
814
|
+
bundlePath,
|
|
815
|
+
moduleSpecifier,
|
|
816
|
+
dependencies: component.dependencies,
|
|
817
|
+
hasNodeImports: component.hasNodeImports,
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
for (const [filePath, component] of this.serverComponents) {
|
|
822
|
+
if (!this.isPageComponent(filePath))
|
|
823
|
+
continue
|
|
824
|
+
|
|
658
825
|
const relativePath = path.relative(this.projectRoot, filePath)
|
|
659
826
|
const componentId = this.getComponentId(relativePath)
|
|
660
827
|
const bundlePath = path.join(this.options.serverDir, `${componentId}.js`)
|
|
@@ -827,7 +994,10 @@ const ${importName} = (props) => {
|
|
|
827
994
|
continue
|
|
828
995
|
if (trimmed === '\'use server\'' || trimmed === '"use server"'
|
|
829
996
|
|| trimmed === '\'use server\';' || trimmed === '"use server";') {
|
|
830
|
-
return {
|
|
997
|
+
return {
|
|
998
|
+
path: args.path,
|
|
999
|
+
namespace: 'server-action-reference',
|
|
1000
|
+
}
|
|
831
1001
|
}
|
|
832
1002
|
if (trimmed)
|
|
833
1003
|
break
|
|
@@ -840,11 +1010,116 @@ const ${importName} = (props) => {
|
|
|
840
1010
|
}
|
|
841
1011
|
return null
|
|
842
1012
|
})
|
|
1013
|
+
|
|
1014
|
+
build.onLoad({ filter: /.*/, namespace: 'server-action-reference' }, (args) => {
|
|
1015
|
+
const aliases = this.options.alias || {}
|
|
1016
|
+
let resolvedPath = args.path
|
|
1017
|
+
|
|
1018
|
+
for (const [alias, replacement] of Object.entries(aliases)) {
|
|
1019
|
+
if (args.path.startsWith(`${alias}/`) || args.path === alias) {
|
|
1020
|
+
const relativePath = args.path.slice(alias.length)
|
|
1021
|
+
const fullPath = path.isAbsolute(replacement)
|
|
1022
|
+
? path.join(replacement, relativePath)
|
|
1023
|
+
: path.resolve(this.projectRoot, replacement, relativePath)
|
|
1024
|
+
|
|
1025
|
+
resolvedPath = path.relative(this.projectRoot, fullPath)
|
|
1026
|
+
break
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
const contents = `export * from "./${resolvedPath}";`
|
|
1031
|
+
|
|
1032
|
+
return {
|
|
1033
|
+
contents,
|
|
1034
|
+
loader: 'js',
|
|
1035
|
+
resolveDir: this.projectRoot,
|
|
1036
|
+
}
|
|
1037
|
+
})
|
|
1038
|
+
},
|
|
1039
|
+
},
|
|
1040
|
+
{
|
|
1041
|
+
name: 'use-transformed-server-components',
|
|
1042
|
+
setup: (build) => {
|
|
1043
|
+
if (!isPage)
|
|
1044
|
+
return
|
|
1045
|
+
|
|
1046
|
+
const self = this
|
|
1047
|
+
const aliases = self.options.alias || {}
|
|
1048
|
+
|
|
1049
|
+
build.onResolve({ filter: /^file:\/\// }, (args) => {
|
|
1050
|
+
const filePath = args.path.replace(/^file:\/\//, '')
|
|
1051
|
+
if (fs.existsSync(filePath)) {
|
|
1052
|
+
return {
|
|
1053
|
+
path: filePath,
|
|
1054
|
+
namespace: 'transformed-server-component',
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
return null
|
|
1058
|
+
})
|
|
1059
|
+
|
|
1060
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
1061
|
+
let resolvedPath: string | null = null
|
|
1062
|
+
|
|
1063
|
+
for (const [alias, replacement] of Object.entries(aliases)) {
|
|
1064
|
+
if (args.path.startsWith(`${alias}/`) || args.path === alias) {
|
|
1065
|
+
const relativePath = args.path.slice(alias.length)
|
|
1066
|
+
const newPath = path.join(replacement, relativePath)
|
|
1067
|
+
resolvedPath = path.isAbsolute(newPath) ? newPath : path.resolve(args.resolveDir, newPath)
|
|
1068
|
+
break
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
if (!resolvedPath && (args.path.startsWith('./') || args.path.startsWith('../')))
|
|
1073
|
+
resolvedPath = path.resolve(args.resolveDir, args.path)
|
|
1074
|
+
|
|
1075
|
+
if (!resolvedPath)
|
|
1076
|
+
return null
|
|
1077
|
+
|
|
1078
|
+
if (args.resolveDir.includes('node_modules'))
|
|
1079
|
+
return null
|
|
1080
|
+
|
|
1081
|
+
const possibleExtensions = ['', '.ts', '.tsx', '.js', '.jsx']
|
|
1082
|
+
for (const ext of possibleExtensions) {
|
|
1083
|
+
const pathWithExt = resolvedPath + ext
|
|
1084
|
+
if (fs.existsSync(pathWithExt) && fs.statSync(pathWithExt).isFile()) {
|
|
1085
|
+
if (self.isClientComponent(pathWithExt))
|
|
1086
|
+
return null
|
|
1087
|
+
|
|
1088
|
+
const srcDir = path.join(self.projectRoot, 'src')
|
|
1089
|
+
if (!pathWithExt.startsWith(srcDir))
|
|
1090
|
+
return null
|
|
1091
|
+
|
|
1092
|
+
const relativePath = path.relative(srcDir, pathWithExt)
|
|
1093
|
+
const distPath = path.join(self.projectRoot, 'dist', 'server', relativePath.replace(/\.(tsx?|jsx?)$/, '.js'))
|
|
1094
|
+
|
|
1095
|
+
if (fs.existsSync(distPath)) {
|
|
1096
|
+
return {
|
|
1097
|
+
path: distPath,
|
|
1098
|
+
namespace: 'transformed-server-component',
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
break
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
return null
|
|
1107
|
+
})
|
|
1108
|
+
|
|
1109
|
+
build.onLoad({ filter: /.*/, namespace: 'transformed-server-component' }, (args) => {
|
|
1110
|
+
const contents = fs.readFileSync(args.path, 'utf-8')
|
|
1111
|
+
return {
|
|
1112
|
+
contents,
|
|
1113
|
+
loader: 'js',
|
|
1114
|
+
resolveDir: path.dirname(args.path),
|
|
1115
|
+
}
|
|
1116
|
+
})
|
|
843
1117
|
},
|
|
844
1118
|
},
|
|
845
1119
|
{
|
|
846
1120
|
name: 'resolve-aliases',
|
|
847
1121
|
setup: (build) => {
|
|
1122
|
+
const self = this
|
|
848
1123
|
const aliases = this.options.alias || {}
|
|
849
1124
|
for (const [alias, replacement] of Object.entries(aliases)) {
|
|
850
1125
|
const escapedAlias = alias.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
@@ -857,13 +1132,81 @@ const ${importName} = (props) => {
|
|
|
857
1132
|
const possibleExtensions = ['', '.ts', '.tsx', '.js', '.jsx']
|
|
858
1133
|
for (const ext of possibleExtensions) {
|
|
859
1134
|
const pathWithExt = resolvedPath + ext
|
|
860
|
-
if (fs.existsSync(pathWithExt) && fs.statSync(pathWithExt).isFile())
|
|
1135
|
+
if (fs.existsSync(pathWithExt) && fs.statSync(pathWithExt).isFile()) {
|
|
1136
|
+
if (self.isClientComponent(pathWithExt)) {
|
|
1137
|
+
return {
|
|
1138
|
+
path: args.path,
|
|
1139
|
+
namespace: 'client-component-reference',
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
try {
|
|
1144
|
+
const content = fs.readFileSync(pathWithExt, 'utf-8')
|
|
1145
|
+
const hasUseServer = content.includes('\'use server\'') || content.includes('"use server"')
|
|
1146
|
+
if (hasUseServer) {
|
|
1147
|
+
return { path: args.path, external: true }
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
catch {}
|
|
1151
|
+
|
|
861
1152
|
return { path: pathWithExt }
|
|
1153
|
+
}
|
|
862
1154
|
}
|
|
863
1155
|
|
|
864
1156
|
return { path: resolvedPath }
|
|
865
1157
|
})
|
|
866
1158
|
}
|
|
1159
|
+
|
|
1160
|
+
build.onLoad({ filter: /.*/, namespace: 'client-component-reference' }, (args) => {
|
|
1161
|
+
let componentId = args.path
|
|
1162
|
+
|
|
1163
|
+
for (const [alias, replacement] of Object.entries(aliases)) {
|
|
1164
|
+
if (args.path.startsWith(`${alias}/`) || args.path === alias) {
|
|
1165
|
+
const relativePath = args.path.slice(alias.length)
|
|
1166
|
+
const resolvedPath = path.isAbsolute(replacement)
|
|
1167
|
+
? path.join(replacement, relativePath)
|
|
1168
|
+
: path.resolve(self.projectRoot, replacement, relativePath)
|
|
1169
|
+
|
|
1170
|
+
componentId = path.relative(self.projectRoot, resolvedPath)
|
|
1171
|
+
break
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
const contents = `
|
|
1176
|
+
function registerClientReference(clientReference, id, exportName) {
|
|
1177
|
+
const key = id + '#' + exportName;
|
|
1178
|
+
const clientProxy = {};
|
|
1179
|
+
Object.defineProperty(clientProxy, '$$typeof', {
|
|
1180
|
+
value: Symbol.for('react.client.reference'),
|
|
1181
|
+
enumerable: false
|
|
1182
|
+
});
|
|
1183
|
+
Object.defineProperty(clientProxy, '$$id', {
|
|
1184
|
+
value: key,
|
|
1185
|
+
enumerable: false
|
|
1186
|
+
});
|
|
1187
|
+
Object.defineProperty(clientProxy, '$$async', {
|
|
1188
|
+
value: false,
|
|
1189
|
+
enumerable: false
|
|
1190
|
+
});
|
|
1191
|
+
try {
|
|
1192
|
+
if (typeof globalThis['~rari']?.bridge !== 'undefined' &&
|
|
1193
|
+
typeof globalThis['~rari'].bridge.registerClientReference === 'function') {
|
|
1194
|
+
globalThis['~rari'].bridge.registerClientReference(key, id, exportName);
|
|
1195
|
+
}
|
|
1196
|
+
} catch (error) {
|
|
1197
|
+
console.error('[rari] Build: Failed to register client reference:', error);
|
|
1198
|
+
}
|
|
1199
|
+
return clientProxy;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
export default registerClientReference(null, ${JSON.stringify(componentId)}, "default");
|
|
1203
|
+
`
|
|
1204
|
+
|
|
1205
|
+
return {
|
|
1206
|
+
contents,
|
|
1207
|
+
loader: 'js',
|
|
1208
|
+
}
|
|
1209
|
+
})
|
|
867
1210
|
},
|
|
868
1211
|
},
|
|
869
1212
|
{
|
|
@@ -957,37 +1300,7 @@ const ${importName} = (props) => {
|
|
|
957
1300
|
|
|
958
1301
|
code = code.replace(
|
|
959
1302
|
/import\s*(\{[^}]+\}|\w+)\s*from\s*["']([^"']+)["'];?/g,
|
|
960
|
-
(match
|
|
961
|
-
if (importPath.startsWith('file://') || importPath.startsWith('npm:'))
|
|
962
|
-
return match
|
|
963
|
-
|
|
964
|
-
if (importPath.startsWith('node:') || isNodeBuiltin(importPath)
|
|
965
|
-
|| importPath === 'react' || importPath === 'react-dom'
|
|
966
|
-
|| importPath === 'react/jsx-runtime' || importPath === 'react/jsx-dev-runtime') {
|
|
967
|
-
return match
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
let resolvedPath: string | null = null
|
|
971
|
-
|
|
972
|
-
const aliases = this.options.alias || {}
|
|
973
|
-
for (const [alias, replacement] of Object.entries(aliases)) {
|
|
974
|
-
if (importPath.startsWith(`${alias}/`) || importPath === alias) {
|
|
975
|
-
const relativePath = importPath.slice(alias.length)
|
|
976
|
-
const newPath = path.join(replacement, relativePath)
|
|
977
|
-
resolvedPath = path.isAbsolute(newPath) ? newPath : path.resolve(this.projectRoot, newPath)
|
|
978
|
-
break
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
if (resolvedPath) {
|
|
983
|
-
const relativeToProject = path.relative(this.projectRoot, resolvedPath)
|
|
984
|
-
const componentId = this.getComponentId(relativeToProject)
|
|
985
|
-
const bundlePath = path.join(this.options.outDir, this.options.serverDir, `${componentId}.js`)
|
|
986
|
-
const fileUrl = `file://${path.resolve(this.projectRoot, bundlePath)}`
|
|
987
|
-
|
|
988
|
-
return `import ${imports} from "${fileUrl}";`
|
|
989
|
-
}
|
|
990
|
-
|
|
1303
|
+
(match) => {
|
|
991
1304
|
return match
|
|
992
1305
|
},
|
|
993
1306
|
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e,r as t,t as n}from"./server-build-Dcu2KENc.mjs";export{n as ServerComponentBuilder,t as scanDirectory};
|
|
@@ -1,124 +0,0 @@
|
|
|
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(`
|
|
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
|
-
`);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(e){return e.replace(/import\s+(\w+)\s+from\s+['"]\.\.\/components\/(\w+)(?:\.tsx?|\.jsx?)?['"]/g,(e,t,n)=>`// Component reference: ${n}
|
|
4
|
-
const ${t} = (props) => {
|
|
5
|
-
const Component = globalThis['~rsc']?.components?.['components/${n}']
|
|
6
|
-
|| globalThis['~rsc']?.modules?.['components/${n}']?.default
|
|
7
|
-
|| globalThis['components/${n}'];
|
|
8
|
-
if (!Component) {
|
|
9
|
-
throw new Error('Component components/${n} not loaded');
|
|
10
|
-
}
|
|
11
|
-
return Component(props);
|
|
12
|
-
}`)}isPageComponent(e){return e.includes(`/app/`)||e.includes(`\\app\\`)}async buildComponentCodeOnly(n,a,o){let s=await e.promises.readFile(n,`utf-8`),c=this.transformClientImports(s,n),l=this.isPageComponent(n)?this.transformComponentImportsToGlobal(c):c,u=t.extname(n),d;d=u===`.tsx`?`tsx`:u===`.ts`?`ts`:u===`.jsx`?`jsx`:`js`;try{let a=await r({stdin:{contents:l,resolveDir:t.dirname(n),sourcefile:n,loader:d},bundle:!0,platform:`node`,target:`es2022`,format:`esm`,mainFields:[`module`,`main`],conditions:[`import`,`module`,`default`],jsx:`transform`,jsxFactory:`React.createElement`,jsxFragment:`React.Fragment`,define:{global:`globalThis`,"process.env.NODE_ENV":`"production"`,...this.options.define},loader:{".ts":`ts`,".tsx":`tsx`,".js":`js`,".jsx":`jsx`},resolveExtensions:[`.ts`,`.tsx`,`.js`,`.jsx`],minify:!1,minifyWhitespace:!0,minifyIdentifiers:!0,minifySyntax:!0,sourcemap:!1,metafile:!1,write:!1,plugins:[{name:`resolve-aliases`,setup:n=>{let r=this.options.alias||{};for(let[i,a]of Object.entries(r)){let r=i.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),o=RegExp(`^${r}(/|$)`);n.onResolve({filter:o},n=>{let r=n.path.slice(i.length),o=t.join(a,r),s=t.isAbsolute(o)?o:t.resolve(n.resolveDir,o);for(let t of[``,`.ts`,`.tsx`,`.js`,`.jsx`]){let r=s+t;if(e.existsSync(r)&&e.statSync(r).isFile()){if(this.isClientComponent(r))return{path:n.path,external:!0};try{let t=e.readFileSync(r,`utf-8`);if(t.includes(`'use server'`)||t.includes(`"use server"`))return{path:n.path,external:!0}}catch{}return{path:r}}}return{path:s}})}}},{name:`replace-react-imports`,setup(e){e.onLoad({filter:/runtime-client.*\.js$/},async e=>{let t=await(await import(`node:fs/promises`)).readFile(e.path,`utf-8`);return t=t.replace(/import\s+React\d*(?:\s*,\s*\{[^}]*\})?\s+from\s+['"]react['"];?/g,`// React is available as globalThis.React`),t=t.replace(/React2/g,`React`),{contents:t,loader:`js`}})}},{name:`hmr-auto-external`,setup(n){n.onResolve({filter:/.*/},async n=>{if(n.path.includes(`../components/`)||n.path.includes(`./components/`))return{path:n.path,namespace:`component-stub`};if(n.path===`react`||n.path===`react-dom`||n.path===`react/jsx-runtime`||n.path===`react/jsx-dev-runtime`||n.path.startsWith(`node:`)||i(n.path)||n.path===`rari/image`||n.path.startsWith(`rari/image/`))return{path:n.path,external:!0};if(n.path===`rari/client`)return null;if(n.path.startsWith(`@/actions/`)||n.path.includes(`/actions/`)){let r=t.resolve(n.resolveDir,n.path);for(let t of[``,`.ts`,`.tsx`,`.js`,`.jsx`]){let i=r+t;if(e.existsSync(i)){try{let t=e.readFileSync(i,`utf-8`);if(t.includes(`'use server'`)||t.includes(`"use server"`))return{path:n.path,external:!0}}catch{}break}}}return null}),n.onLoad({filter:/.*/,namespace:`component-stub`},async e=>{let t=e.path.match(/\/components\/(\w+)/);return{contents:`// Component stub for ${t?t[1]:`Unknown`} - replaced by global reference`,loader:`js`}})}},{name:`resolve-server-functions`,setup(n){n.onResolve({filter:/^\.\.?\/.*(functions|actions)/},async n=>{let r=t.resolve(t.dirname(n.importer),n.path);for(let t of[`.ts`,`.js`,`.tsx`,`.jsx`,`/index.ts`,`/index.js`]){let n=r+t;if(e.existsSync(n))return{path:n}}return null})}}]});if(a.outputFiles&&a.outputFiles.length>0)return a.outputFiles[0].text;throw a.errors.length>0?(console.error(`[rari] Build: ESBuild errors:`,a.errors),Error(`ESBuild compilation failed with ${a.errors.length} errors`)):Error(`No output generated from ESBuild`)}catch(e){throw console.error(`[rari] Build: ESBuild failed for ${n}:`,e),e}}async buildServerComponents(){let n=t.join(this.options.outDir,this.options.serverDir);await e.promises.mkdir(n,{recursive:!0});let r={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`},i=this.options.alias||{};for(let[e,n]of Object.entries(i)){let i=t.isAbsolute(n)?n:t.resolve(this.projectRoot,n);r[`${e}/`]=`file://${i}/`}let a={components:{},importMap:{imports:r},version:`1.0.0`,buildTime:new Date().toISOString(),csp:this.options.csp,rateLimit:this.options.rateLimit,spamBlocker:this.options.spamBlocker};for(let[n,r]of this.serverComponents){let i=t.relative(this.projectRoot,n),o=this.getComponentId(i),s=t.join(this.options.serverDir,`${o}.js`),c=t.join(this.options.outDir,s),l=t.dirname(c);await e.promises.mkdir(l,{recursive:!0}),await this.buildSingleComponent(n,c,r);let u=`file://${t.resolve(this.projectRoot,c)}`;a.components[o]={id:o,filePath:n,relativePath:i,bundlePath:s,moduleSpecifier:u,dependencies:r.dependencies,hasNodeImports:r.hasNodeImports}}for(let[n,r]of this.serverActions){let i=t.relative(this.projectRoot,n),o=this.getComponentId(i),s=t.join(this.options.serverDir,`${o}.js`),c=t.join(this.options.outDir,s),l=t.dirname(c);await e.promises.mkdir(l,{recursive:!0}),await this.buildSingleComponent(n,c,r);let u=`file://${t.resolve(this.projectRoot,c)}`;a.components[o]={id:o,filePath:n,relativePath:i,bundlePath:s,moduleSpecifier:u,dependencies:r.dependencies,hasNodeImports:r.hasNodeImports}}let o=t.join(this.options.outDir,this.options.manifestPath);return await e.promises.writeFile(o,JSON.stringify(a,null,2),`utf-8`),a}async buildSingleComponent(n,a,o,s=!1){let c=await e.promises.readFile(n,`utf-8`),l=this.transformClientImports(c,n),u=this.isPageComponent(n)?this.transformComponentImportsToGlobal(l):l,d=t.extname(n),f;f=d===`.tsx`?`tsx`:d===`.ts`?`ts`:d===`.jsx`?`jsx`:`js`;try{let o=await r({stdin:{contents:u,resolveDir:t.dirname(n),sourcefile:n,loader:f},bundle:!0,platform:`node`,target:`es2022`,format:`esm`,outfile:a,mainFields:[`module`,`main`],conditions:[`import`,`module`,`default`],jsx:`transform`,jsxFactory:`React.createElement`,jsxFragment:`React.Fragment`,define:{global:`globalThis`,"process.env.NODE_ENV":`"production"`,...this.options.define},loader:{".ts":`ts`,".tsx":`tsx`,".js":`js`,".jsx":`jsx`},resolveExtensions:[`.ts`,`.tsx`,`.js`,`.jsx`],minify:this.options.minify,minifyWhitespace:this.options.minify,minifyIdentifiers:this.options.minify,minifySyntax:this.options.minify,sourcemap:!1,metafile:!1,write:!1,plugins:[{name:`external-server-actions`,setup:n=>{n.onResolve({filter:/.*/},async n=>{if(n.namespace!==`file`&&n.namespace!==``||n.path.startsWith(`node:`)||i(n.path)||n.path===`react`||n.path===`react-dom`||n.path===`react/jsx-runtime`||n.path===`react/jsx-dev-runtime`)return null;let r=null,a=this.options.alias||{};for(let[e,i]of Object.entries(a))if(n.path.startsWith(`${e}/`)||n.path===e){let a=n.path.slice(e.length),o=t.join(i,a);r=t.isAbsolute(o)?o:t.resolve(n.resolveDir,o);break}if(!r&&(n.path.startsWith(`./`)||n.path.startsWith(`../`))&&(r=t.resolve(n.resolveDir,n.path)),r)for(let t of[``,`.ts`,`.tsx`,`.js`,`.jsx`]){let i=r+t;if(e.existsSync(i)&&e.statSync(i).isFile()){try{let t=e.readFileSync(i,`utf-8`).split(`
|
|
13
|
-
`);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{path:n.path,external:!0};if(t)break}}}catch{}break}}return null})}},{name:`resolve-aliases`,setup:n=>{let r=this.options.alias||{};for(let[i,a]of Object.entries(r)){let r=i.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),o=RegExp(`^${r}(/|$)`);n.onResolve({filter:o},n=>{let r=n.path.slice(i.length),o=t.join(a,r),s=t.isAbsolute(o)?o:t.resolve(n.resolveDir,o);for(let t of[``,`.ts`,`.tsx`,`.js`,`.jsx`]){let n=s+t;if(e.existsSync(n)&&e.statSync(n).isFile())return{path:n}}return{path:s}})}}},{name:`replace-react-imports`,setup(e){e.onLoad({filter:/runtime-client.*\.js$/},async e=>{let t=await(await import(`node:fs/promises`)).readFile(e.path,`utf-8`);return t=t.replace(/import\s+React\d*(?:\s*,\s*\{[^}]*\})?\s+from\s+['"]react['"];?/g,`// React is available as globalThis.React`),t=t.replace(/React2/g,`React`),{contents:t,loader:`js`}})}},{name:`auto-external`,setup(e){e.onResolve({filter:/^[^./]/},async e=>e.path===`react`||e.path===`react-dom`||e.path===`react/jsx-runtime`||e.path===`react/jsx-dev-runtime`||e.path.startsWith(`node:`)||i(e.path)||e.path===`rari/image`||e.path.startsWith(`rari/image/`)?{path:e.path,external:!0}:(e.path,null))}},{name:`resolve-server-functions`,setup(n){n.onResolve({filter:/^\.\.?\/.*(functions|actions)/},async n=>{let r=t.resolve(t.dirname(n.importer),n.path);for(let t of[`.ts`,`.js`,`.tsx`,`.jsx`,`/index.ts`,`/index.js`]){let n=r+t;if(e.existsSync(n))return{path:n}}return null})}}]});if(o.outputFiles&&o.outputFiles.length>0){let n=o.outputFiles[0].text;if(n=n.replace(/import\s+\{[^}]*\}\s+from\s+['"]react\/jsx-runtime['"];?\s*/g,`// jsx/jsxs are available as globals
|
|
14
|
-
`),n=n.replace(/import\s+\{[^}]*\}\s+from\s+['"]react\/jsx-dev-runtime['"];?\s*/g,`// jsx/jsxs are available as globals
|
|
15
|
-
`),n=n.replace(/import\s+React\d*(?:\s*,\s*\{[^}]*\})?\s+from\s+['"]react['"];?\s*/g,`// React is available as globalThis.React
|
|
16
|
-
`),n=n.replace(/import\s+\{[^}]*\}\s+from\s+['"]react['"];?\s*/g,`// React is available as globalThis.React
|
|
17
|
-
`),n=n.replace(/import\s*(\{[^}]+\}|\w+)\s*from\s*["']([^"']+)["'];?/g,(e,n,r)=>{if(r.startsWith(`file://`)||r.startsWith(`npm:`)||r.startsWith(`node:`)||i(r)||r===`react`||r===`react-dom`||r===`react/jsx-runtime`||r===`react/jsx-dev-runtime`)return e;let a=null,o=this.options.alias||{};for(let[e,n]of Object.entries(o))if(r.startsWith(`${e}/`)||r===e){let i=r.slice(e.length),o=t.join(n,i);a=t.isAbsolute(o)?o:t.resolve(this.projectRoot,o);break}if(a){let e=t.relative(this.projectRoot,a),r=this.getComponentId(e),i=t.join(this.options.outDir,this.options.serverDir,`${r}.js`);return`import ${n} from "${`file://${t.resolve(this.projectRoot,i)}`}";`}return e}),await e.promises.writeFile(a,n,`utf-8`),s)return n}if(o.errors.length>0)throw console.error(`[rari] Build: ESBuild errors:`,o.errors),Error(`ESBuild compilation failed with ${o.errors.length} errors`);o.warnings.length>0&&console.warn(`[rari] Build: ESBuild warnings:`,o.warnings)}catch(e){throw console.error(`[rari] Build: ESBuild failed for ${n}:`,e),e}}createSelfRegisteringModule(e,t){if(e.includes(`Self-registering Production Component`))return e;let n=e,r=null,i=[];if(n=n.replace(/^export\s+default\s+function\s+(\w+)/gm,(e,t)=>(r=t,`function ${t}`)),n=n.replace(/^export\s+default\s+async\s+function\s+(\w+)/gm,(e,t)=>(r=t,`async function ${t}`)),n=n.replace(/^export\s+default\s+(\w+);?\s*$/gm,(e,t)=>(r=t,`// Default export: ${t}`)),n=n.replace(/^export\s*\{\s*(\w+)\s+as\s+default\s*\};?\s*$/gm,(e,t)=>(r=t,`// Default export: ${t}`)),n=n.replace(/^export\s*\{([^}]+)\};?\s*$/gm,(e,a)=>{let o=a.split(`,`).map(e=>e.trim()),s=[];return o.forEach(e=>{if(e.includes(`as default`)){let t=e.replace(`as default`,``).trim();r=t,s.push(`${t} (default)`)}else if(e===`default`){let e=`${t}_default`;n.includes(`var ${e}`)&&(r=e),s.push(`default`)}else i.push(e),s.push(e)}),`// Exports: ${s.join(`, `)}`}),n=n.replace(/^export\s+(?:async\s+)?function\s+(\w+)/gm,(e,t)=>(i.push(t),e.replace(`export `,``))),n=n.replace(/^export\s+(const|let|var)\s+(\w+)/gm,(e,t,n)=>(i.push(n),`${t} ${n}`)),!r){let e=`${t}_default`;n.includes(`var ${e}`)&&(r=e)}return`// Self-registering Production Component: ${t}
|
|
18
|
-
|
|
19
|
-
if (!globalThis["${t}"]) {
|
|
20
|
-
${n}
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
const moduleKey = "${t}";
|
|
24
|
-
let mainExport = null;
|
|
25
|
-
const exportedFunctions = {};
|
|
26
|
-
|
|
27
|
-
if (!globalThis['~serverFunctions']) globalThis['~serverFunctions'] = {};
|
|
28
|
-
if (!globalThis['~serverFunctions'].all) globalThis['~serverFunctions'].all = {};
|
|
29
|
-
|
|
30
|
-
${i.map(e=>`if (typeof ${e} !== 'undefined') {
|
|
31
|
-
globalThis.${e} = ${e};
|
|
32
|
-
globalThis['~serverFunctions'].all['${e}'] = ${e};
|
|
33
|
-
exportedFunctions['${e}'] = ${e};
|
|
34
|
-
}`).join(`
|
|
35
|
-
`)}
|
|
36
|
-
|
|
37
|
-
${r?`if (typeof ${r} !== 'undefined') {
|
|
38
|
-
mainExport = ${r};
|
|
39
|
-
}`:``}
|
|
40
|
-
|
|
41
|
-
if (mainExport === null && Object.keys(exportedFunctions).length > 0) {
|
|
42
|
-
if (Object.keys(exportedFunctions).length === 1) {
|
|
43
|
-
mainExport = exportedFunctions[Object.keys(exportedFunctions)[0]];
|
|
44
|
-
} else {
|
|
45
|
-
let componentFunction = null;
|
|
46
|
-
let firstFunction = null;
|
|
47
|
-
|
|
48
|
-
for (const [name, value] of Object.entries(exportedFunctions)) {
|
|
49
|
-
if (typeof value === 'function') {
|
|
50
|
-
if (!firstFunction) firstFunction = value;
|
|
51
|
-
if (/^[A-Z]/.test(name)) {
|
|
52
|
-
componentFunction = value;
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
mainExport = componentFunction || firstFunction;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (mainExport !== null) {
|
|
63
|
-
if (!globalThis[moduleKey]) {
|
|
64
|
-
globalThis[moduleKey] = mainExport;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (!globalThis['~rsc']) globalThis['~rsc'] = {};
|
|
68
|
-
globalThis['~rsc'].components = globalThis['~rsc'].components || {};
|
|
69
|
-
globalThis['~rsc'].components[moduleKey] = mainExport;
|
|
70
|
-
|
|
71
|
-
globalThis['~rsc'].modules = globalThis['~rsc'].modules || {};
|
|
72
|
-
globalThis['~rsc'].modules[moduleKey] = { default: mainExport, ...exportedFunctions };
|
|
73
|
-
|
|
74
|
-
if (typeof globalThis.RscModuleManager !== 'undefined' && globalThis.RscModuleManager.register) {
|
|
75
|
-
globalThis.RscModuleManager.register(moduleKey, mainExport, exportedFunctions);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
} catch (error) {
|
|
79
|
-
console.error('[rari] Build: Error in self-registration for ${t}:', error);
|
|
80
|
-
}
|
|
81
|
-
}`}transformClientImports(e,n){let r=e,i=/import\s+(?:(\w+)|\{([^}]+)\})\s+from\s+['"]([^'"]+)['"];?\s*$/gm,a,o=[],s=!1,c=[`rari/image`];for(;a=i.exec(e),a!==null;){let[e,r,i,l]=a,u=!1,d=l;if(c.includes(l))u=!0;else{let e=this.resolveImportPath(l,n);this.isClientComponent(e)&&(u=!0,d=t.relative(this.projectRoot,e))}if(u){s=!0;let t=``;r?t=`const ${r} = registerClientReference(
|
|
82
|
-
null,
|
|
83
|
-
${JSON.stringify(d)},
|
|
84
|
-
"default"
|
|
85
|
-
);`:i&&(t=i.split(`,`).map(e=>e.trim()).map(e=>{let[t,n]=e.includes(` as `)?e.split(` as `).map(e=>e.trim()):[e,e];return`const ${n} = registerClientReference(
|
|
86
|
-
null,
|
|
87
|
-
${JSON.stringify(d)},
|
|
88
|
-
${JSON.stringify(t)}
|
|
89
|
-
);`}).join(`
|
|
90
|
-
`)),o.push({original:e,replacement:t})}}s&&(r=`
|
|
91
|
-
function registerClientReference(clientReference, id, exportName) {
|
|
92
|
-
const key = id + '#' + exportName;
|
|
93
|
-
|
|
94
|
-
const clientProxy = {};
|
|
95
|
-
|
|
96
|
-
Object.defineProperty(clientProxy, '$$typeof', {
|
|
97
|
-
value: Symbol.for('react.client.reference'),
|
|
98
|
-
enumerable: false
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
Object.defineProperty(clientProxy, '$$id', {
|
|
102
|
-
value: key,
|
|
103
|
-
enumerable: false
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
Object.defineProperty(clientProxy, '$$async', {
|
|
107
|
-
value: false,
|
|
108
|
-
enumerable: false
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
if (typeof globalThis['~rari']?.bridge !== 'undefined' &&
|
|
113
|
-
typeof globalThis['~rari'].bridge.registerClientReference === 'function') {
|
|
114
|
-
globalThis['~rari'].bridge.registerClientReference(key, id, exportName);
|
|
115
|
-
}
|
|
116
|
-
} catch (error) {
|
|
117
|
-
console.error('[rari] Build: Failed to register client reference with Rust bridge:', error);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return clientProxy;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
`+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(`
|
|
124
|
-
`),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};
|