Files
orca/src/main/shell-ready-marker-scanner.ts
T

87 lines
2.2 KiB
TypeScript

export const SHELL_READY_MARKER_PREFIX = '\x1b]777;orca-shell-ready'
export type ShellReadyScanState = {
matchPos: number
heldBytes: string
}
export type ShellReadyScanResult = {
output: string
matched: boolean
postMarkerBytesObserved: boolean
}
type ShellReadyBoundaryScanResult = ShellReadyScanResult & {
postMarkerOutputIndex: number | null
}
export function createShellReadyScanState(): ShellReadyScanState {
return { matchPos: 0, heldBytes: '' }
}
export function drainShellReadyHeldBytes(state: ShellReadyScanState): string {
const heldBytes = state.heldBytes
state.heldBytes = ''
state.matchPos = 0
return heldBytes
}
export function scanForShellReadyBoundary(
state: ShellReadyScanState,
data: string
): ShellReadyBoundaryScanResult {
let output = ''
for (let i = 0; i < data.length; i += 1) {
const ch = data[i] as string
if (state.matchPos < SHELL_READY_MARKER_PREFIX.length) {
if (ch === SHELL_READY_MARKER_PREFIX[state.matchPos]) {
state.heldBytes += ch
state.matchPos += 1
} else {
output += state.heldBytes
state.heldBytes = ''
state.matchPos = 0
if (ch === SHELL_READY_MARKER_PREFIX[0]) {
state.heldBytes = ch
state.matchPos = 1
} else {
output += ch
}
}
} else if (ch === '\x07') {
const remaining = data.slice(i + 1)
state.heldBytes = ''
state.matchPos = 0
return {
output: output + remaining,
matched: true,
postMarkerBytesObserved: remaining.length > 0,
postMarkerOutputIndex: output.length
}
} else {
output += state.heldBytes
state.heldBytes = ''
state.matchPos = 0
if (ch === SHELL_READY_MARKER_PREFIX[0]) {
state.heldBytes = ch
state.matchPos = 1
} else {
output += ch
}
}
}
return {
output,
matched: false,
postMarkerBytesObserved: false,
postMarkerOutputIndex: null
}
}
export function scanForShellReady(state: ShellReadyScanState, data: string): ShellReadyScanResult {
const { postMarkerOutputIndex: _, ...result } = scanForShellReadyBoundary(state, data)
return result
}