UNPKG

@versatiles/google-cloud

Version:
117 lines (116 loc) 4.17 kB
import { ENCODINGS, acceptEncoding, findBestEncoding } from './encoding.js'; import { recompress } from './recompress.js'; import { ResponseHeaders } from './response_headers.js'; var ResponderState; (function (ResponderState) { ResponderState[ResponderState["Initialised"] = 0] = "Initialised"; ResponderState[ResponderState["HeaderSend"] = 1] = "HeaderSend"; ResponderState[ResponderState["Finished"] = 2] = "Finished"; })(ResponderState || (ResponderState = {})); /** * Class defining the structure and methods of a Responder. */ export class Responder { #options; #responderState; #time; #responseHeaders; constructor(options) { this.#time = Date.now(); this.#options = options; this.#responderState = ResponderState.Initialised; this.#responseHeaders = new ResponseHeaders(); } get fastRecompression() { return this.#options.fastRecompression; } get headers() { return this.#responseHeaders; } get verbose() { return this.#options.verbose; } get requestNo() { return this.#options.requestNo; } async respond(content, contentMIME, contentEncoding) { this.headers.set('content-type', contentMIME); ENCODINGS[contentEncoding].setEncodingHeader(this.#responseHeaders); if (typeof content === 'string') content = Buffer.from(content); this.log('respond'); await recompress(this, content); } error(code, message) { this.log(`error ${code}: ${message}`); this.#options.response .writeHead(code, { 'content-type': 'text/plain' }) .end(message); } write(buffer, callback) { if (this.#responderState < ResponderState.HeaderSend) throw Error('Headers not send yet'); this.#options.response.write(buffer, error => { if (error) throw Error(); callback(); }); } end(bufferOrCallback, maybeCallback) { if (this.#responderState < ResponderState.HeaderSend) throw Error('Headers not send yet'); if (this.#responderState >= ResponderState.Finished) throw Error('already ended'); if (Buffer.isBuffer(bufferOrCallback)) { const buffer = bufferOrCallback; const callback = maybeCallback; if (callback !== undefined) { this.#options.response.end(buffer, () => { this.#responderState = ResponderState.Finished; callback(); }); } else { return new Promise(resolve => this.#options.response.end(buffer, () => { this.#responderState = ResponderState.Finished; resolve(); })); } } else { const callback = bufferOrCallback; if (callback !== undefined) { this.#options.response.end(() => { this.#responderState = ResponderState.Finished; callback(); }); } else { return new Promise(resolve => this.#options.response.end(() => { this.#responderState = ResponderState.Finished; resolve(); })); } } } sendHeaders(status) { if (this.#responderState >= ResponderState.HeaderSend) throw Error('Headers already send'); const headers = this.#responseHeaders.getHeaders(); this.#responseHeaders.lock(); this.#options.response.writeHead(status, headers); this.#responderState = ResponderState.HeaderSend; } acceptEncoding(encoding) { return acceptEncoding(this.#options.requestHeaders, encoding); } findBestEncoding() { return findBestEncoding(this.#options.requestHeaders); } log(message) { if (!this.#options.verbose) return; const time = Date.now() - this.#time; console.log(` #${this.#options.requestNo} (${time}ms) ${message}`); } }