@peerbit/log 3.0.34 → 4.0.0-55cebfe

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/dist/benchmark/append.d.ts +2 -0
  2. package/dist/benchmark/append.d.ts.map +1 -0
  3. package/dist/benchmark/append.js +40 -0
  4. package/dist/benchmark/append.js.map +1 -0
  5. package/dist/benchmark/memory/index.d.ts +2 -0
  6. package/dist/benchmark/memory/index.d.ts.map +1 -0
  7. package/dist/benchmark/memory/index.js +122 -0
  8. package/dist/benchmark/memory/index.js.map +1 -0
  9. package/dist/benchmark/memory/insert.d.ts +2 -0
  10. package/dist/benchmark/memory/insert.d.ts.map +1 -0
  11. package/dist/benchmark/memory/insert.js +59 -0
  12. package/dist/benchmark/memory/insert.js.map +1 -0
  13. package/dist/benchmark/memory/utils.d.ts +13 -0
  14. package/dist/benchmark/memory/utils.d.ts.map +1 -0
  15. package/dist/benchmark/memory/utils.js +2 -0
  16. package/dist/benchmark/memory/utils.js.map +1 -0
  17. package/dist/benchmark/payload.d.ts +2 -0
  18. package/dist/benchmark/payload.d.ts.map +1 -0
  19. package/{lib/esm/__benchmark__/index.js → dist/benchmark/payload.js} +20 -22
  20. package/dist/benchmark/payload.js.map +1 -0
  21. package/dist/src/change.d.ts +6 -0
  22. package/dist/src/change.d.ts.map +1 -0
  23. package/{lib/esm → dist/src}/clock.d.ts +3 -26
  24. package/dist/src/clock.d.ts.map +1 -0
  25. package/{lib/esm → dist/src}/clock.js +30 -39
  26. package/dist/src/clock.js.map +1 -0
  27. package/{lib/esm → dist/src}/difference.d.ts +1 -0
  28. package/dist/src/difference.d.ts.map +1 -0
  29. package/{lib/esm → dist/src}/encoding.d.ts +2 -1
  30. package/dist/src/encoding.d.ts.map +1 -0
  31. package/{lib/esm → dist/src}/encoding.js +2 -2
  32. package/{lib/esm → dist/src}/encoding.js.map +1 -1
  33. package/dist/src/entry-index.d.ts +78 -0
  34. package/dist/src/entry-index.d.ts.map +1 -0
  35. package/dist/src/entry-index.js +316 -0
  36. package/dist/src/entry-index.js.map +1 -0
  37. package/{lib/esm → dist/src}/entry-with-refs.d.ts +2 -1
  38. package/dist/src/entry-with-refs.d.ts.map +1 -0
  39. package/{lib/esm → dist/src}/entry.d.ts +22 -18
  40. package/dist/src/entry.d.ts.map +1 -0
  41. package/{lib/esm → dist/src}/entry.js +69 -42
  42. package/dist/src/entry.js.map +1 -0
  43. package/{lib/esm → dist/src}/find-uniques.d.ts +1 -0
  44. package/dist/src/find-uniques.d.ts.map +1 -0
  45. package/{lib/esm → dist/src}/heads-cache.d.ts +4 -3
  46. package/dist/src/heads-cache.d.ts.map +1 -0
  47. package/{lib/esm → dist/src}/heads-cache.js +9 -10
  48. package/dist/src/heads-cache.js.map +1 -0
  49. package/{lib/esm → dist/src}/index.d.ts +1 -0
  50. package/dist/src/index.d.ts.map +1 -0
  51. package/{lib/esm → dist/src}/log-errors.d.ts +1 -0
  52. package/dist/src/log-errors.d.ts.map +1 -0
  53. package/dist/src/log-sorting.d.ts +35 -0
  54. package/dist/src/log-sorting.d.ts.map +1 -0
  55. package/dist/src/log-sorting.js +105 -0
  56. package/dist/src/log-sorting.js.map +1 -0
  57. package/{lib/esm → dist/src}/log.d.ts +78 -56
  58. package/dist/src/log.d.ts.map +1 -0
  59. package/{lib/esm → dist/src}/log.js +355 -465
  60. package/dist/src/log.js.map +1 -0
  61. package/{lib/esm → dist/src}/logger.d.ts +1 -0
  62. package/dist/src/logger.d.ts.map +1 -0
  63. package/{lib/esm → dist/src}/logger.js.map +1 -1
  64. package/{lib/esm → dist/src}/snapshot.d.ts +5 -4
  65. package/dist/src/snapshot.d.ts.map +1 -0
  66. package/{lib/esm → dist/src}/snapshot.js +10 -10
  67. package/dist/src/snapshot.js.map +1 -0
  68. package/{lib/esm → dist/src}/trim.d.ts +11 -9
  69. package/dist/src/trim.d.ts.map +1 -0
  70. package/{lib/esm → dist/src}/trim.js +46 -35
  71. package/dist/src/trim.js.map +1 -0
  72. package/dist/src/utils.d.ts +4 -0
  73. package/dist/src/utils.d.ts.map +1 -0
  74. package/dist/src/utils.js +12 -0
  75. package/dist/src/utils.js.map +1 -0
  76. package/package.json +104 -78
  77. package/src/change.ts +3 -2
  78. package/src/clock.ts +22 -22
  79. package/src/encoding.ts +4 -4
  80. package/src/entry-index.ts +451 -52
  81. package/src/entry-with-refs.ts +1 -1
  82. package/src/entry.ts +95 -81
  83. package/src/heads-cache.ts +33 -29
  84. package/src/log-sorting.ts +116 -94
  85. package/src/log.ts +482 -571
  86. package/src/logger.ts +1 -0
  87. package/src/snapshot.ts +15 -17
  88. package/src/trim.ts +81 -50
  89. package/src/utils.ts +10 -0
  90. package/lib/esm/__benchmark__/index.d.ts +0 -1
  91. package/lib/esm/__benchmark__/index.js.map +0 -1
  92. package/lib/esm/change.d.ts +0 -5
  93. package/lib/esm/clock.js.map +0 -1
  94. package/lib/esm/entry-index.d.ts +0 -24
  95. package/lib/esm/entry-index.js +0 -74
  96. package/lib/esm/entry-index.js.map +0 -1
  97. package/lib/esm/entry.js.map +0 -1
  98. package/lib/esm/heads-cache.js.map +0 -1
  99. package/lib/esm/heads.d.ts +0 -69
  100. package/lib/esm/heads.js +0 -157
  101. package/lib/esm/heads.js.map +0 -1
  102. package/lib/esm/log-sorting.d.ts +0 -44
  103. package/lib/esm/log-sorting.js +0 -86
  104. package/lib/esm/log-sorting.js.map +0 -1
  105. package/lib/esm/log.js.map +0 -1
  106. package/lib/esm/snapshot.js.map +0 -1
  107. package/lib/esm/trim.js.map +0 -1
  108. package/lib/esm/types.d.ts +0 -6
  109. package/lib/esm/types.js +0 -23
  110. package/lib/esm/types.js.map +0 -1
  111. package/lib/esm/utils.d.ts +0 -2
  112. package/lib/esm/utils.js +0 -3
  113. package/lib/esm/utils.js.map +0 -1
  114. package/lib/esm/values.d.ts +0 -26
  115. package/lib/esm/values.js +0 -131
  116. package/lib/esm/values.js.map +0 -1
  117. package/src/__benchmark__/index.ts +0 -130
  118. package/src/heads.ts +0 -233
  119. package/src/types.ts +0 -12
  120. package/src/values.ts +0 -174
  121. /package/{lib/esm → dist/src}/change.js +0 -0
  122. /package/{lib/esm → dist/src}/change.js.map +0 -0
  123. /package/{lib/esm → dist/src}/difference.js +0 -0
  124. /package/{lib/esm → dist/src}/difference.js.map +0 -0
  125. /package/{lib/esm → dist/src}/entry-with-refs.js +0 -0
  126. /package/{lib/esm → dist/src}/entry-with-refs.js.map +0 -0
  127. /package/{lib/esm → dist/src}/find-uniques.js +0 -0
  128. /package/{lib/esm → dist/src}/find-uniques.js.map +0 -0
  129. /package/{lib/esm → dist/src}/index.js +0 -0
  130. /package/{lib/esm → dist/src}/index.js.map +0 -0
  131. /package/{lib/esm → dist/src}/log-errors.js +0 -0
  132. /package/{lib/esm → dist/src}/log-errors.js.map +0 -0
  133. /package/{lib/esm → dist/src}/logger.js +0 -0
@@ -8,45 +8,53 @@ var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
10
  var Log_1;
11
- import { randomBytes, sha256Base64Sync } from "@peerbit/crypto";
12
- import { Cache } from "@peerbit/cache";
13
- import { EntryIndex } from "./entry-index.js";
14
- import * as LogError from "./log-errors.js";
15
- import * as Sorting from "./log-sorting.js";
16
- import { findUniques } from "./find-uniques.js";
17
- import { Entry, EntryType } from "./entry.js";
18
- import { HLC, LamportClock as Clock } from "./clock.js";
19
11
  import { deserialize, field, fixedArray, variant } from "@dao-xyz/borsh";
12
+ import {} from "@peerbit/any-store";
13
+ import { cidifyString } from "@peerbit/blocks-interface";
14
+ import { SignatureWithKey, X25519Keypair, randomBytes, sha256Base64Sync, } from "@peerbit/crypto";
15
+ import {} from "@peerbit/indexer-interface";
16
+ import { create } from "@peerbit/indexer-sqlite3";
17
+ import {} from "@peerbit/keychain";
18
+ import {} from "./change.js";
19
+ import { LamportClock as Clock, HLC, LamportClock, Timestamp, } from "./clock.js";
20
20
  import { NO_ENCODING } from "./encoding.js";
21
- import { HeadsIndex } from "./heads.js";
22
- import { Values } from "./values.js";
21
+ import { EntryIndex, } from "./entry-index.js";
22
+ import {} from "./entry-with-refs.js";
23
+ import { Entry, EntryType, Payload, ShallowEntry, } from "./entry.js";
24
+ import { findUniques } from "./find-uniques.js";
25
+ import * as LogError from "./log-errors.js";
26
+ import * as Sorting from "./log-sorting.js";
23
27
  import { Trim } from "./trim.js";
24
- import { logger } from "./logger.js";
25
- import { cidifyString } from "@peerbit/blocks";
26
- const { LastWriteWins, NoZeroes } = Sorting;
27
- const ENTRY_CACHE_MAX = 1000; // TODO as param
28
+ const { LastWriteWins } = Sorting;
29
+ export const ENTRY_JOIN_SHAPE = {
30
+ hash: true,
31
+ meta: { type: true, next: true, gid: true, clock: true },
32
+ };
28
33
  let Log = Log_1 = class Log {
29
34
  _id;
30
- _sortFn;
35
+ /* private _sortFn!: Sorting.ISortFunction; */
31
36
  _storage;
32
37
  _hlc;
33
38
  // Identity
34
39
  _identity;
35
40
  // Keeping track of entries
36
41
  _entryIndex;
37
- _headsIndex;
38
- _values;
42
+ /* private _headsIndex!: HeadsIndex<T>;
43
+ private _values!: Values<T>;
44
+ */
39
45
  // Index of all next pointers in this log
40
- _nextsIndex;
46
+ /* private _nextsIndex!: Map<string, Set<string>>; */
41
47
  _keychain;
42
48
  _encoding;
43
49
  _trim;
44
- _entryCache;
45
50
  _canAppend;
46
51
  _onChange;
47
52
  _closed = true;
48
- _memory;
53
+ _closeController;
54
+ _loadedOnce = false;
55
+ _indexer;
49
56
  _joining; // entry hashes that are currently joining into this log
57
+ _sortFn;
50
58
  constructor(properties) {
51
59
  this._id = properties?.id || randomBytes(32);
52
60
  }
@@ -60,18 +68,13 @@ let Log = Log_1 = class Log {
60
68
  if (this.closed === false) {
61
69
  throw new Error("Already open");
62
70
  }
63
- const { encoding, trim, keychain, cache, onGidRemoved } = options;
64
- let { sortFn } = options;
65
- if (sortFn == null) {
66
- sortFn = LastWriteWins;
67
- }
68
- sortFn = sortFn;
69
- this._sortFn = NoZeroes(sortFn);
71
+ this._closeController = new AbortController();
72
+ const { encoding, trim, keychain, indexer, onGidRemoved, sortFn } = options;
73
+ // TODO do correctly with tie breaks
74
+ this._sortFn = sortFn || LastWriteWins;
70
75
  this._storage = store;
71
- this._memory = cache;
72
- if (this._memory && (await this._memory.status()) !== "open") {
73
- await this._memory.open();
74
- }
76
+ this._indexer = indexer || (await create());
77
+ await this._indexer.start?.();
75
78
  this._encoding = encoding || NO_ENCODING;
76
79
  this._joining = new Map();
77
80
  // Identity
@@ -80,47 +83,30 @@ let Log = Log_1 = class Log {
80
83
  this._keychain = keychain;
81
84
  // Clock
82
85
  this._hlc = new HLC();
83
- this._nextsIndex = new Map();
84
86
  const id = this.id;
85
87
  if (!id) {
86
88
  throw new Error("Id not set");
87
89
  }
88
- this._headsIndex = new HeadsIndex(id);
89
- await this._headsIndex.init(this, { onGidRemoved });
90
- this._entryCache = new Cache({ max: ENTRY_CACHE_MAX });
91
90
  this._entryIndex = new EntryIndex({
92
91
  store: this._storage,
93
92
  init: (e) => e.init(this),
94
- cache: this._entryCache
93
+ onGidRemoved,
94
+ index: await (await this._indexer.scope("heads")).init({ schema: ShallowEntry }),
95
+ publicKey: this._identity.publicKey,
96
+ sort: this._sortFn,
95
97
  });
96
- this._values = new Values(this._entryIndex, this._sortFn);
98
+ await this._entryIndex.init();
99
+ /* this._values = new Values(this._entryIndex, this._sortFn); */
97
100
  this._trim = new Trim({
98
- headsIndex: this._headsIndex,
101
+ index: this._entryIndex,
99
102
  deleteNode: async (node) => {
100
- // TODO check if we have before delete?
101
- const entry = await this.get(node.value);
102
- //f (!!entry)
103
- const a = this.values.length;
104
- if (entry) {
105
- this.values.deleteNode(node);
106
- await Promise.all([
107
- this.headsIndex.del(this.entryIndex.getShallow(node.value)),
108
- this.entryIndex.delete(node.value)
109
- ]);
110
- this.nextsIndex.delete(node.value);
111
- await this.blocks.rm(node.value);
112
- }
113
- const b = this.values.length;
114
- if (a === b) {
115
- /* throw new Error(
116
- "Unexpected miss match between log size and entry index size: " +
117
- this.values.length +
118
- this.entryIndex._index.size
119
- ); */
120
- }
121
- return entry;
103
+ const resolved = await this.get(node.hash);
104
+ await this._entryIndex.delete(node.hash);
105
+ await this._storage.rm(node.hash);
106
+ return resolved;
122
107
  },
123
- values: () => this.values
108
+ sortFn: this._sortFn,
109
+ getLength: () => this.length,
124
110
  }, trim);
125
111
  this._canAppend = async (entry) => {
126
112
  if (options?.canAppend) {
@@ -132,6 +118,7 @@ let Log = Log_1 = class Log {
132
118
  };
133
119
  this._onChange = options?.onChange;
134
120
  this._closed = false;
121
+ this._closeController = new AbortController();
135
122
  }
136
123
  _idString;
137
124
  get idString() {
@@ -157,13 +144,10 @@ let Log = Log_1 = class Log {
157
144
  * Returns the length of the log.
158
145
  */
159
146
  get length() {
160
- return this.values.length;
161
- }
162
- get values() {
163
- if (this.closed) {
147
+ if (this._closed) {
164
148
  throw new Error("Closed");
165
149
  }
166
- return this._values;
150
+ return this._entryIndex.length;
167
151
  }
168
152
  get canAppend() {
169
153
  return this._canAppend;
@@ -174,36 +158,20 @@ let Log = Log_1 = class Log {
174
158
  * @returns {boolean}
175
159
  */
176
160
  has(cid) {
177
- return this._entryIndex._index.has(cid);
161
+ return this._entryIndex.has(cid);
178
162
  }
179
163
  /**
180
164
  * Get all entries sorted. Don't use this method anywhere where performance matters
181
165
  */
182
- toArray() {
166
+ async toArray() {
183
167
  // we call init, because the values might be unitialized
184
- return this._values.toArray().then((arr) => arr.map((x) => x.init(this)));
168
+ return this.entryIndex.query([], this.sortFn.sort, true).all();
185
169
  }
186
170
  /**
187
171
  * Returns the head index
188
172
  */
189
- get headsIndex() {
190
- return this._headsIndex;
191
- }
192
- get memory() {
193
- return this._memory;
194
- }
195
- async getHeads() {
196
- const heads = new Array(this.headsIndex.index.size);
197
- let i = 0;
198
- for (const hash of this.headsIndex.index) {
199
- heads[i++] = this._entryIndex.get(hash).then((x) => x?.init(this));
200
- }
201
- const resolved = await Promise.all(heads);
202
- const defined = resolved.filter((x) => !!x);
203
- if (defined.length !== resolved.length) {
204
- logger.error("Failed to resolve all heads");
205
- }
206
- return defined;
173
+ getHeads(resolve = false) {
174
+ return this.entryIndex.getHeads(undefined, resolve);
207
175
  }
208
176
  /**
209
177
  * Returns an array of Entry objects that reference entries which
@@ -233,9 +201,6 @@ let Log = Log_1 = class Log {
233
201
  get blocks() {
234
202
  return this._storage;
235
203
  }
236
- get nextsIndex() {
237
- return this._nextsIndex;
238
- }
239
204
  get entryIndex() {
240
205
  return this._entryIndex;
241
206
  }
@@ -259,68 +224,89 @@ let Log = Log_1 = class Log {
259
224
  this._identity = identity;
260
225
  }
261
226
  /**
262
- * Find an entry.
227
+ * Get an entry.
263
228
  * @param {string} [hash] The hashes of the entry
264
229
  */
265
230
  get(hash, options) {
266
- return this._entryIndex.get(hash, options);
267
- }
268
- async traverse(rootEntries, amount = -1, endHash) {
269
- // Sort the given given root entries and use as the starting stack
270
- let stack = rootEntries.sort(this._sortFn).reverse();
271
- // Cache for checking if we've processed an entry already
272
- let traversed = {};
273
- // End result
274
- const result = {};
275
- let count = 0;
276
- // Named function for getting an entry from the log
277
- const getEntry = (e) => this.get(e);
278
- // Add an entry to the stack and traversed nodes index
279
- const addToStack = (entry) => {
280
- // If we've already processed the Entry<T>, don't add it to the stack
281
- if (!entry || traversed[entry.hash]) {
282
- return;
283
- }
284
- // Add the entry in front of the stack and sort
285
- stack = [entry, ...stack].sort(this._sortFn).reverse();
286
- // Add to the cache of processed entries
287
- traversed[entry.hash] = true;
288
- };
289
- const addEntry = (rootEntry) => {
290
- result[rootEntry.hash] = rootEntry;
291
- traversed[rootEntry.hash] = true;
292
- count++;
293
- };
294
- // Start traversal
295
- // Process stack until it's empty (traversed the full log)
296
- // or when we have the requested amount of entries
297
- // If requested entry amount is -1, traverse all
298
- while (stack.length > 0 && (count < amount || amount < 0)) {
299
- // eslint-disable-line no-unmodified-loop-condition
300
- // Get the next element from the stack
301
- const entry = stack.shift();
302
- if (!entry) {
303
- throw new Error("Unexpected");
304
- }
305
- // Add to the result
306
- addEntry(entry);
307
- // If it is the specified end hash, break out of the while loop
308
- if (endHash && endHash === entry.hash)
309
- break;
310
- // Add entry's next references to the stack
311
- const entries = (await Promise.all(entry.next.map(getEntry))).filter((x) => !!x);
312
- entries.forEach(addToStack);
313
- }
314
- stack = [];
315
- traversed = {};
316
- // End result
317
- return result;
231
+ return this._entryIndex.get(hash, options ? { type: "full", timeout: options.timeout } : undefined);
318
232
  }
233
+ /**
234
+ * Get a entry with shallow representation
235
+ * @param {string} [hash] The hashes of the entry
236
+ */
237
+ async getShallow(hash, options) {
238
+ return (await this._entryIndex.getShallow(hash))?.value;
239
+ }
240
+ /*
241
+ async traverse(
242
+ rootEntries: Entry<T>[],
243
+ amount = -1,
244
+ endHash?: string
245
+ ): Promise<{ [key: string]: Entry<T> }> {
246
+ // Sort the given given root entries and use as the starting stack
247
+ let stack: Entry<T>[] = rootEntries.sort(this._sortFn).reverse();
248
+
249
+ // Cache for checking if we've processed an entry already
250
+ let traversed: { [key: string]: boolean } = {};
251
+ // End result
252
+ const result: { [key: string]: Entry<T> } = {};
253
+ let count = 0;
254
+ // Named function for getting an entry from the log
255
+ const getEntry = (e: string) => this.get(e);
256
+
257
+ // Add an entry to the stack and traversed nodes index
258
+ const addToStack = (entry: Entry<T>) => {
259
+ // If we've already processed the Entry<T>, don't add it to the stack
260
+ if (!entry || traversed[entry.hash]) {
261
+ return;
262
+ }
263
+
264
+ // Add the entry in front of the stack and sort
265
+ stack = [entry, ...stack].sort(this._sortFn).reverse();
266
+ // Add to the cache of processed entries
267
+ traversed[entry.hash] = true;
268
+ };
269
+
270
+ const addEntry = (rootEntry: Entry<T>) => {
271
+ result[rootEntry.hash] = rootEntry;
272
+ traversed[rootEntry.hash] = true;
273
+ count++;
274
+ };
275
+
276
+ // Start traversal
277
+ // Process stack until it's empty (traversed the full log)
278
+ // or when we have the requested amount of entries
279
+ // If requested entry amount is -1, traverse all
280
+ while (stack.length > 0 && (count < amount || amount < 0)) {
281
+ // eslint-disable-line no-unmodified-loop-condition
282
+ // Get the next element from the stack
283
+ const entry = stack.shift();
284
+ if (!entry) {
285
+ throw new Error("Unexpected");
286
+ }
287
+ // Add to the result
288
+ addEntry(entry);
289
+ // If it is the specified end hash, break out of the while loop
290
+ if (endHash && endHash === entry.hash) break;
291
+
292
+ // Add entry's next references to the stack
293
+ const entries = (await Promise.all(entry.next.map(getEntry))).filter(
294
+ (x) => !!x
295
+ ) as Entry<any>[];
296
+ entries.forEach(addToStack);
297
+ }
298
+
299
+ stack = [];
300
+ traversed = {};
301
+ // End result
302
+ return result;
303
+ }
304
+ */
319
305
  async getReferenceSamples(from, options) {
320
306
  const hashes = new Set();
321
307
  const pointerCount = options?.pointerCount || 0;
322
308
  const memoryLimit = options?.memoryLimit;
323
- const maxDistance = Math.min(pointerCount, this._values.length);
309
+ const maxDistance = Math.min(pointerCount, this.entryIndex.length);
324
310
  if (maxDistance === 0) {
325
311
  return [];
326
312
  }
@@ -378,8 +364,9 @@ let Log = Log_1 = class Log {
378
364
  }
379
365
  /**
380
366
  * Append an entry to the log.
381
- * @param {Entry} entry Entry to add
382
- * @return {Log} New Log containing the appended value
367
+ * @param {T} data The data to be appended
368
+ * @param {AppendOptions} [options] The options for the append
369
+ * @returns {{ entry: Entry<T>; removed: ShallowEntry[] }} The appended entry and an array of removed entries
383
370
  */
384
371
  async append(data, options = {}) {
385
372
  // Update the clock (find the latest clock)
@@ -390,11 +377,14 @@ let Log = Log_1 = class Log {
390
377
  }
391
378
  }
392
379
  await this.load({ reload: false });
393
- const nexts = options.meta?.next || (await this.getHeads());
380
+ const nexts = options.meta?.next ||
381
+ (await this.entryIndex
382
+ .getHeads(undefined, { type: "shape", shape: Sorting.ENTRY_SORT_SHAPE })
383
+ .all());
394
384
  // Calculate max time for log/graph
395
385
  const clock = new Clock({
396
386
  id: this._identity.publicKey.bytes,
397
- timestamp: options?.meta?.timestamp || this._hlc.now()
387
+ timestamp: options?.meta?.timestamp || this._hlc.now(),
398
388
  });
399
389
  const entry = await Entry.create({
400
390
  store: this._storage,
@@ -406,63 +396,67 @@ let Log = Log_1 = class Log {
406
396
  type: options.meta?.type,
407
397
  gidSeed: options.meta?.gidSeed,
408
398
  data: options.meta?.data,
409
- next: nexts
399
+ next: nexts,
410
400
  },
411
401
  encoding: this._encoding,
412
402
  encryption: options.encryption
413
403
  ? {
414
404
  keypair: options.encryption.keypair,
415
405
  receiver: {
416
- ...options.encryption.receiver
417
- }
406
+ ...options.encryption.receiver,
407
+ },
418
408
  }
419
409
  : undefined,
420
- canAppend: this._canAppend
410
+ canAppend: options.canAppend || this._canAppend,
421
411
  });
422
412
  if (!entry.hash) {
423
413
  throw new Error("Unexpected");
424
414
  }
425
- for (const e of nexts) {
426
- if (!this.has(e.hash)) {
427
- await this.join([e]);
428
- }
429
- let nextIndexSet = this._nextsIndex.get(e.hash);
430
- if (!nextIndexSet) {
431
- nextIndexSet = new Set();
432
- nextIndexSet.add(entry.hash);
433
- this._nextsIndex.set(e.hash, nextIndexSet);
434
- }
435
- else {
436
- nextIndexSet.add(entry.hash);
415
+ if (entry.meta.type !== EntryType.CUT) {
416
+ for (const e of nexts) {
417
+ if (!(await this.has(e.hash))) {
418
+ let entry;
419
+ if (e instanceof Entry) {
420
+ entry = e;
421
+ }
422
+ else {
423
+ let resolved = await this.entryIndex.get(e.hash);
424
+ if (!resolved) {
425
+ // eslint-disable-next-line no-console
426
+ console.warn("Unexpected missing entry when joining", e.hash);
427
+ continue;
428
+ }
429
+ entry = resolved;
430
+ }
431
+ await this.join([entry]);
432
+ }
437
433
  }
438
434
  }
439
- await this._entryIndex.set(entry, false); // save === false, because its already saved when Entry.create
440
- await this._headsIndex.put(entry, { cache: { update: false } }); // we will update the cache a few lines later *
441
- await this._values.put(entry);
435
+ await this.entryIndex.put(entry, {
436
+ unique: true,
437
+ isHead: true,
438
+ toMultiHash: false,
439
+ });
442
440
  const removed = await this.processEntry(entry);
443
441
  entry.init({ encoding: this._encoding, keychain: this._keychain });
444
442
  const trimmed = await this.trim(options?.trim);
445
- for (const entry of trimmed) {
446
- removed.push(entry);
443
+ if (trimmed) {
444
+ for (const entry of trimmed) {
445
+ removed.push(entry);
446
+ }
447
447
  }
448
448
  const changes = {
449
449
  added: [entry],
450
- removed: removed
450
+ removed,
451
451
  };
452
- await this._headsIndex.updateHeadsCache(changes); // * here
453
- await this._onChange?.(changes);
452
+ await (options?.onChange || this._onChange)?.(changes);
454
453
  return { entry, removed };
455
454
  }
456
455
  async reset(entries) {
457
- this._nextsIndex = new Map();
458
- this._entryIndex = new EntryIndex({
459
- store: this._storage,
460
- init: (e) => e.init(this),
461
- cache: this._entryCache
462
- });
463
- await this.headsIndex.reset([]);
464
- this._values = new Values(this._entryIndex, this._sortFn, []);
465
- await this.join(entries);
456
+ const heads = await this.getHeads(true).all();
457
+ await this._entryIndex.clear();
458
+ await this._onChange?.({ added: [], removed: heads });
459
+ await this.join(entries || heads);
466
460
  }
467
461
  async remove(entry, options) {
468
462
  await this.load({ reload: false });
@@ -470,267 +464,200 @@ let Log = Log_1 = class Log {
470
464
  if (entries.length === 0) {
471
465
  return {
472
466
  added: [],
473
- removed: []
467
+ removed: [],
474
468
  };
475
469
  }
470
+ const change = {
471
+ added: [],
472
+ removed: Array.isArray(entry) ? entry : [entry],
473
+ };
474
+ await this._onChange?.(change);
476
475
  if (options?.recursively) {
477
476
  await this.deleteRecursively(entry);
478
477
  }
479
478
  else {
480
479
  for (const entry of entries) {
481
- await this.delete(entry);
480
+ await this.delete(entry.hash);
482
481
  }
483
482
  }
484
- const change = {
485
- added: [],
486
- removed: Array.isArray(entry) ? entry : [entry]
487
- };
488
- /* await Promise.all([
489
- this._logCache?.queue(change),
490
- this._onUpdate(change),
491
- ]); */
492
- await this._onChange?.(change);
493
483
  return change;
494
484
  }
495
- iterator(options) {
485
+ /* iterator(options?: {
486
+ from?: "tail" | "head";
487
+ amount?: number;
488
+ }): IterableIterator<string> {
496
489
  const from = options?.from || "tail";
497
490
  const amount = typeof options?.amount === "number" ? options?.amount : -1;
498
491
  let next = from === "tail" ? this._values.tail : this._values.head;
499
- const nextFn = from === "tail" ? (e) => e.prev : (e) => e.next;
492
+ const nextFn = from === "tail" ? (e: any) => e.prev : (e: any) => e.next;
500
493
  return (function* () {
501
494
  let counter = 0;
502
495
  while (next) {
503
496
  if (amount >= 0 && counter >= amount) {
504
497
  return;
505
498
  }
499
+
506
500
  yield next.value;
507
501
  counter++;
502
+
508
503
  next = nextFn(next);
509
504
  }
510
505
  })();
511
- }
506
+ } */
512
507
  async trim(option = this._trim.options) {
513
508
  return this._trim.trim(option);
514
509
  }
515
- /**
516
- *
517
- * @param entries
518
- * @returns change
519
- */
520
- /* async sync(
521
- entries: (EntryWithRefs<T> | Entry<T> | string)[],
522
- options: {
523
- canAppend?: CanAppend<T>;
524
- onChange?: (change: Change<T>) => void | Promise<void>;
525
- timeout?: number;
526
- } = {}
527
- ): Promise<void> {
528
-
529
-
530
- logger.debug(`Sync request #${entries.length}`);
531
- const entriesToJoin: (Entry<T> | string)[] = [];
532
- for (const e of entries) {
533
- if (e instanceof Entry || typeof e === "string") {
534
- entriesToJoin.push(e);
535
- } else {
536
- for (const ref of e.references) {
537
- entriesToJoin.push(ref);
538
- }
539
- entriesToJoin.push(e.entry);
540
- }
541
- }
542
-
543
- await this.join(entriesToJoin, {
544
- canAppend: (entry) => {
545
- const canAppend = options?.canAppend || this.canAppend;
546
- return !canAppend || canAppend(entry);
547
- },
548
- onChange: (change) => {
549
- options?.onChange?.(change);
550
- return this._onChange?.({
551
- added: change.added,
552
- removed: change.removed,
553
- });
554
- },
555
- timeout: options.timeout,
556
- });
557
- } */
558
510
  async join(entriesOrLog, options) {
559
- const definedOptions = {
560
- ...options,
561
- cache: options?.cache ?? {
562
- update: true
511
+ let entries;
512
+ let references = new Map();
513
+ if (entriesOrLog instanceof Log_1) {
514
+ if (entriesOrLog.entryIndex.length === 0)
515
+ return;
516
+ entries = await entriesOrLog.toArray();
517
+ for (const element of entries) {
518
+ references.set(element.hash, element);
563
519
  }
564
- };
565
- await this.load({ reload: false });
566
- if (entriesOrLog.length === 0) {
567
- return;
568
520
  }
569
- /* const joinLength = options?.length ?? Number.MAX_SAFE_INTEGER; TODO */
570
- const visited = new Set();
571
- const nextRefs = new Map();
572
- const entriesBottomUp = [];
573
- const stack = [];
574
- const resolvedEntries = new Map();
575
- const entries = Array.isArray(entriesOrLog)
576
- ? entriesOrLog
577
- : await entriesOrLog.values.toArray();
578
- // Build a list of already resolved entries, and filter out already joined entries
579
- for (const e of entries) {
580
- // TODO, do this less ugly
581
- let hash;
582
- if (e instanceof Entry) {
583
- hash = e.hash;
584
- resolvedEntries.set(e.hash, e);
585
- if (this.has(hash)) {
586
- continue;
587
- }
588
- stack.push(hash);
521
+ else if (Array.isArray(entriesOrLog)) {
522
+ if (entriesOrLog.length === 0) {
523
+ return;
589
524
  }
590
- else if (typeof e === "string") {
591
- hash = e;
592
- if (this.has(hash)) {
593
- continue;
525
+ entries = [];
526
+ for (const element of entriesOrLog) {
527
+ if (element instanceof Entry) {
528
+ entries.push(element);
529
+ references.set(element.hash, element);
594
530
  }
595
- stack.push(hash);
596
- }
597
- else {
598
- hash = e.entry.hash;
599
- resolvedEntries.set(e.entry.hash, e.entry);
600
- if (this.has(hash)) {
601
- continue;
531
+ else if (typeof element === "string") {
532
+ let entry = await Entry.fromMultihash(this._storage, element, {
533
+ timeout: options?.timeout,
534
+ });
535
+ if (!entry) {
536
+ throw new Error("Missing entry in join by hash: " + element);
537
+ }
538
+ entries.push(entry);
539
+ }
540
+ else if (element instanceof ShallowEntry) {
541
+ let entry = await Entry.fromMultihash(this._storage, element.hash, {
542
+ timeout: options?.timeout,
543
+ });
544
+ if (!entry) {
545
+ throw new Error("Missing entry in join by hash: " + element.hash);
546
+ }
547
+ entries.push(entry);
602
548
  }
603
- stack.push(hash);
604
- for (const e2 of e.references) {
605
- resolvedEntries.set(e2.hash, e2);
606
- if (this.has(e2.hash)) {
607
- continue;
549
+ else {
550
+ entries.push(element.entry);
551
+ references.set(element.entry.hash, element.entry);
552
+ for (const ref of element.references) {
553
+ references.set(ref.hash, ref);
608
554
  }
609
- stack.push(e2.hash);
610
555
  }
611
556
  }
612
557
  }
613
- const removedHeads = [];
614
- for (const hash of stack) {
615
- if (visited.has(hash) || this.has(hash)) {
616
- continue;
558
+ else {
559
+ let all = await entriesOrLog.all(); // TODO dont load all at once
560
+ if (all.length === 0) {
561
+ return;
617
562
  }
618
- visited.add(hash);
619
- const entry = resolvedEntries.get(hash) ||
620
- (await Entry.fromMultihash(this._storage, hash, {
621
- timeout: options?.timeout
622
- }));
623
- entry.init(this);
624
- resolvedEntries.set(entry.hash, entry);
625
- let nexts;
626
- if (entry.meta.type !== EntryType.CUT &&
627
- (nexts = await entry.getNext())) {
628
- let isRoot = true;
629
- for (const next of nexts) {
630
- if (!this.has(next)) {
631
- isRoot = false;
632
- }
633
- else {
634
- if (this._headsIndex.has(next)) {
635
- const toRemove = (await this.get(next, options));
636
- await this._headsIndex.del(toRemove);
637
- removedHeads.push(toRemove);
638
- }
639
- }
640
- let nextIndexSet = nextRefs.get(next);
641
- if (!nextIndexSet) {
642
- nextIndexSet = [];
643
- nextIndexSet.push(entry);
644
- nextRefs.set(next, nextIndexSet);
645
- }
646
- else {
647
- nextIndexSet.push(entry);
648
- }
649
- if (!visited.has(next)) {
650
- stack.push(next);
651
- }
652
- }
653
- if (isRoot) {
654
- entriesBottomUp.push(entry);
655
- }
563
+ entries = all;
564
+ }
565
+ let heads = new Map();
566
+ for (const entry of entries) {
567
+ if (heads.has(entry.hash)) {
568
+ continue;
656
569
  }
657
- else {
658
- entriesBottomUp.push(entry);
570
+ heads.set(entry.hash, true);
571
+ for (const next of await entry.getNext()) {
572
+ heads.set(next, false);
659
573
  }
660
574
  }
661
- while (entriesBottomUp.length > 0) {
662
- const e = entriesBottomUp.shift();
663
- await this._joining.get(e.hash);
664
- const p = this.joinEntry(e, nextRefs, entriesBottomUp, definedOptions).then(() => this._joining.delete(e.hash) // TODO, if head we run into problems with concurrency here!, we add heads at line 929 but resolve here
665
- );
666
- this._joining.set(e.hash, p);
575
+ for (const entry of entries) {
576
+ const p = this.joinRecursively(entry, {
577
+ references,
578
+ isHead: heads.get(entry.hash),
579
+ ...options,
580
+ });
581
+ this._joining.set(entry.hash, p);
582
+ p.finally(() => {
583
+ this._joining.delete(entry.hash);
584
+ });
667
585
  await p;
668
586
  }
669
587
  }
670
- async joinEntry(e, nextRefs, stack, options) {
671
- if (this.length > (options?.length ?? Number.MAX_SAFE_INTEGER)) {
588
+ /**
589
+ * Bottom up join of entries into the log
590
+ * @param entry
591
+ * @param options
592
+ * @returns
593
+ */
594
+ async joinRecursively(entry, options) {
595
+ if (this.entryIndex.length > (options?.length ?? Number.MAX_SAFE_INTEGER)) {
672
596
  return;
673
597
  }
674
- if (!e.hash) {
598
+ if (!entry.hash) {
675
599
  throw new Error("Unexpected");
676
600
  }
677
- const headsWithGid = this.headsIndex.gids.get(e.gid);
601
+ if (await this.has(entry.hash)) {
602
+ return;
603
+ }
604
+ entry.init(this);
605
+ if (options?.verifySignatures) {
606
+ if (!(await entry.verifySignatures())) {
607
+ throw new Error('Invalid signature entry with hash "' + entry.hash + '"');
608
+ }
609
+ }
610
+ if (this?._canAppend && !(await this?._canAppend(entry))) {
611
+ return;
612
+ }
613
+ const headsWithGid = await this.entryIndex
614
+ .getHeads(entry.gid, { type: "shape", shape: ENTRY_JOIN_SHAPE })
615
+ .all();
678
616
  if (headsWithGid) {
679
- for (const [_k, v] of headsWithGid) {
680
- if (v.meta.type === EntryType.CUT && v.next.includes(e.hash)) {
617
+ for (const v of headsWithGid) {
618
+ // TODO second argument should be a time compare instead? what about next nexts?
619
+ // and check the cut entry is newer than the current 'entry'
620
+ if (v.meta.type === EntryType.CUT &&
621
+ v.meta.next.includes(entry.hash) &&
622
+ Sorting.compare(entry, v, this._sortFn) < 0) {
681
623
  return; // already deleted
682
624
  }
683
625
  }
684
626
  }
685
- if (!this.has(e.hash)) {
686
- if (options?.verifySignatures) {
687
- if (!(await e.verifySignatures())) {
688
- throw new Error('Invalid signature entry with hash "' + e.hash + '"');
689
- }
690
- }
691
- if (this?._canAppend && !(await this?._canAppend(e))) {
692
- return;
693
- }
694
- // Update the internal entry index
695
- await this._entryIndex.set(e);
696
- await this._values.put(e);
697
- if (e.meta.type !== EntryType.CUT) {
698
- for (const a of e.next) {
699
- if (!this.has(a)) {
700
- await this.join([a]);
701
- }
702
- let nextIndexSet = this._nextsIndex.get(a);
703
- if (!nextIndexSet) {
704
- nextIndexSet = new Set();
705
- nextIndexSet.add(e.hash);
706
- this._nextsIndex.set(a, nextIndexSet);
707
- }
708
- else {
709
- nextIndexSet.add(a);
627
+ if (entry.meta.type !== EntryType.CUT) {
628
+ for (const a of entry.next) {
629
+ if (!(await this.has(a))) {
630
+ const nested = options.references?.get(a) ||
631
+ (await Entry.fromMultihash(this._storage, a, {
632
+ timeout: options?.timeout,
633
+ }));
634
+ if (!nested) {
635
+ throw new Error("Missing entry in joinRecursively: " + a);
710
636
  }
637
+ const p = this.joinRecursively(nested, options.isHead ? { ...options, isHead: false } : options);
638
+ this._joining.set(nested.hash, p);
639
+ p.finally(() => {
640
+ this._joining.delete(nested.hash);
641
+ });
642
+ await p;
711
643
  }
712
644
  }
713
- const clock = await e.getClock();
714
- this._hlc.update(clock.timestamp);
715
- const removed = await this.processEntry(e);
716
- const trimmed = await this.trim(options?.trim);
645
+ }
646
+ const clock = await entry.getClock();
647
+ this._hlc.update(clock.timestamp);
648
+ await this._entryIndex.put(entry, {
649
+ unique: false,
650
+ isHead: options.isHead,
651
+ toMultiHash: true,
652
+ });
653
+ const removed = await this.processEntry(entry);
654
+ const trimmed = await this.trim(options?.trim);
655
+ if (trimmed) {
717
656
  for (const entry of trimmed) {
718
657
  removed.push(entry);
719
658
  }
720
- await this?._onChange?.({ added: [e], removed: removed });
721
- }
722
- const forward = nextRefs.get(e.hash);
723
- if (forward) {
724
- if (this._headsIndex.has(e.hash)) {
725
- await this._headsIndex.del(e, options);
726
- }
727
- for (const en of forward) {
728
- stack.push(en);
729
- }
730
- }
731
- else {
732
- await this.headsIndex.put(e, options);
733
659
  }
660
+ await this?._onChange?.({ added: [entry], removed: removed });
734
661
  }
735
662
  async processEntry(entry) {
736
663
  if (entry.meta.type === EntryType.CUT) {
@@ -746,22 +673,25 @@ let Log = Log_1 = class Log {
746
673
  const deleted = [];
747
674
  while (stack.length > 0) {
748
675
  const entry = stack.pop();
749
- if ((counter > 0 || !skipFirst) && this.has(entry.hash)) {
750
- // 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.
751
- this._trim.deleteFromCache(entry);
752
- await this._headsIndex.del(entry);
753
- await this._values.delete(entry);
754
- await this._entryIndex.delete(entry.hash);
755
- this._nextsIndex.delete(entry.hash);
756
- deleted.push(entry);
757
- promises.push(entry.delete(this._storage));
758
- }
759
- for (const next of entry.next) {
760
- const nextFromNext = this._nextsIndex.get(next);
761
- if (nextFromNext) {
762
- nextFromNext.delete(entry.hash);
676
+ const skip = counter === 0 && skipFirst;
677
+ if (!skip) {
678
+ const has = await this.has(entry.hash);
679
+ if (has) {
680
+ // 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.
681
+ const deletedEntry = await this.delete(entry.hash);
682
+ if (deletedEntry) {
683
+ /* this._nextsIndex.delete(entry.hash); */
684
+ deleted.push(deletedEntry);
685
+ }
763
686
  }
764
- if (!nextFromNext || nextFromNext.size === 0) {
687
+ }
688
+ for (const next of entry.meta.next) {
689
+ const nextFromNext = this.entryIndex.getHasNext(next);
690
+ const entriesThatHasNext = await nextFromNext.all();
691
+ // if there are no entries which is not of "CUT" type, we can safely delete the next entry
692
+ // figureately speaking, these means where are cutting all branches to a stem, so we can delete the stem as well
693
+ let hasAlternativeNext = !!entriesThatHasNext.find((x) => x.meta.type !== EntryType.CUT);
694
+ if (!hasAlternativeNext) {
765
695
  const ne = await this.get(next);
766
696
  if (ne) {
767
697
  stack.push(ne);
@@ -773,33 +703,10 @@ let Log = Log_1 = class Log {
773
703
  await Promise.all(promises);
774
704
  return deleted;
775
705
  }
776
- async delete(entry) {
777
- this._trim.deleteFromCache(entry);
778
- await this._headsIndex.del(entry, {
779
- cache: {
780
- update: false
781
- }
782
- }); // cache is not updated here, but at *
783
- await this._values.delete(entry);
784
- await this._entryIndex.delete(entry.hash);
785
- this._nextsIndex.delete(entry.hash);
786
- const newHeads = [];
787
- for (const next of entry.next) {
788
- const ne = await this.get(next);
789
- if (ne) {
790
- const nexts = this._nextsIndex.get(next);
791
- nexts.delete(entry.hash);
792
- if (nexts.size === 0) {
793
- await this._headsIndex.put(ne);
794
- newHeads.push(ne.hash);
795
- }
796
- }
797
- }
798
- await this._headsIndex.updateHeadsCache({
799
- added: newHeads,
800
- removed: [entry.hash]
801
- }); // * here
802
- return entry.delete(this._storage);
706
+ async delete(hash) {
707
+ await this._trim.deleteFromCache(hash);
708
+ const removedEntry = await this._entryIndex.delete(hash);
709
+ return removedEntry;
803
710
  }
804
711
  /**
805
712
  * Returns the log entries as a formatted string.
@@ -819,37 +726,29 @@ let Log = Log_1 = class Log {
819
726
  let padding = new Array(Math.max(len - 1, 0));
820
727
  padding = len > 1 ? padding.fill(" ") : padding;
821
728
  padding = len > 0 ? padding.concat(["└─"]) : padding;
822
- /* istanbul ignore next */
823
729
  return (padding.join("") +
824
- (payloadMapper ? payloadMapper(e.payload) : e.payload));
730
+ (payloadMapper?.(e.payload) || e.payload));
825
731
  }))).join("\n");
826
732
  }
827
- async idle() {
828
- await this._headsIndex.headsCache?.idle();
829
- }
830
733
  async close() {
831
734
  // Don't return early here if closed = true, because "load" might create processes that needs to be closed
832
735
  this._closed = true; // closed = true before doing below, else we might try to open the headsIndex cache because it is closed as we assume log is still open
833
- await this._entryCache?.clear();
834
- await this._headsIndex?.close();
835
- await this._memory?.close();
836
- this._entryCache = undefined;
837
- this._headsIndex = undefined;
838
- this._memory = undefined;
839
- this._values = undefined;
736
+ this._closeController.abort();
737
+ await this._indexer?.stop?.();
738
+ this._indexer = undefined;
739
+ this._loadedOnce = false;
840
740
  }
841
741
  async drop() {
842
742
  // Don't return early here if closed = true, because "load" might create processes that needs to be closed
843
743
  this._closed = true; // closed = true before doing below, else we might try to open the headsIndex cache because it is closed as we assume log is still open
844
- await Promise.all([...this.entryIndex._index.values()].map((x) => this.blocks.rm(x.hash)));
845
- await this._headsIndex?.drop();
846
- await this._entryCache?.clear();
847
- await this._memory?.clear();
848
- await this._memory?.close();
744
+ this._closeController.abort();
745
+ await this.entryIndex?.clear();
746
+ await this._indexer?.drop();
747
+ await this._indexer?.stop?.();
849
748
  }
850
749
  async recover() {
851
750
  // merge existing
852
- const existing = await this.getHeads();
751
+ const existing = await this.getHeads(true).all();
853
752
  const allHeads = new Map();
854
753
  for (const head of existing) {
855
754
  allHeads.set(head.hash, head);
@@ -878,42 +777,33 @@ let Log = Log_1 = class Log {
878
777
  // assume they are valid, (let access control reject them if not)
879
778
  await this.load({ reload: true, heads: [...allHeads.values()] });
880
779
  }
881
- async load(opts = { reload: true }) {
780
+ async load(opts = {}) {
882
781
  if (this.closed) {
883
782
  throw new Error("Closed");
884
783
  }
784
+ if (this._loadedOnce && !opts.reload && !opts.reset) {
785
+ return;
786
+ }
787
+ this._loadedOnce = true;
885
788
  const providedCustomHeads = Array.isArray(opts["heads"]);
886
789
  const heads = providedCustomHeads
887
790
  ? opts["heads"]
888
- : await this.headsIndex.load({
889
- replicate: true, // TODO this.replication.replicate(x) => true/false
890
- timeout: opts.fetchEntryTimeout,
891
- reload: opts.reload,
791
+ : await this._entryIndex
792
+ .getHeads(undefined, {
793
+ type: "full",
794
+ signal: this._closeController.signal,
892
795
  ignoreMissing: opts.ignoreMissing,
893
- cache: { update: true, reset: true }
894
- });
796
+ timeout: opts.timeout,
797
+ })
798
+ .all();
895
799
  if (heads) {
896
800
  // Load the log
897
- if (providedCustomHeads) {
801
+ if (providedCustomHeads || opts.reset) {
898
802
  await this.reset(heads);
899
803
  }
900
804
  else {
901
- /*
902
- TODO feat amount load
903
- const amount = (opts as { amount?: number }).amount;
904
- if (amount != null && amount >= 0 && amount < heads.length) {
905
- throw new Error(
906
- "You are not loading all heads, this will lead to unexpected behaviours on write. Please load at least load: " +
907
- amount +
908
- " entries"
909
- );
910
- } */
911
805
  await this.join(heads instanceof Entry ? [heads] : heads, {
912
- /* length: amount, */
913
806
  timeout: opts?.fetchEntryTimeout,
914
- cache: {
915
- update: false
916
- }
917
807
  });
918
808
  }
919
809
  }
@@ -924,7 +814,7 @@ let Log = Log_1 = class Log {
924
814
  await log.join(!Array.isArray(entryOrHash) ? [entryOrHash] : entryOrHash, {
925
815
  timeout: options.timeout,
926
816
  trim: options.trim,
927
- verifySignatures: true
817
+ verifySignatures: true,
928
818
  });
929
819
  return log;
930
820
  }
@@ -934,7 +824,7 @@ let Log = Log_1 = class Log {
934
824
  * Finds entries that are the heads of this collection,
935
825
  * ie. entries that are not referenced by other entries.
936
826
  *
937
- * @param {Array<Entry<T>>} entries Entries to search heads from
827
+ * @param {Array<Entry<T>>} entries - Entries to search heads from
938
828
  * @returns {Array<Entry<T>>}
939
829
  */
940
830
  static findHeads(entries) {