116 lines
4.3 KiB
JavaScript
116 lines
4.3 KiB
JavaScript
![]() |
"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;
|