@solidrt/cli 0.0.9 → 0.0.10
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 +6 -5
- package/src/args.ts +8 -4
- package/src/bundler.ts +1 -1
- package/src/cache.ts +16 -1
- package/src/commands/bundle.ts +27 -2
- package/src/dev-android.ts +74 -35
- package/src/dev-server.ts +34 -20
- package/src/util.ts +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidrt/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Antoine van Wel",
|
|
6
6
|
"type": "module",
|
|
@@ -16,15 +16,16 @@
|
|
|
16
16
|
"@babel/core": "^7.28.5",
|
|
17
17
|
"@babel/preset-typescript": "^7.28.5",
|
|
18
18
|
"babel-preset-solid": "2.0.0-beta.14",
|
|
19
|
+
"bonjour-service": "^1.4.0",
|
|
19
20
|
"qrcode-generator": "^2.0.4"
|
|
20
21
|
},
|
|
21
22
|
"optionalDependencies": {
|
|
22
|
-
"@solidrt/darwin-arm64": "0.0.
|
|
23
|
-
"@solidrt/linux-x64-gnu": "0.0.
|
|
24
|
-
"@solidrt/win32-x64-msvc": "0.0.
|
|
23
|
+
"@solidrt/darwin-arm64": "0.0.10",
|
|
24
|
+
"@solidrt/linux-x64-gnu": "0.0.10",
|
|
25
|
+
"@solidrt/win32-x64-msvc": "0.0.10"
|
|
25
26
|
},
|
|
26
27
|
"peerDependencies": {
|
|
27
|
-
"@solidrt/core": "0.0.
|
|
28
|
+
"@solidrt/core": "0.0.10",
|
|
28
29
|
"typescript": "^5"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
package/src/args.ts
CHANGED
|
@@ -5,7 +5,7 @@ export let { values, positionals } = parseArgs({
|
|
|
5
5
|
dev: { type: "boolean", short: "d", default: false },
|
|
6
6
|
minify: { type: "boolean", short: "m", default: false },
|
|
7
7
|
compile: { type: "boolean", short: "c", default: false },
|
|
8
|
-
flux: { type: "boolean", default: false },
|
|
8
|
+
flux: { type: "boolean", short: "f", default: false },
|
|
9
9
|
stdout: { type: "boolean", default: false },
|
|
10
10
|
output: { type: "string", short: "o" },
|
|
11
11
|
"proxy-files": { type: "boolean", default: false },
|
|
@@ -35,8 +35,11 @@ function usage(line: string): never {
|
|
|
35
35
|
export function validateArgs() {
|
|
36
36
|
switch (command) {
|
|
37
37
|
case "bundle":
|
|
38
|
-
if (
|
|
38
|
+
if (values.flux) {
|
|
39
|
+
if (!source || !isTs) usage("srt bundle --flux [options] <entry.[ts|js]>")
|
|
40
|
+
} else if (!source || (!isSource && !isPrebuilt)) {
|
|
39
41
|
usage("srt bundle [options] <entry.[tsx|jsx|ts|js|srt.js|srt.bin]>")
|
|
42
|
+
}
|
|
40
43
|
break
|
|
41
44
|
case "record":
|
|
42
45
|
if (!source || !isTsx) usage("srt record <entry.[tsx|jsx]>")
|
|
@@ -77,9 +80,10 @@ run/client options:
|
|
|
77
80
|
|
|
78
81
|
client options:
|
|
79
82
|
--android Install and launch the client on a connected Android device
|
|
80
|
-
--device <serial> Target a specific adb device
|
|
83
|
+
--device <serial> Target a specific adb device by serial or unique prefix
|
|
81
84
|
|
|
82
85
|
bundle options:
|
|
86
|
+
-f, --flux Bundle for the bare Flux runtime, without SolidJS (entry must be .ts|.js)
|
|
83
87
|
-d, --dev Use development build of SolidJS (default: production)
|
|
84
88
|
-m, --minify Minify the output
|
|
85
89
|
-c, --compile Compile to bytecode
|
|
@@ -87,7 +91,7 @@ bundle options:
|
|
|
87
91
|
--stdout Write bundle to stdout
|
|
88
92
|
|
|
89
93
|
pack options:
|
|
90
|
-
|
|
94
|
+
-f, --flux Pack for the bare Flux runtime instead of SolidRT (entry must be .ts|.js)
|
|
91
95
|
-m, --minify Minify the output
|
|
92
96
|
-o, --output <name> Output filename
|
|
93
97
|
|
package/src/bundler.ts
CHANGED
package/src/cache.ts
CHANGED
|
@@ -46,6 +46,21 @@ export function isEnabled(): boolean {
|
|
|
46
46
|
return enabled
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
// Strings returned by bun:sqlite carry an internal representation that
|
|
50
|
+
// Headers.set() rejects, even when value-identical to an acceptable string
|
|
51
|
+
// (Bun bug, present through 1.3.14). Rebuilding each char yields a clean string.
|
|
52
|
+
function reflatten(s: string): string {
|
|
53
|
+
return Array.from(s, (c) => String.fromCharCode(c.charCodeAt(0))).join("")
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function reflattenHeaders(obj: Record<string, string>): Record<string, string> {
|
|
57
|
+
let out: Record<string, string> = {}
|
|
58
|
+
for (let key in obj) {
|
|
59
|
+
out[reflatten(key)] = reflatten(obj[key]!)
|
|
60
|
+
}
|
|
61
|
+
return out
|
|
62
|
+
}
|
|
63
|
+
|
|
49
64
|
function keyFor(method: string, url: string): string {
|
|
50
65
|
let h = createHash("sha256")
|
|
51
66
|
h.update(method)
|
|
@@ -101,7 +116,7 @@ export function get(method: string, url: string): Entry | null {
|
|
|
101
116
|
method: row.method,
|
|
102
117
|
url: row.url,
|
|
103
118
|
status: row.status,
|
|
104
|
-
headers: JSON.parse(row.headers),
|
|
119
|
+
headers: reflattenHeaders(JSON.parse(row.headers)),
|
|
105
120
|
body: row.body,
|
|
106
121
|
cachedAt: row.cached_at,
|
|
107
122
|
}
|
package/src/commands/bundle.ts
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { values, source, isPrebuilt } from "../args"
|
|
2
|
-
import { bundle, bundleTo, compileToBytecode } from "../bundler"
|
|
2
|
+
import { bundle, bundleTo, bundleFlux, compileToBytecode } from "../bundler"
|
|
3
3
|
import { resolve } from "path"
|
|
4
4
|
|
|
5
|
+
// Write to stdout and resolve only once the whole payload is flushed.
|
|
6
|
+
// process.stdout.write to a pipe is async and applies backpressure; the
|
|
7
|
+
// callback fires after every byte is drained, so it is safe to exit after.
|
|
8
|
+
function writeStdout(data: string): Promise<void> {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
process.stdout.write(data, (err) => (err ? reject(err) : resolve()))
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
|
|
5
14
|
// Compile JS to a .srt.bin file and report its size.
|
|
6
15
|
async function writeBytecode(jsCode: string, outfile: string) {
|
|
7
16
|
let bytecode = await compileToBytecode(jsCode)
|
|
@@ -11,6 +20,22 @@ async function writeBytecode(jsCode: string, outfile: string) {
|
|
|
11
20
|
}
|
|
12
21
|
|
|
13
22
|
export async function runBundleCommand() {
|
|
23
|
+
if (values.flux) {
|
|
24
|
+
let baseName = values.output ?? source!.replace(/\.[jt]s$/, "")
|
|
25
|
+
let jsCode = await bundleFlux(source!)
|
|
26
|
+
|
|
27
|
+
if (values.stdout) {
|
|
28
|
+
await writeStdout(jsCode)
|
|
29
|
+
} else if (values.compile) {
|
|
30
|
+
await writeBytecode(jsCode, baseName + ".flux.bin")
|
|
31
|
+
} else {
|
|
32
|
+
let outfile = baseName + ".flux.js"
|
|
33
|
+
await Bun.write(outfile, jsCode)
|
|
34
|
+
console.log(`>> wrote ${jsCode.length} bytes to ${outfile}`)
|
|
35
|
+
}
|
|
36
|
+
process.exit()
|
|
37
|
+
}
|
|
38
|
+
|
|
14
39
|
if (isPrebuilt) {
|
|
15
40
|
if (!source!.endsWith(".srt.js")) {
|
|
16
41
|
console.error("Can only compile .srt.js files. .srt.bin is already compiled.")
|
|
@@ -31,7 +56,7 @@ export async function runBundleCommand() {
|
|
|
31
56
|
process.exit(1)
|
|
32
57
|
}
|
|
33
58
|
for (let output of result.outputs) {
|
|
34
|
-
|
|
59
|
+
await writeStdout(await output.text())
|
|
35
60
|
}
|
|
36
61
|
process.exit()
|
|
37
62
|
}
|
package/src/dev-android.ts
CHANGED
|
@@ -1,20 +1,79 @@
|
|
|
1
1
|
import { print, requireAdb } from "./util"
|
|
2
2
|
import { resolveApk } from "./artifacts"
|
|
3
3
|
import { values } from "./args"
|
|
4
|
+
import { DEV_PORT } from "./dev-server"
|
|
4
5
|
|
|
5
|
-
// Launch component of the "go" dev-client flavor (see lattice/Makefile.
|
|
6
|
+
// Launch component of the "go" dev-client flavor (see lattice/Makefile.android).
|
|
6
7
|
let PACKAGE_ACTIVITY = "com.solidrt.go/com.solidrt.app.MainActivity"
|
|
7
8
|
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
// Forward the device's loopback DEV_PORT to the host dev server, so the client
|
|
10
|
+
// reaches it at 127.0.0.1:DEV_PORT (see lattice/src/go/connection.rs). This is
|
|
11
|
+
// the adb-reverse path: it works for the emulator (behind NAT, cannot reach the
|
|
12
|
+
// host via LAN mDNS discovery) and for USB-tethered devices alike, and is
|
|
13
|
+
// harmless on any adb connection. (Android only uses this path; the client's
|
|
14
|
+
// mDNS discovery is desktop-only -- see lattice/src/go/connection.rs.)
|
|
15
|
+
function setupAdbReverse(adb: string, target: string) {
|
|
16
|
+
print(`[cli] Forwarding 127.0.0.1:${DEV_PORT} on ${target} to host dev server`)
|
|
17
|
+
let res = Bun.spawnSync([adb, "-s", target, "reverse", `tcp:${DEV_PORT}`, `tcp:${DEV_PORT}`], {
|
|
18
|
+
stdout: "pipe",
|
|
19
|
+
stderr: "pipe",
|
|
20
|
+
})
|
|
21
|
+
if (res.exitCode !== 0) {
|
|
22
|
+
print(`[cli] adb reverse failed (client will fall back to discovery):\n${res.stderr.toString()}`)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Serials of connected, authorized devices (excludes offline/unauthorized).
|
|
27
|
+
function listDevices(adb: string): string[] {
|
|
28
|
+
let listed = Bun.spawnSync([adb, "devices"], { stdout: "pipe", stderr: "pipe" })
|
|
29
|
+
return listed.stdout
|
|
30
|
+
.toString()
|
|
31
|
+
.split("\n")
|
|
32
|
+
.slice(1)
|
|
33
|
+
.map((l) => l.trim())
|
|
34
|
+
.filter(Boolean)
|
|
35
|
+
.filter((l) => l.endsWith("\tdevice"))
|
|
36
|
+
.map((l) => l.split("\t")[0])
|
|
37
|
+
.filter((s): s is string => Boolean(s))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Resolve the target device serial. With --device, treat the value as a serial
|
|
41
|
+
// prefix and require it to match exactly one connected device; without it, use
|
|
42
|
+
// the sole connected device. Exits with a clear message on any ambiguity.
|
|
43
|
+
function resolveTarget(adb: string): string {
|
|
44
|
+
let devices = listDevices(adb)
|
|
45
|
+
|
|
46
|
+
if (values.device) {
|
|
47
|
+
let prefix = values.device
|
|
48
|
+
let matches = devices.filter((d) => d.startsWith(prefix))
|
|
49
|
+
if (matches.length > 1) {
|
|
50
|
+
console.error(`--device "${prefix}" is ambiguous; matches: ${matches.join(", ")}`)
|
|
51
|
+
process.exit(1)
|
|
52
|
+
}
|
|
53
|
+
let [match] = matches
|
|
54
|
+
if (!match) {
|
|
55
|
+
console.error(`No connected device matches --device "${prefix}". Connected: ${devices.join(", ") || "none"}`)
|
|
56
|
+
process.exit(1)
|
|
57
|
+
}
|
|
58
|
+
return match
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (devices.length > 1) {
|
|
62
|
+
console.error(`Multiple devices connected (${devices.join(", ")}); pick one with --device <serial or prefix>.`)
|
|
63
|
+
process.exit(1)
|
|
64
|
+
}
|
|
65
|
+
let [only] = devices
|
|
66
|
+
if (!only) {
|
|
67
|
+
console.error("No authorized Android device found. Enable USB debugging and check `adb devices`.")
|
|
68
|
+
process.exit(1)
|
|
69
|
+
}
|
|
70
|
+
return only
|
|
12
71
|
}
|
|
13
72
|
|
|
14
|
-
// Install + launch the Android client on a connected device over adb,
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
73
|
+
// Install + launch the Android client on a connected device over adb, forwarding
|
|
74
|
+
// its loopback to the host dev server so the client connects at 127.0.0.1 (see
|
|
75
|
+
// setupAdbReverse). Fire-and-forget: the client's lifecycle is tracked via WS
|
|
76
|
+
// connect/disconnect in dev-server.ts, not as a child process here.
|
|
18
77
|
export async function spawnAndroidClient() {
|
|
19
78
|
let adb = requireAdb()
|
|
20
79
|
|
|
@@ -25,38 +84,18 @@ export async function spawnAndroidClient() {
|
|
|
25
84
|
process.exit(1)
|
|
26
85
|
}
|
|
27
86
|
|
|
28
|
-
|
|
29
|
-
let target = values.device
|
|
30
|
-
if (!target) {
|
|
31
|
-
let listed = Bun.spawnSync([adb, "devices"], { stdout: "pipe", stderr: "pipe" })
|
|
32
|
-
let devices = listed.stdout
|
|
33
|
-
.toString()
|
|
34
|
-
.split("\n")
|
|
35
|
-
.slice(1)
|
|
36
|
-
.map((l) => l.trim())
|
|
37
|
-
.filter(Boolean)
|
|
38
|
-
.filter((l) => l.endsWith("\tdevice"))
|
|
39
|
-
.map((l) => l.split("\t")[0])
|
|
40
|
-
|
|
41
|
-
if (devices.length === 0) {
|
|
42
|
-
console.error("No authorized Android device found. Enable USB debugging and check `adb devices`.")
|
|
43
|
-
process.exit(1)
|
|
44
|
-
}
|
|
45
|
-
if (devices.length > 1) {
|
|
46
|
-
console.error(`Multiple devices connected (${devices.join(", ")}); pick one with --device <serial>.`)
|
|
47
|
-
process.exit(1)
|
|
48
|
-
}
|
|
49
|
-
target = devices[0]
|
|
50
|
-
}
|
|
87
|
+
let target = resolveTarget(adb)
|
|
51
88
|
|
|
52
89
|
print(`[cli] Installing SolidRT-Go on ${target}`)
|
|
53
|
-
let install = Bun.spawn([adb,
|
|
90
|
+
let install = Bun.spawn([adb, "-s", target, "install", "-r", apk], { stdout: "pipe", stderr: "pipe" })
|
|
54
91
|
if ((await install.exited) !== 0) {
|
|
55
92
|
console.error("adb install failed:\n" + (await new Response(install.stderr).text()))
|
|
56
93
|
process.exit(1)
|
|
57
94
|
}
|
|
58
95
|
|
|
59
|
-
|
|
96
|
+
setupAdbReverse(adb, target)
|
|
97
|
+
|
|
98
|
+
let start = Bun.spawn([adb, "-s", target, "shell", "am", "start", "-n", PACKAGE_ACTIVITY], {
|
|
60
99
|
stdout: "pipe",
|
|
61
100
|
stderr: "pipe",
|
|
62
101
|
})
|
|
@@ -65,5 +104,5 @@ export async function spawnAndroidClient() {
|
|
|
65
104
|
process.exit(1)
|
|
66
105
|
}
|
|
67
106
|
|
|
68
|
-
print(`[cli] Launched SolidRT-Go on ${target}; waiting for it to
|
|
107
|
+
print(`[cli] Launched SolidRT-Go on ${target}; waiting for it to connect to the dev server...`)
|
|
69
108
|
}
|
package/src/dev-server.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolve } from "path"
|
|
2
2
|
import { stat as fsStat, readdir } from "node:fs/promises"
|
|
3
3
|
import { networkInterfaces } from "node:os"
|
|
4
|
-
import {
|
|
4
|
+
import { Bonjour } from "bonjour-service"
|
|
5
5
|
import qrcode from "qrcode-generator"
|
|
6
6
|
import { state, print } from "./util"
|
|
7
7
|
import { values } from "./args"
|
|
@@ -28,7 +28,6 @@ function headersToObject(h: Headers): Record<string, string> {
|
|
|
28
28
|
})
|
|
29
29
|
return out
|
|
30
30
|
}
|
|
31
|
-
|
|
32
31
|
async function handleProxy(req: Request): Promise<Response> {
|
|
33
32
|
let target = req.headers.get("x-srt-proxy-url")
|
|
34
33
|
if (!target) {
|
|
@@ -156,6 +155,9 @@ export function startServer() {
|
|
|
156
155
|
open(ws) {
|
|
157
156
|
state.clients.set(ws, { platform: "unknown", version: "unknown" })
|
|
158
157
|
print(`[cli] Client connected ${ws.remoteAddress}`)
|
|
158
|
+
// Advertise our real LAN address so clients dialed over the adb loopback
|
|
159
|
+
// can show/remember the directly reachable address (see connection.rs).
|
|
160
|
+
ws.send(JSON.stringify({ type: "welcome", address: state.serverUrl }))
|
|
159
161
|
if (state.currentCode) {
|
|
160
162
|
ws.send(buildReload({ code: state.currentCode }))
|
|
161
163
|
}
|
|
@@ -199,31 +201,43 @@ export function startServer() {
|
|
|
199
201
|
qr.addData(serverUrl)
|
|
200
202
|
qr.make()
|
|
201
203
|
let modCount = qr.getModuleCount()
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
204
|
+
// Render as a white tile with black modules (explicit ANSI colors) plus the
|
|
205
|
+
// 4-module quiet zone the QR spec requires. Drawing with the terminal's
|
|
206
|
+
// default foreground inverts the code on dark themes, which standard
|
|
207
|
+
// decoders reject.
|
|
208
|
+
const QR_INK = "\x1b[30;107m" // black modules on bright-white tile (tile = background)
|
|
209
|
+
const QR_TILE_FG = "\x1b[97m" // bright-white as foreground over the default background
|
|
210
|
+
const QR_RESET = "\x1b[0m"
|
|
211
|
+
const QUIET_ZONE = 2 // modules (spec says 4, but scanners cope and it reads tighter)
|
|
212
|
+
let qrWidth = modCount + 2 * QUIET_ZONE
|
|
213
|
+
let dark = (y: number, x: number) => y >= 0 && y < modCount && x >= 0 && x < modCount && qr.isDark(y, x)
|
|
214
|
+
// modCount is always odd, so the tile is a half-line taller than an even row
|
|
215
|
+
// count. The loop packs two module-rows per line via half-blocks and stops on
|
|
216
|
+
// the last content row, leaving the bottom quiet zone half a line short of the
|
|
217
|
+
// full-line top quiet zone.
|
|
218
|
+
for (let y = -QUIET_ZONE; y < modCount + QUIET_ZONE - 1; y += 2) {
|
|
219
|
+
let row = " " + QR_INK
|
|
220
|
+
for (let x = -QUIET_ZONE; x < modCount + QUIET_ZONE; x++) {
|
|
221
|
+
let top = dark(y, x)
|
|
222
|
+
let bot = dark(y + 1, x)
|
|
207
223
|
row += top && bot ? "\u2588" : top ? "\u2580" : bot ? "\u2584" : " "
|
|
208
224
|
}
|
|
209
|
-
console.log(row)
|
|
225
|
+
console.log(row + QR_RESET)
|
|
210
226
|
}
|
|
227
|
+
// Close that gap with a half-height tile line: upper half painted in the tile
|
|
228
|
+
// color (foreground), lower half the terminal background. The 0.5 here plus
|
|
229
|
+
// the 0.5 already under the last content row equal the full-line top margin.
|
|
230
|
+
console.log(" " + QR_TILE_FG + "\u2580".repeat(qrWidth) + QR_RESET)
|
|
211
231
|
|
|
212
232
|
console.log("")
|
|
213
233
|
console.log(`[cli] WebSocket server on ws://${serverUrl}`)
|
|
214
234
|
|
|
215
|
-
//
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
})
|
|
223
|
-
udp.bind(DEV_PORT, () => {
|
|
224
|
-
udp.setBroadcast(true)
|
|
225
|
-
print("[cli] UDP discovery listener on port " + DEV_PORT)
|
|
226
|
-
})
|
|
235
|
+
// LAN discovery: advertise the dev server as a DNS-SD service so go clients on
|
|
236
|
+
// the same network can find it (see lattice/src/go/connection.rs). Stored on
|
|
237
|
+
// state so shutdown() can send the mDNS goodbye.
|
|
238
|
+
state.bonjour = new Bonjour()
|
|
239
|
+
state.bonjour.publish({ name: "SolidRT Dev Server", type: "solidrt", protocol: "tcp", port: DEV_PORT })
|
|
240
|
+
print(`[cli] Advertising _solidrt._tcp on port ${DEV_PORT} via mDNS`)
|
|
227
241
|
|
|
228
242
|
// Keepalive
|
|
229
243
|
setInterval(() => {
|
package/src/util.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { existsSync } from "node:fs"
|
|
|
3
3
|
import { resolve } from "node:path"
|
|
4
4
|
import type { Interface as ReadlineInterface } from "node:readline"
|
|
5
5
|
import type { Server as BunServer } from "bun"
|
|
6
|
+
import type { Bonjour } from "bonjour-service"
|
|
6
7
|
|
|
7
8
|
export let state = {
|
|
8
9
|
clients: new Map<any, { platform: string; version: string }>(),
|
|
@@ -13,11 +14,12 @@ export let state = {
|
|
|
13
14
|
server: null as BunServer<undefined> | null,
|
|
14
15
|
serverUrl: null as string | null,
|
|
15
16
|
rl: null as ReadlineInterface | null,
|
|
17
|
+
bonjour: null as Bonjour | null,
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
// Build target per binary, for the "not found" hint. Run from the repo root.
|
|
19
21
|
let BUILD_HINTS: Record<string, string> = {
|
|
20
|
-
"solidrt-go": "make
|
|
22
|
+
"solidrt-go": "make client",
|
|
21
23
|
solidrt: "make runtime",
|
|
22
24
|
flux: "make -C flux flux",
|
|
23
25
|
fluxc: "make -C flux fluxc",
|
|
@@ -82,5 +84,6 @@ export function printErr(...args: any[]) {
|
|
|
82
84
|
export function shutdown() {
|
|
83
85
|
if (state.child) state.child.kill()
|
|
84
86
|
if (state.server) state.server.stop()
|
|
87
|
+
if (state.bonjour) state.bonjour.destroy()
|
|
85
88
|
process.exit(0)
|
|
86
89
|
}
|