@fireproof/core 0.5.13 → 0.5.14

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.
@@ -5499,17 +5499,17 @@ class CIDCounter {
5499
5499
 
5500
5500
  /**
5501
5501
  * @typedef {{
5502
- * type: 'put'|'del'
5503
- * key: string
5504
- * value: import('./link').AnyLink
5505
- * root: import('./link').AnyLink
5506
- * }} EventData
5507
- * @typedef {{
5508
- * root: import('./link').AnyLink
5509
- * head: import('./clock').EventLink<EventData>[]
5510
- * event: import('./clock').EventBlockView<EventData>
5511
- * }} Result
5512
- */
5502
+ * type: 'put'|'del'
5503
+ * key: string
5504
+ * value: import('./link').AnyLink
5505
+ * root: import('./link').AnyLink
5506
+ * }} EventData
5507
+ * @typedef {{
5508
+ * root: import('./link').AnyLink
5509
+ * head: import('./clock').EventLink<EventData>[]
5510
+ * event: import('./clock').EventBlockView<EventData>
5511
+ * }} Result
5512
+ */
5513
5513
 
5514
5514
  /**
5515
5515
  * Advance the clock by adding an event.
@@ -5523,7 +5523,7 @@ class CIDCounter {
5523
5523
  async function advance (blocks, head, event) {
5524
5524
  /** @type {EventFetcher<T>} */
5525
5525
  const events = new EventFetcher(blocks);
5526
- const headmap = new Map(head.map((cid) => [cid.toString(), cid]));
5526
+ const headmap = new Map(head.map(cid => [cid.toString(), cid]));
5527
5527
 
5528
5528
  // Check if the headmap already includes the event, return head if it does
5529
5529
  if (headmap.has(event.toString())) return { head, cids: await events.all() }
@@ -5645,14 +5645,16 @@ async function decodeEventBlock (bytes) {
5645
5645
  async function contains (events, a, b) {
5646
5646
  if (a.toString() === b.toString()) return true
5647
5647
  const [{ value: aevent }, { value: bevent }] = await Promise.all([events.get(a), events.get(b)]);
5648
- const links = [...aevent.parents];
5648
+ // const links = [...aevent.parents]
5649
+ // console.log('aevent', aevent.parents)
5650
+ const links = [...(aevent.parents || [])];
5649
5651
  while (links.length) {
5650
5652
  const link = links.shift();
5651
5653
  if (!link) break
5652
5654
  if (link.toString() === b.toString()) return true
5653
5655
  // if any of b's parents are this link, then b cannot exist in any of the
5654
5656
  // tree below, since that would create a cycle.
5655
- if (bevent.parents.some((p) => link.toString() === p.toString())) continue
5657
+ if (bevent.parents.some(p => link.toString() === p.toString())) continue
5656
5658
  const { value: event } = await events.get(link);
5657
5659
  links.push(...event.parents);
5658
5660
  }
@@ -5668,15 +5670,19 @@ async function contains (events, a, b) {
5668
5670
  */
5669
5671
  async function * vis$1 (blocks, head, options = {}) {
5670
5672
  // @ts-ignore
5671
- const renderNodeLabel = options.renderNodeLabel ?? ((b) => {
5672
- // @ts-ignore
5673
- const { key, root, type } = b.value.data;
5674
- return b.cid.toString() + '\n' + JSON.stringify({ key, root: root.cid.toString(), type }, null, 2).replace(/"/g, '\'')
5675
- });
5673
+ const renderNodeLabel =
5674
+ options.renderNodeLabel ??
5675
+ (b => {
5676
+ // @ts-ignore
5677
+ const { key, root, type } = b.value.data;
5678
+ return (
5679
+ b.cid.toString() + '\n' + JSON.stringify({ key, root: root.cid.toString(), type }, null, 2).replace(/"/g, "'")
5680
+ )
5681
+ });
5676
5682
  const events = new EventFetcher(blocks);
5677
5683
  yield 'digraph clock {';
5678
5684
  yield ' node [shape=point fontname="Courier"]; head;';
5679
- const hevents = await Promise.all(head.map((link) => events.get(link)));
5685
+ const hevents = await Promise.all(head.map(link => events.get(link)));
5680
5686
  const links = [];
5681
5687
  const nodes = new Set();
5682
5688
  for (const e of hevents) {
@@ -5709,17 +5715,18 @@ async function findEventsToSync (blocks, head) {
5709
5715
  // console.time(callTag + '.findCommonAncestorWithSortedEvents')
5710
5716
  const { ancestor, sorted } = await findCommonAncestorWithSortedEvents(events, head);
5711
5717
  // console.timeEnd(callTag + '.findCommonAncestorWithSortedEvents')
5712
- // console.log('sorted', sorted.length)
5718
+ // console.log('sorted', !!ancestor, sorted.length)
5713
5719
  // console.time(callTag + '.contains')
5714
- const toSync = await asyncFilter(sorted, async (uks) => !(await contains(events, ancestor, uks.cid)));
5720
+
5721
+ const toSync = ancestor ? await asyncFilter(sorted, async uks => !(await contains(events, ancestor, uks.cid))) : sorted;
5715
5722
  // console.timeEnd(callTag + '.contains')
5716
- // console.log('toSync.contains', toSync.length)
5723
+ console.log('toSync', !!ancestor, sorted.length - toSync.length);
5717
5724
 
5718
5725
  return { cids: events, events: toSync }
5719
5726
  }
5720
5727
 
5721
5728
  const asyncFilter = async (arr, predicate) =>
5722
- Promise.all(arr.map(predicate)).then((results) => arr.filter((_v, index) => results[index]));
5729
+ Promise.all(arr.map(predicate)).then(results => arr.filter((_v, index) => results[index]));
5723
5730
 
5724
5731
  async function findCommonAncestorWithSortedEvents (events, children, doFull = false) {
5725
5732
  // console.trace('findCommonAncestorWithSortedEvents')
@@ -5730,12 +5737,16 @@ async function findCommonAncestorWithSortedEvents (events, children, doFull = fa
5730
5737
  // console.timeEnd(callTag + '.findCommonAncestor')
5731
5738
  // console.log('ancestor', ancestor.toString())
5732
5739
  if (!ancestor) {
5733
- throw new Error('failed to find common ancestor event')
5740
+ console.log('no common ancestor', children);
5741
+ // throw new Error('no common ancestor')
5742
+ const sorted = await findSortedEvents(events, children, children, doFull);
5743
+ return { ancestor: null, sorted }
5734
5744
  }
5735
5745
  // console.time(callTag + '.findSortedEvents')
5736
- const sorted = await findSortedEvents(events, children, ancestor, doFull);
5746
+ const sorted = await findSortedEvents(events, children, [ancestor], doFull);
5737
5747
  // console.timeEnd(callTag + '.findSortedEvents')
5738
5748
  // console.log('sorted', sorted.length)
5749
+ // console.log('ancestor', JSON.stringify(ancestor, null, 2))
5739
5750
  return { ancestor, sorted }
5740
5751
  }
5741
5752
 
@@ -5746,17 +5757,58 @@ async function findCommonAncestorWithSortedEvents (events, children, doFull = fa
5746
5757
  * @param {import('./clock').EventFetcher} events
5747
5758
  * @param {import('./clock').EventLink<EventData>[]} children
5748
5759
  */
5760
+ // async function NEWfindCommonAncestor (events, children) {
5761
+ // if (!children.length) return
5762
+ // if (children.length === 1) return children[0]
5763
+
5764
+ // const candidates = children.map(c => [c])
5765
+ // const visited = new Set()
5766
+
5767
+ // while (true) {
5768
+ // let changed = false
5769
+ // for (const c of candidates) {
5770
+ // const candidate = await findAncestorCandidate(events, c[c.length - 1])
5771
+
5772
+ // if (!candidate) continue
5773
+
5774
+ // if (visited.has(candidate)) {
5775
+ // return candidate // Common ancestor found
5776
+ // }
5777
+
5778
+ // visited.add(candidate)
5779
+ // changed = true
5780
+ // c.push(candidate)
5781
+ // }
5782
+
5783
+ // if (!changed) {
5784
+ // // No common ancestor found, exhausted candidates
5785
+ // return null
5786
+ // }
5787
+ // }
5788
+ // }
5789
+
5749
5790
  async function findCommonAncestor (events, children) {
5750
5791
  if (!children.length) return
5792
+ children = [...new Set(children)];
5751
5793
  if (children.length === 1) return children[0]
5752
5794
  const candidates = children.map((c) => [c]);
5795
+ // console.log(
5796
+ // 'og candidates',
5797
+ // candidates.map((c) => c.toString())
5798
+ // )
5753
5799
  while (true) {
5754
5800
  let changed = false;
5755
5801
  for (const c of candidates) {
5756
5802
  const candidate = await findAncestorCandidate(events, c[c.length - 1]);
5757
5803
  if (!candidate) continue
5804
+
5805
+ // Check if the candidate is already in the list, and if so, skip it.
5806
+ if (c.includes(candidate)) continue
5807
+
5808
+ // if set size is all cids, then no common ancestor
5758
5809
  changed = true;
5759
- c.push(candidate);
5810
+ c.push(candidate); // make set?
5811
+ // console.log('candidate', candidates.map((c) => c.toString()))
5760
5812
  const ancestor = findCommonString(candidates);
5761
5813
  if (ancestor) return ancestor
5762
5814
  }
@@ -5764,12 +5816,45 @@ async function findCommonAncestor (events, children) {
5764
5816
  }
5765
5817
  }
5766
5818
 
5819
+ // async function OGfindCommonAncestor (events, children) {
5820
+ // if (!children.length) return
5821
+ // if (children.length === 1) return children[0]
5822
+ // const candidates = children.map(c => [c])
5823
+ // console.log(
5824
+ // 'og candidates',
5825
+ // candidates.map(c => c.toString())
5826
+ // )
5827
+ // while (true) {
5828
+ // let changed = false
5829
+ // for (const c of candidates) {
5830
+ // const candidate = await findAncestorCandidate(events, c[c.length - 1])
5831
+ // if (!candidate) continue
5832
+ // // if set size is all cids, then no common ancestor
5833
+ // changed = true
5834
+ // c.push(candidate) // make set?
5835
+ // console.log(
5836
+ // 'candidate',
5837
+ // candidates.map(c => c.toString())
5838
+ // )
5839
+ // const ancestor = findCommonString(candidates)
5840
+ // if (ancestor) return ancestor
5841
+ // }
5842
+ // if (!changed) return
5843
+ // }
5844
+ // }
5845
+
5767
5846
  /**
5768
5847
  * @param {import('./clock').EventFetcher} events
5769
5848
  * @param {import('./clock').EventLink<EventData>} root
5770
5849
  */
5771
5850
  async function findAncestorCandidate (events, root) {
5772
- const { value: event } = await events.get(root);// .catch(() => ({ value: { parents: [] } }))
5851
+ const { value: event } = await events.get(root); // .catch(() => ({ value: { parents: [] } }))
5852
+ // console.log(
5853
+ // 'findAncestorCandidate',
5854
+ // root.toString(),
5855
+ // 'parents',
5856
+ // event.parents.map(p => p.toString())
5857
+ // )
5773
5858
  if (!event.parents.length) return root
5774
5859
  return event.parents.length === 1 ? event.parents[0] : findCommonAncestor(events, event.parents)
5775
5860
  }
@@ -5780,13 +5865,13 @@ async function findAncestorCandidate (events, root) {
5780
5865
  */
5781
5866
  function findCommonString (arrays) {
5782
5867
  // console.log('findCommonString', arrays.map((a) => a.map((i) => String(i))))
5783
- arrays = arrays.map((a) => [...a]);
5868
+ arrays = arrays.map(a => [...a]);
5784
5869
  for (const arr of arrays) {
5785
5870
  for (const item of arr) {
5786
5871
  let matched = true;
5787
5872
  for (const other of arrays) {
5788
5873
  if (arr === other) continue
5789
- matched = other.some((i) => String(i) === String(item));
5874
+ matched = other.some(i => String(i) === String(item));
5790
5875
  if (!matched) break
5791
5876
  }
5792
5877
  if (matched) return item
@@ -5798,19 +5883,19 @@ function findCommonString (arrays) {
5798
5883
  * Find and sort events between the head(s) and the tail.
5799
5884
  * @param {import('./clock').EventFetcher} events
5800
5885
  * @param {any[]} head
5801
- * @param {import('./clock').EventLink<EventData>} tail
5886
+ * @param {import('./clock').EventLink<EventData>[]} tails
5802
5887
  */
5803
- async function findSortedEvents (events, head, tail, doFull) {
5888
+ async function findSortedEvents (events, head, tails, doFull) {
5804
5889
  // const callTag = Math.random().toString(36).substring(7)
5805
5890
  // get weighted events - heavier events happened first
5806
5891
  // const callTag = Math.random().toString(36).substring(7)
5807
5892
 
5808
5893
  /** @type {Map<string, { event: import('./clock').EventBlockView<EventData>, weight: number }>} */
5809
5894
  const weights = new Map();
5810
- head = [...new Set([...head.map((h) => h.toString())])];
5895
+ head = [...new Set([...head.map(h => h.toString())])];
5811
5896
  // console.log(callTag + '.head', head.length)
5812
5897
 
5813
- const allEvents = new Set([tail.toString(), ...head]);
5898
+ const allEvents = new Set([tails.map((t) => t.toString()).toString(), ...head]);
5814
5899
  if (!doFull && allEvents.size === 1) {
5815
5900
  // console.log('head contains tail', tail.toString())
5816
5901
  return []
@@ -5822,7 +5907,8 @@ async function findSortedEvents (events, head, tail, doFull) {
5822
5907
  // console.log(callTag + '.head', head.length, [...head.map((h) => h.toString())], tail.toString())
5823
5908
 
5824
5909
  // console.time(callTag + '.findEvents')
5825
- const all = await Promise.all(head.map((h) => findEvents(events, h, tail)));
5910
+ const all = await (await Promise.all(tails.map((t) => Promise.all(head.map(h => findEvents(events, h, t)))))).flat();
5911
+ // console.log('all', all.length)
5826
5912
  // console.timeEnd(callTag + '.findEvents')
5827
5913
  for (const arr of all) {
5828
5914
  for (const { event, depth } of arr) {
@@ -5870,9 +5956,9 @@ async function findEvents (events, start, end, depth = 0) {
5870
5956
  const acc = [{ event, depth }];
5871
5957
  const { parents } = event.value;
5872
5958
  // if (parents.length === 1 && String(parents[0]) === send) return acc
5873
- if (parents.findIndex((p) => String(p) === send) !== -1) return acc
5959
+ if (parents.findIndex(p => String(p) === send) !== -1) return acc
5874
5960
  // if (parents.length === 1) return acc
5875
- const rest = await Promise.all(parents.map((p) => findEvents(events, p, end, depth + 1)));
5961
+ const rest = await Promise.all(parents.map(p => findEvents(events, p, end, depth + 1)));
5876
5962
  return acc.concat(...rest)
5877
5963
  }
5878
5964
 
@@ -9573,15 +9659,7 @@ var _polyfillNode_events = /*#__PURE__*/Object.freeze({
9573
9659
 
9574
9660
  var require$$0$1 = /*@__PURE__*/getAugmentedNamespace(_polyfillNode_events);
9575
9661
 
9576
- var streamBrowser;
9577
- var hasRequiredStreamBrowser;
9578
-
9579
- function requireStreamBrowser () {
9580
- if (hasRequiredStreamBrowser) return streamBrowser;
9581
- hasRequiredStreamBrowser = 1;
9582
- streamBrowser = require$$0$1.EventEmitter;
9583
- return streamBrowser;
9584
- }
9662
+ var streamBrowser = require$$0$1.EventEmitter;
9585
9663
 
9586
9664
  // shim for using process in browser
9587
9665
  // based off https://github.com/defunctzombie/node-process/blob/master/browser.js
@@ -9724,7 +9802,7 @@ var argv = [];
9724
9802
  var version$2 = ''; // empty string to avoid regexp issues
9725
9803
  var versions = {};
9726
9804
  var release = {};
9727
- var config = {};
9805
+ var config$1 = {};
9728
9806
 
9729
9807
  function noop$2() {}
9730
9808
 
@@ -9801,7 +9879,7 @@ var browser$1$1 = {
9801
9879
  hrtime: hrtime,
9802
9880
  platform: platform,
9803
9881
  release: release,
9804
- config: config,
9882
+ config: config$1,
9805
9883
  uptime: uptime
9806
9884
  };
9807
9885
 
@@ -9882,11 +9960,11 @@ function format(f) {
9882
9960
  // Mark that a method should not be used.
9883
9961
  // Returns a modified function which warns once by default.
9884
9962
  // If --no-deprecation is set, then it is a no-op.
9885
- function deprecate$1(fn, msg) {
9963
+ function deprecate$2(fn, msg) {
9886
9964
  // Allow for deprecating things in the process of starting up.
9887
9965
  if (isUndefined(global$1.process)) {
9888
9966
  return function() {
9889
- return deprecate$1(fn, msg).apply(this, arguments);
9967
+ return deprecate$2(fn, msg).apply(this, arguments);
9890
9968
  };
9891
9969
  }
9892
9970
 
@@ -10495,7 +10573,7 @@ var _polyfillNode_util = {
10495
10573
  isBoolean: isBoolean,
10496
10574
  isArray: isArray,
10497
10575
  inspect: inspect,
10498
- deprecate: deprecate$1,
10576
+ deprecate: deprecate$2,
10499
10577
  format: format,
10500
10578
  debuglog: debuglog,
10501
10579
  promisify: promisify,
@@ -10508,7 +10586,7 @@ var _polyfillNode_util$1 = /*#__PURE__*/Object.freeze({
10508
10586
  callbackify: callbackify,
10509
10587
  debuglog: debuglog,
10510
10588
  default: _polyfillNode_util,
10511
- deprecate: deprecate$1,
10589
+ deprecate: deprecate$2,
10512
10590
  format: format,
10513
10591
  inherits: inherits$w,
10514
10592
  inspect: inspect,
@@ -10696,108 +10774,99 @@ function requireBuffer_list () {
10696
10774
  return buffer_list;
10697
10775
  }
10698
10776
 
10699
- var destroy_1;
10700
- var hasRequiredDestroy;
10701
-
10702
- function requireDestroy () {
10703
- if (hasRequiredDestroy) return destroy_1;
10704
- hasRequiredDestroy = 1;
10705
-
10706
- // undocumented cb() API, needed for core, not for public API
10707
- function destroy(err, cb) {
10708
- const readableDestroyed = this._readableState && this._readableState.destroyed;
10709
- const writableDestroyed = this._writableState && this._writableState.destroyed;
10710
- if (readableDestroyed || writableDestroyed) {
10711
- if (cb) {
10712
- cb(err);
10713
- } else if (err) {
10714
- if (!this._writableState) {
10715
- process.nextTick(emitErrorNT, this, err);
10716
- } else if (!this._writableState.errorEmitted) {
10717
- this._writableState.errorEmitted = true;
10718
- process.nextTick(emitErrorNT, this, err);
10719
- }
10720
- }
10721
- return this;
10722
- }
10777
+ // undocumented cb() API, needed for core, not for public API
10778
+ function destroy(err, cb) {
10779
+ const readableDestroyed = this._readableState && this._readableState.destroyed;
10780
+ const writableDestroyed = this._writableState && this._writableState.destroyed;
10781
+ if (readableDestroyed || writableDestroyed) {
10782
+ if (cb) {
10783
+ cb(err);
10784
+ } else if (err) {
10785
+ if (!this._writableState) {
10786
+ process.nextTick(emitErrorNT, this, err);
10787
+ } else if (!this._writableState.errorEmitted) {
10788
+ this._writableState.errorEmitted = true;
10789
+ process.nextTick(emitErrorNT, this, err);
10790
+ }
10791
+ }
10792
+ return this;
10793
+ }
10723
10794
 
10724
- // we set destroyed to true before firing error callbacks in order
10725
- // to make it re-entrance safe in case destroy() is called within callbacks
10795
+ // we set destroyed to true before firing error callbacks in order
10796
+ // to make it re-entrance safe in case destroy() is called within callbacks
10726
10797
 
10727
- if (this._readableState) {
10728
- this._readableState.destroyed = true;
10729
- }
10798
+ if (this._readableState) {
10799
+ this._readableState.destroyed = true;
10800
+ }
10730
10801
 
10731
- // if this is a duplex stream mark the writable part as destroyed as well
10732
- if (this._writableState) {
10733
- this._writableState.destroyed = true;
10734
- }
10735
- this._destroy(err || null, err => {
10736
- if (!cb && err) {
10737
- if (!this._writableState) {
10738
- process.nextTick(emitErrorAndCloseNT, this, err);
10739
- } else if (!this._writableState.errorEmitted) {
10740
- this._writableState.errorEmitted = true;
10741
- process.nextTick(emitErrorAndCloseNT, this, err);
10742
- } else {
10743
- process.nextTick(emitCloseNT, this);
10744
- }
10745
- } else if (cb) {
10746
- process.nextTick(emitCloseNT, this);
10747
- cb(err);
10748
- } else {
10749
- process.nextTick(emitCloseNT, this);
10750
- }
10751
- });
10752
- return this;
10753
- }
10754
- function emitErrorAndCloseNT(self, err) {
10755
- emitErrorNT(self, err);
10756
- emitCloseNT(self);
10757
- }
10758
- function emitCloseNT(self) {
10759
- if (self._writableState && !self._writableState.emitClose) return;
10760
- if (self._readableState && !self._readableState.emitClose) return;
10761
- self.emit('close');
10762
- }
10763
- function undestroy() {
10764
- if (this._readableState) {
10765
- this._readableState.destroyed = false;
10766
- this._readableState.reading = false;
10767
- this._readableState.ended = false;
10768
- this._readableState.endEmitted = false;
10769
- }
10770
- if (this._writableState) {
10771
- this._writableState.destroyed = false;
10772
- this._writableState.ended = false;
10773
- this._writableState.ending = false;
10774
- this._writableState.finalCalled = false;
10775
- this._writableState.prefinished = false;
10776
- this._writableState.finished = false;
10777
- this._writableState.errorEmitted = false;
10778
- }
10779
- }
10780
- function emitErrorNT(self, err) {
10781
- self.emit('error', err);
10782
- }
10783
- function errorOrDestroy(stream, err) {
10784
- // We have tests that rely on errors being emitted
10785
- // in the same tick, so changing this is semver major.
10786
- // For now when you opt-in to autoDestroy we allow
10787
- // the error to be emitted nextTick. In a future
10788
- // semver major update we should change the default to this.
10789
-
10790
- const rState = stream._readableState;
10791
- const wState = stream._writableState;
10792
- if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err);
10793
- }
10794
- destroy_1 = {
10795
- destroy,
10796
- undestroy,
10797
- errorOrDestroy
10798
- };
10799
- return destroy_1;
10802
+ // if this is a duplex stream mark the writable part as destroyed as well
10803
+ if (this._writableState) {
10804
+ this._writableState.destroyed = true;
10805
+ }
10806
+ this._destroy(err || null, err => {
10807
+ if (!cb && err) {
10808
+ if (!this._writableState) {
10809
+ process.nextTick(emitErrorAndCloseNT, this, err);
10810
+ } else if (!this._writableState.errorEmitted) {
10811
+ this._writableState.errorEmitted = true;
10812
+ process.nextTick(emitErrorAndCloseNT, this, err);
10813
+ } else {
10814
+ process.nextTick(emitCloseNT, this);
10815
+ }
10816
+ } else if (cb) {
10817
+ process.nextTick(emitCloseNT, this);
10818
+ cb(err);
10819
+ } else {
10820
+ process.nextTick(emitCloseNT, this);
10821
+ }
10822
+ });
10823
+ return this;
10824
+ }
10825
+ function emitErrorAndCloseNT(self, err) {
10826
+ emitErrorNT(self, err);
10827
+ emitCloseNT(self);
10800
10828
  }
10829
+ function emitCloseNT(self) {
10830
+ if (self._writableState && !self._writableState.emitClose) return;
10831
+ if (self._readableState && !self._readableState.emitClose) return;
10832
+ self.emit('close');
10833
+ }
10834
+ function undestroy() {
10835
+ if (this._readableState) {
10836
+ this._readableState.destroyed = false;
10837
+ this._readableState.reading = false;
10838
+ this._readableState.ended = false;
10839
+ this._readableState.endEmitted = false;
10840
+ }
10841
+ if (this._writableState) {
10842
+ this._writableState.destroyed = false;
10843
+ this._writableState.ended = false;
10844
+ this._writableState.ending = false;
10845
+ this._writableState.finalCalled = false;
10846
+ this._writableState.prefinished = false;
10847
+ this._writableState.finished = false;
10848
+ this._writableState.errorEmitted = false;
10849
+ }
10850
+ }
10851
+ function emitErrorNT(self, err) {
10852
+ self.emit('error', err);
10853
+ }
10854
+ function errorOrDestroy(stream, err) {
10855
+ // We have tests that rely on errors being emitted
10856
+ // in the same tick, so changing this is semver major.
10857
+ // For now when you opt-in to autoDestroy we allow
10858
+ // the error to be emitted nextTick. In a future
10859
+ // semver major update we should change the default to this.
10860
+
10861
+ const rState = stream._readableState;
10862
+ const wState = stream._writableState;
10863
+ if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err);
10864
+ }
10865
+ var destroy_1 = {
10866
+ destroy,
10867
+ undestroy,
10868
+ errorOrDestroy
10869
+ };
10801
10870
 
10802
10871
  var errorsBrowser = {};
10803
10872
 
@@ -10927,109 +10996,92 @@ createErrorType('ERR_UNKNOWN_ENCODING', function (arg) {
10927
10996
  createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event');
10928
10997
  errorsBrowser.codes = codes;
10929
10998
 
10930
- var state;
10931
- var hasRequiredState;
10932
-
10933
- function requireState () {
10934
- if (hasRequiredState) return state;
10935
- hasRequiredState = 1;
10936
-
10937
- const ERR_INVALID_OPT_VALUE = errorsBrowser.codes.ERR_INVALID_OPT_VALUE;
10938
- function highWaterMarkFrom(options, isDuplex, duplexKey) {
10939
- return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null;
10940
- }
10941
- function getHighWaterMark(state, options, duplexKey, isDuplex) {
10942
- const hwm = highWaterMarkFrom(options, isDuplex, duplexKey);
10943
- if (hwm != null) {
10944
- if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) {
10945
- const name = isDuplex ? duplexKey : 'highWaterMark';
10946
- throw new ERR_INVALID_OPT_VALUE(name, hwm);
10947
- }
10948
- return Math.floor(hwm);
10949
- }
10950
-
10951
- // Default value
10952
- return state.objectMode ? 16 : 16 * 1024;
10953
- }
10954
- state = {
10955
- getHighWaterMark
10956
- };
10957
- return state;
10999
+ const ERR_INVALID_OPT_VALUE = errorsBrowser.codes.ERR_INVALID_OPT_VALUE;
11000
+ function highWaterMarkFrom(options, isDuplex, duplexKey) {
11001
+ return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null;
10958
11002
  }
11003
+ function getHighWaterMark(state, options, duplexKey, isDuplex) {
11004
+ const hwm = highWaterMarkFrom(options, isDuplex, duplexKey);
11005
+ if (hwm != null) {
11006
+ if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) {
11007
+ const name = isDuplex ? duplexKey : 'highWaterMark';
11008
+ throw new ERR_INVALID_OPT_VALUE(name, hwm);
11009
+ }
11010
+ return Math.floor(hwm);
11011
+ }
10959
11012
 
10960
- var browser$b;
10961
- var hasRequiredBrowser$3;
11013
+ // Default value
11014
+ return state.objectMode ? 16 : 16 * 1024;
11015
+ }
11016
+ var state = {
11017
+ getHighWaterMark
11018
+ };
10962
11019
 
10963
- function requireBrowser$3 () {
10964
- if (hasRequiredBrowser$3) return browser$b;
10965
- hasRequiredBrowser$3 = 1;
10966
- /**
10967
- * Module exports.
10968
- */
11020
+ /**
11021
+ * Module exports.
11022
+ */
10969
11023
 
10970
- browser$b = deprecate;
11024
+ var browser$b = deprecate$1;
10971
11025
 
10972
- /**
10973
- * Mark that a method should not be used.
10974
- * Returns a modified function which warns once by default.
10975
- *
10976
- * If `localStorage.noDeprecation = true` is set, then it is a no-op.
10977
- *
10978
- * If `localStorage.throwDeprecation = true` is set, then deprecated functions
10979
- * will throw an Error when invoked.
10980
- *
10981
- * If `localStorage.traceDeprecation = true` is set, then deprecated functions
10982
- * will invoke `console.trace()` instead of `console.error()`.
10983
- *
10984
- * @param {Function} fn - the function to deprecate
10985
- * @param {String} msg - the string to print to the console when `fn` is invoked
10986
- * @returns {Function} a new "deprecated" version of `fn`
10987
- * @api public
10988
- */
11026
+ /**
11027
+ * Mark that a method should not be used.
11028
+ * Returns a modified function which warns once by default.
11029
+ *
11030
+ * If `localStorage.noDeprecation = true` is set, then it is a no-op.
11031
+ *
11032
+ * If `localStorage.throwDeprecation = true` is set, then deprecated functions
11033
+ * will throw an Error when invoked.
11034
+ *
11035
+ * If `localStorage.traceDeprecation = true` is set, then deprecated functions
11036
+ * will invoke `console.trace()` instead of `console.error()`.
11037
+ *
11038
+ * @param {Function} fn - the function to deprecate
11039
+ * @param {String} msg - the string to print to the console when `fn` is invoked
11040
+ * @returns {Function} a new "deprecated" version of `fn`
11041
+ * @api public
11042
+ */
10989
11043
 
10990
- function deprecate (fn, msg) {
10991
- if (config('noDeprecation')) {
10992
- return fn;
10993
- }
11044
+ function deprecate$1 (fn, msg) {
11045
+ if (config('noDeprecation')) {
11046
+ return fn;
11047
+ }
10994
11048
 
10995
- var warned = false;
10996
- function deprecated() {
10997
- if (!warned) {
10998
- if (config('throwDeprecation')) {
10999
- throw new Error(msg);
11000
- } else if (config('traceDeprecation')) {
11001
- console.trace(msg);
11002
- } else {
11003
- console.warn(msg);
11004
- }
11005
- warned = true;
11006
- }
11007
- return fn.apply(this, arguments);
11008
- }
11049
+ var warned = false;
11050
+ function deprecated() {
11051
+ if (!warned) {
11052
+ if (config('throwDeprecation')) {
11053
+ throw new Error(msg);
11054
+ } else if (config('traceDeprecation')) {
11055
+ console.trace(msg);
11056
+ } else {
11057
+ console.warn(msg);
11058
+ }
11059
+ warned = true;
11060
+ }
11061
+ return fn.apply(this, arguments);
11062
+ }
11009
11063
 
11010
- return deprecated;
11011
- }
11064
+ return deprecated;
11065
+ }
11012
11066
 
11013
- /**
11014
- * Checks `localStorage` for boolean values for the given `name`.
11015
- *
11016
- * @param {String} name
11017
- * @returns {Boolean}
11018
- * @api private
11019
- */
11067
+ /**
11068
+ * Checks `localStorage` for boolean values for the given `name`.
11069
+ *
11070
+ * @param {String} name
11071
+ * @returns {Boolean}
11072
+ * @api private
11073
+ */
11020
11074
 
11021
- function config (name) {
11022
- // accessing global.localStorage can trigger a DOMException in sandboxed iframes
11023
- try {
11024
- if (!commonjsGlobal.localStorage) return false;
11025
- } catch (_) {
11026
- return false;
11027
- }
11028
- var val = commonjsGlobal.localStorage[name];
11029
- if (null == val) return false;
11030
- return String(val).toLowerCase() === 'true';
11031
- }
11032
- return browser$b;
11075
+ function config (name) {
11076
+ // accessing global.localStorage can trigger a DOMException in sandboxed iframes
11077
+ try {
11078
+ if (!commonjsGlobal.localStorage) return false;
11079
+ } catch (_) {
11080
+ return false;
11081
+ }
11082
+ var val = commonjsGlobal.localStorage[name];
11083
+ if (null == val) return false;
11084
+ return String(val).toLowerCase() === 'true';
11033
11085
  }
11034
11086
 
11035
11087
  var _stream_writable;
@@ -11060,12 +11112,12 @@ function require_stream_writable () {
11060
11112
 
11061
11113
  /*<replacement>*/
11062
11114
  const internalUtil = {
11063
- deprecate: requireBrowser$3()
11115
+ deprecate: browser$b
11064
11116
  };
11065
11117
  /*</replacement>*/
11066
11118
 
11067
11119
  /*<replacement>*/
11068
- var Stream = requireStreamBrowser();
11120
+ var Stream = streamBrowser;
11069
11121
  /*</replacement>*/
11070
11122
 
11071
11123
  const Buffer = require$$6$1.Buffer;
@@ -11076,8 +11128,8 @@ function require_stream_writable () {
11076
11128
  function _isUint8Array(obj) {
11077
11129
  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
11078
11130
  }
11079
- const destroyImpl = requireDestroy();
11080
- const _require = requireState(),
11131
+ const destroyImpl = destroy_1;
11132
+ const _require = state,
11081
11133
  getHighWaterMark = _require.getHighWaterMark;
11082
11134
  const _require$codes = errorsBrowser.codes,
11083
11135
  ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
@@ -12271,7 +12323,7 @@ function require_stream_readable () {
12271
12323
  /*</replacement>*/
12272
12324
 
12273
12325
  /*<replacement>*/
12274
- var Stream = requireStreamBrowser();
12326
+ var Stream = streamBrowser;
12275
12327
  /*</replacement>*/
12276
12328
 
12277
12329
  const Buffer = require$$6$1.Buffer;
@@ -12294,8 +12346,8 @@ function require_stream_readable () {
12294
12346
  /*</replacement>*/
12295
12347
 
12296
12348
  const BufferList = requireBuffer_list();
12297
- const destroyImpl = requireDestroy();
12298
- const _require = requireState(),
12349
+ const destroyImpl = destroy_1;
12350
+ const _require = state,
12299
12351
  getHighWaterMark = _require.getHighWaterMark;
12300
12352
  const _require$codes = errorsBrowser.codes,
12301
12353
  ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
@@ -15661,7 +15713,7 @@ function WriteReq(chunk, encoding, cb) {
15661
15713
 
15662
15714
  function WritableState(options, stream) {
15663
15715
  Object.defineProperty(this, 'buffer', {
15664
- get: deprecate$1(function () {
15716
+ get: deprecate$2(function () {
15665
15717
  return this.getBuffer();
15666
15718
  }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
15667
15719
  });
@@ -36862,7 +36914,7 @@ const decrypt = async function * ({ root, get, key, cache, chunker, hasher }) {
36862
36914
  const { result: nodes } = await cidset.getAllEntries();
36863
36915
  const unwrap = async (eblock) => {
36864
36916
  const { bytes, cid } = await decrypt$1({ ...eblock, key }).catch(e => {
36865
- console.log('ekey', e);
36917
+ // console.log('ekey', e)
36866
36918
  throw new Error('bad key: ' + key.toString('hex'))
36867
36919
  });
36868
36920
  const block = await createBlock(bytes, cid);
@@ -36983,11 +37035,11 @@ class Valet {
36983
37035
  this.name = name;
36984
37036
  this.setKeyMaterial(keyMaterial);
36985
37037
  this.uploadQueue = cargoQueue(async (tasks, callback) => {
36986
- console.log(
36987
- 'queue worker',
36988
- tasks.length,
36989
- tasks.reduce((acc, t) => acc + t.value.length, 0)
36990
- );
37038
+ // console.log(
37039
+ // 'queue worker',
37040
+ // tasks.length,
37041
+ // tasks.reduce((acc, t) => acc + t.value.length, 0)
37042
+ // )
36991
37043
  if (this.uploadFunction) {
36992
37044
  // todo we can coalesce these into a single car file
36993
37045
  return await this.withDB(async db => {
@@ -37409,6 +37461,7 @@ class TransactionBlockstore {
37409
37461
  await this.doCommit(innerBlockstore);
37410
37462
  if (doSync) {
37411
37463
  // const all =
37464
+ // console.log('syncing', innerBlockstore.label)
37412
37465
  await Promise.all([...this.syncs].map(async sync => sync.sendUpdate(innerBlockstore).catch(e => {
37413
37466
  console.error('sync error, cancelling', e);
37414
37467
  sync.destroy();
@@ -37521,6 +37574,8 @@ class InnerBlockstore {
37521
37574
 
37522
37575
  const blockOpts = { cache: nocache, chunker: bf(30), codec: codec$1, hasher: sha256$2, compare: simpleCompare };
37523
37576
 
37577
+ // const SYNC_ROOT = 'fireproof' // change this if you want to break sync
37578
+
37524
37579
  /**
37525
37580
  * @typedef {import('./blockstore.js').TransactionBlockstore} TransactionBlockstore
37526
37581
  */
@@ -37554,13 +37609,11 @@ const makeGetBlock = blocks => {
37554
37609
  async function createAndSaveNewEvent ({ inBlocks, bigPut, root, event: inEvent, head, additions, removals = [] }) {
37555
37610
  let cids;
37556
37611
  const { key, value, del } = inEvent;
37612
+ // console.log('createAndSaveNewEvent', root.constructor.name, root.entryList)
37613
+ // root = await root.block
37557
37614
  const data = {
37558
37615
  root: root
37559
- ? {
37560
- cid: root.cid,
37561
- bytes: root.bytes, // can we remove this?
37562
- value: root.value // can we remove this?
37563
- }
37616
+ ? (await root.address)
37564
37617
  : null,
37565
37618
  key
37566
37619
  };
@@ -37572,6 +37625,29 @@ async function createAndSaveNewEvent ({ inBlocks, bigPut, root, event: inEvent,
37572
37625
  data.value = value;
37573
37626
  data.type = 'put';
37574
37627
  }
37628
+ // console.log('head', head)
37629
+ // if (head.length === 0) {
37630
+ // // create an empty prolly root
37631
+ // let emptyRoot
37632
+
37633
+ // for await (const node of create({ get: getBlock, list: [{ key: '_sync', value: SYNC_ROOT }], ...blockOpts })) {
37634
+ // emptyRoot = await node.block
37635
+ // bigPut(emptyRoot)
37636
+ // }
37637
+ // console.log('emptyRoot', emptyRoot)
37638
+ // const first = await EventBlock.create(
37639
+ // {
37640
+ // root: emptyRoot.cid,
37641
+ // key: null,
37642
+ // value: null,
37643
+ // type: 'del'
37644
+ // },
37645
+ // []
37646
+ // )
37647
+ // bigPut(first)
37648
+ // head = [first.cid]
37649
+ // }
37650
+
37575
37651
  /** @type {import('./clock').EventData} */
37576
37652
  // @ts-ignore
37577
37653
  const event = await EventBlock.create(data, head);
@@ -37640,16 +37716,23 @@ const prollyRootFromAncestor = async (events, ancestor, getBlock) => {
37640
37716
  // console.log('prollyRootFromAncestor', ancestor)
37641
37717
  const event = await events.get(ancestor);
37642
37718
  const { root } = event.value.data;
37643
- // console.log('prollyRootFromAncestor', root.cid, JSON.stringify(root.value))
37644
37719
  if (root) {
37645
- return load$2({ cid: root.cid, get: getBlock, ...blockOpts })
37720
+ return load$2({ cid: root, get: getBlock, ...blockOpts })
37646
37721
  } else {
37647
- return null
37722
+ // console.log('no root', root) // false means no common ancestor. null means empty database.
37723
+ return root
37648
37724
  }
37649
37725
  };
37650
37726
 
37727
+ // async function bigMerge (events, head, getBlock) {
37728
+ // const allRoots = await Promise.all(head.map(async h => prollyRootFromAncestor(events, h, getBlock)))
37729
+ // console.log('allRoots', allRoots)
37730
+ // // todo query over all roots and merge them, but how do they not have a common ancestor? they all start with the _sync root
37731
+ // throw new Error('not implemented')
37732
+ // }
37733
+
37651
37734
  const doProllyBulk = async (inBlocks, head, event, doFull = false) => {
37652
- const { getBlock, blocks } = makeGetAndPutBlock(inBlocks);
37735
+ const { getBlock, blocks } = makeGetAndPutBlock(inBlocks); // this is doubled with eventfetcher
37653
37736
  let bulkSorted = [];
37654
37737
  let prollyRootNode = null;
37655
37738
  const events = new EventFetcher(blocks);
@@ -37657,14 +37740,22 @@ const doProllyBulk = async (inBlocks, head, event, doFull = false) => {
37657
37740
  if (!doFull && head.length === 1) {
37658
37741
  prollyRootNode = await prollyRootFromAncestor(events, head[0], getBlock);
37659
37742
  } else {
37660
- // Otherwise, we find the common ancestor and update the root and other blocks
37661
- // todo this is returning more events than necessary, lets define the desired semantics from the top down
37662
- // good semantics mean we can cache the results of this call
37743
+ // Otherwise, we find the common ancestor and update the root and other blocks
37744
+ // todo this is returning more events than necessary, lets define the desired semantics from the top down
37745
+ // good semantics mean we can cache the results of this call
37746
+ // const {cids, events : bulkSorted } = await findEventsToSync(blocks, head)
37663
37747
  const { ancestor, sorted } = await findCommonAncestorWithSortedEvents(events, head, doFull);
37748
+
37664
37749
  bulkSorted = sorted;
37665
- // console.log('sorted', JSON.stringify(sorted.map(({ value: { data: { key, value } } }) => ({ key, value }))))
37666
- prollyRootNode = await prollyRootFromAncestor(events, ancestor, getBlock);
37667
- // console.log('event', event)
37750
+ // console.log('sorted', !!ancestor, JSON.stringify(sorted.map(({ value: { data: { key, value } } }) => ({ key, value }))))
37751
+ if (ancestor) {
37752
+ prollyRootNode = await prollyRootFromAncestor(events, ancestor, getBlock);
37753
+ // if (!prollyRootNode) {
37754
+ // prollyRootNode = await bigMerge(events, head, getBlock)
37755
+ // // throw new Error('no common ancestor')
37756
+ // }
37757
+ }
37758
+ // console.log('event', event)
37668
37759
  }
37669
37760
  }
37670
37761
 
@@ -37672,16 +37763,23 @@ const doProllyBulk = async (inBlocks, head, event, doFull = false) => {
37672
37763
 
37673
37764
  // if prolly root node is null, we need to create a new one
37674
37765
  if (!prollyRootNode) {
37766
+ // console.log('make new root', bulkOperations.length)
37675
37767
  let root;
37768
+ // let rootNode
37676
37769
  const newBlocks = [];
37677
37770
  // if all operations are deletes, we can just return an empty root
37678
37771
  if (bulkOperations.every(op => op.del)) {
37679
37772
  return { root: null, blocks: [], clockCIDs: await events.all() }
37680
37773
  }
37681
37774
  for await (const node of create$3({ get: getBlock, list: bulkOperations, ...blockOpts })) {
37682
- root = await node.block;
37683
- newBlocks.push(root);
37775
+ // root = await node.block
37776
+ root = node;
37777
+ newBlocks.push(await node.block);
37684
37778
  }
37779
+ // throw new Error('not root time')
37780
+ // root.isThisOne = 'yes'
37781
+ // console.log('made new root', root.constructor.name, root.block.cid.toString())
37782
+
37685
37783
  return { root, blocks: newBlocks, clockCIDs: await events.all() }
37686
37784
  } else {
37687
37785
  const writeResp = await prollyRootNode.bulk(bulkOperations); // { root: newProllyRootNode, blocks: newBlocks }
@@ -37701,7 +37799,7 @@ const doProllyBulk = async (inBlocks, head, event, doFull = false) => {
37701
37799
  */
37702
37800
  async function put (inBlocks, head, event, options) {
37703
37801
  const { bigPut } = makeGetAndPutBlock(inBlocks);
37704
-
37802
+ // console.log('major put')
37705
37803
  // If the head is empty, we create a new event and return the root and addition blocks
37706
37804
  if (!head.length) {
37707
37805
  const additions = new Map();
@@ -37733,7 +37831,7 @@ async function put (inBlocks, head, event, options) {
37733
37831
  return createAndSaveNewEvent({
37734
37832
  inBlocks,
37735
37833
  bigPut,
37736
- root: prollyRootBlock,
37834
+ root: newProllyRootNode, // Block
37737
37835
  event,
37738
37836
  head,
37739
37837
  additions: Array.from(additions.values()) /*, todo? Array.from(removals.values()) */
@@ -37752,20 +37850,25 @@ async function root (inBlocks, head, doFull = false) {
37752
37850
  throw new Error('no head')
37753
37851
  }
37754
37852
  // console.log('root', head.map(h => h.toString()))
37755
- const { root: newProllyRootNode, blocks: newBlocks, clockCIDs } = await doProllyBulk(inBlocks, head, null, doFull);
37756
37853
  // todo maybe these should go to a temp blockstore?
37757
- await doTransaction(
37854
+ return await doTransaction(
37758
37855
  'root',
37759
37856
  inBlocks,
37760
37857
  async transactionBlocks => {
37761
37858
  const { bigPut } = makeGetAndPutBlock(transactionBlocks);
37859
+ const { root: newProllyRootNode, blocks: newBlocks, clockCIDs } = await doProllyBulk(inBlocks, head, null, doFull);
37860
+ //
37861
+ // const rootBlock = await newProllyRootNode.block
37862
+ // bigPut(rootBlock)
37762
37863
  for (const nb of newBlocks) {
37763
37864
  bigPut(nb);
37764
37865
  }
37866
+ // console.log('root root', newProllyRootNode.constructor.name, newProllyRootNode)
37867
+ return { clockCIDs, node: newProllyRootNode }
37765
37868
  },
37766
37869
  false
37767
- );
37768
- return { clockCIDs, node: newProllyRootNode }
37870
+ )
37871
+ // return { clockCIDs, node: newProllyRootNode }
37769
37872
  }
37770
37873
 
37771
37874
  /**
@@ -37781,7 +37884,8 @@ async function eventsSince (blocks, head, since) {
37781
37884
  return { clockCIDs: [], result: [] }
37782
37885
  }
37783
37886
  // @ts-ignore
37784
- const sinceHead = [...since, ...head]; // ?
37887
+ const sinceHead = [...since, ...head].map(h => h.toString()); // ?
37888
+ // console.log('eventsSince', sinceHead.map(h => h.toString()))
37785
37889
  const { cids, events: unknownSorted3 } = await findEventsToSync(blocks, sinceHead);
37786
37890
  return { clockCIDs: cids, result: unknownSorted3.map(({ value: { data } }) => data) }
37787
37891
  }
@@ -37818,8 +37922,12 @@ async function rootOrCache (blocks, head, rootCache, doFull = false) {
37818
37922
  clockCIDs = rootCache.clockCIDs;
37819
37923
  } else {
37820
37924
  ({ node, clockCIDs } = await root(blocks, head, doFull));
37925
+
37926
+ // this.applyClock(prevClock, result.head)
37927
+ // await this.notifyListeners([decodedEvent])
37928
+
37821
37929
  // console.timeEnd(callTag + '.root')
37822
- // console.log('found root')
37930
+ // console.log('found root', node.entryList)
37823
37931
  }
37824
37932
  return { node, clockCIDs }
37825
37933
  }
@@ -38187,8 +38295,8 @@ class Database {
38187
38295
  * @memberof Fireproof
38188
38296
  * @instance
38189
38297
  */
38190
- clockToJSON () {
38191
- return this.clock.map(cid => cid.toString())
38298
+ clockToJSON (clock = null) {
38299
+ return (clock || this.clock).map(cid => cid.toString())
38192
38300
  }
38193
38301
 
38194
38302
  hydrate ({ clock, name, key }) {
@@ -38228,21 +38336,21 @@ class Database {
38228
38336
  * @memberof Fireproof
38229
38337
  * @instance
38230
38338
  */
38231
- async changesSince (event) {
38232
- // console.log('events for', this.instanceId, event.constructor.name)
38233
- // console.log('changesSince', this.instanceId, event, this.clock)
38339
+ async changesSince (aClock) {
38340
+ // console.log('events for', this.instanceId, aClock?.constructor.name)
38341
+ // console.log('changesSince', this.instanceId, this.clockToJSON(aClock), this.clockToJSON())
38234
38342
  let rows, dataCIDs, clockCIDs;
38235
- // if (!event) event = []
38236
- if (event) {
38237
- event = event.map((cid) => cid.toString());
38238
- const eventKey = JSON.stringify([...event, ...this.clockToJSON()]);
38343
+ // if (!aClock) aClock = []
38344
+ if (aClock && aClock.length > 0) {
38345
+ aClock = aClock.map((cid) => cid.toString());
38346
+ const eventKey = JSON.stringify([...this.clockToJSON(aClock), ...this.clockToJSON()]);
38239
38347
 
38240
38348
  let resp;
38241
38349
  if (this.eventsCache.has(eventKey)) {
38242
- console.log('events from cache');
38350
+ // console.log('events from cache')
38243
38351
  resp = this.eventsCache.get(eventKey);
38244
38352
  } else {
38245
- resp = await eventsSince(this.blocks, this.clock, event);
38353
+ resp = await eventsSince(this.blocks, this.clock, aClock);
38246
38354
  this.eventsCache.set(eventKey, resp);
38247
38355
  }
38248
38356
  const docsMap = new Map();
@@ -38403,7 +38511,9 @@ class Database {
38403
38511
  */
38404
38512
  async putToProllyTree (decodedEvent, clock = null) {
38405
38513
  const event = encodeEvent(decodedEvent);
38406
- if (clock && JSON.stringify(clock) !== JSON.stringify(this.clockToJSON())) {
38514
+ if (clock && JSON.stringify(this.clockToJSON(clock)) !== JSON.stringify(this.clockToJSON())) {
38515
+ // console.log('this.clock', this.clockToJSON())
38516
+ // console.log('that.clock', this.clockToJSON(clock))
38407
38517
  // we need to check and see what version of the document exists at the clock specified
38408
38518
  // if it is the same as the one we are trying to put, then we can proceed
38409
38519
  const resp = await eventsSince(this.blocks, this.clock, event.value._clock);
@@ -38413,6 +38523,7 @@ class Database {
38413
38523
  }
38414
38524
  }
38415
38525
  const prevClock = [...this.clock];
38526
+ // console.log('putToProllyTree', this.clockToJSON(), decodedEvent)
38416
38527
  const result = await doTransaction(
38417
38528
  'putToProllyTree',
38418
38529
  this.blocks,
@@ -39102,7 +39213,7 @@ class DbIndex {
39102
39213
  );
39103
39214
  this.indexByKey = await bulkIndex(blocks, this.indexByKey, oldIndexEntries.concat(indexEntries), dbIndexOpts);
39104
39215
  this.dbHead = result.clock;
39105
- });
39216
+ }, false /* don't sync transaction -- maybe move this flag to database.indexBlocks? */);
39106
39217
  // todo index subscriptions
39107
39218
  // this.database.notifyExternal('dbIndex')
39108
39219
  // console.timeEnd(callTag + '.doTransactionupdateIndex')
@@ -41057,10 +41168,15 @@ class Sync {
41057
41168
  this.pushBacklogResolve = resolve;
41058
41169
  this.pushBacklogReject = reject;
41059
41170
  });
41171
+ this.isReady = false;
41060
41172
  // this.pushBacklog.then(() => {
41061
41173
  // // console.log('sync backlog resolved')
41062
41174
  // this.database.notifyReset()
41063
41175
  // })
41176
+ // this.connected = new Promise((resolve, reject) => {
41177
+ // this.readyResolve = resolve
41178
+ // this.readyReject = reject
41179
+ // })
41064
41180
  }
41065
41181
 
41066
41182
  async offer () {
@@ -41109,22 +41225,22 @@ class Sync {
41109
41225
  // console.log('not a car', data.toString())
41110
41226
  }
41111
41227
  if (reader) {
41112
- console.log('got car');
41228
+ // console.log('got car')
41113
41229
  this.status = 'parking car';
41114
41230
  const blz = new Set();
41115
41231
  for await (const block of reader.blocks()) {
41116
41232
  blz.add(block);
41117
41233
  }
41118
41234
  const roots = await reader.getRoots();
41119
- console.log(
41120
- 'got car',
41121
- roots.map(c => c.toString()),
41122
- this.database.clock.map(c => c.toString())
41123
- );
41124
- console.log(
41125
- 'got blocks',
41126
- [...blz].map(({ cid }) => cid.toString())
41127
- );
41235
+ // console.log(
41236
+ // 'got car',
41237
+ // roots.map(c => c.toString()),
41238
+ // this.database.clock.map(c => c.toString())
41239
+ // )
41240
+ // console.log(
41241
+ // 'got blocks!',
41242
+ // [...blz].map(({ cid }) => cid.toString())
41243
+ // )
41128
41244
  // @ts-ignore
41129
41245
  reader.entries = reader.blocks;
41130
41246
  await this.database.blocks.commit(
@@ -41163,7 +41279,7 @@ class Sync {
41163
41279
  } else if (message.clock) {
41164
41280
  const reqCidDiff = message;
41165
41281
  // this might be a CID diff
41166
- console.log('got diff', reqCidDiff);
41282
+ // console.log('got diff', reqCidDiff)
41167
41283
  const carBlock = await Sync.makeCar(this.database, null, reqCidDiff.cids);
41168
41284
  if (!carBlock) {
41169
41285
  // we are full synced
@@ -41172,9 +41288,10 @@ class Sync {
41172
41288
  this.peer.send(JSON.stringify({ ok: true }));
41173
41289
  // this.pushBacklogResolve({ ok: true })
41174
41290
  } else {
41175
- console.log('do send', carBlock.bytes.length);
41291
+ // console.log('do send diff', carBlock.bytes.length)
41176
41292
  this.status = 'sending diff car';
41177
41293
  this.peer.send(carBlock.bytes);
41294
+ // console.log('sent diff car')
41178
41295
  // this.pushBacklogResolve({ ok: true })
41179
41296
  }
41180
41297
  }
@@ -41188,7 +41305,7 @@ class Sync {
41188
41305
  }
41189
41306
 
41190
41307
  async sendUpdate (blockstore) {
41191
- if (!this.peer) return
41308
+ if (!this.peer || !this.isReady) return
41192
41309
  // console.log('send update from', this.database.instanceId)
41193
41310
  // todo should send updates since last sync
41194
41311
  const newCar = await blocksToCarBlock(blockstore.lastCid, blockstore);
@@ -41198,6 +41315,7 @@ class Sync {
41198
41315
 
41199
41316
  async startSync () {
41200
41317
  // console.log('start sync', this.peer.initiator)
41318
+ this.isReady = true;
41201
41319
  const allCIDs = await this.database.allStoredCIDs();
41202
41320
  // console.log('allCIDs', allCIDs)
41203
41321
  const reqCidDiff = {