@opentf/web-compiler 0.1.0

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/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # @opentf/web-compiler
2
+
3
+ Prebuilt binaries for **otfwc**, the OTF Web IR compiler (a Rust binary). You
4
+ normally don't install this directly — `@opentf/web-cli` depends on it.
5
+
6
+ ```js
7
+ import { otfwcPath } from "@opentf/web-compiler";
8
+ const bin = otfwcPath(); // absolute path to the otfwc executable for this platform
9
+ ```
10
+
11
+ ## How it works
12
+
13
+ This single package ships the `otfwc` binary for every supported platform,
14
+ **brotli-compressed**, under `bin/<platform>-<arch>/otfwc[.exe].br` (~0.65 MB each
15
+ vs ~2.3 MB raw). On install a `postinstall` script decompresses **only the host's**
16
+ binary; `otfwcPath()` also decompresses lazily as a fallback (e.g. under
17
+ `--ignore-scripts`) and returns the path matching the host
18
+ (`process.platform-process.arch`).
19
+
20
+ Shipping all platforms in one package is cheaper to maintain than the per-platform
21
+ optionalDependencies fan-out that rolldown/swc/esbuild use (their binaries are far
22
+ larger). `OTFWC_BIN` overrides everything (used in this repo's own dev to point at
23
+ the cargo `target/` build).
24
+
25
+ ## Releasing (CI)
26
+
27
+ `bin/` is empty in git, and the package is `private: true` only as a guard so the
28
+ monorepo `changeset publish` doesn't ship it binary-less. It is published by its
29
+ own workflow, `.github/workflows/release-compiler.yml` (run manually after a
30
+ release): that cross-builds otfwc for each target, brotli-compresses each into
31
+ `bin/<platform>/`, flips `private` off, and publishes — so the package on npm is
32
+ public. Versioning is owned entirely by changesets — there is no version-sync
33
+ script.
Binary file
Binary file
Binary file
Binary file
Binary file
package/extract.js ADDED
@@ -0,0 +1,73 @@
1
+ //! Decompress the host's otfwc binary from its shipped brotli archive.
2
+ //
3
+ // The package ships one brotli-compressed binary per platform under
4
+ // `bin/<platform>-<arch>/otfwc[.exe].br` (~0.65MB each vs ~2.3MB raw). On install
5
+ // the postinstall script decompresses only the host's; `otfwcPath()` also does it
6
+ // lazily as a fallback (e.g. when scripts are skipped with --ignore-scripts).
7
+
8
+ import { existsSync, readFileSync, writeFileSync, chmodSync } from "node:fs";
9
+ import { brotliDecompressSync } from "node:zlib";
10
+ import { dirname, join } from "node:path";
11
+ import { fileURLToPath } from "node:url";
12
+
13
+ const here = dirname(fileURLToPath(import.meta.url));
14
+
15
+ // `process.platform-process.arch` maps directly onto our bin/ subdirectory names.
16
+ const SUPPORTED = new Set([
17
+ "linux-x64",
18
+ "linux-arm64",
19
+ "darwin-x64",
20
+ "darwin-arm64",
21
+ "win32-x64",
22
+ ]);
23
+
24
+ function hostBinPath() {
25
+ const key = `${process.platform}-${process.arch}`;
26
+ if (!SUPPORTED.has(key)) return null;
27
+ const bin = process.platform === "win32" ? "otfwc.exe" : "otfwc";
28
+ return join(here, "bin", key, bin);
29
+ }
30
+
31
+ /** Decompress the host's `.br` archive to a runnable binary; returns its path. */
32
+ function decompress(out) {
33
+ const archive = `${out}.br`;
34
+ writeFileSync(out, brotliDecompressSync(readFileSync(archive)));
35
+ if (process.platform !== "win32") chmodSync(out, 0o755);
36
+ return out;
37
+ }
38
+
39
+ /**
40
+ * Best-effort: decompress the host binary if the archive is present. No-op (returns
41
+ * null) on an unsupported platform or a source checkout without the `.br`. Used by
42
+ * the postinstall script — never throws, so it can't break `npm install`.
43
+ */
44
+ export function extractIfPackaged() {
45
+ const out = hostBinPath();
46
+ if (!out || existsSync(out) || !existsSync(`${out}.br`)) return null;
47
+ try {
48
+ return decompress(out);
49
+ } catch {
50
+ return null; // lazy fallback in otfwcPath() will retry / surface the error
51
+ }
52
+ }
53
+
54
+ /** Absolute path to the otfwc executable, or throw with a clear message. */
55
+ export function otfwcPath() {
56
+ if (process.env.OTFWC_BIN) {
57
+ if (existsSync(process.env.OTFWC_BIN)) return process.env.OTFWC_BIN;
58
+ throw new Error(`otfwc: OTFWC_BIN is set but ${process.env.OTFWC_BIN} does not exist`);
59
+ }
60
+ const out = hostBinPath();
61
+ if (!out) {
62
+ throw new Error(
63
+ `otfwc: no prebuilt binary for ${process.platform}-${process.arch}. ` +
64
+ `Supported: ${[...SUPPORTED].join(", ")}. Build from source and set OTFWC_BIN.`,
65
+ );
66
+ }
67
+ if (existsSync(out)) return out;
68
+ if (existsSync(`${out}.br`)) return decompress(out);
69
+ throw new Error(
70
+ `otfwc: prebuilt binary missing at ${out}. ` +
71
+ `Reinstall @opentf/web-compiler, or set OTFWC_BIN.`,
72
+ );
73
+ }
package/index.js ADDED
@@ -0,0 +1,10 @@
1
+ //! Resolve the `otfwc` compiler binary for the current platform.
2
+ //
3
+ // otfwc is a Rust binary. It ships brotli-compressed for every supported platform
4
+ // inside this single package under `bin/<platform>-<arch>/otfwc[.exe].br`; the
5
+ // host's copy is decompressed on install (and lazily here as a fallback). The
6
+ // toolchain (`@opentf/web-cli`) calls `otfwcPath()` to get the executable path.
7
+ // `OTFWC_BIN` overrides everything (used in this repo's own dev to point at the
8
+ // cargo build). See extract.js for the decompression logic.
9
+
10
+ export { otfwcPath } from "./extract.js";
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@opentf/web-compiler",
3
+ "version": "0.1.0",
4
+ "description": "OTF Web IR compiler (otfwc) — prebuilt platform binaries + host resolver (ARCHITECTURE.md §8).",
5
+ "type": "module",
6
+ "main": "index.js",
7
+ "exports": {
8
+ ".": "./index.js"
9
+ },
10
+ "scripts": {
11
+ "postinstall": "node scripts/postinstall.js"
12
+ },
13
+ "files": [
14
+ "index.js",
15
+ "extract.js",
16
+ "scripts",
17
+ "bin"
18
+ ],
19
+ "keywords": [
20
+ "opentf",
21
+ "compiler",
22
+ "jsx",
23
+ "web-components",
24
+ "ssg"
25
+ ],
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/Open-Tech-Foundation/Web-App-Framework.git",
29
+ "directory": "packages/web-compiler"
30
+ },
31
+ "homepage": "https://github.com/Open-Tech-Foundation/Web-App-Framework#readme",
32
+ "bugs": "https://github.com/Open-Tech-Foundation/Web-App-Framework/issues",
33
+ "license": "MIT",
34
+ "publishConfig": {
35
+ "access": "public"
36
+ }
37
+ }
@@ -0,0 +1,7 @@
1
+ //! Decompress the host's otfwc binary after install. Best-effort: a no-op on a
2
+ //! source checkout (no `.br` present) and never throws, so it can't break install.
3
+ //! `otfwcPath()` decompresses lazily anyway if this is skipped (--ignore-scripts).
4
+
5
+ import { extractIfPackaged } from "../extract.js";
6
+
7
+ extractIfPackaged();