39 lines
1.6 KiB
TypeScript
39 lines
1.6 KiB
TypeScript
/**
|
|
* `emit` pass — IR → manifest JSON.
|
|
*
|
|
* In this architecture slice the `VideoTimeline` IR *is* the manifest: emitting
|
|
* is stamping the schema/version envelope and validating the result against
|
|
* {@link VideoTimelineSchema}, so a malformed IR fails loudly here rather than
|
|
* downstream in the (future) Hyperframes emitter. The returned object is plain,
|
|
* JSON-serializable data — the export report and the render input in one.
|
|
*
|
|
* (The composition HTML / GSAP emitter is the next phase, P1d; this pass stops
|
|
* at the manifest, as the issue scopes it.)
|
|
*
|
|
* Pure: validation only, no IO.
|
|
*/
|
|
import { type VideoTimeline, VideoTimelineSchema } from '../ir';
|
|
import { RuntimeDiagnosticSchema } from '../runtime-diagnostics';
|
|
|
|
export const VideoExportManifestSchema = VideoTimelineSchema.extend({
|
|
runtimeDiagnostics: RuntimeDiagnosticSchema.array(),
|
|
});
|
|
export type VideoExportManifest = ReturnType<typeof VideoExportManifestSchema.parse>;
|
|
|
|
/**
|
|
* Validate and return the IR as a manifest object. Throws (via zod) if the IR
|
|
* does not satisfy {@link VideoTimelineSchema} — a compiler bug, since the IR is
|
|
* assembled internally, so failing loud is correct.
|
|
*/
|
|
export function emitManifest(ir: VideoTimeline): VideoExportManifest {
|
|
return VideoExportManifestSchema.parse({
|
|
...VideoTimelineSchema.parse(ir),
|
|
runtimeDiagnostics: [],
|
|
});
|
|
}
|
|
|
|
/** Serialize the manifest to a JSON string (pretty-printed by default). */
|
|
export function emitManifestJson(ir: VideoTimeline, space: number = 2): string {
|
|
return JSON.stringify(emitManifest(ir), null, space);
|
|
}
|