Skip to content

Instantly share code, notes, and snippets.

@AutoSponge
Last active May 1, 2020 15:13
Show Gist options
  • Select an option

  • Save AutoSponge/0b75dd54f60ee49876ed939d50047ba4 to your computer and use it in GitHub Desktop.

Select an option

Save AutoSponge/0b75dd54f60ee49876ed939d50047ba4 to your computer and use it in GitHub Desktop.

Revisions

  1. AutoSponge revised this gist May 1, 2020. 1 changed file with 0 additions and 3 deletions.
    3 changes: 0 additions & 3 deletions stream-x.js
    Original file line number Diff line number Diff line change
    @@ -9,9 +9,6 @@ class TextDecoderStream extends TransformStream {
    },
    });
    }
    get encoding() {
    return this.decoder.encoding;
    }
    }

    class HTMLWritableStream extends WritableStream {
  2. AutoSponge revised this gist May 1, 2020. 1 changed file with 3 additions and 5 deletions.
    8 changes: 3 additions & 5 deletions stream-x.js
    Original file line number Diff line number Diff line change
    @@ -18,23 +18,21 @@ class HTMLWritableStream extends WritableStream {
    constructor(sink, signal = {}) {
    super({
    write(chunk) {
    if (this.signal.aborted) return;
    if (signal.aborted) return;
    return new Promise((resolve) => {
    requestAnimationFrame(() => {
    this.sink.write(chunk);
    sink.write(chunk);
    resolve();
    });
    });
    },
    close() {
    this.sink.close();
    sink.close();
    },
    abort() {
    this.close();
    },
    });
    this.sink = sink;
    this.signal = signal;
    }
    }

  3. AutoSponge revised this gist May 1, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion stream-x.js
    Original file line number Diff line number Diff line change
    @@ -45,7 +45,7 @@ class X extends HTMLElement {
    const button = shadowRoot.querySelector('button');

    const controller = new AbortController();
    const { signal, abort } = this.controller;
    const { signal, abort } = controller;
    button.addEventListener('click', abort.bind(controller));

    const sink = document.implementation.createHTMLDocument('shadow-stream');
  4. AutoSponge created this gist May 1, 2020.
    67 changes: 67 additions & 0 deletions stream-x.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    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 }));
    },
    });
    }
    get encoding() {
    return this.decoder.encoding;
    }
    }

    class HTMLWritableStream extends WritableStream {
    constructor(sink, signal = {}) {
    super({
    write(chunk) {
    if (this.signal.aborted) return;
    return new Promise((resolve) => {
    requestAnimationFrame(() => {
    this.sink.write(chunk);
    resolve();
    });
    });
    },
    close() {
    this.sink.close();
    },
    abort() {
    this.close();
    },
    });
    this.sink = sink;
    this.signal = signal;
    }
    }

    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 } = this.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);