-
-
Notifications
You must be signed in to change notification settings - Fork 652
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: implement stream api utility-class * test: write the test of StreamApi * feat: implement `c.stream` to context * test: write the test of `c.stream()` * chore: denoify * fix: extend for bytes, remove buffer system, add pipe and log interface * test: update test about log, pipe, etc... for streaming API * feat: extend textStream interface, remove utf-8 content-type * test: add test about `c.textStream` * refactor: update some args name * chore: denoify * fix: for deno, removed the optional parameter of `write` and `writeln` * chore: denoify * feat: add charset for textStream content-type header * fix: rename textStream to streamText * fix: reuse stream in streamText for bundle size * feat: add `stream.wait()` api * chore: denoify * fix: rename `stream.wait` to `stream.sleep` * test: use `stream.sleep` for waiting * refactor: remove `stream.log` * fix: remove preHeader from `c.stream()` and use `transfer-encoding` only `c.streamText()` * chore: denoify * refactoring: remove preHeader initialize * test: reduce sleep duration * chore: denoify Co-authored-by: Glen Maddern <glenmaddern@gmail.com>
- Loading branch information
Showing
6 changed files
with
235 additions
and
0 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
export class StreamingApi { | ||
private writer: WritableStreamDefaultWriter<Uint8Array> | ||
private encoder: TextEncoder | ||
private writable: WritableStream | ||
|
||
constructor(writable: WritableStream) { | ||
this.writable = writable | ||
this.writer = writable.getWriter() | ||
this.encoder = new TextEncoder() | ||
} | ||
|
||
async write(input: Uint8Array | string) { | ||
if (typeof input === 'string') { | ||
input = this.encoder.encode(input) | ||
} | ||
await this.writer.write(input) | ||
return this | ||
} | ||
|
||
async writeln(input: string) { | ||
await this.write(input + '\n') | ||
return this | ||
} | ||
|
||
sleep(ms: number) { | ||
return new Promise((res) => setTimeout(res, ms)) | ||
} | ||
|
||
async close() { | ||
await this.writer.close() | ||
} | ||
|
||
async pipe(body: ReadableStream) { | ||
this.writer.releaseLock() | ||
await body.pipeTo(this.writable, { preventClose: true }) | ||
this.writer = this.writable.getWriter() | ||
} | ||
} |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { StreamingApi } from './stream' | ||
|
||
describe('StreamingApi', () => { | ||
it('write(string)', async () => { | ||
const { readable, writable } = new TransformStream() | ||
const api = new StreamingApi(writable) | ||
const reader = readable.getReader() | ||
api.write('foo') | ||
expect((await reader.read()).value).toEqual(new TextEncoder().encode('foo')) | ||
api.write('bar') | ||
expect((await reader.read()).value).toEqual(new TextEncoder().encode('bar')) | ||
}) | ||
|
||
it('write(Uint8Array)', async () => { | ||
const { readable, writable } = new TransformStream() | ||
const api = new StreamingApi(writable) | ||
const reader = readable.getReader() | ||
api.write(new Uint8Array([1, 2, 3])) | ||
expect((await reader.read()).value).toEqual(new Uint8Array([1, 2, 3])) | ||
api.write(new Uint8Array([4, 5, 6])) | ||
expect((await reader.read()).value).toEqual(new Uint8Array([4, 5, 6])) | ||
}) | ||
|
||
it('writeln(string)', async () => { | ||
const { readable, writable } = new TransformStream() | ||
const api = new StreamingApi(writable) | ||
const reader = readable.getReader() | ||
api.writeln('foo') | ||
expect((await reader.read()).value).toEqual(new TextEncoder().encode('foo\n')) | ||
api.writeln('bar') | ||
expect((await reader.read()).value).toEqual(new TextEncoder().encode('bar\n')) | ||
}) | ||
|
||
it('pipe()', async () => { | ||
const { readable: senderReadable, writable: senderWritable } = new TransformStream() | ||
|
||
// send data to readable in other scope | ||
;(async () => { | ||
const writer = senderWritable.getWriter() | ||
await writer.write(new TextEncoder().encode('foo')) | ||
await writer.write(new TextEncoder().encode('bar')) | ||
// await writer.close() | ||
})() | ||
|
||
const { readable: receiverReadable, writable: receiverWritable } = new TransformStream() | ||
|
||
const api = new StreamingApi(receiverWritable) | ||
|
||
// pipe readable to api in other scope | ||
;(async () => { | ||
await api.pipe(senderReadable) | ||
})() | ||
|
||
// read data from api | ||
const reader = receiverReadable.getReader() | ||
expect((await reader.read()).value).toEqual(new TextEncoder().encode('foo')) | ||
expect((await reader.read()).value).toEqual(new TextEncoder().encode('bar')) | ||
}) | ||
|
||
it('close()', async () => { | ||
const { readable, writable } = new TransformStream() | ||
const api = new StreamingApi(writable) | ||
const reader = readable.getReader() | ||
await api.close() | ||
expect((await reader.read()).done).toBe(true) | ||
await expect(api.write('foo')).rejects.toThrow() | ||
}) | ||
}) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
export class StreamingApi { | ||
private writer: WritableStreamDefaultWriter<Uint8Array> | ||
private encoder: TextEncoder | ||
private writable: WritableStream | ||
|
||
constructor(writable: WritableStream) { | ||
this.writable = writable | ||
this.writer = writable.getWriter() | ||
this.encoder = new TextEncoder() | ||
} | ||
|
||
async write(input: Uint8Array | string) { | ||
if (typeof input === 'string') { | ||
input = this.encoder.encode(input) | ||
} | ||
await this.writer.write(input) | ||
return this | ||
} | ||
|
||
async writeln(input: string) { | ||
await this.write(input + '\n') | ||
return this | ||
} | ||
|
||
sleep(ms: number) { | ||
return new Promise((res) => setTimeout(res, ms)) | ||
} | ||
|
||
async close() { | ||
await this.writer.close() | ||
} | ||
|
||
async pipe(body: ReadableStream) { | ||
this.writer.releaseLock() | ||
await body.pipeTo(this.writable, { preventClose: true }) | ||
this.writer = this.writable.getWriter() | ||
} | ||
} |