braid-http 1.0.5 → 1.0.6
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/braid-http-client.js +40 -19
- package/braid-http-server.js +16 -0
- package/package.json +1 -1
package/braid-http-client.js
CHANGED
|
@@ -169,6 +169,9 @@ async function braid_fetch (url, params = {}) {
|
|
|
169
169
|
params.headers.set('subscribe', 'true')
|
|
170
170
|
if (params.peer)
|
|
171
171
|
params.headers.set('peer', params.peer)
|
|
172
|
+
|
|
173
|
+
if (params.heartbeats)
|
|
174
|
+
params.headers.set('heartbeats', typeof params.heartbeats === 'number' ? `${params.heartbeats}s` : params.heartbeats)
|
|
172
175
|
|
|
173
176
|
// Prevent browsers from going to disk cache
|
|
174
177
|
params.cache = 'no-cache'
|
|
@@ -225,8 +228,23 @@ async function braid_fetch (url, params = {}) {
|
|
|
225
228
|
return await new Promise((done, fail) => {
|
|
226
229
|
connect()
|
|
227
230
|
async function connect() {
|
|
231
|
+
let on_error = e => {
|
|
232
|
+
on_error = () => {}
|
|
233
|
+
|
|
234
|
+
if (!params.retry || (e.name === "AbortError")) {
|
|
235
|
+
subscription_error?.(e)
|
|
236
|
+
return fail(e)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
underlying_aborter.abort()
|
|
240
|
+
|
|
241
|
+
console.log(`retrying in ${waitTime}ms: ${url} after error: ${e}`)
|
|
242
|
+
setTimeout(connect, waitTime)
|
|
243
|
+
waitTime = Math.min(waitTime * 2, 3000)
|
|
244
|
+
}
|
|
245
|
+
|
|
228
246
|
try {
|
|
229
|
-
if (original_signal?.aborted)
|
|
247
|
+
if (original_signal?.aborted) throw new DOMException('already aborted', 'AbortError')
|
|
230
248
|
|
|
231
249
|
// We need a fresh underlying abort controller each time we connect
|
|
232
250
|
underlying_aborter = new AbortController()
|
|
@@ -257,6 +275,22 @@ async function braid_fetch (url, params = {}) {
|
|
|
257
275
|
subscription_cb = cb
|
|
258
276
|
subscription_error = error
|
|
259
277
|
|
|
278
|
+
// heartbeat
|
|
279
|
+
let on_heartbeat = () => {}
|
|
280
|
+
if (res.headers.get('heartbeats')) {
|
|
281
|
+
let heartbeats = parseFloat(res.headers.get('heartbeats'))
|
|
282
|
+
if (isFinite(heartbeats)) {
|
|
283
|
+
let timeout = null
|
|
284
|
+
on_heartbeat = () => {
|
|
285
|
+
clearTimeout(timeout)
|
|
286
|
+
timeout = setTimeout(() => {
|
|
287
|
+
on_error(new Error(`heartbeat not seen in ${(1.2 * heartbeats).toFixed(2)}s`))
|
|
288
|
+
}, 1.2 * heartbeats * 1000)
|
|
289
|
+
}
|
|
290
|
+
on_heartbeat()
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
260
294
|
if (!res.ok)
|
|
261
295
|
throw new Error('Request returned not ok status:', res.status)
|
|
262
296
|
|
|
@@ -274,20 +308,17 @@ async function braid_fetch (url, params = {}) {
|
|
|
274
308
|
if (!err)
|
|
275
309
|
// Yay! We got a new version! Tell the callback!
|
|
276
310
|
cb(result)
|
|
277
|
-
else
|
|
311
|
+
else
|
|
278
312
|
// This error handling code runs if the connection
|
|
279
313
|
// closes, or if there is unparseable stuff in the
|
|
280
314
|
// streamed response.
|
|
281
|
-
|
|
282
|
-
// In any case, we want to be sure to abort the
|
|
283
|
-
// underlying fetch.
|
|
284
|
-
underlying_aborter.abort()
|
|
285
|
-
|
|
286
315
|
on_error(err)
|
|
287
|
-
}
|
|
288
316
|
},
|
|
289
317
|
!isTextContentType(res.headers.get('content-type')),
|
|
290
|
-
|
|
318
|
+
(...args) => {
|
|
319
|
+
on_heartbeat()
|
|
320
|
+
params.onBytes?.(...args)
|
|
321
|
+
}
|
|
291
322
|
)
|
|
292
323
|
}
|
|
293
324
|
|
|
@@ -366,16 +397,6 @@ async function braid_fetch (url, params = {}) {
|
|
|
366
397
|
waitTime = 10
|
|
367
398
|
} catch (e) { on_error(e) }
|
|
368
399
|
}
|
|
369
|
-
function on_error(e) {
|
|
370
|
-
if (!params.retry || (e.name === "AbortError")) {
|
|
371
|
-
subscription_error?.(e)
|
|
372
|
-
return fail(e)
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
console.log(`retrying in ${waitTime}ms: ${url} after error: ${e}`)
|
|
376
|
-
setTimeout(connect, waitTime)
|
|
377
|
-
waitTime = Math.min(waitTime * 2, 3000)
|
|
378
|
-
}
|
|
379
400
|
})
|
|
380
401
|
}
|
|
381
402
|
|
package/braid-http-server.js
CHANGED
|
@@ -270,6 +270,22 @@ function braidify (req, res, next) {
|
|
|
270
270
|
res.on('close', x => disconnected('close'))
|
|
271
271
|
res.on('finish', x => disconnected('finish'))
|
|
272
272
|
req.on('abort', x => disconnected('abort'))
|
|
273
|
+
|
|
274
|
+
// Heartbeats
|
|
275
|
+
if (req.headers['heartbeats']) {
|
|
276
|
+
let heartbeats = parseFloat(req.headers['heartbeats'])
|
|
277
|
+
if (isFinite(heartbeats)) {
|
|
278
|
+
res.setHeader('heartbeats', req.headers['heartbeats'])
|
|
279
|
+
let closed
|
|
280
|
+
res.on('close', () => closed = true)
|
|
281
|
+
loop()
|
|
282
|
+
function loop() {
|
|
283
|
+
if (res.writableEnded || closed) return
|
|
284
|
+
res.write("\r\n")
|
|
285
|
+
setTimeout(loop, 1000 * heartbeats)
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
273
289
|
}
|
|
274
290
|
|
|
275
291
|
// Check the Useragent to work around Firefox bugs
|