sparkecoder 0.1.7 → 0.1.8

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.
@@ -19,6 +19,7 @@ declare function startServer(options?: ServerOptions): Promise<{
19
19
  port: number;
20
20
  host: string;
21
21
  webPort: number | undefined;
22
+ webStarted: boolean | undefined;
22
23
  }>;
23
24
  declare function stopServer(): void;
24
25
 
@@ -4388,6 +4388,33 @@ async function findWebPort(preferredPort) {
4388
4388
  }
4389
4389
  return { port: preferredPort, alreadyRunning: false };
4390
4390
  }
4391
+ function hasProductionBuild(webDir) {
4392
+ const buildIdPath = join3(webDir, ".next", "BUILD_ID");
4393
+ return existsSync7(buildIdPath);
4394
+ }
4395
+ function runCommand(command, args, cwd, env) {
4396
+ return new Promise((resolve7) => {
4397
+ const child = spawn(command, args, {
4398
+ cwd,
4399
+ stdio: ["ignore", "pipe", "pipe"],
4400
+ env,
4401
+ shell: true
4402
+ });
4403
+ let output = "";
4404
+ child.stdout?.on("data", (data) => {
4405
+ output += data.toString();
4406
+ });
4407
+ child.stderr?.on("data", (data) => {
4408
+ output += data.toString();
4409
+ });
4410
+ child.on("close", (code) => {
4411
+ resolve7({ success: code === 0, output });
4412
+ });
4413
+ child.on("error", (err) => {
4414
+ resolve7({ success: false, output: err.message });
4415
+ });
4416
+ });
4417
+ }
4391
4418
  async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false) {
4392
4419
  const webDir = getWebDirectory();
4393
4420
  if (!webDir) {
@@ -4399,39 +4426,90 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false) {
4399
4426
  if (!quiet) console.log(` \u2713 Web UI already running at http://localhost:${actualPort}`);
4400
4427
  return { process: null, port: actualPort };
4401
4428
  }
4402
- const useNpm = existsSync7(join3(webDir, "package-lock.json"));
4403
- const command = useNpm ? "npm" : "npx";
4404
- const args = useNpm ? ["run", "dev", "--", "-p", String(actualPort)] : ["next", "dev", "-p", String(actualPort)];
4429
+ const usePnpm = existsSync7(join3(webDir, "pnpm-lock.yaml"));
4430
+ const useNpm = !usePnpm && existsSync7(join3(webDir, "package-lock.json"));
4431
+ const pkgManager = usePnpm ? "pnpm" : useNpm ? "npm" : "npx";
4432
+ const { NODE_OPTIONS, TSX_TSCONFIG_PATH, ...cleanEnv } = process.env;
4433
+ const webEnv = {
4434
+ ...cleanEnv,
4435
+ NEXT_PUBLIC_API_URL: `http://127.0.0.1:${apiPort}`
4436
+ };
4437
+ const isProduction = process.env.NODE_ENV === "production";
4438
+ let command;
4439
+ let args;
4440
+ if (isProduction) {
4441
+ if (!hasProductionBuild(webDir)) {
4442
+ if (!quiet) console.log(" \u{1F4E6} Building Web UI for production...");
4443
+ const buildArgs = pkgManager === "npx" ? ["next", "build"] : ["run", "build"];
4444
+ const buildResult = await runCommand(pkgManager, buildArgs, webDir, webEnv);
4445
+ if (!buildResult.success) {
4446
+ if (!quiet) console.error(" \u274C Web UI build failed");
4447
+ return { process: null, port: actualPort };
4448
+ }
4449
+ if (!quiet) console.log(" \u2713 Web UI build complete");
4450
+ }
4451
+ command = pkgManager;
4452
+ args = pkgManager === "npx" ? ["next", "start", "-p", String(actualPort)] : ["run", "start", "-p", String(actualPort)];
4453
+ } else {
4454
+ command = pkgManager;
4455
+ args = pkgManager === "npx" ? ["next", "dev", "-p", String(actualPort)] : ["run", "dev", "-p", String(actualPort)];
4456
+ }
4405
4457
  const child = spawn(command, args, {
4406
4458
  cwd: webDir,
4407
4459
  stdio: ["ignore", "pipe", "pipe"],
4408
- env: {
4409
- ...process.env,
4410
- NEXT_PUBLIC_API_URL: `http://127.0.0.1:${apiPort}`
4411
- },
4412
- detached: false
4460
+ env: webEnv,
4461
+ detached: false,
4462
+ shell: true
4413
4463
  });
4464
+ const startupTimeout = 3e4;
4414
4465
  let started = false;
4415
- child.stdout?.on("data", (data) => {
4416
- const output = data.toString();
4417
- if (!started && (output.includes("Ready") || output.includes("started") || output.includes("localhost"))) {
4418
- started = true;
4419
- if (!quiet) console.log(` \u2713 Web UI running at http://localhost:${actualPort}`);
4420
- }
4421
- });
4422
- if (!quiet) {
4466
+ let exited = false;
4467
+ let exitCode = null;
4468
+ const startedPromise = new Promise((resolve7) => {
4469
+ const timeout = setTimeout(() => {
4470
+ if (!started && !exited) {
4471
+ resolve7(false);
4472
+ }
4473
+ }, startupTimeout);
4474
+ child.stdout?.on("data", (data) => {
4475
+ const output = data.toString();
4476
+ if (!started && (output.includes("Ready") || output.includes("started") || output.includes("localhost"))) {
4477
+ started = true;
4478
+ clearTimeout(timeout);
4479
+ resolve7(true);
4480
+ }
4481
+ });
4423
4482
  child.stderr?.on("data", (data) => {
4424
4483
  const output = data.toString();
4425
4484
  if (output.toLowerCase().includes("error")) {
4426
- console.error(` Web UI error: ${output.trim()}`);
4485
+ if (!quiet) console.error(` Web UI error: ${output.trim().slice(0, 200)}`);
4427
4486
  }
4428
4487
  });
4429
- }
4430
- child.on("exit", () => {
4431
- webUIProcess = null;
4488
+ child.on("error", (err) => {
4489
+ if (!quiet) console.error(` \u274C Web UI spawn error: ${err.message}`);
4490
+ clearTimeout(timeout);
4491
+ resolve7(false);
4492
+ });
4493
+ child.on("exit", (code) => {
4494
+ exited = true;
4495
+ exitCode = code;
4496
+ if (!started) {
4497
+ clearTimeout(timeout);
4498
+ resolve7(false);
4499
+ }
4500
+ webUIProcess = null;
4501
+ });
4432
4502
  });
4433
4503
  webUIProcess = child;
4434
- return { process: child, port: actualPort };
4504
+ const didStart = await startedPromise;
4505
+ if (!didStart) {
4506
+ if (exited && exitCode !== 0) {
4507
+ if (!quiet) console.error(` \u274C Web UI failed to start (exit code: ${exitCode})`);
4508
+ } else if (!exited) {
4509
+ if (!quiet) console.log(` \u26A0 Web UI startup timed out, continuing anyway...`);
4510
+ }
4511
+ }
4512
+ return { process: child, port: actualPort, started: didStart };
4435
4513
  }
4436
4514
  function stopWebUI() {
4437
4515
  if (webUIProcess) {
@@ -4525,11 +4603,13 @@ async function startServer(options = {}) {
4525
4603
  hostname: host
4526
4604
  });
4527
4605
  let webPort;
4606
+ let webStarted;
4528
4607
  if (options.webUI !== false) {
4529
4608
  const result = await startWebUI(port, options.webPort || DEFAULT_WEB_PORT, options.quiet);
4530
4609
  webPort = result.port;
4610
+ webStarted = result.started;
4531
4611
  }
4532
- return { app, port, host, webPort };
4612
+ return { app, port, host, webPort, webStarted };
4533
4613
  }
4534
4614
  function stopServer() {
4535
4615
  stopWebUI();