braid-blob 0.0.36 → 0.0.38
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/AI-README.md +2 -2
- package/README.md +43 -0
- package/index.js +146 -33
- package/package.json +2 -2
- package/test/tests.js +2 -54
package/AI-README.md
CHANGED
|
@@ -188,7 +188,7 @@ SUBSCRIPTION_BEHAVIOR:
|
|
|
188
188
|
- Subscription callback receives: {body: Buffer, version: [string], content_type: string}
|
|
189
189
|
|
|
190
190
|
ERROR_HANDLING:
|
|
191
|
-
- Throws "
|
|
191
|
+
- Throws "unknown version: {version}" if requested version > local version
|
|
192
192
|
- Returns 309 status code via serve() when version unknown
|
|
193
193
|
```
|
|
194
194
|
|
|
@@ -426,7 +426,7 @@ url-file-db (^0.0.15):
|
|
|
426
426
|
## ERROR_CONDITIONS
|
|
427
427
|
|
|
428
428
|
```
|
|
429
|
-
"
|
|
429
|
+
"unknown version: {version}"
|
|
430
430
|
- GET with version/parents newer than local version
|
|
431
431
|
- Results in 309 status via serve()
|
|
432
432
|
|
package/README.md
CHANGED
|
@@ -88,6 +88,49 @@ Handles HTTP requests for blob storage and synchronization.
|
|
|
88
88
|
- `PUT` - Store/update a blob
|
|
89
89
|
- `DELETE` - Remove a blob
|
|
90
90
|
|
|
91
|
+
### `braid_blob.get(key, options)`
|
|
92
|
+
|
|
93
|
+
Retrieves a blob from local storage or a remote URL.
|
|
94
|
+
|
|
95
|
+
**Parameters:**
|
|
96
|
+
- `key` - Local storage key (string) or remote URL (URL object)
|
|
97
|
+
- `options` - Optional configuration object
|
|
98
|
+
- `version` - Request a specific version
|
|
99
|
+
- `parents` - Version parents for subscription fork-point
|
|
100
|
+
- `subscribe` - Callback function for real-time updates
|
|
101
|
+
- `head` - If true, returns only metadata (version, content_type) without body
|
|
102
|
+
- `content_type` / `accept` - Content type for the request
|
|
103
|
+
- `signal` - AbortSignal for cancellation
|
|
104
|
+
|
|
105
|
+
**Returns:** `{version, body, content_type}` object, or `null` if not found.
|
|
106
|
+
|
|
107
|
+
### `braid_blob.put(key, body, options)`
|
|
108
|
+
|
|
109
|
+
Stores a blob to local storage or a remote URL.
|
|
110
|
+
|
|
111
|
+
**Parameters:**
|
|
112
|
+
- `key` - Local storage key (string) or remote URL (URL object)
|
|
113
|
+
- `body` - Buffer or data to store
|
|
114
|
+
- `options` - Optional configuration object
|
|
115
|
+
- `version` - Version identifier
|
|
116
|
+
- `content_type` / `accept` - Content type of the blob
|
|
117
|
+
- `signal` - AbortSignal for cancellation
|
|
118
|
+
|
|
119
|
+
### `braid_blob.sync(a, b, options)`
|
|
120
|
+
|
|
121
|
+
Bidirectionally synchronizes blobs between two endpoints (local keys or URLs).
|
|
122
|
+
|
|
123
|
+
**Parameters:**
|
|
124
|
+
- `a` - First endpoint (local key or URL)
|
|
125
|
+
- `b` - Second endpoint (local key or URL)
|
|
126
|
+
- `options` - Optional configuration object
|
|
127
|
+
- `signal` - AbortSignal for cancellation (use to stop sync)
|
|
128
|
+
- `content_type` / `accept` - Content type for requests
|
|
129
|
+
- `on_pre_connect` - Async callback before connection attempt
|
|
130
|
+
- `on_disconnect` - Callback when connection drops
|
|
131
|
+
- `on_unauthorized` - Callback on 401/403 responses
|
|
132
|
+
- `on_res` - Callback receiving the response object
|
|
133
|
+
|
|
91
134
|
## Testing
|
|
92
135
|
|
|
93
136
|
### to run unit tests:
|
package/index.js
CHANGED
|
@@ -92,20 +92,23 @@ function create_braid_blob() {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
braid_blob.put = async (key, body, options = {}) => {
|
|
95
|
+
options = normalize_options(options)
|
|
96
|
+
|
|
95
97
|
// Handle URL case - make a remote PUT request
|
|
96
98
|
if (key instanceof URL) {
|
|
97
99
|
|
|
98
100
|
var params = {
|
|
99
101
|
method: 'PUT',
|
|
100
102
|
signal: options.signal,
|
|
101
|
-
retry: () => true,
|
|
102
103
|
body: body
|
|
103
104
|
}
|
|
105
|
+
if (!options.dont_retry)
|
|
106
|
+
params.retry = () => true
|
|
104
107
|
for (var x of ['headers', 'version', 'peer'])
|
|
105
108
|
if (options[x] != null) params[x] = options[x]
|
|
106
|
-
if (options.content_type)
|
|
107
|
-
params.headers = { ...params.headers,
|
|
108
|
-
|
|
109
|
+
if (options.content_type)
|
|
110
|
+
params.headers = { ...params.headers,
|
|
111
|
+
'Content-Type': options.content_type }
|
|
109
112
|
|
|
110
113
|
return await braid_fetch(key.href, params)
|
|
111
114
|
}
|
|
@@ -146,7 +149,7 @@ function create_braid_blob() {
|
|
|
146
149
|
// (except the peer which made the PUT request itself)
|
|
147
150
|
if (braid_blob.key_to_subs[key])
|
|
148
151
|
for (var [peer, sub] of braid_blob.key_to_subs[key].entries())
|
|
149
|
-
if (peer
|
|
152
|
+
if (!options.peer || options.peer !== peer)
|
|
150
153
|
sub.sendUpdate({
|
|
151
154
|
version: [meta.event],
|
|
152
155
|
'Merge-Type': 'aww',
|
|
@@ -158,6 +161,8 @@ function create_braid_blob() {
|
|
|
158
161
|
}
|
|
159
162
|
|
|
160
163
|
braid_blob.get = async (key, options = {}) => {
|
|
164
|
+
options = normalize_options(options)
|
|
165
|
+
|
|
161
166
|
// Handle URL case - make a remote GET request
|
|
162
167
|
if (key instanceof URL) {
|
|
163
168
|
var params = {
|
|
@@ -166,14 +171,24 @@ function create_braid_blob() {
|
|
|
166
171
|
heartbeats: 120,
|
|
167
172
|
}
|
|
168
173
|
if (!options.dont_retry) {
|
|
169
|
-
params.retry = (res) => res.status !==
|
|
174
|
+
params.retry = (res) => res.status !== 309 &&
|
|
175
|
+
res.status !== 404 && res.status !== 406
|
|
170
176
|
}
|
|
177
|
+
if (options.head) params.method = 'HEAD'
|
|
171
178
|
for (var x of ['headers', 'parents', 'version', 'peer'])
|
|
172
179
|
if (options[x] != null) params[x] = options[x]
|
|
180
|
+
if (options.content_type)
|
|
181
|
+
params.headers = { ...params.headers,
|
|
182
|
+
'Accept': options.content_type }
|
|
173
183
|
|
|
174
184
|
var res = await braid_fetch(key.href, params)
|
|
175
185
|
|
|
176
|
-
if (res.
|
|
186
|
+
if (!res.ok) return null
|
|
187
|
+
|
|
188
|
+
var result = {}
|
|
189
|
+
if (res.version) result.version = res.version
|
|
190
|
+
|
|
191
|
+
if (options.head) return result
|
|
177
192
|
|
|
178
193
|
if (options.subscribe) {
|
|
179
194
|
res.subscribe(async update => {
|
|
@@ -181,7 +196,8 @@ function create_braid_blob() {
|
|
|
181
196
|
}, e => options.on_error?.(e))
|
|
182
197
|
return res
|
|
183
198
|
} else {
|
|
184
|
-
|
|
199
|
+
result.body = await res.arrayBuffer()
|
|
200
|
+
return result
|
|
185
201
|
}
|
|
186
202
|
}
|
|
187
203
|
|
|
@@ -192,15 +208,15 @@ function create_braid_blob() {
|
|
|
192
208
|
|
|
193
209
|
var result = {
|
|
194
210
|
version: [meta.event],
|
|
195
|
-
content_type: meta.content_type
|
|
211
|
+
content_type: meta.content_type || options.content_type
|
|
196
212
|
}
|
|
197
213
|
if (options.header_cb) await options.header_cb(result)
|
|
198
214
|
if (options.signal?.aborted) return
|
|
199
215
|
// Check if requested version/parents is newer than what we have - if so, we don't have it
|
|
200
216
|
if (options.version && options.version.length && compare_events(options.version[0], meta.event) > 0)
|
|
201
|
-
throw new Error('
|
|
217
|
+
throw new Error('unknown version: ' + options.version)
|
|
202
218
|
if (options.parents && options.parents.length && compare_events(options.parents[0], meta.event) > 0)
|
|
203
|
-
throw new Error('
|
|
219
|
+
throw new Error('unknown version: ' + options.parents)
|
|
204
220
|
if (options.head) return result
|
|
205
221
|
|
|
206
222
|
if (options.subscribe) {
|
|
@@ -219,7 +235,7 @@ function create_braid_blob() {
|
|
|
219
235
|
options.my_subscribe({
|
|
220
236
|
body: update.body,
|
|
221
237
|
version: update.version,
|
|
222
|
-
content_type: meta.content_type
|
|
238
|
+
content_type: meta.content_type || options.content_type
|
|
223
239
|
})
|
|
224
240
|
}
|
|
225
241
|
})
|
|
@@ -253,6 +269,8 @@ function create_braid_blob() {
|
|
|
253
269
|
}
|
|
254
270
|
|
|
255
271
|
braid_blob.delete = async (key, options = {}) => {
|
|
272
|
+
options = normalize_options(options)
|
|
273
|
+
|
|
256
274
|
// Handle URL case - make a remote DELETE request
|
|
257
275
|
if (key instanceof URL) {
|
|
258
276
|
|
|
@@ -326,7 +344,7 @@ function create_braid_blob() {
|
|
|
326
344
|
} : null
|
|
327
345
|
})
|
|
328
346
|
} catch (e) {
|
|
329
|
-
if (e.message && e.message.startsWith('
|
|
347
|
+
if (e.message && e.message.startsWith('unknown version')) {
|
|
330
348
|
// Server doesn't have this version
|
|
331
349
|
res.statusCode = 309
|
|
332
350
|
res.statusMessage = 'Version Unknown Here'
|
|
@@ -370,6 +388,9 @@ function create_braid_blob() {
|
|
|
370
388
|
}
|
|
371
389
|
|
|
372
390
|
braid_blob.sync = (a, b, options = {}) => {
|
|
391
|
+
options = normalize_options(options)
|
|
392
|
+
if (!options.peer) options.peer = Math.random().toString(36).slice(2)
|
|
393
|
+
|
|
373
394
|
if ((a instanceof URL) === (b instanceof URL)) {
|
|
374
395
|
// Both are URLs or both are local keys
|
|
375
396
|
var a_first_put, b_first_put
|
|
@@ -378,11 +399,16 @@ function create_braid_blob() {
|
|
|
378
399
|
|
|
379
400
|
var a_ops = {
|
|
380
401
|
signal: options.signal,
|
|
402
|
+
headers: options.headers,
|
|
403
|
+
content_type: options.content_type,
|
|
404
|
+
peer: options.peer,
|
|
381
405
|
subscribe: update => {
|
|
382
406
|
braid_blob.put(b, update.body, {
|
|
383
407
|
signal: options.signal,
|
|
384
408
|
version: update.version,
|
|
385
|
-
|
|
409
|
+
headers: options.headers,
|
|
410
|
+
content_type: update.content_type,
|
|
411
|
+
peer: options.peer,
|
|
386
412
|
}).then(a_first_put)
|
|
387
413
|
}
|
|
388
414
|
}
|
|
@@ -392,11 +418,16 @@ function create_braid_blob() {
|
|
|
392
418
|
|
|
393
419
|
var b_ops = {
|
|
394
420
|
signal: options.signal,
|
|
421
|
+
headers: options.headers,
|
|
422
|
+
content_type: options.content_type,
|
|
423
|
+
peer: options.peer,
|
|
395
424
|
subscribe: update => {
|
|
396
425
|
braid_blob.put(a, update.body, {
|
|
397
426
|
signal: options.signal,
|
|
398
427
|
version: update.version,
|
|
399
|
-
|
|
428
|
+
headers: options.headers,
|
|
429
|
+
content_type: update.content_type,
|
|
430
|
+
peer: options.peer,
|
|
400
431
|
}).then(b_first_put)
|
|
401
432
|
}
|
|
402
433
|
}
|
|
@@ -426,6 +457,8 @@ function create_braid_blob() {
|
|
|
426
457
|
}
|
|
427
458
|
|
|
428
459
|
async function connect() {
|
|
460
|
+
if (options.on_pre_connect) await options.on_pre_connect()
|
|
461
|
+
|
|
429
462
|
var ac = new AbortController()
|
|
430
463
|
disconnect = () => ac.abort()
|
|
431
464
|
|
|
@@ -433,34 +466,50 @@ function create_braid_blob() {
|
|
|
433
466
|
// Check if remote has our current version (simple fork-point check)
|
|
434
467
|
var local_result = await braid_blob.get(a, {
|
|
435
468
|
signal: ac.signal,
|
|
436
|
-
head: true
|
|
469
|
+
head: true,
|
|
470
|
+
headers: options.headers,
|
|
471
|
+
content_type: options.content_type,
|
|
472
|
+
peer: options.peer,
|
|
437
473
|
})
|
|
438
474
|
var local_version = local_result ? local_result.version : null
|
|
439
475
|
var server_has_our_version = false
|
|
440
476
|
|
|
441
477
|
if (local_version) {
|
|
442
|
-
|
|
443
|
-
var r = await braid_fetch(b.href, {
|
|
478
|
+
var r = await braid_blob.get(b, {
|
|
444
479
|
signal: ac.signal,
|
|
445
|
-
|
|
446
|
-
|
|
480
|
+
head: true,
|
|
481
|
+
dont_retry: true,
|
|
482
|
+
version: local_version,
|
|
483
|
+
headers: options.headers,
|
|
484
|
+
content_type: options.content_type,
|
|
485
|
+
peer: options.peer,
|
|
447
486
|
})
|
|
448
|
-
server_has_our_version = r
|
|
487
|
+
server_has_our_version = !!r
|
|
449
488
|
}
|
|
450
489
|
|
|
451
490
|
// Local -> remote: subscribe to future local changes
|
|
452
491
|
var a_ops = {
|
|
453
492
|
signal: ac.signal,
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
493
|
+
headers: options.headers,
|
|
494
|
+
content_type: options.content_type,
|
|
495
|
+
peer: options.peer,
|
|
496
|
+
subscribe: async update => {
|
|
497
|
+
try {
|
|
498
|
+
var x = await braid_blob.put(b, update.body, {
|
|
499
|
+
signal: ac.signal,
|
|
500
|
+
dont_retry: true,
|
|
501
|
+
version: update.version,
|
|
502
|
+
headers: options.headers,
|
|
503
|
+
content_type: update.content_type,
|
|
504
|
+
peer: options.peer,
|
|
505
|
+
})
|
|
506
|
+
if (x.ok) local_first_put()
|
|
507
|
+
else if (x.status === 401 || x.status === 403) {
|
|
508
|
+
await options.on_unauthorized?.()
|
|
509
|
+
} else throw new Error('failed to PUT: ' + x.status)
|
|
510
|
+
} catch (e) {
|
|
511
|
+
if (e.name !== 'AbortError') throw e
|
|
512
|
+
}
|
|
464
513
|
}
|
|
465
514
|
}
|
|
466
515
|
// Only set parents if server already has our version
|
|
@@ -473,14 +522,22 @@ function create_braid_blob() {
|
|
|
473
522
|
var b_ops = {
|
|
474
523
|
signal: ac.signal,
|
|
475
524
|
dont_retry: true,
|
|
525
|
+
headers: options.headers,
|
|
526
|
+
content_type: options.content_type,
|
|
527
|
+
peer: options.peer,
|
|
476
528
|
subscribe: async update => {
|
|
477
529
|
await braid_blob.put(a, update.body, {
|
|
478
530
|
version: update.version,
|
|
479
|
-
|
|
531
|
+
headers: options.headers,
|
|
532
|
+
content_type: update.content_type,
|
|
533
|
+
peer: options.peer,
|
|
480
534
|
})
|
|
481
535
|
remote_first_put()
|
|
482
536
|
},
|
|
483
|
-
on_error:
|
|
537
|
+
on_error: e => {
|
|
538
|
+
options.on_disconnect?.()
|
|
539
|
+
handle_error(e)
|
|
540
|
+
}
|
|
484
541
|
}
|
|
485
542
|
// Use fork-point (parents) to avoid receiving data we already have
|
|
486
543
|
if (local_version) {
|
|
@@ -500,6 +557,9 @@ function create_braid_blob() {
|
|
|
500
557
|
disconnect()
|
|
501
558
|
connect()
|
|
502
559
|
}
|
|
560
|
+
|
|
561
|
+
options.on_res?.(remote_res)
|
|
562
|
+
|
|
503
563
|
// Otherwise, on_error will call handle_error when connection drops
|
|
504
564
|
} catch (e) {
|
|
505
565
|
handle_error(e)
|
|
@@ -617,6 +677,59 @@ function create_braid_blob() {
|
|
|
617
677
|
}
|
|
618
678
|
}
|
|
619
679
|
|
|
680
|
+
function get_header(headers, key) {
|
|
681
|
+
if (!headers) return
|
|
682
|
+
|
|
683
|
+
// optimization..
|
|
684
|
+
if (headers.hasOwnProperty(key))
|
|
685
|
+
return headers[key]
|
|
686
|
+
|
|
687
|
+
var lowerKey = key.toLowerCase()
|
|
688
|
+
for (var headerKey of Object.keys(headers))
|
|
689
|
+
if (headerKey.toLowerCase() === lowerKey)
|
|
690
|
+
return headers[headerKey]
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
function normalize_options(options = {}) {
|
|
694
|
+
if (!normalize_options.special) {
|
|
695
|
+
normalize_options.special = {
|
|
696
|
+
version: 'version',
|
|
697
|
+
parents: 'parents',
|
|
698
|
+
'content-type': 'content_type',
|
|
699
|
+
accept: 'content_type',
|
|
700
|
+
peer: 'peer',
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
var normalized = {}
|
|
705
|
+
Object.assign(normalized, options)
|
|
706
|
+
|
|
707
|
+
// Normalize top-level accept to content_type
|
|
708
|
+
if (options.accept) {
|
|
709
|
+
normalized.content_type = options.accept
|
|
710
|
+
delete normalized.accept
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
if (options.headers) {
|
|
714
|
+
normalized.headers = {}
|
|
715
|
+
for (var [k, v] of (options.headers instanceof Headers ?
|
|
716
|
+
options.headers.entries() :
|
|
717
|
+
Object.entries(options.headers))) {
|
|
718
|
+
var s = normalize_options.special[k]
|
|
719
|
+
if (s) normalized[s] = v
|
|
720
|
+
else normalized.headers[k] = v
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// Normalize version/parents strings to arrays
|
|
725
|
+
if (typeof normalized.version === 'string')
|
|
726
|
+
normalized.version = JSON.parse('[' + normalized.version + ']')
|
|
727
|
+
if (typeof normalized.parents === 'string')
|
|
728
|
+
normalized.parents = JSON.parse('[' + normalized.parents + ']')
|
|
729
|
+
|
|
730
|
+
return normalized
|
|
731
|
+
}
|
|
732
|
+
|
|
620
733
|
braid_blob.create_braid_blob = create_braid_blob
|
|
621
734
|
|
|
622
735
|
return braid_blob
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "braid-blob",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.38",
|
|
4
4
|
"description": "Library for collaborative blobs over http using braid.",
|
|
5
5
|
"author": "Braid Working Group",
|
|
6
6
|
"repository": "braid-org/braid-blob",
|
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
"test:browser": "node test/test.js --browser"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"braid-http": "~1.3.
|
|
13
|
+
"braid-http": "~1.3.84"
|
|
14
14
|
}
|
|
15
15
|
}
|
package/test/tests.js
CHANGED
|
@@ -918,7 +918,7 @@ runTest(
|
|
|
918
918
|
var braid_blob = require(\`\${__dirname}/../index.js\`)
|
|
919
919
|
var url = new URL('http://localhost:' + req.socket.localPort + '/${key}')
|
|
920
920
|
var result = await braid_blob.get(url)
|
|
921
|
-
res.end(Buffer.from(result).toString('utf8'))
|
|
921
|
+
res.end(Buffer.from(result.body).toString('utf8'))
|
|
922
922
|
})()`
|
|
923
923
|
})
|
|
924
924
|
|
|
@@ -1147,58 +1147,6 @@ runTest(
|
|
|
1147
1147
|
'shared content'
|
|
1148
1148
|
)
|
|
1149
1149
|
|
|
1150
|
-
runTest(
|
|
1151
|
-
"test sync does not disconnect unnecessarily",
|
|
1152
|
-
async () => {
|
|
1153
|
-
var local_key = 'test-sync-no-disconnect-local-' + Math.random().toString(36).slice(2)
|
|
1154
|
-
var remote_key = 'test-sync-no-disconnect-remote-' + Math.random().toString(36).slice(2)
|
|
1155
|
-
|
|
1156
|
-
var r1 = await braid_fetch(`/eval`, {
|
|
1157
|
-
method: 'POST',
|
|
1158
|
-
body: `void (async () => {
|
|
1159
|
-
try {
|
|
1160
|
-
var braid_blob = require(\`\${__dirname}/../index.js\`)
|
|
1161
|
-
|
|
1162
|
-
// Put something locally first
|
|
1163
|
-
await braid_blob.put('${local_key}', Buffer.from('local content'), { version: ['600'] })
|
|
1164
|
-
|
|
1165
|
-
var remote_url = new URL('http://localhost:' + req.socket.localPort + '/${remote_key}')
|
|
1166
|
-
|
|
1167
|
-
// Capture console.log to count disconnects
|
|
1168
|
-
var disconnect_count = 0
|
|
1169
|
-
var original_log = console.log
|
|
1170
|
-
console.log = function(...args) {
|
|
1171
|
-
if (args[0]?.includes?.('disconnected')) disconnect_count++
|
|
1172
|
-
original_log.apply(console, args)
|
|
1173
|
-
}
|
|
1174
|
-
|
|
1175
|
-
// Create an AbortController to stop the sync
|
|
1176
|
-
var ac = new AbortController()
|
|
1177
|
-
|
|
1178
|
-
// Start sync
|
|
1179
|
-
braid_blob.sync('${local_key}', remote_url, { signal: ac.signal })
|
|
1180
|
-
|
|
1181
|
-
// Wait for sync to establish and stabilize
|
|
1182
|
-
await new Promise(done => setTimeout(done, 500))
|
|
1183
|
-
|
|
1184
|
-
// Stop sync
|
|
1185
|
-
ac.abort()
|
|
1186
|
-
|
|
1187
|
-
// Restore console.log
|
|
1188
|
-
console.log = original_log
|
|
1189
|
-
|
|
1190
|
-
// Should have zero disconnects during normal operation
|
|
1191
|
-
res.end(disconnect_count === 0 ? 'no disconnects' : 'disconnects: ' + disconnect_count)
|
|
1192
|
-
} catch (e) {
|
|
1193
|
-
res.end('error: ' + e.message + ' ' + e.stack)
|
|
1194
|
-
}
|
|
1195
|
-
})()`
|
|
1196
|
-
})
|
|
1197
|
-
return await r1.text()
|
|
1198
|
-
},
|
|
1199
|
-
'no disconnects'
|
|
1200
|
-
)
|
|
1201
|
-
|
|
1202
1150
|
runTest(
|
|
1203
1151
|
"test sync connect does not read file body for version check",
|
|
1204
1152
|
async () => {
|
|
@@ -1355,7 +1303,7 @@ runTest(
|
|
|
1355
1303
|
})
|
|
1356
1304
|
|
|
1357
1305
|
// Try to subscribe with parents 200 (newer than what server has)
|
|
1358
|
-
// This triggers the "
|
|
1306
|
+
// This triggers the "unknown version" error which gets caught and returns 309
|
|
1359
1307
|
var r = await braid_fetch(`/${key}`, {
|
|
1360
1308
|
subscribe: true,
|
|
1361
1309
|
parents: ['200']
|