/** * In-memory spool readers and stores for tests, scripts, and non-durable prototypes. * * @module @nhtio/adk/batteries/storage/in_memory * * @remarks * Opt-in in-memory persistence battery. Provides {@link InMemorySpoolReader} (a sync * {@link @nhtio/adk!SpoolReader} over a string) plus {@link InMemorySpoolStore} (a `Map` * with a `write()` method that returns a fresh reader bound to the stored bytes). * * Use this when: * * - Writing unit or functional tests that need a real `SpoolReader` over known bytes. * - Running a REPL or one-shot script where persistence beyond the process lifetime is not * needed. * - Prototyping an agent before deciding on a real disk/object-store-backed persistence layer. * * Do **not** use this for production agents that need durability across process restarts — * everything lives in process memory and is lost on exit. */ import type { ReaderDescriptor, SpoolReader, SpoolStore } from "../../../common"; /** * Resolver tag for the in-memory spool reader handle. The locator inlines the decoded content because an * in-memory reader owns its bytes outright — there is no external store to point at. */ export declare const SPOOL_READER_TAG_IN_MEMORY = "spool:in-memory"; /** * Sync in-memory {@link @nhtio/adk!SpoolReader} over a byte-faithful `Uint8Array` body. * * @remarks * Stores the raw bytes and decodes them as UTF-8 once at construction, then splits the decoded * string on `\n` and caches the resulting line array. All four `SpoolReader` methods resolve * synchronously from the cache — no I/O happens after construction. `byteLength()` reports the * true stored byte count (not the decoded character count), so it stays correct for multi-byte * content; `line()`/`readAll()` operate on the decoded text. * * The reader accepts a `string` or a `Uint8Array`. A `string` is encoded as UTF-8 for the byte * count; a `Uint8Array` is held byte-faithfully (no lossy re-encode) and decoded for text reads. * * Empty input yields a reader with `lineCount() === 0` and `byteLength() === 0`. A trailing * newline produces a final empty line: `"a\nb\n".split('\n') === ['a', 'b', '']`. This matches * the JavaScript `String.prototype.split` contract and lets a `lineCount()` consumer * distinguish "two lines, no trailing newline" from "two lines, trailing newline". */ export declare class InMemorySpoolReader implements SpoolReader { #private; constructor(content: string | Uint8Array); line(index: number): string | undefined; byteLength(): number; lineCount(): number; readAll(): string; describe(): ReaderDescriptor; } /** * In-memory "give bytes, get a reader" persistence layer keyed by `callId`. * * @remarks * Stores each value byte-faithfully as a `Uint8Array`. `string` inputs are encoded as UTF-8; * `Uint8Array` inputs are held verbatim (no lossy text round-trip, so binary payloads survive * intact); `ReadableStream` inputs are drained fully into a buffer — in-memory storage * cannot stream to disk, so the stream form resolves asynchronously and is the documented * trade-off for this battery. * * Each `write()` and each `read()` returns a *fresh* {@link InMemorySpoolReader} — the store * owns the bytes, the reader is a view. Mutating the store after handing out a reader does not * invalidate the reader. * * Implements {@link @nhtio/adk/common!SpoolStore} (i.e. `ByteStore`). * * @example * ```ts * const store = new InMemorySpoolStore() * const bytes = await tool.executor(ctx)(args) * const reader = await store.write(callId, bytes) * const Ctor = tool.artifactConstructor?.() ?? SpooledArtifact * const artifact = new Ctor(reader) * ``` */ export declare class InMemorySpoolStore implements SpoolStore { #private; /** * Persists `bytes` under `callId` and returns a reader over them. * * @remarks * `string` input is encoded as UTF-8; `Uint8Array` is stored byte-faithfully; * `ReadableStream` is drained fully (and `write` returns a `Promise`). Re-writing the * same `callId` replaces the prior entry; readers handed out before the rewrite continue to view * the old bytes (they hold their own snapshot via the `InMemorySpoolReader` constructor). * * @param callId - Identifier used to retrieve the bytes via {@link InMemorySpoolStore.read}. * @param bytes - The bytes to store, as a `string`, `Uint8Array`, or `ReadableStream`. * @returns A fresh {@link InMemorySpoolReader} bound to the stored bytes — a `Promise` for stream * input, synchronous otherwise. */ write(callId: string, bytes: string): InMemorySpoolReader; write(callId: string, bytes: Uint8Array): InMemorySpoolReader; write(callId: string, bytes: ReadableStream): Promise; write(callId: string, bytes: string | Uint8Array | ReadableStream): InMemorySpoolReader | Promise; /** * Returns a reader over the bytes previously written under `callId`, or `undefined` if the * entry has not been written or has been deleted. * * @param callId - Identifier supplied to a prior {@link InMemorySpoolStore.write} call. * @returns A fresh {@link InMemorySpoolReader} bound to the stored bytes, or `undefined`. */ read(callId: string): InMemorySpoolReader | undefined; /** * Removes the entry under `callId`. * * @param callId - Identifier whose entry should be removed. * @returns `true` if an entry existed and was removed; `false` otherwise. */ delete(callId: string): boolean; /** * Removes every entry from the store. * * @remarks * Existing readers handed out by prior `write()` / `read()` calls remain valid — they hold * their own snapshot. */ clear(): void; /** * Returns the number of entries currently in the store. */ get size(): number; }