UNPKG

4.43 kBJavaScriptView Raw
1"use strict";
2/* --------------------------------------------------------------------------------------------
3 * Copyright (c) Microsoft Corporation. All rights reserved.
4 * Licensed under the MIT License. See License.txt in the project root for license information.
5 * ------------------------------------------------------------------------------------------ */
6Object.defineProperty(exports, "__esModule", { value: true });
7exports.WriteableStreamMessageWriter = exports.AbstractMessageWriter = exports.MessageWriter = void 0;
8const ral_1 = require("./ral");
9const Is = require("./is");
10const semaphore_1 = require("./semaphore");
11const events_1 = require("./events");
12const ContentLength = 'Content-Length: ';
13const CRLF = '\r\n';
14var MessageWriter;
15(function (MessageWriter) {
16 function is(value) {
17 let candidate = value;
18 return candidate && Is.func(candidate.dispose) && Is.func(candidate.onClose) &&
19 Is.func(candidate.onError) && Is.func(candidate.write);
20 }
21 MessageWriter.is = is;
22})(MessageWriter || (exports.MessageWriter = MessageWriter = {}));
23class AbstractMessageWriter {
24 constructor() {
25 this.errorEmitter = new events_1.Emitter();
26 this.closeEmitter = new events_1.Emitter();
27 }
28 dispose() {
29 this.errorEmitter.dispose();
30 this.closeEmitter.dispose();
31 }
32 get onError() {
33 return this.errorEmitter.event;
34 }
35 fireError(error, message, count) {
36 this.errorEmitter.fire([this.asError(error), message, count]);
37 }
38 get onClose() {
39 return this.closeEmitter.event;
40 }
41 fireClose() {
42 this.closeEmitter.fire(undefined);
43 }
44 asError(error) {
45 if (error instanceof Error) {
46 return error;
47 }
48 else {
49 return new Error(`Writer received error. Reason: ${Is.string(error.message) ? error.message : 'unknown'}`);
50 }
51 }
52}
53exports.AbstractMessageWriter = AbstractMessageWriter;
54var ResolvedMessageWriterOptions;
55(function (ResolvedMessageWriterOptions) {
56 function fromOptions(options) {
57 if (options === undefined || typeof options === 'string') {
58 return { charset: options ?? 'utf-8', contentTypeEncoder: (0, ral_1.default)().applicationJson.encoder };
59 }
60 else {
61 return { charset: options.charset ?? 'utf-8', contentEncoder: options.contentEncoder, contentTypeEncoder: options.contentTypeEncoder ?? (0, ral_1.default)().applicationJson.encoder };
62 }
63 }
64 ResolvedMessageWriterOptions.fromOptions = fromOptions;
65})(ResolvedMessageWriterOptions || (ResolvedMessageWriterOptions = {}));
66class WriteableStreamMessageWriter extends AbstractMessageWriter {
67 constructor(writable, options) {
68 super();
69 this.writable = writable;
70 this.options = ResolvedMessageWriterOptions.fromOptions(options);
71 this.errorCount = 0;
72 this.writeSemaphore = new semaphore_1.Semaphore(1);
73 this.writable.onError((error) => this.fireError(error));
74 this.writable.onClose(() => this.fireClose());
75 }
76 async write(msg) {
77 return this.writeSemaphore.lock(async () => {
78 const payload = this.options.contentTypeEncoder.encode(msg, this.options).then((buffer) => {
79 if (this.options.contentEncoder !== undefined) {
80 return this.options.contentEncoder.encode(buffer);
81 }
82 else {
83 return buffer;
84 }
85 });
86 return payload.then((buffer) => {
87 const headers = [];
88 headers.push(ContentLength, buffer.byteLength.toString(), CRLF);
89 headers.push(CRLF);
90 return this.doWrite(msg, headers, buffer);
91 }, (error) => {
92 this.fireError(error);
93 throw error;
94 });
95 });
96 }
97 async doWrite(msg, headers, data) {
98 try {
99 await this.writable.write(headers.join(''), 'ascii');
100 return this.writable.write(data);
101 }
102 catch (error) {
103 this.handleError(error, msg);
104 return Promise.reject(error);
105 }
106 }
107 handleError(error, msg) {
108 this.errorCount++;
109 this.fireError(error, msg, this.errorCount);
110 }
111 end() {
112 this.writable.end();
113 }
114}
115exports.WriteableStreamMessageWriter = WriteableStreamMessageWriter;