braid-text 0.0.19 → 0.0.21
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 +77 -23
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -4,7 +4,8 @@ let braidify = require("braid-http").http_server
|
|
|
4
4
|
let fs = require("fs")
|
|
5
5
|
|
|
6
6
|
let braid_text = {
|
|
7
|
-
db_folder: './braid-text-db'
|
|
7
|
+
db_folder: './braid-text-db',
|
|
8
|
+
cache: {}
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
let waiting_puts = 0
|
|
@@ -156,7 +157,7 @@ braid_text.serve = async (req, res, options = {}) => {
|
|
|
156
157
|
|
|
157
158
|
await braid_text.put(resource, { peer, version: req.version, parents: req.parents, patches, body, merge_type })
|
|
158
159
|
|
|
159
|
-
options.put_cb(options.key, resource.
|
|
160
|
+
options.put_cb(options.key, resource.val)
|
|
160
161
|
} catch (e) {
|
|
161
162
|
console.log(`EEE= ${e}:${e.stack}`)
|
|
162
163
|
// we couldn't apply the version, possibly because we're missing its parents,
|
|
@@ -195,8 +196,8 @@ braid_text.serve = async (req, res, options = {}) => {
|
|
|
195
196
|
braid_text.get = async (key, options) => {
|
|
196
197
|
if (!options) {
|
|
197
198
|
// if it doesn't exist already, don't create it in this case
|
|
198
|
-
if (!
|
|
199
|
-
return (await get_resource(key)).
|
|
199
|
+
if (!braid_text.cache[key]) return
|
|
200
|
+
return (await get_resource(key)).val
|
|
200
201
|
}
|
|
201
202
|
|
|
202
203
|
if (options.version) validate_version_array(options.version)
|
|
@@ -254,14 +255,7 @@ braid_text.get = async (key, options) => {
|
|
|
254
255
|
updates = OpLog_get_patches(resource.doc.toBytes(), resource.doc.getOpsSince([]))
|
|
255
256
|
} else {
|
|
256
257
|
// Then start the subscription from the parents in options
|
|
257
|
-
let
|
|
258
|
-
|
|
259
|
-
let local_version = []
|
|
260
|
-
let [agents, versions, parentss] = parseDT([...resource.doc.toBytes()])
|
|
261
|
-
for (let i = 0; i < versions.length; i++) {
|
|
262
|
-
if (parents[versions[i].join("-")]) local_version.push(i)
|
|
263
|
-
}
|
|
264
|
-
local_version = new Uint32Array(local_version)
|
|
258
|
+
let local_version = OpLog_remote_to_local(resource.doc, options.parents || options.version)
|
|
265
259
|
|
|
266
260
|
updates = OpLog_get_patches(resource.doc.getPatchSince(local_version), resource.doc.getOpsSince(local_version))
|
|
267
261
|
}
|
|
@@ -293,7 +287,13 @@ braid_text.put = async (key, options) => {
|
|
|
293
287
|
let { version, patches, body, peer } = options
|
|
294
288
|
|
|
295
289
|
if (version) validate_version_array(version)
|
|
296
|
-
|
|
290
|
+
|
|
291
|
+
// translate a single parent of "root" to the empty array (same meaning)
|
|
292
|
+
let options_parents = options.parents
|
|
293
|
+
if (options_parents?.length === 1 && options_parents[0] === 'root')
|
|
294
|
+
options_parents = []
|
|
295
|
+
|
|
296
|
+
if (options_parents) validate_version_array(options_parents)
|
|
297
297
|
if (body != null && patches) throw new Error(`cannot have a body and patches`)
|
|
298
298
|
if (body != null && (typeof body !== 'string')) throw new Error(`body must be a string`)
|
|
299
299
|
if (patches) validate_patches(patches)
|
|
@@ -301,7 +301,7 @@ braid_text.put = async (key, options) => {
|
|
|
301
301
|
let resource = (typeof key == 'string') ? await get_resource(key) : key
|
|
302
302
|
|
|
303
303
|
let parents = resource.doc.getRemoteVersion().map((x) => x.join("-"))
|
|
304
|
-
let og_parents =
|
|
304
|
+
let og_parents = options_parents || parents
|
|
305
305
|
|
|
306
306
|
let max_pos = count_code_points(v_eq(parents, og_parents) ?
|
|
307
307
|
resource.doc.get() :
|
|
@@ -338,7 +338,63 @@ braid_text.put = async (key, options) => {
|
|
|
338
338
|
let v = decode_version(og_v)
|
|
339
339
|
|
|
340
340
|
// validate version: make sure we haven't seen it already
|
|
341
|
-
if (v[1] <= (resource.actor_seqs[v[0]] ?? -1))
|
|
341
|
+
if (v[1] <= (resource.actor_seqs[v[0]] ?? -1)) {
|
|
342
|
+
|
|
343
|
+
// if we have seen it already, make sure it's the same as before
|
|
344
|
+
let local_version = OpLog_remote_to_local(resource.doc, og_parents)
|
|
345
|
+
let updates = OpLog_get_patches(resource.doc.getPatchSince(local_version), resource.doc.getOpsSince(local_version))
|
|
346
|
+
|
|
347
|
+
let seen = {}
|
|
348
|
+
for (let u of updates) {
|
|
349
|
+
if (u.start != u.end) {
|
|
350
|
+
// delete
|
|
351
|
+
let v = decode_version(u.version)
|
|
352
|
+
for (let i = 0; i < u.end - u.start; i++) {
|
|
353
|
+
let ps = (i < u.end - u.start - 1) ? [`${v[0]}-${v[1] - i - 1}`] : u.parents
|
|
354
|
+
seen[JSON.stringify([v[0], v[1] - i, ps, u.start + i])] = true
|
|
355
|
+
}
|
|
356
|
+
} else {
|
|
357
|
+
// insert
|
|
358
|
+
let v = decode_version(u.version)
|
|
359
|
+
let content = [...u.content]
|
|
360
|
+
for (let i = 0; i < content.length; i++) {
|
|
361
|
+
let ps = (i > 0) ? [`${v[0]}-${v[1] - content.length + i}`] : u.parents
|
|
362
|
+
seen[JSON.stringify([v[0], v[1] + 1 - content.length + i, ps, u.start + i, content[i]])] = true
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
v = `${v[0]}-${v[1] + 1 - change_count}`
|
|
368
|
+
let ps = og_parents
|
|
369
|
+
let offset = 0
|
|
370
|
+
for (let p of patches) {
|
|
371
|
+
// delete
|
|
372
|
+
for (let i = p.range[0]; i < p.range[1]; i++) {
|
|
373
|
+
let vv = decode_version(v)
|
|
374
|
+
|
|
375
|
+
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')
|
|
376
|
+
|
|
377
|
+
offset--
|
|
378
|
+
ps = [v]
|
|
379
|
+
v = vv
|
|
380
|
+
v = `${v[0]}-${v[1] + 1}`
|
|
381
|
+
}
|
|
382
|
+
// insert
|
|
383
|
+
for (let i = 0; i < p.content?.length ?? 0; i++) {
|
|
384
|
+
let c = p.content[i]
|
|
385
|
+
|
|
386
|
+
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')
|
|
387
|
+
|
|
388
|
+
offset++
|
|
389
|
+
ps = [v]
|
|
390
|
+
v = decode_version(v)
|
|
391
|
+
v = `${v[0]}-${v[1] + 1}`
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// we already have this version, so nothing left to do
|
|
396
|
+
return
|
|
397
|
+
}
|
|
342
398
|
resource.actor_seqs[v[0]] = v[1]
|
|
343
399
|
|
|
344
400
|
v = `${v[0]}-${v[1] + 1 - change_count}`
|
|
@@ -374,12 +430,6 @@ braid_text.put = async (key, options) => {
|
|
|
374
430
|
|
|
375
431
|
resource.need_defrag = true
|
|
376
432
|
|
|
377
|
-
let v_after = resource.doc.getLocalVersion()
|
|
378
|
-
if (JSON.stringify(v_before) === JSON.stringify(v_after)) {
|
|
379
|
-
console.log(`we got a version we already had: ${v_before}`)
|
|
380
|
-
return
|
|
381
|
-
}
|
|
382
|
-
|
|
383
433
|
if (options.merge_type != "dt") {
|
|
384
434
|
patches = get_xf_patches(resource.doc, v_before)
|
|
385
435
|
console.log(JSON.stringify({ patches }))
|
|
@@ -479,6 +529,8 @@ braid_text.put = async (key, options) => {
|
|
|
479
529
|
}
|
|
480
530
|
|
|
481
531
|
await resource.db_delta(resource.doc.getPatchSince(v_before))
|
|
532
|
+
|
|
533
|
+
resource.val = resource.doc.get()
|
|
482
534
|
}
|
|
483
535
|
|
|
484
536
|
braid_text.list = async () => {
|
|
@@ -488,12 +540,12 @@ braid_text.list = async () => {
|
|
|
488
540
|
var pages = new Set()
|
|
489
541
|
for (let x of await require('fs').promises.readdir(braid_text.db_folder)) pages.add(decode_filename(x.replace(/\.\w+$/, '')))
|
|
490
542
|
return [...pages.keys()]
|
|
491
|
-
} else return Object.keys(
|
|
543
|
+
} else return Object.keys(braid_text.cache)
|
|
492
544
|
} catch (e) { return [] }
|
|
493
545
|
}
|
|
494
546
|
|
|
495
547
|
async function get_resource(key) {
|
|
496
|
-
let cache =
|
|
548
|
+
let cache = braid_text.cache
|
|
497
549
|
if (!cache[key]) cache[key] = new Promise(async done => {
|
|
498
550
|
let resource = {}
|
|
499
551
|
resource.clients = new Set()
|
|
@@ -524,6 +576,8 @@ async function get_resource(key) {
|
|
|
524
576
|
delete cache[key]
|
|
525
577
|
}
|
|
526
578
|
|
|
579
|
+
resource.val = resource.doc.get()
|
|
580
|
+
|
|
527
581
|
done(resource)
|
|
528
582
|
})
|
|
529
583
|
return await cache[key]
|