171 lines
4.7 KiB
JavaScript
171 lines
4.7 KiB
JavaScript
/**
|
|
* Session history management
|
|
* @module nopy.history
|
|
*/
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
/** Default number of sessions to keep in history */
|
|
export const DEFAULT_HISTORY_SIZE = 10;
|
|
/** History file name */
|
|
export const HISTORY_FILE = '.nopy.history.json';
|
|
/**
|
|
* Gets the path to the history file
|
|
*/
|
|
export function getHistoryPath() {
|
|
return path.resolve(process.cwd(), HISTORY_FILE);
|
|
}
|
|
/**
|
|
* Loads the session history from disk
|
|
*
|
|
* @returns The session history or empty history if file doesn't exist
|
|
*/
|
|
export function loadHistory() {
|
|
const historyPath = getHistoryPath();
|
|
if (!fs.existsSync(historyPath)) {
|
|
return { entries: [] };
|
|
}
|
|
try {
|
|
const content = fs.readFileSync(historyPath, 'utf-8');
|
|
return JSON.parse(content);
|
|
}
|
|
catch {
|
|
return { entries: [] };
|
|
}
|
|
}
|
|
/**
|
|
* Saves the session history to disk
|
|
*
|
|
* @param history - The history to save
|
|
*/
|
|
export function saveHistory(history) {
|
|
const historyPath = getHistoryPath();
|
|
fs.writeFileSync(historyPath, JSON.stringify(history, null, 2), 'utf-8');
|
|
}
|
|
/**
|
|
* Generates a history entry name from session data
|
|
*
|
|
* Format: "YYYY-MM-DD HH:mm - cube1, cube2, ..."
|
|
*
|
|
* @param session - The session to name
|
|
* @param timestamp - ISO timestamp
|
|
* @returns Human-readable name
|
|
*/
|
|
function generateEntryName(session, timestamp) {
|
|
const date = new Date(timestamp);
|
|
const dateStr = date.toLocaleString('en-US', {
|
|
year: 'numeric',
|
|
month: '2-digit',
|
|
day: '2-digit',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
hour12: false,
|
|
});
|
|
const cubeNames = session.cubes.map((c) => c.key).join(', ');
|
|
const truncatedCubes = cubeNames.length > 40 ? `${cubeNames.substring(0, 37)}...` : cubeNames;
|
|
const hosts = session.hosts?.join(', ') || 'no host';
|
|
const truncatedHosts = hosts.length > 20 ? `${hosts.substring(0, 17)}...` : hosts;
|
|
return `${dateStr} - ${truncatedCubes} → ${truncatedHosts}`;
|
|
}
|
|
/**
|
|
* Generates a unique ID for a history entry
|
|
*/
|
|
function generateEntryId() {
|
|
return Date.now().toString(36) + Math.random().toString(36).substring(2, 7);
|
|
}
|
|
/**
|
|
* Adds a session to the history
|
|
*
|
|
* @param session - The session to add
|
|
* @param maxEntries - Maximum number of entries to keep
|
|
* @returns The created history entry
|
|
*/
|
|
export function addToHistory(session, maxEntries = DEFAULT_HISTORY_SIZE) {
|
|
const history = loadHistory();
|
|
const timestamp = new Date().toISOString();
|
|
const entry = {
|
|
id: generateEntryId(),
|
|
name: generateEntryName(session, timestamp),
|
|
timestamp,
|
|
session,
|
|
};
|
|
// Add to beginning (newest first)
|
|
history.entries.unshift(entry);
|
|
// Trim to max size
|
|
if (history.entries.length > maxEntries) {
|
|
history.entries = history.entries.slice(0, maxEntries);
|
|
}
|
|
saveHistory(history);
|
|
return entry;
|
|
}
|
|
/**
|
|
* Gets the most recent session from history
|
|
*
|
|
* @returns The last session or undefined if history is empty
|
|
*/
|
|
export function getLastSession() {
|
|
const history = loadHistory();
|
|
return history.entries[0];
|
|
}
|
|
/**
|
|
* Gets a session by ID
|
|
*
|
|
* @param id - The session ID
|
|
* @returns The session entry or undefined
|
|
*/
|
|
export function getSessionById(id) {
|
|
const history = loadHistory();
|
|
return history.entries.find((e) => e.id === id);
|
|
}
|
|
/**
|
|
* Lists all sessions in history
|
|
*
|
|
* @returns Array of history entries, newest first
|
|
*/
|
|
export function listHistory() {
|
|
const history = loadHistory();
|
|
return history.entries;
|
|
}
|
|
/**
|
|
* Clears all session history
|
|
*/
|
|
export function clearHistory() {
|
|
saveHistory({ entries: [] });
|
|
}
|
|
/**
|
|
* Removes a specific session from history
|
|
*
|
|
* @param id - The session ID to remove
|
|
* @returns true if removed, false if not found
|
|
*/
|
|
export function removeFromHistory(id) {
|
|
const history = loadHistory();
|
|
const initialLength = history.entries.length;
|
|
history.entries = history.entries.filter((e) => e.id !== id);
|
|
if (history.entries.length < initialLength) {
|
|
saveHistory(history);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
/**
|
|
* Formats history entries for display
|
|
*
|
|
* @param entries - History entries to format
|
|
* @returns Formatted string for console output
|
|
*/
|
|
export function formatHistoryList(entries) {
|
|
if (entries.length === 0) {
|
|
return 'No sessions in history.';
|
|
}
|
|
const lines = ['', 'Session History:', ''];
|
|
entries.forEach((entry, index) => {
|
|
const marker = index === 0 ? '→' : ' ';
|
|
lines.push(` ${marker} [${index + 1}] ${entry.name}`);
|
|
lines.push(` ID: ${entry.id}`);
|
|
});
|
|
lines.push('');
|
|
lines.push(`Total: ${entries.length} session(s)`);
|
|
lines.push('');
|
|
return lines.join('\n');
|
|
}
|