braid-text 0.2.22 → 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.
- package/index.js +53 -26
- package/package.json +1 -1
- 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 (
|
|
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 (
|
|
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]]
|
|
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]]
|
|
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
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
|
|
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-
|
|
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
|
-
|
|
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
|
|
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('
|
|
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
|
}})
|