bleam 0.0.4 → 0.0.5

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.cjs CHANGED
@@ -85,8 +85,37 @@ function parseNewOptions(argv) {
85
85
  run
86
86
  };
87
87
  }
88
+ function parseInternalMetroOptions(argv) {
89
+ let workspaceRoot;
90
+ let port = 8081;
91
+ for (let index = 0; index < argv.length; index += 1) {
92
+ const arg = argv[index];
93
+ if (arg === "--workspace-root") {
94
+ workspaceRoot = node_path.default.resolve(invocationRoot(), argv[++index] ?? "");
95
+ continue;
96
+ }
97
+ if (arg === "--port") {
98
+ port = Number(argv[++index]);
99
+ continue;
100
+ }
101
+ if (arg.startsWith("--port=")) {
102
+ port = Number(arg.slice(7));
103
+ continue;
104
+ }
105
+ throw new Error(`Unknown internal option: ${arg}`);
106
+ }
107
+ if (!workspaceRoot) throw new Error("Missing --workspace-root");
108
+ if (!Number.isInteger(port) || port <= 0) throw new Error(`Invalid port: ${port}`);
109
+ return {
110
+ workspaceRoot,
111
+ port
112
+ };
113
+ }
88
114
  function isBleamProjectRoot(projectRoot) {
89
- return (0, node_fs.existsSync)(node_path.default.join(projectRoot, "app.config.ts")) && (0, node_fs.existsSync)(node_path.default.join(projectRoot, "app.tsx"));
115
+ return (0, node_fs.existsSync)(node_path.default.join(projectRoot, "app.config.ts")) && (0, node_fs.existsSync)(node_path.default.join(projectRoot, "app", "index.tsx"));
116
+ }
117
+ function resolvedDependencyRoot() {
118
+ return node_path.default.dirname(node_path.default.dirname(require$1.resolve("react-native/package.json")));
90
119
  }
91
120
  function discoverBleamProjectRoot(searchRoot) {
92
121
  const ignoredNames = new Set([
@@ -138,7 +167,7 @@ function loadAppConfig(projectRoot) {
138
167
  ...process.env,
139
168
  NODE_PATH: [
140
169
  node_path.default.join(projectRoot, "node_modules"),
141
- node_path.default.join(packageRoot, "node_modules"),
170
+ resolvedDependencyRoot(),
142
171
  process.env.NODE_PATH
143
172
  ].filter(Boolean).join(node_path.default.delimiter)
144
173
  }
@@ -155,7 +184,12 @@ function loadAppConfig(projectRoot) {
155
184
  function assertBleamConfigFiles(projectRoot) {
156
185
  if ((0, node_fs.existsSync)(node_path.default.join(projectRoot, "app.json"))) throw new Error("Bleam projects use app.config.ts; app.json is not supported.");
157
186
  if (!(0, node_fs.existsSync)(node_path.default.join(projectRoot, "app.config.ts"))) throw new Error("Missing app.config.ts. Bleam projects must define app.config.ts.");
158
- if (!(0, node_fs.existsSync)(node_path.default.join(projectRoot, "app.tsx"))) throw new Error("Missing app.tsx. Bleam projects must define app.tsx.");
187
+ if (!(0, node_fs.existsSync)(node_path.default.join(projectRoot, "app", "index.tsx"))) throw new Error("Missing app/index.tsx. Bleam projects must define app/index.tsx.");
188
+ }
189
+ function ensureProjectTsconfig(projectRoot) {
190
+ const tsconfigPath = node_path.default.join(projectRoot, "tsconfig.json");
191
+ if ((0, node_fs.existsSync)(tsconfigPath)) return;
192
+ (0, node_fs.writeFileSync)(tsconfigPath, `${JSON.stringify({ extends: "./.bleam/dev/tsconfig.json" }, null, 2)}\n`);
159
193
  }
160
194
  function readProjectConfig(options) {
161
195
  assertBleamConfigFiles(options.projectRoot);
@@ -183,14 +217,27 @@ function createNewProject(options) {
183
217
  if ((0, node_fs.existsSync)(options.projectRoot) && (0, node_fs.readdirSync)(options.projectRoot).length > 0) throw new Error(`Directory is not empty: ${options.projectRoot}`);
184
218
  (0, node_fs.mkdirSync)(options.projectRoot, { recursive: true });
185
219
  (0, node_fs.cpSync)(templateRoot, options.projectRoot, { recursive: true });
186
- (0, node_fs.writeFileSync)(node_path.default.join(options.projectRoot, "app.config.ts"), `export default {\n name: ${JSON.stringify(nameFromDirectory(options.projectRoot))},\n}\n`);
220
+ const name = nameFromDirectory(options.projectRoot);
221
+ (0, node_fs.writeFileSync)(node_path.default.join(options.projectRoot, "app.config.ts"), `export default {\n name: ${JSON.stringify(name)},\n}\n`);
222
+ (0, node_fs.writeFileSync)(node_path.default.join(options.projectRoot, ".gitignore"), `.bleam\n`);
223
+ createDevWorkspace(options.projectRoot, {
224
+ name,
225
+ runtimeVersion,
226
+ sdkVersion: runtimeVersion
227
+ });
187
228
  console.log(`Created Bleam project at ${options.projectRoot}`);
188
229
  }
189
230
  function createDevWorkspace(projectRoot, config) {
190
231
  const workspaceRoot = node_path.default.join(projectRoot, ".bleam", "dev");
191
232
  (0, node_fs.mkdirSync)(workspaceRoot, { recursive: true });
192
233
  const workspaceNodeModules = node_path.default.join(workspaceRoot, "node_modules");
193
- if (!(0, node_fs.existsSync)(workspaceNodeModules)) (0, node_fs.symlinkSync)(node_path.default.join(packageRoot, "node_modules"), workspaceNodeModules);
234
+ const dependencyRoot = resolvedDependencyRoot();
235
+ (0, node_fs.rmSync)(workspaceNodeModules, {
236
+ recursive: true,
237
+ force: true
238
+ });
239
+ (0, node_fs.symlinkSync)(dependencyRoot, workspaceNodeModules);
240
+ ensureProjectTsconfig(projectRoot);
194
241
  (0, node_fs.writeFileSync)(node_path.default.join(workspaceRoot, "app.config.js"), `module.exports = ${JSON.stringify({ expo: {
195
242
  name: config.name,
196
243
  slug: slugFromName(config.name),
@@ -217,7 +264,18 @@ function createDevWorkspace(projectRoot, config) {
217
264
  }, null, 2)}\n`);
218
265
  (0, node_fs.writeFileSync)(node_path.default.join(workspaceRoot, "tsconfig.json"), `${JSON.stringify({
219
266
  extends: "bleam/tsconfig",
220
- include: [node_path.default.relative(workspaceRoot, node_path.default.join(projectRoot, "app.tsx")), node_path.default.relative(workspaceRoot, node_path.default.join(projectRoot, "app.config.ts"))]
267
+ compilerOptions: { paths: {
268
+ bleam: ["./node_modules/bleam"],
269
+ "bleam/*": ["./node_modules/bleam/*"],
270
+ expo: ["./node_modules/expo"],
271
+ "expo/*": ["./node_modules/expo/*"],
272
+ react: ["./node_modules/@types/react"],
273
+ "react/jsx-runtime": ["./node_modules/@types/react/jsx-runtime"],
274
+ "react/jsx-dev-runtime": ["./node_modules/@types/react/jsx-dev-runtime"],
275
+ "react-native": ["./node_modules/react-native"],
276
+ "react-native/*": ["./node_modules/react-native/*"]
277
+ } },
278
+ include: [node_path.default.relative(workspaceRoot, node_path.default.join(projectRoot, "app")), node_path.default.relative(workspaceRoot, node_path.default.join(projectRoot, "app.config.ts"))]
221
279
  }, null, 2)}\n`);
222
280
  return workspaceRoot;
223
281
  }
@@ -340,39 +398,6 @@ function copyRuntimeClient(projectRoot, runtime) {
340
398
  (0, node_fs.cpSync)(runtime.appPath, clientAppPath, { recursive: true });
341
399
  return clientAppPath;
342
400
  }
343
- function waitForDevServer(port, timeoutMs = 12e4) {
344
- return new Promise((resolve, reject) => {
345
- const startedAt = Date.now();
346
- const poll = () => {
347
- const req = node_http.default.get(`http://localhost:${port}/status`, (res) => {
348
- let data = "";
349
- res.on("data", (chunk) => {
350
- data += chunk.toString();
351
- });
352
- res.on("end", () => {
353
- if (data.includes("packager-status:running")) {
354
- resolve();
355
- return;
356
- }
357
- retry();
358
- });
359
- });
360
- req.on("error", retry);
361
- req.setTimeout(2e3, () => {
362
- req.destroy();
363
- retry();
364
- });
365
- };
366
- const retry = () => {
367
- if (Date.now() - startedAt > timeoutMs) {
368
- reject(/* @__PURE__ */ new Error(`Bleam dev server did not start within ${timeoutMs / 1e3}s`));
369
- return;
370
- }
371
- setTimeout(poll, 500);
372
- };
373
- poll();
374
- });
375
- }
376
401
  function isBleamManifest(value) {
377
402
  const manifest = value && typeof value === "object" ? value : {};
378
403
  return typeof manifest.name === "string" && typeof manifest.bundleUrl === "string" && manifest.platform === "macos" && manifest.dev === true;
@@ -380,6 +405,7 @@ function isBleamManifest(value) {
380
405
  async function readDevManifest(origin, timeoutMs = 3e4) {
381
406
  const manifestUrl = `${origin}/bleam/manifest.json`;
382
407
  const startedAt = Date.now();
408
+ console.log("Waiting for Bleam dev server...");
383
409
  while (Date.now() - startedAt <= timeoutMs) {
384
410
  try {
385
411
  const response = await fetch(manifestUrl, { cache: "no-store" });
@@ -390,8 +416,37 @@ async function readDevManifest(origin, timeoutMs = 3e4) {
390
416
  }
391
417
  throw new Error(`Bleam manifest did not become available: ${manifestUrl}`);
392
418
  }
419
+ function formatDuration(ms) {
420
+ return `${(ms / 1e3).toFixed(1)}s`;
421
+ }
422
+ async function waitForDevBundle(bundleUrl, timeoutMs = 6e4) {
423
+ const startedAt = Date.now();
424
+ const requestTimeoutMs = 3e4;
425
+ console.log("Bundling app...");
426
+ while (Date.now() - startedAt <= timeoutMs) {
427
+ const requestStartedAt = Date.now();
428
+ try {
429
+ const response = await fetch(bundleUrl, {
430
+ cache: "no-store",
431
+ signal: AbortSignal.timeout(requestTimeoutMs)
432
+ });
433
+ await response.body?.cancel();
434
+ if (response.ok) {
435
+ console.log(`Bundled app in ${formatDuration(Date.now() - startedAt)}`);
436
+ return;
437
+ }
438
+ console.log(`Bundle request returned ${response.status}, retrying...`);
439
+ } catch (error) {
440
+ if (error instanceof Error && error.name === "TimeoutError") console.log(`Bundle request timed out after ${formatDuration(Date.now() - requestStartedAt)}, retrying...`);
441
+ else console.log(`Bundle request failed: ${error instanceof Error ? error.message : String(error)}`);
442
+ }
443
+ await new Promise((resolve) => setTimeout(resolve, 500));
444
+ }
445
+ throw new Error(`Bleam bundle did not complete within ${formatDuration(timeoutMs)}: ${bundleUrl}`);
446
+ }
393
447
  function openRuntimeClient(appPath, projectConfigPath, manifest) {
394
- (0, node_child_process.spawn)("open", [
448
+ const child = (0, node_child_process.spawn)("open", [
449
+ "-n",
395
450
  appPath,
396
451
  "--args",
397
452
  "--bleam-project-config",
@@ -400,10 +455,56 @@ function openRuntimeClient(appPath, projectConfigPath, manifest) {
400
455
  manifest.bundleUrl,
401
456
  "--bleam-title",
402
457
  manifest.name
403
- ], {
404
- detached: true,
405
- stdio: "ignore"
406
- }).unref();
458
+ ], { stdio: "ignore" });
459
+ child.on("error", (error) => {
460
+ console.error(`Failed to open Bleam runtime at ${appPath}: ${error.message}`);
461
+ });
462
+ child.on("exit", (code) => {
463
+ if (code && code !== 0) console.error(`Failed to open Bleam runtime at ${appPath}`);
464
+ });
465
+ }
466
+ async function startInternalMetroServer(options) {
467
+ const metro = require$1("@expo/metro/metro");
468
+ const { loadConfig } = require$1("@expo/metro/metro-config");
469
+ const config = await loadConfig({
470
+ config: node_path.default.join(options.workspaceRoot, "metro.config.js"),
471
+ cwd: options.workspaceRoot,
472
+ port: options.port
473
+ });
474
+ const { middleware, end, attachHmrServer } = await metro.createConnectMiddleware(config, {
475
+ watch: true,
476
+ waitForBundler: true
477
+ });
478
+ const server = node_http.default.createServer((req, res) => {
479
+ if (req.url?.split("?")[0] === "/status") {
480
+ res.writeHead(200, {
481
+ "Cache-Control": "no-store",
482
+ "Content-Type": "text/plain; charset=utf-8",
483
+ "X-React-Native-Project-Root": encodeURI(config.projectRoot)
484
+ });
485
+ res.end("packager-status:running");
486
+ return;
487
+ }
488
+ middleware(req, res);
489
+ });
490
+ server.timeout = 0;
491
+ attachHmrServer(server);
492
+ await new Promise((resolve, reject) => {
493
+ server.on("error", reject);
494
+ server.listen(options.port, "localhost", () => resolve());
495
+ });
496
+ server.on("error", (error) => {
497
+ console.error(error instanceof Error ? error.message : String(error));
498
+ });
499
+ console.log(`Bleam dev server running at http://localhost:${options.port}`);
500
+ const close = () => {
501
+ server.close(() => {
502
+ end();
503
+ process.exit(0);
504
+ });
505
+ };
506
+ process.on("SIGINT", close);
507
+ process.on("SIGTERM", close);
407
508
  }
408
509
  async function startDevServer(options) {
409
510
  const config = readProjectConfig(options);
@@ -413,10 +514,10 @@ async function startDevServer(options) {
413
514
  const origin = `http://localhost:${options.port}`;
414
515
  const projectConfigPath = writeProjectRuntimeConfig(options.projectRoot, config, origin);
415
516
  const child = (0, node_child_process.spawn)(process.execPath, [
416
- require$1.resolve("expo/bin/cli"),
417
- "start",
517
+ (0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href),
518
+ "internal:metro",
519
+ "--workspace-root",
418
520
  workspaceRoot,
419
- "--localhost",
420
521
  "--port",
421
522
  String(options.port)
422
523
  ], {
@@ -432,7 +533,7 @@ async function startDevServer(options) {
432
533
  BLEAM_DEV_SDK_VERSION: config.sdkVersion,
433
534
  NODE_PATH: [
434
535
  node_path.default.join(options.projectRoot, "node_modules"),
435
- node_path.default.join(packageRoot, "node_modules"),
536
+ resolvedDependencyRoot(),
436
537
  node_path.default.dirname(node_path.default.dirname(require$1.resolve("expo/package.json"))),
437
538
  node_path.default.dirname(node_path.default.dirname(require$1.resolve("react/package.json"))),
438
539
  node_path.default.dirname(node_path.default.dirname(require$1.resolve("react-native/package.json"))),
@@ -446,9 +547,17 @@ async function startDevServer(options) {
446
547
  process.on("SIGINT", () => stop("SIGINT"));
447
548
  process.on("SIGTERM", () => stop("SIGTERM"));
448
549
  child.on("exit", (code) => process.exit(code ?? 0));
449
- await waitForDevServer(options.port);
450
- const manifest = await readDevManifest(origin);
451
- if (process.env.BLEAM_NO_OPEN !== "1") openRuntimeClient(clientAppPath, projectConfigPath, manifest);
550
+ try {
551
+ const manifest = await readDevManifest(origin);
552
+ if (process.env.BLEAM_NO_OPEN !== "1") {
553
+ await waitForDevBundle(manifest.bundleUrl);
554
+ console.log("Opening Bleam app...");
555
+ openRuntimeClient(clientAppPath, projectConfigPath, manifest);
556
+ }
557
+ } catch (error) {
558
+ child.kill("SIGTERM");
559
+ throw error;
560
+ }
452
561
  }
453
562
  async function main(argv = process.argv.slice(2)) {
454
563
  const [command, ...args] = argv;
@@ -469,6 +578,10 @@ async function main(argv = process.argv.slice(2)) {
469
578
  await startDevServer(parseDevOptions(args));
470
579
  return;
471
580
  }
581
+ if (command === "internal:metro") {
582
+ await startInternalMetroServer(parseInternalMetroOptions(args));
583
+ return;
584
+ }
472
585
  throw new Error(`Unknown command: ${command}`);
473
586
  }
474
587
  main().catch((error) => {
package/dist/cli.js CHANGED
@@ -76,8 +76,37 @@ function parseNewOptions(argv) {
76
76
  run
77
77
  };
78
78
  }
79
+ function parseInternalMetroOptions(argv) {
80
+ let workspaceRoot;
81
+ let port = 8081;
82
+ for (let index = 0; index < argv.length; index += 1) {
83
+ const arg = argv[index];
84
+ if (arg === "--workspace-root") {
85
+ workspaceRoot = path.resolve(invocationRoot(), argv[++index] ?? "");
86
+ continue;
87
+ }
88
+ if (arg === "--port") {
89
+ port = Number(argv[++index]);
90
+ continue;
91
+ }
92
+ if (arg.startsWith("--port=")) {
93
+ port = Number(arg.slice(7));
94
+ continue;
95
+ }
96
+ throw new Error(`Unknown internal option: ${arg}`);
97
+ }
98
+ if (!workspaceRoot) throw new Error("Missing --workspace-root");
99
+ if (!Number.isInteger(port) || port <= 0) throw new Error(`Invalid port: ${port}`);
100
+ return {
101
+ workspaceRoot,
102
+ port
103
+ };
104
+ }
79
105
  function isBleamProjectRoot(projectRoot) {
80
- return existsSync(path.join(projectRoot, "app.config.ts")) && existsSync(path.join(projectRoot, "app.tsx"));
106
+ return existsSync(path.join(projectRoot, "app.config.ts")) && existsSync(path.join(projectRoot, "app", "index.tsx"));
107
+ }
108
+ function resolvedDependencyRoot() {
109
+ return path.dirname(path.dirname(require.resolve("react-native/package.json")));
81
110
  }
82
111
  function discoverBleamProjectRoot(searchRoot) {
83
112
  const ignoredNames = new Set([
@@ -129,7 +158,7 @@ function loadAppConfig(projectRoot) {
129
158
  ...process.env,
130
159
  NODE_PATH: [
131
160
  path.join(projectRoot, "node_modules"),
132
- path.join(packageRoot, "node_modules"),
161
+ resolvedDependencyRoot(),
133
162
  process.env.NODE_PATH
134
163
  ].filter(Boolean).join(path.delimiter)
135
164
  }
@@ -146,7 +175,12 @@ function loadAppConfig(projectRoot) {
146
175
  function assertBleamConfigFiles(projectRoot) {
147
176
  if (existsSync(path.join(projectRoot, "app.json"))) throw new Error("Bleam projects use app.config.ts; app.json is not supported.");
148
177
  if (!existsSync(path.join(projectRoot, "app.config.ts"))) throw new Error("Missing app.config.ts. Bleam projects must define app.config.ts.");
149
- if (!existsSync(path.join(projectRoot, "app.tsx"))) throw new Error("Missing app.tsx. Bleam projects must define app.tsx.");
178
+ if (!existsSync(path.join(projectRoot, "app", "index.tsx"))) throw new Error("Missing app/index.tsx. Bleam projects must define app/index.tsx.");
179
+ }
180
+ function ensureProjectTsconfig(projectRoot) {
181
+ const tsconfigPath = path.join(projectRoot, "tsconfig.json");
182
+ if (existsSync(tsconfigPath)) return;
183
+ writeFileSync(tsconfigPath, `${JSON.stringify({ extends: "./.bleam/dev/tsconfig.json" }, null, 2)}\n`);
150
184
  }
151
185
  function readProjectConfig(options) {
152
186
  assertBleamConfigFiles(options.projectRoot);
@@ -174,14 +208,27 @@ function createNewProject(options) {
174
208
  if (existsSync(options.projectRoot) && readdirSync(options.projectRoot).length > 0) throw new Error(`Directory is not empty: ${options.projectRoot}`);
175
209
  mkdirSync(options.projectRoot, { recursive: true });
176
210
  cpSync(templateRoot, options.projectRoot, { recursive: true });
177
- writeFileSync(path.join(options.projectRoot, "app.config.ts"), `export default {\n name: ${JSON.stringify(nameFromDirectory(options.projectRoot))},\n}\n`);
211
+ const name = nameFromDirectory(options.projectRoot);
212
+ writeFileSync(path.join(options.projectRoot, "app.config.ts"), `export default {\n name: ${JSON.stringify(name)},\n}\n`);
213
+ writeFileSync(path.join(options.projectRoot, ".gitignore"), `.bleam\n`);
214
+ createDevWorkspace(options.projectRoot, {
215
+ name,
216
+ runtimeVersion,
217
+ sdkVersion: runtimeVersion
218
+ });
178
219
  console.log(`Created Bleam project at ${options.projectRoot}`);
179
220
  }
180
221
  function createDevWorkspace(projectRoot, config) {
181
222
  const workspaceRoot = path.join(projectRoot, ".bleam", "dev");
182
223
  mkdirSync(workspaceRoot, { recursive: true });
183
224
  const workspaceNodeModules = path.join(workspaceRoot, "node_modules");
184
- if (!existsSync(workspaceNodeModules)) symlinkSync(path.join(packageRoot, "node_modules"), workspaceNodeModules);
225
+ const dependencyRoot = resolvedDependencyRoot();
226
+ rmSync(workspaceNodeModules, {
227
+ recursive: true,
228
+ force: true
229
+ });
230
+ symlinkSync(dependencyRoot, workspaceNodeModules);
231
+ ensureProjectTsconfig(projectRoot);
185
232
  writeFileSync(path.join(workspaceRoot, "app.config.js"), `module.exports = ${JSON.stringify({ expo: {
186
233
  name: config.name,
187
234
  slug: slugFromName(config.name),
@@ -208,7 +255,18 @@ function createDevWorkspace(projectRoot, config) {
208
255
  }, null, 2)}\n`);
209
256
  writeFileSync(path.join(workspaceRoot, "tsconfig.json"), `${JSON.stringify({
210
257
  extends: "bleam/tsconfig",
211
- include: [path.relative(workspaceRoot, path.join(projectRoot, "app.tsx")), path.relative(workspaceRoot, path.join(projectRoot, "app.config.ts"))]
258
+ compilerOptions: { paths: {
259
+ bleam: ["./node_modules/bleam"],
260
+ "bleam/*": ["./node_modules/bleam/*"],
261
+ expo: ["./node_modules/expo"],
262
+ "expo/*": ["./node_modules/expo/*"],
263
+ react: ["./node_modules/@types/react"],
264
+ "react/jsx-runtime": ["./node_modules/@types/react/jsx-runtime"],
265
+ "react/jsx-dev-runtime": ["./node_modules/@types/react/jsx-dev-runtime"],
266
+ "react-native": ["./node_modules/react-native"],
267
+ "react-native/*": ["./node_modules/react-native/*"]
268
+ } },
269
+ include: [path.relative(workspaceRoot, path.join(projectRoot, "app")), path.relative(workspaceRoot, path.join(projectRoot, "app.config.ts"))]
212
270
  }, null, 2)}\n`);
213
271
  return workspaceRoot;
214
272
  }
@@ -331,39 +389,6 @@ function copyRuntimeClient(projectRoot, runtime) {
331
389
  cpSync(runtime.appPath, clientAppPath, { recursive: true });
332
390
  return clientAppPath;
333
391
  }
334
- function waitForDevServer(port, timeoutMs = 12e4) {
335
- return new Promise((resolve, reject) => {
336
- const startedAt = Date.now();
337
- const poll = () => {
338
- const req = http.get(`http://localhost:${port}/status`, (res) => {
339
- let data = "";
340
- res.on("data", (chunk) => {
341
- data += chunk.toString();
342
- });
343
- res.on("end", () => {
344
- if (data.includes("packager-status:running")) {
345
- resolve();
346
- return;
347
- }
348
- retry();
349
- });
350
- });
351
- req.on("error", retry);
352
- req.setTimeout(2e3, () => {
353
- req.destroy();
354
- retry();
355
- });
356
- };
357
- const retry = () => {
358
- if (Date.now() - startedAt > timeoutMs) {
359
- reject(/* @__PURE__ */ new Error(`Bleam dev server did not start within ${timeoutMs / 1e3}s`));
360
- return;
361
- }
362
- setTimeout(poll, 500);
363
- };
364
- poll();
365
- });
366
- }
367
392
  function isBleamManifest(value) {
368
393
  const manifest = value && typeof value === "object" ? value : {};
369
394
  return typeof manifest.name === "string" && typeof manifest.bundleUrl === "string" && manifest.platform === "macos" && manifest.dev === true;
@@ -371,6 +396,7 @@ function isBleamManifest(value) {
371
396
  async function readDevManifest(origin, timeoutMs = 3e4) {
372
397
  const manifestUrl = `${origin}/bleam/manifest.json`;
373
398
  const startedAt = Date.now();
399
+ console.log("Waiting for Bleam dev server...");
374
400
  while (Date.now() - startedAt <= timeoutMs) {
375
401
  try {
376
402
  const response = await fetch(manifestUrl, { cache: "no-store" });
@@ -381,8 +407,37 @@ async function readDevManifest(origin, timeoutMs = 3e4) {
381
407
  }
382
408
  throw new Error(`Bleam manifest did not become available: ${manifestUrl}`);
383
409
  }
410
+ function formatDuration(ms) {
411
+ return `${(ms / 1e3).toFixed(1)}s`;
412
+ }
413
+ async function waitForDevBundle(bundleUrl, timeoutMs = 6e4) {
414
+ const startedAt = Date.now();
415
+ const requestTimeoutMs = 3e4;
416
+ console.log("Bundling app...");
417
+ while (Date.now() - startedAt <= timeoutMs) {
418
+ const requestStartedAt = Date.now();
419
+ try {
420
+ const response = await fetch(bundleUrl, {
421
+ cache: "no-store",
422
+ signal: AbortSignal.timeout(requestTimeoutMs)
423
+ });
424
+ await response.body?.cancel();
425
+ if (response.ok) {
426
+ console.log(`Bundled app in ${formatDuration(Date.now() - startedAt)}`);
427
+ return;
428
+ }
429
+ console.log(`Bundle request returned ${response.status}, retrying...`);
430
+ } catch (error) {
431
+ if (error instanceof Error && error.name === "TimeoutError") console.log(`Bundle request timed out after ${formatDuration(Date.now() - requestStartedAt)}, retrying...`);
432
+ else console.log(`Bundle request failed: ${error instanceof Error ? error.message : String(error)}`);
433
+ }
434
+ await new Promise((resolve) => setTimeout(resolve, 500));
435
+ }
436
+ throw new Error(`Bleam bundle did not complete within ${formatDuration(timeoutMs)}: ${bundleUrl}`);
437
+ }
384
438
  function openRuntimeClient(appPath, projectConfigPath, manifest) {
385
- spawn("open", [
439
+ const child = spawn("open", [
440
+ "-n",
386
441
  appPath,
387
442
  "--args",
388
443
  "--bleam-project-config",
@@ -391,10 +446,56 @@ function openRuntimeClient(appPath, projectConfigPath, manifest) {
391
446
  manifest.bundleUrl,
392
447
  "--bleam-title",
393
448
  manifest.name
394
- ], {
395
- detached: true,
396
- stdio: "ignore"
397
- }).unref();
449
+ ], { stdio: "ignore" });
450
+ child.on("error", (error) => {
451
+ console.error(`Failed to open Bleam runtime at ${appPath}: ${error.message}`);
452
+ });
453
+ child.on("exit", (code) => {
454
+ if (code && code !== 0) console.error(`Failed to open Bleam runtime at ${appPath}`);
455
+ });
456
+ }
457
+ async function startInternalMetroServer(options) {
458
+ const metro = require("@expo/metro/metro");
459
+ const { loadConfig } = require("@expo/metro/metro-config");
460
+ const config = await loadConfig({
461
+ config: path.join(options.workspaceRoot, "metro.config.js"),
462
+ cwd: options.workspaceRoot,
463
+ port: options.port
464
+ });
465
+ const { middleware, end, attachHmrServer } = await metro.createConnectMiddleware(config, {
466
+ watch: true,
467
+ waitForBundler: true
468
+ });
469
+ const server = http.createServer((req, res) => {
470
+ if (req.url?.split("?")[0] === "/status") {
471
+ res.writeHead(200, {
472
+ "Cache-Control": "no-store",
473
+ "Content-Type": "text/plain; charset=utf-8",
474
+ "X-React-Native-Project-Root": encodeURI(config.projectRoot)
475
+ });
476
+ res.end("packager-status:running");
477
+ return;
478
+ }
479
+ middleware(req, res);
480
+ });
481
+ server.timeout = 0;
482
+ attachHmrServer(server);
483
+ await new Promise((resolve, reject) => {
484
+ server.on("error", reject);
485
+ server.listen(options.port, "localhost", () => resolve());
486
+ });
487
+ server.on("error", (error) => {
488
+ console.error(error instanceof Error ? error.message : String(error));
489
+ });
490
+ console.log(`Bleam dev server running at http://localhost:${options.port}`);
491
+ const close = () => {
492
+ server.close(() => {
493
+ end();
494
+ process.exit(0);
495
+ });
496
+ };
497
+ process.on("SIGINT", close);
498
+ process.on("SIGTERM", close);
398
499
  }
399
500
  async function startDevServer(options) {
400
501
  const config = readProjectConfig(options);
@@ -404,10 +505,10 @@ async function startDevServer(options) {
404
505
  const origin = `http://localhost:${options.port}`;
405
506
  const projectConfigPath = writeProjectRuntimeConfig(options.projectRoot, config, origin);
406
507
  const child = spawn(process.execPath, [
407
- require.resolve("expo/bin/cli"),
408
- "start",
508
+ fileURLToPath(import.meta.url),
509
+ "internal:metro",
510
+ "--workspace-root",
409
511
  workspaceRoot,
410
- "--localhost",
411
512
  "--port",
412
513
  String(options.port)
413
514
  ], {
@@ -423,7 +524,7 @@ async function startDevServer(options) {
423
524
  BLEAM_DEV_SDK_VERSION: config.sdkVersion,
424
525
  NODE_PATH: [
425
526
  path.join(options.projectRoot, "node_modules"),
426
- path.join(packageRoot, "node_modules"),
527
+ resolvedDependencyRoot(),
427
528
  path.dirname(path.dirname(require.resolve("expo/package.json"))),
428
529
  path.dirname(path.dirname(require.resolve("react/package.json"))),
429
530
  path.dirname(path.dirname(require.resolve("react-native/package.json"))),
@@ -437,9 +538,17 @@ async function startDevServer(options) {
437
538
  process.on("SIGINT", () => stop("SIGINT"));
438
539
  process.on("SIGTERM", () => stop("SIGTERM"));
439
540
  child.on("exit", (code) => process.exit(code ?? 0));
440
- await waitForDevServer(options.port);
441
- const manifest = await readDevManifest(origin);
442
- if (process.env.BLEAM_NO_OPEN !== "1") openRuntimeClient(clientAppPath, projectConfigPath, manifest);
541
+ try {
542
+ const manifest = await readDevManifest(origin);
543
+ if (process.env.BLEAM_NO_OPEN !== "1") {
544
+ await waitForDevBundle(manifest.bundleUrl);
545
+ console.log("Opening Bleam app...");
546
+ openRuntimeClient(clientAppPath, projectConfigPath, manifest);
547
+ }
548
+ } catch (error) {
549
+ child.kill("SIGTERM");
550
+ throw error;
551
+ }
443
552
  }
444
553
  async function main(argv = process.argv.slice(2)) {
445
554
  const [command, ...args] = argv;
@@ -460,6 +569,10 @@ async function main(argv = process.argv.slice(2)) {
460
569
  await startDevServer(parseDevOptions(args));
461
570
  return;
462
571
  }
572
+ if (command === "internal:metro") {
573
+ await startInternalMetroServer(parseInternalMetroOptions(args));
574
+ return;
575
+ }
463
576
  throw new Error(`Unknown command: ${command}`);
464
577
  }
465
578
  main().catch((error) => {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":["matches: string[]","value: unknown"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { execFileSync, spawn, spawnSync } from 'node:child_process'\nimport { createHash } from 'node:crypto'\nimport {\n cpSync,\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n rmSync,\n symlinkSync,\n writeFileSync,\n} from 'node:fs'\nimport http from 'node:http'\nimport { createRequire } from 'node:module'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\n\nimport type { BleamConfig } from './config'\n\ninterface DevOptions {\n projectRoot: string\n port: number\n}\n\ninterface NewOptions {\n projectRoot: string\n run: boolean\n}\n\ninterface ProjectConfig {\n name: string\n version?: string\n bundleIdentifier?: string\n teamId?: string\n runtimeVersion: string\n sdkVersion: string\n}\n\ninterface RuntimeArtifact {\n appPath: string\n version: string\n platform: string\n}\n\ninterface BleamManifest {\n name: string\n bundleUrl: string\n platform: 'macos'\n dev: boolean\n}\n\nconst require = createRequire(import.meta.url)\nconst packageRoot = path.dirname(\n fileURLToPath(new URL('../package.json', import.meta.url)),\n)\nconst packageJson = require('../package.json') as {\n version: string\n dependencies?: Record<string, string>\n}\nconst runtimeVersion = packageJson.version\nconst runtimePlatform = `macos-${process.arch}`\n\nfunction printUsage() {\n console.log(`Usage: bleam <command>\n\nCommands:\n new [dir] [--run] Create a new Bleam project\n dev [dir] [--port <port>] Start a Bleam dev server`)\n}\n\nfunction invocationRoot() {\n return path.isAbsolute(process.env.PWD ?? '')\n ? process.env.PWD!\n : process.cwd()\n}\n\nfunction parseDevOptions(argv: string[]): DevOptions {\n const root = invocationRoot()\n let projectRoot = root\n let port = 8081\n let hasProjectRootArg = false\n\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index]\n\n if (arg === '--port' || arg === '-p') {\n const value = argv[++index]\n port = Number(value)\n continue\n }\n\n if (arg.startsWith('--port=')) {\n port = Number(arg.slice('--port='.length))\n continue\n }\n\n if (arg === '--help' || arg === '-h') {\n printUsage()\n process.exit(0)\n }\n\n if (arg.startsWith('-')) {\n throw new Error(`Unknown option: ${arg}`)\n }\n\n projectRoot = path.resolve(root, arg)\n hasProjectRootArg = true\n }\n\n if (!Number.isInteger(port) || port <= 0) {\n throw new Error(`Invalid port: ${port}`)\n }\n\n if (!hasProjectRootArg && !isBleamProjectRoot(projectRoot)) {\n projectRoot = discoverBleamProjectRoot(projectRoot) ?? projectRoot\n }\n\n return { projectRoot: path.resolve(projectRoot), port }\n}\n\nfunction parseNewOptions(argv: string[]): NewOptions {\n const root = invocationRoot()\n let projectRoot = root\n let run = false\n\n for (const arg of argv) {\n if (arg === '--run') {\n run = true\n continue\n }\n\n if (arg === '--help' || arg === '-h') {\n printUsage()\n process.exit(0)\n }\n\n if (arg.startsWith('-')) {\n throw new Error(`Unknown option: ${arg}`)\n }\n\n projectRoot = path.resolve(root, arg)\n }\n\n return { projectRoot, run }\n}\n\nfunction isBleamProjectRoot(projectRoot: string) {\n return (\n existsSync(path.join(projectRoot, 'app.config.ts')) &&\n existsSync(path.join(projectRoot, 'app.tsx'))\n )\n}\n\nfunction discoverBleamProjectRoot(searchRoot: string) {\n const ignoredNames = new Set([\n '.bleam',\n '.expo',\n '.git',\n '.yarn',\n 'build',\n 'dist',\n 'node_modules',\n 'templates',\n ])\n const matches: string[] = []\n\n function visit(directory: string) {\n if (matches.length > 1) {\n return\n }\n\n if (isBleamProjectRoot(directory)) {\n matches.push(directory)\n return\n }\n\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n if (!entry.isDirectory() || ignoredNames.has(entry.name)) {\n continue\n }\n\n visit(path.join(directory, entry.name))\n }\n }\n\n visit(searchRoot)\n\n if (matches.length > 1) {\n throw new Error('Multiple Bleam projects found. Run bleam dev <dir>.')\n }\n\n return matches[0]\n}\n\nfunction assertStringField(value: unknown, field: keyof BleamConfig): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new Error(`app.config.ts must define ${field}`)\n }\n return value\n}\n\nfunction loadAppConfig(projectRoot: string): BleamConfig {\n const configPath = path.join(projectRoot, 'app.config.ts')\n const loader = `\n const mod = await import(${JSON.stringify(pathToFileURL(configPath).href)});\n const config = mod.default?.default ?? mod.default ?? mod;\n process.stdout.write(JSON.stringify(config));\n `\n\n const result = spawnSync(\n process.execPath,\n ['--import', require.resolve('tsx'), '--eval', loader],\n {\n cwd: projectRoot,\n encoding: 'utf8',\n env: {\n ...process.env,\n NODE_PATH: [\n path.join(projectRoot, 'node_modules'),\n path.join(packageRoot, 'node_modules'),\n process.env.NODE_PATH,\n ]\n .filter(Boolean)\n .join(path.delimiter),\n },\n },\n )\n\n if (result.status !== 0) {\n throw new Error(result.stderr.trim() || 'Failed to load app.config.ts')\n }\n\n const value = JSON.parse(result.stdout) as Partial<BleamConfig>\n return {\n name: assertStringField(value.name, 'name'),\n version: typeof value.version === 'string' ? value.version : undefined,\n bundleIdentifier:\n typeof value.bundleIdentifier === 'string'\n ? value.bundleIdentifier\n : undefined,\n teamId: typeof value.teamId === 'string' ? value.teamId : undefined,\n }\n}\n\nfunction assertBleamConfigFiles(projectRoot: string) {\n if (existsSync(path.join(projectRoot, 'app.json'))) {\n throw new Error(\n 'Bleam projects use app.config.ts; app.json is not supported.',\n )\n }\n\n if (!existsSync(path.join(projectRoot, 'app.config.ts'))) {\n throw new Error(\n 'Missing app.config.ts. Bleam projects must define app.config.ts.',\n )\n }\n\n if (!existsSync(path.join(projectRoot, 'app.tsx'))) {\n throw new Error('Missing app.tsx. Bleam projects must define app.tsx.')\n }\n}\n\nfunction readProjectConfig(options: DevOptions): ProjectConfig {\n assertBleamConfigFiles(options.projectRoot)\n const config = loadAppConfig(options.projectRoot)\n\n return {\n name: config.name,\n version: config.version,\n bundleIdentifier: config.bundleIdentifier,\n teamId: config.teamId,\n runtimeVersion,\n sdkVersion: runtimeVersion,\n }\n}\n\nfunction slugFromName(name: string) {\n return (\n name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '') || 'bleam-app'\n )\n}\n\nfunction nameFromDirectory(projectRoot: string) {\n const name = path.basename(projectRoot).replace(/[-_]+/g, ' ').trim()\n if (!name) {\n return 'Bleam App'\n }\n\n return name.replace(/\\b\\w/g, (letter) => letter.toUpperCase())\n}\n\nfunction createNewProject(options: NewOptions) {\n const templateRoot = path.join(packageRoot, 'templates', 'basic')\n\n if (!existsSync(templateRoot)) {\n throw new Error(`Missing basic template: ${templateRoot}`)\n }\n\n if (\n existsSync(options.projectRoot) &&\n readdirSync(options.projectRoot).length > 0\n ) {\n throw new Error(`Directory is not empty: ${options.projectRoot}`)\n }\n\n mkdirSync(options.projectRoot, { recursive: true })\n cpSync(templateRoot, options.projectRoot, { recursive: true })\n writeFileSync(\n path.join(options.projectRoot, 'app.config.ts'),\n `export default {\\n name: ${JSON.stringify(nameFromDirectory(options.projectRoot))},\\n}\\n`,\n )\n\n console.log(`Created Bleam project at ${options.projectRoot}`)\n}\n\nfunction createDevWorkspace(projectRoot: string, config: ProjectConfig) {\n const workspaceRoot = path.join(projectRoot, '.bleam', 'dev')\n mkdirSync(workspaceRoot, { recursive: true })\n const workspaceNodeModules = path.join(workspaceRoot, 'node_modules')\n if (!existsSync(workspaceNodeModules)) {\n symlinkSync(path.join(packageRoot, 'node_modules'), workspaceNodeModules)\n }\n\n writeFileSync(\n path.join(workspaceRoot, 'app.config.js'),\n `module.exports = ${JSON.stringify(\n {\n expo: {\n name: config.name,\n slug: slugFromName(config.name),\n version: config.version ?? '0.0.0',\n orientation: 'default',\n platforms: ['ios'],\n newArchEnabled: true,\n },\n },\n null,\n 2,\n )}\\n`,\n )\n\n writeFileSync(\n path.join(workspaceRoot, 'index.js'),\n `import { registerApp } from 'bleam/app'\\nimport App from ${JSON.stringify(path.join(projectRoot, 'app'))}\\n\\nregisterApp(App)\\n`,\n )\n\n writeFileSync(\n path.join(workspaceRoot, 'metro.config.js'),\n `const { getDefaultConfig } = require(${JSON.stringify(path.join(packageRoot, 'metro-config.cjs'))})\\n\\nmodule.exports = getDefaultConfig(__dirname)\\n`,\n )\n\n writeFileSync(\n path.join(workspaceRoot, 'package.json'),\n `${JSON.stringify(\n {\n name: `${slugFromName(config.name)}-bleam-dev`,\n version: config.version ?? '0.0.0',\n private: true,\n main: 'index.js',\n dependencies: {\n '@types/react': packageJson.dependencies?.['@types/react'],\n expo: packageJson.dependencies?.expo,\n react: packageJson.dependencies?.react,\n 'react-native': packageJson.dependencies?.['react-native'],\n typescript: packageJson.dependencies?.typescript,\n },\n expo: {\n install: {\n exclude: ['typescript'],\n },\n },\n },\n null,\n 2,\n )}\\n`,\n )\n\n writeFileSync(\n path.join(workspaceRoot, 'tsconfig.json'),\n `${JSON.stringify(\n {\n extends: 'bleam/tsconfig',\n include: [\n path.relative(workspaceRoot, path.join(projectRoot, 'app.tsx')),\n path.relative(workspaceRoot, path.join(projectRoot, 'app.config.ts')),\n ],\n },\n null,\n 2,\n )}\\n`,\n )\n\n return workspaceRoot\n}\n\nfunction writeProjectRuntimeConfig(\n projectRoot: string,\n config: ProjectConfig,\n origin: string,\n) {\n const projectConfigPath = path.join(projectRoot, '.bleam', 'project.json')\n mkdirSync(path.dirname(projectConfigPath), { recursive: true })\n writeFileSync(\n projectConfigPath,\n `${JSON.stringify(\n {\n name: config.name,\n version: config.version,\n bundleIdentifier: config.bundleIdentifier,\n teamId: config.teamId,\n devServer: origin,\n runtimeVersion: config.runtimeVersion,\n sdkVersion: config.sdkVersion,\n },\n null,\n 2,\n )}\\n`,\n )\n return projectConfigPath\n}\n\nfunction runtimeCacheRoot() {\n return path.join(\n os.homedir(),\n 'Library',\n 'Caches',\n 'bleam',\n 'runtimes',\n runtimeVersion,\n runtimePlatform,\n )\n}\n\nfunction localDevelopmentRuntimeAppPath() {\n return path.resolve(\n packageRoot,\n '..',\n '..',\n 'app',\n 'bleam',\n 'build',\n 'Build',\n 'Products',\n 'Debug-maccatalyst',\n 'Bleam.app',\n )\n}\n\nfunction runtimeReleaseBaseUrl() {\n return (\n process.env.BLEAM_RUNTIME_RELEASE_BASE_URL ??\n 'https://github.com/bajedev/bleam-app/releases/download'\n )\n}\n\nfunction runtimeArchiveName() {\n return `bleam-runtime-v${runtimeVersion}-${runtimePlatform}.zip`\n}\n\nfunction runtimeArchiveUrl() {\n const tag = encodeURIComponent(`bleam@${runtimeVersion}`)\n return `${runtimeReleaseBaseUrl()}/${tag}/${runtimeArchiveName()}`\n}\n\nfunction sha256(filePath: string) {\n return createHash('sha256').update(readFileSync(filePath)).digest('hex')\n}\n\nasync function downloadFile(url: string, destination: string) {\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(\n `Failed to download ${url}: ${response.status} ${response.statusText}`,\n )\n }\n\n const bytes = new Uint8Array(await response.arrayBuffer())\n writeFileSync(destination, bytes)\n}\n\nasync function downloadExpectedSha256(url: string) {\n const response = await fetch(`${url}.sha256`)\n if (!response.ok) {\n return undefined\n }\n\n const text = await response.text()\n return text.trim().split(/\\s+/)[0]\n}\n\nasync function downloadRuntimeArtifact(): Promise<RuntimeArtifact> {\n if (process.platform !== 'darwin') {\n throw new Error(\n 'Bleam runtime artifacts are currently only available on macOS.',\n )\n }\n\n const cacheRoot = runtimeCacheRoot()\n const cachedAppPath = path.join(cacheRoot, 'Bleam.app')\n if (existsSync(cachedAppPath)) {\n return {\n appPath: cachedAppPath,\n version: runtimeVersion,\n platform: runtimePlatform,\n }\n }\n\n mkdirSync(cacheRoot, { recursive: true })\n const archiveUrl = runtimeArchiveUrl()\n const archivePath = path.join(cacheRoot, runtimeArchiveName())\n const extractRoot = path.join(cacheRoot, 'extract')\n\n await downloadFile(archiveUrl, archivePath)\n const expectedSha256 = await downloadExpectedSha256(archiveUrl)\n if (expectedSha256 && sha256(archivePath) !== expectedSha256) {\n rmSync(archivePath, { force: true })\n throw new Error(`Runtime artifact checksum mismatch: ${archiveUrl}`)\n }\n\n rmSync(extractRoot, { recursive: true, force: true })\n mkdirSync(extractRoot, { recursive: true })\n execFileSync('ditto', ['-x', '-k', archivePath, extractRoot], {\n stdio: 'ignore',\n })\n\n const extractedAppPath = path.join(extractRoot, 'Bleam.app')\n if (!existsSync(extractedAppPath)) {\n throw new Error(`Runtime archive did not contain Bleam.app: ${archiveUrl}`)\n }\n\n rmSync(cachedAppPath, { recursive: true, force: true })\n cpSync(extractedAppPath, cachedAppPath, { recursive: true })\n rmSync(extractRoot, { recursive: true, force: true })\n\n return {\n appPath: cachedAppPath,\n version: runtimeVersion,\n platform: runtimePlatform,\n }\n}\n\nasync function resolveRuntimeArtifact(): Promise<RuntimeArtifact> {\n const overrideAppPath = process.env.BLEAM_RUNTIME_APP\n if (overrideAppPath) {\n const appPath = path.resolve(overrideAppPath)\n if (!existsSync(appPath)) {\n throw new Error(`BLEAM_RUNTIME_APP does not exist: ${appPath}`)\n }\n\n return { appPath, version: runtimeVersion, platform: runtimePlatform }\n }\n\n const localAppPath = localDevelopmentRuntimeAppPath()\n if (existsSync(localAppPath)) {\n return {\n appPath: localAppPath,\n version: runtimeVersion,\n platform: runtimePlatform,\n }\n }\n\n return downloadRuntimeArtifact()\n}\n\nfunction copyRuntimeClient(projectRoot: string, runtime: RuntimeArtifact) {\n const clientAppPath = path.join(projectRoot, '.bleam', 'client', 'Bleam.app')\n rmSync(clientAppPath, { recursive: true, force: true })\n mkdirSync(path.dirname(clientAppPath), { recursive: true })\n cpSync(runtime.appPath, clientAppPath, { recursive: true })\n return clientAppPath\n}\n\nfunction waitForDevServer(port: number, timeoutMs = 120_000) {\n return new Promise<void>((resolve, reject) => {\n const startedAt = Date.now()\n\n const poll = () => {\n const req = http.get(`http://localhost:${port}/status`, (res) => {\n let data = ''\n res.on('data', (chunk) => {\n data += chunk.toString()\n })\n res.on('end', () => {\n if (data.includes('packager-status:running')) {\n resolve()\n return\n }\n\n retry()\n })\n })\n\n req.on('error', retry)\n req.setTimeout(2_000, () => {\n req.destroy()\n retry()\n })\n }\n\n const retry = () => {\n if (Date.now() - startedAt > timeoutMs) {\n reject(\n new Error(\n `Bleam dev server did not start within ${timeoutMs / 1000}s`,\n ),\n )\n return\n }\n\n setTimeout(poll, 500)\n }\n\n poll()\n })\n}\n\nfunction isBleamManifest(value: unknown): value is BleamManifest {\n const manifest =\n value && typeof value === 'object' ? (value as Partial<BleamManifest>) : {}\n\n return (\n typeof manifest.name === 'string' &&\n typeof manifest.bundleUrl === 'string' &&\n manifest.platform === 'macos' &&\n manifest.dev === true\n )\n}\n\nasync function readDevManifest(origin: string, timeoutMs = 30_000) {\n const manifestUrl = `${origin}/bleam/manifest.json`\n const startedAt = Date.now()\n\n while (Date.now() - startedAt <= timeoutMs) {\n try {\n const response = await fetch(manifestUrl, { cache: 'no-store' })\n const value: unknown = await response.json()\n if (response.ok && isBleamManifest(value)) {\n return value\n }\n } catch {\n // Metro can answer /status before custom middleware is ready.\n }\n\n await new Promise((resolve) => setTimeout(resolve, 500))\n }\n\n throw new Error(`Bleam manifest did not become available: ${manifestUrl}`)\n}\n\nfunction openRuntimeClient(\n appPath: string,\n projectConfigPath: string,\n manifest: BleamManifest,\n) {\n const child = spawn(\n 'open',\n [\n appPath,\n '--args',\n '--bleam-project-config',\n projectConfigPath,\n '--bleam-bundle-url',\n manifest.bundleUrl,\n '--bleam-title',\n manifest.name,\n ],\n {\n detached: true,\n stdio: 'ignore',\n },\n )\n child.unref()\n}\n\nasync function startDevServer(options: DevOptions) {\n const config = readProjectConfig(options)\n const runtime = await resolveRuntimeArtifact()\n const clientAppPath = copyRuntimeClient(options.projectRoot, runtime)\n const workspaceRoot = createDevWorkspace(options.projectRoot, config)\n const origin = `http://localhost:${options.port}`\n const projectConfigPath = writeProjectRuntimeConfig(\n options.projectRoot,\n config,\n origin,\n )\n const child = spawn(\n process.execPath,\n [\n require.resolve('expo/bin/cli'),\n 'start',\n workspaceRoot,\n '--localhost',\n '--port',\n String(options.port),\n ],\n {\n stdio: 'inherit',\n env: {\n ...process.env,\n BLEAM_DEV: '1',\n BLEAM_PROJECT_ROOT: options.projectRoot,\n BLEAM_DEV_NAME: config.name,\n BLEAM_DEV_ORIGIN: origin,\n BLEAM_DEV_PORT: String(options.port),\n BLEAM_DEV_RUNTIME_VERSION: config.runtimeVersion,\n BLEAM_DEV_SDK_VERSION: config.sdkVersion,\n NODE_PATH: [\n path.join(options.projectRoot, 'node_modules'),\n path.join(packageRoot, 'node_modules'),\n path.dirname(path.dirname(require.resolve('expo/package.json'))),\n path.dirname(path.dirname(require.resolve('react/package.json'))),\n path.dirname(\n path.dirname(require.resolve('react-native/package.json')),\n ),\n process.env.NODE_PATH,\n ]\n .filter(Boolean)\n .join(path.delimiter),\n },\n },\n )\n\n const stop = (signal: NodeJS.Signals) => {\n child.kill(signal)\n }\n\n process.on('SIGINT', () => stop('SIGINT'))\n process.on('SIGTERM', () => stop('SIGTERM'))\n child.on('exit', (code) => process.exit(code ?? 0))\n\n await waitForDevServer(options.port)\n const manifest = await readDevManifest(origin)\n if (process.env.BLEAM_NO_OPEN !== '1') {\n openRuntimeClient(clientAppPath, projectConfigPath, manifest)\n }\n}\n\nasync function main(argv = process.argv.slice(2)) {\n const [command, ...args] = argv\n\n if (!command || command === '--help' || command === '-h') {\n printUsage()\n return\n }\n\n if (command === 'new') {\n const options = parseNewOptions(args)\n createNewProject(options)\n if (options.run) {\n await startDevServer({ projectRoot: options.projectRoot, port: 8081 })\n }\n return\n }\n\n if (command === 'dev') {\n await startDevServer(parseDevOptions(args))\n return\n }\n\n throw new Error(`Unknown command: ${command}`)\n}\n\nmain().catch((error) => {\n console.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":["workspaceRoot: string | undefined","matches: string[]","value: unknown"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { execFileSync, spawn, spawnSync } from 'node:child_process'\nimport { createHash } from 'node:crypto'\nimport {\n cpSync,\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n rmSync,\n symlinkSync,\n writeFileSync,\n} from 'node:fs'\nimport http from 'node:http'\nimport { createRequire } from 'node:module'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\n\nimport type { BleamConfig } from './config'\n\ninterface DevOptions {\n projectRoot: string\n port: number\n}\n\ninterface NewOptions {\n projectRoot: string\n run: boolean\n}\n\ninterface ProjectConfig {\n name: string\n version?: string\n bundleIdentifier?: string\n teamId?: string\n runtimeVersion: string\n sdkVersion: string\n}\n\ninterface RuntimeArtifact {\n appPath: string\n version: string\n platform: string\n}\n\ninterface BleamManifest {\n name: string\n bundleUrl: string\n platform: 'macos'\n dev: boolean\n}\n\ninterface InternalMetroOptions {\n workspaceRoot: string\n port: number\n}\n\nconst require = createRequire(import.meta.url)\nconst packageRoot = path.dirname(\n fileURLToPath(new URL('../package.json', import.meta.url)),\n)\nconst packageJson = require('../package.json') as {\n version: string\n dependencies?: Record<string, string>\n}\nconst runtimeVersion = packageJson.version\nconst runtimePlatform = `macos-${process.arch}`\n\nfunction printUsage() {\n console.log(`Usage: bleam <command>\n\nCommands:\n new [dir] [--run] Create a new Bleam project\n dev [dir] [--port <port>] Start a Bleam dev server`)\n}\n\nfunction invocationRoot() {\n return path.isAbsolute(process.env.PWD ?? '')\n ? process.env.PWD!\n : process.cwd()\n}\n\nfunction parseDevOptions(argv: string[]): DevOptions {\n const root = invocationRoot()\n let projectRoot = root\n let port = 8081\n let hasProjectRootArg = false\n\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index]\n\n if (arg === '--port' || arg === '-p') {\n const value = argv[++index]\n port = Number(value)\n continue\n }\n\n if (arg.startsWith('--port=')) {\n port = Number(arg.slice('--port='.length))\n continue\n }\n\n if (arg === '--help' || arg === '-h') {\n printUsage()\n process.exit(0)\n }\n\n if (arg.startsWith('-')) {\n throw new Error(`Unknown option: ${arg}`)\n }\n\n projectRoot = path.resolve(root, arg)\n hasProjectRootArg = true\n }\n\n if (!Number.isInteger(port) || port <= 0) {\n throw new Error(`Invalid port: ${port}`)\n }\n\n if (!hasProjectRootArg && !isBleamProjectRoot(projectRoot)) {\n projectRoot = discoverBleamProjectRoot(projectRoot) ?? projectRoot\n }\n\n return { projectRoot: path.resolve(projectRoot), port }\n}\n\nfunction parseNewOptions(argv: string[]): NewOptions {\n const root = invocationRoot()\n let projectRoot = root\n let run = false\n\n for (const arg of argv) {\n if (arg === '--run') {\n run = true\n continue\n }\n\n if (arg === '--help' || arg === '-h') {\n printUsage()\n process.exit(0)\n }\n\n if (arg.startsWith('-')) {\n throw new Error(`Unknown option: ${arg}`)\n }\n\n projectRoot = path.resolve(root, arg)\n }\n\n return { projectRoot, run }\n}\n\nfunction parseInternalMetroOptions(argv: string[]): InternalMetroOptions {\n let workspaceRoot: string | undefined\n let port = 8081\n\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index]\n\n if (arg === '--workspace-root') {\n workspaceRoot = path.resolve(invocationRoot(), argv[++index] ?? '')\n continue\n }\n\n if (arg === '--port') {\n port = Number(argv[++index])\n continue\n }\n\n if (arg.startsWith('--port=')) {\n port = Number(arg.slice('--port='.length))\n continue\n }\n\n throw new Error(`Unknown internal option: ${arg}`)\n }\n\n if (!workspaceRoot) {\n throw new Error('Missing --workspace-root')\n }\n\n if (!Number.isInteger(port) || port <= 0) {\n throw new Error(`Invalid port: ${port}`)\n }\n\n return { workspaceRoot, port }\n}\n\nfunction isBleamProjectRoot(projectRoot: string) {\n return (\n existsSync(path.join(projectRoot, 'app.config.ts')) &&\n existsSync(path.join(projectRoot, 'app', 'index.tsx'))\n )\n}\n\nfunction resolvedDependencyRoot() {\n return path.dirname(\n path.dirname(require.resolve('react-native/package.json')),\n )\n}\n\nfunction discoverBleamProjectRoot(searchRoot: string) {\n const ignoredNames = new Set([\n '.bleam',\n '.expo',\n '.git',\n '.yarn',\n 'build',\n 'dist',\n 'node_modules',\n 'templates',\n ])\n const matches: string[] = []\n\n function visit(directory: string) {\n if (matches.length > 1) {\n return\n }\n\n if (isBleamProjectRoot(directory)) {\n matches.push(directory)\n return\n }\n\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n if (!entry.isDirectory() || ignoredNames.has(entry.name)) {\n continue\n }\n\n visit(path.join(directory, entry.name))\n }\n }\n\n visit(searchRoot)\n\n if (matches.length > 1) {\n throw new Error('Multiple Bleam projects found. Run bleam dev <dir>.')\n }\n\n return matches[0]\n}\n\nfunction assertStringField(value: unknown, field: keyof BleamConfig): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new Error(`app.config.ts must define ${field}`)\n }\n return value\n}\n\nfunction loadAppConfig(projectRoot: string): BleamConfig {\n const configPath = path.join(projectRoot, 'app.config.ts')\n const loader = `\n const mod = await import(${JSON.stringify(pathToFileURL(configPath).href)});\n const config = mod.default?.default ?? mod.default ?? mod;\n process.stdout.write(JSON.stringify(config));\n `\n\n const result = spawnSync(\n process.execPath,\n ['--import', require.resolve('tsx'), '--eval', loader],\n {\n cwd: projectRoot,\n encoding: 'utf8',\n env: {\n ...process.env,\n NODE_PATH: [\n path.join(projectRoot, 'node_modules'),\n resolvedDependencyRoot(),\n process.env.NODE_PATH,\n ]\n .filter(Boolean)\n .join(path.delimiter),\n },\n },\n )\n\n if (result.status !== 0) {\n throw new Error(result.stderr.trim() || 'Failed to load app.config.ts')\n }\n\n const value = JSON.parse(result.stdout) as Partial<BleamConfig>\n return {\n name: assertStringField(value.name, 'name'),\n version: typeof value.version === 'string' ? value.version : undefined,\n bundleIdentifier:\n typeof value.bundleIdentifier === 'string'\n ? value.bundleIdentifier\n : undefined,\n teamId: typeof value.teamId === 'string' ? value.teamId : undefined,\n }\n}\n\nfunction assertBleamConfigFiles(projectRoot: string) {\n if (existsSync(path.join(projectRoot, 'app.json'))) {\n throw new Error(\n 'Bleam projects use app.config.ts; app.json is not supported.',\n )\n }\n\n if (!existsSync(path.join(projectRoot, 'app.config.ts'))) {\n throw new Error(\n 'Missing app.config.ts. Bleam projects must define app.config.ts.',\n )\n }\n\n if (!existsSync(path.join(projectRoot, 'app', 'index.tsx'))) {\n throw new Error(\n 'Missing app/index.tsx. Bleam projects must define app/index.tsx.',\n )\n }\n}\n\nfunction ensureProjectTsconfig(projectRoot: string) {\n const tsconfigPath = path.join(projectRoot, 'tsconfig.json')\n if (existsSync(tsconfigPath)) {\n return\n }\n\n writeFileSync(\n tsconfigPath,\n `${JSON.stringify(\n {\n extends: './.bleam/dev/tsconfig.json',\n },\n null,\n 2,\n )}\\n`,\n )\n}\n\nfunction readProjectConfig(options: DevOptions): ProjectConfig {\n assertBleamConfigFiles(options.projectRoot)\n const config = loadAppConfig(options.projectRoot)\n\n return {\n name: config.name,\n version: config.version,\n bundleIdentifier: config.bundleIdentifier,\n teamId: config.teamId,\n runtimeVersion,\n sdkVersion: runtimeVersion,\n }\n}\n\nfunction slugFromName(name: string) {\n return (\n name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '') || 'bleam-app'\n )\n}\n\nfunction nameFromDirectory(projectRoot: string) {\n const name = path.basename(projectRoot).replace(/[-_]+/g, ' ').trim()\n if (!name) {\n return 'Bleam App'\n }\n\n return name.replace(/\\b\\w/g, (letter) => letter.toUpperCase())\n}\n\nfunction createNewProject(options: NewOptions) {\n const templateRoot = path.join(packageRoot, 'templates', 'basic')\n\n if (!existsSync(templateRoot)) {\n throw new Error(`Missing basic template: ${templateRoot}`)\n }\n\n if (\n existsSync(options.projectRoot) &&\n readdirSync(options.projectRoot).length > 0\n ) {\n throw new Error(`Directory is not empty: ${options.projectRoot}`)\n }\n\n mkdirSync(options.projectRoot, { recursive: true })\n cpSync(templateRoot, options.projectRoot, { recursive: true })\n const name = nameFromDirectory(options.projectRoot)\n writeFileSync(\n path.join(options.projectRoot, 'app.config.ts'),\n `export default {\\n name: ${JSON.stringify(name)},\\n}\\n`,\n )\n writeFileSync(path.join(options.projectRoot, '.gitignore'), `.bleam\\n`)\n createDevWorkspace(options.projectRoot, {\n name,\n runtimeVersion,\n sdkVersion: runtimeVersion,\n })\n\n console.log(`Created Bleam project at ${options.projectRoot}`)\n}\n\nfunction createDevWorkspace(projectRoot: string, config: ProjectConfig) {\n const workspaceRoot = path.join(projectRoot, '.bleam', 'dev')\n mkdirSync(workspaceRoot, { recursive: true })\n const workspaceNodeModules = path.join(workspaceRoot, 'node_modules')\n const dependencyRoot = resolvedDependencyRoot()\n rmSync(workspaceNodeModules, { recursive: true, force: true })\n symlinkSync(dependencyRoot, workspaceNodeModules)\n ensureProjectTsconfig(projectRoot)\n\n writeFileSync(\n path.join(workspaceRoot, 'app.config.js'),\n `module.exports = ${JSON.stringify(\n {\n expo: {\n name: config.name,\n slug: slugFromName(config.name),\n version: config.version ?? '0.0.0',\n orientation: 'default',\n platforms: ['ios'],\n newArchEnabled: true,\n },\n },\n null,\n 2,\n )}\\n`,\n )\n\n writeFileSync(\n path.join(workspaceRoot, 'index.js'),\n `import { registerApp } from 'bleam/app'\\nimport App from ${JSON.stringify(path.join(projectRoot, 'app'))}\\n\\nregisterApp(App)\\n`,\n )\n\n writeFileSync(\n path.join(workspaceRoot, 'metro.config.js'),\n `const { getDefaultConfig } = require(${JSON.stringify(path.join(packageRoot, 'metro-config.cjs'))})\\n\\nmodule.exports = getDefaultConfig(__dirname)\\n`,\n )\n\n writeFileSync(\n path.join(workspaceRoot, 'package.json'),\n `${JSON.stringify(\n {\n name: `${slugFromName(config.name)}-bleam-dev`,\n version: config.version ?? '0.0.0',\n private: true,\n main: 'index.js',\n dependencies: {\n '@types/react': packageJson.dependencies?.['@types/react'],\n expo: packageJson.dependencies?.expo,\n react: packageJson.dependencies?.react,\n 'react-native': packageJson.dependencies?.['react-native'],\n typescript: packageJson.dependencies?.typescript,\n },\n expo: {\n install: {\n exclude: ['typescript'],\n },\n },\n },\n null,\n 2,\n )}\\n`,\n )\n\n writeFileSync(\n path.join(workspaceRoot, 'tsconfig.json'),\n `${JSON.stringify(\n {\n extends: 'bleam/tsconfig',\n compilerOptions: {\n paths: {\n bleam: ['./node_modules/bleam'],\n 'bleam/*': ['./node_modules/bleam/*'],\n expo: ['./node_modules/expo'],\n 'expo/*': ['./node_modules/expo/*'],\n react: ['./node_modules/@types/react'],\n 'react/jsx-runtime': ['./node_modules/@types/react/jsx-runtime'],\n 'react/jsx-dev-runtime': [\n './node_modules/@types/react/jsx-dev-runtime',\n ],\n 'react-native': ['./node_modules/react-native'],\n 'react-native/*': ['./node_modules/react-native/*'],\n },\n },\n include: [\n path.relative(workspaceRoot, path.join(projectRoot, 'app')),\n path.relative(workspaceRoot, path.join(projectRoot, 'app.config.ts')),\n ],\n },\n null,\n 2,\n )}\\n`,\n )\n\n return workspaceRoot\n}\n\nfunction writeProjectRuntimeConfig(\n projectRoot: string,\n config: ProjectConfig,\n origin: string,\n) {\n const projectConfigPath = path.join(projectRoot, '.bleam', 'project.json')\n mkdirSync(path.dirname(projectConfigPath), { recursive: true })\n writeFileSync(\n projectConfigPath,\n `${JSON.stringify(\n {\n name: config.name,\n version: config.version,\n bundleIdentifier: config.bundleIdentifier,\n teamId: config.teamId,\n devServer: origin,\n runtimeVersion: config.runtimeVersion,\n sdkVersion: config.sdkVersion,\n },\n null,\n 2,\n )}\\n`,\n )\n return projectConfigPath\n}\n\nfunction runtimeCacheRoot() {\n return path.join(\n os.homedir(),\n 'Library',\n 'Caches',\n 'bleam',\n 'runtimes',\n runtimeVersion,\n runtimePlatform,\n )\n}\n\nfunction localDevelopmentRuntimeAppPath() {\n return path.resolve(\n packageRoot,\n '..',\n '..',\n 'app',\n 'bleam',\n 'build',\n 'Build',\n 'Products',\n 'Debug-maccatalyst',\n 'Bleam.app',\n )\n}\n\nfunction runtimeReleaseBaseUrl() {\n return (\n process.env.BLEAM_RUNTIME_RELEASE_BASE_URL ??\n 'https://github.com/bajedev/bleam-app/releases/download'\n )\n}\n\nfunction runtimeArchiveName() {\n return `bleam-runtime-v${runtimeVersion}-${runtimePlatform}.zip`\n}\n\nfunction runtimeArchiveUrl() {\n const tag = encodeURIComponent(`bleam@${runtimeVersion}`)\n return `${runtimeReleaseBaseUrl()}/${tag}/${runtimeArchiveName()}`\n}\n\nfunction sha256(filePath: string) {\n return createHash('sha256').update(readFileSync(filePath)).digest('hex')\n}\n\nasync function downloadFile(url: string, destination: string) {\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(\n `Failed to download ${url}: ${response.status} ${response.statusText}`,\n )\n }\n\n const bytes = new Uint8Array(await response.arrayBuffer())\n writeFileSync(destination, bytes)\n}\n\nasync function downloadExpectedSha256(url: string) {\n const response = await fetch(`${url}.sha256`)\n if (!response.ok) {\n return undefined\n }\n\n const text = await response.text()\n return text.trim().split(/\\s+/)[0]\n}\n\nasync function downloadRuntimeArtifact(): Promise<RuntimeArtifact> {\n if (process.platform !== 'darwin') {\n throw new Error(\n 'Bleam runtime artifacts are currently only available on macOS.',\n )\n }\n\n const cacheRoot = runtimeCacheRoot()\n const cachedAppPath = path.join(cacheRoot, 'Bleam.app')\n if (existsSync(cachedAppPath)) {\n return {\n appPath: cachedAppPath,\n version: runtimeVersion,\n platform: runtimePlatform,\n }\n }\n\n mkdirSync(cacheRoot, { recursive: true })\n const archiveUrl = runtimeArchiveUrl()\n const archivePath = path.join(cacheRoot, runtimeArchiveName())\n const extractRoot = path.join(cacheRoot, 'extract')\n\n await downloadFile(archiveUrl, archivePath)\n const expectedSha256 = await downloadExpectedSha256(archiveUrl)\n if (expectedSha256 && sha256(archivePath) !== expectedSha256) {\n rmSync(archivePath, { force: true })\n throw new Error(`Runtime artifact checksum mismatch: ${archiveUrl}`)\n }\n\n rmSync(extractRoot, { recursive: true, force: true })\n mkdirSync(extractRoot, { recursive: true })\n execFileSync('ditto', ['-x', '-k', archivePath, extractRoot], {\n stdio: 'ignore',\n })\n\n const extractedAppPath = path.join(extractRoot, 'Bleam.app')\n if (!existsSync(extractedAppPath)) {\n throw new Error(`Runtime archive did not contain Bleam.app: ${archiveUrl}`)\n }\n\n rmSync(cachedAppPath, { recursive: true, force: true })\n cpSync(extractedAppPath, cachedAppPath, { recursive: true })\n rmSync(extractRoot, { recursive: true, force: true })\n\n return {\n appPath: cachedAppPath,\n version: runtimeVersion,\n platform: runtimePlatform,\n }\n}\n\nasync function resolveRuntimeArtifact(): Promise<RuntimeArtifact> {\n const overrideAppPath = process.env.BLEAM_RUNTIME_APP\n if (overrideAppPath) {\n const appPath = path.resolve(overrideAppPath)\n if (!existsSync(appPath)) {\n throw new Error(`BLEAM_RUNTIME_APP does not exist: ${appPath}`)\n }\n\n return { appPath, version: runtimeVersion, platform: runtimePlatform }\n }\n\n const localAppPath = localDevelopmentRuntimeAppPath()\n if (existsSync(localAppPath)) {\n return {\n appPath: localAppPath,\n version: runtimeVersion,\n platform: runtimePlatform,\n }\n }\n\n return downloadRuntimeArtifact()\n}\n\nfunction copyRuntimeClient(projectRoot: string, runtime: RuntimeArtifact) {\n const clientAppPath = path.join(projectRoot, '.bleam', 'client', 'Bleam.app')\n rmSync(clientAppPath, { recursive: true, force: true })\n mkdirSync(path.dirname(clientAppPath), { recursive: true })\n cpSync(runtime.appPath, clientAppPath, { recursive: true })\n return clientAppPath\n}\n\nfunction isBleamManifest(value: unknown): value is BleamManifest {\n const manifest =\n value && typeof value === 'object' ? (value as Partial<BleamManifest>) : {}\n\n return (\n typeof manifest.name === 'string' &&\n typeof manifest.bundleUrl === 'string' &&\n manifest.platform === 'macos' &&\n manifest.dev === true\n )\n}\n\nasync function readDevManifest(origin: string, timeoutMs = 30_000) {\n const manifestUrl = `${origin}/bleam/manifest.json`\n const startedAt = Date.now()\n\n console.log('Waiting for Bleam dev server...')\n\n while (Date.now() - startedAt <= timeoutMs) {\n try {\n const response = await fetch(manifestUrl, { cache: 'no-store' })\n const value: unknown = await response.json()\n if (response.ok && isBleamManifest(value)) {\n return value\n }\n } catch {\n // Metro can answer /status before custom middleware is ready.\n }\n\n await new Promise((resolve) => setTimeout(resolve, 500))\n }\n\n throw new Error(`Bleam manifest did not become available: ${manifestUrl}`)\n}\n\nfunction formatDuration(ms: number) {\n return `${(ms / 1000).toFixed(1)}s`\n}\n\nasync function waitForDevBundle(bundleUrl: string, timeoutMs = 60_000) {\n const startedAt = Date.now()\n const requestTimeoutMs = 30_000\n\n console.log('Bundling app...')\n\n while (Date.now() - startedAt <= timeoutMs) {\n const requestStartedAt = Date.now()\n try {\n const response = await fetch(bundleUrl, {\n cache: 'no-store',\n signal: AbortSignal.timeout(requestTimeoutMs),\n })\n await response.body?.cancel()\n if (response.ok) {\n console.log(`Bundled app in ${formatDuration(Date.now() - startedAt)}`)\n return\n }\n\n console.log(`Bundle request returned ${response.status}, retrying...`)\n } catch (error) {\n if (error instanceof Error && error.name === 'TimeoutError') {\n console.log(\n `Bundle request timed out after ${formatDuration(\n Date.now() - requestStartedAt,\n )}, retrying...`,\n )\n } else {\n console.log(\n `Bundle request failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n )\n }\n }\n\n await new Promise((resolve) => setTimeout(resolve, 500))\n }\n\n throw new Error(\n `Bleam bundle did not complete within ${formatDuration(\n timeoutMs,\n )}: ${bundleUrl}`,\n )\n}\n\nfunction openRuntimeClient(\n appPath: string,\n projectConfigPath: string,\n manifest: BleamManifest,\n) {\n const child = spawn(\n 'open',\n [\n '-n',\n appPath,\n '--args',\n '--bleam-project-config',\n projectConfigPath,\n '--bleam-bundle-url',\n manifest.bundleUrl,\n '--bleam-title',\n manifest.name,\n ],\n {\n stdio: 'ignore',\n },\n )\n\n child.on('error', (error) => {\n console.error(\n `Failed to open Bleam runtime at ${appPath}: ${error.message}`,\n )\n })\n\n child.on('exit', (code) => {\n if (code && code !== 0) {\n console.error(`Failed to open Bleam runtime at ${appPath}`)\n }\n })\n}\n\nasync function startInternalMetroServer(options: InternalMetroOptions) {\n const metro = require('@expo/metro/metro') as typeof import('metro')\n const { loadConfig } =\n require('@expo/metro/metro-config') as typeof import('metro-config')\n const config = await loadConfig({\n config: path.join(options.workspaceRoot, 'metro.config.js'),\n cwd: options.workspaceRoot,\n port: options.port,\n })\n const { middleware, end, attachHmrServer } =\n await metro.createConnectMiddleware(config, {\n watch: true,\n waitForBundler: true,\n })\n const server = http.createServer((req, res) => {\n if (req.url?.split('?')[0] === '/status') {\n res.writeHead(200, {\n 'Cache-Control': 'no-store',\n 'Content-Type': 'text/plain; charset=utf-8',\n 'X-React-Native-Project-Root': encodeURI(config.projectRoot),\n })\n res.end('packager-status:running')\n return\n }\n\n middleware(req, res)\n })\n\n server.timeout = 0\n attachHmrServer(server)\n\n await new Promise<void>((resolve, reject) => {\n server.on('error', reject)\n server.listen(options.port, 'localhost', () => resolve())\n })\n\n server.on('error', (error) => {\n console.error(error instanceof Error ? error.message : String(error))\n })\n\n console.log(`Bleam dev server running at http://localhost:${options.port}`)\n\n const close = () => {\n server.close(() => {\n end()\n process.exit(0)\n })\n }\n process.on('SIGINT', close)\n process.on('SIGTERM', close)\n}\n\nasync function startDevServer(options: DevOptions) {\n const config = readProjectConfig(options)\n const runtime = await resolveRuntimeArtifact()\n const clientAppPath = copyRuntimeClient(options.projectRoot, runtime)\n const workspaceRoot = createDevWorkspace(options.projectRoot, config)\n const origin = `http://localhost:${options.port}`\n const projectConfigPath = writeProjectRuntimeConfig(\n options.projectRoot,\n config,\n origin,\n )\n const child = spawn(\n process.execPath,\n [\n fileURLToPath(import.meta.url),\n 'internal:metro',\n '--workspace-root',\n workspaceRoot,\n '--port',\n String(options.port),\n ],\n {\n stdio: 'inherit',\n env: {\n ...process.env,\n BLEAM_DEV: '1',\n BLEAM_PROJECT_ROOT: options.projectRoot,\n BLEAM_DEV_NAME: config.name,\n BLEAM_DEV_ORIGIN: origin,\n BLEAM_DEV_PORT: String(options.port),\n BLEAM_DEV_RUNTIME_VERSION: config.runtimeVersion,\n BLEAM_DEV_SDK_VERSION: config.sdkVersion,\n NODE_PATH: [\n path.join(options.projectRoot, 'node_modules'),\n resolvedDependencyRoot(),\n path.dirname(path.dirname(require.resolve('expo/package.json'))),\n path.dirname(path.dirname(require.resolve('react/package.json'))),\n path.dirname(\n path.dirname(require.resolve('react-native/package.json')),\n ),\n process.env.NODE_PATH,\n ]\n .filter(Boolean)\n .join(path.delimiter),\n },\n },\n )\n\n const stop = (signal: NodeJS.Signals) => {\n child.kill(signal)\n }\n\n process.on('SIGINT', () => stop('SIGINT'))\n process.on('SIGTERM', () => stop('SIGTERM'))\n child.on('exit', (code) => process.exit(code ?? 0))\n\n try {\n const manifest = await readDevManifest(origin)\n if (process.env.BLEAM_NO_OPEN !== '1') {\n await waitForDevBundle(manifest.bundleUrl)\n console.log('Opening Bleam app...')\n openRuntimeClient(clientAppPath, projectConfigPath, manifest)\n }\n } catch (error) {\n child.kill('SIGTERM')\n throw error\n }\n}\n\nasync function main(argv = process.argv.slice(2)) {\n const [command, ...args] = argv\n\n if (!command || command === '--help' || command === '-h') {\n printUsage()\n return\n }\n\n if (command === 'new') {\n const options = parseNewOptions(args)\n createNewProject(options)\n if (options.run) {\n await startDevServer({ projectRoot: options.projectRoot, port: 8081 })\n }\n return\n }\n\n if (command === 'dev') {\n await startDevServer(parseDevOptions(args))\n return\n }\n\n if (command === 'internal:metro') {\n await startInternalMetroServer(parseInternalMetroOptions(args))\n return\n }\n\n throw new Error(`Unknown command: ${command}`)\n}\n\nmain().catch((error) => {\n console.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n})\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bleam",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "packageManager": "yarn@1.22.22",
5
5
  "type": "module",
6
6
  "files": [
@@ -30,6 +30,7 @@
30
30
  "tsdown": "^0.15.6"
31
31
  },
32
32
  "dependencies": {
33
+ "@expo/metro": "56.0.0",
33
34
  "@nativescript/react-native": "9.0.0-preview.4",
34
35
  "@types/react": "~19.2.14",
35
36
  "expo": "56",
@@ -3,7 +3,7 @@ import { StyleSheet, Text, View } from 'react-native'
3
3
  export default function App() {
4
4
  return (
5
5
  <View style={styles.container}>
6
- <Text>Open up app.tsx to start working on your app!</Text>
6
+ <Text>Open up app/index.tsx to start working on your app!</Text>
7
7
  </View>
8
8
  )
9
9
  }