# All files / lib/reflection memory.ts

80.51% Statements 62/77
81.81% Branches 9/11
72.72% Functions 8/11
80.51% Lines 62/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
    1111x

    1x
    1x
    1x

    1x

    1x
    1x
    1x

    1x
    1x
    1x

    1x
    1x
    1x

    1x

    1x
    1x

    1x

    1x
    1x

    1x

    1x
    1x

    1x

    1x
    1x
    7x
    7x
    7x
    7x

    1x
    1x
    1x

    1x

    1x
    9x
    9x

    1x
    6x
    6x

    1x
    1x
    1x
    1x

    1x
    14x
    14x

    1x
    7x
    7x
    7x

    1x

    1x
    1x
    1x
    19x
    19x
    19x
    19x

    1x
    5x
    5x
     // 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];
    }