braid-text 0.2.15 → 0.2.17
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 +56 -24
- package/package.json +1 -1
- package/test/server.js +1 -1
- package/test/test.js +37 -7
package/index.js
CHANGED
|
@@ -80,7 +80,7 @@ braid_text.serve = async (req, res, options = {}) => {
|
|
|
80
80
|
try {
|
|
81
81
|
x = await braid_text.get(resource, { version: req.version, parents: req.parents })
|
|
82
82
|
} catch (e) {
|
|
83
|
-
return my_end(
|
|
83
|
+
return my_end(500, "The server failed to get something. The error generated was: " + e)
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
res.setHeader("Version", x.version.map((x) => JSON.stringify(x)).join(", "))
|
|
@@ -116,7 +116,7 @@ braid_text.serve = async (req, res, options = {}) => {
|
|
|
116
116
|
try {
|
|
117
117
|
return await braid_text.get(resource, options)
|
|
118
118
|
} catch (e) {
|
|
119
|
-
return my_end(
|
|
119
|
+
return my_end(500, "The server failed to get something. The error generated was: " + e)
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -192,7 +192,7 @@ braid_text.serve = async (req, res, options = {}) => {
|
|
|
192
192
|
// - cons: typically implies that the request was missing an http conditional field like If-Match. that is to say, it implies that the request is missing a precondition, not that the server is missing a precondition
|
|
193
193
|
return done_my_turn(425, e.message)
|
|
194
194
|
} else {
|
|
195
|
-
return done_my_turn(
|
|
195
|
+
return done_my_turn(500, "The server failed to apply this version. The error generated was: " + e)
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
|
|
@@ -219,17 +219,14 @@ braid_text.get = async (key, options) => {
|
|
|
219
219
|
let resource = (typeof key == 'string') ? await get_resource(key) : key
|
|
220
220
|
|
|
221
221
|
if (!options.subscribe) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
if (options.version || options.parents) doc.free()
|
|
231
|
-
|
|
232
|
-
return ret
|
|
222
|
+
return options.version || options.parents ?
|
|
223
|
+
{
|
|
224
|
+
version: options.version || options.parents,
|
|
225
|
+
body: dt_get_string(resource.doc, options.version || options.parents)
|
|
226
|
+
} : {
|
|
227
|
+
version: resource.doc.getRemoteVersion().map((x) => x.join("-")).sort(),
|
|
228
|
+
body: resource.doc.get()
|
|
229
|
+
}
|
|
233
230
|
} else {
|
|
234
231
|
if (options.merge_type != "dt") {
|
|
235
232
|
let version = resource.doc.getRemoteVersion().map((x) => x.join("-")).sort()
|
|
@@ -580,6 +577,34 @@ braid_text.put = async (key, options) => {
|
|
|
580
577
|
await resource.db_delta(resource.doc.getPatchSince(v_before))
|
|
581
578
|
}
|
|
582
579
|
|
|
580
|
+
braid_text.revert = async (key, actor, seq) => {
|
|
581
|
+
var resource = (typeof key == 'string') ? await get_resource(key) : key
|
|
582
|
+
|
|
583
|
+
// get version without actor-seq,
|
|
584
|
+
// and update actor_seqs
|
|
585
|
+
var v = []
|
|
586
|
+
for (var [a, s] of Object.entries(resource.actor_seqs)) {
|
|
587
|
+
if (a !== actor) v.push(`${a}-${s}`)
|
|
588
|
+
else {
|
|
589
|
+
if (s < seq) return // nothing to do
|
|
590
|
+
else if (seq > 0) {
|
|
591
|
+
v.push(`${a}-${seq - 1}`)
|
|
592
|
+
resource.actor_seqs[actor] = seq - 1
|
|
593
|
+
} else delete resource.actor_seqs[actor]
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// revert dt
|
|
598
|
+
var old_doc = resource.doc
|
|
599
|
+
resource.doc = dt_get(resource.doc, v)
|
|
600
|
+
old_doc.free()
|
|
601
|
+
|
|
602
|
+
resource.val = resource.doc.get()
|
|
603
|
+
|
|
604
|
+
// save it
|
|
605
|
+
await resource.db_delta()
|
|
606
|
+
}
|
|
607
|
+
|
|
583
608
|
braid_text.list = async () => {
|
|
584
609
|
try {
|
|
585
610
|
if (braid_text.db_folder) {
|
|
@@ -745,7 +770,8 @@ async function file_sync(key, process_delta, get_init) {
|
|
|
745
770
|
return {
|
|
746
771
|
change: async (bytes) => {
|
|
747
772
|
await (chain = chain.then(async () => {
|
|
748
|
-
|
|
773
|
+
if (!bytes) currentSize = threshold
|
|
774
|
+
else currentSize += bytes.length + 4 // we account for the extra 4 bytes for uint32
|
|
749
775
|
const filename = `${braid_text.db_folder}/${encoded}.${currentNumber}`
|
|
750
776
|
if (currentSize < threshold) {
|
|
751
777
|
if (braid_text.verbose) console.log(`appending to db..`)
|
|
@@ -790,14 +816,18 @@ async function file_sync(key, process_delta, get_init) {
|
|
|
790
816
|
//////////////////////////////////////////////////////////////////
|
|
791
817
|
|
|
792
818
|
function dt_len(doc, version) {
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
let [_agents, versions, _parentss] = dt_parse([...bytes])
|
|
819
|
+
return count_code_points(dt_get_string(doc, version))
|
|
820
|
+
}
|
|
796
821
|
|
|
797
|
-
|
|
822
|
+
function dt_get_string(doc, version) {
|
|
823
|
+
var bytes = doc.toBytes()
|
|
824
|
+
var oplog = OpLog.fromBytes(bytes)
|
|
825
|
+
var [_agents, versions, _parentss] = dt_parse([...bytes])
|
|
798
826
|
|
|
799
|
-
|
|
800
|
-
|
|
827
|
+
var frontier = new Set(version)
|
|
828
|
+
|
|
829
|
+
var local_version = []
|
|
830
|
+
for (var i = 0; i < versions.length; i++) {
|
|
801
831
|
var v = versions[i].join("-")
|
|
802
832
|
if (frontier.has(v)) {
|
|
803
833
|
local_version.push(i)
|
|
@@ -807,13 +837,13 @@ function dt_len(doc, version) {
|
|
|
807
837
|
|
|
808
838
|
if (frontier.size) throw new Error(`version not found: ${version}`)
|
|
809
839
|
|
|
810
|
-
|
|
840
|
+
var b = new Branch()
|
|
811
841
|
b.merge(oplog, new Uint32Array(local_version))
|
|
812
|
-
|
|
842
|
+
var s = b.get()
|
|
813
843
|
b.free()
|
|
814
844
|
|
|
815
845
|
oplog.free()
|
|
816
|
-
return
|
|
846
|
+
return s
|
|
817
847
|
}
|
|
818
848
|
|
|
819
849
|
function dt_get(doc, version, agent = null) {
|
|
@@ -1741,4 +1771,6 @@ braid_text.dt_get_patches = dt_get_patches
|
|
|
1741
1771
|
braid_text.dt_parse = dt_parse
|
|
1742
1772
|
braid_text.dt_create_bytes = dt_create_bytes
|
|
1743
1773
|
|
|
1774
|
+
braid_text.decode_version = decode_version
|
|
1775
|
+
|
|
1744
1776
|
module.exports = braid_text
|
package/package.json
CHANGED
package/test/server.js
CHANGED
package/test/test.js
CHANGED
|
@@ -12,18 +12,43 @@ process.on("uncaughtException", (x) =>
|
|
|
12
12
|
|
|
13
13
|
braid_text.db_folder = null
|
|
14
14
|
|
|
15
|
+
async function test_revert() {
|
|
16
|
+
braid_text.db_folder = './braid-text-db'
|
|
17
|
+
var key = Math.random().toString(36).slice(2)
|
|
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)
|
|
21
|
+
delete braid_text.cache[key]
|
|
22
|
+
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
|
+
|
|
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')
|
|
34
|
+
|
|
35
|
+
braid_text.db_folder = null
|
|
36
|
+
}
|
|
37
|
+
|
|
15
38
|
async function main() {
|
|
16
39
|
let best_seed = NaN
|
|
17
40
|
let best_n = Infinity
|
|
18
41
|
let base = Math.floor(Math.random() * 10000000)
|
|
19
42
|
let st = Date.now()
|
|
20
43
|
|
|
44
|
+
await test_revert()
|
|
45
|
+
|
|
21
46
|
let og_log = console.log
|
|
22
47
|
console.log = () => {}
|
|
23
48
|
for (let t = 0; t < 10000; t++) {
|
|
24
49
|
let seed = base + t
|
|
25
50
|
// for (let t = 0; t < 1; t++) {
|
|
26
|
-
// let seed =
|
|
51
|
+
// let seed = 7375800
|
|
27
52
|
|
|
28
53
|
og_log(`t = ${t}, seed = ${seed}, best_n = ${best_n} @ ${best_seed}`)
|
|
29
54
|
Math.randomSeed(seed)
|
|
@@ -53,6 +78,11 @@ async function main() {
|
|
|
53
78
|
let dt_to_braid = async (doc, key) => {
|
|
54
79
|
await braid_text.get(key, {})
|
|
55
80
|
for (let x of dt_get_patches(doc)) {
|
|
81
|
+
var resource = await braid_text.get_resource(key)
|
|
82
|
+
var [actor, seq] = braid_text.decode_version(x.version)
|
|
83
|
+
var pre_seq = resource.actor_seqs[actor]
|
|
84
|
+
var old_text = await braid_text.get(key)
|
|
85
|
+
|
|
56
86
|
console.log(`x = `, x)
|
|
57
87
|
let y = {
|
|
58
88
|
merge_type: 'dt',
|
|
@@ -67,6 +97,12 @@ async function main() {
|
|
|
67
97
|
await braid_text.put(key, y)
|
|
68
98
|
y.validate_already_seen_versions = true
|
|
69
99
|
await braid_text.put(key, y)
|
|
100
|
+
|
|
101
|
+
// test revert
|
|
102
|
+
await braid_text.revert(key, actor, (pre_seq ?? -1) + 1)
|
|
103
|
+
var new_text = await braid_text.get(key)
|
|
104
|
+
if (old_text !== new_text) throw new Error('revert failed!')
|
|
105
|
+
await braid_text.put(key, y)
|
|
70
106
|
}
|
|
71
107
|
}
|
|
72
108
|
await dt_to_braid(doc, 'doc')
|
|
@@ -196,12 +232,6 @@ function getRandomCharacter() {
|
|
|
196
232
|
return characters[randomIndex];
|
|
197
233
|
}
|
|
198
234
|
|
|
199
|
-
function decode_version(v) {
|
|
200
|
-
let m = v.match(/^(.*)-(\d+)$/s)
|
|
201
|
-
if (!m) throw new Error(`invalid actor-seq version: ${v}`)
|
|
202
|
-
return [m[1], parseInt(m[2])]
|
|
203
|
-
}
|
|
204
|
-
|
|
205
235
|
/////////
|
|
206
236
|
|
|
207
237
|
// the next two functions added by me
|