Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ jobs:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: quickjs-kmp host tools (qjsc-kmp for bytecode, host JNI for Android host tests)
- name: quickjs-kmp host JNI for Android host tests (qjsc-kmp comes from the npm package)
run: |
version=$(sed -n 's/^quickjsKmp = "\(.*\)"/\1/p' gradle/libs.versions.toml)
git clone --depth 1 --branch "$version" https://github.com/HarlonWang/quickjs-kmp.git "$RUNNER_TEMP/quickjs-kmp"
(cd "$RUNNER_TEMP/quickjs-kmp" && ./gradlew :library:buildHostTools :library:buildNativeHostJni --no-daemon)
echo "TINYUI_QJSC=$RUNNER_TEMP/quickjs-kmp/library/build/native/host-tools/bin/qjsc-kmp" >> "$GITHUB_ENV"
(cd "$RUNNER_TEMP/quickjs-kmp" && ./gradlew :library:buildNativeHostJni --no-daemon)
echo "TINYUI_QUICKJS_HOST_JNI=$RUNNER_TEMP/quickjs-kmp/library/build/native/host-jni/lib" >> "$GITHUB_ENV"
- run: ./gradlew :compose:testAndroidHostTest :compose:apiCheck :sample:androidApp:assembleDebug --no-daemon

Expand Down
5 changes: 2 additions & 3 deletions .github/workflows/ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ jobs:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: quickjs-kmp host tools
- name: quickjs-kmp host JNI (qjsc-kmp comes from the npm package)
run: |
version=$(sed -n 's/^quickjsKmp = "\(.*\)"/\1/p' gradle/libs.versions.toml)
git clone --depth 1 --branch "$version" https://github.com/HarlonWang/quickjs-kmp.git "$RUNNER_TEMP/quickjs-kmp"
(cd "$RUNNER_TEMP/quickjs-kmp" && ./gradlew :library:buildHostTools :library:buildNativeHostJni --no-daemon)
echo "TINYUI_QJSC=$RUNNER_TEMP/quickjs-kmp/library/build/native/host-tools/bin/qjsc-kmp" >> "$GITHUB_ENV"
(cd "$RUNNER_TEMP/quickjs-kmp" && ./gradlew :library:buildNativeHostJni --no-daemon)
echo "TINYUI_QUICKJS_HOST_JNI=$RUNNER_TEMP/quickjs-kmp/library/build/native/host-jni/lib" >> "$GITHUB_ENV"
- run: ./gradlew build --no-daemon
5 changes: 2 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@ jobs:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: quickjs-kmp host tools (qjsc-kmp for bytecode, host JNI for Android host tests)
- name: quickjs-kmp host JNI for Android host tests (qjsc-kmp comes from the npm package)
run: |
version=$(sed -n 's/^quickjsKmp = "\(.*\)"/\1/p' gradle/libs.versions.toml)
git clone --depth 1 --branch "$version" https://github.com/HarlonWang/quickjs-kmp.git "$RUNNER_TEMP/quickjs-kmp"
(cd "$RUNNER_TEMP/quickjs-kmp" && ./gradlew :library:buildHostTools :library:buildNativeHostJni --no-daemon)
echo "TINYUI_QJSC=$RUNNER_TEMP/quickjs-kmp/library/build/native/host-tools/bin/qjsc-kmp" >> "$GITHUB_ENV"
(cd "$RUNNER_TEMP/quickjs-kmp" && ./gradlew :library:buildNativeHostJni --no-daemon)
echo "TINYUI_QUICKJS_HOST_JNI=$RUNNER_TEMP/quickjs-kmp/library/build/native/host-jni/lib" >> "$GITHUB_ENV"
- run: ./gradlew :compose:testAndroidHostTest :compose:apiCheck --no-daemon
- name: Publish to Maven Central
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ build-logic/ Gradle convention plugins
## 安装

- Kotlin:`implementation("app.tinyui:tinyui:<version>")`(Maven Central;自带 `wang.harlon:quickjs-kmp`);热下发另加 `app.tinyui:tinyui-updates`,同版本号
- JS:`pnpm add tinyui-core tinyui-native` 与 `pnpm add -D tinyui-cli`,三包同版本号;`tinyui build` 另需 quickjs-kmp 的宿主工具 `qjsc-kmp`(见下)
- JS:`pnpm add tinyui-core tinyui-native` 与 `pnpm add -D tinyui-cli`,三包同版本号;`tinyui build` 用的 quickjs-kmp 宿主工具 `qjsc-kmp` 随 `tinyui-cli` 的依赖装好(macOS、Linux 预编译版)

版本号与 git tag 一致,不带 `v` 前缀,Maven 与 npm 三包同号同 tag 发:推 tag 触发 `publish.yml`,Maven 走 Sonatype,npm 走 trusted publishing(OIDC,无 token)。

Expand All @@ -39,10 +39,10 @@ pnpm build && pnpm test # 三个 npm 包
pnpm schema # 改了 schema/ 之后重新生成两侧代码
```

sample 的 Gradle 构建会调 `tinyui build` 把 `sample/js` 编成字节码,需要 quickjs-kmp 的宿主工具 `qjsc-kmp`,Android host 测试还需要宿主 JNI 库。两种来源:
sample 的 Gradle 构建会调 `tinyui build` 把 `sample/js` 编成字节码,`qjsc-kmp` 来自 `pnpm install` 装好的 npm 包;Android host 测试还需要宿主 JNI 库。两种来源:

- 本地联调:`local.properties` 加 `quickjs-kmp.dir=<quickjs-kmp 仓路径>`,SDK 从源码构建(composite build),两样宿主产物由该仓的任务自动编出,零配置
- 否则:`TINYUI_QJSC` 指向 `qjsc-kmp`,`TINYUI_QUICKJS_HOST_JNI` 指向含 `libquickjs_kmp` 的目录(CI 的做法见 `.github/workflows/build.yml`)
- 本地联调:`local.properties` 加 `quickjs-kmp.dir=<quickjs-kmp 仓路径>`,SDK 从源码构建(composite build),`qjsc-kmp` 与 JNI 库都由该仓的任务自动编出,零配置
- 否则:`TINYUI_QUICKJS_HOST_JNI` 指向含 `libquickjs_kmp` 的目录(CI 的做法见 `.github/workflows/build.yml`);没有预编译 `qjsc-kmp` 的平台再用 `TINYUI_QJSC` 指向自己编的那份

## License

Expand Down
16 changes: 8 additions & 8 deletions docs/build-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

- 状态:已完成(2026-09-16,PR #2;2026-09-17 加 §7 错误上报与 source map);2026-09-19 修订模块名规则——加包名前缀、去 `pages/` 段,引入 `tinyui.config.json`([ADR-006](./adr-006-hot-updates.md) §2.10),随热下发 M1 实施,sample 与 TrendingAI 的现有模块名一并改
- 来源:[ADR-005](./adr-005-engine.md) §4 "语言目标 / 模块" 两行的展开;roadmap A 组"构建链打通"
- 范围:`tinyui-cli` 的 `tinyui build`、`compose/` 的 K0 加载序列、sample 的接线与 CI。自动 thunk(roadmap C 组)、`qjsc-kmp` 二进制分发、页面级配置文件不在本期;字节码行号回映射见 §7
- 范围:`tinyui-cli` 的 `tinyui build`、`compose/` 的 K0 加载序列、sample 的接线与 CI。自动 thunk(roadmap C 组)、页面级配置文件不在本期(`qjsc-kmp` 二进制分发已于 2026-09-23 随热下发 M5.2 做完,见 §5);字节码行号回映射见 §7

## 1. 目标与验收

Expand Down Expand Up @@ -76,27 +76,27 @@ rolldown 是真正的备选(Rollup 同形 API、oxc 转译)。CLI 只包一

## 5. 字节码由 CLI 生成,宿主工具从 quickjs-kmp 来

字节码编译放 CLI 而不放 Gradle:业务 App 不会有本仓的 build-logic,`tinyui build` 必须自己出最终产物。`qjsc-kmp` 二进制查找顺序:`--qjsc` 参数 → `TINYUI_QJSC` 环境变量 → PATH。
字节码编译放 CLI 而不放 Gradle:业务 App 不会有本仓的 build-logic,`tinyui build` 必须自己出最终产物。`qjsc-kmp` 二进制查找顺序:`--qjsc` 参数 → `TINYUI_QJSC` 环境变量 → npm 包 `qjsc-kmp` 的预编译版 → PATH。

字节码绑定引擎构建(文件头记上游 commit,quickjs-kmp `docs/native-build.md`"字节码与宿主工具"),CLI 用的 `qjsc-kmp` 必须与 App 链接的 quickjs-kmp 同一上游 commit。
字节码绑定引擎构建(文件头记上游 commit,quickjs-kmp `docs/native-build.md`"字节码与宿主工具"),CLI 用的 `qjsc-kmp` 必须与 App 链接的 quickjs-kmp 同一上游 commit。`tinyui-cli` 依赖的 `qjsc-kmp` 版本钉成与 catalog 的 `quickjsKmp` 相等(`packages/cli/test/qjsc.test.ts` 校验),对齐因此只剩"JS 工程的 `tinyui-cli` 与 App 的 `tinyui` 同版本"。

| 场景 | 来源 |
|---|---|
| 本地 | `local.properties` 有 `quickjs-kmp.dir` 时,Gradle 把 `<dir>/library/build/native/host-tools/bin/qjsc-kmp` 传给 CLI,零配置 |
| CI(本期) | clone quickjs-kmp 的 catalog 对应 tag,`./gradlew :library:buildHostTools` 现编,多花一两分钟 |
| 长期 | quickjs-kmp 在 tag 发布时把 macOS / Linux 宿主二进制挂到 GitHub Release,CLI 按版本下载(esbuild 的平台包模式);属 quickjs-kmp 仓改动,记 roadmap |
| 默认 | npm 包 `qjsc-kmp`:入口包加 `@qjsc-kmp/{darwin-arm64,darwin-x64,linux-x64,linux-arm64}` 平台包(esbuild 模式,Linux 为 musl 全静态),npm 只装与本机匹配的那个;由 quickjs-kmp 随 tag 经 OIDC 发布 |
| 本地联调 | `local.properties` 有 `quickjs-kmp.dir` 时,Gradle 把 `<dir>/library/build/native/host-tools/bin/qjsc-kmp` 经 `--qjsc` 传给 CLI,用的是本地源码编出的那份 |
| 其他平台 | Windows 等没有预编译版的平台用 `--qjsc` / `TINYUI_QJSC` 指向自己编的那份 |

## 6. 各处职责

| 位置 | 改动 |
|---|---|
| `packages/cli` | `bin` 入口 `tinyui`,子命令 `build`,读工程根 `tinyui.config.json`(包名、公钥、页面目录),参数 `--root` / `--out` / `--qjsc`;依赖 esbuild。测试:夹具 TSX 打包后断言 `h(` 调用、裸说明符保留、相对 import 已合并、`.map` 存在;qjsc 步骤在 `TINYUI_QJSC` 缺失时跳过 |
| `packages/cli` | `bin` 入口 `tinyui`,子命令 `build`,读工程根 `tinyui.config.json`(包名、公钥、页面目录),参数 `--root` / `--out` / `--qjsc`;依赖 esbuild。测试:夹具 TSX 打包后断言 `h(` 调用、裸说明符保留、相对 import 已合并、`.map` 存在;qjsc 步骤在找不到 `qjsc-kmp` 时跳过 |
| `packages/core` / `native` | 不动运行时 API,只保证入口能打成单模块,各导出 `VERSION` 供 sample 显示 |
| `compose/` | ADR-002 K0 最小版:注册 core → 注册 native → 运行页面模块 → 返回 namespace。命名待 M1 定,本期只保证序列在库里而不在 sample 里。commonTest 用 `JsBytecode.compile` 现场编字节码,不依赖宿主工具 |
| `sample/js` | 新 pnpm workspace 成员,包名 `sample`,`src/pages/home.tsx`。本期页面用纯 TS 只 import `VERSION`:`h` 的签名是 C 组的事,不在 core 放临时实现;JSX 变换的正确性由 CLI 单元测试覆盖 |
| `sample/shared` | Gradle:`pnpm run build` → `tinyui build` → `Sync` 只取 `.bin` 与清单 → `compose.resources.customDirectory`,`Res.readBytes("files/tinyui/…")` 读入后走 K0。AGP 9 的 KMP 库插件默认不处理 assets,Compose resources 在 Android 走 assets,必须 `androidResources { enable = true }`,否则 APK 里没有资源且构建不报错(2026-09-16 实测) |
| `settings.gradle.kts` | 有 `quickjs-kmp.dir` 时把 `qjsc-kmp` 路径传给 Exec 任务 |
| CI | gradle job 加 setup-node + pnpm,clone quickjs-kmp 的 catalog 版本 tag 编 `buildHostTools`(qjsc-kmp)与 `buildNativeHostJni`(Android host 测试要加载宿主 JNI 库,Maven 包里没有),经 `TINYUI_QJSC` / `TINYUI_QUICKJS_HOST_JNI` 传入;ios.yml 同样 |
| CI | gradle job 加 setup-node + pnpm,clone quickjs-kmp 的 catalog 版本 tag 编 `buildNativeHostJni`(Android host 测试要加载宿主 JNI 库,Maven 包里没有),经 `TINYUI_QUICKJS_HOST_JNI` 传入;`qjsc-kmp` 来自 npm 包(2026-09-23 起);ios.yml 同样 |

## 7. 错误上报与 source map

Expand Down
2 changes: 1 addition & 1 deletion docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
|---|---|---|
| ~~`createStore`(Solid 式 Proxy 深层响应式)~~ | ADR-005 | 已完成(2026-09-17,定名 `observable`,[runtime-api.md](./runtime-api.md) §2.6):直接赋值、属性级订阅、只深代理纯对象与数组;`reconcile` / `produce` 不做,触发条件"服务端全量刷新导致整表重绑成为性能问题" |
| ~~热下发~~ | ADR-005 | 已定(2026-09-18,[ADR-006](./adr-006-hot-updates.md) + [updates.md](./updates.md);2026-09-19 定服务端与签名、改多包模型),实现待开,顺序见下方第 7 条;ADR-006 §4.3 的推迟项(控制台、遥测、D1、非 CF 适配器、计费)各带触发条件 |
| `qjsc-kmp` 宿主二进制分发 | build-chain.md §5 | **触发已到**(2026-09-19,第二个 App 接入,其 CI 不能现编 quickjs-kmp):形态改为 npm 平台包(`qjsc-kmp-darwin-arm64` / `-linux-x64` 等作 `tinyui-cli` 的 `optionalDependencies`,esbuild 模式)而非 GitHub Release——内网 npm 代理天然能拉;属 quickjs-kmp 仓改动,待做 |
| `qjsc-kmp` 宿主二进制分发 | build-chain.md §5 | **已完成**(2026-09-23,热下发 M5.2):npm 入口包 `qjsc-kmp` 加 `@qjsc-kmp/<os>-<arch>` 平台包(esbuild 模式)而非 GitHub Release——内网 npm 代理天然能拉;quickjs-kmp 0.1.2 起随 tag 发布,`tinyui-cli` 依赖它 |
| ~~App 级共享模块(业务共享代码进 external 列表与模块表)~~ | build-chain.md §3 | 砍掉(2026-09-19):多包模型下包自包含,体积问题的出口是拆包(ADR-006 §2.10) |
| 向 bellard/mquickjs 上报 S4 段错误 | ADR-005 §3.2 | 用户决定 |
| `ErrorBoundary` 分支级兜底 | ADR-002 | 整页失败的比例成为问题 |
Expand Down
4 changes: 2 additions & 2 deletions docs/updates-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,6 @@ M1 之后 M2 → M3 与 M4 并行;M5.1、M5.2 与 tinyui 0.3.0(npm 三包 +
| M4 服务 MVP | 已完成(tiny-ui/tinyui-updates-server PR #1,2026-09-22):Hono + 单 R2 桶,投递 / 发布 / release / 管理四组端点,Workers 运行时一致性测试 12 条;已部署 `updates.tinyui.app`(R2 桶 `tinyui-updates`,`ADMIN_TOKEN` 存 HarlonWang/secrets 的 `tinyui-updates/admin-token.txt`),Cloudflare Workers Builds 已连 tiny-ui/tinyui-updates-server 的 main,push 即部署(`wrangler deploy --config wrangler.tinyui.toml`) |
| M5 CLI 发布与管理 | 已完成(2026-09-22):`publish`(发现 bundle 目录、并发上传、指针最后)、`apps` / `packages`(含 `rotate-key`)/ `tokens` / `releases` 四组命令;凭据只走环境变量,`--app` / `--channel` / `--pkg` 按名字规则校验;CLI 侧契约测试 15 条,另对本地 `wrangler dev` 起的真服务端跑通发布 / 幂等重发 / 晋级 / 改灰度 / 回滚 / 跨 channel 被拒 / 吊销即时生效 |
| M5.1 改名 `hostVersion` | 已完成(2026-09-23,tinyui PR #17、tinyui-updates-server PR #2,服务端已部署):manifest 字段、Kotlin API、CLI `--host-version`、服务端路由与校验、文档全部改名;CLI、`Updates` 构造、服务端路径与 manifest 五处限定正整数;共用签名夹具换钥重签,Android host 与 iOS 模拟器两端验签通过 |
| M5.2 `qjsc-kmp` 平台包 | 待开;之后发 tinyui 0.3.0 |
| M6 TrendingAI 接入 | 拍板完成(2026-09-23),待 M5.1、M5.2、0.3.0 |
| M5.2 `qjsc-kmp` 平台包 | 已完成(2026-09-23,quickjs-kmp PR #13 与 0.1.2、tinyui PR #18):入口包 `qjsc-kmp` + `@qjsc-kmp/{darwin-arm64,darwin-x64,linux-x64,linux-arm64}`,Linux 为 musl 全静态;首版本地发布,之后随 quickjs-kmp 的 tag 经 OIDC 发布;`tinyui-cli` 依赖它并由测试钉住与 `quickjsKmp` 同版本,CI 不再现编 `qjsc-kmp` |
| M6 TrendingAI 接入 | 拍板完成(2026-09-23),待发 tinyui 0.3.0 |
| M7 第二个 App | 待开 |
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ android-targetSdk = "37"
androidxActivityCompose = "1.13.0"
kotlinxCoroutines = "1.11.0"
kotlinxSerialization = "1.11.0"
quickjsKmp = "0.1.1"
quickjsKmp = "0.1.2"
vanniktechMavenPublish = "0.37.0"
binaryCompatibilityValidator = "0.18.2"
okio = "3.18.2"
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

`tinyui publish` 把 `bundle` 的产物传到热下发服务并切换 channel 指针,`tinyui apps` / `packages` / `tokens` / `releases` 是这套服务的管理面(建 app、登记包的验签公钥、签发与吊销发布 token、列 release 与回滚 / 晋级 / 改灰度)。实例地址取 `--url`、`$TINYUI_UPDATES_URL`、`https://updates.tinyui.app` 三者之一;凭据只从环境变量读,不接受命令行参数:`$TINYUI_TOKEN` 是发布 token,`$TINYUI_ADMIN_TOKEN` 是实例管理 token。`--app` 可用 `$TINYUI_APP` 代替,`--pkg` 缺省取当前目录 `tinyui.config.json` 的 `name`,`--channel` 必须每次显式写。

字节码编译需要 quickjs-kmp 的宿主工具 `qjsc-kmp`(`--qjsc` 或 `TINYUI_QJSC`)。用法见仓库 `docs/build-chain.md` 与 `docs/updates.md`;与 `tinyui-core` 同版本号。
字节码编译用 quickjs-kmp 的宿主工具 `qjsc-kmp`:依赖里的 npm 包 `qjsc-kmp` 带 macOS 与 Linux 的预编译版,装完即用;其他平台用 `--qjsc` 或 `TINYUI_QJSC` 指向自己编的那份。`qjsc-kmp` 的版本钉在与 tinyui 所用 quickjs-kmp 相同的版本上,编出的字节码才认 App 里的引擎。用法见仓库 `docs/build-chain.md` 与 `docs/updates.md`;与 `tinyui-core` 同版本号。
3 changes: 2 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"dependencies": {
"esbuild": "0.28.2",
"magic-string": "1.4.1",
"oxc-parser": "0.150.0"
"oxc-parser": "0.150.0",
"qjsc-kmp": "0.1.2"
Comment thread
HarlonWang marked this conversation as resolved.
},
"devDependencies": {
"tinyui-core": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const USAGE = `usage: tinyui build [--root <dir>] [--out <dir>] [--qjsc <path>]
build compile the pages of the package described by <root>/tinyui.config.json
--root project root (default: cwd)
--out output directory (default: <root>/dist)
--qjsc path to qjsc-kmp (default: $TINYUI_QJSC, then PATH)
--qjsc path to qjsc-kmp (default: $TINYUI_QJSC, then the qjsc-kmp npm package, then PATH)
--js-only emit ESM sources and source maps only, skip bytecode
--version package version to record (default: <createdAt>-<git sha>)

Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface BuildOptions {
root: string;
/** Output directory; defaults to `<root>/dist`. */
out?: string;
/** Path to `qjsc-kmp`; falls back to `TINYUI_QJSC` and then `PATH`. */
/** Path to `qjsc-kmp`; falls back to `TINYUI_QJSC`, the `qjsc-kmp` npm package, then `PATH`. */
qjsc?: string;
/** Emit only the ESM sources and skip bytecode; for debugging the transform without an engine build. */
jsOnly?: boolean;
Expand Down Expand Up @@ -74,7 +74,7 @@ export async function build(options: BuildOptions): Promise<BuildResult> {

const qjsc = options.jsOnly ? undefined : await findQjsc(options.qjsc);
if (!options.jsOnly && !qjsc) {
throw new Error("qjsc-kmp not found: pass --qjsc, set TINYUI_QJSC, or put it on PATH (or use --js-only)");
throw new Error("qjsc-kmp not found: the qjsc-kmp npm package has no binary for this machine or was installed without optional dependencies; pass --qjsc, set TINYUI_QJSC, or put it on PATH (or use --js-only)");
}

// stale outputs would otherwise be packaged along with the current pages
Expand Down
18 changes: 17 additions & 1 deletion packages/cli/src/qjsc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,35 @@ const execFileAsync = promisify(execFile);

const EXECUTABLE = process.platform === "win32" ? "qjsc-kmp.exe" : "qjsc-kmp";

/** Locates the quickjs-kmp host compiler: explicit path, then `TINYUI_QJSC`, then `PATH`. */
/**
* Locates the quickjs-kmp host compiler: explicit path, then `TINYUI_QJSC`, then the prebuilt binary of the
* `qjsc-kmp` npm package, then `PATH`.
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
*/
export async function findQjsc(explicit?: string): Promise<string | undefined> {
const candidates = [explicit, process.env["TINYUI_QJSC"]].filter((p): p is string => !!p);
for (const p of candidates) {
if (await isExecutable(p)) return p;
throw new Error(`qjsc-kmp not found at ${p}`);
}
const prebuilt = await prebuiltQjsc();
if (prebuilt) return prebuilt;
for (const dir of (process.env["PATH"] ?? "").split(delimiter)) {
if (dir && (await isExecutable(join(dir, EXECUTABLE)))) return join(dir, EXECUTABLE);
}
return undefined;
}

/** The binary `qjsc-kmp` installed for this machine; none on a platform it has no build for, or with optional dependencies omitted. */
async function prebuiltQjsc(): Promise<string | undefined> {
try {
const { binaryPath } = await import("qjsc-kmp");
const path = binaryPath();
return (await isExecutable(path)) ? path : undefined;
} catch {
return undefined;
}
}

export interface CompileOptions {
qjsc: string;
input: string;
Expand Down
Loading
Loading