@jxrstudios/jxr 1.0.9 → 1.0.11
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/bin/jxr.js +6 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +57 -2
- package/dist/jxr-server-manager.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/jxr-server-manager.ts +57 -1
- package/zzz_react_template/App.tsx +43 -156
- package/zzz_react_template/components/ErrorBoundary.tsx +62 -0
- package/zzz_react_template/components/ManusDialog.tsx +85 -0
- package/zzz_react_template/components/Map.tsx +155 -0
- package/zzz_react_template/components/jxr/CodeEditor.tsx +313 -0
- package/zzz_react_template/components/jxr/FileExplorer.tsx +230 -0
- package/zzz_react_template/components/jxr/IDEShell.tsx +159 -0
- package/zzz_react_template/components/jxr/LandingPage.tsx +414 -0
- package/zzz_react_template/components/jxr/LivePreview.tsx +169 -0
- package/zzz_react_template/components/jxr/PerformanceDashboard.tsx +379 -0
- package/zzz_react_template/components/jxr/TopBar.tsx +149 -0
- package/zzz_react_template/components/ui/accordion.tsx +64 -0
- package/zzz_react_template/components/ui/alert-dialog.tsx +155 -0
- package/zzz_react_template/components/ui/alert.tsx +66 -0
- package/zzz_react_template/components/ui/aspect-ratio.tsx +9 -0
- package/zzz_react_template/components/ui/avatar.tsx +51 -0
- package/zzz_react_template/components/ui/badge.tsx +46 -0
- package/zzz_react_template/components/ui/breadcrumb.tsx +109 -0
- package/zzz_react_template/components/ui/button-group.tsx +83 -0
- package/zzz_react_template/components/ui/button.tsx +60 -0
- package/zzz_react_template/components/ui/calendar.tsx +211 -0
- package/zzz_react_template/components/ui/card.tsx +92 -0
- package/zzz_react_template/components/ui/carousel.tsx +239 -0
- package/zzz_react_template/components/ui/chart.tsx +355 -0
- package/zzz_react_template/components/ui/checkbox.tsx +30 -0
- package/zzz_react_template/components/ui/collapsible.tsx +31 -0
- package/zzz_react_template/components/ui/command.tsx +184 -0
- package/zzz_react_template/components/ui/context-menu.tsx +250 -0
- package/zzz_react_template/components/ui/dialog.tsx +209 -0
- package/zzz_react_template/components/ui/drawer.tsx +133 -0
- package/zzz_react_template/components/ui/dropdown-menu.tsx +255 -0
- package/zzz_react_template/components/ui/empty.tsx +104 -0
- package/zzz_react_template/components/ui/field.tsx +242 -0
- package/zzz_react_template/components/ui/form.tsx +168 -0
- package/zzz_react_template/components/ui/hover-card.tsx +42 -0
- package/zzz_react_template/components/ui/input-group.tsx +168 -0
- package/zzz_react_template/components/ui/input-otp.tsx +75 -0
- package/zzz_react_template/components/ui/input.tsx +70 -0
- package/zzz_react_template/components/ui/item.tsx +193 -0
- package/zzz_react_template/components/ui/kbd.tsx +28 -0
- package/zzz_react_template/components/ui/label.tsx +22 -0
- package/zzz_react_template/components/ui/menubar.tsx +274 -0
- package/zzz_react_template/components/ui/navigation-menu.tsx +168 -0
- package/zzz_react_template/components/ui/pagination.tsx +127 -0
- package/zzz_react_template/components/ui/popover.tsx +46 -0
- package/zzz_react_template/components/ui/progress.tsx +29 -0
- package/zzz_react_template/components/ui/radio-group.tsx +43 -0
- package/zzz_react_template/components/ui/resizable.tsx +54 -0
- package/zzz_react_template/components/ui/scroll-area.tsx +56 -0
- package/zzz_react_template/components/ui/select.tsx +185 -0
- package/zzz_react_template/components/ui/separator.tsx +26 -0
- package/zzz_react_template/components/ui/sheet.tsx +139 -0
- package/zzz_react_template/components/ui/sidebar.tsx +734 -0
- package/zzz_react_template/components/ui/skeleton.tsx +13 -0
- package/zzz_react_template/components/ui/slider.tsx +61 -0
- package/zzz_react_template/components/ui/sonner.tsx +23 -0
- package/zzz_react_template/components/ui/spinner.tsx +16 -0
- package/zzz_react_template/components/ui/switch.tsx +29 -0
- package/zzz_react_template/components/ui/table.tsx +114 -0
- package/zzz_react_template/components/ui/tabs.tsx +64 -0
- package/zzz_react_template/components/ui/textarea.tsx +67 -0
- package/zzz_react_template/components/ui/toggle-group.tsx +73 -0
- package/zzz_react_template/components/ui/toggle.tsx +45 -0
- package/zzz_react_template/components/ui/tooltip.tsx +59 -0
- package/zzz_react_template/const.ts +17 -0
- package/zzz_react_template/contexts/JXRContext.tsx +264 -0
- package/zzz_react_template/contexts/ThemeContext.tsx +64 -0
- package/zzz_react_template/hooks/useComposition.ts +81 -0
- package/zzz_react_template/hooks/useMobile.tsx +21 -0
- package/zzz_react_template/hooks/usePersistFn.ts +20 -0
- package/zzz_react_template/index.css +518 -11
- package/zzz_react_template/lib/jxr-runtime/index.ts +201 -0
- package/zzz_react_template/lib/jxr-runtime/module-resolver.ts +520 -0
- package/zzz_react_template/lib/jxr-runtime/moq-transport.ts +267 -0
- package/zzz_react_template/lib/jxr-runtime/web-crypto.ts +279 -0
- package/zzz_react_template/lib/jxr-runtime/worker-pool.ts +321 -0
- package/zzz_react_template/lib/utils.ts +6 -0
- package/zzz_react_template/main.tsx +4 -9
- package/zzz_react_template/pages/Docs.tsx +955 -0
- package/zzz_react_template/pages/Home.tsx +1080 -0
- package/zzz_react_template/pages/NotFound.tsx +105 -0
- package/zzz_react_template/tsconfig.json +24 -0
package/bin/jxr.js
CHANGED
|
@@ -55,6 +55,12 @@ if (command === "init") {
|
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// Copy tsconfig.json
|
|
59
|
+
await cp(
|
|
60
|
+
path.join(templateDir, "tsconfig.json"),
|
|
61
|
+
path.join(projectDir, "tsconfig.json")
|
|
62
|
+
);
|
|
63
|
+
|
|
58
64
|
console.log(`✅ Project created: ${projectDir}`);
|
|
59
65
|
console.log("");
|
|
60
66
|
console.log("Next steps:");
|
package/dist/index.d.ts
CHANGED
|
@@ -26,4 +26,47 @@ export { JXRServerManager } from './jxr-server-manager.ts';
|
|
|
26
26
|
export type { JXRServerConfig } from './jxr-server-manager.ts';
|
|
27
27
|
export { JXRDeployer, jxrDeployer } from './deployer.ts';
|
|
28
28
|
export type { DeployConfig, DeployResult, DeploymentStatus } from './deployer.ts';
|
|
29
|
+
export interface JXRConfig {
|
|
30
|
+
name: string;
|
|
31
|
+
platform: 'web' | 'native' | 'expo' | 'cloudflare-worker' | 'deno' | 'node';
|
|
32
|
+
workers?: {
|
|
33
|
+
size?: number;
|
|
34
|
+
enablePriority?: boolean;
|
|
35
|
+
maxQueueSize?: number;
|
|
36
|
+
taskTimeout?: number;
|
|
37
|
+
};
|
|
38
|
+
moq?: {
|
|
39
|
+
enabled?: boolean;
|
|
40
|
+
relayUrl?: string;
|
|
41
|
+
trackPriority?: 'high' | 'normal' | 'low';
|
|
42
|
+
maxSubscriptions?: number;
|
|
43
|
+
reconnectDelay?: number;
|
|
44
|
+
};
|
|
45
|
+
crypto?: {
|
|
46
|
+
enabled?: boolean;
|
|
47
|
+
algorithm?: 'AES-GCM' | 'AES-CBC';
|
|
48
|
+
keySize?: number;
|
|
49
|
+
signing?: boolean;
|
|
50
|
+
keyDerivation?: 'HKDF';
|
|
51
|
+
};
|
|
52
|
+
build?: {
|
|
53
|
+
entry?: string;
|
|
54
|
+
outDir?: string;
|
|
55
|
+
minify?: boolean;
|
|
56
|
+
sourcemap?: boolean;
|
|
57
|
+
splitting?: 'auto' | 'manual' | false;
|
|
58
|
+
target?: string[];
|
|
59
|
+
external?: string[];
|
|
60
|
+
};
|
|
61
|
+
devServer?: {
|
|
62
|
+
port?: number;
|
|
63
|
+
host?: string;
|
|
64
|
+
hmr?: boolean;
|
|
65
|
+
open?: boolean;
|
|
66
|
+
https?: boolean;
|
|
67
|
+
};
|
|
68
|
+
imports?: Record<string, string>;
|
|
69
|
+
plugins?: any[];
|
|
70
|
+
}
|
|
71
|
+
export declare function defineConfig(config: JXRConfig): JXRConfig;
|
|
29
72
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EACV,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,SAAS,EACT,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAElE,OAAO,EACL,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,SAAS,GACV,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGvF,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG/D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1815,7 +1815,55 @@ var JXRServerManager = class {
|
|
|
1815
1815
|
return;
|
|
1816
1816
|
}
|
|
1817
1817
|
if (vfsPath.endsWith(".css")) {
|
|
1818
|
-
|
|
1818
|
+
let cssContent = file.content;
|
|
1819
|
+
if (vfsPath === "/src/index.css") {
|
|
1820
|
+
try {
|
|
1821
|
+
const fs = await import("fs");
|
|
1822
|
+
const compiledPath = path.join(process.cwd(), "src", "index.compiled.css");
|
|
1823
|
+
if (fs.existsSync(compiledPath)) {
|
|
1824
|
+
cssContent = fs.readFileSync(compiledPath, "utf-8");
|
|
1825
|
+
console.log(`[JXR] Using pre-compiled Tailwind CSS from index.compiled.css`);
|
|
1826
|
+
} else {
|
|
1827
|
+
const { execSync } = await import("child_process");
|
|
1828
|
+
const os = await import("os");
|
|
1829
|
+
const tmpDir = os.tmpdir();
|
|
1830
|
+
const inputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.css`);
|
|
1831
|
+
const outputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.compiled.css`);
|
|
1832
|
+
fs.writeFileSync(inputFile, cssContent);
|
|
1833
|
+
try {
|
|
1834
|
+
execSync(`npx @tailwindcss/cli -i "${inputFile}" -o "${outputFile}" --minify`, {
|
|
1835
|
+
timeout: 3e4,
|
|
1836
|
+
stdio: "pipe"
|
|
1837
|
+
});
|
|
1838
|
+
cssContent = fs.readFileSync(outputFile, "utf-8");
|
|
1839
|
+
fs.unlinkSync(inputFile);
|
|
1840
|
+
fs.unlinkSync(outputFile);
|
|
1841
|
+
console.log(`[JXR] Compiled Tailwind CSS for ${vfsPath}`);
|
|
1842
|
+
} catch {
|
|
1843
|
+
const js2 = `
|
|
1844
|
+
const tailwindScript = document.createElement('script');
|
|
1845
|
+
tailwindScript.src = 'https://cdn.tailwindcss.com';
|
|
1846
|
+
tailwindScript.onload = function() {
|
|
1847
|
+
const style = document.createElement('style');
|
|
1848
|
+
style.textContent = \`${file.content.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$")}\`;
|
|
1849
|
+
document.head.appendChild(style);
|
|
1850
|
+
};
|
|
1851
|
+
document.head.appendChild(tailwindScript);
|
|
1852
|
+
export default \`${file.content.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$")}\`;
|
|
1853
|
+
`;
|
|
1854
|
+
res.writeHead(200, {
|
|
1855
|
+
"Content-Type": "application/javascript",
|
|
1856
|
+
"Cache-Control": "no-cache"
|
|
1857
|
+
});
|
|
1858
|
+
res.end(js2);
|
|
1859
|
+
return;
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
} catch (error) {
|
|
1863
|
+
console.warn(`[JXR] Tailwind handling error: ${error?.message || error}`);
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
const escapedCSS = cssContent.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
|
|
1819
1867
|
const js = `
|
|
1820
1868
|
const style = document.createElement('style');
|
|
1821
1869
|
style.textContent = \`${escapedCSS}\`;
|
|
@@ -1936,7 +1984,8 @@ export default \`${escapedCSS}\`;
|
|
|
1936
1984
|
"clsx": "https://esm.sh/clsx@2.1.1",
|
|
1937
1985
|
"tailwind-merge": "https://esm.sh/tailwind-merge@3.0.2",
|
|
1938
1986
|
"class-variance-authority": "https://esm.sh/class-variance-authority@0.7.1",
|
|
1939
|
-
"framer-motion": "https://esm.sh/framer-motion@12.5.0?external=react"
|
|
1987
|
+
"framer-motion": "https://esm.sh/framer-motion@12.5.0?external=react,motion-dom",
|
|
1988
|
+
"motion-dom": "https://esm.sh/motion-dom@12.5.0"
|
|
1940
1989
|
}
|
|
1941
1990
|
};
|
|
1942
1991
|
const hasMainFile = this.projectFiles.some(
|
|
@@ -2135,6 +2184,11 @@ var jxrDeployer = new JXRDeployer(
|
|
|
2135
2184
|
process.env.JXR_API_KEY || "",
|
|
2136
2185
|
process.env.JXR_PROJECT_ID
|
|
2137
2186
|
);
|
|
2187
|
+
|
|
2188
|
+
// src/index.ts
|
|
2189
|
+
function defineConfig(config) {
|
|
2190
|
+
return config;
|
|
2191
|
+
}
|
|
2138
2192
|
export {
|
|
2139
2193
|
DEFAULT_PROJECT_FILES,
|
|
2140
2194
|
EnhancedTranspiler,
|
|
@@ -2148,6 +2202,7 @@ export {
|
|
|
2148
2202
|
ModuleCache,
|
|
2149
2203
|
VirtualFS,
|
|
2150
2204
|
WorkerPool,
|
|
2205
|
+
defineConfig,
|
|
2151
2206
|
findOrCreateEntryPoint,
|
|
2152
2207
|
jxrCrypto,
|
|
2153
2208
|
jxrDeployer,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jxr-server-manager.d.ts","sourceRoot":"","sources":["../src/jxr-server-manager.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,QAAQ,CAAoD;IACpE,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,OAAO,CAAuC;gBAE1C,MAAM,GAAE,eAAoB;IAYlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,gBAAgB;IAoC9B,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,cAAc;YAUR,qBAAqB;IA2BnC,OAAO,CAAC,eAAe;IAOjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"jxr-server-manager.d.ts","sourceRoot":"","sources":["../src/jxr-server-manager.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,QAAQ,CAAoD;IACpE,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,OAAO,CAAuC;gBAE1C,MAAM,GAAE,eAAoB;IAYlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,gBAAgB;IAoC9B,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,cAAc;YAUR,qBAAqB;IA2BnC,OAAO,CAAC,eAAe;IAOjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmLtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B3B,OAAO,CAAC,YAAY;CA+GrB"}
|
package/package.json
CHANGED
|
@@ -249,7 +249,63 @@ export class JXRServerManager {
|
|
|
249
249
|
|
|
250
250
|
// Serve CSS files as JavaScript that injects the CSS
|
|
251
251
|
if (vfsPath.endsWith('.css')) {
|
|
252
|
-
|
|
252
|
+
let cssContent = file.content;
|
|
253
|
+
|
|
254
|
+
// Check for pre-compiled Tailwind CSS first
|
|
255
|
+
if (vfsPath === '/src/index.css') {
|
|
256
|
+
try {
|
|
257
|
+
const fs = await import('fs');
|
|
258
|
+
const compiledPath = path.join(process.cwd(), 'src', 'index.compiled.css');
|
|
259
|
+
if (fs.existsSync(compiledPath)) {
|
|
260
|
+
cssContent = fs.readFileSync(compiledPath, 'utf-8');
|
|
261
|
+
console.log(`[JXR] Using pre-compiled Tailwind CSS from index.compiled.css`);
|
|
262
|
+
} else {
|
|
263
|
+
// Try to compile on-the-fly
|
|
264
|
+
const { execSync } = await import('child_process');
|
|
265
|
+
const os = await import('os');
|
|
266
|
+
|
|
267
|
+
const tmpDir = os.tmpdir();
|
|
268
|
+
const inputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.css`);
|
|
269
|
+
const outputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.compiled.css`);
|
|
270
|
+
|
|
271
|
+
fs.writeFileSync(inputFile, cssContent);
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
execSync(`npx @tailwindcss/cli -i "${inputFile}" -o "${outputFile}" --minify`, {
|
|
275
|
+
timeout: 30000,
|
|
276
|
+
stdio: 'pipe'
|
|
277
|
+
});
|
|
278
|
+
cssContent = fs.readFileSync(outputFile, 'utf-8');
|
|
279
|
+
fs.unlinkSync(inputFile);
|
|
280
|
+
fs.unlinkSync(outputFile);
|
|
281
|
+
console.log(`[JXR] Compiled Tailwind CSS for ${vfsPath}`);
|
|
282
|
+
} catch {
|
|
283
|
+
// CDN fallback
|
|
284
|
+
const js = `
|
|
285
|
+
const tailwindScript = document.createElement('script');
|
|
286
|
+
tailwindScript.src = 'https://cdn.tailwindcss.com';
|
|
287
|
+
tailwindScript.onload = function() {
|
|
288
|
+
const style = document.createElement('style');
|
|
289
|
+
style.textContent = \`${file.content.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$')}\`;
|
|
290
|
+
document.head.appendChild(style);
|
|
291
|
+
};
|
|
292
|
+
document.head.appendChild(tailwindScript);
|
|
293
|
+
export default \`${file.content.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$')}\`;
|
|
294
|
+
`;
|
|
295
|
+
res.writeHead(200, {
|
|
296
|
+
"Content-Type": "application/javascript",
|
|
297
|
+
"Cache-Control": "no-cache"
|
|
298
|
+
});
|
|
299
|
+
res.end(js);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
} catch (error: any) {
|
|
304
|
+
console.warn(`[JXR] Tailwind handling error: ${error?.message || error}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const escapedCSS = cssContent
|
|
253
309
|
.replace(/\\/g, '\\\\')
|
|
254
310
|
.replace(/`/g, '\\`')
|
|
255
311
|
.replace(/\$/g, '\\$');
|
|
@@ -1,160 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
/**
|
|
2
|
+
* JXR.js Marketing Website — App.tsx
|
|
3
|
+
* LavaFlow OS Design System
|
|
4
|
+
* Powered by JXR Studios × DamascusAI
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Toaster } from "@/components/ui/sonner";
|
|
8
|
+
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
9
|
+
import { Route, Switch } from "wouter";
|
|
10
|
+
import ErrorBoundary from "./components/ErrorBoundary";
|
|
11
|
+
import { ThemeProvider } from "./contexts/ThemeContext";
|
|
12
|
+
import Home from "./pages/Home";
|
|
13
|
+
import DocsPage from "./pages/Docs";
|
|
14
|
+
import NotFound from "./pages/NotFound";
|
|
15
|
+
|
|
16
|
+
function Router() {
|
|
17
|
+
return (
|
|
18
|
+
<Switch>
|
|
19
|
+
<Route path="/" component={Home} />
|
|
20
|
+
<Route path="/docs" component={DocsPage} />
|
|
21
|
+
<Route path="/docs/:section" component={DocsPage} />
|
|
22
|
+
<Route component={NotFound} />
|
|
23
|
+
</Switch>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
9
26
|
|
|
10
27
|
export default function App() {
|
|
11
|
-
const [count, setCount] = useState(0)
|
|
12
|
-
|
|
13
28
|
return (
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
{/* Hero Card */}
|
|
26
|
-
<div style={{
|
|
27
|
-
background: 'rgba(255,255,255,0.05)',
|
|
28
|
-
backdropFilter: 'blur(20px)',
|
|
29
|
-
borderRadius: '1.5rem',
|
|
30
|
-
border: '1px solid rgba(255,255,255,0.1)',
|
|
31
|
-
padding: '3rem',
|
|
32
|
-
maxWidth: '640px',
|
|
33
|
-
width: '100%',
|
|
34
|
-
textAlign: 'center',
|
|
35
|
-
boxShadow: '0 25px 50px -12px rgba(0,0,0,0.5)',
|
|
36
|
-
}}>
|
|
37
|
-
{/* Logo */}
|
|
38
|
-
<div style={{
|
|
39
|
-
width: '64px',
|
|
40
|
-
height: '64px',
|
|
41
|
-
borderRadius: '16px',
|
|
42
|
-
background: 'linear-gradient(135deg, #6366f1, #a855f7, #ec4899)',
|
|
43
|
-
display: 'flex',
|
|
44
|
-
alignItems: 'center',
|
|
45
|
-
justifyContent: 'center',
|
|
46
|
-
margin: '0 auto 1.5rem',
|
|
47
|
-
fontSize: '1.5rem',
|
|
48
|
-
fontWeight: 'bold',
|
|
49
|
-
color: 'white',
|
|
50
|
-
boxShadow: '0 0 30px rgba(99,102,241,0.4)',
|
|
51
|
-
}}>
|
|
52
|
-
x0
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
<h1 style={{
|
|
56
|
-
fontSize: '2.25rem',
|
|
57
|
-
fontWeight: 800,
|
|
58
|
-
marginBottom: '0.75rem',
|
|
59
|
-
background: 'linear-gradient(135deg, #c7d2fe, #e9d5ff, #fbcfe8)',
|
|
60
|
-
WebkitBackgroundClip: 'text',
|
|
61
|
-
WebkitTextFillColor: 'transparent',
|
|
62
|
-
lineHeight: 1.2,
|
|
63
|
-
}}>
|
|
64
|
-
Your App is Live
|
|
65
|
-
</h1>
|
|
66
|
-
|
|
67
|
-
<p style={{
|
|
68
|
-
fontSize: '1.1rem',
|
|
69
|
-
color: 'rgba(226,232,240,0.7)',
|
|
70
|
-
marginBottom: '2rem',
|
|
71
|
-
lineHeight: 1.6,
|
|
72
|
-
}}>
|
|
73
|
-
This project is ready for development. Use the AI chat to describe
|
|
74
|
-
what you want to build, or start editing files directly.
|
|
75
|
-
</p>
|
|
76
|
-
|
|
77
|
-
{/* Interactive Counter */}
|
|
78
|
-
<div style={{
|
|
79
|
-
display: 'flex',
|
|
80
|
-
alignItems: 'center',
|
|
81
|
-
justifyContent: 'center',
|
|
82
|
-
gap: '1rem',
|
|
83
|
-
marginBottom: '2.5rem',
|
|
84
|
-
}}>
|
|
85
|
-
<button
|
|
86
|
-
onClick={() => setCount(c => c - 1)}
|
|
87
|
-
style={{
|
|
88
|
-
width: '40px', height: '40px', borderRadius: '12px',
|
|
89
|
-
background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.15)',
|
|
90
|
-
color: '#e2e8f0', fontSize: '1.25rem', cursor: 'pointer',
|
|
91
|
-
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
92
|
-
transition: 'all 0.15s',
|
|
93
|
-
}}
|
|
94
|
-
onMouseEnter={e => (e.currentTarget.style.background = 'rgba(255,255,255,0.2)')}
|
|
95
|
-
onMouseLeave={e => (e.currentTarget.style.background = 'rgba(255,255,255,0.1)')}
|
|
96
|
-
>
|
|
97
|
-
−
|
|
98
|
-
</button>
|
|
99
|
-
<div style={{
|
|
100
|
-
padding: '0.5rem 1.5rem',
|
|
101
|
-
borderRadius: '12px',
|
|
102
|
-
background: 'rgba(99,102,241,0.2)',
|
|
103
|
-
border: '1px solid rgba(99,102,241,0.3)',
|
|
104
|
-
fontSize: '1.25rem',
|
|
105
|
-
fontWeight: 700,
|
|
106
|
-
fontVariantNumeric: 'tabular-nums',
|
|
107
|
-
minWidth: '80px',
|
|
108
|
-
}}>
|
|
109
|
-
{count}
|
|
110
|
-
</div>
|
|
111
|
-
<button
|
|
112
|
-
onClick={() => setCount(c => c + 1)}
|
|
113
|
-
style={{
|
|
114
|
-
width: '40px', height: '40px', borderRadius: '12px',
|
|
115
|
-
background: 'linear-gradient(135deg, #6366f1, #a855f7)',
|
|
116
|
-
border: 'none', color: 'white', fontSize: '1.25rem', cursor: 'pointer',
|
|
117
|
-
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
118
|
-
boxShadow: '0 0 20px rgba(99,102,241,0.3)',
|
|
119
|
-
transition: 'all 0.15s',
|
|
29
|
+
<ErrorBoundary>
|
|
30
|
+
<ThemeProvider defaultTheme="dark">
|
|
31
|
+
<TooltipProvider>
|
|
32
|
+
<Toaster
|
|
33
|
+
theme="dark"
|
|
34
|
+
toastOptions={{
|
|
35
|
+
style: {
|
|
36
|
+
background: 'oklch(0.13 0.007 285)',
|
|
37
|
+
border: '1px solid oklch(1 0 0 / 10%)',
|
|
38
|
+
color: 'oklch(0.93 0.005 65)',
|
|
39
|
+
},
|
|
120
40
|
}}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
{/* Feature Grid */}
|
|
129
|
-
<div style={{
|
|
130
|
-
display: 'grid',
|
|
131
|
-
gridTemplateColumns: 'repeat(2, 1fr)',
|
|
132
|
-
gap: '0.75rem',
|
|
133
|
-
textAlign: 'left',
|
|
134
|
-
}}>
|
|
135
|
-
{FEATURES.map((f) => (
|
|
136
|
-
<div key={f.title} style={{
|
|
137
|
-
padding: '1rem',
|
|
138
|
-
borderRadius: '12px',
|
|
139
|
-
background: 'rgba(255,255,255,0.04)',
|
|
140
|
-
border: '1px solid rgba(255,255,255,0.06)',
|
|
141
|
-
}}>
|
|
142
|
-
<div style={{ fontSize: '1.25rem', marginBottom: '0.25rem' }}>{f.icon}</div>
|
|
143
|
-
<div style={{ fontWeight: 600, fontSize: '0.875rem', marginBottom: '0.25rem' }}>{f.title}</div>
|
|
144
|
-
<div style={{ fontSize: '0.75rem', color: 'rgba(226,232,240,0.5)', lineHeight: 1.4 }}>{f.desc}</div>
|
|
145
|
-
</div>
|
|
146
|
-
))}
|
|
147
|
-
</div>
|
|
148
|
-
</div>
|
|
149
|
-
|
|
150
|
-
{/* Footer */}
|
|
151
|
-
<p style={{
|
|
152
|
-
marginTop: '2rem',
|
|
153
|
-
fontSize: '0.8rem',
|
|
154
|
-
color: 'rgba(226,232,240,0.3)',
|
|
155
|
-
}}>
|
|
156
|
-
Built with x0 · React 19 · TypeScript · Tailwind CSS
|
|
157
|
-
</p>
|
|
158
|
-
</div>
|
|
159
|
-
)
|
|
160
|
-
}
|
|
41
|
+
/>
|
|
42
|
+
<Router />
|
|
43
|
+
</TooltipProvider>
|
|
44
|
+
</ThemeProvider>
|
|
45
|
+
</ErrorBoundary>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { cn } from "@/lib/utils";
|
|
2
|
+
import { AlertTriangle, RotateCcw } from "lucide-react";
|
|
3
|
+
import { Component, ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface State {
|
|
10
|
+
hasError: boolean;
|
|
11
|
+
error: Error | null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
class ErrorBoundary extends Component<Props, State> {
|
|
15
|
+
constructor(props: Props) {
|
|
16
|
+
super(props);
|
|
17
|
+
this.state = { hasError: false, error: null };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static getDerivedStateFromError(error: Error): State {
|
|
21
|
+
return { hasError: true, error };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
render() {
|
|
25
|
+
if (this.state.hasError) {
|
|
26
|
+
return (
|
|
27
|
+
<div className="flex items-center justify-center min-h-screen p-8 bg-background">
|
|
28
|
+
<div className="flex flex-col items-center w-full max-w-2xl p-8">
|
|
29
|
+
<AlertTriangle
|
|
30
|
+
size={48}
|
|
31
|
+
className="text-destructive mb-6 flex-shrink-0"
|
|
32
|
+
/>
|
|
33
|
+
|
|
34
|
+
<h2 className="text-xl mb-4">An unexpected error occurred.</h2>
|
|
35
|
+
|
|
36
|
+
<div className="p-4 w-full rounded bg-muted overflow-auto mb-6">
|
|
37
|
+
<pre className="text-sm text-muted-foreground whitespace-break-spaces">
|
|
38
|
+
{this.state.error?.stack}
|
|
39
|
+
</pre>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<button
|
|
43
|
+
onClick={() => window.location.reload()}
|
|
44
|
+
className={cn(
|
|
45
|
+
"flex items-center gap-2 px-4 py-2 rounded-lg",
|
|
46
|
+
"bg-primary text-primary-foreground",
|
|
47
|
+
"hover:opacity-90 cursor-pointer"
|
|
48
|
+
)}
|
|
49
|
+
>
|
|
50
|
+
<RotateCcw size={16} />
|
|
51
|
+
Reload Page
|
|
52
|
+
</button>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return this.props.children;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default ErrorBoundary;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { Button } from "@/components/ui/button";
|
|
4
|
+
import {
|
|
5
|
+
Dialog,
|
|
6
|
+
DialogContent,
|
|
7
|
+
DialogDescription,
|
|
8
|
+
DialogFooter,
|
|
9
|
+
DialogTitle,
|
|
10
|
+
} from "@/components/ui/dialog";
|
|
11
|
+
|
|
12
|
+
interface ManusDialogProps {
|
|
13
|
+
title?: string;
|
|
14
|
+
logo?: string;
|
|
15
|
+
open?: boolean;
|
|
16
|
+
onLogin: () => void;
|
|
17
|
+
onOpenChange?: (open: boolean) => void;
|
|
18
|
+
onClose?: () => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function ManusDialog({
|
|
22
|
+
title,
|
|
23
|
+
logo,
|
|
24
|
+
open = false,
|
|
25
|
+
onLogin,
|
|
26
|
+
onOpenChange,
|
|
27
|
+
onClose,
|
|
28
|
+
}: ManusDialogProps) {
|
|
29
|
+
const [internalOpen, setInternalOpen] = useState(open);
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (!onOpenChange) {
|
|
33
|
+
setInternalOpen(open);
|
|
34
|
+
}
|
|
35
|
+
}, [open, onOpenChange]);
|
|
36
|
+
|
|
37
|
+
const handleOpenChange = (nextOpen: boolean) => {
|
|
38
|
+
if (onOpenChange) {
|
|
39
|
+
onOpenChange(nextOpen);
|
|
40
|
+
} else {
|
|
41
|
+
setInternalOpen(nextOpen);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!nextOpen) {
|
|
45
|
+
onClose?.();
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<Dialog
|
|
51
|
+
open={onOpenChange ? open : internalOpen}
|
|
52
|
+
onOpenChange={handleOpenChange}
|
|
53
|
+
>
|
|
54
|
+
<DialogContent className="py-5 bg-[#f8f8f7] rounded-[20px] w-[400px] shadow-[0px_4px_11px_0px_rgba(0,0,0,0.08)] border border-[rgba(0,0,0,0.08)] backdrop-blur-2xl p-0 gap-0 text-center">
|
|
55
|
+
<div className="flex flex-col items-center gap-2 p-5 pt-12">
|
|
56
|
+
{logo ? (
|
|
57
|
+
<div className="w-16 h-16 bg-white rounded-xl border border-[rgba(0,0,0,0.08)] flex items-center justify-center">
|
|
58
|
+
<img src={logo} alt="Dialog graphic" className="w-10 h-10 rounded-md" />
|
|
59
|
+
</div>
|
|
60
|
+
) : null}
|
|
61
|
+
|
|
62
|
+
{/* Title and subtitle */}
|
|
63
|
+
{title ? (
|
|
64
|
+
<DialogTitle className="text-xl font-semibold text-[#34322d] leading-[26px] tracking-[-0.44px]">
|
|
65
|
+
{title}
|
|
66
|
+
</DialogTitle>
|
|
67
|
+
) : null}
|
|
68
|
+
<DialogDescription className="text-sm text-[#858481] leading-5 tracking-[-0.154px]">
|
|
69
|
+
Please login with Manus to continue
|
|
70
|
+
</DialogDescription>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<DialogFooter className="px-5 py-5">
|
|
74
|
+
{/* Login button */}
|
|
75
|
+
<Button
|
|
76
|
+
onClick={onLogin}
|
|
77
|
+
className="w-full h-10 bg-[#1a1a19] hover:bg-[#1a1a19]/90 text-white rounded-[10px] text-sm font-medium leading-5 tracking-[-0.154px]"
|
|
78
|
+
>
|
|
79
|
+
Login with Manus
|
|
80
|
+
</Button>
|
|
81
|
+
</DialogFooter>
|
|
82
|
+
</DialogContent>
|
|
83
|
+
</Dialog>
|
|
84
|
+
);
|
|
85
|
+
}
|