effectify SessionStatus service, add runSyncInstance helper
This commit is contained in:
parent
2c056c90da
commit
3217d112ec
4 changed files with 50 additions and 26 deletions
|
|
@ -123,6 +123,7 @@ Done now:
|
||||||
- [x] `Discovery`
|
- [x] `Discovery`
|
||||||
- [x] `File`
|
- [x] `File`
|
||||||
- [x] `Snapshot`
|
- [x] `Snapshot`
|
||||||
|
- [x] `SessionStatus`
|
||||||
|
|
||||||
Still open and likely worth migrating:
|
Still open and likely worth migrating:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { Instance } from "@/project/instance"
|
||||||
import { Vcs } from "@/project/vcs"
|
import { Vcs } from "@/project/vcs"
|
||||||
import { ProviderAuth } from "@/provider/auth"
|
import { ProviderAuth } from "@/provider/auth"
|
||||||
import { Question } from "@/question"
|
import { Question } from "@/question"
|
||||||
|
import { SessionStatus } from "@/session/status"
|
||||||
import { Skill } from "@/skill/skill"
|
import { Skill } from "@/skill/skill"
|
||||||
import { Snapshot } from "@/snapshot"
|
import { Snapshot } from "@/snapshot"
|
||||||
import { InstanceContext } from "./instance-context"
|
import { InstanceContext } from "./instance-context"
|
||||||
|
|
@ -24,6 +25,7 @@ export type InstanceServices =
|
||||||
| FileTime.Service
|
| FileTime.Service
|
||||||
| Format.Service
|
| Format.Service
|
||||||
| File.Service
|
| File.Service
|
||||||
|
| SessionStatus.Service
|
||||||
| Skill.Service
|
| Skill.Service
|
||||||
| Snapshot.Service
|
| Snapshot.Service
|
||||||
|
|
||||||
|
|
@ -44,6 +46,7 @@ function lookup(_key: string) {
|
||||||
Layer.fresh(FileTime.layer).pipe(Layer.orDie),
|
Layer.fresh(FileTime.layer).pipe(Layer.orDie),
|
||||||
Layer.fresh(Format.layer),
|
Layer.fresh(Format.layer),
|
||||||
Layer.fresh(File.layer),
|
Layer.fresh(File.layer),
|
||||||
|
Layer.fresh(SessionStatus.layer),
|
||||||
Layer.fresh(Skill.defaultLayer),
|
Layer.fresh(Skill.defaultLayer),
|
||||||
Layer.fresh(Snapshot.defaultLayer),
|
Layer.fresh(Snapshot.defaultLayer),
|
||||||
).pipe(Layer.provide(ctx))
|
).pipe(Layer.provide(ctx))
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ export function runPromiseInstance<A, E>(effect: Effect.Effect<A, E, InstanceSer
|
||||||
return runtime.runPromise(effect.pipe(Effect.provide(Instances.get(Instance.directory))))
|
return runtime.runPromise(effect.pipe(Effect.provide(Instances.get(Instance.directory))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function runSyncInstance<A, E>(effect: Effect.Effect<A, E, InstanceServices>) {
|
||||||
|
return runtime.runSync(effect.pipe(Effect.provide(Instances.get(Instance.directory))))
|
||||||
|
}
|
||||||
|
|
||||||
export function disposeRuntime() {
|
export function disposeRuntime() {
|
||||||
return runtime.dispose()
|
return runtime.dispose()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { BusEvent } from "@/bus/bus-event"
|
import { BusEvent } from "@/bus/bus-event"
|
||||||
import { Bus } from "@/bus"
|
import { Bus } from "@/bus"
|
||||||
import { Instance } from "@/project/instance"
|
import { runSyncInstance } from "@/effect/runtime"
|
||||||
import { SessionID } from "./schema"
|
import { SessionID } from "./schema"
|
||||||
|
import { Effect, Layer, ServiceMap } from "effect"
|
||||||
import z from "zod"
|
import z from "zod"
|
||||||
|
|
||||||
export namespace SessionStatus {
|
export namespace SessionStatus {
|
||||||
|
|
@ -42,36 +43,51 @@ export namespace SessionStatus {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = Instance.state(() => {
|
export interface Interface {
|
||||||
const data: Record<string, Info> = {}
|
readonly get: (sessionID: SessionID) => Effect.Effect<Info>
|
||||||
return data
|
readonly list: () => Effect.Effect<Record<string, Info>>
|
||||||
})
|
readonly set: (sessionID: SessionID, status: Info) => Effect.Effect<void>
|
||||||
|
|
||||||
export function get(sessionID: SessionID) {
|
|
||||||
return (
|
|
||||||
state()[sessionID] ?? {
|
|
||||||
type: "idle",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function list() {
|
export class Service extends ServiceMap.Service<Service, Interface>()("@opencode/SessionStatus") {}
|
||||||
return state()
|
|
||||||
|
export const layer = Layer.effect(
|
||||||
|
Service,
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const data = new Map<SessionID, Info>()
|
||||||
|
|
||||||
|
const get = Effect.fn("SessionStatus.get")(function* (sessionID: SessionID) {
|
||||||
|
return data.get(sessionID) ?? { type: "idle" as const }
|
||||||
|
})
|
||||||
|
|
||||||
|
const list = Effect.fn("SessionStatus.list")(function* () {
|
||||||
|
return Object.fromEntries(data)
|
||||||
|
})
|
||||||
|
|
||||||
|
const set = Effect.fn("SessionStatus.set")(function* (sessionID: SessionID, status: Info) {
|
||||||
|
Bus.publish(Event.Status, { sessionID, status })
|
||||||
|
if (status.type === "idle") {
|
||||||
|
// deprecated
|
||||||
|
Bus.publish(Event.Idle, { sessionID })
|
||||||
|
data.delete(sessionID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data.set(sessionID, status)
|
||||||
|
})
|
||||||
|
|
||||||
|
return Service.of({ get, list, set })
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
export function get(sessionID: SessionID): Info {
|
||||||
|
return runSyncInstance(Service.use((svc) => svc.get(sessionID)))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(): Record<string, Info> {
|
||||||
|
return runSyncInstance(Service.use((svc) => svc.list()))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function set(sessionID: SessionID, status: Info) {
|
export function set(sessionID: SessionID, status: Info) {
|
||||||
Bus.publish(Event.Status, {
|
runSyncInstance(Service.use((svc) => svc.set(sessionID, status)))
|
||||||
sessionID,
|
|
||||||
status,
|
|
||||||
})
|
|
||||||
if (status.type === "idle") {
|
|
||||||
// deprecated
|
|
||||||
Bus.publish(Event.Idle, {
|
|
||||||
sessionID,
|
|
||||||
})
|
|
||||||
delete state()[sessionID]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
state()[sessionID] = status
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue