/** * FileSystemHologramStore — Node-only filesystem implementation of * HologramStore. Used by the studio service (mounted on `/data/hologram` * via Railway volume `studio-data`) and by the hologram-worker service. * * NOT EXPORTED from `@holoscript/engine` or `@holoscript/engine/hologram` * barrels — this file imports `node:fs` and `node:path` at the top level * and would break browser bundles. Consumers that need the fs impl * import it by direct path: * * import { FileSystemHologramStore } from * '@holoscript/engine/hologram/FileSystemHologramStore'; * * SECURITY (Sprint 0b.1, team mode SECURITY): * - Paths are NEVER built from raw input. All hash/asset inputs pass * through assertValidHash / assertValidAssetName before touching fs. * - Writes are atomic: write to `.tmp..`, then `rename`. * A crash mid-write never leaves a readable partial bundle. * - MaxBundleBytes guards total-bundle size at write time so a * runaway depth map can't fill the volume. * - The store does NOT fall back to any "close-enough" hash match; * a bundle's path is a PURE function of its recomputed hash. */ import type { HologramBundle, HologramMeta } from './HologramBundle'; import { type AssetName, type HologramStore, type HologramStorePutResult } from './HologramStore'; export interface FileSystemHologramStoreOptions { /** * Absolute filesystem root. All bundle dirs live under this path. * In production: `/data/hologram` (on the `studio-data` Railway * volume mounted at `/data`). In dev/test: a tmp dir. */ rootDir: string; /** * Upper bound on total bundle size in bytes (sum of depth+normal+ * rendered outputs + meta). Default: 256 MB. A well-formed 1080p * single-frame bundle is ~20 MB; a 30-frame 1080p GIF is ~150 MB. */ maxBundleBytes?: number; } export declare class FileSystemHologramStore implements HologramStore { private readonly rootDir; private readonly maxBundleBytes; constructor(opts: FileSystemHologramStoreOptions); /** * Resolve a relative path against rootDir and assert it stays under it. * This is defense-in-depth: even though callers ONLY build relative * paths from validated hashes via bundleRelDir / bundleAssetRelPath, * re-verifying post-join catches any future refactor that mistakenly * allows a `..` segment to slip through. */ private resolveUnderRoot; put(bundle: HologramBundle): Promise; has(hash: string): Promise; getAsset(hash: string, asset: AssetName): Promise; getMeta(hash: string): Promise; /** * Write bytes atomically. Creates a sibling `.tmp..` file, * flushes to disk, then renames over the final path. On Unix rename * is atomic within a filesystem; on Windows it's effectively atomic * for the observable reader contract. */ private writeAtomic; /** Expose root for tests and diagnostics. Never used to build paths. */ getRootDir(): string; } //# sourceMappingURL=FileSystemHologramStore.d.ts.map