@fireproof/core 0.14.8 → 0.15.0-dev

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.
@@ -11337,7 +11337,7 @@ var parse2 = (data) => decode16(utf8Encoder.encode(data));
11337
11337
  var utf8Encoder = new TextEncoder();
11338
11338
 
11339
11339
  // src/version.ts
11340
- var PACKAGE_VERSION = "0.14.8";
11340
+ var PACKAGE_VERSION = "0.15.0-dev";
11341
11341
 
11342
11342
  // src/store.ts
11343
11343
  var match = PACKAGE_VERSION.match(/^([^.]*\.[^.]*)/);
@@ -11365,9 +11365,9 @@ var MetaStore = class extends VersionedStore {
11365
11365
  var DataStore = class {
11366
11366
  tag = "car-base";
11367
11367
  STORAGE_VERSION = STORAGE_VERSION;
11368
- loader;
11369
- constructor(loader) {
11370
- this.loader = loader;
11368
+ name;
11369
+ constructor(name8) {
11370
+ this.name = name8;
11371
11371
  }
11372
11372
  };
11373
11373
 
@@ -11538,11 +11538,11 @@ var DataStore2 = class extends DataStore {
11538
11538
  this.store.delete(cid.toString());
11539
11539
  }
11540
11540
  };
11541
- var RemoteWAL2 = class extends RemoteWAL {
11542
- tag = "wal-mem";
11541
+ var MetaStore2 = class extends MetaStore {
11542
+ tag = "header-mem";
11543
11543
  store = /* @__PURE__ */ new Map();
11544
11544
  headerKey(branch) {
11545
- return `fp.${this.STORAGE_VERSION}.wal.${this.loader.name}.${branch}`;
11545
+ return `fp.${this.STORAGE_VERSION}.meta.${this.name}.${branch}`;
11546
11546
  }
11547
11547
  // eslint-disable-next-line @typescript-eslint/require-await
11548
11548
  async load(branch = "main") {
@@ -11550,27 +11550,28 @@ var RemoteWAL2 = class extends RemoteWAL {
11550
11550
  const bytesString = this.store.get(this.headerKey(branch));
11551
11551
  if (!bytesString)
11552
11552
  return null;
11553
- return parse2(bytesString);
11553
+ return [this.parseHeader(bytesString)];
11554
11554
  } catch (e) {
11555
11555
  return null;
11556
11556
  }
11557
11557
  }
11558
11558
  // eslint-disable-next-line @typescript-eslint/require-await
11559
- async save(state, branch = "main") {
11559
+ async save(meta, branch = "main") {
11560
11560
  try {
11561
- const encoded = format3(state);
11562
- this.store.set(this.headerKey(branch), encoded);
11561
+ const headerKey = this.headerKey(branch);
11562
+ const bytes = this.makeHeader(meta);
11563
+ this.store.set(headerKey, bytes);
11564
+ return null;
11563
11565
  } catch (e) {
11564
- console.error("error saving wal", e);
11565
- throw e;
11566
+ return null;
11566
11567
  }
11567
11568
  }
11568
11569
  };
11569
- var MetaStore2 = class extends MetaStore {
11570
- tag = "header-mem";
11570
+ var RemoteWAL2 = class extends RemoteWAL {
11571
+ tag = "wal-mem";
11571
11572
  store = /* @__PURE__ */ new Map();
11572
11573
  headerKey(branch) {
11573
- return `fp.${this.STORAGE_VERSION}.meta.${this.name}.${branch}`;
11574
+ return `fp.${this.STORAGE_VERSION}.wal.${this.loader.name}.${branch}`;
11574
11575
  }
11575
11576
  // eslint-disable-next-line @typescript-eslint/require-await
11576
11577
  async load(branch = "main") {
@@ -11578,20 +11579,19 @@ var MetaStore2 = class extends MetaStore {
11578
11579
  const bytesString = this.store.get(this.headerKey(branch));
11579
11580
  if (!bytesString)
11580
11581
  return null;
11581
- return [this.parseHeader(bytesString)];
11582
+ return parse2(bytesString);
11582
11583
  } catch (e) {
11583
11584
  return null;
11584
11585
  }
11585
11586
  }
11586
11587
  // eslint-disable-next-line @typescript-eslint/require-await
11587
- async save(meta, branch = "main") {
11588
+ async save(state, branch = "main") {
11588
11589
  try {
11589
- const headerKey = this.headerKey(branch);
11590
- const bytes = this.makeHeader(meta);
11591
- this.store.set(headerKey, bytes);
11592
- return null;
11590
+ const encoded = format3(state);
11591
+ this.store.set(this.headerKey(branch), encoded);
11593
11592
  } catch (e) {
11594
- return null;
11593
+ console.error("error saving wal", e);
11594
+ throw e;
11595
11595
  }
11596
11596
  }
11597
11597
  };
@@ -11637,7 +11637,7 @@ var Loader = class {
11637
11637
  this.name = name8;
11638
11638
  this.opts = opts || this.opts;
11639
11639
  this.metaStore = new MetaStore2(this.name);
11640
- this.carStore = new DataStore2(this);
11640
+ this.carStore = new DataStore2(this.name);
11641
11641
  this.remoteWAL = new RemoteWAL2(this);
11642
11642
  this.ready = Promise.resolve().then(async () => {
11643
11643
  if (!this.metaStore || !this.carStore || !this.remoteWAL)
@@ -20707,7 +20707,7 @@ var DbLoader = class _DbLoader extends Loader {
20707
20707
  fileStore;
20708
20708
  constructor(name8, clock, opts) {
20709
20709
  super(name8, opts);
20710
- this.fileStore = new DataStore2(this);
20710
+ this.fileStore = new DataStore2(this.name);
20711
20711
  this.clock = clock;
20712
20712
  }
20713
20713
  async _readyForMerge() {
@@ -20912,7 +20912,7 @@ function applyHeadQueue(worker) {
20912
20912
  const task = queue.shift();
20913
20913
  if (!task)
20914
20914
  continue;
20915
- await worker(task.id, task.newHead, task.prevHead, task.updates);
20915
+ await worker(task.newHead, task.prevHead);
20916
20916
  if (task.updates) {
20917
20917
  allUpdates.push(...task.updates);
20918
20918
  }
@@ -20941,7 +20941,7 @@ function applyHeadQueue(worker) {
20941
20941
 
20942
20942
  // src/crdt-clock.ts
20943
20943
  var CRDTClock = class {
20944
- // todo: keep the clock of remote and local changes separate, merge on read
20944
+ // todo: track local and remote clocks independently, merge on read
20945
20945
  // that way we can drop the whole remote if we need to
20946
20946
  // should go with making sure the local clock only references locally available blocks on write
20947
20947
  head = [];
@@ -20957,68 +20957,22 @@ var CRDTClock = class {
20957
20957
  this.head = head;
20958
20958
  }
20959
20959
  async applyHead(newHead, prevHead, updates = null) {
20960
- const taskId = Math.random().toString().slice(2, 8);
20961
20960
  for await (const { updates: updatesAcc, all } of this.applyHeadQueue.push({
20962
- id: taskId,
20963
- // tblocks,
20964
20961
  newHead,
20965
20962
  prevHead,
20966
20963
  updates
20967
20964
  })) {
20968
- ;
20969
- ((updatesAcc2, all2) => {
20970
- void Promise.resolve().then(async () => {
20971
- let intUpdates = updatesAcc2;
20972
- if (this.watchers.size && !all2) {
20973
- const changes = await clockChangesSince(this.blocks, this.head, prevHead, {});
20974
- intUpdates = changes.result;
20975
- }
20976
- this.zoomers.forEach((fn) => fn());
20977
- this.notifyWatchers(intUpdates || []);
20978
- });
20979
- })([...updatesAcc], all);
20965
+ this.processUpdates(updatesAcc, all, prevHead);
20980
20966
  }
20981
20967
  }
20982
- async int_applyHead(taskId, newHead, prevHead) {
20983
- const ogHead = this.head.sort((a, b) => a.toString().localeCompare(b.toString()));
20984
- newHead = newHead.sort((a, b) => a.toString().localeCompare(b.toString()));
20985
- newHead.map(async (cid) => {
20986
- const got = await this.blocks.get(cid);
20987
- if (!got) {
20988
- throw new Error("int_applyHead missing block: " + cid.toString());
20989
- }
20990
- });
20991
- if (ogHead.toString() === newHead.toString()) {
20992
- return;
20968
+ async processUpdates(updatesAcc, all, prevHead) {
20969
+ let internalUpdates = updatesAcc;
20970
+ if (this.watchers.size && !all) {
20971
+ const changes = await clockChangesSince(this.blocks, this.head, prevHead, {});
20972
+ internalUpdates = changes.result;
20993
20973
  }
20994
- const ogPrev = prevHead.sort((a, b) => a.toString().localeCompare(b.toString()));
20995
- if (ogHead.toString() === ogPrev.toString()) {
20996
- this.setHead(newHead);
20997
- return;
20998
- }
20999
- let head = this.head;
21000
- const noLoader = false;
21001
- const withBlocks = async (fn) => {
21002
- if (!this.blocks)
21003
- throw new Error("missing blocks");
21004
- return await this.blocks.transaction(fn, void 0, { noLoader });
21005
- };
21006
- await withBlocks(async (tblocks) => {
21007
- for (const cid of newHead) {
21008
- try {
21009
- head = await advance(tblocks, head, cid);
21010
- } catch (e) {
21011
- console.error("failed to advance", cid.toString(), e);
21012
- continue;
21013
- }
21014
- }
21015
- const result = await root(tblocks, head);
21016
- for (const { cid, bytes } of [...result.additions, ...result.removals]) {
21017
- tblocks.putSync(cid, bytes);
21018
- }
21019
- return { head };
21020
- });
21021
- this.setHead(head);
20974
+ this.zoomers.forEach((fn) => fn());
20975
+ this.notifyWatchers(internalUpdates || []);
21022
20976
  }
21023
20977
  notifyWatchers(updates) {
21024
20978
  this.emptyWatchers.forEach((fn) => fn());
@@ -21033,7 +20987,62 @@ var CRDTClock = class {
21033
20987
  onZoom(fn) {
21034
20988
  this.zoomers.add(fn);
21035
20989
  }
20990
+ async int_applyHead(newHead, prevHead) {
20991
+ const ogHead = sortClockHead(this.head);
20992
+ newHead = sortClockHead(newHead);
20993
+ await validateBlocks(newHead, this.blocks);
20994
+ if (compareClockHeads(ogHead, newHead)) {
20995
+ return;
20996
+ }
20997
+ const ogPrev = sortClockHead(prevHead);
20998
+ if (compareClockHeads(ogHead, ogPrev)) {
20999
+ this.setHead(newHead);
21000
+ return;
21001
+ }
21002
+ let head = this.head;
21003
+ const noLoader = false;
21004
+ if (!this.blocks)
21005
+ throw new Error("missing blocks");
21006
+ await this.blocks.transaction(
21007
+ async (tblocks) => {
21008
+ head = await advanceBlocks(newHead, tblocks, head);
21009
+ const result = await root(tblocks, head);
21010
+ for (const { cid, bytes } of [...result.additions, ...result.removals]) {
21011
+ tblocks.putSync(cid, bytes);
21012
+ }
21013
+ return { head };
21014
+ },
21015
+ void 0,
21016
+ { noLoader }
21017
+ );
21018
+ this.setHead(head);
21019
+ }
21036
21020
  };
21021
+ function sortClockHead(clockHead) {
21022
+ return clockHead.sort((a, b) => a.toString().localeCompare(b.toString()));
21023
+ }
21024
+ async function validateBlocks(newHead, blocks) {
21025
+ newHead.map(async (cid) => {
21026
+ const got = await blocks.get(cid);
21027
+ if (!got) {
21028
+ throw new Error("int_applyHead missing block: " + cid.toString());
21029
+ }
21030
+ });
21031
+ }
21032
+ function compareClockHeads(head1, head2) {
21033
+ return head1.toString() === head2.toString();
21034
+ }
21035
+ async function advanceBlocks(newHead, tblocks, head) {
21036
+ for (const cid of newHead) {
21037
+ try {
21038
+ head = await advance(tblocks, head, cid);
21039
+ } catch (e) {
21040
+ console.error("failed to advance", cid.toString(), e);
21041
+ continue;
21042
+ }
21043
+ }
21044
+ return head;
21045
+ }
21037
21046
 
21038
21047
  // src/crdt.ts
21039
21048
  var CRDT = class {
@@ -21208,6 +21217,9 @@ var Database = class {
21208
21217
  }));
21209
21218
  return { rows, clock: head };
21210
21219
  }
21220
+ async allDocuments() {
21221
+ return this.allDocs();
21222
+ }
21211
21223
  subscribe(listener, updates) {
21212
21224
  if (updates) {
21213
21225
  if (!this._listening) {