braid-http 1.3.49 → 1.3.50

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.
@@ -315,7 +315,7 @@ async function braid_fetch (url, params = {}) {
315
315
  (params.headers.has('subscribe') &&
316
316
  braid_fetch.subscription_counts?.[origin] >
317
317
  (!mux_params ? 1 : (mux_params.after ?? 0))))) {
318
- res = await multiplex_fetch(url, params, mux_params)
318
+ res = await multiplex_fetch(url, params, mux_params, underlying_aborter)
319
319
  } else
320
320
  res = await normal_fetch(url, params)
321
321
 
@@ -830,9 +830,72 @@ function parse_body (state) {
830
830
  }
831
831
  }
832
832
 
833
+
834
+ // The "extra_headers" field is returned to the client on any *update* or
835
+ // *patch* to include any headers that we've received, but don't have braid
836
+ // semantics for.
837
+ //
838
+ // This function creates that hash from a headers object, by filtering out all
839
+ // known headers.
840
+ function extra_headers (headers) {
841
+ // Clone headers
842
+ var result = Object.assign({}, headers)
843
+
844
+ // Remove the non-extra parts
845
+ var known_headers = ['version', 'parents', 'patches',
846
+ 'content-length', 'content-range', ':status']
847
+ for (var i = 0; i < known_headers.length; i++)
848
+ delete result[known_headers[i]]
849
+
850
+ // Return undefined if we deleted them all
851
+ if (Object.keys(result).length === 0)
852
+ return undefined
853
+
854
+ return result
855
+ }
856
+
857
+ function get_binary_length(x) {
858
+ return x instanceof ArrayBuffer ? x.byteLength :
859
+ x instanceof Uint8Array ? x.length :
860
+ x instanceof Blob ? x.size : undefined
861
+ }
862
+
863
+ function deep_copy(x) {
864
+ if (x === null || typeof x !== 'object') return x
865
+ if (Array.isArray(x)) return x.map(x => deep_copy(x))
866
+ if (Object.prototype.toString.call(x) === '[object Object]')
867
+ return Object.fromEntries(Object.entries(x).map(([k, x]) => [k, deep_copy(x)]))
868
+ return x
869
+ }
870
+
871
+ function ascii_ify(s) {
872
+ return s.replace(/[^\x20-\x7E]/g, c => '\\u' + c.charCodeAt(0).toString(16).padStart(4, '0'))
873
+ }
874
+
875
+ function create_abort_error(msg) {
876
+ var e = new Error(msg)
877
+ e.name = 'AbortError'
878
+ return e
879
+ }
880
+
881
+ async function promise_done(promise) {
882
+ var pending = {}
883
+ var ret = await Promise.race([promise, Promise.resolve(pending)])
884
+ return ret !== pending
885
+ }
886
+
887
+ function random_base64url(n) {
888
+ return [...crypto.getRandomValues(new Uint8Array(n))].map(x => 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'[x % 64]).join('')
889
+ }
890
+
891
+
892
+ // ****************************
893
+ // Multiplexing
894
+ // ****************************
895
+
833
896
  // multiplex_fetch provides a fetch-like experience for HTTP requests
834
897
  // where the result is actually being sent over a separate multiplexed connection.
835
- async function multiplex_fetch(url, params, mux_params) {
898
+ async function multiplex_fetch(url, params, mux_params, aborter) {
836
899
  var multiplex_version = '1.0'
837
900
 
838
901
  var origin = new URL(url, typeof document !== 'undefined' ? document.baseURI : undefined).origin
@@ -894,7 +957,8 @@ async function multiplex_fetch(url, params, mux_params) {
894
957
  })
895
958
  if (r.status === 409) {
896
959
  var e = await r.json()
897
- if (e.error === 'Multiplexer already exists') return cleanup(new Error(e.error))
960
+ if (e.error === 'Multiplexer already exists')
961
+ return cleanup(new Error(e.error))
898
962
  }
899
963
  if (!r.ok || r.headers.get('Multiplex-Version') !== multiplex_version)
900
964
  throw 'bad'
@@ -908,7 +972,8 @@ async function multiplex_fetch(url, params, mux_params) {
908
972
  retry: true})
909
973
  if (r.status === 409) {
910
974
  var e = await r.json()
911
- if (e.error === 'Multiplexer already exists') return cleanup(new Error(e.error))
975
+ if (e.error === 'Multiplexer already exists')
976
+ return cleanup(new Error(e.error))
912
977
  }
913
978
  if (!r.ok) throw new Error('status not ok: ' + r.status)
914
979
  if (r.headers.get('Multiplex-Version') !== multiplex_version)
@@ -938,7 +1003,9 @@ async function multiplex_fetch(url, params, mux_params) {
938
1003
  // if we already know the multiplexer is not working,
939
1004
  // then fallback to normal fetch
940
1005
  // (unless the user is specifically asking for multiplexing)
941
- if ((await promise_done(mux_promise)) && (await mux_promise) === false && !params.headers.get('multiplex-through'))
1006
+ if ((await promise_done(mux_promise))
1007
+ && (await mux_promise) === false
1008
+ && !params.headers.get('multiplex-through'))
942
1009
  return await normal_fetch(url, params)
943
1010
 
944
1011
  // make up a new request id (unless it is being overriden)
@@ -972,8 +1039,10 @@ async function multiplex_fetch(url, params, mux_params) {
972
1039
 
973
1040
  // tell the multiplexer to send bytes for this request to us
974
1041
  requests.set(request, bytes => {
975
- if (!bytes) buffers.push(bytes)
976
- else if (!mux_error) buffers.push(bytes)
1042
+ if (!bytes) {
1043
+ buffers.push(bytes)
1044
+ if (mux_error || request_error) aborter.abort()
1045
+ } else if (!mux_error) buffers.push(bytes)
977
1046
  bytes_available()
978
1047
  })
979
1048
 
@@ -1066,7 +1135,10 @@ async function multiplex_fetch(url, params, mux_params) {
1066
1135
  try {
1067
1136
  await process_buffers(() => {
1068
1137
  var b = buffers.shift()
1069
- if (!b) return true
1138
+ if (!b) {
1139
+ if (mux_error || request_error) controller.error(mux_error || request_error)
1140
+ return true
1141
+ }
1070
1142
  controller.enqueue(b)
1071
1143
  })
1072
1144
  } finally { controller.close() }
@@ -1085,7 +1157,7 @@ async function multiplex_fetch(url, params, mux_params) {
1085
1157
  } catch (e) {
1086
1158
  // if we had an error, be sure to unregister ourselves
1087
1159
  unset(e)
1088
- throw e
1160
+ throw mux_error || e
1089
1161
  }
1090
1162
  }
1091
1163
  })()
@@ -1173,62 +1245,6 @@ function concat_buffers(buffers) {
1173
1245
  return x
1174
1246
  }
1175
1247
 
1176
- // The "extra_headers" field is returned to the client on any *update* or
1177
- // *patch* to include any headers that we've received, but don't have braid
1178
- // semantics for.
1179
- //
1180
- // This function creates that hash from a headers object, by filtering out all
1181
- // known headers.
1182
- function extra_headers (headers) {
1183
- // Clone headers
1184
- var result = Object.assign({}, headers)
1185
-
1186
- // Remove the non-extra parts
1187
- var known_headers = ['version', 'parents', 'patches',
1188
- 'content-length', 'content-range', ':status']
1189
- for (var i = 0; i < known_headers.length; i++)
1190
- delete result[known_headers[i]]
1191
-
1192
- // Return undefined if we deleted them all
1193
- if (Object.keys(result).length === 0)
1194
- return undefined
1195
-
1196
- return result
1197
- }
1198
-
1199
- function get_binary_length(x) {
1200
- return x instanceof ArrayBuffer ? x.byteLength :
1201
- x instanceof Uint8Array ? x.length :
1202
- x instanceof Blob ? x.size : undefined
1203
- }
1204
-
1205
- function deep_copy(x) {
1206
- if (x === null || typeof x !== 'object') return x
1207
- if (Array.isArray(x)) return x.map(x => deep_copy(x))
1208
- if (Object.prototype.toString.call(x) === '[object Object]')
1209
- return Object.fromEntries(Object.entries(x).map(([k, x]) => [k, deep_copy(x)]))
1210
- return x
1211
- }
1212
-
1213
- function ascii_ify(s) {
1214
- return s.replace(/[^\x20-\x7E]/g, c => '\\u' + c.charCodeAt(0).toString(16).padStart(4, '0'))
1215
- }
1216
-
1217
- function create_abort_error(msg) {
1218
- var e = new Error(msg)
1219
- e.name = 'AbortError'
1220
- return e
1221
- }
1222
-
1223
- async function promise_done(promise) {
1224
- var pending = {}
1225
- var ret = await Promise.race([promise, Promise.resolve(pending)])
1226
- return ret !== pending
1227
- }
1228
-
1229
- function random_base64url(n) {
1230
- return [...crypto.getRandomValues(new Uint8Array(n))].map(x => 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'[x % 64]).join('')
1231
- }
1232
1248
 
1233
1249
  // ****************************
1234
1250
  // Exports
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-http",
3
- "version": "1.3.49",
3
+ "version": "1.3.50",
4
4
  "description": "An implementation of Braid-HTTP for Node.js and Browsers",
5
5
  "scripts": {
6
6
  "test": "node test/server.js"