@magneticjs/cli 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -148,8 +148,33 @@ function generateBridge(scan) {
148
148
 
149
149
  // src/bundler.ts
150
150
  import { build } from "esbuild";
151
- import { join as join2 } from "node:path";
152
- import { mkdirSync, existsSync as existsSync2, statSync as statSync2, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "node:fs";
151
+ import { join as join2, dirname as dirname2 } from "node:path";
152
+ import { mkdirSync, existsSync as existsSync2, statSync as statSync2, readdirSync as readdirSync2, readFileSync as readFileSync2, copyFileSync } from "node:fs";
153
+ import { createRequire } from "node:module";
154
+ function copyTransportWasm(appDir, monorepoRoot) {
155
+ const publicDir = join2(appDir, "public");
156
+ const dest = join2(publicDir, "transport.wasm");
157
+ if (existsSync2(dest)) return true;
158
+ const candidates = [];
159
+ if (monorepoRoot) {
160
+ candidates.push(join2(monorepoRoot, "js/packages/magnetic-server/wasm/transport.wasm"));
161
+ }
162
+ try {
163
+ const require2 = createRequire(join2(appDir, "package.json"));
164
+ const serverPkg = require2.resolve("@magneticjs/server");
165
+ candidates.push(join2(dirname2(serverPkg), "..", "wasm", "transport.wasm"));
166
+ } catch {
167
+ }
168
+ candidates.push(join2(import.meta.dirname || __dirname, "..", "wasm", "transport.wasm"));
169
+ for (const src of candidates) {
170
+ if (existsSync2(src)) {
171
+ mkdirSync(publicDir, { recursive: true });
172
+ copyFileSync(src, dest);
173
+ return true;
174
+ }
175
+ }
176
+ return false;
177
+ }
153
178
  async function bundleApp(opts) {
154
179
  const outDir = opts.outDir || join2(opts.appDir, "dist");
155
180
  const outFile = opts.outFile || "app.js";
@@ -157,6 +182,7 @@ async function bundleApp(opts) {
157
182
  if (!existsSync2(outDir)) {
158
183
  mkdirSync(outDir, { recursive: true });
159
184
  }
185
+ copyTransportWasm(opts.appDir, opts.monorepoRoot);
160
186
  const alias = {};
161
187
  if (opts.monorepoRoot) {
162
188
  const serverPkg = join2(opts.monorepoRoot, "js/packages/magnetic-server/src");
@@ -228,8 +254,23 @@ async function startDev(opts) {
228
254
  const outDir = join3(appDir, "dist");
229
255
  const serverBin = opts.serverBin || findServerBinary(monorepoRoot || appDir);
230
256
  if (!serverBin) {
231
- console.error("[magnetic] Cannot find magnetic-v8-server binary.");
232
- console.error(" Build it with: cargo build --release -p magnetic-v8-server");
257
+ console.error("");
258
+ console.error(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
259
+ console.error(" \u2551 MAGNETIC: Server binary not found \u2551");
260
+ console.error(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
261
+ console.error("");
262
+ console.error(" `magnetic dev` requires the magnetic-v8-server binary.");
263
+ console.error(" It should have been downloaded during `npm install @magneticjs/cli`.");
264
+ console.error("");
265
+ console.error(" To fix:");
266
+ console.error(" npm rebuild @magneticjs/cli");
267
+ console.error("");
268
+ console.error(" Or build from source:");
269
+ console.error(" git clone https://github.com/inventhq/magnetic.git");
270
+ console.error(" cd magnetic/rs/crates/magnetic-v8-server");
271
+ console.error(" cargo build --release");
272
+ console.error(" cp target/release/magnetic-v8-server $(npm root -g)/@magneticjs/cli/bin/");
273
+ console.error("");
233
274
  process.exit(1);
234
275
  }
235
276
  let serverProcess = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magneticjs/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Magnetic CLI — build, dev, and deploy server-driven UI apps",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,12 +11,12 @@
11
11
  "dev": "tsx src/cli.ts",
12
12
  "postinstall": "node scripts/install-server.js || true"
13
13
  },
14
- "files": ["dist", "src", "scripts"],
14
+ "files": ["dist", "src", "scripts", "wasm"],
15
15
  "publishConfig": {
16
16
  "access": "public"
17
17
  },
18
18
  "dependencies": {
19
- "@magneticjs/server": "^0.1.0",
19
+ "@magneticjs/server": "^0.1.1",
20
20
  "esbuild": "^0.27.3"
21
21
  },
22
22
  "devDependencies": {
@@ -69,24 +69,52 @@ console.log(`[magnetic] ${url}`);
69
69
 
70
70
  try {
71
71
  mkdirSync(binDir, { recursive: true });
72
- // Use curl or wget — available on all platforms
72
+
73
+ // Download — curl with -L follows GitHub's 302 redirect
74
+ let downloaded = false;
73
75
  try {
74
- execSync(`curl -fsSL "${url}" | tar xz -C "${binDir}"`, { stdio: 'pipe' });
75
- } catch {
76
- execSync(`wget -qO- "${url}" | tar xz -C "${binDir}"`, { stdio: 'pipe' });
76
+ execSync(`curl -fsSL "${url}" -o "${join(binDir, filename)}"`, { stdio: 'pipe' });
77
+ execSync(`tar xzf "${join(binDir, filename)}" -C "${binDir}"`, { stdio: 'pipe' });
78
+ downloaded = true;
79
+ } catch (e1) {
80
+ try {
81
+ execSync(`wget -q "${url}" -O "${join(binDir, filename)}"`, { stdio: 'pipe' });
82
+ execSync(`tar xzf "${join(binDir, filename)}" -C "${binDir}"`, { stdio: 'pipe' });
83
+ downloaded = true;
84
+ } catch (e2) {
85
+ // Both failed
86
+ }
77
87
  }
78
88
 
79
- if (existsSync(binPath)) {
89
+ // Clean up tarball
90
+ try { execSync(`rm -f "${join(binDir, filename)}"`, { stdio: 'pipe' }); } catch {}
91
+
92
+ if (downloaded && existsSync(binPath)) {
80
93
  chmodSync(binPath, 0o755);
81
94
  writeFileSync(versionFile, version);
82
95
  console.log(`[magnetic] ✓ Server binary v${version} installed: ${binPath}`);
83
96
  } else {
84
- throw new Error('Binary not found after extraction');
97
+ throw new Error(`Download failed or binary not found after extraction`);
85
98
  }
86
99
  } catch (err) {
87
- console.warn(`[magnetic] Could not download prebuilt binary: ${err.message}`);
88
- console.warn('[magnetic] The CLI will still work, but you need the server binary for `magnetic dev`.');
89
- console.warn('[magnetic] Build from source: cargo build --release -p magnetic-v8-server');
90
- // Don't fail the install — just warn
100
+ console.error('');
101
+ console.error(' ╔══════════════════════════════════════════════════════════════╗');
102
+ console.error(' ║ MAGNETIC: Server binary download failed ║');
103
+ console.error(' ╚══════════════════════════════════════════════════════════════╝');
104
+ console.error('');
105
+ console.error(` URL: ${url}`);
106
+ console.error(` Error: ${err.message}`);
107
+ console.error('');
108
+ console.error(' `magnetic dev` will NOT work without the server binary.');
109
+ console.error('');
110
+ console.error(' To fix, either:');
111
+ console.error(' 1. Re-run: npm rebuild @magneticjs/cli');
112
+ console.error(' 2. Build from source:');
113
+ console.error(' git clone https://github.com/inventhq/magnetic.git');
114
+ console.error(' cd magnetic/rs/crates/magnetic-v8-server');
115
+ console.error(' cargo build --release');
116
+ console.error(' cp target/release/magnetic-v8-server $(npm root -g)/@magneticjs/cli/bin/');
117
+ console.error('');
118
+ // Don't fail npm install — but make the error impossible to miss
91
119
  process.exit(0);
92
120
  }
package/src/bundler.ts CHANGED
@@ -2,8 +2,9 @@
2
2
  // Takes generated bridge code and bundles it into an IIFE for V8
3
3
 
4
4
  import { build } from 'esbuild';
5
- import { join, resolve } from 'node:path';
6
- import { mkdirSync, existsSync, writeFileSync, statSync, readdirSync, readFileSync } from 'node:fs';
5
+ import { join, resolve, dirname } from 'node:path';
6
+ import { mkdirSync, existsSync, writeFileSync, statSync, readdirSync, readFileSync, copyFileSync } from 'node:fs';
7
+ import { createRequire } from 'node:module';
7
8
 
8
9
  export interface BundleOptions {
9
10
  /** Absolute path to the app directory */
@@ -25,6 +26,46 @@ export interface BundleResult {
25
26
  sizeBytes: number;
26
27
  }
27
28
 
29
+ /**
30
+ * Copy transport.wasm into the app's public/ directory.
31
+ * Looks in @magneticjs/server/wasm/ (npm) or monorepo path.
32
+ */
33
+ export function copyTransportWasm(appDir: string, monorepoRoot?: string): boolean {
34
+ const publicDir = join(appDir, 'public');
35
+ const dest = join(publicDir, 'transport.wasm');
36
+
37
+ // Already there — skip
38
+ if (existsSync(dest)) return true;
39
+
40
+ // Candidate locations for the WASM file
41
+ const candidates: string[] = [];
42
+
43
+ // Monorepo path
44
+ if (monorepoRoot) {
45
+ candidates.push(join(monorepoRoot, 'js/packages/magnetic-server/wasm/transport.wasm'));
46
+ }
47
+
48
+ // npm-installed @magneticjs/server
49
+ try {
50
+ const require = createRequire(join(appDir, 'package.json'));
51
+ const serverPkg = require.resolve('@magneticjs/server');
52
+ candidates.push(join(dirname(serverPkg), '..', 'wasm', 'transport.wasm'));
53
+ } catch {}
54
+
55
+ // CLI's own bundled copy (sibling to dist/)
56
+ candidates.push(join(import.meta.dirname || __dirname, '..', 'wasm', 'transport.wasm'));
57
+
58
+ for (const src of candidates) {
59
+ if (existsSync(src)) {
60
+ mkdirSync(publicDir, { recursive: true });
61
+ copyFileSync(src, dest);
62
+ return true;
63
+ }
64
+ }
65
+
66
+ return false;
67
+ }
68
+
28
69
  /**
29
70
  * Bundle the generated bridge code into an IIFE for V8 consumption.
30
71
  * Uses esbuild with stdin so no temp file is needed.
@@ -38,6 +79,9 @@ export async function bundleApp(opts: BundleOptions): Promise<BundleResult> {
38
79
  mkdirSync(outDir, { recursive: true });
39
80
  }
40
81
 
82
+ // Ensure transport.wasm is in public/
83
+ copyTransportWasm(opts.appDir, opts.monorepoRoot);
84
+
41
85
  // Resolve @magneticjs/server — in monorepo use actual path, otherwise npm package
42
86
  const alias: Record<string, string> = {};
43
87
  if (opts.monorepoRoot) {
package/src/dev.ts CHANGED
@@ -39,8 +39,23 @@ export async function startDev(opts: DevOptions): Promise<void> {
39
39
  // Find the V8 server binary
40
40
  const serverBin = opts.serverBin || findServerBinary(monorepoRoot || appDir);
41
41
  if (!serverBin) {
42
- console.error('[magnetic] Cannot find magnetic-v8-server binary.');
43
- console.error(' Build it with: cargo build --release -p magnetic-v8-server');
42
+ console.error('');
43
+ console.error(' ╔══════════════════════════════════════════════════════════════╗');
44
+ console.error(' ║ MAGNETIC: Server binary not found ║');
45
+ console.error(' ╚══════════════════════════════════════════════════════════════╝');
46
+ console.error('');
47
+ console.error(' `magnetic dev` requires the magnetic-v8-server binary.');
48
+ console.error(' It should have been downloaded during `npm install @magneticjs/cli`.');
49
+ console.error('');
50
+ console.error(' To fix:');
51
+ console.error(' npm rebuild @magneticjs/cli');
52
+ console.error('');
53
+ console.error(' Or build from source:');
54
+ console.error(' git clone https://github.com/inventhq/magnetic.git');
55
+ console.error(' cd magnetic/rs/crates/magnetic-v8-server');
56
+ console.error(' cargo build --release');
57
+ console.error(' cp target/release/magnetic-v8-server $(npm root -g)/@magneticjs/cli/bin/');
58
+ console.error('');
44
59
  process.exit(1);
45
60
  }
46
61
 
Binary file