import type { SerializedProjectCommand } from "./project-command.model.js"; import { assertDistributionBoardSubtreeSnapshot, type DistributionBoardSubtreeSnapshot, } from "./distribution-board-subtree-snapshot.model.js"; export const distributionBoardInsertSubtreeCommandType = "distribution-board.insert-subtree" as const; export const distributionBoardDeleteSubtreeCommandType = "distribution-board.delete-subtree" as const; export const distributionBoardSubtreeCommandSchemaVersion = 1 as const; interface Payload { snapshot: DistributionBoardSubtreeSnapshot; } export interface DistributionBoardInsertSubtreeProjectCommand extends SerializedProjectCommand { schemaVersion: typeof distributionBoardSubtreeCommandSchemaVersion; type: typeof distributionBoardInsertSubtreeCommandType; } export interface DistributionBoardDeleteSubtreeProjectCommand extends SerializedProjectCommand { schemaVersion: typeof distributionBoardSubtreeCommandSchemaVersion; type: typeof distributionBoardDeleteSubtreeCommandType; } export type DistributionBoardSubtreeProjectCommand = | DistributionBoardInsertSubtreeProjectCommand | DistributionBoardDeleteSubtreeProjectCommand; export function createDistributionBoardInsertSubtreeProjectCommand( snapshot: DistributionBoardSubtreeSnapshot ): DistributionBoardInsertSubtreeProjectCommand { const command: DistributionBoardInsertSubtreeProjectCommand = { schemaVersion: distributionBoardSubtreeCommandSchemaVersion, type: distributionBoardInsertSubtreeCommandType, payload: { snapshot }, }; assertDistributionBoardInsertSubtreeProjectCommand(command); return command; } export function createDistributionBoardDeleteSubtreeProjectCommand( snapshot: DistributionBoardSubtreeSnapshot ): DistributionBoardDeleteSubtreeProjectCommand { const command: DistributionBoardDeleteSubtreeProjectCommand = { schemaVersion: distributionBoardSubtreeCommandSchemaVersion, type: distributionBoardDeleteSubtreeCommandType, payload: { snapshot }, }; assertDistributionBoardDeleteSubtreeProjectCommand(command); return command; } export function assertDistributionBoardInsertSubtreeProjectCommand( command: SerializedProjectCommand ): asserts command is DistributionBoardInsertSubtreeProjectCommand { assertCommand(command, distributionBoardInsertSubtreeCommandType); } export function assertDistributionBoardDeleteSubtreeProjectCommand( command: SerializedProjectCommand ): asserts command is DistributionBoardDeleteSubtreeProjectCommand { assertCommand(command, distributionBoardDeleteSubtreeCommandType); } function assertCommand( command: SerializedProjectCommand, type: DistributionBoardSubtreeProjectCommand["type"] ) { if ( command.schemaVersion !== distributionBoardSubtreeCommandSchemaVersion || command.type !== type || !isPlainObject(command.payload) || Object.keys(command.payload).length !== 1 ) { throw new Error("Unsupported distribution-board subtree command."); } assertDistributionBoardSubtreeSnapshot(command.payload.snapshot); } function isPlainObject(value: unknown): value is Record { return value !== null && typeof value === "object" && !Array.isArray(value); }