"use strict"; /* -------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ Object.defineProperty(exports, "__esModule", { value: true }); exports.WriteableStreamMessageWriter = exports.AbstractMessageWriter = exports.MessageWriter = void 0; const ral_1 = require("./ral"); const Is = require("./is"); const semaphore_1 = require("./semaphore"); const events_1 = require("./events"); const ContentLength = 'Content-Length: '; const CRLF = '\r\n'; var MessageWriter; (function (MessageWriter) { function is(value) { let candidate = value; return candidate && Is.func(candidate.dispose) && Is.func(candidate.onClose) && Is.func(candidate.onError) && Is.func(candidate.write); } MessageWriter.is = is; })(MessageWriter = exports.MessageWriter || (exports.MessageWriter = {})); class AbstractMessageWriter { constructor() { this.errorEmitter = new events_1.Emitter(); this.closeEmitter = new events_1.Emitter(); } dispose() { this.errorEmitter.dispose(); this.closeEmitter.dispose(); } get onError() { return this.errorEmitter.event; } fireError(error, message, count) { this.errorEmitter.fire([this.asError(error), message, count]); } get onClose() { return this.closeEmitter.event; } fireClose() { this.closeEmitter.fire(undefined); } asError(error) { if (error instanceof Error) { return error; } else { return new Error(`Writer received error. Reason: ${Is.string(error.message) ? error.message : 'unknown'}`); } } } exports.AbstractMessageWriter = AbstractMessageWriter; var ResolvedMessageWriterOptions; (function (ResolvedMessageWriterOptions) { function fromOptions(options) { if (options === undefined || typeof options === 'string') { return { charset: options ?? 'utf-8', contentTypeEncoder: (0, ral_1.default)().applicationJson.encoder }; } else { return { charset: options.charset ?? 'utf-8', contentEncoder: options.contentEncoder, contentTypeEncoder: options.contentTypeEncoder ?? (0, ral_1.default)().applicationJson.encoder }; } } ResolvedMessageWriterOptions.fromOptions = fromOptions; })(ResolvedMessageWriterOptions || (ResolvedMessageWriterOptions = {})); class WriteableStreamMessageWriter extends AbstractMessageWriter { constructor(writable, options) { super(); this.writable = writable; this.options = ResolvedMessageWriterOptions.fromOptions(options); this.errorCount = 0; this.writeSemaphore = new semaphore_1.Semaphore(1); this.writable.onError((error) => this.fireError(error)); this.writable.onClose(() => this.fireClose()); } async write(msg) { return this.writeSemaphore.lock(async () => { const payload = this.options.contentTypeEncoder.encode(msg, this.options).then((buffer) => { if (this.options.contentEncoder !== undefined) { return this.options.contentEncoder.encode(buffer); } else { return buffer; } }); return payload.then((buffer) => { const headers = []; headers.push(ContentLength, buffer.byteLength.toString(), CRLF); headers.push(CRLF); return this.doWrite(msg, headers, buffer); }, (error) => { this.fireError(error); throw error; }); }); } async doWrite(msg, headers, data) { try { await this.writable.write(headers.join(''), 'ascii'); return this.writable.write(data); } catch (error) { this.handleError(error, msg); return Promise.reject(error); } } handleError(error, msg) { this.errorCount++; this.fireError(error, msg, this.errorCount); } end() { this.writable.end(); } } exports.WriteableStreamMessageWriter = WriteableStreamMessageWriter;