mirror of
https://github.com/stablyai/orca.git
synced 2026-10-25 08:04:05 +00:00
fix(mobile): serialize accessory key presses
This commit is contained in:
@@ -60,6 +60,28 @@ describe('terminal accessory repeat', () => {
|
||||
expect(send).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('serializes a new press behind the previous press send', async () => {
|
||||
vi.useFakeTimers()
|
||||
const first = deferred()
|
||||
const sent: string[] = []
|
||||
const send = vi.fn((input: string) => {
|
||||
sent.push(input)
|
||||
return input === 'down' ? first.promise.then(() => true) : Promise.resolve(true)
|
||||
})
|
||||
const repeat = createTerminalAccessoryRepeatController<string>()
|
||||
|
||||
repeat.start('down', send)
|
||||
repeat.stop()
|
||||
repeat.start('up', send)
|
||||
|
||||
expect(sent).toEqual(['down'])
|
||||
|
||||
first.resolve()
|
||||
await vi.advanceTimersByTimeAsync(0)
|
||||
expect(sent).toEqual(['down', 'up'])
|
||||
repeat.stop()
|
||||
})
|
||||
|
||||
it('stops repeating when the transport rejects a send', async () => {
|
||||
vi.useFakeTimers()
|
||||
const send = vi.fn(() => Promise.reject(new Error('disconnected')))
|
||||
|
||||
@@ -19,6 +19,28 @@ export function createTerminalAccessoryRepeatSender<TInput>(
|
||||
export function createTerminalAccessoryRepeatController<TInput>() {
|
||||
let generation = 0
|
||||
let timer: ReturnType<typeof setTimeout> | null = null
|
||||
let dispatchTail: Promise<void> | null = null
|
||||
|
||||
const dispatch = (
|
||||
input: TInput,
|
||||
send: TerminalAccessoryRepeatSender<TInput>,
|
||||
activeGeneration: number
|
||||
) => {
|
||||
const sendIfCurrent = () =>
|
||||
generation === activeGeneration ? send(input) : Promise.resolve(false)
|
||||
const result = dispatchTail ? dispatchTail.then(sendIfCurrent) : sendIfCurrent()
|
||||
const settled = result.then(
|
||||
() => undefined,
|
||||
() => undefined
|
||||
)
|
||||
dispatchTail = settled
|
||||
void settled.then(() => {
|
||||
if (dispatchTail === settled) {
|
||||
dispatchTail = null
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
const stop = () => {
|
||||
generation += 1
|
||||
@@ -39,7 +61,7 @@ export function createTerminalAccessoryRepeatController<TInput>() {
|
||||
if (generation !== activeGeneration) {
|
||||
return
|
||||
}
|
||||
void send(input).then(
|
||||
void dispatch(input, send, activeGeneration).then(
|
||||
(sent) => {
|
||||
if (sent && generation === activeGeneration) {
|
||||
schedule(TERMINAL_ACCESSORY_REPEAT_INTERVAL_MS)
|
||||
@@ -50,7 +72,7 @@ export function createTerminalAccessoryRepeatController<TInput>() {
|
||||
}, delayMs)
|
||||
}
|
||||
|
||||
void send(input).then(
|
||||
void dispatch(input, send, activeGeneration).then(
|
||||
(sent) => {
|
||||
if (sent && generation === activeGeneration) {
|
||||
schedule(
|
||||
|
||||
Reference in New Issue
Block a user