@solidrt/cli 0.0.5 → 0.0.6

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.5",
3
+ "version": "0.0.6",
4
4
  "license": "MIT",
5
5
  "author": "Antoine van Wel",
6
6
  "type": "module",
@@ -15,16 +15,16 @@
15
15
  "dependencies": {
16
16
  "@babel/core": "^7.28.5",
17
17
  "@babel/preset-typescript": "^7.28.5",
18
- "babel-preset-solid": "2.0.0-beta.13",
18
+ "babel-preset-solid": "2.0.0-beta.14",
19
19
  "qrcode-generator": "^2.0.4"
20
20
  },
21
21
  "optionalDependencies": {
22
- "@solidrt/darwin-arm64": "0.0.5",
23
- "@solidrt/linux-x64-gnu": "0.0.5",
24
- "@solidrt/win32-x64-msvc": "0.0.5"
22
+ "@solidrt/darwin-arm64": "0.0.6",
23
+ "@solidrt/linux-x64-gnu": "0.0.6",
24
+ "@solidrt/win32-x64-msvc": "0.0.6"
25
25
  },
26
26
  "peerDependencies": {
27
- "@solidrt/core": "0.0.5",
27
+ "@solidrt/core": "0.0.6",
28
28
  "typescript": "^5"
29
29
  },
30
30
  "devDependencies": {
package/src/args.ts CHANGED
@@ -2,14 +2,13 @@ import { parseArgs } from "node:util"
2
2
 
3
3
  export let { values, positionals } = parseArgs({
4
4
  options: {
5
+ dev: { type: "boolean", short: "d", default: false },
5
6
  minify: { type: "boolean", short: "m", default: false },
6
7
  compile: { type: "boolean", short: "c", default: false },
7
8
  stdout: { type: "boolean", default: false },
8
9
  output: { type: "string", short: "o" },
9
- client: { type: "boolean", default: false },
10
- server: { type: "boolean", default: false },
11
- cache: { type: "boolean", default: false },
12
- proxy: { type: "boolean", default: false },
10
+ "proxy-files": { type: "boolean", default: false },
11
+ "proxy-http": { type: "boolean", default: false },
13
12
  fps: { type: "string" },
14
13
  duration: { type: "string" },
15
14
  size: { type: "string" },
@@ -19,34 +18,35 @@ export let { values, positionals } = parseArgs({
19
18
 
20
19
  export let command = positionals[0]
21
20
  export let source = positionals[1]
22
- export let isTsx = source?.endsWith(".tsx")
21
+ export let isTsx = source?.endsWith(".tsx") || source?.endsWith(".jsx")
23
22
  export let isPrebuilt = source?.endsWith(".srt.js") || source?.endsWith(".srt.bin")
24
23
 
25
24
  export function printUsage() {
26
25
  console.error(`Usage: srt <command> [options] [file]
27
26
 
28
27
  Commands:
29
- run [file.tsx] Start dev server + local solidrt-go client
30
- run --client Start solidrt-go client only
31
- run --server [file.tsx] Start dev server only
32
- build <file.tsx> Bundle
33
- record <file.tsx> Capture frames for video generation
34
-
35
- run options:
36
- --client Run client only
37
- --server Run server only
38
- --cache Enable HTTP cache
39
- --proxy Tell connected clients to route file/dir/fetch through the dev server
40
- --size <WxH> Window size (default: 1280x720)
41
-
42
- build options:
43
- -m, --minify Minify the output
44
- -c, --compile Compile to bytecode
45
- -o, --output <name> Output filename
46
- --stdout Write bundle to stdout
28
+ run [file.tsx|jsx] Start dev server + local solidrt-go client
29
+ server [file.tsx|jsx] Start dev server only
30
+ client Start solidrt-go client only
31
+ bundle <file.tsx|jsx> Transpile TSX/JSX to JS or bytecode
32
+ record <file.tsx|jsx> Capture frames for video generation
33
+
34
+ run/server options:
35
+ --proxy-files Route file/dir access through the dev server
36
+ --proxy-http Route fetch calls through the dev server (HTTP cache enabled)
37
+
38
+ run/client options:
39
+ --size <WxH> Window size (default: 1280x720)
40
+
41
+ bundle options:
42
+ -d, --dev Use development build of SolidJS (default: production)
43
+ -m, --minify Minify the output
44
+ -c, --compile Compile to bytecode
45
+ -o, --output <name> Output filename
46
+ --stdout Write bundle to stdout
47
47
 
48
48
  record options:
49
- --fps <N> Frames per second (default: 60)
50
- --duration <N> Duration in seconds (default: 1)
51
- --size <WxH> Frame size (default: 1280x720)`)
52
- }
49
+ --fps <N> Frames per second (default: 60)
50
+ --duration <N> Duration in seconds (default: 1)
51
+ --size <WxH> Frame size (default: 1280x720)`)
52
+ }
package/src/build.ts CHANGED
@@ -1,14 +1,18 @@
1
1
  import { solidPlugin } from "./bun-plugin-solid"
2
2
  import { values, source, isPrebuilt } from "./args"
3
- import { requireBinary, state } from "./util"
3
+ import { requireBinary, state, print } from "./util"
4
4
  import { resolve } from "path"
5
5
 
6
6
  export async function bundle(entry = source) {
7
7
  let result = null
8
8
 
9
9
  let devBase = state.serverUrl ?? undefined
10
- let define: Record<string, string> = { "process.env.NODE_ENV": "production" }
11
- if (devBase) define.__SRT_DEV_BASE__ = JSON.stringify(devBase)
10
+ let dev = !!devBase || values.dev
11
+ print(`[cli] Bundling (${dev ? "development" : "production"})`)
12
+ let define: Record<string, string> = {
13
+ "process.env.NODE_ENV": dev ? "development" : "production",
14
+ }
15
+ if (devBase) define.__SRT_DEV_BASE__ = devBase
12
16
 
13
17
  try {
14
18
  result = await Bun.build({
@@ -18,7 +22,7 @@ export async function bundle(entry = source) {
18
22
  minify: values.minify,
19
23
  external: ["qjs:*"],
20
24
  define,
21
- plugins: [solidPlugin({ devBase })],
25
+ plugins: [solidPlugin()],
22
26
  })
23
27
  } catch (e) {
24
28
  console.error("[cli] compile error:\n", e)
@@ -76,11 +80,13 @@ export async function runBuildCommand() {
76
80
  console.error("Can only compile .srt.js files. .srt.bin is already compiled.")
77
81
  process.exit(1)
78
82
  }
79
- await compileToBytecode(resolve(source!))
83
+ let binOut = await compileToBytecode(resolve(source!))
84
+ let binSize = (await Bun.file(binOut).stat()).size
85
+ console.log(`>> wrote ${binSize} bytes to ${binOut}`)
80
86
  process.exit()
81
87
  }
82
88
 
83
- let baseName = values.output ?? source!.replace(/\.tsx$/, "")
89
+ let baseName = values.output ?? source!.replace(/\.[jt]sx$/, "")
84
90
 
85
91
  if (values.stdout) {
86
92
  let result = await bundle()
@@ -106,6 +112,8 @@ export async function runBuildCommand() {
106
112
  }
107
113
  let binOutfile = baseName + ".srt.bin"
108
114
  await compileFromStdin(jsCode, binOutfile)
115
+ let binSize = (await Bun.file(binOutfile).stat()).size
116
+ console.log(`>> wrote ${binSize} bytes to ${binOutfile}`)
109
117
  process.exit()
110
118
  }
111
119
 
@@ -115,4 +123,4 @@ export async function runBuildCommand() {
115
123
  console.log(`>> wrote ${output.size} bytes to ${jsOutfile}`)
116
124
  }
117
125
  process.exit()
118
- }
126
+ }
package/src/cache.ts CHANGED
@@ -1,19 +1,17 @@
1
1
  // SQLite-backed HTTP response cache for the dev server's /__proxy__ endpoint.
2
2
  //
3
- // Project-local: stored at <cwd>/.srt-cache/cache.db. Opt-in via the --cache
4
- // flag. Entries live forever; delete the .srt-cache directory to drop them.
3
+ // Project-local: stored at <cwd>/.srt-cache.db. Opt-in via the --cache
4
+ // flag. Entries live forever; delete .srt-cache.db to drop them.
5
5
  //
6
6
  // Cached: GET (and HEAD) 2xx responses with no Authorization on the request
7
7
  // and no Cache-Control: no-store on either side. The cache key is
8
8
  // sha256(method + "\n" + url); headers are intentionally not part of the key.
9
9
 
10
10
  import { Database } from "bun:sqlite"
11
- import { resolve, join } from "path"
12
- import { mkdirSync } from "node:fs"
11
+ import { resolve } from "path"
13
12
  import { createHash } from "node:crypto"
14
13
 
15
- const CACHE_DIR = ".srt-cache"
16
- const CACHE_DB = "cache.db"
14
+ const CACHE_FILE = ".srt-cache.db"
17
15
 
18
16
  export type Decision = "hit" | "miss" | "bypass" | "skip"
19
17
 
@@ -30,8 +28,7 @@ let db: Database | null = null
30
28
  let enabled = false
31
29
 
32
30
  export function initCache(opts: { dir: string }) {
33
- mkdirSync(resolve(opts.dir, CACHE_DIR), { recursive: true })
34
- let d = new Database(join(resolve(opts.dir, CACHE_DIR), CACHE_DB), { create: true })
31
+ let d = new Database(resolve(opts.dir, CACHE_FILE), { create: true })
35
32
  d.run(`CREATE TABLE IF NOT EXISTS entries (
36
33
  key TEXT PRIMARY KEY,
37
34
  method TEXT NOT NULL,
package/src/main.ts CHANGED
@@ -5,11 +5,11 @@
5
5
  // Usage:
6
6
  // srt run - start dev server + client
7
7
  // srt run examples/hello.tsx - start dev server + client, bundle + push via WS
8
- // srt run --client - start dev client only (connects to WS server)
9
- // srt run --server examples/hello.tsx - start dev server only, no client
10
- // srt build examples/hello.tsx - bundle TSX to .srt.js
11
- // srt build -c examples/hello.tsx - bundle TSX to .srt.js + compile to .srt.bin
12
- // srt build examples/hello.srt.js - compile .srt.js to .srt.bin
8
+ // srt server examples/hello.tsx - start dev server only, no client
9
+ // srt client - start dev client only (connects to WS server)
10
+ // srt bundle examples/hello.tsx - bundle TSX to .srt.js
11
+ // srt bundle -c examples/hello.tsx - bundle TSX to .srt.js + compile to .srt.bin
12
+ // srt bundle examples/hello.srt.js - compile .srt.js to .srt.bin
13
13
  // srt record examples/hello.tsx - bundle TSX and run with frame capture
14
14
 
15
15
  import pkg from "../package.json"
@@ -25,31 +25,54 @@ import { resolve, dirname } from "path"
25
25
 
26
26
  // -- Validate args --
27
27
 
28
- if (!command || (command !== "build" && command !== "run" && command !== "record")) {
28
+ let COMMANDS = ["run", "server", "client", "bundle", "record"]
29
+
30
+ if (!command || !COMMANDS.includes(command)) {
29
31
  printUsage()
30
32
  process.exit(1)
31
33
  }
32
34
 
33
- if (command === "build" && (!source || (!isTsx && !isPrebuilt))) {
34
- console.error("Usage: srt build [options] <entry.tsx|.srt.js|.srt.bin>")
35
+ if (command === "bundle" && (!source || (!isTsx && !isPrebuilt))) {
36
+ console.error("Usage: srt bundle [options] <entry.[tsx|jsx|srt.js|srt.bin]>")
35
37
  process.exit(1)
36
38
  }
37
39
 
38
40
  if (command === "record" && (!source || !isTsx)) {
39
- console.error("Usage: srt record <entry.tsx>")
41
+ console.error("Usage: srt record <entry.[tsx|jsx]>")
40
42
  process.exit(1)
41
43
  }
42
44
 
43
- // -- Build command --
45
+ // Force the production export condition for prod bundles. Bun auto-activates the
46
+ // "development" condition whenever NODE_ENV != "production" (read once at startup),
47
+ // and an auto-active condition cannot be turned off via Bun.build({ conditions }).
48
+ // Our deps (@solidjs/signals, solid-js) only expose a "development" branch + a
49
+ // default fallback - no "production" key - so adding conditions does nothing; the
50
+ // only way to reach the default (smaller, no extra invariants) build is to stop
51
+ // the auto-activation by setting NODE_ENV=production. Since that is read at startup,
52
+ // we re-exec rather than mutate process.env. Assumes srt runs via bun (argv is
53
+ // [bun, script, ...]); would need rework if ever shipped as a compiled binary.
54
+ let isProdBuild = (command === "bundle" || command === "record") && !values.dev
55
+ if (isProdBuild && process.env.NODE_ENV !== "production") {
56
+ let proc = Bun.spawnSync({
57
+ cmd: [process.execPath, ...process.argv.slice(1)],
58
+ env: { ...process.env, NODE_ENV: "production" },
59
+ stdin: "inherit",
60
+ stdout: "inherit",
61
+ stderr: "inherit",
62
+ })
63
+ process.exit(proc.exitCode ?? 0)
64
+ }
65
+
66
+ // -- Bundle command --
44
67
 
45
- if (command === "build") {
68
+ if (command === "bundle") {
46
69
  await runBuildCommand()
47
70
  }
48
71
 
49
72
  // -- Record command --
50
73
 
51
74
  if (command === "record") {
52
- let jsOutfile = source!.replace(/\.tsx$/, "") + ".srt.js"
75
+ let jsOutfile = source!.replace(/\.[jt]sx$/, "") + ".srt.js"
53
76
  await bundleTo(jsOutfile)
54
77
  let runner = requireBinary("solidrt-go")
55
78
  let recordArgs = ["--record", resolve(jsOutfile)]
@@ -60,9 +83,9 @@ if (command === "record") {
60
83
  process.exit(exit)
61
84
  }
62
85
 
63
- // -- Run command --
86
+ // -- Client command --
64
87
 
65
- if (values.client) {
88
+ if (command === "client") {
66
89
  let runner = requireBinary("solidrt-go")
67
90
  let args: string[] = []
68
91
  if (values.size) args.push("--size", values.size)
@@ -72,11 +95,13 @@ if (values.client) {
72
95
  process.exit(exit)
73
96
  }
74
97
 
98
+ // -- Server / Run command --
99
+
75
100
  // Initialize state from args
76
101
  state.source = source
77
102
  state.sourceDir = source ? dirname(resolve(source)) : process.cwd()
78
103
 
79
- if (values.cache) {
104
+ if (values["proxy-http"]) {
80
105
  cache.initCache({ dir: process.cwd() })
81
106
  console.log("[cli] HTTP cache enabled")
82
107
  }
@@ -92,9 +117,11 @@ if (source && isTsx) {
92
117
  state.currentCode = await output.text()
93
118
  }
94
119
  }
120
+ } else if (source && isPrebuilt && source.endsWith(".srt.js")) {
121
+ state.currentCode = await Bun.file(resolve(source)).text()
95
122
  }
96
123
 
97
- if (!values.server) {
124
+ if (command === "run") {
98
125
  spawnClient()
99
126
  }
100
127
 
package/src/util.ts CHANGED
@@ -43,7 +43,7 @@ export function printErr(...args: any[]) {
43
43
  }
44
44
 
45
45
  export function buildReload(payload: { code?: string | null; bytecode?: string }) {
46
- return JSON.stringify({ type: "reload", proxy: values.proxy, ...payload })
46
+ return JSON.stringify({ type: "reload", proxyFiles: values["proxy-files"], proxyHttp: values["proxy-http"], ...payload })
47
47
  }
48
48
 
49
49
  export function broadcastStop() {