@whitewall/blip-sdk 0.0.180 → 0.0.181
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/sender/enveloperesolver.js +2 -2
- package/dist/cjs/sender/enveloperesolver.js.map +1 -1
- package/dist/cjs/sender/sender.js +6 -0
- package/dist/cjs/sender/sender.js.map +1 -1
- package/dist/cjs/sender/sessionnegotiator.js +15 -7
- package/dist/cjs/sender/sessionnegotiator.js.map +1 -1
- package/dist/cjs/sender/tcp/tcpsender.js +47 -31
- package/dist/cjs/sender/tcp/tcpsender.js.map +1 -1
- package/dist/cjs/sender/websocket/websocketsender.js +40 -12
- package/dist/cjs/sender/websocket/websocketsender.js.map +1 -1
- package/dist/esm/sender/enveloperesolver.js +2 -2
- package/dist/esm/sender/enveloperesolver.js.map +1 -1
- package/dist/esm/sender/sender.js +6 -0
- package/dist/esm/sender/sender.js.map +1 -1
- package/dist/esm/sender/sessionnegotiator.js +15 -7
- package/dist/esm/sender/sessionnegotiator.js.map +1 -1
- package/dist/esm/sender/tcp/tcpsender.js +47 -31
- package/dist/esm/sender/tcp/tcpsender.js.map +1 -1
- package/dist/esm/sender/websocket/websocketsender.js +40 -12
- package/dist/esm/sender/websocket/websocketsender.js.map +1 -1
- package/dist/types/sender/enveloperesolver.d.ts +1 -1
- package/dist/types/sender/enveloperesolver.d.ts.map +1 -1
- package/dist/types/sender/sender.d.ts +1 -0
- package/dist/types/sender/sender.d.ts.map +1 -1
- package/dist/types/sender/sessionnegotiator.d.ts +2 -0
- package/dist/types/sender/sessionnegotiator.d.ts.map +1 -1
- package/dist/types/sender/tcp/tcpsender.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/sender/enveloperesolver.ts +2 -2
- package/src/sender/sender.ts +7 -0
- package/src/sender/sessionnegotiator.ts +16 -7
- package/src/sender/tcp/tcpsender.ts +51 -33
- package/src/sender/websocket/websocketsender.ts +40 -14
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { logger } from "../../utils/logger.js";
|
|
2
1
|
import { BlipError } from "../bliperror.js";
|
|
3
2
|
import { RetryableError } from "../retryableerror.js";
|
|
4
3
|
import { ConnectionSender, OpenConnectionSender } from "../sender.js";
|
|
@@ -21,20 +20,19 @@ export class TCPSender extends OpenConnectionSender {
|
|
|
21
20
|
const host = `${prefix}tcp.${this.domain}`;
|
|
22
21
|
const auth = options.authentication;
|
|
23
22
|
const tlsOptions = auth.scheme === 'transport' ? { ...buildTlsConnectOptions(auth), servername: host } : null;
|
|
24
|
-
this.connectionHandle = new TCPHandle(host, 443, () => {
|
|
23
|
+
this.connectionHandle = new TCPHandle(host, 443, (socketRef) => {
|
|
25
24
|
this.sessionNegotiator = new SessionNegotiator(this, (session) => {
|
|
26
|
-
|
|
27
|
-
.get()
|
|
28
|
-
.then((s) => s.write(JSON.stringify(session)))
|
|
29
|
-
.catch((err) => logger.warn('TCPSender', 'Failed to write session frame', err));
|
|
25
|
+
socketRef.current.write(JSON.stringify(session));
|
|
30
26
|
});
|
|
31
|
-
const upgradeToTls = tlsOptions
|
|
27
|
+
const upgradeToTls = tlsOptions
|
|
28
|
+
? () => this.connectionHandle.upgradeToTls(tlsOptions, socketRef)
|
|
29
|
+
: undefined;
|
|
32
30
|
return this.sessionNegotiator.negotiate({
|
|
33
31
|
node: options.node,
|
|
34
32
|
authentication: auth,
|
|
35
33
|
upgradeToTls,
|
|
36
34
|
});
|
|
37
|
-
}, () => this.
|
|
35
|
+
}, () => this.rejectPending('Connection was closed'), (envelope) => {
|
|
38
36
|
if (this.sessionNegotiator?.negotiating) {
|
|
39
37
|
return this.sessionNegotiator.handleEnvelope(envelope);
|
|
40
38
|
}
|
|
@@ -117,15 +115,16 @@ class TCPHandle {
|
|
|
117
115
|
current.end().removeAllListeners().destroySoon();
|
|
118
116
|
}
|
|
119
117
|
}
|
|
120
|
-
async upgradeToTls(options) {
|
|
121
|
-
|
|
122
|
-
throw new Error('Cannot upgrade: no active socket.');
|
|
123
|
-
}
|
|
124
|
-
const plain = await this.currentSocketPromise;
|
|
118
|
+
async upgradeToTls(options, socketRef) {
|
|
119
|
+
const plain = socketRef.current;
|
|
125
120
|
plain.removeAllListeners('data');
|
|
126
121
|
this.buffer = Buffer.alloc(0);
|
|
127
122
|
const { connect: tlsConnect } = await import('node:tls');
|
|
128
123
|
const secured = tlsConnect({ ...options, socket: plain });
|
|
124
|
+
// Permanent no-op handler attached up front, so errors that arrive in
|
|
125
|
+
// the microtask gap after secureConnect resolves don't become
|
|
126
|
+
// uncaughtException. The underlying TCP socket's 'close' drives reconnect.
|
|
127
|
+
secured.on('error', () => undefined);
|
|
129
128
|
await new Promise((resolve, reject) => {
|
|
130
129
|
const onError = (err) => {
|
|
131
130
|
secured.off('secureConnect', onConnect);
|
|
@@ -139,7 +138,7 @@ class TCPHandle {
|
|
|
139
138
|
secured.once('error', onError);
|
|
140
139
|
});
|
|
141
140
|
this.attachDataListener(secured);
|
|
142
|
-
|
|
141
|
+
socketRef.current = secured;
|
|
143
142
|
}
|
|
144
143
|
attachDataListener(socket) {
|
|
145
144
|
socket.on('data', (chunk) => {
|
|
@@ -154,37 +153,54 @@ class TCPHandle {
|
|
|
154
153
|
const { connect } = await import('node:net');
|
|
155
154
|
const socket = connect({ host, port }).setKeepAlive(true);
|
|
156
155
|
this.buffer = Buffer.alloc(0);
|
|
157
|
-
|
|
156
|
+
// Mutable holder so upgradeToTls can swap the socket mid-handshake;
|
|
157
|
+
// the negotiator's sendSession reads .current at write time, so frames
|
|
158
|
+
// always go to the active socket even after the TLS upgrade.
|
|
159
|
+
const socketRef = { current: socket };
|
|
160
|
+
await new Promise((resolve, reject) => {
|
|
161
|
+
let connected = false;
|
|
158
162
|
socket.once('connect', () => {
|
|
163
|
+
connected = true;
|
|
159
164
|
resolve();
|
|
160
165
|
});
|
|
161
166
|
socket.once('error', (err) => {
|
|
162
|
-
if (!
|
|
163
|
-
|
|
167
|
+
if (!connected) {
|
|
168
|
+
reject(err);
|
|
164
169
|
}
|
|
170
|
+
// Post-connect errors are followed by 'close', which drives reconnect;
|
|
171
|
+
// this listener exists only to prevent uncaughtException.
|
|
165
172
|
});
|
|
166
173
|
socket.once('close', () => {
|
|
167
|
-
socket
|
|
174
|
+
// socketRef.current is the TLS-upgraded socket if upgrade ran; the
|
|
175
|
+
// plain one otherwise. Both cases hold the only live data listener.
|
|
176
|
+
socketRef.current.removeAllListeners('data');
|
|
168
177
|
if (!this.closing) {
|
|
169
|
-
|
|
178
|
+
if (connected)
|
|
179
|
+
onClose();
|
|
170
180
|
this.connectionAttempts++;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
181
|
+
// Swallow the rejection of the now-orphaned previous promise; any
|
|
182
|
+
// in-flight get() awaiter still sees it via their captured reference.
|
|
183
|
+
const previous = this.currentSocketPromise;
|
|
184
|
+
this.currentSocketPromise =
|
|
185
|
+
this.connectionAttempts < 3 ? this.connect(host, port, onConnected, onClose) : null;
|
|
186
|
+
previous?.catch(() => undefined);
|
|
177
187
|
}
|
|
188
|
+
if (!connected)
|
|
189
|
+
reject(new Error('Socket closed before connect'));
|
|
178
190
|
});
|
|
179
191
|
this.attachDataListener(socket);
|
|
180
192
|
});
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
193
|
+
try {
|
|
194
|
+
await onConnected(socketRef);
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
// Handshake failures (timeout, bad response) leave the socket open
|
|
198
|
+
// otherwise; destroy it so the 'close' handler drives reconnect.
|
|
199
|
+
socketRef.current.destroy();
|
|
200
|
+
throw err;
|
|
201
|
+
}
|
|
186
202
|
this.connectionAttempts = 0;
|
|
187
|
-
return
|
|
203
|
+
return socketRef.current;
|
|
188
204
|
}
|
|
189
205
|
}
|
|
190
206
|
//# sourceMappingURL=tcpsender.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tcpsender.js","sourceRoot":"","sources":["../../../../src/sender/tcp/tcpsender.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"tcpsender.js","sourceRoot":"","sources":["../../../../src/sender/tcp/tcpsender.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ export class WebSocketSender extends OpenConnectionSender {
|
|
|
20
20
|
node: options.node,
|
|
21
21
|
authentication: options.authentication,
|
|
22
22
|
});
|
|
23
|
-
}, () => this.
|
|
23
|
+
}, () => this.rejectPending('Connection was closed'), (envelope) => {
|
|
24
24
|
if (this.sessionNegotiator?.negotiating) {
|
|
25
25
|
return this.sessionNegotiator.handleEnvelope(envelope);
|
|
26
26
|
}
|
|
@@ -93,6 +93,9 @@ class WebSocketHandle {
|
|
|
93
93
|
this.currentWebSocketPromise = this.connect(url, onConnected, onClose, onMessage);
|
|
94
94
|
}
|
|
95
95
|
get() {
|
|
96
|
+
if (!this.currentWebSocketPromise) {
|
|
97
|
+
throw new Error('WebSocket connection is not available.');
|
|
98
|
+
}
|
|
96
99
|
return this.currentWebSocketPromise;
|
|
97
100
|
}
|
|
98
101
|
async close() {
|
|
@@ -105,29 +108,54 @@ class WebSocketHandle {
|
|
|
105
108
|
async connect(url, onConnected, onClose, onMessage) {
|
|
106
109
|
const connection = new WebSocket(url, 'lime');
|
|
107
110
|
await new Promise((resolve, reject) => {
|
|
111
|
+
let connected = false;
|
|
108
112
|
connection.onopen = () => {
|
|
113
|
+
connected = true;
|
|
109
114
|
resolve();
|
|
110
115
|
};
|
|
116
|
+
connection.onerror = (err) => {
|
|
117
|
+
if (!connected) {
|
|
118
|
+
reject('message' in err ? new Error(`WebSocket error: ${err.message}`, { cause: err }) : err);
|
|
119
|
+
}
|
|
120
|
+
// Post-open errors are followed by 'close', which drives reconnect.
|
|
121
|
+
};
|
|
111
122
|
connection.onclose = () => {
|
|
112
123
|
if (!this.closing) {
|
|
124
|
+
if (connected)
|
|
125
|
+
onClose();
|
|
113
126
|
this.connectionAttempts++;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
onClose();
|
|
127
|
+
// Swallow the rejection of the now-orphaned previous promise; any
|
|
128
|
+
// in-flight get() awaiter still sees it via their captured reference.
|
|
129
|
+
const previous = this.currentWebSocketPromise;
|
|
130
|
+
this.currentWebSocketPromise =
|
|
131
|
+
this.connectionAttempts < 3 ? this.connect(url, onConnected, onClose, onMessage) : null;
|
|
132
|
+
previous?.catch(() => undefined);
|
|
121
133
|
}
|
|
134
|
+
if (!connected)
|
|
135
|
+
reject(new Error('WebSocket closed before open'));
|
|
122
136
|
};
|
|
123
137
|
connection.onmessage = (event) => {
|
|
124
138
|
onMessage(JSON.parse(event.data));
|
|
125
139
|
};
|
|
126
|
-
connection.onerror = (err) => {
|
|
127
|
-
reject('message' in err ? new Error(`WebSocket error: ${err.message}`, { cause: err }) : err);
|
|
128
|
-
};
|
|
129
140
|
});
|
|
130
|
-
|
|
141
|
+
try {
|
|
142
|
+
await onConnected(connection);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
// Handshake failures leave the socket open otherwise; tear it down so
|
|
146
|
+
// the 'onclose' handler drives reconnect. Prefer ws.terminate() (hard
|
|
147
|
+
// kill, Node only) to avoid waiting on the graceful close handshake
|
|
148
|
+
// with a peer that just failed to negotiate; fall back to close() in
|
|
149
|
+
// browsers where terminate() doesn't exist.
|
|
150
|
+
const terminable = connection;
|
|
151
|
+
if (terminable.terminate) {
|
|
152
|
+
terminable.terminate();
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
connection.close();
|
|
156
|
+
}
|
|
157
|
+
throw err;
|
|
158
|
+
}
|
|
131
159
|
this.connectionAttempts = 0;
|
|
132
160
|
return connection;
|
|
133
161
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocketsender.js","sourceRoot":"","sources":["../../../../src/sender/websocket/websocketsender.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAmC,MAAM,gBAAgB,CAAA;AACxF,OAAO,EAAE,gBAAgB,EAAoC,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACvG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEnD,MAAM,OAAO,eAAgB,SAAQ,oBAAoB;IACpC,SAAS,GAAG,IAAI,iBAAiB,EAAE,CAAA;IACnC,gBAAgB,CAA2B;IAE5D,YACI,OAA2G;QAE3G,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,sBAAsB,CAAC,OAAO,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAA;QAEjE,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;QAE7D,IAAI,CAAC,gBAAgB,GAAG,IAAI,eAAe,CACvC,SAAS,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,EAClC,CAAC,SAAS,EAAE,EAAE;YACV,IAAI,CAAC,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE;gBAC7D,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;YAC3C,CAAC,CAAC,CAAA;YACF,OAAO,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC;gBACpC,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,cAAc,EAAE,OAAO,CAAC,cAAc;aACzC,CAAC,CAAA;QACN,CAAC,EACD,GAAG,EAAE,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"websocketsender.js","sourceRoot":"","sources":["../../../../src/sender/websocket/websocketsender.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ export declare class EnvelopeResolver {
|
|
|
20
20
|
addListener<K extends keyof EventMap>(ev: K, listener: Listener<K>): void;
|
|
21
21
|
removeListener<K extends keyof EventMap>(ev: K, callback: Listener<K>['callback']): void;
|
|
22
22
|
close(): void;
|
|
23
|
-
rejectPendingEnvelopes(
|
|
23
|
+
rejectPendingEnvelopes(error: Error): void;
|
|
24
24
|
private resolveEnvelopeResponse;
|
|
25
25
|
private emit;
|
|
26
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enveloperesolver.d.ts","sourceRoot":"","sources":["../../../src/sender/enveloperesolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,KAAK,QAAQ,EAKb,KAAK,IAAI,EACT,KAAK,YAAY,EAEjB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACtB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAEvD,MAAM,MAAM,QAAQ,GAAG;IACnB,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,YAAY,CAAC,IAAI,CAAC,CAAA;IACxD,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IACtF,YAAY,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,YAAY,CAAC,IAAI,CAAC,CAAA;CACnE,CAAA;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,QAAQ,IAAI;IAC7C,SAAS,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAA;IACzD,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;CAC1E,CAAA;AAMD,qBAAa,gBAAgB;IAmBrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAlB3B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgB;IAEhD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAIzB;IAED,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAO3C;gBAGe,MAAM,EAAE,oBAAoB,EAC7C,cAAc,SAAU;IAgBf,OAAO,CAAC,QAAQ,EAAE,QAAQ;IAuEhC,6BAA6B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAM5D,WAAW,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAQlE,cAAc,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAIjF,KAAK;IAQL,sBAAsB,CAAC,
|
|
1
|
+
{"version":3,"file":"enveloperesolver.d.ts","sourceRoot":"","sources":["../../../src/sender/enveloperesolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,KAAK,QAAQ,EAKb,KAAK,IAAI,EACT,KAAK,YAAY,EAEjB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACtB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAEvD,MAAM,MAAM,QAAQ,GAAG;IACnB,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,YAAY,CAAC,IAAI,CAAC,CAAA;IACxD,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IACtF,YAAY,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,YAAY,CAAC,IAAI,CAAC,CAAA;CACnE,CAAA;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,QAAQ,IAAI;IAC7C,SAAS,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAA;IACzD,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;CAC1E,CAAA;AAMD,qBAAa,gBAAgB;IAmBrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAlB3B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgB;IAEhD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAIzB;IAED,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAO3C;gBAGe,MAAM,EAAE,oBAAoB,EAC7C,cAAc,SAAU;IAgBf,OAAO,CAAC,QAAQ,EAAE,QAAQ;IAuEhC,6BAA6B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAM5D,WAAW,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAQlE,cAAc,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAIjF,KAAK;IAQL,sBAAsB,CAAC,KAAK,EAAE,KAAK;IAM1C,OAAO,CAAC,uBAAuB;YAajB,IAAI;CAcrB"}
|
|
@@ -35,5 +35,6 @@ export declare abstract class OpenConnectionSender extends ConnectionSender impl
|
|
|
35
35
|
off<K extends keyof EventMap>(ev: K, listener: Listener<K>['callback']): this;
|
|
36
36
|
get session(): import("./sessionnegotiator.ts").ConnectionSession | null;
|
|
37
37
|
close(): Promise<void>;
|
|
38
|
+
protected rejectPending(reason: string): void;
|
|
38
39
|
}
|
|
39
40
|
//# sourceMappingURL=sender.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sender.d.ts","sourceRoot":"","sources":["../../../src/sender/sender.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,YAAY,EAEjB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC9B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"sender.d.ts","sourceRoot":"","sources":["../../../src/sender/sender.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@ export declare class SessionNegotiator {
|
|
|
16
16
|
session: ConnectionSession | null;
|
|
17
17
|
private presencePromise;
|
|
18
18
|
private currentSessionResolver;
|
|
19
|
+
private failure;
|
|
19
20
|
constructor(sender: OpenConnectionSender, sendSession: (session: Session) => void);
|
|
20
21
|
negotiate(options: {
|
|
21
22
|
node: NodeLike;
|
|
@@ -23,6 +24,7 @@ export declare class SessionNegotiator {
|
|
|
23
24
|
upgradeToTls?: () => Promise<void>;
|
|
24
25
|
}): Promise<void>;
|
|
25
26
|
handleEnvelope(envelope: Envelope): void;
|
|
27
|
+
fail(error: Error): void;
|
|
26
28
|
ensurePresence(currentCommandUri?: string): Promise<void>;
|
|
27
29
|
finish(): void;
|
|
28
30
|
get negotiating(): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionnegotiator.d.ts","sourceRoot":"","sources":["../../../src/sender/sessionnegotiator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAElD,MAAM,MAAM,iBAAiB,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,IAAI,CAAA;IACf,UAAU,EAAE,IAAI,CAAA;IAChB,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;CACnC,CAAA;AAED,qBAAa,iBAAiB;
|
|
1
|
+
{"version":3,"file":"sessionnegotiator.d.ts","sourceRoot":"","sources":["../../../src/sender/sessionnegotiator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAElD,MAAM,MAAM,iBAAiB,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,IAAI,CAAA;IACf,UAAU,EAAE,IAAI,CAAA;IAChB,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;CACnC,CAAA;AAED,qBAAa,iBAAiB;IAStB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IATzB,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,SAAS,CAAQ;IAC3C,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAO;IAE/C,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,sBAAsB,CAAyE;IACvG,OAAO,CAAC,OAAO,CAAqB;gBAGf,MAAM,EAAE,oBAAoB,EAC5B,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI;IAG/C,SAAS,CAAC,OAAO,EAAE;QAC5B,IAAI,EAAE,QAAQ,CAAA;QACd,cAAc,EAAE,cAAc,CAAA;QAC9B,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KACrC,GAAG,OAAO,CAAC,IAAI,CAAC;IA+EV,cAAc,CAAC,QAAQ,EAAE,QAAQ;IAOjC,IAAI,CAAC,KAAK,EAAE,KAAK;IAQX,cAAc,CAAC,iBAAiB,SAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAyC3D,MAAM;IAWb,IAAW,WAAW,IAAI,OAAO,CAEhC;YAEa,sBAAsB;CAcvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tcpsender.d.ts","sourceRoot":"","sources":["../../../../src/sender/tcp/tcpsender.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACR,OAAO,EACP,cAAc,EAGd,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,sBAAsB,EACzB,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"tcpsender.d.ts","sourceRoot":"","sources":["../../../../src/sender/tcp/tcpsender.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACR,OAAO,EACP,cAAc,EAGd,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,sBAAsB,EACzB,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EAAoB,KAAK,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAMvG;;;;;GAKG;AACH,qBAAa,SAAU,SAAQ,oBAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;gBAE1C,OAAO,EAAE,qBAAqB,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC;IAmC7D,gBAAgB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3D,WAAW,CAAC,IAAI,SAAS,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IASnF,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IA0BzD,mBAAmB,CAAC,QAAQ,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpE,KAAK;IAMlB,OAAc,KAAK;;;MAAoC;YAEzC,eAAe;CAahC"}
|
package/package.json
CHANGED
|
@@ -164,9 +164,9 @@ export class EnvelopeResolver {
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
public rejectPendingEnvelopes(
|
|
167
|
+
public rejectPendingEnvelopes(error: Error) {
|
|
168
168
|
for (const id in this.waitingEnvelopeResponseResolvers) {
|
|
169
|
-
this.resolveEnvelopeResponse(id,
|
|
169
|
+
this.resolveEnvelopeResponse(id, error)
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
|
package/src/sender/sender.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from '../types/index.ts'
|
|
13
13
|
import type { Closable } from './closable.ts'
|
|
14
14
|
import { EnvelopeResolver, type EventMap, type Listener } from './enveloperesolver.ts'
|
|
15
|
+
import { RetryableError } from './retryableerror.ts'
|
|
15
16
|
import type { Authentication } from './security.ts'
|
|
16
17
|
import type { SessionNegotiator } from './sessionnegotiator.ts'
|
|
17
18
|
|
|
@@ -149,4 +150,10 @@ export abstract class OpenConnectionSender extends ConnectionSender implements S
|
|
|
149
150
|
this.envelopeResolver.close()
|
|
150
151
|
return Promise.resolve()
|
|
151
152
|
}
|
|
153
|
+
|
|
154
|
+
protected rejectPending(reason: string) {
|
|
155
|
+
const error = new RetryableError(reason)
|
|
156
|
+
this.sessionNegotiator?.fail(error)
|
|
157
|
+
this.envelopeResolver.rejectPendingEnvelopes(error)
|
|
158
|
+
}
|
|
152
159
|
}
|
|
@@ -17,6 +17,7 @@ export class SessionNegotiator {
|
|
|
17
17
|
|
|
18
18
|
private presencePromise: Promise<void> | null = null
|
|
19
19
|
private currentSessionResolver: Pick<PromiseWithResolvers<Session>, 'reject' | 'resolve'> | null = null
|
|
20
|
+
private failure: Error | null = null
|
|
20
21
|
|
|
21
22
|
constructor(
|
|
22
23
|
private readonly sender: OpenConnectionSender,
|
|
@@ -28,11 +29,8 @@ export class SessionNegotiator {
|
|
|
28
29
|
authentication: Authentication
|
|
29
30
|
upgradeToTls?: () => Promise<void>
|
|
30
31
|
}): Promise<void> {
|
|
31
|
-
const timeout = setTimeout(
|
|
32
|
-
|
|
33
|
-
await this.sender.close()
|
|
34
|
-
throw new Error('Negotiation timeout')
|
|
35
|
-
}
|
|
32
|
+
const timeout = setTimeout(() => {
|
|
33
|
+
this.fail(new Error('Negotiation timeout'))
|
|
36
34
|
}, 60000) // 60 seconds
|
|
37
35
|
|
|
38
36
|
try {
|
|
@@ -116,6 +114,14 @@ export class SessionNegotiator {
|
|
|
116
114
|
}
|
|
117
115
|
}
|
|
118
116
|
|
|
117
|
+
public fail(error: Error) {
|
|
118
|
+
this.failure = error
|
|
119
|
+
if (this.currentSessionResolver) {
|
|
120
|
+
this.currentSessionResolver.reject(error)
|
|
121
|
+
this.currentSessionResolver = null
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
119
125
|
public async ensurePresence(currentCommandUri = ''): Promise<void> {
|
|
120
126
|
if (!this.session) {
|
|
121
127
|
throw new Error('Session not established')
|
|
@@ -159,11 +165,11 @@ export class SessionNegotiator {
|
|
|
159
165
|
|
|
160
166
|
public finish() {
|
|
161
167
|
if (!this.session) {
|
|
162
|
-
|
|
168
|
+
return
|
|
163
169
|
}
|
|
164
170
|
|
|
165
171
|
this.sendSession({
|
|
166
|
-
id: this.session
|
|
172
|
+
id: this.session.id,
|
|
167
173
|
state: 'finishing',
|
|
168
174
|
})
|
|
169
175
|
}
|
|
@@ -173,6 +179,9 @@ export class SessionNegotiator {
|
|
|
173
179
|
}
|
|
174
180
|
|
|
175
181
|
private async waitForSessionResponse(): Promise<Session> {
|
|
182
|
+
if (this.failure) {
|
|
183
|
+
throw this.failure
|
|
184
|
+
}
|
|
176
185
|
const { promise, resolve, reject } = Promise.withResolvers<Session>()
|
|
177
186
|
this.currentSessionResolver = { resolve, reject }
|
|
178
187
|
const session = await promise
|
|
@@ -10,7 +10,6 @@ import type {
|
|
|
10
10
|
Notification,
|
|
11
11
|
UnknownCommandResponse,
|
|
12
12
|
} from '../../types/index.ts'
|
|
13
|
-
import { logger } from '../../utils/logger.ts'
|
|
14
13
|
import { BlipError } from '../bliperror.ts'
|
|
15
14
|
import { RetryableError } from '../retryableerror.ts'
|
|
16
15
|
import { ConnectionSender, type ConnectionSenderConstructor, OpenConnectionSender } from '../sender.ts'
|
|
@@ -41,21 +40,20 @@ export class TCPSender extends OpenConnectionSender {
|
|
|
41
40
|
this.connectionHandle = new TCPHandle<Envelope>(
|
|
42
41
|
host,
|
|
43
42
|
443,
|
|
44
|
-
() => {
|
|
43
|
+
(socketRef) => {
|
|
45
44
|
this.sessionNegotiator = new SessionNegotiator(this, (session) => {
|
|
46
|
-
|
|
47
|
-
.get()
|
|
48
|
-
.then((s) => s.write(JSON.stringify(session)))
|
|
49
|
-
.catch((err) => logger.warn('TCPSender', 'Failed to write session frame', err))
|
|
45
|
+
socketRef.current.write(JSON.stringify(session))
|
|
50
46
|
})
|
|
51
|
-
const upgradeToTls = tlsOptions
|
|
47
|
+
const upgradeToTls = tlsOptions
|
|
48
|
+
? () => this.connectionHandle.upgradeToTls(tlsOptions, socketRef)
|
|
49
|
+
: undefined
|
|
52
50
|
return this.sessionNegotiator.negotiate({
|
|
53
51
|
node: options.node,
|
|
54
52
|
authentication: auth,
|
|
55
53
|
upgradeToTls,
|
|
56
54
|
})
|
|
57
55
|
},
|
|
58
|
-
() => this.
|
|
56
|
+
() => this.rejectPending('Connection was closed'),
|
|
59
57
|
(envelope: Envelope) => {
|
|
60
58
|
if (this.sessionNegotiator?.negotiating) {
|
|
61
59
|
return this.sessionNegotiator.handleEnvelope(envelope)
|
|
@@ -143,7 +141,7 @@ class TCPHandle<T> {
|
|
|
143
141
|
constructor(
|
|
144
142
|
host: string,
|
|
145
143
|
port: number,
|
|
146
|
-
onConnected: () => Promise<void>,
|
|
144
|
+
onConnected: (socketRef: { current: Socket }) => Promise<void>,
|
|
147
145
|
onClose: () => void,
|
|
148
146
|
onMessage: (message: T) => void,
|
|
149
147
|
) {
|
|
@@ -167,17 +165,19 @@ class TCPHandle<T> {
|
|
|
167
165
|
}
|
|
168
166
|
}
|
|
169
167
|
|
|
170
|
-
public async upgradeToTls(options: ConnectionOptions): Promise<void> {
|
|
171
|
-
|
|
172
|
-
throw new Error('Cannot upgrade: no active socket.')
|
|
173
|
-
}
|
|
174
|
-
const plain = await this.currentSocketPromise
|
|
168
|
+
public async upgradeToTls(options: ConnectionOptions, socketRef: { current: Socket }): Promise<void> {
|
|
169
|
+
const plain = socketRef.current
|
|
175
170
|
plain.removeAllListeners('data')
|
|
176
171
|
this.buffer = Buffer.alloc(0)
|
|
177
172
|
|
|
178
173
|
const { connect: tlsConnect } = await import('node:tls')
|
|
179
174
|
const secured = tlsConnect({ ...options, socket: plain })
|
|
180
175
|
|
|
176
|
+
// Permanent no-op handler attached up front, so errors that arrive in
|
|
177
|
+
// the microtask gap after secureConnect resolves don't become
|
|
178
|
+
// uncaughtException. The underlying TCP socket's 'close' drives reconnect.
|
|
179
|
+
secured.on('error', () => undefined)
|
|
180
|
+
|
|
181
181
|
await new Promise<void>((resolve, reject) => {
|
|
182
182
|
const onError = (err: Error) => {
|
|
183
183
|
secured.off('secureConnect', onConnect)
|
|
@@ -192,7 +192,7 @@ class TCPHandle<T> {
|
|
|
192
192
|
})
|
|
193
193
|
|
|
194
194
|
this.attachDataListener(secured)
|
|
195
|
-
|
|
195
|
+
socketRef.current = secured
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
private attachDataListener(socket: NodeJS.ReadableStream) {
|
|
@@ -209,7 +209,7 @@ class TCPHandle<T> {
|
|
|
209
209
|
private async connect(
|
|
210
210
|
host: string,
|
|
211
211
|
port: number,
|
|
212
|
-
onConnected: () => Promise<void>,
|
|
212
|
+
onConnected: (socketRef: { current: Socket }) => Promise<void>,
|
|
213
213
|
onClose: () => void,
|
|
214
214
|
): Promise<Socket> {
|
|
215
215
|
const { connect } = await import('node:net')
|
|
@@ -217,42 +217,60 @@ class TCPHandle<T> {
|
|
|
217
217
|
const socket = connect({ host, port }).setKeepAlive(true)
|
|
218
218
|
this.buffer = Buffer.alloc(0)
|
|
219
219
|
|
|
220
|
-
|
|
220
|
+
// Mutable holder so upgradeToTls can swap the socket mid-handshake;
|
|
221
|
+
// the negotiator's sendSession reads .current at write time, so frames
|
|
222
|
+
// always go to the active socket even after the TLS upgrade.
|
|
223
|
+
const socketRef = { current: socket }
|
|
224
|
+
|
|
225
|
+
await new Promise<void>((resolve, reject) => {
|
|
226
|
+
let connected = false
|
|
227
|
+
|
|
221
228
|
socket.once('connect', () => {
|
|
229
|
+
connected = true
|
|
222
230
|
resolve()
|
|
223
231
|
})
|
|
224
232
|
|
|
225
233
|
socket.once('error', (err) => {
|
|
226
|
-
if (!
|
|
227
|
-
|
|
234
|
+
if (!connected) {
|
|
235
|
+
reject(err)
|
|
228
236
|
}
|
|
237
|
+
// Post-connect errors are followed by 'close', which drives reconnect;
|
|
238
|
+
// this listener exists only to prevent uncaughtException.
|
|
229
239
|
})
|
|
230
240
|
|
|
231
241
|
socket.once('close', () => {
|
|
232
|
-
socket
|
|
242
|
+
// socketRef.current is the TLS-upgraded socket if upgrade ran; the
|
|
243
|
+
// plain one otherwise. Both cases hold the only live data listener.
|
|
244
|
+
socketRef.current.removeAllListeners('data')
|
|
245
|
+
|
|
233
246
|
if (!this.closing) {
|
|
234
|
-
onClose()
|
|
247
|
+
if (connected) onClose()
|
|
235
248
|
|
|
236
249
|
this.connectionAttempts++
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
250
|
+
// Swallow the rejection of the now-orphaned previous promise; any
|
|
251
|
+
// in-flight get() awaiter still sees it via their captured reference.
|
|
252
|
+
const previous = this.currentSocketPromise
|
|
253
|
+
this.currentSocketPromise =
|
|
254
|
+
this.connectionAttempts < 3 ? this.connect(host, port, onConnected, onClose) : null
|
|
255
|
+
previous?.catch(() => undefined)
|
|
242
256
|
}
|
|
257
|
+
|
|
258
|
+
if (!connected) reject(new Error('Socket closed before connect'))
|
|
243
259
|
})
|
|
244
260
|
|
|
245
261
|
this.attachDataListener(socket)
|
|
246
262
|
})
|
|
247
263
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
264
|
+
try {
|
|
265
|
+
await onConnected(socketRef)
|
|
266
|
+
} catch (err) {
|
|
267
|
+
// Handshake failures (timeout, bad response) leave the socket open
|
|
268
|
+
// otherwise; destroy it so the 'close' handler drives reconnect.
|
|
269
|
+
socketRef.current.destroy()
|
|
270
|
+
throw err
|
|
271
|
+
}
|
|
254
272
|
this.connectionAttempts = 0
|
|
255
273
|
|
|
256
|
-
return
|
|
274
|
+
return socketRef.current
|
|
257
275
|
}
|
|
258
276
|
}
|