braid-http 1.0.5 → 1.0.7
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 +41 -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,23 @@ 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
|
+
let wait_seconds = 1.2 * heartbeats + 3
|
|
287
|
+
timeout = setTimeout(() => {
|
|
288
|
+
on_error(new Error(`heartbeat not seen in ${wait_seconds.toFixed(2)}s`))
|
|
289
|
+
}, wait_seconds * 1000)
|
|
290
|
+
}
|
|
291
|
+
on_heartbeat()
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
260
295
|
if (!res.ok)
|
|
261
296
|
throw new Error('Request returned not ok status:', res.status)
|
|
262
297
|
|
|
@@ -274,20 +309,17 @@ async function braid_fetch (url, params = {}) {
|
|
|
274
309
|
if (!err)
|
|
275
310
|
// Yay! We got a new version! Tell the callback!
|
|
276
311
|
cb(result)
|
|
277
|
-
else
|
|
312
|
+
else
|
|
278
313
|
// This error handling code runs if the connection
|
|
279
314
|
// closes, or if there is unparseable stuff in the
|
|
280
315
|
// streamed response.
|
|
281
|
-
|
|
282
|
-
// In any case, we want to be sure to abort the
|
|
283
|
-
// underlying fetch.
|
|
284
|
-
underlying_aborter.abort()
|
|
285
|
-
|
|
286
316
|
on_error(err)
|
|
287
|
-
}
|
|
288
317
|
},
|
|
289
318
|
!isTextContentType(res.headers.get('content-type')),
|
|
290
|
-
|
|
319
|
+
(...args) => {
|
|
320
|
+
on_heartbeat()
|
|
321
|
+
params.onBytes?.(...args)
|
|
322
|
+
}
|
|
291
323
|
)
|
|
292
324
|
}
|
|
293
325
|
|
|
@@ -366,16 +398,6 @@ async function braid_fetch (url, params = {}) {
|
|
|
366
398
|
waitTime = 10
|
|
367
399
|
} catch (e) { on_error(e) }
|
|
368
400
|
}
|
|
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
401
|
})
|
|
380
402
|
}
|
|
381
403
|
|
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
|