@solidrt/cli 0.0.6 → 0.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidrt/cli",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
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.8",
23
+ "@solidrt/linux-x64-gnu": "0.0.8",
24
+ "@solidrt/win32-x64-msvc": "0.0.8"
25
25
  },
26
26
  "peerDependencies": {
27
- "@solidrt/core": "0.0.6",
27
+ "@solidrt/core": "0.0.8",
28
28
  "typescript": "^5"
29
29
  },
30
30
  "devDependencies": {
package/src/args.ts CHANGED
@@ -19,17 +19,20 @@ 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")
23
+ export let isSource = isTsx || isTs
22
24
  export let isPrebuilt = source?.endsWith(".srt.js") || source?.endsWith(".srt.bin")
23
25
 
24
26
  export function printUsage() {
25
27
  console.error(`Usage: srt <command> [options] [file]
26
28
 
27
29
  Commands:
28
- run [file.tsx|jsx] Start dev server + local solidrt-go client
29
- server [file.tsx|jsx] Start dev server only
30
+ run [file] Start dev server + local solidrt-go client
31
+ server [file] Start dev server only
30
32
  client Start solidrt-go client only
31
- bundle <file.tsx|jsx> Transpile TSX/JSX to JS or bytecode
33
+ bundle <file> Transpile TS/JS/TSX/JSX to JS or bytecode
32
34
  record <file.tsx|jsx> Capture frames for video generation
35
+ pack <file.ts|js> Bundle + compile to a standalone executable (experimental, Flux only)
33
36
 
34
37
  run/server options:
35
38
  --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: ["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.")
@@ -86,7 +86,7 @@ export async function runBuildCommand() {
86
86
  process.exit()
87
87
  }
88
88
 
89
- let baseName = values.output ?? source!.replace(/\.[jt]sx$/, "")
89
+ let baseName = values.output ?? source!.replace(/\.[jt]sx?$/, "")
90
90
 
91
91
  if (values.stdout) {
92
92
  let result = await bundle()
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, isSource, 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,15 +26,15 @@ 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()
32
33
  process.exit(1)
33
34
  }
34
35
 
35
- if (command === "bundle" && (!source || (!isTsx && !isPrebuilt))) {
36
- console.error("Usage: srt bundle [options] <entry.[tsx|jsx|srt.js|srt.bin]>")
36
+ if (command === "bundle" && (!source || (!isSource && !isPrebuilt))) {
37
+ console.error("Usage: srt bundle [options] <entry.[tsx|jsx|ts|js|srt.js|srt.bin]>")
37
38
  process.exit(1)
38
39
  }
39
40
 
@@ -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 --
@@ -110,7 +120,7 @@ startServer()
110
120
 
111
121
  // Bundle initial code if source file given (after server start so the
112
122
  // dev base URL is available to the bundler).
113
- if (source && isTsx) {
123
+ if (source && isSource) {
114
124
  let initialResult = await bundle()
115
125
  if (initialResult) {
116
126
  for (let output of initialResult.outputs) {
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: ["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