@jxrstudios/jxr 1.1.11 → 1.2.13

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.
Files changed (2) hide show
  1. package/bin/jxr.js +179 -4
  2. package/package.json +1 -1
package/bin/jxr.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { JXRServerManager, JXRDeployer } from "../src/index.ts";
3
3
 
4
- import { mkdir, writeFile, cp } from "fs/promises";
4
+ import { mkdir, writeFile, cp, readdir } from "fs/promises";
5
5
  import { existsSync } from "fs";
6
6
  import path from "path";
7
7
  import { fileURLToPath } from "url";
@@ -38,6 +38,11 @@ if (command === "init") {
38
38
  },
39
39
  dependencies: {
40
40
  "@jxrstudios/jxr": "^1.0.5"
41
+ },
42
+ devDependencies: {
43
+ "@types/react": "^19.0.0",
44
+ "@types/react-dom": "^19.0.0",
45
+ "typescript": "^5.5.0"
41
46
  }
42
47
  };
43
48
  await writeFile(
@@ -73,6 +78,175 @@ if (command === "init") {
73
78
  process.exit(1);
74
79
  }
75
80
 
81
+ } else if (command === "build") {
82
+ // Build command - production-optimized build
83
+ const platform = args.find((a) => a.startsWith("--platform="))?.split("=")[1] || "web";
84
+ const analyze = args.includes("--analyze");
85
+ const noMinify = args.includes("--no-minify");
86
+ const outDir = args.find((a) => a.startsWith("--out-dir="))?.split("=")[1] || "dist";
87
+
88
+ console.log(`šŸ”Ø Building for ${platform}...`);
89
+
90
+ try {
91
+ const esbuild = await import("esbuild");
92
+ const fs = await import("fs");
93
+ const path = await import("path");
94
+ const crypto = await import("crypto");
95
+
96
+ // Ensure output directory exists
97
+ await mkdir(outDir, { recursive: true });
98
+ await mkdir(path.join(outDir, "assets"), { recursive: true });
99
+
100
+ // Find entry point
101
+ const entryFile = fs.existsSync("src/main.tsx") ? "src/main.tsx" :
102
+ fs.existsSync("src/main.ts") ? "src/main.ts" :
103
+ fs.existsSync("src/App.tsx") ? "src/App.tsx" : "src/index.tsx";
104
+
105
+ // Build configuration
106
+ const buildConfig = {
107
+ entryPoints: [entryFile],
108
+ bundle: true,
109
+ platform: platform === "node" ? "node" : "browser",
110
+ target: platform === "cloudflare-worker" ? "es2022" : "es2020",
111
+ format: "esm",
112
+ minify: !noMinify,
113
+ sourcemap: !noMinify,
114
+ splitting: platform !== "node",
115
+ outdir: path.join(outDir, "assets"),
116
+ entryNames: "[name]-[hash]",
117
+ chunkNames: "[name]-[hash]",
118
+ assetNames: "[name]-[hash]",
119
+ metafile: true,
120
+ define: {
121
+ "process.env.NODE_ENV": '"production"',
122
+ ...(platform === "cloudflare-worker" && {
123
+ "process": "{}",
124
+ "process.env": "{}",
125
+ }),
126
+ },
127
+ external: [
128
+ "react", "react/jsx-runtime", "react/jsx-dev-runtime", "react-dom/client",
129
+ "wouter", "lucide-react", "sonner", "next-themes", "framer-motion", "motion-dom",
130
+ "@radix-ui/react-dialog", "@radix-ui/react-tooltip", "@radix-ui/react-slot",
131
+ "clsx", "tailwind-merge", "class-variance-authority",
132
+ "tailwindcss", "tw-animate-css",
133
+ ...(platform === "cloudflare-worker" ? ["__STATIC_CONTENT_MANIFEST"] : []),
134
+ ],
135
+ alias: {
136
+ "@": "./src",
137
+ },
138
+ loader: {
139
+ ".tsx": "tsx",
140
+ ".ts": "ts",
141
+ ".css": "css",
142
+ ".png": "file",
143
+ ".jpg": "file",
144
+ ".svg": "file",
145
+ },
146
+ };
147
+
148
+ // Run build
149
+ const result = await esbuild.build(buildConfig);
150
+
151
+ console.log(`āœ… Build complete: ${outDir}/`);
152
+
153
+ // Analyze bundle if requested
154
+ if (analyze && result.metafile) {
155
+ console.log("\nšŸ“Š Bundle Analysis:");
156
+ const outputs = Object.entries(result.metafile.outputs);
157
+ outputs.sort((a, b) => b[1].bytes - a[1].bytes);
158
+ outputs.slice(0, 10).forEach(([file, info]) => {
159
+ const sizeKB = (info.bytes / 1024).toFixed(2);
160
+ console.log(` ${file}: ${sizeKB} KB`);
161
+ });
162
+ }
163
+
164
+ // Find main entry output (exclude source maps)
165
+ const mainOutput = Object.keys(result.metafile?.outputs || {}).find(k =>
166
+ (k.includes("main-") || k.includes("index-")) && k.endsWith(".js")
167
+ );
168
+ const vendorOutput = Object.keys(result.metafile?.outputs || {}).find(k =>
169
+ k.includes("chunk-") && k.endsWith(".js")
170
+ );
171
+
172
+ // Copy compiled CSS if available
173
+ if (fs.existsSync("src/index.compiled.css")) {
174
+ fs.copyFileSync("src/index.compiled.css", path.join(outDir, "assets", "index-[hash].css"));
175
+ console.log(` šŸ“„ Copied compiled CSS`);
176
+ }
177
+
178
+ // Find CSS output
179
+ const cssOutput = Object.keys(result.metafile?.outputs || {}).find(k => k.endsWith(".css"));
180
+
181
+ // Generate index.html with proper CSS and JS references
182
+ const indexHtml = `<!DOCTYPE html>
183
+ <html lang="en">
184
+ <head>
185
+ <meta charset="UTF-8">
186
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
187
+ <title>JXR.js — Edge OS Runtime Framework</title>
188
+ <meta name="description" content="JXR.js is the next-generation edge runtime framework for React Native and React. MoQ transport, Web Crypto, Worker pools.">
189
+
190
+ <!-- Google Fonts -->
191
+ <link rel="preconnect" href="https://fonts.googleapis.com">
192
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
193
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
194
+
195
+ ${cssOutput ? `<link rel="stylesheet" href="${cssOutput.replace(outDir, "").replace(/^\//, "")}">` : ""}
196
+ </head>
197
+ <body>
198
+ <div id="root"></div>
199
+ ${vendorOutput ? `<script type="module" src="${vendorOutput.replace(outDir, "").replace(/^\//, "")}"></script>` : ""}
200
+ <script type="module" src="${mainOutput ? mainOutput.replace(outDir, "").replace(/^\//, "") : "assets/index.js"}"></script>
201
+ </body>
202
+ </html>`;
203
+
204
+ await writeFile(path.join(outDir, "index.html"), indexHtml);
205
+
206
+ // Generate crypto-signed manifest
207
+ const manifest = {
208
+ version: "1.0.0",
209
+ platform,
210
+ buildTime: new Date().toISOString(),
211
+ entries: {
212
+ main: mainOutput ? path.basename(mainOutput) : "index.js",
213
+ ...(vendorOutput && { vendor: path.basename(vendorOutput) }),
214
+ },
215
+ files: Object.keys(result.metafile?.outputs || {}).map(k => path.basename(k)),
216
+ };
217
+
218
+ // Sign manifest with ECDSA P-256
219
+ const manifestJson = JSON.stringify(manifest, null, 2);
220
+ const { privateKey, publicKey } = crypto.generateKeyPairSync("ec", {
221
+ namedCurve: "prime256v1",
222
+ });
223
+ const signature = crypto.sign("sha256", Buffer.from(manifestJson), privateKey);
224
+
225
+ const signedManifest = {
226
+ ...manifest,
227
+ signature: signature.toString("base64"),
228
+ algorithm: "ECDSA-P256",
229
+ publicKey: publicKey.export({ type: "spki", format: "pem" }),
230
+ };
231
+
232
+ await writeFile(
233
+ path.join(outDir, "jxr-manifest.json"),
234
+ JSON.stringify(signedManifest, null, 2)
235
+ );
236
+
237
+ console.log(`āœ… Manifest: ${outDir}/jxr-manifest.json`);
238
+ console.log(` Signed with ECDSA-P256`);
239
+
240
+ // Show output files
241
+ console.log("\nšŸ“ Build outputs:");
242
+ const files = await readdir(outDir, { recursive: true });
243
+ files.forEach(f => console.log(` ${f}`));
244
+
245
+ } catch (err) {
246
+ console.error("āŒ Build failed:", err.message);
247
+ process.exit(1);
248
+ }
249
+
76
250
  } else if (command === "deploy") {
77
251
  // Deploy command
78
252
  const projectPath = args[1] || "./dist";
@@ -123,8 +297,9 @@ if (command === "init") {
123
297
 
124
298
  } else {
125
299
  console.log("Usage:");
126
- console.log(" jxr init <project-name> Create new project");
127
- console.log(" jxr dev [--port=3000] Start dev server");
128
- console.log(" jxr deploy <path> Deploy to production");
300
+ console.log(" jxr init <project-name> Create new project");
301
+ console.log(" jxr dev [--port=3000] Start dev server");
302
+ console.log(" jxr build [--platform=web] Production build");
303
+ console.log(" jxr deploy <path> [--env=prod] Deploy to production");
129
304
  process.exit(1);
130
305
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jxrstudios/jxr",
3
- "version": "1.1.11",
3
+ "version": "1.2.13",
4
4
  "description": "JXR.js — Edge OS Runtime Framework for elite developers",
5
5
  "type": "module",
6
6
  "license": "MIT",