@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.
Files changed (33) hide show
  1. package/dist/cjs/sender/enveloperesolver.js +2 -2
  2. package/dist/cjs/sender/enveloperesolver.js.map +1 -1
  3. package/dist/cjs/sender/sender.js +6 -0
  4. package/dist/cjs/sender/sender.js.map +1 -1
  5. package/dist/cjs/sender/sessionnegotiator.js +15 -7
  6. package/dist/cjs/sender/sessionnegotiator.js.map +1 -1
  7. package/dist/cjs/sender/tcp/tcpsender.js +47 -31
  8. package/dist/cjs/sender/tcp/tcpsender.js.map +1 -1
  9. package/dist/cjs/sender/websocket/websocketsender.js +40 -12
  10. package/dist/cjs/sender/websocket/websocketsender.js.map +1 -1
  11. package/dist/esm/sender/enveloperesolver.js +2 -2
  12. package/dist/esm/sender/enveloperesolver.js.map +1 -1
  13. package/dist/esm/sender/sender.js +6 -0
  14. package/dist/esm/sender/sender.js.map +1 -1
  15. package/dist/esm/sender/sessionnegotiator.js +15 -7
  16. package/dist/esm/sender/sessionnegotiator.js.map +1 -1
  17. package/dist/esm/sender/tcp/tcpsender.js +47 -31
  18. package/dist/esm/sender/tcp/tcpsender.js.map +1 -1
  19. package/dist/esm/sender/websocket/websocketsender.js +40 -12
  20. package/dist/esm/sender/websocket/websocketsender.js.map +1 -1
  21. package/dist/types/sender/enveloperesolver.d.ts +1 -1
  22. package/dist/types/sender/enveloperesolver.d.ts.map +1 -1
  23. package/dist/types/sender/sender.d.ts +1 -0
  24. package/dist/types/sender/sender.d.ts.map +1 -1
  25. package/dist/types/sender/sessionnegotiator.d.ts +2 -0
  26. package/dist/types/sender/sessionnegotiator.d.ts.map +1 -1
  27. package/dist/types/sender/tcp/tcpsender.d.ts.map +1 -1
  28. package/package.json +1 -1
  29. package/src/sender/enveloperesolver.ts +2 -2
  30. package/src/sender/sender.ts +7 -0
  31. package/src/sender/sessionnegotiator.ts +16 -7
  32. package/src/sender/tcp/tcpsender.ts +51 -33
  33. package/src/sender/websocket/websocketsender.ts +40 -14
@@ -39,7 +39,7 @@ export class WebSocketSender extends OpenConnectionSender {
39
39
  authentication: options.authentication,
40
40
  })
41
41
  },
42
- () => this.envelopeResolver.rejectPendingEnvelopes('Connection was closed'),
42
+ () => this.rejectPending('Connection was closed'),
43
43
  (envelope: Envelope) => {
44
44
  if (this.sessionNegotiator?.negotiating) {
45
45
  return this.sessionNegotiator.handleEnvelope(envelope)
@@ -139,7 +139,10 @@ class WebSocketHandle<T> {
139
139
  }
140
140
 
141
141
  public get() {
142
- return this.currentWebSocketPromise!
142
+ if (!this.currentWebSocketPromise) {
143
+ throw new Error('WebSocket connection is not available.')
144
+ }
145
+ return this.currentWebSocketPromise
143
146
  }
144
147
 
145
148
  public async close() {
@@ -159,31 +162,54 @@ class WebSocketHandle<T> {
159
162
  const connection = new WebSocket(url, 'lime')
160
163
 
161
164
  await new Promise<void>((resolve, reject) => {
165
+ let connected = false
166
+
162
167
  connection.onopen = () => {
168
+ connected = true
163
169
  resolve()
164
170
  }
171
+ connection.onerror = (err) => {
172
+ if (!connected) {
173
+ reject('message' in err ? new Error(`WebSocket error: ${err.message}`, { cause: err }) : err)
174
+ }
175
+ // Post-open errors are followed by 'close', which drives reconnect.
176
+ }
165
177
  connection.onclose = () => {
166
178
  if (!this.closing) {
167
- this.connectionAttempts++
168
-
169
- if (this.connectionAttempts < 3) {
170
- this.currentWebSocketPromise = this.connect(url, onConnected, onClose, onMessage)
171
- } else {
172
- reject(new Error('Failed to connect to WebSocket'))
173
- }
179
+ if (connected) onClose()
174
180
 
175
- onClose()
181
+ this.connectionAttempts++
182
+ // Swallow the rejection of the now-orphaned previous promise; any
183
+ // in-flight get() awaiter still sees it via their captured reference.
184
+ const previous = this.currentWebSocketPromise
185
+ this.currentWebSocketPromise =
186
+ this.connectionAttempts < 3 ? this.connect(url, onConnected, onClose, onMessage) : null
187
+ previous?.catch(() => undefined)
176
188
  }
189
+
190
+ if (!connected) reject(new Error('WebSocket closed before open'))
177
191
  }
178
192
  connection.onmessage = (event) => {
179
193
  onMessage(JSON.parse(event.data))
180
194
  }
181
- connection.onerror = (err) => {
182
- reject('message' in err ? new Error(`WebSocket error: ${err.message}`, { cause: err }) : err)
183
- }
184
195
  })
185
196
 
186
- await onConnected(connection)
197
+ try {
198
+ await onConnected(connection)
199
+ } catch (err) {
200
+ // Handshake failures leave the socket open otherwise; tear it down so
201
+ // the 'onclose' handler drives reconnect. Prefer ws.terminate() (hard
202
+ // kill, Node only) to avoid waiting on the graceful close handshake
203
+ // with a peer that just failed to negotiate; fall back to close() in
204
+ // browsers where terminate() doesn't exist.
205
+ const terminable = connection as WebSocket & { terminate?: () => void }
206
+ if (terminable.terminate) {
207
+ terminable.terminate()
208
+ } else {
209
+ connection.close()
210
+ }
211
+ throw err
212
+ }
187
213
  this.connectionAttempts = 0
188
214
 
189
215
  return connection