import { QxReject, type ExactReference, type MutationKey } from "@quixos/camino-replica-core"; import { generic, type Contexts, type PortableImplementation } from "./gen/qx.js"; const position = (value: { readonly x: number; readonly y: number }) => { if (!Number.isFinite(value.x) || !Number.isFinite(value.y)) throw new QxReject("INVALID_POSITION"); }; const size = (value: { readonly width: number; readonly height: number }) => { if (!Number.isFinite(value.width) || !Number.isFinite(value.height) || value.width <= 0 || value.height <= 0) throw new QxReject("INVALID_SIZE"); }; const canPresent = async ({ receiver, input, ports, }: { readonly receiver: ExactReference; readonly input: string; readonly ports: { readonly catalog: { presentations(): Promise>; }; }; }) => { const presentations = await ports.catalog.presentations(); return presentations.some((p) => p.id === input && p.atoms.includes(receiver.expectation.id)); }; const place = async ({ receiver, input, ports }: Contexts["place"]) => { position(input.layout); size(input.layout); if (!(await ports.subject["canPresent.call"]({ receiver: input.subject, input: input.presentation }))) throw new QxReject("INVALID_PRESENTATION"); return ports.placement.create( { canvas: { ...receiver, expectation: { kind: "interface", id: "interface:org.quixos.web-studio.canvas@1" } }, subject: input.subject, presentation: input.presentation, position: { x: input.layout.x, y: input.layout.y }, size: { width: input.layout.width, height: input.layout.height }, z: input.layout.z, }, { key: "placement" }, ); }; export const createPlaced = async ({ input, ports, }: { input: { seed: Input; canvas: Contexts["place"]["receiver"]; presentation: string; layout: Contexts["place"]["input"]["layout"]; }; ports: { factory: { "create.call"(input: Input, key: MutationKey): Promise }; canvas: { "place.call"( input: { receiver: ExactReference; input: Contexts["place"]["input"] }, key: MutationKey, ): Promise>>; }; }; }) => { const subject = await ports.factory["create.call"](input.seed, { key: "subject" }); return ports.canvas["place.call"]( { receiver: input.canvas, input: { subject: { ...subject, expectation: { kind: "interface", id: "interface:org.quixos.web-studio.placeable@1" } }, presentation: input.presentation, layout: input.layout, }, }, { key: "placement" }, ); }; export const handlers: Omit = { ...generic.canPresent(canPresent), ...generic.createPlaced(createPlaced), createCanvas: ({ input, ports }) => ports.canvas.create({ name: input }, { key: "canvas" }), place, createAndPlace: async (context) => { const subject = await context.ports.canvas.create({ name: context.input.name }, { key: "canvas" }); return place({ ...context, input: { subject: { ...subject, expectation: { kind: "interface", id: "interface:org.quixos.web-studio.placeable@1" } }, presentation: context.input.presentation, layout: context.input.layout, }, }); }, };