import { objectRef, type QxObjectRef } from "@quixos/camino-package-runtime"; import type { Contexts } from "./gen/qx.js"; export type PlacementInput = { canvas_id: QxObjectRef; subject_id: QxObjectRef; x: number; y: number; width: number; height: number; z: number; }; const finiteNumber = (value: unknown, fallback: number) => typeof value === "number" && Number.isFinite(value) ? value : fallback; const objectId = (value: unknown, field: string) => { try { return objectRef(value as QxObjectRef); } catch { throw new Error(`${field} must be a managed object reference`); } }; export const normalizePlacementInput = (input: Record): PlacementInput => ({ canvas_id: objectId(input.canvas_id, "canvas_id"), subject_id: objectId(input.subject_id, "subject_id"), x: finiteNumber(input.x, 0), y: finiteNumber(input.y, 0), width: Math.max(220, finiteNumber(input.width, 420)), height: Math.max(150, finiteNumber(input.height, 320)), z: Math.trunc(finiteNumber(input.z, 0)), }); export const createCanvas = ({ objectId }: Contexts["createCanvas"]) => objectId; export const createPlacement = async (context: Contexts["createPlacement"]) => { const input = normalizePlacementInput(context.input); await Promise.all([ context.ports.placement["position.set"]({ x: input.x, y: input.y }), context.ports.placement["size.set"]({ width: input.width, height: input.height }), context.ports.placement["z.set"](input.z), ]); await context.ports.placement["subject.connect"](context.input.subject_id); await context.ports.placement["canvas.connect"](context.input.canvas_id); return context.objectId; };