fix(schedule): reconcile latest master contracts
This commit is contained in:
@@ -3,9 +3,8 @@
|
||||
// one, the durable event type and JSON sidecar remain inspectable in the flow.
|
||||
|
||||
import { useMemo, useState } from 'react'
|
||||
import { IconSparkle16 } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||
import { DisclosureRow, IconSparkle16 } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||
import type { ChatViewSlotProps, EventRowOwnerProps } from '../contract/slots.ts'
|
||||
import { DisclosureRow } from './DisclosureRow.tsx'
|
||||
import css from './ContextInjectionRow.module.css'
|
||||
|
||||
/** Card props: the event owner payload plus the render site's locale seat. */
|
||||
|
||||
@@ -63,8 +63,6 @@
|
||||
"lib/index.js",
|
||||
"lib/invariant.js",
|
||||
"lib/client.js",
|
||||
"lib/types/**/*.d.ts",
|
||||
"lib/types/**/*.d.ts.map",
|
||||
"src"
|
||||
"lib/types/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ interface ReminderPresentation {
|
||||
scheduleId: string
|
||||
prompt: string
|
||||
occurrenceAt: string
|
||||
deliveryMode: 'session-local'
|
||||
}
|
||||
|
||||
/** Full Schedule row props: event owner/runtime share plus the locale seat. */
|
||||
@@ -20,12 +19,10 @@ function reminderPresentation(value: unknown): ReminderPresentation | null {
|
||||
if (typeof record['scheduleId'] !== 'string' || record['scheduleId'].length === 0) return null
|
||||
if (typeof record['prompt'] !== 'string') return null
|
||||
if (typeof record['occurrenceAt'] !== 'string' || record['occurrenceAt'].length === 0) return null
|
||||
if (record['deliveryMode'] !== 'session-local') return null
|
||||
return {
|
||||
scheduleId: record['scheduleId'],
|
||||
prompt: record['prompt'],
|
||||
occurrenceAt: record['occurrenceAt'],
|
||||
deliveryMode: record['deliveryMode'],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,7 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `conversation` is an ordering edge: its service is published after the chat
|
||||
* entry has declared `conversation.chat.eventview`.
|
||||
*/
|
||||
export const inject = ['slots', 'conversation', 'locale']
|
||||
export const inject = ['slots', 'locale']
|
||||
|
||||
/**
|
||||
* Register bilingual copy and the Schedule reminder keyed row.
|
||||
@@ -27,12 +23,12 @@ export const inject = ['slots', 'conversation', 'locale']
|
||||
*/
|
||||
export function apply(ctx: ClientContext): void {
|
||||
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ui-schedule: dictionaries')
|
||||
ctx.effect(
|
||||
ctx.slots.inject(
|
||||
'conversation.chat.eventview',
|
||||
() => ctx.slots.register({
|
||||
name: 'conversation.chat.eventview',
|
||||
key: 'schedule/change',
|
||||
locale: NS,
|
||||
}, ReminderRow),
|
||||
'ui-schedule: reminder row registration',
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Context } from 'cordis'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { LocaleService } from '@deepseek-ai/dsh-client-locale/client'
|
||||
import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import { apply, inject } from '../src/client/index.ts'
|
||||
import { ReminderRow } from '../src/client/ReminderRow.tsx'
|
||||
import { apply as nodeApply } from '../src/index.ts'
|
||||
@@ -10,41 +11,55 @@ import {
|
||||
name as invariantName,
|
||||
} from '../src/invariant.ts'
|
||||
|
||||
interface CapturedEntry {
|
||||
name: string
|
||||
key?: string
|
||||
locale?: string
|
||||
component: unknown
|
||||
}
|
||||
|
||||
function bench() {
|
||||
async function bench(declareBeforeApply = true) {
|
||||
const ctx = new Context()
|
||||
let entry: CapturedEntry | undefined
|
||||
ctx.provide('slots', {
|
||||
register(options: Omit<CapturedEntry, 'component'>, component: unknown) {
|
||||
entry = { ...options, component }
|
||||
return () => { entry = undefined }
|
||||
},
|
||||
})
|
||||
ctx.provide('conversation', {})
|
||||
await ctx.plugin(SlotsService)
|
||||
const slots = ctx.slots as unknown as {
|
||||
register: (options: object, component: unknown) => () => void
|
||||
}
|
||||
const declareHost = () => slots.register({
|
||||
name: 'root',
|
||||
children: { 'conversation.chat.eventview': { kind: 'keyed', scope: 'session' } },
|
||||
}, () => null)
|
||||
const initialHost = declareBeforeApply ? declareHost() : undefined
|
||||
ctx.provide('locale', new LocaleService(ctx))
|
||||
const fiber = ctx.plugin({ inject: [...inject], apply })
|
||||
return { ctx, fiber, entry: () => entry }
|
||||
await fiber.await()
|
||||
return {
|
||||
ctx,
|
||||
fiber,
|
||||
declareHost,
|
||||
initialHost,
|
||||
entry: () => ctx.slots.entries('conversation.chat.eventview')[0],
|
||||
}
|
||||
}
|
||||
|
||||
describe('ui-schedule browser plugin', () => {
|
||||
it('registers the keyed reminder renderer and unloads it with the fiber', async () => {
|
||||
const b = bench()
|
||||
await b.fiber.await()
|
||||
expect(b.entry()).toEqual({
|
||||
name: 'conversation.chat.eventview',
|
||||
key: 'schedule/change',
|
||||
locale: 'schedule',
|
||||
component: ReminderRow,
|
||||
})
|
||||
const b = await bench()
|
||||
expect(b.entry()?.options).toEqual({ key: 'schedule/change' })
|
||||
expect(b.entry()?.locale).toBe('schedule')
|
||||
expect(b.entry()?.component).toBe(ReminderRow)
|
||||
|
||||
await b.fiber.dispose()
|
||||
expect(b.entry()).toBeUndefined()
|
||||
b.initialHost?.()
|
||||
})
|
||||
|
||||
it('follows delayed declaration, collapse, and redeclaration until contributor disposal', async () => {
|
||||
const b = await bench(false)
|
||||
expect(b.entry()).toBeUndefined()
|
||||
|
||||
const firstHost = b.declareHost()
|
||||
expect(b.entry()?.component).toBe(ReminderRow)
|
||||
firstHost()
|
||||
expect(b.entry()).toBeUndefined()
|
||||
|
||||
const secondHost = b.declareHost()
|
||||
expect(b.entry()?.component).toBe(ReminderRow)
|
||||
await b.fiber.dispose()
|
||||
expect(b.entry()).toBeUndefined()
|
||||
secondHost()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ const invalidSidecars: ReadonlyArray<{ name: string; view: unknown }> = [
|
||||
scheduleId: null,
|
||||
prompt: 'not trusted',
|
||||
occurrenceAt: '2026-08-05T08:00:00.000Z',
|
||||
deliveryMode: 'session-local',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -28,7 +27,6 @@ const invalidSidecars: ReadonlyArray<{ name: string; view: unknown }> = [
|
||||
scheduleId: '',
|
||||
prompt: 'not trusted',
|
||||
occurrenceAt: '2026-08-05T08:00:00.000Z',
|
||||
deliveryMode: 'session-local',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -37,7 +35,6 @@ const invalidSidecars: ReadonlyArray<{ name: string; view: unknown }> = [
|
||||
scheduleId: 'schedule-7',
|
||||
prompt: 7,
|
||||
occurrenceAt: '2026-08-05T08:00:00.000Z',
|
||||
deliveryMode: 'session-local',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -46,7 +43,6 @@ const invalidSidecars: ReadonlyArray<{ name: string; view: unknown }> = [
|
||||
scheduleId: 'schedule-7',
|
||||
prompt: 'not trusted',
|
||||
occurrenceAt: 7,
|
||||
deliveryMode: 'session-local',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -55,16 +51,6 @@ const invalidSidecars: ReadonlyArray<{ name: string; view: unknown }> = [
|
||||
scheduleId: 'schedule-7',
|
||||
prompt: 'not trusted',
|
||||
occurrenceAt: '',
|
||||
deliveryMode: 'session-local',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'unsupported delivery mode',
|
||||
view: {
|
||||
scheduleId: 'schedule-7',
|
||||
prompt: 'not trusted',
|
||||
occurrenceAt: '2026-08-05T08:00:00.000Z',
|
||||
deliveryMode: 'external',
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -88,7 +74,6 @@ describe('ReminderRow', () => {
|
||||
scheduleId: 'schedule-7',
|
||||
prompt: 'Check the deploy',
|
||||
occurrenceAt: '2026-08-05T08:00:00.000Z',
|
||||
deliveryMode: 'session-local',
|
||||
})} />)
|
||||
|
||||
expect(screen.getByRole('note')).toBeTruthy()
|
||||
|
||||
Reference in New Issue
Block a user