All files / lib/reflection memory.ts

0% Statements 0/77
0% Branches 0/1
0% Functions 0/1
0% Lines 0/77

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111                                                                                                                                                                                                                             
// lib/reflection/memory.ts
 
import type { ReflectionMemoryEntry, ReflectionSnapshot } from './types';
 
// ========================================
//   Configuration
// ========================================
 
const MEMORY_CAPACITY = 100; // Maximum number of entries to keep in memory
 
// ========================================
//   Module State
// ========================================
 
const memoryBuffer: ReflectionMemoryEntry[] = [];
let currentSequence = 0;
let head = 0; // Pointer to the next slot to write to
 
// ========================================
//   Public API
// ========================================
 
/**
 * Adds a new entry to the reflection memory.
 * Overwrites the oldest entry if capacity is reached.
 * @param entry The partial memory entry to add.
 */
export function addToMemory(entry: Omit<ReflectionMemoryEntry, 'sequence' | 'timestamp'>): void {
  const newEntry: ReflectionMemoryEntry = {
    ...entry,
    sequence: ++currentSequence,
    timestamp: performance.now(),
  };
 
  memoryBuffer[head] = newEntry;
  head = (head + 1) % MEMORY_CAPACITY;
}
 
/**
 * Returns a copy of all entries currently in the reflection memory.
 * The entries are not guaranteed to be in chronological order.
 * @returns An array of memory entries.
 */
export function getMemorySnapshot(): Readonly<ReflectionMemoryEntry[]> {
  return [...memoryBuffer];
}
 
/**
 * Returns the most recent `n` entries from memory, ordered from newest to oldest.
 * @param count The number of recent entries to retrieve.
 * @returns An array of the most recent memory entries.
 */
export function getRecentMemory(count: number): Readonly<ReflectionMemoryEntry[]> {
  const snapshot = [...memoryBuffer];
  // Sort by sequence number in descending order to get the newest first
  snapshot.sort((a, b) => b.sequence - a.sequence);
  return snapshot.slice(0, count);
}
 
/**
 * Resets the reflection memory to its initial state.
 * (For testing purposes)
 */
export function _resetMemory(): void {
  memoryBuffer.length = 0;
  currentSequence = 0;
  head = 0;
}
 
// ------------------------------------------------------------------
// Backwards compatible API expected by tests
// ------------------------------------------------------------------
 
const snapshotBuffer: ReflectionSnapshot[] = [];
 
export function storeReflectionSnapshot(snapshot: ReflectionSnapshot): void {
  snapshotBuffer.push(snapshot);
}
 
export function getReflectionHistory(): ReflectionSnapshot[] {
  return [...snapshotBuffer].sort((a, b) => a.timestamp - b.timestamp);
}
 
export function getLastReflection(): ReflectionSnapshot | null {
  if (snapshotBuffer.length === 0) return null;
  return snapshotBuffer[snapshotBuffer.length - 1];
}
 
export function clearReflectionMemory(): void {
  snapshotBuffer.length = 0;
}
 
export function _resetMemoryForTests(): void {
  _resetMemory();
  clearReflectionMemory();
}
 
/**
 * Tests expect introspection to expose a "latest signals" buffer.
 */
const latestSignals: any[] = [];
export function _pushLatestSignals(signals: any[]) {
  latestSignals.push(...signals);
  // keep small
  if (latestSignals.length > 100) latestSignals.splice(0, latestSignals.length - 100);
}
 
export function getLatestSignals(): any[] {
  return [...latestSignals];
}