Files
ansiblings/packages/nopy/dist/nopy.history.js
T
Benjamin Diedrichsen 736c01216a initial transfer
2026-07-27 13:09:00 +02:00

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');
}