braidfs 0.0.91 → 0.0.93

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 +118 -73
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -375,28 +375,25 @@ async function sync_url(url) {
375
375
  fullpath = `${sync_base}/${path}`,
376
376
  meta_path = `${sync_base_meta}/${braid_text.encode_filename(url)}`
377
377
 
378
- async function get_fullpath() {
379
- var p = fullpath
380
- while (await is_dir(p)) p = require("path").join(p, 'index')
381
- return p
382
- }
383
-
384
378
  if (!sync_url.cache) sync_url.cache = {}
385
379
  if (!sync_url.chain) sync_url.chain = Promise.resolve()
386
380
  if (!sync_url.cache[path]) {
387
381
  var freed = false,
388
382
  aborts = new Set(),
389
- braid_text_get_options = null,
390
- wait_count = 0
391
- var wait_promise, wait_promise_done
392
- var start_something = () => {
393
- if (freed) return
394
- if (!wait_count) wait_promise = new Promise(done => wait_promise_done = done)
395
- return ++wait_count
383
+ braid_text_get_options = null
384
+ var wait_promise = Promise.resolve()
385
+ var wait_on = p => {
386
+ wait_promise = wait_promise.then(() => p)
387
+ return p
396
388
  }
397
- var finish_something = () => {
398
- wait_count--
399
- if (!wait_count) wait_promise_done()
389
+ var get_fullpath = async () => {
390
+ if (freed) return
391
+ var p = fullpath
392
+ while (await wait_on(is_dir(p))) {
393
+ if (freed) return
394
+ p = require("path").join(p, 'index')
395
+ }
396
+ return p
400
397
  }
401
398
  if (!unsync_url.cache) unsync_url.cache = {}
402
399
  unsync_url.cache[path] = async () => {
@@ -417,19 +414,25 @@ async function sync_url(url) {
417
414
  sync_url.cache[path] = sync_url.chain = sync_url.chain.then(init)
418
415
  }
419
416
  async function init() {
417
+ if (freed) return
418
+
420
419
  var self = {url}
421
420
 
422
421
  console.log(`sync_url: ${url}`)
423
422
 
424
- if (!start_something()) return
423
+ var resource = await braid_text.get_resource(url)
424
+ if (freed) return
425
425
 
426
426
  // if we're accessing /blah/index, it will be normalized to /blah,
427
427
  // but we still want to create a directory out of blah in this case
428
- if (wasnt_normal && !(await is_dir(fullpath))) await ensure_path(fullpath)
428
+ if (wasnt_normal && !(await is_dir(fullpath))) {
429
+ if (freed) return
430
+ await ensure_path(fullpath)
431
+ }
432
+ if (freed) return
429
433
 
430
434
  await ensure_path(require("path").dirname(fullpath))
431
-
432
- finish_something()
435
+ if (freed) return
433
436
 
434
437
  self.peer = Math.random().toString(36).slice(2)
435
438
  self.local_edit_counter = 0
@@ -487,7 +490,7 @@ async function sync_url(url) {
487
490
  }
488
491
 
489
492
  async function my_fetch(params) {
490
- if (!start_something()) return
493
+ if (freed) return
491
494
  try {
492
495
  var a = new AbortController()
493
496
  aborts.add(a)
@@ -502,23 +505,26 @@ async function sync_url(url) {
502
505
  ...params
503
506
  })
504
507
  } catch (e) {
508
+ if (freed) return
505
509
  if (e?.name !== "AbortError") console.log(e)
506
510
  } finally {
511
+ if (freed) return
507
512
  aborts.delete(a)
508
- finish_something()
509
513
  }
510
514
  }
511
515
 
512
516
  async function send_out(stuff) {
513
517
  if (!is_external_link) return
518
+ if (freed) return
514
519
 
515
520
  console.log(`send_out ${url} ${JSON.stringify(stuff, null, 4).slice(0, 1000)}`)
516
521
 
517
522
  var r = await my_fetch({ method: "PUT", ...stuff })
523
+ if (freed) return
518
524
 
519
525
  // the server has acknowledged this version,
520
526
  // so add it to the fork point
521
- if (r.ok) await self.update_fork_point(stuff.version[0], stuff.parents)
527
+ if (r.ok) self.update_fork_point(stuff.version[0], stuff.parents)
522
528
 
523
529
  // if we're not authorized,
524
530
  if (r.status == 401 || r.status == 403) {
@@ -532,13 +538,18 @@ async function sync_url(url) {
532
538
  }
533
539
  }
534
540
 
535
- if (!start_something()) return
536
541
  await within_fiber(fullpath, async () => {
542
+ if (freed) return
537
543
  var fullpath = await get_fullpath()
538
- if (await require('fs').promises.access(meta_path).then(
539
- () => 1, () => 0)) {
544
+ if (freed) return
545
+ if (await wait_on(require('fs').promises.access(meta_path).then(
546
+ () => 1, () => 0))) {
547
+ if (freed) return
548
+
540
549
  // meta file exists
541
- let meta = JSON.parse(await require('fs').promises.readFile(meta_path, { encoding: 'utf8' }))
550
+ let meta = JSON.parse(await wait_on(require('fs').promises.readFile(meta_path, { encoding: 'utf8' })))
551
+ if (freed) return
552
+
542
553
  // destructure stuff from the meta file
543
554
  !({
544
555
  version: file_last_version,
@@ -552,8 +563,9 @@ async function sync_url(url) {
552
563
  if (!self.local_edit_counter) self.local_edit_counter = 0
553
564
 
554
565
  try {
555
- self.file_last_text = (await braid_text.get(url, { version: file_last_version })).body
566
+ self.file_last_text = (await wait_on(braid_text.get(url, { version: file_last_version }))).body
556
567
  } catch (e) {
568
+ if (freed) return
557
569
  // the version from the meta file doesn't exist..
558
570
  if (fullpath === braidfs_config_file) {
559
571
  // in the case of the config file,
@@ -561,44 +573,49 @@ async function sync_url(url) {
561
573
  // which we can acheive by setting file_last_version
562
574
  // to the latest
563
575
  console.log(`WARNING: there was an issue with the config file, and it is reverting to the contents at: ${braidfs_config_file}`)
564
- var x = await braid_text.get(url, {})
576
+ var x = await wait_on(braid_text.get(url, {}))
577
+ if (freed) return
565
578
  file_last_version = x.version
566
579
  self.file_last_text = x.body
567
580
  file_last_digest = sha256(self.file_last_text)
568
581
  } else throw new Error(`sync error: version not found: ${file_last_version}`)
569
582
  }
583
+ if (freed) return
570
584
 
571
- file_needs_writing = !v_eq(file_last_version, (await braid_text.get(url, {})).version)
585
+ file_needs_writing = !v_eq(file_last_version, (await wait_on(braid_text.get(url, {}))).version)
586
+ if (freed) return
572
587
 
573
588
  // sanity check
574
589
  if (file_last_digest && sha256(self.file_last_text) != file_last_digest) throw new Error('file_last_text does not match file_last_digest')
575
- } else if (await require('fs').promises.access(fullpath).then(() => 1, () => 0)) {
590
+ } else if (await wait_on(require('fs').promises.access(fullpath).then(() => 1, () => 0))) {
591
+ if (freed) return
576
592
  // file exists, but not meta file
577
593
  file_last_version = []
578
594
  self.file_last_text = ''
579
595
  }
580
596
  })
581
- finish_something()
597
+ if (freed) return
582
598
 
583
599
  file_loop_pump()
584
600
  async function file_loop_pump() {
601
+ if (freed) return
585
602
  if (file_loop_pump_lock) return
586
603
  file_loop_pump_lock++
587
604
 
588
- if (!start_something()) return
589
-
590
605
  await within_fiber(fullpath, async () => {
591
606
  var fullpath = await get_fullpath()
607
+ if (freed) return
592
608
 
593
609
  while (file_needs_reading || file_needs_writing) {
594
610
  async function write_meta_file() {
595
- await require('fs').promises.writeFile(meta_path, JSON.stringify({
611
+ if (freed) return
612
+ await wait_on(require('fs').promises.writeFile(meta_path, JSON.stringify({
596
613
  version: file_last_version,
597
614
  digest: sha256(self.file_last_text),
598
615
  peer: self.peer,
599
616
  local_edit_counter: self.local_edit_counter,
600
617
  fork_point: self.fork_point
601
- }))
618
+ })))
602
619
  }
603
620
 
604
621
  if (file_needs_reading) {
@@ -607,22 +624,28 @@ async function sync_url(url) {
607
624
  file_needs_reading = false
608
625
 
609
626
  // check if file is missing, and create it if so..
610
- if (!(await file_exists(fullpath))) {
627
+ if (!(await wait_on(file_exists(fullpath)))) {
628
+ if (freed) return
629
+
611
630
  console.log(`file not found, creating: ${fullpath}`)
612
631
 
613
632
  file_needs_writing = true
614
633
  file_last_version = []
615
634
  self.file_last_text = ''
616
635
 
617
- await require('fs').promises.writeFile(fullpath, self.file_last_text)
636
+ await wait_on(require('fs').promises.writeFile(fullpath, self.file_last_text))
618
637
  }
638
+ if (freed) return
619
639
 
620
- if (self.file_read_only === null) try { self.file_read_only = await is_read_only(fullpath) } catch (e) { }
640
+ if (self.file_read_only === null) try { self.file_read_only = await wait_on(is_read_only(fullpath)) } catch (e) { }
641
+ if (freed) return
621
642
 
622
- let text = await require('fs').promises.readFile(
623
- fullpath, { encoding: 'utf8' })
643
+ let text = await wait_on(require('fs').promises.readFile(
644
+ fullpath, { encoding: 'utf8' }))
645
+ if (freed) return
624
646
 
625
- var stat = await require('fs').promises.stat(fullpath, { bigint: true })
647
+ var stat = await wait_on(require('fs').promises.stat(fullpath, { bigint: true }))
648
+ if (freed) return
626
649
 
627
650
  var patches = diff(self.file_last_text, text)
628
651
  if (patches.length) {
@@ -639,9 +662,11 @@ async function sync_url(url) {
639
662
 
640
663
  add_to_version_cache(text, version)
641
664
 
642
- await braid_text.put(url, { version, parents, patches, merge_type: 'dt' })
665
+ await wait_on(braid_text.put(url, { version, parents, patches, merge_type: 'dt' }))
666
+ if (freed) return
643
667
 
644
668
  await write_meta_file()
669
+ if (freed) return
645
670
  } else {
646
671
  add_to_version_cache(text, file_last_version)
647
672
 
@@ -658,13 +683,16 @@ async function sync_url(url) {
658
683
  if (file_needs_writing === 'just_meta_file') {
659
684
  file_needs_writing = false
660
685
  await write_meta_file()
686
+ if (freed) return
661
687
  } else if (file_needs_writing) {
662
688
  file_needs_writing = false
663
- let { version, body } = await braid_text.get(url, {})
689
+ let { version, body } = await wait_on(braid_text.get(url, {}))
690
+ if (freed) return
664
691
  if (!v_eq(version, file_last_version)) {
665
692
  // let's do a final check to see if anything has changed
666
693
  // before writing out a new version of the file
667
- let text = await require('fs').promises.readFile(fullpath, { encoding: 'utf8' })
694
+ let text = await wait_on(require('fs').promises.readFile(fullpath, { encoding: 'utf8' }))
695
+ if (freed) return
668
696
  if (self.file_last_text != text) {
669
697
  // if the text is different, let's read it first..
670
698
  file_needs_reading = true
@@ -676,22 +704,28 @@ async function sync_url(url) {
676
704
 
677
705
  add_to_version_cache(body, version)
678
706
 
679
- try { if (await is_read_only(fullpath)) await set_read_only(fullpath, false) } catch (e) { }
707
+ try { if (await wait_on(is_read_only(fullpath))) await wait_on(set_read_only(fullpath, false)) } catch (e) { }
708
+ if (freed) return
680
709
 
681
710
  file_last_version = version
682
711
  self.file_last_text = body
683
712
  self.file_ignore_until = Date.now() + 1000
684
- await require('fs').promises.writeFile(fullpath, self.file_last_text)
713
+ await wait_on(require('fs').promises.writeFile(fullpath, self.file_last_text))
714
+ if (freed) return
685
715
  }
686
716
 
687
717
  await write_meta_file()
718
+ if (freed) return
688
719
 
689
- if (await is_read_only(fullpath) !== self.file_read_only) {
720
+ if (await wait_on(is_read_only(fullpath) !== self.file_read_only)) {
721
+ if (freed) return
690
722
  self.file_ignore_until = Date.now() + 1000
691
- await set_read_only(fullpath, self.file_read_only)
723
+ await wait_on(set_read_only(fullpath, self.file_read_only))
692
724
  }
725
+ if (freed) return
693
726
 
694
- self.file_last_stat = await require('fs').promises.stat(fullpath, { bigint: true })
727
+ self.file_last_stat = await wait_on(require('fs').promises.stat(fullpath, { bigint: true }))
728
+ if (freed) return
695
729
 
696
730
  for (var cb of self.file_written_cbs) cb(self.file_last_stat)
697
731
  self.file_written_cbs = []
@@ -699,30 +733,31 @@ async function sync_url(url) {
699
733
  }
700
734
  })
701
735
 
702
- finish_something()
703
-
704
736
  file_loop_pump_lock--
705
737
  }
706
738
 
707
- self.update_fork_point = async (event, parents) => {
708
- var resource = await braid_text.get_resource(url)
739
+ self.update_fork_point = (event, parents) => {
740
+ self.fork_point = extend_frontier(self.fork_point, event, parents)
741
+ self.signal_file_needs_writing(true)
742
+ }
709
743
 
744
+ function extend_frontier(frontier, event, parents) {
710
745
  // special case:
711
- // if current fork point has all parents,
746
+ // if current frontier has all parents,
712
747
  // then we can just remove those
713
748
  // and add event
714
- var fork_set = new Set(self.fork_point)
749
+ var frontier_set = new Set(frontier)
715
750
  if (parents.length &&
716
- parents.every(p => fork_set.has(p))) {
717
- parents.forEach(p => fork_set.delete(p))
718
- fork_set.add(event)
719
- self.fork_point = [...fork_set.values()]
751
+ parents.every(p => frontier_set.has(p))) {
752
+ parents.forEach(p => frontier_set.delete(p))
753
+ frontier_set.add(event)
754
+ frontier = [...frontier_set.values()]
720
755
  } else {
721
756
  // full-proof approach..
722
- var looking_for = fork_set
757
+ var looking_for = frontier_set
723
758
  looking_for.add(event)
724
759
 
725
- self.fork_point = []
760
+ frontier = []
726
761
  var shadow = new Set()
727
762
 
728
763
  var bytes = resource.doc.toBytes()
@@ -731,23 +766,24 @@ async function sync_url(url) {
731
766
  var e = events[i].join('-')
732
767
  if (looking_for.has(e)) {
733
768
  looking_for.delete(e)
734
- if (!shadow.has(e)) self.fork_point.push(e)
769
+ if (!shadow.has(e)) frontier.push(e)
735
770
  shadow.add(e)
736
771
  }
737
772
  if (shadow.has(e))
738
773
  parentss[i].forEach(p => shadow.add(p.join('-')))
739
774
  }
740
775
  }
741
- self.fork_point.sort()
742
- self.signal_file_needs_writing(true)
776
+ return frontier.sort()
743
777
  }
744
778
 
745
779
  async function find_fork_point() {
780
+ if (freed) return
746
781
  console.log(`[find_fork_point] url: ${url}`)
747
782
 
748
783
  // see if remote has the fork point
749
784
  if (self.fork_point) {
750
785
  var r = await my_fetch({ method: "HEAD", version: self.fork_point })
786
+ if (freed) return
751
787
  if (r.ok) {
752
788
  console.log(`[find_fork_point] it has our latest fork point, hooray!`)
753
789
  return self.fork_point
@@ -755,7 +791,6 @@ async function sync_url(url) {
755
791
  }
756
792
 
757
793
  // otherwise let's binary search for new fork point..
758
- var resource = await braid_text.get_resource(url)
759
794
  var bytes = resource.doc.toBytes()
760
795
  var [_, events, __] = braid_text.dt_parse([...bytes])
761
796
  events = events.map(x => x.join('-'))
@@ -771,6 +806,7 @@ async function sync_url(url) {
771
806
 
772
807
  var st = Date.now()
773
808
  var r = await my_fetch({ method: "HEAD", version })
809
+ if (freed) return
774
810
  console.log(`fetched in ${Date.now() - st}`)
775
811
 
776
812
  if (r.ok) {
@@ -787,14 +823,18 @@ async function sync_url(url) {
787
823
  var initial_connect_promise = new Promise(done => initial_connect_done = done)
788
824
 
789
825
  if (is_external_link) find_fork_point().then(async fork_point => {
826
+ if (freed) return
790
827
  await send_new_stuff(fork_point)
828
+ if (freed) return
791
829
  connect(fork_point)
792
830
  })
793
831
 
794
832
  function connect(fork_point) {
833
+ if (freed) return
795
834
  let a = new AbortController()
796
835
  aborts.add(a)
797
836
  self.reconnect = () => {
837
+ if (freed) return
798
838
  console.log(`reconnecting ${url}`)
799
839
 
800
840
  aborts.delete(a)
@@ -826,15 +866,19 @@ async function sync_url(url) {
826
866
  },
827
867
  heartbeats: 120,
828
868
  parents: async () => {
869
+ if (freed) return
829
870
  var x = fork_point || await find_fork_point()
871
+ if (freed) return
830
872
  fork_point = null
831
873
  return x
832
874
  },
833
875
  peer: self.peer
834
876
  }).then(x => {
877
+ if (freed) return
835
878
  if (x.status !== 209) throw new Error(`unexpected status: ${x.status}`)
836
879
  initial_connect_done()
837
880
  x.subscribe(async update => {
881
+ if (freed) return
838
882
  console.log(`got external update about ${url}`)
839
883
 
840
884
  if (update.body) update.body = update.body_text
@@ -844,36 +888,37 @@ async function sync_url(url) {
844
888
  if (update.version.length === 0) return
845
889
  if (update.version.length !== 1) throw 'unexpected'
846
890
 
847
- if (!start_something()) return
848
-
849
- await braid_text.put(url, { ...update, peer: self.peer, merge_type: 'dt' })
891
+ await wait_on(braid_text.put(url, { ...update, peer: self.peer, merge_type: 'dt' }))
892
+ console.log(`PUT DONE!`)
893
+ if (freed) return
850
894
 
851
895
  // the server is giving us this version,
852
896
  // so it must have it,
853
897
  // so let's add it to our fork point
854
- await self.update_fork_point(update.version[0], update.parents)
898
+ self.update_fork_point(update.version[0], update.parents)
855
899
 
856
900
  self.signal_file_needs_writing()
857
- finish_something()
858
901
  }, e => (e?.name !== "AbortError") && console.log(e))
859
902
  }).catch(e => (e?.name !== "AbortError") && console.log(e))
860
903
  }
861
904
 
862
905
  // send it stuff we have but it doesn't't
863
906
  async function send_new_stuff(fork_point) {
907
+ if (freed) return
864
908
  var in_parallel = create_parallel_promises(10)
865
- await braid_text.get(url, braid_text_get_options = {
909
+ await wait_on(braid_text.get(url, braid_text_get_options = {
866
910
  parents: fork_point,
867
911
  merge_type: 'dt',
868
912
  peer: self.peer,
869
913
  subscribe: async (u) => {
914
+ if (freed) return
870
915
  if (u.version.length) {
871
916
  self.signal_file_needs_writing()
872
917
  await initial_connect_promise
873
918
  in_parallel(() => send_out({...u, peer: self.peer}))
874
919
  }
875
920
  },
876
- })
921
+ }))
877
922
  }
878
923
 
879
924
  // for config and errors file, listen for web changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braidfs",
3
- "version": "0.0.91",
3
+ "version": "0.0.93",
4
4
  "description": "braid technology synchronizing files and webpages",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braidfs",