braid-text 0.2.66 → 0.2.68

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.
Files changed (3) hide show
  1. package/index.js +66 -7
  2. package/package.json +2 -2
  3. package/test/test.html +392 -0
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  let { Doc, OpLog, Branch } = require("@braid.org/diamond-types-node")
3
- let braidify = require("braid-http").http_server
3
+ let {http_server: braidify, fetch: braid_fetch} = require("braid-http")
4
4
  let fs = require("fs")
5
5
 
6
6
  function create_braid_text() {
@@ -16,6 +16,15 @@ function create_braid_text() {
16
16
 
17
17
  let max_encoded_key_size = 240
18
18
 
19
+ braid_text.sync = async (a, b, options) => {
20
+ braid_text.get(a, {
21
+ subscribe: update => braid_text.put(b, update)
22
+ })
23
+ braid_text.get(b, {
24
+ subscribe: update => braid_text.put(a, update)
25
+ })
26
+ }
27
+
19
28
  braid_text.serve = async (req, res, options = {}) => {
20
29
  options = {
21
30
  key: req.url.split('?')[0], // Default key
@@ -237,7 +246,7 @@ function create_braid_text() {
237
246
  req.parents,
238
247
  resource.actor_seqs,
239
248
  // approximation of memory usage for this update
240
- body ? body.length :
249
+ body != null ? body.length :
241
250
  patches.reduce((a, b) => a + b.range.length + b.content.length, 0),
242
251
  options.recv_buffer_max_time,
243
252
  options.recv_buffer_max_space)
@@ -270,7 +279,8 @@ function create_braid_text() {
270
279
  return done_my_turn(550, "repr-digest mismatch!")
271
280
  }
272
281
 
273
- if (req.version) got_event(options.key, req.version[0], change_count)
282
+ if (req.version?.length)
283
+ got_event(options.key, req.version[0], change_count)
274
284
 
275
285
  res.setHeader("Version", get_current_version())
276
286
 
@@ -291,6 +301,33 @@ function create_braid_text() {
291
301
  }
292
302
 
293
303
  braid_text.get = async (key, options) => {
304
+ if (key instanceof URL) {
305
+ if (!options) options = {}
306
+
307
+ options.my_abort = new AbortController()
308
+
309
+ var params = {
310
+ signal: options.my_abort.signal,
311
+ retry: () => true,
312
+ subscribe: !!options.subscribe,
313
+ heartbeats: 120,
314
+ }
315
+ for (var x of ['headers', 'parents', 'version', 'peer'])
316
+ if (options[x] != null) params[x] = options[x]
317
+
318
+ var res = await braid_fetch(key.href, params)
319
+
320
+ if (options.subscribe) {
321
+ res.subscribe(update => {
322
+ update.body = update.body_text
323
+ if (update.patches)
324
+ for (var p of update.patches) p.content = p.content_text
325
+ options.subscribe(update)
326
+ })
327
+ return res
328
+ } else return await res.text()
329
+ }
330
+
294
331
  if (!options) {
295
332
  // if it doesn't exist already, don't create it in this case
296
333
  if (!braid_text.cache[key]) return
@@ -412,6 +449,8 @@ function create_braid_text() {
412
449
  braid_text.forget = async (key, options) => {
413
450
  if (!options) throw new Error('options is required')
414
451
 
452
+ if (key instanceof URL) return options.my_abort.abort()
453
+
415
454
  let resource = (typeof key == 'string') ? await get_resource(key) : key
416
455
 
417
456
  if (options.merge_type != "dt")
@@ -420,6 +459,20 @@ function create_braid_text() {
420
459
  }
421
460
 
422
461
  braid_text.put = async (key, options) => {
462
+ if (key instanceof URL) {
463
+ options.my_abort = new AbortController()
464
+
465
+ var params = {
466
+ method: 'PUT',
467
+ signal: options.my_abort.signal,
468
+ retry: () => true,
469
+ }
470
+ for (var x of ['headers', 'parents', 'version', 'peer', 'body', 'patches'])
471
+ if (options[x] != null) params[x] = options[x]
472
+
473
+ return await braid_fetch(key.href, params)
474
+ }
475
+
423
476
  let { version, patches, body, peer } = options
424
477
 
425
478
  // support for json patch puts..
@@ -456,6 +509,12 @@ function create_braid_text() {
456
509
  }
457
510
 
458
511
  if (version) validate_version_array(version)
512
+ if (version && !version.length) {
513
+ console.log(`warning: ignoring put with empty version`)
514
+ return { change_count: 0 }
515
+ }
516
+ if (version && version.length > 1)
517
+ throw new Error(`cannot put a version with multiple ids`)
459
518
 
460
519
  // translate a single parent of "root" to the empty array (same meaning)
461
520
  let options_parents = options.parents
@@ -894,11 +953,11 @@ function create_braid_text() {
894
953
  var meta_filename = `${braid_text.db_folder}/.meta/${encoded}`
895
954
  var meta_dirty = null
896
955
  var meta_saving = null
956
+ var meta_file_content = '{}'
897
957
  try {
898
- set_meta(JSON.parse(await fs.promises.readFile(meta_filename)))
899
- } catch (e) {
900
- console.error(`Error processing meta file: ${meta_filename}`)
901
- }
958
+ var meta_file_content = await fs.promises.readFile(meta_filename)
959
+ } catch (e) {}
960
+ set_meta(JSON.parse(meta_file_content))
902
961
 
903
962
  let chain = Promise.resolve()
904
963
  return {
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.2.66",
3
+ "version": "0.2.68",
4
4
  "description": "Library for collaborative text over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braid-text",
7
7
  "homepage": "https://braid.org",
8
8
  "dependencies": {
9
9
  "@braid.org/diamond-types-node": "^2.0.0",
10
- "braid-http": "~1.3.80"
10
+ "braid-http": "~1.3.83"
11
11
  }
12
12
  }
package/test/test.html CHANGED
@@ -96,6 +96,398 @@ async function runTest(testName, testFunction, expectedResult) {
96
96
  }
97
97
  }
98
98
 
99
+ runTest(
100
+ "test subscribe update with body_text",
101
+ async () => {
102
+ var key = 'test' + Math.random().toString(36).slice(2)
103
+
104
+ var r = await braid_fetch(`/${key}`, {
105
+ method: 'PUT',
106
+ body: 'hi'
107
+ })
108
+ if (!r.ok) return 'got: ' + r.status
109
+
110
+ var r1p = braid_fetch(`/eval`, {
111
+ method: 'PUT',
112
+ body: `void (async () => {
113
+ var x = await new Promise(done => {
114
+ braid_text.get(new URL('http://localhost:8889/${key}'), {
115
+ subscribe: update => {
116
+ if (update.body_text) done(update.body_text)
117
+ }
118
+ })
119
+ })
120
+ res.end(x)
121
+ })()`
122
+ })
123
+
124
+ var r2 = await braid_fetch(`/${key}`, {
125
+ method: 'PUT',
126
+ body: 'yo'
127
+ })
128
+
129
+ var r1 = await r1p
130
+ if (!r1.ok) return 'got: ' + r.status
131
+
132
+ return await r1.text()
133
+ },
134
+ 'yo'
135
+ )
136
+
137
+ runTest(
138
+ "test braid_text.sync, url to key",
139
+ async () => {
140
+ var key_a = 'test-a-' + Math.random().toString(36).slice(2)
141
+ var key_b = 'test-b-' + Math.random().toString(36).slice(2)
142
+
143
+ var r = await braid_fetch(`/${key_a}`, {
144
+ method: 'PUT',
145
+ body: 'hi'
146
+ })
147
+ if (!r.ok) return 'got: ' + r.status
148
+
149
+ var r = await braid_fetch(`/eval`, {
150
+ method: 'PUT',
151
+ body: `void (async () => {
152
+ braid_text.sync(new URL('http://localhost:8889/${key_a}'), '/${key_b}')
153
+ res.end('')
154
+ })()`
155
+ })
156
+ if (!r.ok) return 'got: ' + r.status
157
+
158
+ await new Promise(done => setTimeout(done, 100))
159
+
160
+ var r = await braid_fetch(`/${key_b}`)
161
+ return 'got: ' + (await r.text())
162
+ },
163
+ 'got: hi'
164
+ )
165
+
166
+ runTest(
167
+ "test braid_text.sync, with two urls",
168
+ async () => {
169
+ var key_a = 'test-a-' + Math.random().toString(36).slice(2)
170
+ var key_b = 'test-b-' + Math.random().toString(36).slice(2)
171
+
172
+ var r = await braid_fetch(`/${key_a}`, {
173
+ method: 'PUT',
174
+ body: 'hi'
175
+ })
176
+ if (!r.ok) return 'got: ' + r.status
177
+
178
+ var r = await braid_fetch(`/eval`, {
179
+ method: 'PUT',
180
+ body: `void (async () => {
181
+ braid_text.sync(new URL('http://localhost:8889/${key_a}'),
182
+ new URL('http://localhost:8889/${key_b}'))
183
+ res.end('')
184
+ })()`
185
+ })
186
+ if (!r.ok) return 'got: ' + r.status
187
+
188
+ await new Promise(done => setTimeout(done, 100))
189
+
190
+ var r = await braid_fetch(`/${key_b}`)
191
+ return 'got: ' + (await r.text())
192
+ },
193
+ 'got: hi'
194
+ )
195
+
196
+ runTest(
197
+ "test braid_text.sync, key to url",
198
+ async () => {
199
+ var key_a = 'test-a-' + Math.random().toString(36).slice(2)
200
+ var key_b = 'test-b-' + Math.random().toString(36).slice(2)
201
+
202
+ var r = await braid_fetch(`/${key_a}`, {
203
+ method: 'PUT',
204
+ body: 'hi'
205
+ })
206
+ if (!r.ok) return 'got: ' + r.status
207
+
208
+ var r = await braid_fetch(`/eval`, {
209
+ method: 'PUT',
210
+ body: `void (async () => {
211
+ braid_text.sync('/${key_a}', new URL('http://localhost:8889/${key_b}'))
212
+ res.end('')
213
+ })()`
214
+ })
215
+ if (!r.ok) return 'got: ' + r.status
216
+
217
+ await new Promise(done => setTimeout(done, 100))
218
+
219
+ var r = await braid_fetch(`/${key_b}`)
220
+ return 'got: ' + (await r.text())
221
+ },
222
+ 'got: hi'
223
+ )
224
+
225
+ runTest(
226
+ "test braid_text.sync, with two keys",
227
+ async () => {
228
+ var key_a = 'test-a-' + Math.random().toString(36).slice(2)
229
+ var key_b = 'test-b-' + Math.random().toString(36).slice(2)
230
+
231
+ var r = await braid_fetch(`/${key_a}`, {
232
+ method: 'PUT',
233
+ body: 'hi'
234
+ })
235
+ if (!r.ok) return 'got: ' + r.status
236
+
237
+ var r = await braid_fetch(`/eval`, {
238
+ method: 'PUT',
239
+ body: `void (async () => {
240
+ braid_text.sync('/${key_a}', '/${key_b}')
241
+ res.end('')
242
+ })()`
243
+ })
244
+ if (!r.ok) return 'got: ' + r.status
245
+
246
+ await new Promise(done => setTimeout(done, 100))
247
+
248
+ var r = await braid_fetch(`/${key_b}`)
249
+ return 'got: ' + (await r.text())
250
+ },
251
+ 'got: hi'
252
+ )
253
+
254
+ runTest(
255
+ "test putting version with multiple event ids, should have error",
256
+ async () => {
257
+ var key_a = 'test-a-' + Math.random().toString(36).slice(2)
258
+
259
+ var r = await braid_fetch(`/${key_a}`, {
260
+ method: 'PUT',
261
+ version: ['abc-1', 'xyz-2'],
262
+ body: 'hi'
263
+ })
264
+ return '' + (await r.text()).includes('cannot put a version with multiple ids')
265
+ },
266
+ 'true'
267
+ )
268
+
269
+ runTest(
270
+ "test braid_text.get(url), with no options",
271
+ async () => {
272
+ var key = 'test-' + Math.random().toString(36).slice(2)
273
+ let r = await braid_fetch(`/${key}`, {
274
+ method: 'PUT',
275
+ body: 'hi'
276
+ })
277
+ if (!r.ok) return 'got: ' + r.status
278
+
279
+ var r1 = await braid_fetch(`/eval`, {
280
+ method: 'PUT',
281
+ body: `void (async () => {
282
+ res.end(await braid_text.get(new URL('http://localhost:8889/${key}')))
283
+ })()`
284
+ })
285
+
286
+ return 'got: ' + (await r1.text())
287
+ },
288
+ 'got: hi'
289
+ )
290
+
291
+ runTest(
292
+ "test braid_text.get(url), with headers",
293
+ async () => {
294
+ var key = 'test-' + Math.random().toString(36).slice(2)
295
+ let r = await braid_fetch(`/${key}`, {
296
+ method: 'PUT',
297
+ version: ['xyz-1'],
298
+ body: 'hi'
299
+ })
300
+ if (!r.ok) return 'got: ' + r.status
301
+
302
+ var r1 = await braid_fetch(`/eval`, {
303
+ method: 'PUT',
304
+ body: `void (async () => {
305
+ res.end(await braid_text.get(new URL('http://localhost:8889/${key}'), {
306
+ headers: {
307
+ version: '"xyz-0"'
308
+ }
309
+ }))
310
+ })()`
311
+ })
312
+
313
+ return 'got: ' + (await r1.text())
314
+ },
315
+ 'got: h'
316
+ )
317
+
318
+ runTest(
319
+ "test braid_text.get(url), with parents",
320
+ async () => {
321
+ var key = 'test-' + Math.random().toString(36).slice(2)
322
+ let r = await braid_fetch(`/${key}`, {
323
+ method: 'PUT',
324
+ version: ['xyz-1'],
325
+ body: 'hi'
326
+ })
327
+ if (!r.ok) return 'got: ' + r.status
328
+
329
+ var r1 = await braid_fetch(`/eval`, {
330
+ method: 'PUT',
331
+ body: `void (async () => {
332
+ res.end(await braid_text.get(new URL('http://localhost:8889/${key}'), {
333
+ parents: ['xyz-0']
334
+ }))
335
+ })()`
336
+ })
337
+
338
+ return 'got: ' + (await r1.text())
339
+ },
340
+ 'got: h'
341
+ )
342
+
343
+ runTest(
344
+ "test braid_text.get(url), with version and peer",
345
+ async () => {
346
+ var key = 'test-' + Math.random().toString(36).slice(2)
347
+ let r = await braid_fetch(`/${key}`, {
348
+ method: 'PUT',
349
+ version: ['xyz-1'],
350
+ body: 'hi'
351
+ })
352
+ if (!r.ok) return 'got: ' + r.status
353
+
354
+ var r1 = await braid_fetch(`/eval`, {
355
+ method: 'PUT',
356
+ body: `void (async () => {
357
+ res.end(await braid_text.get(new URL('http://localhost:8889/${key}'), {
358
+ version: ['xyz-0'],
359
+ peer: 'xyz'
360
+ }))
361
+ })()`
362
+ })
363
+
364
+ return 'got: ' + (await r1.text())
365
+ },
366
+ 'got: h'
367
+ )
368
+
369
+ runTest(
370
+ "test braid_text.get(url) with subscription",
371
+ async () => {
372
+ var key = 'test-' + Math.random().toString(36).slice(2)
373
+ let r = await braid_fetch(`/${key}`, {
374
+ method: 'PUT',
375
+ version: ['xyz-1'],
376
+ body: 'hi'
377
+ })
378
+ if (!r.ok) return 'got: ' + r.status
379
+
380
+ var r1 = await braid_fetch(`/eval`, {
381
+ method: 'PUT',
382
+ body: `void (async () => {
383
+ var url = new URL('http://localhost:8889/${key}')
384
+ var update = await new Promise(done => {
385
+ var o = {
386
+ subscribe: update => {
387
+ braid_text.forget(url, o)
388
+ done(update)
389
+ }
390
+ }
391
+ braid_text.get(url, o)
392
+ })
393
+ res.end(update.body)
394
+ })()`
395
+ })
396
+
397
+ return 'got: ' + (await r1.text())
398
+ },
399
+ 'got: hi'
400
+ )
401
+
402
+ runTest(
403
+ "test braid_text.put(url), with body",
404
+ async () => {
405
+ var key = 'test-' + Math.random().toString(36).slice(2)
406
+
407
+ var r = await braid_fetch(`/eval`, {
408
+ method: 'PUT',
409
+ body: `void (async () => {
410
+ var r = await braid_text.put(new URL('http://localhost:8889/${key}'),
411
+ {body: 'yo'})
412
+ res.end('')
413
+ })()`
414
+ })
415
+ if (!r.ok) return 'got: ' + r.status
416
+
417
+ let r1 = await braid_fetch(`/${key}`)
418
+ return 'got: ' + (await r1.text())
419
+ },
420
+ 'got: yo'
421
+ )
422
+
423
+ runTest(
424
+ "test braid_text.put(url), with body and headers",
425
+ async () => {
426
+ var key = 'test-' + Math.random().toString(36).slice(2)
427
+
428
+ var r = await braid_fetch(`/eval`, {
429
+ method: 'PUT',
430
+ body: `void (async () => {
431
+ var r = await braid_text.put(new URL('http://localhost:8889/${key}'),
432
+ {body: 'yo', headers: {version: '"abc123-1"'}})
433
+ res.end('')
434
+ })()`
435
+ })
436
+ if (!r.ok) return 'got: ' + r.status
437
+
438
+ let r2 = await braid_fetch(`/${key}`)
439
+ return 'got: ' + (await r2.text()) + ' -- version: ' + r2.headers.get('version')
440
+ },
441
+ 'got: yo -- version: "abc123-1"'
442
+ )
443
+
444
+ runTest(
445
+ "test braid_text.put(url), with body and version and parents",
446
+ async () => {
447
+ var key = 'test-' + Math.random().toString(36).slice(2)
448
+ let r = await braid_fetch(`/${key}`, {
449
+ method: 'PUT',
450
+ body: 'hi',
451
+ version: ['abc-1']
452
+ })
453
+
454
+ var r1 = await braid_fetch(`/eval`, {
455
+ method: 'PUT',
456
+ body: `void (async () => {
457
+ var r = await braid_text.put(new URL('http://localhost:8889/${key}'),
458
+ {body: 'yo', version: ['xyz-3'], parents: ['abc-1']})
459
+ res.end('')
460
+ })()`
461
+ })
462
+ if (!r1.ok) return 'got: ' + r1.status
463
+
464
+ let r2 = await braid_fetch(`/${key}`)
465
+ return 'got: ' + (await r2.text()) + ' -- version: ' + r2.headers.get('version')
466
+ },
467
+ 'got: yo -- version: "xyz-3"'
468
+ )
469
+
470
+ runTest(
471
+ "test braid_text.put(url), with peer",
472
+ async () => {
473
+ var key = 'test-' + Math.random().toString(36).slice(2)
474
+
475
+ var r1 = await braid_fetch(`/eval`, {
476
+ method: 'PUT',
477
+ body: `void (async () => {
478
+ var r = await braid_text.put(new URL('http://localhost:8889/${key}'),
479
+ {body: 'yo', peer: 'xyz', parents: []})
480
+ res.end('')
481
+ })()`
482
+ })
483
+ if (!r1.ok) return 'got: ' + r1.status
484
+
485
+ let r2 = await braid_fetch(`/${key}`)
486
+ return 'got: ' + (await r2.text()) + ' -- version: ' + r2.headers.get('version')
487
+ },
488
+ 'got: yo -- version: "xyz-1"'
489
+ )
490
+
99
491
  runTest(
100
492
  "test updating meta data",
101
493
  async () => {