Files
orca/src/shared/native-chat-transcript-retention.test.ts
T
NeilandOrca b3965f3205 perf(native-chat): suspend hidden transcript streams (#13622)
* perf(native-chat): suspend hidden transcript streams

* fix(native-chat): keep assembly renders pure

* fix(native-chat): keep a transient error from stranding a revealed chat

- An error snapshot frame no longer latches frameArrived, so the in-flight
  read can still seed the pane instead of leaving it on the error surface.
- Retained history is shown over a full-pane read error for the same source.
- The paged read window survives a hide/reveal; only a source change resets it.

Co-authored-by: Orca <help@stably.ai>

* fix(mobile): match the trimmed native-chat retention signature

The shared retention type no longer takes `loading`, so mobile's call was an
excess-property error that broke the mobile typecheck job. Dropping it also
lets mobile inherit the desktop behavior: a stream error or dropped client
keeps the last transcript instead of swapping it for the error empty state.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-11 01:27:25 -07:00

42 lines
1.7 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import type { NativeChatMessage } from './native-chat-types'
import {
createNativeChatTranscriptRetention,
encodeNativeChatTranscriptIdentity
} from './native-chat-transcript-retention'
function message(id: string): NativeChatMessage {
return { id, role: 'assistant', blocks: [], timestamp: 0, source: 'transcript' }
}
describe('native chat transcript retention', () => {
it('holds only the latest settled transcript for the same identity while unsettled', () => {
const retention = createNativeChatTranscriptRetention()
const first = [message('first')]
const second = [message('second')]
retention.capture('source-a', first)
expect(retention.visible({ identity: 'source-a', messages: [], settled: false })).toBe(first)
expect(retention.visible({ identity: 'source-b', messages: [], settled: false })).toEqual([])
retention.capture('source-b', second)
expect(retention.visible({ identity: 'source-a', messages: [], settled: false })).toEqual([])
expect(retention.visible({ identity: 'source-b', messages: [], settled: false })).toBe(second)
})
it('never substitutes retained history for a settled read', () => {
const retention = createNativeChatTranscriptRetention()
const retained = [message('retained')]
const fresh = [message('fresh')]
retention.capture('source', retained)
expect(retention.visible({ identity: 'source', messages: fresh, settled: true })).toBe(fresh)
})
it('encodes identity components without delimiter collisions', () => {
expect(encodeNativeChatTranscriptIdentity(['host\0workspace', 'session'])).not.toBe(
encodeNativeChatTranscriptIdentity(['host', 'workspace\0session'])
)
})
})