@fireproof/core 0.5.13 → 0.5.15

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