refactor(v2): make memory storage layer constant

This commit is contained in:
Kit Langton 2026-05-20 16:59:59 -04:00
commit 479b49ffa6
2 changed files with 32 additions and 22 deletions

View file

@ -1,4 +1,4 @@
import { DateTime, Effect, Layer } from "effect" import { Context, DateTime, Effect, Layer } from "effect"
import { SessionMessage } from "@opencode-ai/core/session-message" import { SessionMessage } from "@opencode-ai/core/session-message"
import { SessionStorage } from "./storage" import { SessionStorage } from "./storage"
@ -7,15 +7,18 @@ export interface State {
readonly messages: Map<string, SessionMessage.Message[]> readonly messages: Map<string, SessionMessage.Message[]>
} }
export const makeState = (): State => ({ export class StateService extends Context.Service<StateService, State>()("@opencode/v2/session/StorageMemoryState") {}
const stateLayer = Layer.sync(StateService, () => ({
sessions: new Map(), sessions: new Map(),
messages: new Map(), messages: new Map(),
}) }))
export const layer = (state: State = makeState()) => const storageLayer = Layer.effect(
Layer.succeed( SessionStorage.Service,
SessionStorage.Service, Effect.gen(function* () {
SessionStorage.Service.of({ const state = yield* StateService
return SessionStorage.Service.of({
get: (sessionID) => Effect.sync(() => state.sessions.get(sessionID)), get: (sessionID) => Effect.sync(() => state.sessions.get(sessionID)),
list: (input) => list: (input) =>
Effect.sync(() => { Effect.sync(() => {
@ -79,10 +82,13 @@ export const layer = (state: State = makeState()) =>
const index = messages.findLastIndex((message) => message.type === "compaction") const index = messages.findLastIndex((message) => message.type === "compaction")
return index === -1 ? messages : messages.slice(index) return index === -1 ? messages : messages.slice(index)
}), }),
}), })
) }),
)
export const defaultLayer = layer() export const layer = storageLayer.pipe(Layer.provideMerge(stateLayer))
export const defaultLayer = layer
function compareCursor( function compareCursor(
id: string, id: string,

View file

@ -19,7 +19,6 @@ const sessionB = SessionID.make("ses_storage_b")
const sessionC = SessionID.make("ses_storage_c") const sessionC = SessionID.make("ses_storage_c")
const sessionD = SessionID.make("ses_storage_d") const sessionD = SessionID.make("ses_storage_d")
const encodeMessage = Schema.encodeSync(SessionMessage.Message) const encodeMessage = Schema.encodeSync(SessionMessage.Message)
const memoryState = SessionStorageMemory.makeState()
interface Seeds<R> { interface Seeds<R> {
readonly reset: Effect.Effect<void, never, R> readonly reset: Effect.Effect<void, never, R>
@ -163,27 +162,29 @@ const sqlSeeds: Seeds<never> = {
sessionStorageContract("SessionStorageSql", SessionStorageSql.defaultLayer, sqlSeeds) sessionStorageContract("SessionStorageSql", SessionStorageSql.defaultLayer, sqlSeeds)
const memorySeeds: Seeds<never> = { const memorySeeds: Seeds<SessionStorageMemory.StateService> = {
reset: Effect.sync(() => { reset: Effect.gen(function* () {
const memoryState = yield* SessionStorageMemory.StateService
memoryState.sessions.clear() memoryState.sessions.clear()
memoryState.messages.clear() memoryState.messages.clear()
}), }),
project: Effect.void, project: Effect.void,
session: (input) => session: (input) =>
Effect.sync(() => { Effect.gen(function* () {
const memoryState = yield* SessionStorageMemory.StateService
memoryState.sessions.set(input.id, makeSessionRow(input)) memoryState.sessions.set(input.id, makeSessionRow(input))
}), }),
userMessage: (input) => userMessage: (input) =>
Effect.sync(() => { Effect.gen(function* () {
appendMemoryMessage(makeUserMessage(input)) yield* appendMemoryMessage(makeUserMessage(input))
}), }),
compaction: (input) => compaction: (input) =>
Effect.sync(() => { Effect.gen(function* () {
appendMemoryMessage(makeCompaction(input)) yield* appendMemoryMessage(makeCompaction(input))
}), }),
} }
sessionStorageContract("SessionStorageMemory", SessionStorageMemory.layer(memoryState), memorySeeds) sessionStorageContract("SessionStorageMemory", SessionStorageMemory.layer, memorySeeds)
function seedProject() { function seedProject() {
Database.use((db) => Database.use((db) =>
@ -323,7 +324,10 @@ function seedMessage(
} }
function appendMemoryMessage(message: SessionMessage.Message) { function appendMemoryMessage(message: SessionMessage.Message) {
const current = memoryState.messages.get(sessionA) ?? [] return Effect.gen(function* () {
current.push(message) const memoryState = yield* SessionStorageMemory.StateService
memoryState.messages.set(sessionA, current) const current = memoryState.messages.get(sessionA) ?? []
current.push(message)
memoryState.messages.set(sessionA, current)
})
} }