84 lines
2.1 KiB
TypeScript
84 lines
2.1 KiB
TypeScript
import type { PageRef } from '../pdf/pdfTypes';
|
|
|
|
export interface WorkspaceCommandState {
|
|
pages: PageRef[];
|
|
selectedPageIds: string[];
|
|
lastSelectedVisualIndex: number | null;
|
|
}
|
|
|
|
export interface WorkspaceCommandPayload {
|
|
before: WorkspaceCommandState;
|
|
after: WorkspaceCommandState;
|
|
details?: Record<string, unknown>;
|
|
}
|
|
|
|
export interface WorkspaceCommandRecord {
|
|
id: string;
|
|
type: string;
|
|
label: string;
|
|
timestamp: string;
|
|
payload: WorkspaceCommandPayload;
|
|
}
|
|
|
|
export interface WorkspaceCommand extends WorkspaceCommandRecord {
|
|
do: (state: WorkspaceCommandState) => WorkspaceCommandState;
|
|
undo: (state: WorkspaceCommandState) => WorkspaceCommandState;
|
|
}
|
|
|
|
export function cloneCommandState(
|
|
state: WorkspaceCommandState
|
|
): WorkspaceCommandState {
|
|
return {
|
|
pages: state.pages.map((page) => ({ ...page })),
|
|
selectedPageIds: [...state.selectedPageIds],
|
|
lastSelectedVisualIndex: state.lastSelectedVisualIndex,
|
|
};
|
|
}
|
|
|
|
export function createSnapshotCommand(params: {
|
|
id: string;
|
|
type: string;
|
|
label: string;
|
|
timestamp?: string;
|
|
before: WorkspaceCommandState;
|
|
after: WorkspaceCommandState;
|
|
details?: Record<string, unknown>;
|
|
}): WorkspaceCommand {
|
|
return reviveWorkspaceCommand({
|
|
id: params.id,
|
|
type: params.type,
|
|
label: params.label,
|
|
timestamp: params.timestamp ?? new Date().toISOString(),
|
|
payload: {
|
|
before: cloneCommandState(params.before),
|
|
after: cloneCommandState(params.after),
|
|
details: params.details,
|
|
},
|
|
});
|
|
}
|
|
|
|
export function reviveWorkspaceCommand(
|
|
record: WorkspaceCommandRecord
|
|
): WorkspaceCommand {
|
|
return {
|
|
...record,
|
|
do: () => cloneCommandState(record.payload.after),
|
|
undo: () => cloneCommandState(record.payload.before),
|
|
};
|
|
}
|
|
|
|
export function toWorkspaceCommandRecord(
|
|
command: WorkspaceCommand
|
|
): WorkspaceCommandRecord {
|
|
return {
|
|
id: command.id,
|
|
type: command.type,
|
|
label: command.label,
|
|
timestamp: command.timestamp,
|
|
payload: {
|
|
before: cloneCommandState(command.payload.before),
|
|
after: cloneCommandState(command.payload.after),
|
|
details: command.payload.details,
|
|
},
|
|
};
|
|
} |