Просмотр исходного кода

feat: add `session.started` event that triggers when a new session is created (#3413)

Bernat Pericàs 3 месяцев назад
Родитель
Сommit
b562863fcc

+ 9 - 0
packages/opencode/src/session/index.ts

@@ -78,6 +78,12 @@ export namespace Session {
   export type ShareInfo = z.output<typeof ShareInfo>
 
   export const Event = {
+    Started: Bus.event(
+      "session.started",
+      z.object({
+        info: Info,
+      }),
+    ),
     Updated: Bus.event(
       "session.updated",
       z.object({
@@ -167,6 +173,9 @@ export namespace Session {
     }
     log.info("created", result)
     await Storage.write(["session", Instance.project.id, result.id], result)
+    Bus.publish(Event.Started, {
+      info: result,
+    })
     const cfg = await Config.get()
     if (!result.parentID && (Flag.OPENCODE_AUTO_SHARE || cfg.share === "auto"))
       share(result.id)

+ 71 - 0
packages/opencode/test/session/session.test.ts

@@ -0,0 +1,71 @@
+import { describe, expect, test } from "bun:test"
+import path from "path"
+import { Session } from "../../src/session"
+import { Bus } from "../../src/bus"
+import { Log } from "../../src/util/log"
+import { Instance } from "../../src/project/instance"
+
+const projectRoot = path.join(__dirname, "../..")
+Log.init({ print: false })
+
+describe("session.started event", () => {
+  test("should emit session.started event when session is created", async () => {
+    await Instance.provide({
+      directory: projectRoot,
+      fn: async () => {
+        let eventReceived = false
+        let receivedInfo: Session.Info | undefined
+
+        const unsub = Bus.subscribe(Session.Event.Started, (event) => {
+          eventReceived = true
+          receivedInfo = event.properties.info as Session.Info
+        })
+
+        const session = await Session.create({})
+
+        await new Promise((resolve) => setTimeout(resolve, 100))
+
+        unsub()
+
+        expect(eventReceived).toBe(true)
+        expect(receivedInfo).toBeDefined()
+        expect(receivedInfo?.id).toBe(session.id)
+        expect(receivedInfo?.projectID).toBe(session.projectID)
+        expect(receivedInfo?.directory).toBe(session.directory)
+        expect(receivedInfo?.title).toBe(session.title)
+
+        await Session.remove(session.id)
+      },
+    })
+  })
+
+  test("session.started event should be emitted before session.updated", async () => {
+    await Instance.provide({
+      directory: projectRoot,
+      fn: async () => {
+        const events: string[] = []
+
+        const unsubStarted = Bus.subscribe(Session.Event.Started, () => {
+          events.push("started")
+        })
+
+        const unsubUpdated = Bus.subscribe(Session.Event.Updated, () => {
+          events.push("updated")
+        })
+
+        const session = await Session.create({})
+
+        await new Promise((resolve) => setTimeout(resolve, 100))
+
+        unsubStarted()
+        unsubUpdated()
+
+        expect(events).toContain("started")
+        expect(events).toContain("updated")
+        expect(events.indexOf("started")).toBeLessThan(events.indexOf("updated"))
+
+        await Session.remove(session.id)
+      },
+    })
+  })
+})