t3-code-android-nightly/apps/mobile/scripts/generate-device-stream.mts

43 lines
1.7 KiB
TypeScript

import * as NodeFSP from "node:fs/promises";
import * as NodePath from "node:path";
import * as NodeURL from "node:url";
import { build } from "vite-plus";
const mobileRoot = NodePath.resolve(NodePath.dirname(NodeURL.fileURLToPath(import.meta.url)), "..");
/** Metro embeds each shared browser transport as a small script in a native WebView. */
async function generateWebViewScript(feature: string, name: string) {
const stem = `${name.toLowerCase()}-stream`;
const result = await build({
configFile: false,
logLevel: "silent",
build: {
write: false,
target: "es2022",
minify: true,
lib: {
entry: NodePath.join(mobileRoot, "src/features", feature, `${stem}.browser.ts`),
name: `T3${name}Stream`,
formats: ["iife"],
},
},
});
const bundles = Array.isArray(result) ? result : [result];
const chunk = bundles
.flatMap((bundle) => ("output" in bundle ? bundle.output : []))
.find((output) => output.type === "chunk");
if (!chunk) throw new Error(`${name} build did not emit a script.`);
const root = NodePath.join(mobileRoot, ".generated", stem);
await NodeFSP.mkdir(root, { recursive: true });
for (const [file, contents] of [
["index.js", `module.exports = ${JSON.stringify(chunk.code)};\n`],
["package.json", '{"main":"index.js"}\n'],
] as const) {
const destination = NodePath.join(root, file);
const previous = await NodeFSP.readFile(destination, "utf8").catch(() => null);
if (previous !== contents) await NodeFSP.writeFile(destination, contents);
}
}
export const generateDeviceStreamScript = () => generateWebViewScript("devices", "Device");
export const generatePreviewStreamScript = () => generateWebViewScript("browser", "Preview");