Skip to content
Closed
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
6 changes: 6 additions & 0 deletions packages/core/package-subpaths.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@
"types": "./dist/audioFx.d.ts",
"environments": ["browser", "bun", "node"]
},
"./audio-fx-copy": {
"source": "./src/audioFxCopy.ts",
"runtime": "./dist/audioFxCopy.js",
"types": "./dist/audioFxCopy.d.ts",
"environments": ["browser", "bun", "node"]
},
"./audio-fx-eq": {
"source": "./src/audioFxEq.ts",
"runtime": "./dist/audioFxEq.js",
Expand Down
10 changes: 10 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@
"import": "./src/audioFx.ts",
"types": "./src/audioFx.ts"
},
"./audio-fx-copy": {
"bun": "./src/audioFxCopy.ts",
"node": "./dist/audioFxCopy.js",
"import": "./src/audioFxCopy.ts",
"types": "./src/audioFxCopy.ts"
},
"./audio-fx-eq": {
"bun": "./src/audioFxEq.ts",
"node": "./dist/audioFxEq.js",
Expand Down Expand Up @@ -410,6 +416,10 @@
"import": "./dist/audioFx.js",
"types": "./dist/audioFx.d.ts"
},
"./audio-fx-copy": {
"import": "./dist/audioFxCopy.js",
"types": "./dist/audioFxCopy.d.ts"
},
"./audio-fx-eq": {
"import": "./dist/audioFxEq.js",
"types": "./dist/audioFxEq.d.ts"
Expand Down
57 changes: 10 additions & 47 deletions packages/core/scripts/build-audio-fx-runtime.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,13 @@
/** Build the injectable audio-FX runtime artifact from the canonical runtime. */

import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { buildSync } from "esbuild";
import { execFileSync } from "node:child_process";

const thisDir = dirname(fileURLToPath(import.meta.url));
const repoRoot = resolve(thisDir, "..");
const entry = resolve(repoRoot, "stubs/audio-fx-runtime-entry.ts");
const generatedDir = resolve(repoRoot, "src/generated");
const outPath = resolve(generatedDir, "audio-fx-runtime-inline.ts");

const result = buildSync({
entryPoints: [entry],
bundle: true,
write: false,
platform: "browser",
format: "iife",
target: ["es2020"],
minify: true,
legalComments: "none",
import { buildInjectedArtifact } from "./buildInjectedArtifact.js";

buildInjectedArtifact({
scriptUrl: import.meta.url,
entry: "stubs/audio-fx-runtime-entry.ts",
out: "audio-fx-runtime-inline.ts",
constName: "AUDIO_FX_RUNTIME_IIFE",
fnName: "getAudioFxRuntimeScript",
what: "audio-FX runtime IIFE",
event: "audio_fx_runtime_generated",
});
const iife = result.outputFiles[0]?.text ?? "";
if (!iife) throw new Error("esbuild produced no output for audio-fx-runtime-entry.ts");

mkdirSync(generatedDir, { recursive: true });
writeFileSync(
outPath,
[
"// AUTO-GENERATED by scripts/build-audio-fx-runtime.ts - do not edit",
`const AUDIO_FX_RUNTIME_IIFE: string = ${JSON.stringify(iife)};`,
"",
"/** Returns the pre-built audio-FX runtime IIFE as a string constant. */",
"export function getAudioFxRuntimeScript(): string {",
" return AUDIO_FX_RUNTIME_IIFE;",
"}",
"",
].join("\n"),
"utf8",
);

try {
execFileSync("bun", ["x", "oxfmt", outPath], { stdio: "ignore" });
} catch {
// Formatting is best effort when the generator runs in a minimal environment.
}

console.log(JSON.stringify({ event: "audio_fx_runtime_generated", outPath, bytes: iife.length }));
59 changes: 10 additions & 49 deletions packages/core/scripts/build-position-edits-render.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,13 @@
/** Build the injectable position-edits render artifact from the canonical runtime. */

import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { buildSync } from "esbuild";
import { execFileSync } from "node:child_process";

const thisDir = dirname(fileURLToPath(import.meta.url));
const repoRoot = resolve(thisDir, "..");
const entry = resolve(repoRoot, "stubs/position-edits-render-entry.ts");
const generatedDir = resolve(repoRoot, "src/generated");
const outPath = resolve(generatedDir, "position-edits-render-inline.ts");

const result = buildSync({
entryPoints: [entry],
bundle: true,
write: false,
platform: "browser",
format: "iife",
target: ["es2020"],
minify: true,
legalComments: "none",
import { buildInjectedArtifact } from "./buildInjectedArtifact.js";

buildInjectedArtifact({
scriptUrl: import.meta.url,
entry: "stubs/position-edits-render-entry.ts",
out: "position-edits-render-inline.ts",
constName: "POSITION_EDITS_RENDER_IIFE",
fnName: "getPositionEditsRenderScript",
what: "position-edits render IIFE",
event: "position_edits_render_generated",
});
const iife = result.outputFiles[0]?.text ?? "";
if (!iife) throw new Error("esbuild produced no output for position-edits-render-entry.ts");

mkdirSync(generatedDir, { recursive: true });
writeFileSync(
outPath,
[
"// AUTO-GENERATED by scripts/build-position-edits-render.ts - do not edit",
`const POSITION_EDITS_RENDER_IIFE: string = ${JSON.stringify(iife)};`,
"",
"/** Returns the pre-built position-edits render IIFE as a string constant. */",
"export function getPositionEditsRenderScript(): string {",
" return POSITION_EDITS_RENDER_IIFE;",
"}",
"",
].join("\n"),
"utf8",
);

try {
execFileSync("bun", ["x", "oxfmt", outPath], { stdio: "ignore" });
} catch {
// Formatting is best effort when the generator runs in a minimal environment.
}

console.log(
JSON.stringify({ event: "position_edits_render_generated", outPath, bytes: iife.length }),
);
78 changes: 78 additions & 0 deletions packages/core/scripts/buildInjectedArtifact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Bundle a stub entry into an injectable IIFE, wrapped as a TypeScript constant.
*
* Two artifacts are built this way — the audio-FX runtime and the position-edits
* render — and the engine injects both into the headless browser as a script tag.
* They were two copies of this file differing in five names, which is a poor
* place for a divergence to hide: whichever copy stopped being edited would go on
* producing a subtly different artifact with nothing to say so.
*/

import { execFileSync } from "node:child_process";
import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { buildSync } from "esbuild";

export interface InjectedArtifact {
/** The build script's own `import.meta.url`, so paths resolve beside it. */
scriptUrl: string;
/** Entry stub, relative to the package root. */
entry: string;
/** Output file name inside `src/generated`. */
out: string;
/** SCREAMING_CASE name for the string constant holding the IIFE. */
constName: string;
/** The accessor the rest of the codebase imports. */
fnName: string;
/** What that accessor returns, for its doc comment: "the pre-built X". */
what: string;
/** Structured log event name. */
event: string;
}

export function buildInjectedArtifact(spec: InjectedArtifact): void {
const scriptDir = dirname(fileURLToPath(spec.scriptUrl));
const scriptName = spec.scriptUrl.split("/").pop() ?? "";
const repoRoot = resolve(scriptDir, "..");
const entry = resolve(repoRoot, spec.entry);
const generatedDir = resolve(repoRoot, "src/generated");
const outPath = resolve(generatedDir, spec.out);

const result = buildSync({
entryPoints: [entry],
bundle: true,
write: false,
platform: "browser",
format: "iife",
target: ["es2020"],
minify: true,
legalComments: "none",
});
const iife = result.outputFiles[0]?.text ?? "";
if (!iife) throw new Error(`esbuild produced no output for ${spec.entry.split("/").pop()}`);

mkdirSync(generatedDir, { recursive: true });
writeFileSync(
outPath,
[
`// AUTO-GENERATED by scripts/${scriptName} - do not edit`,
`const ${spec.constName}: string = ${JSON.stringify(iife)};`,
"",
`/** Returns the pre-built ${spec.what} as a string constant. */`,
`export function ${spec.fnName}(): string {`,
` return ${spec.constName};`,
"}",
"",
].join("\n"),
"utf8",
);

try {
execFileSync("bun", ["x", "oxfmt", outPath], { stdio: "ignore" });
} catch {
// Formatting is best effort when the generator runs in a minimal environment.
}

console.log(JSON.stringify({ event: spec.event, outPath, bytes: iife.length }));
}
Loading
Loading