1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | Object.defineProperty(exports, "__esModule", { value: true });
|
7 | exports.WriteableStreamMessageWriter = exports.AbstractMessageWriter = exports.MessageWriter = void 0;
|
8 | const ral_1 = require("./ral");
|
9 | const Is = require("./is");
|
10 | const semaphore_1 = require("./semaphore");
|
11 | const events_1 = require("./events");
|
12 | const ContentLength = 'Content-Length: ';
|
13 | const CRLF = '\r\n';
|
14 | var 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 = {}));
|
23 | class 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 | }
|
53 | exports.AbstractMessageWriter = AbstractMessageWriter;
|
54 | var 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 = {}));
|
66 | class 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 | }
|
115 | exports.WriteableStreamMessageWriter = WriteableStreamMessageWriter;
|