diff options
Diffstat (limited to 'src/features/surface-host/logic/plan.ts')
| -rw-r--r-- | src/features/surface-host/logic/plan.ts | 210 |
1 files changed, 105 insertions, 105 deletions
diff --git a/src/features/surface-host/logic/plan.ts b/src/features/surface-host/logic/plan.ts index 89088c3..c8f82b9 100644 --- a/src/features/surface-host/logic/plan.ts +++ b/src/features/surface-host/logic/plan.ts @@ -1,20 +1,20 @@ import type { InvokeMessage, SurfaceSpec } from "@dispatch/ui-contract"; import type { - FieldView, - NumberFieldView, - RenderGroup, - StatFieldView, - SurfaceRenderPlan, + FieldView, + NumberFieldView, + RenderGroup, + StatFieldView, + SurfaceRenderPlan, } from "./types"; const KNOWN_KINDS = new Set([ - "toggle", - "progress", - "selector", - "stat", - "number", - "button", - "custom", + "toggle", + "progress", + "selector", + "stat", + "number", + "button", + "custom", ]); /** @@ -25,73 +25,73 @@ const KNOWN_KINDS = new Set([ * decision (unknown `rendererId` → skipped there), not a planning one. */ export function planSurface(spec: SurfaceSpec): SurfaceRenderPlan { - const fields: FieldView[] = []; - for (const field of spec.fields) { - if (!KNOWN_KINDS.has(field.kind)) continue; - switch (field.kind) { - case "toggle": - fields.push({ - kind: "toggle", - label: field.label, - value: field.value, - action: field.action, - }); - break; - case "progress": - fields.push({ - kind: "progress", - label: field.label, - value: field.value, - }); - break; - case "selector": - fields.push({ - kind: "selector", - label: field.label, - value: field.value, - options: field.options, - action: field.action, - }); - break; - case "stat": - fields.push({ - kind: "stat", - label: field.label, - value: field.value, - }); - break; - case "number": { - // Carry optional hints only when present (exactOptionalPropertyTypes). - const view: NumberFieldView = { - kind: "number", - label: field.label, - value: field.value, - action: field.action, - ...(field.min !== undefined ? { min: field.min } : {}), - ...(field.max !== undefined ? { max: field.max } : {}), - ...(field.step !== undefined ? { step: field.step } : {}), - ...(field.unit !== undefined ? { unit: field.unit } : {}), - }; - fields.push(view); - break; - } - case "button": - fields.push({ - kind: "button", - label: field.label, - action: field.action, - }); - break; - case "custom": - fields.push({ - kind: "custom", - rendererId: field.rendererId, - payload: field.payload, - }); - break; - } - } - return { fields }; + const fields: FieldView[] = []; + for (const field of spec.fields) { + if (!KNOWN_KINDS.has(field.kind)) continue; + switch (field.kind) { + case "toggle": + fields.push({ + kind: "toggle", + label: field.label, + value: field.value, + action: field.action, + }); + break; + case "progress": + fields.push({ + kind: "progress", + label: field.label, + value: field.value, + }); + break; + case "selector": + fields.push({ + kind: "selector", + label: field.label, + value: field.value, + options: field.options, + action: field.action, + }); + break; + case "stat": + fields.push({ + kind: "stat", + label: field.label, + value: field.value, + }); + break; + case "number": { + // Carry optional hints only when present (exactOptionalPropertyTypes). + const view: NumberFieldView = { + kind: "number", + label: field.label, + value: field.value, + action: field.action, + ...(field.min !== undefined ? { min: field.min } : {}), + ...(field.max !== undefined ? { max: field.max } : {}), + ...(field.step !== undefined ? { step: field.step } : {}), + ...(field.unit !== undefined ? { unit: field.unit } : {}), + }; + fields.push(view); + break; + } + case "button": + fields.push({ + kind: "button", + label: field.label, + action: field.action, + }); + break; + case "custom": + fields.push({ + kind: "custom", + rendererId: field.rendererId, + payload: field.payload, + }); + break; + } + } + return { fields }; } /** @@ -100,24 +100,24 @@ export function planSurface(spec: SurfaceSpec): SurfaceRenderPlan { * other field stays a standalone `field` group. Order is preserved. Pure. */ export function groupRenderFields(fields: readonly FieldView[]): RenderGroup[] { - const groups: RenderGroup[] = []; - let run: StatFieldView[] = []; - const flush = (): void => { - if (run.length > 0) { - groups.push({ type: "stats", stats: run }); - run = []; - } - }; - for (const field of fields) { - if (field.kind === "stat") { - run.push(field); - } else { - flush(); - groups.push({ type: "field", field }); - } - } - flush(); - return groups; + const groups: RenderGroup[] = []; + let run: StatFieldView[] = []; + const flush = (): void => { + if (run.length > 0) { + groups.push({ type: "stats", stats: run }); + run = []; + } + }; + for (const field of fields) { + if (field.kind === "stat") { + run.push(field); + } else { + flush(); + groups.push({ type: "field", field }); + } + } + flush(); + return groups; } /** @@ -126,13 +126,13 @@ export function groupRenderFields(fields: readonly FieldView[]): RenderGroup[] { * for button the payload is omitted. */ export function buildInvoke( - surfaceId: string, - field: Extract<FieldView, { action: unknown }>, - value?: unknown, + surfaceId: string, + field: Extract<FieldView, { action: unknown }>, + value?: unknown, ): InvokeMessage { - const base = { type: "invoke" as const, surfaceId, actionId: field.action.actionId }; - if (value !== undefined) { - return { ...base, payload: value }; - } - return base; + const base = { type: "invoke" as const, surfaceId, actionId: field.action.actionId }; + if (value !== undefined) { + return { ...base, payload: value }; + } + return base; } |
