@peerbit/log 4.0.10 → 4.0.11

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.
package/src/log.ts CHANGED
@@ -274,7 +274,7 @@ export class Log<T> {
274
274
  */
275
275
  async toArray(): Promise<Entry<T>[]> {
276
276
  // we call init, because the values might be unitialized
277
- return this.entryIndex.query([], this.sortFn.sort, true).all();
277
+ return this.entryIndex.iterate([], this.sortFn.sort, true).all();
278
278
  }
279
279
 
280
280
  /**
@@ -456,7 +456,7 @@ export class Log<T> {
456
456
  }
457
457
  }
458
458
 
459
- await this.load({ reload: false });
459
+ /* await this.load({ reload: false }); */
460
460
 
461
461
  const nexts: Sorting.SortableEntry[] =
462
462
  options.meta?.next ||
@@ -554,10 +554,12 @@ export class Log<T> {
554
554
  }
555
555
 
556
556
  async remove(
557
- entry: ShallowOrFullEntry<T> | ShallowOrFullEntry<T>[],
557
+ entry:
558
+ | { hash: string; meta: { next: string[] } }
559
+ | { hash: string; meta: { next: string[] } }[],
558
560
  options?: { recursively?: boolean },
559
561
  ): Promise<Change<T>> {
560
- await this.load({ reload: false });
562
+ /* await this.load({ reload: false }); */
561
563
  const entries = Array.isArray(entry) ? entry : [entry];
562
564
 
563
565
  if (entries.length === 0) {
@@ -567,46 +569,34 @@ export class Log<T> {
567
569
  };
568
570
  }
569
571
 
570
- const change: Change<T> = {
571
- added: [],
572
- removed: Array.isArray(entry) ? entry : [entry],
573
- };
574
-
575
- await this._onChange?.(change);
572
+ let removed: {
573
+ entry: ShallowOrFullEntry<T>;
574
+ fn: () => Promise<ShallowEntry | undefined>;
575
+ }[];
576
576
 
577
577
  if (options?.recursively) {
578
- await this.deleteRecursively(entry);
578
+ removed = await this.prepareDeleteRecursively(entry);
579
579
  } else {
580
+ removed = [];
580
581
  for (const entry of entries) {
581
- await this.delete(entry.hash);
582
+ const deleteFn = await this.prepareDelete(entry.hash);
583
+ deleteFn.entry &&
584
+ removed.push({ entry: deleteFn.entry, fn: deleteFn.fn });
582
585
  }
583
586
  }
584
587
 
585
- return change;
586
- }
588
+ const change: Change<T> = {
589
+ added: [],
590
+ removed: removed.map((x) => x.entry),
591
+ };
587
592
 
588
- /* iterator(options?: {
589
- from?: "tail" | "head";
590
- amount?: number;
591
- }): IterableIterator<string> {
592
- const from = options?.from || "tail";
593
- const amount = typeof options?.amount === "number" ? options?.amount : -1;
594
- let next = from === "tail" ? this._values.tail : this._values.head;
595
- const nextFn = from === "tail" ? (e: any) => e.prev : (e: any) => e.next;
596
- return (function* () {
597
- let counter = 0;
598
- while (next) {
599
- if (amount >= 0 && counter >= amount) {
600
- return;
601
- }
593
+ await this._onChange?.(change);
602
594
 
603
- yield next.value;
604
- counter++;
595
+ // invoke deletions
596
+ await Promise.all(removed.map((x) => x.fn()));
605
597
 
606
- next = nextFn(next);
607
- }
608
- })();
609
- } */
598
+ return change;
599
+ }
610
600
 
611
601
  async trim(option: TrimOptions | undefined = this._trim.options) {
612
602
  return this._trim.trim(option);
@@ -699,18 +689,25 @@ export class Log<T> {
699
689
  heads.set(next, false);
700
690
  }
701
691
  }
692
+
702
693
  for (const entry of entries) {
703
694
  let isHead = heads.get(entry.hash)!;
704
- const p = this.joinRecursively(entry, {
705
- references,
706
- isHead,
707
- ...options,
708
- });
709
- this._joining.set(entry.hash, p);
710
- p.finally(() => {
711
- this._joining.delete(entry.hash);
712
- });
713
- await p;
695
+ let prev = this._joining.get(entry.hash);
696
+ if (prev) {
697
+ await prev;
698
+ } else {
699
+ const p = this.joinRecursively(entry, {
700
+ references,
701
+ isHead,
702
+ ...options,
703
+ });
704
+
705
+ this._joining.set(entry.hash, p);
706
+ p.finally(() => {
707
+ this._joining.delete(entry.hash);
708
+ });
709
+ await p;
710
+ }
714
711
  }
715
712
  }
716
713
 
@@ -774,7 +771,10 @@ export class Log<T> {
774
771
 
775
772
  if (entry.meta.type !== EntryType.CUT) {
776
773
  for (const a of entry.meta.next) {
777
- if (!(await this.has(a))) {
774
+ const prev = this._joining.get(a);
775
+ if (prev) {
776
+ await prev;
777
+ } else if (!(await this.has(a))) {
778
778
  const nested =
779
779
  options.references?.get(a) ||
780
780
  (await Entry.fromMultihash<T>(this._storage, a, {
@@ -839,29 +839,47 @@ export class Log<T> {
839
839
  return [];
840
840
  }
841
841
 
842
- /// TODO simplify methods below
843
842
  async deleteRecursively(
844
- from: ShallowOrFullEntry<T> | ShallowOrFullEntry<T>[],
843
+ from:
844
+ | { hash: string; meta: { next: string[] } }
845
+ | { hash: string; meta: { next: string[] } }[],
846
+ skipFirst = false,
847
+ ) {
848
+ const toDelete = await this.prepareDeleteRecursively(from, skipFirst);
849
+ const promises = toDelete.map(async (x) => {
850
+ const removed = await x.fn();
851
+ if (removed) {
852
+ return removed;
853
+ }
854
+ return undefined;
855
+ });
856
+
857
+ const results = Promise.all(promises);
858
+ return (await results).filter((x) => x) as ShallowEntry[];
859
+ }
860
+
861
+ /// TODO simplify methods below
862
+ async prepareDeleteRecursively(
863
+ from:
864
+ | { hash: string; meta: { next: string[] } }
865
+ | { hash: string; meta: { next: string[] } }[],
845
866
  skipFirst = false,
846
867
  ) {
847
868
  const stack = Array.isArray(from) ? [...from] : [from];
848
869
  const promises: (Promise<void> | void)[] = [];
849
870
  let counter = 0;
850
- const deleted: ShallowEntry[] = [];
871
+ const toDelete: {
872
+ entry: ShallowOrFullEntry<T>;
873
+ fn: () => Promise<ShallowEntry | undefined>;
874
+ }[] = [];
851
875
 
852
876
  while (stack.length > 0) {
853
877
  const entry = stack.pop()!;
854
878
  const skip = counter === 0 && skipFirst;
855
879
  if (!skip) {
856
- const has = await this.has(entry.hash);
857
- if (has) {
858
- // TODO test last argument: It is for when multiple heads point to the same entry, hence we might visit it multiple times? or a concurrent delete process is doing it before us.
859
- const deletedEntry = await this.delete(entry.hash);
860
- if (deletedEntry) {
861
- /* this._nextsIndex.delete(entry.hash); */
862
- deleted.push(deletedEntry);
863
- }
864
- }
880
+ const deleteFn = await this.prepareDelete(entry.hash);
881
+ deleteFn.entry &&
882
+ toDelete.push({ entry: deleteFn.entry, fn: deleteFn.fn });
865
883
  }
866
884
 
867
885
  for (const next of entry.meta.next) {
@@ -871,7 +889,7 @@ export class Log<T> {
871
889
  // if there are no entries which is not of "CUT" type, we can safely delete the next entry
872
890
  // figureately speaking, these means where are cutting all branches to a stem, so we can delete the stem as well
873
891
  let hasAlternativeNext = !!entriesThatHasNext.find(
874
- (x) => x.meta.type !== EntryType.CUT,
892
+ (x) => x.meta.type !== EntryType.CUT && x.hash !== entry.hash, // second arg is to avoid references to the same entry that is to be deleted (i.e we are looking for other entries)
875
893
  );
876
894
  if (!hasAlternativeNext) {
877
895
  const ne = await this.get(next);
@@ -883,13 +901,32 @@ export class Log<T> {
883
901
  counter++;
884
902
  }
885
903
  await Promise.all(promises);
886
- return deleted;
904
+ return toDelete;
905
+ }
906
+
907
+ async prepareDelete(
908
+ hash: string,
909
+ ): Promise<
910
+ | { entry: ShallowEntry; fn: () => Promise<ShallowEntry | undefined> }
911
+ | { entry: undefined }
912
+ > {
913
+ let entry = await this._entryIndex.getShallow(hash);
914
+ if (!entry) {
915
+ return { entry: undefined };
916
+ }
917
+ return {
918
+ entry: entry.value,
919
+ fn: async () => {
920
+ await this._trim.deleteFromCache(hash);
921
+ const removedEntry = await this._entryIndex.delete(hash, entry.value);
922
+ return removedEntry;
923
+ },
924
+ };
887
925
  }
888
926
 
889
927
  async delete(hash: string): Promise<ShallowEntry | undefined> {
890
- await this._trim.deleteFromCache(hash);
891
- const removedEntry = await this._entryIndex.delete(hash);
892
- return removedEntry;
928
+ const deleteFn = await this.prepareDelete(hash);
929
+ return deleteFn.entry && deleteFn.fn();
893
930
  }
894
931
 
895
932
  /**
@@ -1003,7 +1040,7 @@ export class Log<T> {
1003
1040
 
1004
1041
  const heads = providedCustomHeads
1005
1042
  ? (opts["heads"] as Array<Entry<T>>)
1006
- : await this._entryIndex
1043
+ : await this.entryIndex
1007
1044
  .getHeads(undefined, {
1008
1045
  type: "full",
1009
1046
  signal: this._closeController.signal,
package/src/trim.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { Cache } from "@peerbit/cache";
2
- import { SumRequest } from "@peerbit/indexer-interface";
3
2
  import PQueue from "p-queue";
4
3
  import type { EntryIndex } from "./entry-index.js";
5
4
  import type { ShallowEntry } from "./entry-shallow.js";
@@ -141,9 +140,7 @@ export class Trim<T> {
141
140
  // TODO calculate the sum and cache it and update it only when entries are added or removed
142
141
  const byteLengthFn = async () =>
143
142
  BigInt(
144
- await this._log.index.properties.index.sum(
145
- new SumRequest({ key: "payloadSize" }),
146
- ),
143
+ await this._log.index.properties.index.sum({ key: "payloadSize" }),
147
144
  );
148
145
 
149
146
  // prune to max sum payload sizes in bytes