// Shared scaffolding for the lightweight composition servers used by `play` and // `present`: locating the built runtime/player/slideshow bundles, serving // composition asset files, and binding to a free port. import { createReadStream, existsSync, statSync } from "node:fs"; import { resolve, dirname } from "node:path"; import { Readable } from "node:stream"; import { fileURLToPath } from "node:url"; import { getMimeType } from "@hyperframes/studio-server"; /** * `window.__HF_MEDIA_CODEC_MAP__` injection + proxy pre-warm for HTML served * by `play` and the static project server. Re-exported from the * single shared implementation in * `packages/studio-server/src/helpers/mediaProxyPreview.ts` (also used by the * studio preview route) so injection behavior cannot drift between surfaces. */ export { injectMediaCodecMapIntoHtml as injectMediaCodecMap } from "@hyperframes/studio-server/media-proxy-preview"; /** Minimal surface of a listening server (satisfied by @hono/node-server's ServerType). */ interface PortBindable { listen(port: number): unknown; once(event: "listening" | "error", listener: (err?: NodeJS.ErrnoException) => void): unknown; removeListener( event: "listening" | "error", listener: (err?: NodeJS.ErrnoException) => void, ): unknown; } function helperDir(): string { // fileURLToPath (not URL.pathname) so the Windows "/D:/..." leading-slash form // doesn't break the bundle-path resolution below. return dirname(fileURLToPath(import.meta.url)); } export function resolveRuntimePath(): string | null { const d = helperDir(); const candidates = [ resolve(d, "hyperframe-runtime.js"), resolve(d, "..", "hyperframe-runtime.js"), // Monorepo dev: src/