@touchtechclub/simbox 0.4.6 → 0.4.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.
Files changed (2) hide show
  1. package/dist/cli.js +62 -17
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -280,7 +280,42 @@ Run \`simbox repair\` to fix the repo setup.`);
280
280
  }
281
281
 
282
282
  // src/commands.ts
283
- import { rmSync } from "node:fs";
283
+ import { rmSync as rmSync2 } from "node:fs";
284
+
285
+ // src/run-cache.ts
286
+ import { chmodSync as chmodSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
287
+ import { join as join2 } from "node:path";
288
+ var cachePath = () => join2(configDir(), "current-run.json");
289
+ function readCachedRun(now = Date.now()) {
290
+ try {
291
+ const info = JSON.parse(readFileSync2(cachePath(), "utf8"));
292
+ if (typeof info.runId !== "string" || typeof info.tunnelUrl !== "string" || typeof info.daemonToken !== "string")
293
+ return null;
294
+ const expiresAt = typeof info.expiresAt === "number" ? info.expiresAt : null;
295
+ if (expiresAt !== null && expiresAt <= now)
296
+ return null;
297
+ return {
298
+ runId: info.runId,
299
+ tunnelUrl: info.tunnelUrl,
300
+ daemonToken: info.daemonToken,
301
+ expiresAt
302
+ };
303
+ } catch {
304
+ return null;
305
+ }
306
+ }
307
+ function writeCachedRun(info) {
308
+ try {
309
+ mkdirSync2(configDir(), { recursive: true, mode: 448 });
310
+ writeFileSync2(cachePath(), JSON.stringify(info), { mode: 384 });
311
+ chmodSync2(cachePath(), 384);
312
+ } catch {}
313
+ }
314
+ function clearCachedRun() {
315
+ rmSync(cachePath(), { force: true });
316
+ }
317
+
318
+ // src/commands.ts
284
319
  import pc3 from "picocolors";
285
320
 
286
321
  // src/connect.ts
@@ -438,24 +473,24 @@ class Spinner {
438
473
 
439
474
  // src/remote.ts
440
475
  import { spawn } from "node:child_process";
441
- import { join as join3 } from "node:path";
476
+ import { join as join4 } from "node:path";
442
477
 
443
478
  // src/device-registration.ts
444
479
  import { randomUUID } from "node:crypto";
445
- import { existsSync, mkdirSync as mkdirSync2, readdirSync, statSync, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
480
+ import { existsSync, mkdirSync as mkdirSync3, readdirSync, statSync, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
446
481
  import { homedir as homedir2 } from "node:os";
447
- import { join as join2 } from "node:path";
482
+ import { join as join3 } from "node:path";
448
483
  var MAX_AGE_MS = 5 * 60000;
449
484
  function registerDevice(info, options = {}) {
450
- if (!process.env.T3CODE_HOME && !process.env.SIMBOX_DEVICE_REGISTRATION_DIR && ![".s5code", ".t3"].some((home) => existsSync(join2(homedir2(), home, "userdata", "server-runtime.json"))))
485
+ if (!process.env.T3CODE_HOME && !process.env.SIMBOX_DEVICE_REGISTRATION_DIR && ![".s5code", ".t3"].some((home) => existsSync(join3(homedir2(), home, "userdata", "server-runtime.json"))))
451
486
  return;
452
487
  try {
453
- const directory = process.env.SIMBOX_DEVICE_REGISTRATION_DIR ?? join2(configDir(), "device-registrations");
454
- mkdirSync2(directory, { recursive: true, mode: 448 });
488
+ const directory = process.env.SIMBOX_DEVICE_REGISTRATION_DIR ?? join3(configDir(), "device-registrations");
489
+ mkdirSync3(directory, { recursive: true, mode: 448 });
455
490
  for (const file of readdirSync(directory)) {
456
491
  if (!/^[a-f0-9-]{36}\.json$/.test(file))
457
492
  continue;
458
- const path = join2(directory, file);
493
+ const path = join3(directory, file);
459
494
  if (Date.now() - statSync(path).mtimeMs > MAX_AGE_MS)
460
495
  unlinkSync(path);
461
496
  }
@@ -467,7 +502,7 @@ function registerDevice(info, options = {}) {
467
502
  return index >= 0 ? flags[index + 1] : flags.find((arg) => arg.startsWith(`${name}=`))?.slice(name.length + 1);
468
503
  };
469
504
  const id = randomUUID();
470
- writeFileSync2(join2(directory, `${id}.json`), JSON.stringify({
505
+ writeFileSync3(join3(directory, `${id}.json`), JSON.stringify({
471
506
  version: 1,
472
507
  createdAt: Date.now(),
473
508
  ...info,
@@ -582,13 +617,21 @@ async function cmdExec(args) {
582
617
  const bin = findAgentDevice();
583
618
  if (!bin)
584
619
  throw new CliError("Install agent-device first: npm i -g agent-device@0.21.20");
585
- const initial = await refreshRemote();
586
- if (!initial)
587
- throw new CliError("No live run. Start one with `simbox sim`.");
588
- if (args.some((arg, i) => arg === "--platform=android" || arg === "--platform" && args[i + 1] === "android")) {
589
- await waitForAndroid(initial.runId);
620
+ const android = args.some((arg, i) => arg === "--platform=android" || arg === "--platform" && args[i + 1] === "android");
621
+ let info = android ? null : readCachedRun();
622
+ if (info && !await probeRemote(info))
623
+ info = null;
624
+ if (!info) {
625
+ const initial = await refreshRemote();
626
+ if (!initial) {
627
+ clearCachedRun();
628
+ throw new CliError("No live run. Start one with `simbox sim`.");
629
+ }
630
+ if (android)
631
+ await waitForAndroid(initial.runId);
632
+ info = await waitForRemote(initial);
590
633
  }
591
- const info = await waitForRemote(initial);
634
+ writeCachedRun(info);
592
635
  const env = {
593
636
  ...process.env,
594
637
  AGENT_DEVICE_DAEMON_AUTH_TOKEN: info.daemonToken
@@ -596,7 +639,7 @@ async function cmdExec(args) {
596
639
  delete env.AGENT_DEVICE_REMOTE_CONFIG;
597
640
  delete env.AGENT_DEVICE_DAEMON_BASE_URL;
598
641
  const code = await new Promise((resolve, reject) => {
599
- const child = spawn(bin, remoteArgs(args, info, join3(configDir(), "agent-device")), {
642
+ const child = spawn(bin, remoteArgs(args, info, join4(configDir(), "agent-device")), {
600
643
  stdio: "inherit",
601
644
  env
602
645
  });
@@ -751,6 +794,7 @@ async function cmdSim(opts) {
751
794
  info = await waitForRemote(info);
752
795
  if (opts.platform === "android")
753
796
  await waitForAndroid(info.runId);
797
+ writeCachedRun(info);
754
798
  registerDevice(info, { platform: opts.platform });
755
799
  if (json) {
756
800
  const payload = {
@@ -793,6 +837,7 @@ async function cmdStop() {
793
837
  return;
794
838
  }
795
839
  await stopRun(run.id);
840
+ clearCachedRun();
796
841
  if (run.tunnelUrl && run.daemonToken)
797
842
  registerDevice({
798
843
  runId: run.id,
@@ -814,7 +859,7 @@ async function cmdRepair() {
814
859
  }
815
860
  async function cmdLogout() {
816
861
  try {
817
- rmSync(authPath());
862
+ rmSync2(authPath());
818
863
  console.log(`${pc3.green("✔")} Logged out.`);
819
864
  } catch {
820
865
  console.log("Already logged out.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@touchtechclub/simbox",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "description": "On-demand iOS simulators & Android emulators on your own GitHub Actions minutes.",
5
5
  "repository": {
6
6
  "type": "git",