File size: 1,988 Bytes
3e05655 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | export * as CommandV2 from "./command"
import { makeLocationNode } from "./effect/app-node"
import { Context, Effect, Layer, Types } from "effect"
import { Command } from "@opencode-ai/schema/command"
import { State } from "./state"
export const Info = Command.Info
export type Info = Command.Info
export type Data = {
commands: Map<string, Types.DeepMutable<Info>>
}
export type Draft = {
list: () => readonly Info[]
get: (name: string) => Info | undefined
update: (name: string, update: (command: Types.DeepMutable<Info>) => void) => void
remove: (name: string) => void
}
export interface Interface extends State.Transformable<Draft> {
readonly get: (name: string) => Effect.Effect<Info | undefined>
readonly list: () => Effect.Effect<Info[]>
}
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Command") {}
const layer = Layer.effect(
Service,
Effect.sync(() => {
const state = State.create<Data, Draft>({
initial: () => ({ commands: new Map() }),
draft: (draft) => ({
list: () => Array.from(draft.commands.values()) as Info[],
get: (name) => draft.commands.get(name),
update: (name, update) => {
const current = draft.commands.get(name) ?? ({ name, template: "" } as Types.DeepMutable<Info>)
if (!draft.commands.has(name)) draft.commands.set(name, current)
update(current)
current.name = name
},
remove: (name) => {
draft.commands.delete(name)
},
}),
})
return Service.of({
reload: state.reload,
transform: state.transform,
get: Effect.fn("CommandV2.get")(function* (name) {
return state.get().commands.get(name)
}),
list: Effect.fn("CommandV2.list")(function* () {
return Array.from(state.get().commands.values())
}),
})
}),
)
export const locationLayer = layer
export const node = makeLocationNode({ service: Service, layer, deps: [] })
|