constellation-analyzer/src/stores/persistence/fileIO.ts
Jan-Henrik Bruhn f56f928dcf Initial commit
2025-10-10 11:15:51 +02:00

112 lines
2.9 KiB
TypeScript

import type { Actor, Relation, NodeTypeConfig, EdgeTypeConfig } from '../../types';
import type { ConstellationDocument } from './types';
import { createDocument } from './saver';
import { validateDocument, deserializeGraphState } from './loader';
/**
* File I/O - Export and import ConstellationDocument to/from files
*/
/**
* Export current graph state to a JSON file
*/
export function exportGraphToFile(
nodes: Actor[],
edges: Relation[],
nodeTypes: NodeTypeConfig[],
edgeTypes: EdgeTypeConfig[]
): void {
// Create the document using the existing saver
const doc = createDocument(nodes, edges, nodeTypes, edgeTypes);
// Convert to JSON with pretty formatting
const jsonString = JSON.stringify(doc, null, 2);
const blob = new Blob([jsonString], { type: 'application/json' });
const url = URL.createObjectURL(blob);
// Create download link
const link = window.document.createElement('a');
link.href = url;
const dateStr = new Date().toISOString().slice(0, 10);
link.download = `constellation-analysis-${dateStr}.json`;
// Trigger download
window.document.body.appendChild(link);
link.click();
// Cleanup
window.document.body.removeChild(link);
URL.revokeObjectURL(url);
}
/**
* Import graph state from a JSON file
*/
export function importGraphFromFile(
file: File,
onSuccess: (data: {
nodes: Actor[];
edges: Relation[];
nodeTypes: NodeTypeConfig[];
edgeTypes: EdgeTypeConfig[];
}) => void,
onError: (error: string) => void
): void {
const reader = new FileReader();
reader.onload = (event) => {
try {
const jsonString = event.target?.result as string;
const parsed = JSON.parse(jsonString);
// Validate using the existing loader validation
if (!validateDocument(parsed)) {
throw new Error('Invalid file format: File does not match expected Constellation Analyzer format');
}
// Deserialize the graph state
const graphState = deserializeGraphState(parsed as ConstellationDocument);
if (!graphState) {
throw new Error('Failed to parse graph data from file');
}
onSuccess(graphState);
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred while importing file';
onError(errorMessage);
}
};
reader.onerror = () => {
onError('Failed to read file');
};
reader.readAsText(file);
}
/**
* Trigger file selection dialog for import
*/
export function selectFileForImport(
onSuccess: (data: {
nodes: Actor[];
edges: Relation[];
nodeTypes: NodeTypeConfig[];
edgeTypes: EdgeTypeConfig[];
}) => void,
onError: (error: string) => void
): void {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.json';
input.onchange = (event) => {
const file = (event.target as HTMLInputElement).files?.[0];
if (file) {
importGraphFromFile(file, onSuccess, onError);
}
};
input.click();
}