import { expect, it } from "vitest"; import { registerToolcraftRendererPipeline, type ToolcraftRendererPipelinePassContract, } from "./renderer-pipeline-registration"; import { createToolcraftRendererPipelineRuntime } from "./renderer-pipeline-runtime"; import { createToolcraftRendererPipelineRuntimeOwner } from "./renderer-pipeline-runtime-owner"; type Resource = Readonly<{ id: string }>; const registration = registerToolcraftRendererPipeline<{ decode: ToolcraftRendererPipelinePassContract< string, Resource, readonly [resourceId: string] >; export: ToolcraftRendererPipelinePassContract; }>()({ interactionInvalidation: [], passes: [ { cacheKey: ["source.asset", "effect.amount"], id: "decode", inputs: ["source.asset"], invalidatedBy: ["source.asset", "effect.amount"], kind: "decode", lifecycle: { cache: "retained-resource", resourceScope: "renderer" }, output: "source", quality: "full", runsOn: "worker", }, { id: "export", inputs: ["source.asset"], invalidatedBy: ["source.asset"], kind: "export", lifecycle: { cache: "none", resourceScope: "call" }, output: "export", quality: "export", runsOn: "export-only", }, ], runtimeId: "runtime-types-test-v1", }); it("keeps result, cache input, and resource types fixed by each pass handle", () => { const runtime = createToolcraftRendererPipelineRuntime(registration); const decode = registration.getPass("decode"); if (false) { // @ts-expect-error Runtime construction requires a branded registration. createToolcraftRendererPipelineRuntime({ interactionInvalidation: [], passes: [] }); // @ts-expect-error Runtime-owner test instrumentation is not a public factory argument. createToolcraftRendererPipelineRuntimeOwner(registration, {}, {}); void runtime.runPass( decode, { "effect.amount": 1, "source.asset": "source" }, // @ts-expect-error Decode results are strings for every key and invocation. () => 42, ); // @ts-expect-error Cache input keys come from the descriptor. void runtime.runPass(decode, { "source.asset": "source" }, () => "pixels"); // @ts-expect-error Cache input arrays are not executable descriptor keys. void runtime.runPass(decode, ["source", 1], () => "pixels"); // @ts-expect-error Retained resources are generation-bound to pass execution context. void runtime.getOrCreateResource(decode, ["gpu"], () => ({ id: "gpu" }), () => undefined); // @ts-expect-error No-cache passes accept only undefined cache input. void runtime.runPass(registration.getPass("export"), {}, () => "file"); void runtime.runPass(registration.getPass("export"), undefined, (context) => { // @ts-expect-error Call-scoped passes expose no retained-resource capability. void context.getOrCreateResource(["gpu"], () => "resource", () => undefined); return "file"; }); void runtime.runPass( decode, { "effect.amount": 2, "source.asset": "resource" }, (context) => { // @ts-expect-error Decode resources have the registered Resource shape. void context.getOrCreateResource(["gpu"], () => 42, () => undefined); void context.getOrCreateResource( // @ts-expect-error Decode resource keys use the registered string tuple. [42], () => ({ id: "gpu" }), () => undefined, ); return "pixels"; }, ); } expect(runtime.getSnapshot().passes.decode.executions).toBe(0); });