UNPKG

15.5 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const through_1 = tslib_1.__importDefault(require("through"));
5const errors_1 = require("../errors");
6class Peer {
7 constructor(options) {
8 this.endpoint = options.endpoint;
9 this.mutableConnected = false;
10 this.stream = options.stream;
11 this.transform = options.transform;
12 this.buffer = through_1.default();
13 this.mutableConnecting = false;
14 this.mutableClosed = false;
15 this.onErrorInternal = options.onError;
16 this.onCloseInternal = options.onClose;
17 this.transform.on('error', this.onError.bind(this));
18 this.buffer.on('error', this.onError.bind(this));
19 this.buffer.pause();
20 this.stream.pipe(this.transform).pipe(this.buffer);
21 }
22 get connected() {
23 return this.mutableConnected;
24 }
25 async connect() {
26 if (this.mutableConnecting || this.mutableConnected) {
27 return;
28 }
29 this.mutableConnecting = true;
30 this.mutableClosed = false;
31 try {
32 await this.connectInternal();
33 this.stream.on('error', this.onError.bind(this));
34 this.stream.on('close', this.onClose.bind(this));
35 this.mutableConnected = true;
36 }
37 finally {
38 this.mutableConnecting = false;
39 }
40 }
41 close(hadError) {
42 if (this.mutableClosed) {
43 return;
44 }
45 this.mutableClosed = true;
46 if (!this.mutableConnecting && !this.mutableConnected) {
47 return;
48 }
49 this.mutableConnecting = false;
50 this.mutableConnected = false;
51 this.closeInternal(!!hadError);
52 this.stream.unpipe(this.transform);
53 this.transform.unpipe(this.buffer);
54 this.transform.end();
55 this.buffer.end();
56 }
57 write(buffer) {
58 if (!this.mutableConnected || this.mutableClosed) {
59 return;
60 }
61 try {
62 this.stream.write(buffer);
63 }
64 catch (error) {
65 this.onError(error);
66 }
67 }
68 async receiveMessage(timeoutMS) {
69 return new Promise((resolve, reject) => {
70 let handled = false;
71 const cleanup = () => {
72 this.buffer.pause();
73 handled = true;
74 this.stream.removeListener('error', onError);
75 this.transform.removeListener('error', onError);
76 this.buffer.removeListener('error', onError);
77 this.buffer.removeListener('data', onDataReceived);
78 };
79 const onError = (error) => {
80 if (!handled) {
81 cleanup();
82 reject(error);
83 }
84 };
85 const onDataReceived = (data) => {
86 if (!handled) {
87 cleanup();
88 resolve(data);
89 }
90 };
91 this.stream.once('error', onError);
92 this.transform.once('error', onError);
93 this.buffer.once('error', onError);
94 this.buffer.once('data', onDataReceived);
95 this.buffer.resume();
96 if (timeoutMS !== undefined) {
97 setTimeout(() => onError(new errors_1.ReceiveMessageTimeoutError(this.endpoint)), timeoutMS);
98 }
99 });
100 }
101 streamData(onDataReceived) {
102 this.buffer.on('data', onDataReceived);
103 this.buffer.resume();
104 return {
105 unsubscribe: () => {
106 this.buffer.pause();
107 this.buffer.removeListener('data', onDataReceived);
108 },
109 };
110 }
111 onError(error) {
112 this.close(true);
113 this.onErrorInternal(this, error);
114 }
115 onClose() {
116 this.mutableClosed = true;
117 this.onCloseInternal(this);
118 }
119}
120exports.Peer = Peer;
121
122//# sourceMappingURL=data:application/json;charset=utf8;base64,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QUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQ3JELENBQUM7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUtTLE9BQU8sQ0FBQyxLQUFZO1FBQzVCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVPLE9BQU87UUFDYixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUMxQixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCLENBQUM7Q0FDRjtBQXJKRCxvQkFxSkMiLCJmaWxlIjoibmVvLW9uZS1ub2RlLWNvcmUvc3JjL25ldC9QZWVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRHVwbGV4IH0gZnJvbSAnc3RyZWFtJztcbmltcG9ydCB0aHJvdWdoIGZyb20gJ3Rocm91Z2gnO1xuaW1wb3J0IHsgUmVjZWl2ZU1lc3NhZ2VUaW1lb3V0RXJyb3IgfSBmcm9tICcuLi9lcnJvcnMnO1xuaW1wb3J0IHsgRW5kcG9pbnQgfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBQZWVyT3B0aW9uczxNZXNzYWdlPiB7XG4gIHJlYWRvbmx5IGVuZHBvaW50OiBFbmRwb2ludDtcbiAgcmVhZG9ubHkgc3RyZWFtOiBEdXBsZXg7XG4gIHJlYWRvbmx5IHRyYW5zZm9ybTogRHVwbGV4O1xuICByZWFkb25seSBvbkVycm9yOiAocGVlcjogUGVlcjxNZXNzYWdlPiwgZXJyb3I6IEVycm9yKSA9PiB2b2lkO1xuICByZWFkb25seSBvbkNsb3NlOiAocGVlcjogUGVlcjxNZXNzYWdlPikgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFBlZXI8TWVzc2FnZT4ge1xuICBwdWJsaWMgcmVhZG9ubHkgZW5kcG9pbnQ6IEVuZHBvaW50O1xuICBwcml2YXRlIHJlYWRvbmx5IHN0cmVhbTogRHVwbGV4O1xuICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zZm9ybTogRHVwbGV4O1xuICBwcml2YXRlIHJlYWRvbmx5IGJ1ZmZlcjogRHVwbGV4O1xuICBwcml2YXRlIG11dGFibGVDb25uZWN0ZWQ6IGJvb2xlYW47XG4gIHByaXZhdGUgbXV0YWJsZUNvbm5lY3Rpbmc6IGJvb2xlYW47XG4gIHByaXZhdGUgbXV0YWJsZUNsb3NlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSBvbkVycm9ySW50ZXJuYWw6IChwZWVyOiBQZWVyPE1lc3NhZ2U+LCBlcnJvcjogRXJyb3IpID0+IHZvaWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgb25DbG9zZUludGVybmFsOiAocGVlcjogUGVlcjxNZXNzYWdlPikgPT4gdm9pZDtcblxuICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9uczogUGVlck9wdGlvbnM8TWVzc2FnZT4pIHtcbiAgICB0aGlzLmVuZHBvaW50ID0gb3B0aW9ucy5lbmRwb2ludDtcbiAgICB0aGlzLm11dGFibGVDb25uZWN0ZWQgPSBmYWxzZTtcblxuICAgIHRoaXMuc3RyZWFtID0gb3B0aW9ucy5zdHJlYW07XG4gICAgdGhpcy50cmFuc2Zvcm0gPSBvcHRpb25zLnRyYW5zZm9ybTtcbiAgICB0aGlzLmJ1ZmZlciA9IHRocm91Z2goKTtcblxuICAgIHRoaXMubXV0YWJsZUNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICB0aGlzLm11dGFibGVDbG9zZWQgPSBmYWxzZTtcblxuICAgIHRoaXMub25FcnJvckludGVybmFsID0gb3B0aW9ucy5vbkVycm9yO1xuICAgIHRoaXMub25DbG9zZUludGVybmFsID0gb3B0aW9ucy5vbkNsb3NlO1xuXG4gICAgdGhpcy50cmFuc2Zvcm0ub24oJ2Vycm9yJywgdGhpcy5vbkVycm9yLmJpbmQodGhpcykpO1xuICAgIHRoaXMuYnVmZmVyLm9uKCdlcnJvcicsIHRoaXMub25FcnJvci5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLmJ1ZmZlci5wYXVzZSgpO1xuICAgIHRoaXMuc3RyZWFtLnBpcGUodGhpcy50cmFuc2Zvcm0pLnBpcGUodGhpcy5idWZmZXIpO1xuICB9XG5cbiAgcHVibGljIGdldCBjb25uZWN0ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubXV0YWJsZUNvbm5lY3RlZDtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLm11dGFibGVDb25uZWN0aW5nIHx8IHRoaXMubXV0YWJsZUNvbm5lY3RlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLm11dGFibGVDb25uZWN0aW5nID0gdHJ1ZTtcbiAgICB0aGlzLm11dGFibGVDbG9zZWQgPSBmYWxzZTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNvbm5lY3RJbnRlcm5hbCgpO1xuICAgICAgdGhpcy5zdHJlYW0ub24oJ2Vycm9yJywgdGhpcy5vbkVycm9yLmJpbmQodGhpcykpO1xuICAgICAgdGhpcy5zdHJlYW0ub24oJ2Nsb3NlJywgdGhpcy5vbkNsb3NlLmJpbmQodGhpcykpO1xuICAgICAgdGhpcy5tdXRhYmxlQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5tdXRhYmxlQ29ubmVjdGluZyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjbG9zZShoYWRFcnJvcj86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tdXRhYmxlQ2xvc2VkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubXV0YWJsZUNsb3NlZCA9IHRydWU7XG5cbiAgICBpZiAoIXRoaXMubXV0YWJsZUNvbm5lY3RpbmcgJiYgIXRoaXMubXV0YWJsZUNvbm5lY3RlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLm11dGFibGVDb25uZWN0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5tdXRhYmxlQ29ubmVjdGVkID0gZmFsc2U7XG5cbiAgICB0aGlzLmNsb3NlSW50ZXJuYWwoISFoYWRFcnJvcik7XG4gICAgdGhpcy5zdHJlYW0udW5waXBlKHRoaXMudHJhbnNmb3JtKTtcbiAgICB0aGlzLnRyYW5zZm9ybS51bnBpcGUodGhpcy5idWZmZXIpO1xuICAgIHRoaXMudHJhbnNmb3JtLmVuZCgpO1xuICAgIHRoaXMuYnVmZmVyLmVuZCgpO1xuICB9XG5cbiAgcHVibGljIHdyaXRlKGJ1ZmZlcjogQnVmZmVyKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm11dGFibGVDb25uZWN0ZWQgfHwgdGhpcy5tdXRhYmxlQ2xvc2VkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuc3RyZWFtLndyaXRlKGJ1ZmZlcik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMub25FcnJvcihlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIHJlY2VpdmVNZXNzYWdlKHRpbWVvdXRNUz86IG51bWJlcik6IFByb21pc2U8TWVzc2FnZT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxNZXNzYWdlPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgaGFuZGxlZCA9IGZhbHNlO1xuICAgICAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5idWZmZXIucGF1c2UoKTtcbiAgICAgICAgaGFuZGxlZCA9IHRydWU7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgICB0aGlzLnN0cmVhbS5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbkVycm9yKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgICAgIHRoaXMudHJhbnNmb3JtLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgdGhpcy5idWZmZXIucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25FcnJvcik7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgICB0aGlzLmJ1ZmZlci5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uRGF0YVJlY2VpdmVkKTtcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG9uRXJyb3IgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgIGlmICghaGFuZGxlZCkge1xuICAgICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBvbkRhdGFSZWNlaXZlZCA9IChkYXRhOiBNZXNzYWdlKSA9PiB7XG4gICAgICAgIGlmICghaGFuZGxlZCkge1xuICAgICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICB0aGlzLnN0cmVhbS5vbmNlKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgICAgdGhpcy50cmFuc2Zvcm0ub25jZSgnZXJyb3InLCBvbkVycm9yKTtcbiAgICAgIHRoaXMuYnVmZmVyLm9uY2UoJ2Vycm9yJywgb25FcnJvcik7XG4gICAgICB0aGlzLmJ1ZmZlci5vbmNlKCdkYXRhJywgb25EYXRhUmVjZWl2ZWQpO1xuICAgICAgdGhpcy5idWZmZXIucmVzdW1lKCk7XG5cbiAgICAgIGlmICh0aW1lb3V0TVMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IG9uRXJyb3IobmV3IFJlY2VpdmVNZXNzYWdlVGltZW91dEVycm9yKHRoaXMuZW5kcG9pbnQpKSwgdGltZW91dE1TKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBzdHJlYW1EYXRhKG9uRGF0YVJlY2VpdmVkOiAoZGF0YTogTWVzc2FnZSkgPT4gdm9pZCk6IHsgcmVhZG9ubHkgdW5zdWJzY3JpYmU6ICgpID0+IHZvaWQgfSB7XG4gICAgdGhpcy5idWZmZXIub24oJ2RhdGEnLCBvbkRhdGFSZWNlaXZlZCk7XG4gICAgdGhpcy5idWZmZXIucmVzdW1lKCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdW5zdWJzY3JpYmU6ICgpID0+IHtcbiAgICAgICAgdGhpcy5idWZmZXIucGF1c2UoKTtcbiAgICAgICAgdGhpcy5idWZmZXIucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBvbkRhdGFSZWNlaXZlZCk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgYXN5bmMgY29ubmVjdEludGVybmFsKCk6IFByb21pc2U8dm9pZD47XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBjbG9zZUludGVybmFsKGhhZEVycm9yOiBib29sZWFuKTogdm9pZDtcblxuICBwcm90ZWN0ZWQgb25FcnJvcihlcnJvcjogRXJyb3IpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlKHRydWUpO1xuICAgIHRoaXMub25FcnJvckludGVybmFsKHRoaXMsIGVycm9yKTtcbiAgfVxuXG4gIHByaXZhdGUgb25DbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLm11dGFibGVDbG9zZWQgPSB0cnVlO1xuICAgIHRoaXMub25DbG9zZUludGVybmFsKHRoaXMpO1xuICB9XG59XG4iXX0=