braid-http 1.1.1 → 1.2.0
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 +38 -10
- package/braid-http-server.js +28 -13
- package/package.json +1 -1
package/braid-http-client.js
CHANGED
|
@@ -189,18 +189,32 @@ async function braid_fetch (url, params = {}) {
|
|
|
189
189
|
if (params.patches.length === 1) {
|
|
190
190
|
let patch = params.patches[0]
|
|
191
191
|
params.headers.set('Content-Range', `${patch.unit} ${patch.range}`)
|
|
192
|
-
|
|
192
|
+
|
|
193
|
+
if (typeof patch.content === 'string')
|
|
194
|
+
patch.content = new TextEncoder().encode(patch.content)
|
|
195
|
+
|
|
196
|
+
params.headers.set('Content-Length', `${patch.content.length}`)
|
|
193
197
|
params.body = patch.content
|
|
194
198
|
}
|
|
195
199
|
|
|
196
200
|
// Multiple patches get sent within a Patches: N block
|
|
197
201
|
else {
|
|
198
202
|
params.headers.set('Patches', params.patches.length)
|
|
199
|
-
|
|
200
|
-
|
|
203
|
+
let bufs = []
|
|
204
|
+
let te = new TextEncoder()
|
|
205
|
+
for (let patch of params.patches) {
|
|
206
|
+
if (bufs.length) bufs.push(te.encode(`\r\n`))
|
|
207
|
+
|
|
208
|
+
if (typeof patch.content === 'string')
|
|
209
|
+
patch.content = te.encode(patch.content)
|
|
210
|
+
|
|
211
|
+
var length = `content-length: ${patch.content.length}`
|
|
201
212
|
var range = `content-range: ${patch.unit} ${patch.range}`
|
|
202
|
-
|
|
203
|
-
|
|
213
|
+
bufs.push(te.encode(`${length}\r\n${range}\r\n\r\n`))
|
|
214
|
+
bufs.push(patch.content)
|
|
215
|
+
bufs.push(te.encode(`\r\n`))
|
|
216
|
+
}
|
|
217
|
+
params.body = new Blob(bufs)
|
|
204
218
|
}
|
|
205
219
|
}
|
|
206
220
|
|
|
@@ -306,10 +320,13 @@ async function braid_fetch (url, params = {}) {
|
|
|
306
320
|
// Each time something happens, we'll either get a new
|
|
307
321
|
// version back, or an error.
|
|
308
322
|
(result, err) => {
|
|
309
|
-
if (!err)
|
|
323
|
+
if (!err) {
|
|
324
|
+
// check whether we aborted
|
|
325
|
+
if (original_signal?.aborted) throw new DOMException('already aborted', 'AbortError')
|
|
326
|
+
|
|
310
327
|
// Yay! We got a new version! Tell the callback!
|
|
311
328
|
cb(result)
|
|
312
|
-
else
|
|
329
|
+
} else
|
|
313
330
|
// This error handling code runs if the connection
|
|
314
331
|
// closes, or if there is unparseable stuff in the
|
|
315
332
|
// streamed response.
|
|
@@ -486,7 +503,18 @@ var subscription_parser = (cb) => ({
|
|
|
486
503
|
}
|
|
487
504
|
})
|
|
488
505
|
|
|
489
|
-
|
|
506
|
+
for (let p of update.patches ?? []) {
|
|
507
|
+
Object.defineProperty(p, 'content_text', {
|
|
508
|
+
get: () => new TextDecoder('utf-8').decode(p.content)
|
|
509
|
+
})
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
try {
|
|
513
|
+
this.cb(update)
|
|
514
|
+
} catch (e) {
|
|
515
|
+
this.cb(null, e)
|
|
516
|
+
return
|
|
517
|
+
}
|
|
490
518
|
|
|
491
519
|
// Reset the parser for the next version!
|
|
492
520
|
this.state = {input: this.state.input}
|
|
@@ -629,7 +657,7 @@ function parse_body (state) {
|
|
|
629
657
|
state.patches = [{
|
|
630
658
|
unit: match.unit,
|
|
631
659
|
range: match.range,
|
|
632
|
-
content:
|
|
660
|
+
content: new Uint8Array(state.input.slice(0, content_length)),
|
|
633
661
|
|
|
634
662
|
// Question: Perhaps we should include headers here, like we do for
|
|
635
663
|
// the Patches: N headers below?
|
|
@@ -715,7 +743,7 @@ function parse_body (state) {
|
|
|
715
743
|
|
|
716
744
|
last_patch.unit = match.unit
|
|
717
745
|
last_patch.range = match.range
|
|
718
|
-
last_patch.content =
|
|
746
|
+
last_patch.content = new Uint8Array(state.input.slice(0, content_length))
|
|
719
747
|
last_patch.extra_headers = extra_headers(last_patch.headers)
|
|
720
748
|
delete last_patch.headers // We only keep the extra headers ^^
|
|
721
749
|
|
package/braid-http-server.js
CHANGED
|
@@ -66,10 +66,14 @@ ${patch.content}`
|
|
|
66
66
|
// Deprecated method for legacy support
|
|
67
67
|
function parse_patches (req, cb) {
|
|
68
68
|
parse_update(req, update => {
|
|
69
|
-
if (
|
|
69
|
+
if (update.body != null) {
|
|
70
70
|
// Return body as an "everything" patch
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
let patch = {unit: 'everything', range: '', content: update.body}
|
|
72
|
+
Object.defineProperty(patch, 'content_text', {
|
|
73
|
+
get: () => new TextDecoder('utf-8').decode(patch.content)
|
|
74
|
+
})
|
|
75
|
+
cb([patch])
|
|
76
|
+
} else
|
|
73
77
|
cb(update.patches)
|
|
74
78
|
})
|
|
75
79
|
}
|
|
@@ -80,16 +84,20 @@ function parse_update (req, cb) {
|
|
|
80
84
|
var num_patches = req.headers.patches
|
|
81
85
|
|
|
82
86
|
if (!num_patches && !req.headers['content-range']) {
|
|
83
|
-
var
|
|
84
|
-
req.on('data', chunk =>
|
|
87
|
+
var buffer = []
|
|
88
|
+
req.on('data', chunk => buffer.push(chunk))
|
|
85
89
|
req.on('end', () => {
|
|
86
|
-
|
|
90
|
+
let body = new Uint8Array(Buffer.concat(buffer))
|
|
91
|
+
let update = { body, patches: undefined }
|
|
92
|
+
Object.defineProperty(update, 'body_text', {
|
|
93
|
+
get: () => new TextDecoder('utf-8').decode(update.body)
|
|
94
|
+
})
|
|
95
|
+
cb(update)
|
|
87
96
|
})
|
|
88
97
|
}
|
|
89
98
|
|
|
90
99
|
// Parse a single patch, lacking Patches: N
|
|
91
100
|
else if (num_patches === undefined && req.headers['content-range']) {
|
|
92
|
-
|
|
93
101
|
// We only support range patches right now, so there must be a
|
|
94
102
|
// Content-Range header.
|
|
95
103
|
assert(req.headers['content-range'], 'No patches to parse: need `Patches: N` or `Content-Range:` header in ' + JSON.stringify(req.headers))
|
|
@@ -104,8 +112,11 @@ function parse_update (req, cb) {
|
|
|
104
112
|
req.on('data', chunk => buffer.push(chunk))
|
|
105
113
|
// Then return it
|
|
106
114
|
req.on('end', () => {
|
|
107
|
-
|
|
108
|
-
|
|
115
|
+
let patch = {unit, range, content: new Uint8Array(Buffer.concat(buffer))}
|
|
116
|
+
Object.defineProperty(patch, 'content_text', {
|
|
117
|
+
get: () => new TextDecoder('utf-8').decode(patch.content)
|
|
118
|
+
})
|
|
119
|
+
cb({ patches: [patch], body: undefined })
|
|
109
120
|
})
|
|
110
121
|
}
|
|
111
122
|
|
|
@@ -136,7 +147,7 @@ function parse_update (req, cb) {
|
|
|
136
147
|
if (!('content-length' in headers)) {
|
|
137
148
|
// Print a nice error if it's missing
|
|
138
149
|
console.error('No content-length in', JSON.stringify(headers),
|
|
139
|
-
'from', {buffer})
|
|
150
|
+
'from', new TextDecoder().decode(new Uint8Array(buffer)), {buffer})
|
|
140
151
|
process.exit(1)
|
|
141
152
|
}
|
|
142
153
|
|
|
@@ -150,10 +161,14 @@ function parse_update (req, cb) {
|
|
|
150
161
|
|
|
151
162
|
// Content-range is of the form '<unit> <range>' e.g. 'json .index'
|
|
152
163
|
var [unit, range] = parse_content_range(headers['content-range'])
|
|
153
|
-
var patch_content = new
|
|
164
|
+
var patch_content = new Uint8Array(h.remaining_bytes.slice(0, body_length))
|
|
154
165
|
|
|
155
166
|
// We've got our patch!
|
|
156
|
-
|
|
167
|
+
let patch = {unit, range, content: patch_content}
|
|
168
|
+
Object.defineProperty(patch, 'content_text', {
|
|
169
|
+
get: () => new TextDecoder('utf-8').decode(patch.content)
|
|
170
|
+
})
|
|
171
|
+
patches.push(patch)
|
|
157
172
|
|
|
158
173
|
buffer = h.remaining_bytes.slice(body_length)
|
|
159
174
|
}
|
|
@@ -215,7 +230,7 @@ function braidify (req, res, next) {
|
|
|
215
230
|
(done, err) => parse_patches(
|
|
216
231
|
req,
|
|
217
232
|
(patches) => done(patches.map(
|
|
218
|
-
p => ({...p, content: JSON.parse(p.
|
|
233
|
+
p => ({...p, content: JSON.parse(p.content_text)})
|
|
219
234
|
))
|
|
220
235
|
)
|
|
221
236
|
)
|