Last active
May 1, 2020 15:13
-
-
Save AutoSponge/0b75dd54f60ee49876ed939d50047ba4 to your computer and use it in GitHub Desktop.
streaming custom element
This file contains 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
class TextDecoderStream extends TransformStream { | |
constructor(encoding = 'utf8') { | |
super({ | |
start() { | |
this.decoder = new TextDecoder(encoding); | |
}, | |
transform(chunk, controller) { | |
controller.enqueue(this.decoder.decode(chunk, { stream: true })); | |
}, | |
}); | |
} | |
} | |
class HTMLWritableStream extends WritableStream { | |
constructor(sink, signal = {}) { | |
super({ | |
write(chunk) { | |
if (signal.aborted) return; | |
return new Promise((resolve) => { | |
requestAnimationFrame(() => { | |
sink.write(chunk); | |
resolve(); | |
}); | |
}); | |
}, | |
close() { | |
sink.close(); | |
}, | |
abort() { | |
this.close(); | |
}, | |
}); | |
} | |
} | |
class X extends HTMLElement { | |
connectedCallback() { | |
const shadowRoot = this.attachShadow({ mode: 'open' }); | |
shadowRoot.innerHTML = `<button type="button">stop</button>`; | |
const button = shadowRoot.querySelector('button'); | |
const controller = new AbortController(); | |
const { signal, abort } = controller; | |
button.addEventListener('click', abort.bind(controller)); | |
const sink = document.implementation.createHTMLDocument('shadow-stream'); | |
sink.open(); | |
sink.write('<div style="height: 500px; overflow: scroll;">'); | |
shadowRoot.appendChild(document.adoptNode(sink.body.firstChild)); | |
const decoder = new TextDecoderStream(); | |
const writableStream = new HTMLWritableStream(sink, signal); | |
fetch('http://localhost:4000/api/html', { signal }) | |
.then((res) => { | |
res.body.pipeThrough(decoder).pipeTo(writableStream); | |
}) | |
.catch(console.log); | |
} | |
} | |
customElements.define('x-elm', X); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment