import { CorrectiveCommandRegistry } from "./corrective-command-registry"; import { CorrectiveCaseRunnerError, MainMutationCommand } from "./corrective-case-runner"; import { InMemoryMainStore, runAtomicMutation } from "./corrective-main-transaction"; export interface ModifierState { uuid: string; name: string; type: string; enabled: boolean; showViewport: boolean; showRender: boolean; } export interface ModifierMain { modifiers: ModifierState[]; } const UUID = /^[A-Za-z0-9._:-]{1,128}$/u; function modifierPayload(command: MainMutationCommand): { modifierUuid: string; enabled: boolean } { const input = command.payload; if (!input || typeof input !== "object" || Array.isArray(input) || typeof input.modifierUuid !== "string" || !UUID.test(input.modifierUuid) || typeof input.enabled !== "boolean" || Object.keys(input).some((key) => !["modifierUuid", "enabled"].includes(key))) { throw new CorrectiveCaseRunnerError("COMMAND_MALFORMED", "modifier payload must contain only modifierUuid and enabled"); } return { modifierUuid: input.modifierUuid, enabled: input.enabled }; } function cloneModifierMain(value: ModifierMain): ModifierMain { return { modifiers: value.modifiers.map((modifier) => ({ ...modifier })) }; } export function createModifierRegistry(main: InMemoryMainStore): CorrectiveCommandRegistry { return new CorrectiveCommandRegistry().register({ commandType: "modifierSetEnabled", targetKinds: ["MODIFIER"], authorizations: ["USER_EDIT", "SYSTEM"], execute: async (command) => { const change = modifierPayload(command); return runAtomicMutation(main, command, (draft) => { const modifier = draft.modifiers.find((candidate) => candidate.uuid === change.modifierUuid); if (!modifier) { throw new CorrectiveCaseRunnerError("COMMAND_UNSUPPORTED", `modifier ${change.modifierUuid} does not exist`); } const previousEnabled = modifier.enabled; modifier.enabled = change.enabled; return { delta: { modifierUuid: modifier.uuid, previousEnabled, enabled: modifier.enabled }, persistence: { dirty: true }, }; }); }, }); } export function createModifierMain(modifiers: readonly ModifierState[], revision = 0, dirty = false): InMemoryMainStore { return new InMemoryMainStore({ modifiers: modifiers.map((modifier) => ({ ...modifier })) }, revision, dirty, cloneModifierMain); }