braid-text 0.0.19 → 0.0.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 (2) hide show
  1. package/index.js +66 -17
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -254,14 +254,7 @@ braid_text.get = async (key, options) => {
254
254
  updates = OpLog_get_patches(resource.doc.toBytes(), resource.doc.getOpsSince([]))
255
255
  } else {
256
256
  // Then start the subscription from the parents in options
257
- let parents = Object.fromEntries((options.parents ? options.parents : options.version).map((x) => [x, true]))
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)
257
+ let local_version = OpLog_remote_to_local(resource.doc, options.parents || options.version)
265
258
 
266
259
  updates = OpLog_get_patches(resource.doc.getPatchSince(local_version), resource.doc.getOpsSince(local_version))
267
260
  }
@@ -293,7 +286,13 @@ braid_text.put = async (key, options) => {
293
286
  let { version, patches, body, peer } = options
294
287
 
295
288
  if (version) validate_version_array(version)
296
- if (options.parents) validate_version_array(options.parents)
289
+
290
+ // translate a single parent of "root" to the empty array (same meaning)
291
+ let options_parents = options.parents
292
+ if (options_parents?.length === 1 && options_parents[0] === 'root')
293
+ options_parents = []
294
+
295
+ if (options_parents) validate_version_array(options_parents)
297
296
  if (body != null && patches) throw new Error(`cannot have a body and patches`)
298
297
  if (body != null && (typeof body !== 'string')) throw new Error(`body must be a string`)
299
298
  if (patches) validate_patches(patches)
@@ -301,7 +300,7 @@ braid_text.put = async (key, options) => {
301
300
  let resource = (typeof key == 'string') ? await get_resource(key) : key
302
301
 
303
302
  let parents = resource.doc.getRemoteVersion().map((x) => x.join("-"))
304
- let og_parents = options.parents || parents
303
+ let og_parents = options_parents || parents
305
304
 
306
305
  let max_pos = count_code_points(v_eq(parents, og_parents) ?
307
306
  resource.doc.get() :
@@ -338,7 +337,63 @@ braid_text.put = async (key, options) => {
338
337
  let v = decode_version(og_v)
339
338
 
340
339
  // validate version: make sure we haven't seen it already
341
- if (v[1] <= (resource.actor_seqs[v[0]] ?? -1)) throw new Error(`invalid version: already processed`)
340
+ if (v[1] <= (resource.actor_seqs[v[0]] ?? -1)) {
341
+
342
+ // if we have seen it already, make sure it's the same as before
343
+ let local_version = OpLog_remote_to_local(resource.doc, og_parents)
344
+ let updates = OpLog_get_patches(resource.doc.getPatchSince(local_version), resource.doc.getOpsSince(local_version))
345
+
346
+ let seen = {}
347
+ for (let u of updates) {
348
+ if (u.start != u.end) {
349
+ // delete
350
+ let v = decode_version(u.version)
351
+ for (let i = 0; i < u.end - u.start; i++) {
352
+ let ps = (i < u.end - u.start - 1) ? [`${v[0]}-${v[1] - i - 1}`] : u.parents
353
+ seen[JSON.stringify([v[0], v[1] - i, ps, u.start + i])] = true
354
+ }
355
+ } else {
356
+ // insert
357
+ let v = decode_version(u.version)
358
+ let content = [...u.content]
359
+ for (let i = 0; i < content.length; i++) {
360
+ let ps = (i > 0) ? [`${v[0]}-${v[1] - content.length + i}`] : u.parents
361
+ seen[JSON.stringify([v[0], v[1] + 1 - content.length + i, ps, u.start + i, content[i]])] = true
362
+ }
363
+ }
364
+ }
365
+
366
+ v = `${v[0]}-${v[1] + 1 - change_count}`
367
+ let ps = og_parents
368
+ let offset = 0
369
+ for (let p of patches) {
370
+ // delete
371
+ for (let i = p.range[0]; i < p.range[1]; i++) {
372
+ let vv = decode_version(v)
373
+
374
+ 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')
375
+
376
+ offset--
377
+ ps = [v]
378
+ v = vv
379
+ v = `${v[0]}-${v[1] + 1}`
380
+ }
381
+ // insert
382
+ for (let i = 0; i < p.content?.length ?? 0; i++) {
383
+ let c = p.content[i]
384
+
385
+ 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')
386
+
387
+ offset++
388
+ ps = [v]
389
+ v = decode_version(v)
390
+ v = `${v[0]}-${v[1] + 1}`
391
+ }
392
+ }
393
+
394
+ // we already have this version, so nothing left to do
395
+ return
396
+ }
342
397
  resource.actor_seqs[v[0]] = v[1]
343
398
 
344
399
  v = `${v[0]}-${v[1] + 1 - change_count}`
@@ -374,12 +429,6 @@ braid_text.put = async (key, options) => {
374
429
 
375
430
  resource.need_defrag = true
376
431
 
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
432
  if (options.merge_type != "dt") {
384
433
  patches = get_xf_patches(resource.doc, v_before)
385
434
  console.log(JSON.stringify({ patches }))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "description": "Library for collaborative text over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braidjs",