@solidrt/cli 0.0.6 → 0.0.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidrt/cli",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "license": "MIT",
5
5
  "author": "Antoine van Wel",
6
6
  "type": "module",
@@ -19,12 +19,12 @@
19
19
  "qrcode-generator": "^2.0.4"
20
20
  },
21
21
  "optionalDependencies": {
22
- "@solidrt/darwin-arm64": "0.0.6",
23
- "@solidrt/linux-x64-gnu": "0.0.6",
24
- "@solidrt/win32-x64-msvc": "0.0.6"
22
+ "@solidrt/darwin-arm64": "0.0.7",
23
+ "@solidrt/linux-x64-gnu": "0.0.7",
24
+ "@solidrt/win32-x64-msvc": "0.0.7"
25
25
  },
26
26
  "peerDependencies": {
27
- "@solidrt/core": "0.0.6",
27
+ "@solidrt/core": "0.0.7",
28
28
  "typescript": "^5"
29
29
  },
30
30
  "devDependencies": {
package/src/args.ts CHANGED
@@ -19,6 +19,7 @@ export let { values, positionals } = parseArgs({
19
19
  export let command = positionals[0]
20
20
  export let source = positionals[1]
21
21
  export let isTsx = source?.endsWith(".tsx") || source?.endsWith(".jsx")
22
+ export let isTs = source?.endsWith(".ts") || source?.endsWith(".js")
22
23
  export let isPrebuilt = source?.endsWith(".srt.js") || source?.endsWith(".srt.bin")
23
24
 
24
25
  export function printUsage() {
@@ -30,6 +31,7 @@ Commands:
30
31
  client Start solidrt-go client only
31
32
  bundle <file.tsx|jsx> Transpile TSX/JSX to JS or bytecode
32
33
  record <file.tsx|jsx> Capture frames for video generation
34
+ pack <file.ts|js> Bundle + compile to a standalone executable (experimental, Flux only)
33
35
 
34
36
  run/server options:
35
37
  --proxy-files Route file/dir access through the dev server
@@ -20,7 +20,7 @@ export async function bundle(entry = source) {
20
20
  target: "browser",
21
21
  format: "esm",
22
22
  minify: values.minify,
23
- external: ["qjs:*"],
23
+ external: ["qjs:*", "flux:*"],
24
24
  define,
25
25
  plugins: [solidPlugin()],
26
26
  })
@@ -74,7 +74,7 @@ async function compileFromStdin(jsCode: string, outfile: string) {
74
74
  return compileJs(jsCode, outfile)
75
75
  }
76
76
 
77
- export async function runBuildCommand() {
77
+ export async function runBundleCommand() {
78
78
  if (isPrebuilt) {
79
79
  if (!source!.endsWith(".srt.js")) {
80
80
  console.error("Can only compile .srt.js files. .srt.bin is already compiled.")
package/src/main.ts CHANGED
@@ -13,9 +13,10 @@
13
13
  // srt record examples/hello.tsx - bundle TSX and run with frame capture
14
14
 
15
15
  import pkg from "../package.json"
16
- import { values, command, source, isTsx, isPrebuilt, printUsage } from "./args"
16
+ import { values, command, source, isTsx, isTs, isPrebuilt, printUsage } from "./args"
17
17
  import { state, requireBinary, run, shutdown } from "./util"
18
- import { bundle, bundleTo, runBuildCommand } from "./build"
18
+ import { bundle, bundleTo, runBundleCommand } from "./bundle"
19
+ import { runPackCommand } from "./pack"
19
20
  import { startServer } from "./server"
20
21
  import { spawnClient } from "./client"
21
22
  import { startRepl } from "./repl"
@@ -25,7 +26,7 @@ import { resolve, dirname } from "path"
25
26
 
26
27
  // -- Validate args --
27
28
 
28
- let COMMANDS = ["run", "server", "client", "bundle", "record"]
29
+ let COMMANDS = ["run", "server", "client", "bundle", "record", "pack"]
29
30
 
30
31
  if (!command || !COMMANDS.includes(command)) {
31
32
  printUsage()
@@ -42,6 +43,11 @@ if (command === "record" && (!source || !isTsx)) {
42
43
  process.exit(1)
43
44
  }
44
45
 
46
+ if (command === "pack" && (!source || !isTs)) {
47
+ console.error("Usage: srt pack [options] <entry.[ts|js]>")
48
+ process.exit(1)
49
+ }
50
+
45
51
  // Force the production export condition for prod bundles. Bun auto-activates the
46
52
  // "development" condition whenever NODE_ENV != "production" (read once at startup),
47
53
  // and an auto-active condition cannot be turned off via Bun.build({ conditions }).
@@ -51,7 +57,7 @@ if (command === "record" && (!source || !isTsx)) {
51
57
  // the auto-activation by setting NODE_ENV=production. Since that is read at startup,
52
58
  // we re-exec rather than mutate process.env. Assumes srt runs via bun (argv is
53
59
  // [bun, script, ...]); would need rework if ever shipped as a compiled binary.
54
- let isProdBuild = (command === "bundle" || command === "record") && !values.dev
60
+ let isProdBuild = (command === "bundle" || command === "record" || command === "pack") && !values.dev
55
61
  if (isProdBuild && process.env.NODE_ENV !== "production") {
56
62
  let proc = Bun.spawnSync({
57
63
  cmd: [process.execPath, ...process.argv.slice(1)],
@@ -66,7 +72,11 @@ if (isProdBuild && process.env.NODE_ENV !== "production") {
66
72
  // -- Bundle command --
67
73
 
68
74
  if (command === "bundle") {
69
- await runBuildCommand()
75
+ await runBundleCommand()
76
+ }
77
+
78
+ if (command === "pack") {
79
+ await runPackCommand()
70
80
  }
71
81
 
72
82
  // -- Record command --
package/src/pack.ts ADDED
@@ -0,0 +1,58 @@
1
+ import { values, source } from "./args"
2
+ import { requireBinary } from "./util"
3
+
4
+ const MAGIC = Buffer.from([0x46, 0x4c, 0x55, 0x58, 0x52, 0x54, 0x00, 0x01]) // "FLUXRT\x00\x01"
5
+
6
+ async function bundleFlux(entry: string): Promise<string> {
7
+ let result = await Bun.build({
8
+ entrypoints: [entry],
9
+ target: "browser",
10
+ format: "esm",
11
+ minify: values.minify,
12
+ external: ["qjs:*", "flux:*"],
13
+ })
14
+ if (!result.success) {
15
+ for (let msg of result.logs) console.error(msg)
16
+ console.error("Build failed")
17
+ process.exit(1)
18
+ }
19
+ let jsCode = ""
20
+ for (let output of result.outputs) jsCode += await output.text()
21
+ return jsCode
22
+ }
23
+
24
+ async function compileToBytecode(jsCode: string): Promise<Buffer> {
25
+ let compiler = requireBinary("fluxc")
26
+ let proc = Bun.spawn([compiler], {
27
+ stdin: new Blob([jsCode]),
28
+ stdout: "pipe",
29
+ stderr: "inherit",
30
+ })
31
+ let [bytecode, code] = await Promise.all([new Response(proc.stdout).arrayBuffer(), proc.exited])
32
+ if (code !== 0) process.exit(code)
33
+ return Buffer.from(bytecode)
34
+ }
35
+
36
+ export async function runPackCommand() {
37
+ let outfile = values.output ?? source!.replace(/\.[jt]s$/, "")
38
+
39
+ let jsCode = await bundleFlux(source!)
40
+
41
+ let bytecode = await compileToBytecode(jsCode)
42
+
43
+ let runner = requireBinary("fluxrt")
44
+ let runnerBytes = Buffer.from(await Bun.file(runner).arrayBuffer())
45
+
46
+ let offsetBuf = Buffer.allocUnsafe(8)
47
+ offsetBuf.writeBigUInt64LE(BigInt(runnerBytes.length))
48
+
49
+ let packed = Buffer.concat([runnerBytes, bytecode, offsetBuf, MAGIC])
50
+ await Bun.write(outfile, packed)
51
+
52
+ if (process.platform !== "win32") {
53
+ Bun.spawnSync(["chmod", "+x", outfile])
54
+ }
55
+
56
+ console.log(`>> wrote ${packed.length} bytes to ${outfile}`)
57
+ process.exit()
58
+ }
package/src/repl.ts CHANGED
@@ -2,7 +2,7 @@ import { createInterface } from "node:readline"
2
2
  import { resolve, dirname } from "path"
3
3
  import { readdirSync } from "node:fs"
4
4
  import { state, print, printErr, broadcastStop, buildReload, shutdown } from "./util"
5
- import { bundle } from "./build"
5
+ import { bundle } from "./bundle"
6
6
  import { startWatcher, stopWatcher } from "./watcher"
7
7
 
8
8
  function cmdStop(args: string) {
package/src/watcher.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { watch } from "node:fs"
2
2
  import { resolve, dirname } from "path"
3
3
  import { state, print, printErr, buildReload } from "./util"
4
- import { bundle } from "./build"
4
+ import { bundle } from "./bundle"
5
5
 
6
6
  let currentWatcher: ReturnType<typeof watch> | null = null
7
7