braid-text 0.0.18 → 0.0.20

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/index.js CHANGED
@@ -194,10 +194,8 @@ braid_text.serve = async (req, res, options = {}) => {
194
194
 
195
195
  braid_text.get = async (key, options) => {
196
196
  if (!options) {
197
- let x = get_resource.cache?.[key]?.doc.get()
198
- if (x !== undefined) return x
199
- // if it doesn't exist on disk, don't create it in this case
200
- if (!(await get_files_for_key(key)).length) return
197
+ // if it doesn't exist already, don't create it in this case
198
+ if (!get_resource.cache?.[key]) return
201
199
  return (await get_resource(key)).doc.get()
202
200
  }
203
201
 
@@ -256,14 +254,7 @@ braid_text.get = async (key, options) => {
256
254
  updates = OpLog_get_patches(resource.doc.toBytes(), resource.doc.getOpsSince([]))
257
255
  } else {
258
256
  // Then start the subscription from the parents in options
259
- let parents = Object.fromEntries((options.parents ? options.parents : options.version).map((x) => [x, true]))
260
-
261
- let local_version = []
262
- let [agents, versions, parentss] = parseDT([...resource.doc.toBytes()])
263
- for (let i = 0; i < versions.length; i++) {
264
- if (parents[versions[i].join("-")]) local_version.push(i)
265
- }
266
- local_version = new Uint32Array(local_version)
257
+ let local_version = OpLog_remote_to_local(resource.doc, options.parents || options.version)
267
258
 
268
259
  updates = OpLog_get_patches(resource.doc.getPatchSince(local_version), resource.doc.getOpsSince(local_version))
269
260
  }
@@ -295,7 +286,13 @@ braid_text.put = async (key, options) => {
295
286
  let { version, patches, body, peer } = options
296
287
 
297
288
  if (version) validate_version_array(version)
298
- if (options.parents) validate_version_array(options.parents)
289
+
290
+ // translate a single parent of "root" to the empty array (same meaning)
291
+ let options_parents = options.parents
292
+ if (options_parents?.length === 1 && options_parents[0] === 'root')
293
+ options_parents = []
294
+
295
+ if (options_parents) validate_version_array(options_parents)
299
296
  if (body != null && patches) throw new Error(`cannot have a body and patches`)
300
297
  if (body != null && (typeof body !== 'string')) throw new Error(`body must be a string`)
301
298
  if (patches) validate_patches(patches)
@@ -303,7 +300,7 @@ braid_text.put = async (key, options) => {
303
300
  let resource = (typeof key == 'string') ? await get_resource(key) : key
304
301
 
305
302
  let parents = resource.doc.getRemoteVersion().map((x) => x.join("-"))
306
- let og_parents = options.parents || parents
303
+ let og_parents = options_parents || parents
307
304
 
308
305
  let max_pos = count_code_points(v_eq(parents, og_parents) ?
309
306
  resource.doc.get() :
@@ -340,7 +337,63 @@ braid_text.put = async (key, options) => {
340
337
  let v = decode_version(og_v)
341
338
 
342
339
  // validate version: make sure we haven't seen it already
343
- if (v[1] <= (resource.actor_seqs[v[0]] ?? -1)) throw new Error(`invalid version: already processed`)
340
+ if (v[1] <= (resource.actor_seqs[v[0]] ?? -1)) {
341
+
342
+ // if we have seen it already, make sure it's the same as before
343
+ let local_version = OpLog_remote_to_local(resource.doc, og_parents)
344
+ let updates = OpLog_get_patches(resource.doc.getPatchSince(local_version), resource.doc.getOpsSince(local_version))
345
+
346
+ let seen = {}
347
+ for (let u of updates) {
348
+ if (u.start != u.end) {
349
+ // delete
350
+ let v = decode_version(u.version)
351
+ for (let i = 0; i < u.end - u.start; i++) {
352
+ let ps = (i < u.end - u.start - 1) ? [`${v[0]}-${v[1] - i - 1}`] : u.parents
353
+ seen[JSON.stringify([v[0], v[1] - i, ps, u.start + i])] = true
354
+ }
355
+ } else {
356
+ // insert
357
+ let v = decode_version(u.version)
358
+ let content = [...u.content]
359
+ for (let i = 0; i < content.length; i++) {
360
+ let ps = (i > 0) ? [`${v[0]}-${v[1] - content.length + i}`] : u.parents
361
+ seen[JSON.stringify([v[0], v[1] + 1 - content.length + i, ps, u.start + i, content[i]])] = true
362
+ }
363
+ }
364
+ }
365
+
366
+ v = `${v[0]}-${v[1] + 1 - change_count}`
367
+ let ps = og_parents
368
+ let offset = 0
369
+ for (let p of patches) {
370
+ // delete
371
+ for (let i = p.range[0]; i < p.range[1]; i++) {
372
+ let vv = decode_version(v)
373
+
374
+ if (!seen[JSON.stringify([vv[0], vv[1], ps, p.range[1] - 1 + offset])]) throw new Error('invalid update: different from previous update with same version')
375
+
376
+ offset--
377
+ ps = [v]
378
+ v = vv
379
+ v = `${v[0]}-${v[1] + 1}`
380
+ }
381
+ // insert
382
+ for (let i = 0; i < p.content?.length ?? 0; i++) {
383
+ let c = p.content[i]
384
+
385
+ if (!seen[JSON.stringify([vv[0], vv[1], ps, p.range[1] + offset, c])]) throw new Error('invalid update: different from previous update with same version')
386
+
387
+ offset++
388
+ ps = [v]
389
+ v = decode_version(v)
390
+ v = `${v[0]}-${v[1] + 1}`
391
+ }
392
+ }
393
+
394
+ // we already have this version, so nothing left to do
395
+ return
396
+ }
344
397
  resource.actor_seqs[v[0]] = v[1]
345
398
 
346
399
  v = `${v[0]}-${v[1] + 1 - change_count}`
@@ -376,12 +429,6 @@ braid_text.put = async (key, options) => {
376
429
 
377
430
  resource.need_defrag = true
378
431
 
379
- let v_after = resource.doc.getLocalVersion()
380
- if (JSON.stringify(v_before) === JSON.stringify(v_after)) {
381
- console.log(`we got a version we already had: ${v_before}`)
382
- return
383
- }
384
-
385
432
  if (options.merge_type != "dt") {
386
433
  patches = get_xf_patches(resource.doc, v_before)
387
434
  console.log(JSON.stringify({ patches }))
@@ -496,38 +543,39 @@ braid_text.list = async () => {
496
543
 
497
544
  async function get_resource(key) {
498
545
  let cache = get_resource.cache || (get_resource.cache = {})
499
- if (cache[key]) return cache[key]
546
+ if (!cache[key]) cache[key] = new Promise(async done => {
547
+ let resource = {}
548
+ resource.clients = new Set()
549
+ resource.simpleton_clients = new Set()
500
550
 
501
- let resource = {}
502
- resource.clients = new Set()
503
- resource.simpleton_clients = new Set()
551
+ resource.doc = new Doc("server")
504
552
 
505
- resource.doc = new Doc("server")
553
+ let { change, delete_me } = braid_text.db_folder
554
+ ? await file_sync(key,
555
+ (bytes) => resource.doc.mergeBytes(bytes),
556
+ () => resource.doc.toBytes())
557
+ : { change: () => { }, delete_me: () => { } }
506
558
 
507
- let { change, delete_me } = braid_text.db_folder
508
- ? await file_sync(key,
509
- (bytes) => resource.doc.mergeBytes(bytes),
510
- () => resource.doc.toBytes())
511
- : { change: () => { }, delete_me: () => { } }
559
+ resource.db_delta = change
512
560
 
513
- resource.db_delta = change
561
+ resource.doc = defrag_dt(resource.doc)
562
+ resource.need_defrag = false
514
563
 
515
- resource.doc = defrag_dt(resource.doc)
516
- resource.need_defrag = false
517
-
518
- resource.actor_seqs = {}
519
- let max_version = resource.doc.getLocalVersion()[0] ?? -1
520
- for (let i = 0; i <= max_version; i++) {
521
- let v = resource.doc.localToRemoteVersion([i])[0]
522
- resource.actor_seqs[v[0]] = Math.max(v[1], resource.actor_seqs[v[0]] ?? -1)
523
- }
564
+ resource.actor_seqs = {}
565
+ let max_version = resource.doc.getLocalVersion()[0] ?? -1
566
+ for (let i = 0; i <= max_version; i++) {
567
+ let v = resource.doc.localToRemoteVersion([i])[0]
568
+ resource.actor_seqs[v[0]] = Math.max(v[1], resource.actor_seqs[v[0]] ?? -1)
569
+ }
524
570
 
525
- resource.delete_me = () => {
526
- delete_me()
527
- delete cache[key]
528
- }
571
+ resource.delete_me = () => {
572
+ delete_me()
573
+ delete cache[key]
574
+ }
529
575
 
530
- return (cache[key] = resource)
576
+ done(resource)
577
+ })
578
+ return await cache[key]
531
579
  }
532
580
 
533
581
  async function db_folder_init() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "description": "Library for collaborative text over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braidjs",
package/braid-text-db/!.1 DELETED
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file