feat(web): add basic past-session search (round 1)
This commit is contained in:
@@ -21,6 +21,26 @@ function fakeApi(overrides: Partial<{ muxFrames: MuxFrame[]; hostFrames: HostFra
|
||||
if (overrides.crashOn === 'session.list') throw new Error('impl crashed')
|
||||
return { rpcId: request.rpcId, result: { ok: true, value: { items: [] } } }
|
||||
},
|
||||
async search(request, signal) {
|
||||
if (request.payload.query === 'hang') {
|
||||
if (!signal.aborted) {
|
||||
await new Promise<void>((resolve) => {
|
||||
signal.addEventListener('abort', () => { resolve() }, { once: true })
|
||||
})
|
||||
}
|
||||
return {
|
||||
rpcId: request.rpcId,
|
||||
result: { ok: false, error: { code: 'cancelled', message: 'aborted', details: {} } },
|
||||
}
|
||||
}
|
||||
return {
|
||||
rpcId: request.rpcId,
|
||||
result: {
|
||||
ok: true,
|
||||
value: { items: [{ sessionId: 's1' as never, snippet: 'fixture match' }], hasMore: false },
|
||||
},
|
||||
}
|
||||
},
|
||||
async create(request) {
|
||||
return { rpcId: request.rpcId, result: { ok: true, value: { sessionId: 's-new' as never } } }
|
||||
},
|
||||
@@ -124,6 +144,10 @@ describe('unary round trip (handler ⇄ client, no network)', () => {
|
||||
|
||||
it('covers create/prompt/cancel/describe passthrough', async () => {
|
||||
const c = client()
|
||||
expect((await c.sessions.search({ query: 'fixture' })).result).toEqual({
|
||||
ok: true,
|
||||
value: { items: [{ sessionId: 's1', snippet: 'fixture match' }], hasMore: false },
|
||||
})
|
||||
expect((await c.sessions.create({})).result.ok).toBe(true)
|
||||
expect((await c.sessions.prompt({ sessionId: 's' as never, mode: 'queue', content: [{ type: 'text', text: 'x' }] })).result.ok).toBe(true)
|
||||
expect((await c.sessions.cancel({ sessionId: 's' as never })).result.ok).toBe(true)
|
||||
@@ -155,6 +179,29 @@ describe('unary round trip (handler ⇄ client, no network)', () => {
|
||||
expect(parsed.rpcId).toBe('r-sig')
|
||||
expect(parsed.result.error?.code).toBe('cancelled')
|
||||
})
|
||||
|
||||
it('propagates the carrier Request signal into session.search', async () => {
|
||||
const handler = toFetchHandler(fakeApi())
|
||||
const controller = new AbortController()
|
||||
const body = JSON.stringify({
|
||||
type: 'client-request',
|
||||
rpcId: 'r-search-sig',
|
||||
method: 'session.search',
|
||||
payload: { query: 'hang' },
|
||||
})
|
||||
const pending = handler.fetch(new Request(
|
||||
'http://x/api/session.search',
|
||||
{ method: 'POST', body, signal: controller.signal },
|
||||
))
|
||||
controller.abort()
|
||||
const response = await pending
|
||||
const parsed = await response.json() as {
|
||||
rpcId: string
|
||||
result: { error?: { code: string } }
|
||||
}
|
||||
expect(parsed.rpcId).toBe('r-search-sig')
|
||||
expect(parsed.result.error?.code).toBe('cancelled')
|
||||
})
|
||||
})
|
||||
|
||||
describe('handler carrier-layer statuses', () => {
|
||||
|
||||
Reference in New Issue
Block a user