braid-http 1.3.50 → 1.3.52
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 +52 -37
- package/package.json +1 -1
package/braid-http-client.js
CHANGED
|
@@ -266,9 +266,13 @@ async function braid_fetch (url, params = {}) {
|
|
|
266
266
|
// see if we should retry..
|
|
267
267
|
var retry = params.retry && // only try to reconnect if the user has chosen to
|
|
268
268
|
e.name !== "AbortError" && // don't retry if the user has chosen to abort
|
|
269
|
-
!e.
|
|
270
|
-
!
|
|
271
|
-
|
|
269
|
+
!e.dont_retry && // some errors are unlikely to be fixed by retrying
|
|
270
|
+
!cb_running // if an error is thrown in the callback,
|
|
271
|
+
// then it may not be good to reconnect, and generate more errors
|
|
272
|
+
|
|
273
|
+
// some errors can be fixed by changing something, and retrying right away,
|
|
274
|
+
// for instance, for a duplicate multiplexer request id
|
|
275
|
+
if (e.dont_wait) waitTime = 0
|
|
272
276
|
|
|
273
277
|
if (retry && !original_signal?.aborted) {
|
|
274
278
|
// retry after some time..
|
|
@@ -278,7 +282,7 @@ async function braid_fetch (url, params = {}) {
|
|
|
278
282
|
} else {
|
|
279
283
|
// if we would have retried except that original_signal?.aborted,
|
|
280
284
|
// then we want to return that as the error..
|
|
281
|
-
if (retry && original_signal?.aborted) e =
|
|
285
|
+
if (retry && original_signal?.aborted) e = create_error('already aborted', {name: 'AbortError'})
|
|
282
286
|
|
|
283
287
|
// let people know things are shutting down..
|
|
284
288
|
subscription_counts_on_close?.()
|
|
@@ -288,7 +292,7 @@ async function braid_fetch (url, params = {}) {
|
|
|
288
292
|
}
|
|
289
293
|
|
|
290
294
|
try {
|
|
291
|
-
if (original_signal?.aborted) throw
|
|
295
|
+
if (original_signal?.aborted) throw create_error('already aborted', {name: 'AbortError'})
|
|
292
296
|
|
|
293
297
|
// We need a fresh underlying abort controller each time we connect
|
|
294
298
|
underlying_aborter = new AbortController()
|
|
@@ -304,7 +308,7 @@ async function braid_fetch (url, params = {}) {
|
|
|
304
308
|
// undocumented feature used by braid-chrome
|
|
305
309
|
// to see the fetch args as they are right before it is actually called,
|
|
306
310
|
// to display them for the user in the dev panel
|
|
307
|
-
params.onFetch?.(url, params)
|
|
311
|
+
params.onFetch?.(url, params, underlying_aborter)
|
|
308
312
|
|
|
309
313
|
// Now we run the original fetch....
|
|
310
314
|
|
|
@@ -363,7 +367,7 @@ async function braid_fetch (url, params = {}) {
|
|
|
363
367
|
if (!err) {
|
|
364
368
|
// check whether we aborted
|
|
365
369
|
if (original_signal?.aborted)
|
|
366
|
-
throw
|
|
370
|
+
throw create_error('already aborted', {name: 'AbortError'})
|
|
367
371
|
|
|
368
372
|
// Yay! We got a new version! Tell the callback!
|
|
369
373
|
cb_running = true
|
|
@@ -442,19 +446,16 @@ async function braid_fetch (url, params = {}) {
|
|
|
442
446
|
give_up = false
|
|
443
447
|
}
|
|
444
448
|
if (give_up) {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
return fail(e)
|
|
448
|
-
}
|
|
449
|
-
if (!res.ok) throw new Error(`status not ok: ${res.status}`)
|
|
449
|
+
if (subscription_cb) subscription_error?.(new Error(`giving up because of http status: ${res.status}${(res.status === 401 || res.status === 403) ? ` (access denied)` : ''}`))
|
|
450
|
+
} else if (!res.ok) throw new Error(`status not ok: ${res.status}`)
|
|
450
451
|
}
|
|
451
452
|
|
|
452
|
-
if (subscription_cb) start_subscription(subscription_cb, subscription_error)
|
|
453
|
-
|
|
454
|
-
done(res)
|
|
453
|
+
if (subscription_cb && res.ok) start_subscription(subscription_cb, subscription_error)
|
|
455
454
|
|
|
456
455
|
params?.retry?.onRes?.(res)
|
|
457
456
|
waitTime = 1
|
|
457
|
+
|
|
458
|
+
done(res)
|
|
458
459
|
} catch (e) { on_error(e) }
|
|
459
460
|
}
|
|
460
461
|
})
|
|
@@ -566,7 +567,7 @@ var subscription_parser = (cb) => ({
|
|
|
566
567
|
|
|
567
568
|
// Or maybe there's an error to report upstream
|
|
568
569
|
else if (this.state.result === 'error') {
|
|
569
|
-
await this.cb(null, this.state.message)
|
|
570
|
+
await this.cb(null, create_error(this.state.message, {dont_retry: true}))
|
|
570
571
|
return
|
|
571
572
|
}
|
|
572
573
|
|
|
@@ -872,9 +873,9 @@ function ascii_ify(s) {
|
|
|
872
873
|
return s.replace(/[^\x20-\x7E]/g, c => '\\u' + c.charCodeAt(0).toString(16).padStart(4, '0'))
|
|
873
874
|
}
|
|
874
875
|
|
|
875
|
-
function
|
|
876
|
+
function create_error(msg, override) {
|
|
876
877
|
var e = new Error(msg)
|
|
877
|
-
e
|
|
878
|
+
if (override) Object.assign(e, override)
|
|
878
879
|
return e
|
|
879
880
|
}
|
|
880
881
|
|
|
@@ -915,6 +916,8 @@ async function multiplex_fetch(url, params, mux_params, aborter) {
|
|
|
915
916
|
var requests = new Map()
|
|
916
917
|
var mux_error = null
|
|
917
918
|
var try_deleting = new Set()
|
|
919
|
+
var not_used_timeout = null
|
|
920
|
+
var mux_aborter = new AbortController()
|
|
918
921
|
|
|
919
922
|
function cleanup(e, stay_dead) {
|
|
920
923
|
// the multiplexer stream has died.. let everyone know..
|
|
@@ -951,6 +954,7 @@ async function multiplex_fetch(url, params, mux_params, aborter) {
|
|
|
951
954
|
try {
|
|
952
955
|
if (mux_params?.via === 'POST') throw 'skip multiplex method'
|
|
953
956
|
var r = await braid_fetch(`${origin}/${multiplexer}`, {
|
|
957
|
+
signal: mux_aborter.signal,
|
|
954
958
|
method: 'MULTIPLEX',
|
|
955
959
|
headers: {'Multiplex-Version': multiplex_version},
|
|
956
960
|
retry: true
|
|
@@ -958,7 +962,7 @@ async function multiplex_fetch(url, params, mux_params, aborter) {
|
|
|
958
962
|
if (r.status === 409) {
|
|
959
963
|
var e = await r.json()
|
|
960
964
|
if (e.error === 'Multiplexer already exists')
|
|
961
|
-
return cleanup(
|
|
965
|
+
return cleanup(create_error(e.error, {dont_wait: true}))
|
|
962
966
|
}
|
|
963
967
|
if (!r.ok || r.headers.get('Multiplex-Version') !== multiplex_version)
|
|
964
968
|
throw 'bad'
|
|
@@ -968,12 +972,13 @@ async function multiplex_fetch(url, params, mux_params, aborter) {
|
|
|
968
972
|
try {
|
|
969
973
|
r = await braid_fetch(`${origin}/.well-known/multiplexer/${multiplexer}`,
|
|
970
974
|
{method: 'POST',
|
|
975
|
+
signal: mux_aborter.signal,
|
|
971
976
|
headers: {'Multiplex-Version': multiplex_version},
|
|
972
977
|
retry: true})
|
|
973
978
|
if (r.status === 409) {
|
|
974
979
|
var e = await r.json()
|
|
975
980
|
if (e.error === 'Multiplexer already exists')
|
|
976
|
-
return cleanup(
|
|
981
|
+
return cleanup(create_error(e.error, {dont_wait: true}))
|
|
977
982
|
}
|
|
978
983
|
if (!r.ok) throw new Error('status not ok: ' + r.status)
|
|
979
984
|
if (r.headers.get('Multiplex-Version') !== multiplex_version)
|
|
@@ -1047,9 +1052,11 @@ async function multiplex_fetch(url, params, mux_params, aborter) {
|
|
|
1047
1052
|
})
|
|
1048
1053
|
|
|
1049
1054
|
// prepare a function that we'll call to cleanly tear things down
|
|
1055
|
+
clearTimeout(not_used_timeout)
|
|
1050
1056
|
var unset = async e => {
|
|
1051
1057
|
unset = () => {}
|
|
1052
1058
|
requests.delete(request)
|
|
1059
|
+
if (!requests.size) not_used_timeout = setTimeout(() => mux_aborter.abort(), mux_params?.not_used_timeout ?? 1000 * 20)
|
|
1053
1060
|
request_error = e
|
|
1054
1061
|
bytes_available()
|
|
1055
1062
|
await try_deleting_request(request)
|
|
@@ -1060,13 +1067,20 @@ async function multiplex_fetch(url, params, mux_params, aborter) {
|
|
|
1060
1067
|
var res = await normal_fetch(url, params)
|
|
1061
1068
|
|
|
1062
1069
|
if (res.status === 409) {
|
|
1063
|
-
var e = await
|
|
1064
|
-
if (e.error === 'Request already multiplexed')
|
|
1070
|
+
var e = await res.json()
|
|
1071
|
+
if (e.error === 'Request already multiplexed') {
|
|
1072
|
+
// the id is already in use,
|
|
1073
|
+
// so we want to retry right away with a different id
|
|
1074
|
+
throw create_error(e.error, {dont_wait: true})
|
|
1075
|
+
}
|
|
1065
1076
|
}
|
|
1066
1077
|
|
|
1067
1078
|
if (res.status === 424) {
|
|
1068
|
-
//
|
|
1069
|
-
|
|
1079
|
+
// the multiplexer isn't there,
|
|
1080
|
+
// could be we arrived before the multiplexer,
|
|
1081
|
+
// or after it was shutdown;
|
|
1082
|
+
// in either case we want to retry right away
|
|
1083
|
+
throw create_error('multiplexer not connected', {dont_wait: true})
|
|
1070
1084
|
}
|
|
1071
1085
|
|
|
1072
1086
|
// if the response says it's ok,
|
|
@@ -1075,21 +1089,23 @@ async function multiplex_fetch(url, params, mux_params, aborter) {
|
|
|
1075
1089
|
if (res.ok && res.status !== 293) return res
|
|
1076
1090
|
|
|
1077
1091
|
if (res.status !== 293)
|
|
1078
|
-
throw
|
|
1079
|
-
|
|
1080
|
-
|
|
1092
|
+
throw create_error('Could not establish multiplexed request '
|
|
1093
|
+
+ params.headers.get('multiplex-through')
|
|
1094
|
+
+ ', got status: ' + res.status,
|
|
1095
|
+
{ dont_retry: true })
|
|
1081
1096
|
|
|
1082
1097
|
if (res.headers.get('Multiplex-Version') !== multiplex_version)
|
|
1083
|
-
throw
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1098
|
+
throw create_error('Could not establish multiplexed request '
|
|
1099
|
+
+ params.headers.get('multiplex-through')
|
|
1100
|
+
+ ', got unknown version: '
|
|
1101
|
+
+ res.headers.get('Multiplex-Version'),
|
|
1102
|
+
{ dont_retry: true })
|
|
1087
1103
|
|
|
1088
1104
|
// we want to present the illusion that the connection is still open,
|
|
1089
1105
|
// and therefor closable with "abort",
|
|
1090
1106
|
// so we handle the abort ourselves to close the multiplexed request
|
|
1091
|
-
params.signal
|
|
1092
|
-
unset(
|
|
1107
|
+
params.signal.addEventListener('abort', () =>
|
|
1108
|
+
unset(create_error('request aborted', {name: 'AbortError'})))
|
|
1093
1109
|
|
|
1094
1110
|
// first, we need to listen for the headers..
|
|
1095
1111
|
var headers_buffer = new Uint8Array()
|
|
@@ -1135,12 +1151,11 @@ async function multiplex_fetch(url, params, mux_params, aborter) {
|
|
|
1135
1151
|
try {
|
|
1136
1152
|
await process_buffers(() => {
|
|
1137
1153
|
var b = buffers.shift()
|
|
1138
|
-
if (!b)
|
|
1139
|
-
if (mux_error || request_error) controller.error(mux_error || request_error)
|
|
1140
|
-
return true
|
|
1141
|
-
}
|
|
1154
|
+
if (!b) return true
|
|
1142
1155
|
controller.enqueue(b)
|
|
1143
1156
|
})
|
|
1157
|
+
} catch (e) {
|
|
1158
|
+
controller.error(e)
|
|
1144
1159
|
} finally { controller.close() }
|
|
1145
1160
|
}
|
|
1146
1161
|
}), {
|