braid-text 0.2.21 → 0.2.23

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 +53 -26
  2. package/package.json +2 -2
  3. package/test/test.js +5 -32
package/index.js CHANGED
@@ -334,7 +334,8 @@ braid_text.put = async (key, options) => {
334
334
  // make sure we have all these parents
335
335
  for (let p of options_parents) {
336
336
  let P = decode_version(p)
337
- if (P[1] > (resource.actor_seqs[P[0]] ?? -1)) throw new Error(`${MISSING_PARENT_VERSION}: ${p}`)
337
+ if (!resource.actor_seqs[P[0]]?.has(P[1]))
338
+ throw new Error(`${MISSING_PARENT_VERSION}: ${p}`)
338
339
  }
339
340
  }
340
341
 
@@ -378,7 +379,7 @@ braid_text.put = async (key, options) => {
378
379
  max_pos))
379
380
 
380
381
  // validate version: make sure we haven't seen it already
381
- if (v[1] <= (resource.actor_seqs[v[0]] ?? -1)) {
382
+ if (resource.actor_seqs[v[0]]?.has(v[1])) {
382
383
 
383
384
  if (!options.validate_already_seen_versions) return
384
385
 
@@ -439,7 +440,8 @@ braid_text.put = async (key, options) => {
439
440
  // we already have this version, so nothing left to do
440
441
  return
441
442
  }
442
- resource.actor_seqs[v[0]] = v[1]
443
+ if (!resource.actor_seqs[v[0]]) resource.actor_seqs[v[0]] = new RangeSet()
444
+ resource.actor_seqs[v[0]].add_range(v[1] + 1 - change_count, v[1])
443
445
 
444
446
  // reduce the version sequence by the number of char-edits
445
447
  v = `${v[0]}-${v[1] + 1 - change_count}`
@@ -580,28 +582,6 @@ braid_text.put = async (key, options) => {
580
582
  await resource.db_delta(resource.doc.getPatchSince(v_before))
581
583
  }
582
584
 
583
- braid_text.revert = async (key, version) => {
584
- var resource = (typeof key == 'string') ? await get_resource(key) : key
585
-
586
- // revert dt
587
- var old_doc = resource.doc
588
- resource.doc = dt_get(resource.doc, null, null, version)
589
- old_doc.free()
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
-
599
- resource.val = resource.doc.get()
600
-
601
- // save it
602
- await resource.db_delta()
603
- }
604
-
605
585
  braid_text.list = async () => {
606
586
  try {
607
587
  if (braid_text.db_folder) {
@@ -645,7 +625,8 @@ async function get_resource(key) {
645
625
  let max_version = resource.doc.getLocalVersion().reduce((a, b) => Math.max(a, b), -1)
646
626
  for (let i = 0; i <= max_version; i++) {
647
627
  let v = resource.doc.localToRemoteVersion([i])[0]
648
- resource.actor_seqs[v[0]] = Math.max(v[1], resource.actor_seqs[v[0]] ?? -1)
628
+ if (!resource.actor_seqs[v[0]]) resource.actor_seqs[v[0]] = new RangeSet()
629
+ resource.actor_seqs[v[0]].add_range(v[1], v[1])
649
630
  }
650
631
 
651
632
  resource.val = resource.doc.get()
@@ -1772,6 +1753,52 @@ function apply_patch(obj, range, content) {
1772
1753
  }
1773
1754
  }
1774
1755
 
1756
+ class RangeSet {
1757
+ constructor() {
1758
+ this.ranges = []
1759
+ }
1760
+
1761
+ add_range(low_inclusive, high_inclusive) {
1762
+ if (low_inclusive > high_inclusive) return
1763
+
1764
+ const startIndex = this._bs(mid => this.ranges[mid][1] >= low_inclusive - 1, this.ranges.length, true)
1765
+ const endIndex = this._bs(mid => this.ranges[mid][0] <= high_inclusive + 1, -1, false)
1766
+
1767
+ if (startIndex > endIndex) {
1768
+ this.ranges.splice(startIndex, 0, [low_inclusive, high_inclusive])
1769
+ } else {
1770
+ const mergedLow = Math.min(low_inclusive, this.ranges[startIndex][0])
1771
+ const mergedHigh = Math.max(high_inclusive, this.ranges[endIndex][1])
1772
+ const removeCount = endIndex - startIndex + 1
1773
+ this.ranges.splice(startIndex, removeCount, [mergedLow, mergedHigh])
1774
+ }
1775
+ }
1776
+
1777
+ has(x) {
1778
+ var index = this._bs(mid => this.ranges[mid][0] <= x, -1, false)
1779
+ return index !== -1 && x <= this.ranges[index][1]
1780
+ }
1781
+
1782
+ _bs(condition, defaultR, moveLeft) {
1783
+ let low = 0
1784
+ let high = this.ranges.length - 1
1785
+ let result = defaultR
1786
+
1787
+ while (low <= high) {
1788
+ const mid = Math.floor((low + high) / 2)
1789
+ if (condition(mid)) {
1790
+ result = mid
1791
+ if (moveLeft) high = mid - 1
1792
+ else low = mid + 1
1793
+ } else {
1794
+ if (moveLeft) low = mid + 1
1795
+ else high = mid - 1
1796
+ }
1797
+ }
1798
+ return result
1799
+ }
1800
+ }
1801
+
1775
1802
  braid_text.get_resource = get_resource
1776
1803
 
1777
1804
  braid_text.encode_filename = encode_filename
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
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
  "diamond-types-node": "^1.0.2",
10
- "braid-http": "^1.3.73"
10
+ "braid-http": "^1.3.74"
11
11
  }
12
12
  }
package/test/test.js CHANGED
@@ -12,25 +12,15 @@ process.on("uncaughtException", (x) =>
12
12
 
13
13
  braid_text.db_folder = null
14
14
 
15
- async function test_revert() {
15
+ async function test_db() {
16
16
  braid_text.db_folder = './braid-text-db'
17
17
  var key = Math.random().toString(36).slice(2)
18
18
  await braid_text.put(key, {version: ['a-0'], body: 'A'})
19
- await braid_text.put(key, {version: ['a-1'], parents: ['a-0'], patches: [{range: '[1:1]', content: 'B'}]})
20
- await braid_text.revert(key, ['a-1'])
19
+ await braid_text.put(key, {version: ['a-2'], parents: ['a-0'], patches: [{range: '[1:1]', content: 'B'}]})
21
20
  delete braid_text.cache[key]
22
21
  var {version, body} = await braid_text.get(key, {})
23
- if (version[0] != 'a-0') throw new Error('revert error: wrong version')
24
- if (body != 'A') throw new Error('revert error: wrong text')
25
22
 
26
- await braid_text.put(key, {version: ['b-0'], parents: ['a-0'], patches: [{range: '[1:1]', content: 'C'}]})
27
- if ('AC' !== await braid_text.get(key)) throw new Error('revert error: wrong text')
28
- await braid_text.revert(key, ['b-0'])
29
- if ('A' !== await braid_text.get(key)) throw new Error('revert error: wrong text')
30
- delete braid_text.cache[key]
31
- var {version, body} = await braid_text.get(key, {})
32
- if (version[0] != 'a-0') throw new Error('revert error: wrong version')
33
- if (body != 'A') throw new Error('revert error: wrong text')
23
+ if (body != 'AB') throw new Error('db error')
34
24
 
35
25
  braid_text.db_folder = null
36
26
  }
@@ -41,7 +31,7 @@ async function main() {
41
31
  let base = Math.floor(Math.random() * 10000000)
42
32
  let st = Date.now()
43
33
 
44
- await test_revert()
34
+ await test_db()
45
35
 
46
36
  let og_log = console.log
47
37
  console.log = () => {}
@@ -96,14 +86,6 @@ async function main() {
96
86
  await braid_text.put(key, y)
97
87
  y.validate_already_seen_versions = true
98
88
  await braid_text.put(key, y)
99
-
100
- // test revert
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}`])
104
- var new_text = await braid_text.get(key)
105
- if (old_text !== new_text) throw new Error('revert failed!')
106
- await braid_text.put(key, y)
107
89
  }
108
90
  }
109
91
  await dt_to_braid(doc, 'doc')
@@ -134,16 +116,7 @@ async function main() {
134
116
  await braid_text.get('middle_doc', {peer: 'sim', subscribe: async update => {
135
117
  if (first_time) {
136
118
  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
-
119
+ if (update.body !== await braid_text.get('middle_doc')) fail(new Error('simpleton fail'))
147
120
  done()
148
121
  }
149
122
  }})