Created
November 2, 2023 14:20
-
-
Save theskcd/bcc1dd9f677b00716bf621a8f2b5cd8f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum AnswerStreamContext { | |
BeforeCodeBlock, | |
InCodeBlock, | |
AfterCodeBlock, | |
} | |
interface AnswerStreamLine { | |
line: string; | |
context: AnswerStreamContext; | |
} | |
class AnswerSplitOnNewLineAccumulator { | |
accumulator: string; | |
runningAnswer: string; | |
lines: AnswerStreamLine[]; | |
codeBlockStringFound: boolean; | |
runningState: AnswerStreamContext; | |
constructor() { | |
this.accumulator = ''; | |
this.runningAnswer = ''; | |
this.lines = []; | |
this.codeBlockStringFound = false; | |
this.runningState = AnswerStreamContext.BeforeCodeBlock; | |
} | |
addDelta(delta: string | null | undefined) { | |
if (delta === null || delta === undefined) { | |
return; | |
} | |
// When we are adding delta, we need to check if after adding the delta | |
// we get a new line, and if we do we split it on the new line and add it | |
// to our queue of events to push | |
this.accumulator = this.accumulator + delta; | |
while (true) { | |
const newLineIndex = this.accumulator.indexOf('\n'); | |
// If we found no new line, lets just break here | |
if (newLineIndex === -1) { | |
break; | |
} | |
const completeLine = this.accumulator.substring(0, newLineIndex); | |
if (/^```/.test(completeLine)) { | |
if (!this.codeBlockStringFound) { | |
this.codeBlockStringFound = true; | |
this.runningState = AnswerStreamContext.InCodeBlock; | |
} else { | |
this.runningState = AnswerStreamContext.AfterCodeBlock; | |
} | |
} | |
this.lines.push({ | |
line: completeLine, | |
context: this.runningState, | |
}); | |
// we set the accumulator to the remaining line | |
this.accumulator = this.accumulator.substring(newLineIndex + 1); | |
} | |
} | |
getLine(): AnswerStreamLine | null { | |
if (this.lines.length === 0) { | |
return null; | |
} | |
// or give back the first element of the string | |
const line = this.lines[0]; | |
// remove the first element from the array | |
this.lines = this.lines.slice(1); | |
return line; | |
} | |
getLineLength(): number { | |
return this.lines.length; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment