Browse Source

fixup! refactor(interaction): move Approval and Question into UI owners

imccyu 1 month ago
parent
commit
55dd6320d2

+ 6 - 4
packages/client/ui-approval/src/client/index.ts

@@ -36,7 +36,7 @@ async function answerApproval(
   owner: ClientContext,
   request: ClientApprovalRequest,
   next: ClientApprovalNext,
-  attend: (pending: PendingApproval) => () => void,
+  registerPendingInteraction: (pending: PendingApproval) => () => void,
 ): Promise<ClientApprovalOutcome> {
   const sessionId = ctx.sessions.scopeOf(owner)
   if (sessionId === undefined) return next()
@@ -48,7 +48,7 @@ async function answerApproval(
     ...(request.reason === undefined ? {} : { reason: request.reason }),
     ...(request.signal === undefined ? {} : { signal: request.signal }),
   })
-  const remove = attend(pending)
+  const remove = registerPendingInteraction(pending)
   try {
     return await pending.result
   } finally {
@@ -62,7 +62,9 @@ async function answerApproval(
  */
 export function apply(ctx: ClientContext): void {
   ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ui-approval: dictionaries')
-  const attend = ctx.uiSession.attend<PendingApproval>(() => 0)
+  const registerPendingInteraction = ctx.uiSession.registerPendingInteraction<PendingApproval>(
+    () => 0,
+  )
   ctx.slots.inject('conversation.composer', () => ctx.slots.register({
     name: 'conversation.composer',
     priority: 1,
@@ -74,6 +76,6 @@ export function apply(ctx: ClientContext): void {
     },
   }, ApprovalPanel))
   ctx.remote.$on('approval/request', function (request, next) {
-    return answerApproval(ctx, this, request, next, attend)
+    return answerApproval(ctx, this, request, next, registerPendingInteraction)
   })
 }

+ 4 - 4
packages/client/ui-approval/tests/ui-approval.client.spec.tsx

@@ -28,7 +28,7 @@ interface PluginBench {
   readonly ctx: Context
   readonly listener: ApprovalListener
   readonly pending: { getSnapshot(): readonly PendingApproval[] }
-  readonly attend: ReturnType<typeof vi.fn>
+  readonly registerPendingInteraction: ReturnType<typeof vi.fn>
   readonly disposeSlot: ReturnType<typeof vi.fn>
   readonly disposeLocale: ReturnType<typeof vi.fn>
   readonly register: ReturnType<typeof vi.fn>
@@ -53,7 +53,7 @@ function setupPlugin(): PluginBench {
   const disposeSlot = vi.fn()
   const disposeLocale = vi.fn()
   let pending: readonly PendingApproval[] = []
-  const attend = vi.fn((_precedence: (value: PendingApproval) => number) => (
+  const registerPendingInteraction = vi.fn((_precedence: (value: PendingApproval) => number) => (
     value: PendingApproval,
   ) => {
     pending = [...pending, value]
@@ -77,7 +77,7 @@ function setupPlugin(): PluginBench {
     },
   } as never)
   ctx.provide('sessions', { scopeOf } as never)
-  ctx.provide('uiSession', { attend } as never)
+  ctx.provide('uiSession', { registerPendingInteraction } as never)
   ctx.provide('slots', { inject: injectSlot, register } as never)
   ctx.provide('locale', {
     register: vi.fn(() => disposeLocale),
@@ -89,7 +89,7 @@ function setupPlugin(): PluginBench {
     ctx,
     listener,
     pending: { getSnapshot: () => pending },
-    attend,
+    registerPendingInteraction,
     disposeSlot,
     disposeLocale,
     register,

+ 2 - 2
packages/client/ui-session/src/client/index.ts

@@ -282,7 +282,7 @@ export class UiSession extends Service {
    * @param precedence - deterministic cross-domain precedence; larger values win.
    * @returns a function that publishes one exact interaction until its disposer runs.
    */
-  attend<T extends SessionPendingInteractionBase>(
+  registerPendingInteraction<T extends SessionPendingInteractionBase>(
     precedence: (interaction: T) => number,
   ): (interaction: T) => () => void {
     const domain = new PendingInteractionDomain(precedence, () => {
@@ -297,7 +297,7 @@ export class UiSession extends Service {
         if (index !== -1) this.pendingDomains.splice(index, 1)
         this.publishPendingInteractions()
       }
-    }, 'uiSession.attend()')
+    }, 'uiSession.registerPendingInteraction()')
     return interaction => domain.publish(interaction)
   }
 

+ 13 - 9
packages/client/ui-session/tests/ui-session.client.spec.ts

@@ -380,8 +380,10 @@ describe('UiSession pending interactions', () => {
     const id = sessionId('s1')
     const listener = vi.fn()
     const off = service.pendingInteractions.subscribe(listener)
-    const attendApproval = service.attend<SessionPendingInteractionBase>(() => 0)
-    const attendQuestion = service.attend<SessionPendingInteractionBase>(
+    const registerApproval = service.registerPendingInteraction<SessionPendingInteractionBase>(
+      () => 0,
+    )
+    const registerQuestion = service.registerPendingInteraction<SessionPendingInteractionBase>(
       interaction => interaction.kind === 'plan-review' ? 2 : 1,
     )
     listener.mockClear()
@@ -390,13 +392,13 @@ describe('UiSession pending interactions', () => {
     const duplicate = { key: 'approval:2', kind: 'approval', sessionId: id }
     const question = { key: 'question:1', kind: 'question', sessionId: id }
     const plan = { key: 'question:2', kind: 'plan-review', sessionId: id }
-    const removeApproval = attendApproval(approval)
+    const removeApproval = registerApproval(approval)
     expect(service.pendingInteractions.getSnapshot().get(id)).toBe(approval)
-    const removeDuplicate = attendApproval(duplicate)
+    const removeDuplicate = registerApproval(duplicate)
     expect(service.pendingInteractions.getSnapshot().get(id)).toBe(duplicate)
-    const removeQuestion = attendQuestion(question)
+    const removeQuestion = registerQuestion(question)
     expect(service.pendingInteractions.getSnapshot().get(id)).toBe(question)
-    const removePlan = attendQuestion(plan)
+    const removePlan = registerQuestion(plan)
     expect(service.pendingInteractions.getSnapshot().get(id)).toBe(plan)
 
     removeQuestion()
@@ -414,10 +416,12 @@ describe('UiSession pending interactions', () => {
     const ctx = new Context()
     const bench = createSessionsBench(ctx)
     const service = createUiSession(ctx, bench)
-    const attend = service.attend<SessionPendingInteractionBase>(() => 1)
+    const registerPendingInteraction = service.registerPendingInteraction<SessionPendingInteractionBase>(
+      () => 1,
+    )
     const interaction = { key: 'question:1', kind: 'question', sessionId: sessionId('s1') }
-    const remove = attend(interaction)
-    expect(() => { attend(interaction) })
+    const remove = registerPendingInteraction(interaction)
+    expect(() => { registerPendingInteraction(interaction) })
       .toThrow("ui-session: duplicate pending interaction key 'question:1'")
 
     const failure = new Error('pending subscriber failed')

+ 4 - 4
packages/client/ui-user-questions/src/client/index.ts

@@ -55,12 +55,12 @@ async function answerQuestion(
   owner: ClientContext,
   request: ClientQuestionRequest,
   next: ClientQuestionNext,
-  attend: (pending: PendingQuestion) => () => void,
+  registerPendingInteraction: (pending: PendingQuestion) => () => void,
 ): Promise<ClientQuestionAnswer> {
   const sessionId = ctx.sessions.scopeOf(owner)
   if (sessionId === undefined) return next()
   const pending = new PendingQuestion(sessionId, request.questions, request.signal)
-  const remove = attend(pending)
+  const remove = registerPendingInteraction(pending)
   try {
     return await pending.result
   } finally {
@@ -76,7 +76,7 @@ async function answerQuestion(
  */
 export function apply(ctx: ClientContext): void {
   ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ui-user-questions: dictionaries')
-  const attend = ctx.uiSession.attend<PendingQuestion>(
+  const registerPendingInteraction = ctx.uiSession.registerPendingInteraction<PendingQuestion>(
     pending => pending.kind === 'plan-review' ? 2 : 1,
   )
   ctx.slots.inject('conversation.composer', () => ctx.slots.register(
@@ -89,6 +89,6 @@ export function apply(ctx: ClientContext): void {
     QuestionComposer,
   ))
   ctx.remote.$on('user-questions/request', function (request, next) {
-    return answerQuestion(ctx, this, request, next, attend)
+    return answerQuestion(ctx, this, request, next, registerPendingInteraction)
   })
 }

+ 3 - 3
packages/client/ui-user-questions/tests/browser-plugin.client.spec.ts

@@ -50,13 +50,13 @@ async function bench(declare = true) {
   )[SESSION_SCOPE])
   ctx.provide('sessions', { scopeOf } as never)
   let pending: readonly PendingQuestion[] = []
-  const attend = vi.fn((_precedence: (value: PendingQuestion) => number) => (
+  const registerPendingInteraction = vi.fn((_precedence: (value: PendingQuestion) => number) => (
     value: PendingQuestion,
   ) => {
     pending = [...pending, value]
     return () => { pending = pending.filter(candidate => candidate !== value) }
   })
-  ctx.provide('uiSession', { attend } as never)
+  ctx.provide('uiSession', { registerPendingInteraction } as never)
   let listener: QuestionListener | undefined
   const on = vi.fn((event: string, value: QuestionListener) => {
     expect(event).toBe('user-questions/request')
@@ -81,7 +81,7 @@ async function bench(declare = true) {
     agent,
     scopeOf,
     pending: { getSnapshot: () => pending },
-    attend,
+    registerPendingInteraction,
     on,
     fiber,
     invoke,