{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../src/cache/compaction.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,IAAI;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IAC1B,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,IAAI,EAAE,CAAC;IACb,OAAO,EAAE,IAAI,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,CAIjD;AAED;8DAC8D;AAC9D,wBAAgB,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,CAmBxE;AAGD,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,cAAc,CAAK;IAE3B,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAQtE;IAED,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAG9B;CACD","sourcesContent":["// T-050, T-051, T-052: cache-aware middle-drop trimming with N-recent-turn floor\n// + deterministic stable summary block.\n\nexport interface Turn {\n\tindex: number;\n\tbytes: string;\n}\n\nexport interface TrimConfig {\n\t/** Keep the most recent N turns untouched. */\n\trecentFloor: number;\n}\n\nexport interface TrimResult {\n\tkept: Turn[];\n\tsummary: Turn;\n\tdroppedCount: number;\n}\n\n/** Deterministic summary bytes derived from dropped turns. */\nexport function summarize(dropped: Turn[]): string {\n\tconst indices = dropped.map((t) => t.index).join(\",\");\n\tconst totalBytes = dropped.reduce((acc, t) => acc + t.bytes.length, 0);\n\treturn `<compact ${dropped.length} turns [${indices}], ${totalBytes} bytes>`;\n}\n\n/** Middle-drop: keep [0..pivot] as a placeholder floor and [tail - recentFloor..tail];\n *  drop the middle span and replace with a stable summary. */\nexport function trimMiddle(turns: Turn[], config: TrimConfig): TrimResult {\n\tif (turns.length <= config.recentFloor + 1) {\n\t\treturn {\n\t\t\tkept: turns,\n\t\t\tsummary: { index: -1, bytes: \"\" },\n\t\t\tdroppedCount: 0,\n\t\t};\n\t}\n\tconst tail = turns.slice(turns.length - config.recentFloor);\n\tconst middle = turns.slice(0, turns.length - config.recentFloor);\n\tconst summary: Turn = {\n\t\tindex: middle[middle.length - 1].index + 0.5,\n\t\tbytes: summarize(middle),\n\t};\n\treturn {\n\t\tkept: [summary, ...tail],\n\t\tsummary,\n\t\tdroppedCount: middle.length,\n\t};\n}\n\n// T-053, T-054: opt-in keepalive pings with idle shutoff.\nexport interface KeepaliveConfig {\n\tintervalMs: number;\n\tretention: \"long\" | \"short\" | \"none\";\n\tenabled: boolean;\n}\n\nexport class KeepaliveScheduler {\n\tprivate lastPingMs = 0;\n\tprivate lastActivityMs = 0;\n\n\ttick(now: number, config: KeepaliveConfig): \"ping\" | \"shutoff\" | \"skip\" {\n\t\tif (!config.enabled || config.retention === \"none\") return \"skip\";\n\t\tif (now - this.lastActivityMs > config.intervalMs * 2) return \"shutoff\";\n\t\tif (now - this.lastPingMs >= config.intervalMs) {\n\t\t\tthis.lastPingMs = now;\n\t\t\treturn \"ping\";\n\t\t}\n\t\treturn \"skip\";\n\t}\n\n\tmarkActivity(now: number): void {\n\t\tthis.lastActivityMs = now;\n\t\tthis.lastPingMs = now;\n\t}\n}\n"]}