/** * JSON file memory store. Zero deps, case-insensitive substring search. * * SCALING: intended for small memory sets. `search()` is an O(n) substring scan * (no index), and every `store()`/`delete()` re-serializes and rewrites the entire * file synchronously. Fine for hundreds–low-thousands of entries; for larger or * write-heavy memory use SQLiteStore (FTS5 index, parameterized, incremental writes). * * Interface (implements Memory store contract): * store(content, metadata) → id * search(query, options) → [{ id, content, metadata, score }] * get(id) → { content, metadata } * delete(id) → void */ export type JsonRecord = { id: number; content: any; metadata: Record; createdAt: string; }; /** * JSON file memory store. Zero deps, case-insensitive substring search. * * SCALING: intended for small memory sets. `search()` is an O(n) substring scan * (no index), and every `store()`/`delete()` re-serializes and rewrites the entire * file synchronously. Fine for hundreds–low-thousands of entries; for larger or * write-heavy memory use SQLiteStore (FTS5 index, parameterized, incremental writes). * * Interface (implements Memory store contract): * store(content, metadata) → id * search(query, options) → [{ id, content, metadata, score }] * get(id) → { content, metadata } * delete(id) → void * * @typedef {object} JsonRecord * @property {number} id * @property {any} content * @property {Record} metadata * @property {string} createdAt */ export class JsonFileStore { /** * @param {{ path?: string }} [options] * @throws {Error} `[JsonFileStore] requires options.path` — when path is missing. * @name JsonFile * @when you want zero-dependency JSON-file storage for Memory (store/search/get/delete) — the simplest durable backend, no native deps * @fails throws on a missing path; implements the four-verb Store socket over a plain JSON file. * @example * const store = new JsonFile({ path: './agent.json' }); */ constructor(options?: { path?: string; }); _path: string; /** @type {JsonRecord[]} */ _data: JsonRecord[]; _nextId: number; _warnedLarge: boolean; _save(): void; /** * @param {any} content * @param {Record} [metadata] * @returns {number} id */ store(content: any, metadata?: Record): number; /** * @param {string} query * @param {{ limit?: number }} [options] * @returns {Array} */ search(query: string, options?: { limit?: number; }): Array; /** * @param {number} id * @returns {{ id: number, content: any, metadata: Record } | null} */ get(id: number): { id: number; content: any; metadata: Record; } | null; /** * @param {number} id * @returns {void} */ delete(id: number): void; }