summaryrefslogtreecommitdiffhomepage
path: root/src/features/conversation-cache/cache.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-27 01:13:28 +0900
committerAdam Malczewski <[email protected]>2026-06-27 01:13:31 +0900
commit2fa03f8d7410c2b8d6be8e10ad088863e83d7177 (patch)
tree94e1923180ae38d571d34b578afecb0a18913c24 /src/features/conversation-cache/cache.ts
parent80f99665034a0e510300793205c162fc7a46769f (diff)
parent08b12478636f4a5c86a1f3c40a843f2906b7c82f (diff)
downloaddispatch-web-2fa03f8d7410c2b8d6be8e10ad088863e83d7177.tar.gz
dispatch-web-2fa03f8d7410c2b8d6be8e10ad088863e83d7177.zip
Merge branch 'dev' into feature/heartbeat
# Conflicts: # src/app/App.svelte # src/app/store.svelte.ts # src/app/store.test.ts # src/features/workspaces/ui/WorkspaceCard.test.ts
Diffstat (limited to 'src/features/conversation-cache/cache.ts')
-rw-r--r--src/features/conversation-cache/cache.ts98
1 files changed, 49 insertions, 49 deletions
diff --git a/src/features/conversation-cache/cache.ts b/src/features/conversation-cache/cache.ts
index 3d5743a..4953944 100644
--- a/src/features/conversation-cache/cache.ts
+++ b/src/features/conversation-cache/cache.ts
@@ -3,31 +3,31 @@ import { nextSinceSeq, reconcileCache, selectEvictions } from "./logic";
import type { ConversationChunkStore } from "./types";
export interface ConversationCache {
- /** Load all cached chunks for a conversation. */
- load(conversationId: string): Promise<readonly StoredChunk[]>;
+ /** Load all cached chunks for a conversation. */
+ load(conversationId: string): Promise<readonly StoredChunk[]>;
- /**
- * Load + reconcile + append new chunks.
- * Returns the merged cache (the new authoritative cache for this conversation).
- */
- commit(conversationId: string, incoming: readonly StoredChunk[]): Promise<readonly StoredChunk[]>;
+ /**
+ * Load + reconcile + append new chunks.
+ * Returns the merged cache (the new authoritative cache for this conversation).
+ */
+ commit(conversationId: string, incoming: readonly StoredChunk[]): Promise<readonly StoredChunk[]>;
- /** Return the `?sinceSeq=` cursor for the next incremental sync. */
- sinceSeq(conversationId: string): Promise<number>;
+ /** Return the `?sinceSeq=` cursor for the next incremental sync. */
+ sinceSeq(conversationId: string): Promise<number>;
- /**
- * Evict conversations over budget.
- * Returns the evicted conversationIds.
- */
- evictIfOverBudget(activeConversationId: string | null): Promise<readonly string[]>;
+ /**
+ * Evict conversations over budget.
+ * Returns the evicted conversationIds.
+ */
+ evictIfOverBudget(activeConversationId: string | null): Promise<readonly string[]>;
- /** Delete all cached data for a single conversation (local forget). */
- delete(conversationId: string): Promise<void>;
+ /** Delete all cached data for a single conversation (local forget). */
+ delete(conversationId: string): Promise<void>;
}
export interface ConversationCacheOptions {
- /** Maximum total chunks across all conversations before eviction triggers. */
- readonly maxChunks?: number;
+ /** Maximum total chunks across all conversations before eviction triggers. */
+ readonly maxChunks?: number;
}
const DEFAULT_MAX_CHUNKS = 10_000;
@@ -38,41 +38,41 @@ const DEFAULT_MAX_CHUNKS = 10_000;
* The ONLY impurity is the injected `store`; all logic delegates to pure functions.
*/
export function createConversationCache(
- store: ConversationChunkStore,
- opts?: ConversationCacheOptions,
+ store: ConversationChunkStore,
+ opts?: ConversationCacheOptions,
): ConversationCache {
- const maxChunks = opts?.maxChunks ?? DEFAULT_MAX_CHUNKS;
+ const maxChunks = opts?.maxChunks ?? DEFAULT_MAX_CHUNKS;
- return {
- async load(conversationId) {
- return store.load(conversationId);
- },
+ return {
+ async load(conversationId) {
+ return store.load(conversationId);
+ },
- async commit(conversationId, incoming) {
- const cached = await store.load(conversationId);
- const { merged, toAppend } = reconcileCache(cached, incoming);
- if (toAppend.length > 0) {
- await store.append(conversationId, toAppend);
- }
- return merged;
- },
+ async commit(conversationId, incoming) {
+ const cached = await store.load(conversationId);
+ const { merged, toAppend } = reconcileCache(cached, incoming);
+ if (toAppend.length > 0) {
+ await store.append(conversationId, toAppend);
+ }
+ return merged;
+ },
- async sinceSeq(conversationId) {
- const cached = await store.load(conversationId);
- return nextSinceSeq(cached);
- },
+ async sinceSeq(conversationId) {
+ const cached = await store.load(conversationId);
+ return nextSinceSeq(cached);
+ },
- async evictIfOverBudget(activeConversationId) {
- const idx = await store.index();
- const toEvict = selectEvictions(idx, { maxChunks, activeConversationId });
- for (const id of toEvict) {
- await store.delete(id);
- }
- return toEvict;
- },
+ async evictIfOverBudget(activeConversationId) {
+ const idx = await store.index();
+ const toEvict = selectEvictions(idx, { maxChunks, activeConversationId });
+ for (const id of toEvict) {
+ await store.delete(id);
+ }
+ return toEvict;
+ },
- async delete(conversationId) {
- await store.delete(conversationId);
- },
- };
+ async delete(conversationId) {
+ await store.delete(conversationId);
+ },
+ };
}