Skip to content

Instantly share code, notes, and snippets.

@padolsey
Created May 25, 2024 08:03
Show Gist options
  • Save padolsey/9f37e98bc5f633e63e2fd825fe6985c0 to your computer and use it in GitHub Desktop.
Save padolsey/9f37e98bc5f633e63e2fd825fe6985c0 to your computer and use it in GitHub Desktop.
class TagStreamProcessor {
constructor(startTag, endTag, placeholder, processFn) {
this.startTag = startTag;
this.endTag = endTag;
this.placeholder = placeholder;
this.process = processFn;
this.buffer = '';
this.tagOpen = false;
}
async next(chunk) {
this.buffer += chunk;
let output = '';
let pos = 0;
while (pos < this.buffer.length) {
if (!this.tagOpen) {
// Check if start tag is found
const startTagIndex = this.buffer.indexOf(this.startTag, pos);
if (startTagIndex === -1) {
output += this.buffer.substring(pos);
this.buffer = output;
break;
} else {
output += this.buffer.substring(pos, startTagIndex);
pos = startTagIndex;
this.tagOpen = true;
}
}
if (this.tagOpen) {
// Check if end tag is found
const endTagIndex = this.buffer.indexOf(this.endTag, pos);
if (endTagIndex === -1) {
output += this.placeholder;
this.buffer = this.buffer.substring(pos);
break;
} else {
const tagContent = this.buffer.substring(pos + this.startTag.length, endTagIndex);
const processedContent = await this.process(tagContent);
output += processedContent;
pos = endTagIndex + this.endTag.length;
this.tagOpen = false;
}
}
}
return output;
}
}
async function processFormContent(content) {
// Simulate processing delay
await new Promise(resolve => setTimeout(resolve, 1000));
return `Rendered Form: ${content}`;
}
const formProcessor = new TagStreamProcessor('<form>', '</form>', '(_OUR_WAITING_TOKEN_)', processFormContent);
async function simulateClientRendering(chunks) {
let renderedOutput = '';
for (const chunk of chunks) {
renderedOutput += await formProcessor.next(chunk);
console.log('Client sees:', renderedOutput);
}
}
// Simulating the incoming stream of chunks
simulateClientRendering([
"Here is some text ",
"<form>Input your",
" name: <input",
" type='text'/></form> and more text follows."
]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment