- From: Morgan Barrett <notifications@github.com>
- Date: Thu, 17 Dec 2020 16:04:13 -0800
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/issues/1097@github.com>
I was hoping to start a discussion about the class `BufferTransformer` that I've just mocked up. Is this an antipattern? Could this be a useful helper class in the spec? ### BufferTransformer ```typescript class Lock { promise: Promise<void>; open : () => void; close : () => void; constructor(){ (this.close = () => this.promise = new Promise(r => this.open = r ) )(); } } class BufferTransformer<I, O> implements Transformer<I[], O[]> { private buffer: I[] = []; private lock: Lock = new Lock(); private terminator: I; constructor(terminator: I){ this.terminator = terminator; } transform(chunk: I[]){ this.buffer = this.buffer.concat(chunk); this.lock.open(); } flush(){ this.lock.open(); } private async has(i: number): Promise<boolean> { if(this.buffer.length > i) return true; this.lock.close(); await this.lock.promise; return this.buffer.length > i; } async read(): Promise<I> { return await this.has(0) ? this.buffer.shift() : this.terminator; } async peek(i): Promise<I> { return await this.has(i) ? this.buffer[i] : this.terminator; } reconsume(i: I){ this.buffer.unshift(i); } } ``` An example of its usage is shown below, it takes a stream of characters, reads an unknown amount of them and enqueues only 1 Token. This seems to be the opposite of how I've seen a transformer used, where a fixed buffer of data is given to the transformer and an unknown amount of things are then queued. ### TokenizerTransformer ```typescript class TokenizerTransformer extends BufferTransformer<string, Token> { async start(controller){ let token: Token; while(token = await this.consumeToken()){ controller.enqueue(token); } } async consumeToken(): Promise<Token>{ await this.consumeComments(); let c = await this.read(); if(c === "") return; if(isWhitespace(c)){ while(isWhitespace(await this.peek(0))){ await this.read(); } return {type: TokenType.whitespace}; } if(isDigit(c)){ this.reconsume(c); return this.consumeNumeric(); } ... } ... } ``` And another thing I was curious about is if I wanted to run this process on a string, is there no utility function or easier way than below to start the process? ```typescript const stringToStream = str => new ReadableStream<string>({ start(controller){ str.split("").forEach(c => controller.enqueue(c) ); controller.close(); } }); stringToStream("foo").pipeThrough(new TokenizerTransformer) ```` -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/whatwg/streams/issues/1097
Received on Friday, 18 December 2020 00:04:25 UTC