Created
April 25, 2018 13:29
-
-
Save ksm2/76bd39ce41935c8299a13436ae430964 to your computer and use it in GitHub Desktop.
WHATWG Transform Streams
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
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" | |
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<title>Text Lines Transform Stream</title> | |
<script src="Uint8ArrayToLinesOfTextTransformer.js"></script> | |
</head> | |
<body> | |
<script> | |
async function main() { | |
const ts = new TransformStream(new Uint8ArrayToLinesOfTextTransformer()) | |
const response = await fetch('https://gist.githubusercontent.com/silveira/5504078/raw/a74e3f11d33e327a100792392871186323f9b515/the_raven_by_edgar_allan_poe') | |
const rs = response.body | |
const lineStream = rs.pipeThrough(ts) | |
const reader = lineStream.getReader() | |
while (true) { | |
const { done, value } = await reader.read() | |
if (done) { | |
break | |
} | |
const p = document.createElement('p') | |
p.textContent = value | |
document.getElementById('section').appendChild(p) | |
} | |
} | |
main() | |
</script> | |
<h1>The Raven by Edgar Allan Poe</h1> | |
<section id="section"></section> | |
</body> | |
</html> |
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
declare interface Transformer<R, W> { | |
start?(controller: TransformStreamDefaultController<W>): void | |
transform?(chunk: R, controller: TransformStreamDefaultController<W>): void | |
flush?(controller: TransformStreamDefaultController<W>): void | |
} | |
declare class TransformStream<R, W> { | |
constructor(transformer: Transformer<R, W>, writableStrategy?: any, readableStrategy?: any) | |
readonly readable: ReadableStream | |
readonly writable: WritableStream | |
} | |
declare class TransformStreamDefaultController<W> { | |
enqueue(chunk: W): void | |
error(reason: Error): void | |
terminate(): void | |
readonly desiredSize: number | |
} |
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
Show hidden characters
{ | |
"compilerOptions": { | |
"target": "es2017", | |
"lib": ["es2017", "dom"] | |
} | |
} |
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 Uint8ArrayToLinesOfTextTransformer implements Transformer<Uint8Array, string> { | |
private readonly decoder: TextDecoder | |
private lastString: string | |
constructor() { | |
this.decoder = new TextDecoder() | |
this.lastString = '' | |
} | |
transform(chunk: Uint8Array, controller: TransformStreamDefaultController<string>): void { | |
// Decode the current chunk | |
const string = `${this.lastString}${this.decoder.decode(chunk)}` | |
// Extract lines from chunk | |
const lines = string.split(/\r\n|[\r\n]/g) | |
// Save last line | |
this.lastString = lines.pop() || '' | |
// Enqueue each line in the next chunk | |
for (const line of lines) { | |
controller.enqueue(line) | |
} | |
} | |
flush(controller: TransformStreamDefaultController<string>): void { | |
// Is there still a line left? Enqueue it | |
if (this.lastString) { | |
controller.enqueue(this.lastString) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment