-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathhtml-response.ts
More file actions
49 lines (41 loc) · 1.96 KB
/
Copy pathhtml-response.ts
File metadata and controls
49 lines (41 loc) · 1.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { asyncIterableToStream } from 'https://ghuc.cc/qwtel/whatwg-stream-to-async-iter/index.ts';
import { aMap, aJoin, promiseToAsyncIterable } from './iter.ts';
import type { HTML } from './html.ts';
const isCFWorkers = (<any>self.navigator)?.userAgent?.includes('Cloudflare-Workers')
|| !('TextEncoderStream' in self)
|| !('ReadableStream' in self)
|| !('pipeThrough' in ReadableStream.prototype)
class DefaultHTMLResponse extends Response {
static contentType = 'text/html;charset=UTF-8';
constructor(html: HTML, init?: ResponseInit) {
super(asyncIterableToStream(html).pipeThrough(new TextEncoderStream()), init);
this.headers.set('Content-Type', DefaultHTMLResponse.contentType);
}
}
export class CFWorkersHTMLResponse extends Response {
static contentType = 'text/html;charset=UTF-8';
constructor(html: HTML, init?: ResponseInit) {
const encoder = new TextEncoder();
const encode = aMap<string, Uint8Array>(x => encoder.encode(x));
super(asyncIterableToStream(encode(html)), init);
this.headers.set('Content-Type', CFWorkersHTMLResponse.contentType);
}
}
// CF Workers doesn't support non-binary Transform Streams,
// so we use a version that does the byte encoding in a async iterator instead:
export const HTMLResponse: typeof DefaultHTMLResponse = isCFWorkers
? CFWorkersHTMLResponse
: DefaultHTMLResponse;
/**
* If for any reason you don't want to use streaming response bodies,
* you can use this class instead, which will buffer the entire body before releasing it to the network.
* Note that headers will still be sent immediately.
*/
export class BufferedHTMLResponse extends Response {
static contentType = 'text/html;charset=UTF-8';
constructor(html: HTML, init?: ResponseInit) {
const bufferedHTML = aJoin(html).then(str => new TextEncoder().encode(str));
super(asyncIterableToStream(promiseToAsyncIterable(bufferedHTML)), init);
this.headers.set('Content-Type', BufferedHTMLResponse.contentType);
}
}