braid-text 0.2.18 → 0.2.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.
Files changed (3) hide show
  1. package/index.js +50 -41
  2. package/package.json +1 -1
  3. package/test/test.js +30 -5
package/index.js CHANGED
@@ -483,13 +483,16 @@ braid_text.put = async (key, options) => {
483
483
  let version = resource.doc.getRemoteVersion().map((x) => x.join("-")).sort()
484
484
 
485
485
  for (let client of resource.simpleton_clients) {
486
- if (client.peer == peer) {
486
+ if (peer && client.peer === peer) {
487
487
  client.my_last_seen_version = [og_v]
488
488
  }
489
489
 
490
490
  function set_timeout(time_override) {
491
491
  if (client.my_timeout) clearTimeout(client.my_timeout)
492
492
  client.my_timeout = setTimeout(() => {
493
+ // if the doc has been freed, exit early
494
+ if (resource.doc.__wbg_ptr === 0) return
495
+
493
496
  let version = resource.doc.getRemoteVersion().map((x) => x.join("-")).sort()
494
497
  let x = { version }
495
498
  x.parents = client.my_last_seen_version
@@ -507,7 +510,7 @@ braid_text.put = async (key, options) => {
507
510
  }
508
511
 
509
512
  if (client.my_timeout) {
510
- if (client.peer == peer) {
513
+ if (peer && client.peer === peer) {
511
514
  if (!v_eq(client.my_last_sent_version, og_parents)) {
512
515
  // note: we don't add to client.my_unused_version_count,
513
516
  // because we're already in a timeout;
@@ -523,7 +526,7 @@ braid_text.put = async (key, options) => {
523
526
  }
524
527
 
525
528
  let x = { version }
526
- if (client.peer == peer) {
529
+ if (peer && client.peer === peer) {
527
530
  if (!v_eq(client.my_last_sent_version, og_parents)) {
528
531
  client.my_unused_version_count = (client.my_unused_version_count ?? 0) + 1
529
532
  set_timeout()
@@ -571,37 +574,28 @@ braid_text.put = async (key, options) => {
571
574
  patches: og_patches,
572
575
  }
573
576
  for (let client of resource.clients) {
574
- if (client.peer != peer) client.subscribe(x)
577
+ if (!peer || client.peer !== peer) client.subscribe(x)
575
578
  }
576
579
 
577
580
  await resource.db_delta(resource.doc.getPatchSince(v_before))
578
581
  }
579
582
 
580
- // currently version must be an array with exactly one element, e.g. ["abc-1"]
581
583
  braid_text.revert = async (key, version) => {
582
584
  var resource = (typeof key == 'string') ? await get_resource(key) : key
583
585
 
584
- var [actor, seq] = decode_version(version[0])
585
-
586
- // get version without actor-seq,
587
- // and update actor_seqs
588
- var v = []
589
- for (var [a, s] of Object.entries(resource.actor_seqs)) {
590
- if (a !== actor) v.push(`${a}-${s}`)
591
- else {
592
- if (s < seq) return // nothing to do
593
- else if (seq > 0) {
594
- v.push(`${a}-${seq - 1}`)
595
- resource.actor_seqs[actor] = seq - 1
596
- } else delete resource.actor_seqs[actor]
597
- }
598
- }
599
-
600
586
  // revert dt
601
587
  var old_doc = resource.doc
602
- resource.doc = dt_get(resource.doc, v)
588
+ resource.doc = dt_get(resource.doc, null, null, version)
603
589
  old_doc.free()
604
590
 
591
+ for (let v of version) {
592
+ var [actor, seq] = decode_version(v)
593
+ if ((resource.actor_seqs[actor] ?? -1) > seq - 1) {
594
+ if (seq > 0) resource.actor_seqs[actor] = seq - 1
595
+ else delete resource.actor_seqs[actor]
596
+ }
597
+ }
598
+
605
599
  resource.val = resource.doc.get()
606
600
 
607
601
  // save it
@@ -849,32 +843,47 @@ function dt_get_string(doc, version) {
849
843
  return s
850
844
  }
851
845
 
852
- function dt_get(doc, version, agent = null) {
846
+ function dt_get(doc, version, agent = null, anti_version = null) {
853
847
  if (dt_get.last_doc) dt_get.last_doc.free()
854
848
 
855
849
  let bytes = doc.toBytes()
856
850
  dt_get.last_doc = doc = Doc.fromBytes(bytes, agent)
857
851
 
858
852
  let [_agents, versions, parentss] = dt_parse([...bytes])
859
-
860
- let frontier = new Set(version)
861
-
862
- let local_version = []
863
- for (let i = 0; i < versions.length; i++) {
864
- var v = versions[i].join("-")
865
- if (frontier.has(v)) {
866
- local_version.push(i)
867
- frontier.delete(v)
853
+ if (anti_version) {
854
+ var include_versions = new Set()
855
+ var bad_versions = new Set(anti_version)
856
+
857
+ for (let i = 0; i < versions.length; i++) {
858
+ var v = versions[i].join("-")
859
+ var ps = parentss[i].map(x => x.join('-'))
860
+ if (bad_versions.has(v) || ps.some(x => bad_versions.has(x)))
861
+ bad_versions.add(v)
862
+ else
863
+ include_versions.add(v)
868
864
  }
869
- }
870
-
871
- if (frontier.size) throw new Error(`version not found: ${version}`)
865
+ } else {
866
+ var include_versions = new Set(version)
867
+ var looking_for = new Set(version)
868
+ var local_version = []
869
+
870
+ for (let i = versions.length - 1; i >= 0; i--) {
871
+ var v = versions[i].join("-")
872
+ var ps = parentss[i].map(x => x.join('-'))
873
+ if (looking_for.has(v)) {
874
+ local_version.push(i)
875
+ looking_for.delete(v)
876
+ }
877
+ if (include_versions.has(v))
878
+ ps.forEach(x => include_versions.add(x))
879
+ }
880
+ local_version.reverse()
872
881
 
873
- dt_get.last_local_version = local_version = new Uint32Array(local_version)
882
+ // NOTE: currently used by braid-chrome in dt.js at the bottom
883
+ dt_get.last_local_version = new Uint32Array(local_version)
874
884
 
875
- let after_versions = {}
876
- let [_, after_versions_array, __] = dt_parse([...doc.getPatchSince(local_version)])
877
- for (let v of after_versions_array) after_versions[v.join("-")] = true
885
+ if (looking_for.size) throw new Error(`version not found: ${version}`)
886
+ }
878
887
 
879
888
  let new_doc = new Doc(agent)
880
889
  let op_runs = doc.getOpsSince([])
@@ -897,12 +906,12 @@ function dt_get(doc, version, agent = null) {
897
906
  ) {
898
907
  for (; i < I; i++) {
899
908
  let version = versions[i].join("-")
900
- if (after_versions[version]) continue
909
+ if (!include_versions.has(version)) continue
901
910
  let og_i = i
902
911
  let content = []
903
912
  if (op_run.content?.[i - base_i]) content.push(op_run.content[i - base_i])
904
913
  if (!!op_run.content === op_run.fwd)
905
- while (i + 1 < I && !after_versions[versions[i + 1].join("-")]) {
914
+ while (i + 1 < I && include_versions.has(versions[i + 1].join("-"))) {
906
915
  i++
907
916
  if (op_run.content?.[i - base_i]) content.push(op_run.content[i - base_i])
908
917
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.2.18",
3
+ "version": "0.2.20",
4
4
  "description": "Library for collaborative text over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braid-text",
package/test/test.js CHANGED
@@ -4,10 +4,10 @@ let braid_text = require('../index.js')
4
4
  let {dt_get, dt_get_patches, dt_parse, dt_create_bytes} = braid_text
5
5
 
6
6
  process.on("unhandledRejection", (x) =>
7
- console.log(`unhandledRejection: ${x.stack}`)
7
+ console.log(`unhandledRejection: ${x.stack ?? x}`)
8
8
  )
9
9
  process.on("uncaughtException", (x) =>
10
- console.log(`uncaughtException: ${x.stack}`)
10
+ console.log(`uncaughtException: ${x.stack ?? x}`)
11
11
  )
12
12
 
13
13
  braid_text.db_folder = null
@@ -48,7 +48,7 @@ async function main() {
48
48
  for (let t = 0; t < 10000; t++) {
49
49
  let seed = base + t
50
50
  // for (let t = 0; t < 1; t++) {
51
- // let seed = 7375800
51
+ // let seed = 2746153
52
52
 
53
53
  og_log(`t = ${t}, seed = ${seed}, best_n = ${best_n} @ ${best_seed}`)
54
54
  Math.randomSeed(seed)
@@ -80,7 +80,6 @@ async function main() {
80
80
  for (let x of dt_get_patches(doc)) {
81
81
  var resource = await braid_text.get_resource(key)
82
82
  var [actor, seq] = braid_text.decode_version(x.version)
83
- var pre_seq = resource.actor_seqs[actor]
84
83
  var old_text = await braid_text.get(key)
85
84
 
86
85
  console.log(`x = `, x)
@@ -99,7 +98,9 @@ async function main() {
99
98
  await braid_text.put(key, y)
100
99
 
101
100
  // test revert
102
- await braid_text.revert(key, [`${actor}-${(pre_seq ?? -1) + 1}`])
101
+ var range = x.range.match(/\d+/g).map((x) => parseInt(x))
102
+ var change_count = [...x.content].length + range[1] - range[0]
103
+ await braid_text.revert(key, [`${actor}-${seq + 1 - change_count}`])
103
104
  var new_text = await braid_text.get(key)
104
105
  if (old_text !== new_text) throw new Error('revert failed!')
105
106
  await braid_text.put(key, y)
@@ -127,6 +128,30 @@ async function main() {
127
128
  console.log(`doc = `, await braid_text.get('doc', {version: middle_v}))
128
129
  if (await braid_text.get('middle_doc') != (await braid_text.get('doc', {version: middle_v})).body) throw new Error('bad')
129
130
 
131
+ // test simplton
132
+ var first_time = true
133
+ await new Promise(async (done, fail) => {
134
+ await braid_text.get('middle_doc', {peer: 'sim', subscribe: async update => {
135
+ if (first_time) {
136
+ first_time = false
137
+ if (update.body !== await braid_text.get('middle_doc')) fail(new Error('test 2'))
138
+
139
+ var x = await braid_text.get('middle_doc', {})
140
+ await braid_text.put('middle_doc', {peer: 'sim', version: ['sim-0'], parents: x.version, patches: [{content: 'A', range: '[0:0]'}]})
141
+ await braid_text.put('middle_doc', {peer: 'other', merge_type: 'dt', version: ['other-0'], parents: [], patches: [{content: 'B', range: '[0:0]'}]})
142
+ await braid_text.put('middle_doc', {peer: 'sim', version: ['sim-1'], parents: ['sim-0'], patches: [{content: 'b', range: '[0:0]'}]})
143
+ await braid_text.put('middle_doc', {peer: 'sim', version: ['sim-2'], parents: ['sim-1'], patches: [{content: 'c', range: '[0:0]'}]})
144
+ await braid_text.revert('middle_doc', ['sim-0'])
145
+ await braid_text.revert('middle_doc', ['other-0'])
146
+
147
+ done()
148
+ }
149
+ }})
150
+ })
151
+
152
+ // test handler on dt
153
+ braid_text.get('middle_doc', {merge_type: 'dt', subscribe: async update => {}})
154
+
130
155
  // try getting updates from middle_doc to doc
131
156
  let o = {merge_type: 'dt', parents: middle_v, subscribe: update => {
132
157
  braid_text.put('middle_doc', update)