@peerbit/log 6.1.1 → 6.2.0

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 (47) hide show
  1. package/dist/benchmark/native-graph.js +447 -5
  2. package/dist/benchmark/native-graph.js.map +1 -1
  3. package/dist/src/clock.d.ts +1 -0
  4. package/dist/src/clock.d.ts.map +1 -1
  5. package/dist/src/clock.js +32 -0
  6. package/dist/src/clock.js.map +1 -1
  7. package/dist/src/entry-create.d.ts +1 -0
  8. package/dist/src/entry-create.d.ts.map +1 -1
  9. package/dist/src/entry-create.js.map +1 -1
  10. package/dist/src/entry-index.d.ts +288 -12
  11. package/dist/src/entry-index.d.ts.map +1 -1
  12. package/dist/src/entry-index.js +1478 -33
  13. package/dist/src/entry-index.js.map +1 -1
  14. package/dist/src/entry-v0.d.ts +184 -1
  15. package/dist/src/entry-v0.d.ts.map +1 -1
  16. package/dist/src/entry-v0.js +1021 -12
  17. package/dist/src/entry-v0.js.map +1 -1
  18. package/dist/src/entry.d.ts +73 -1
  19. package/dist/src/entry.d.ts.map +1 -1
  20. package/dist/src/entry.js +124 -1
  21. package/dist/src/entry.js.map +1 -1
  22. package/dist/src/index.d.ts +1 -1
  23. package/dist/src/index.d.ts.map +1 -1
  24. package/dist/src/index.js +1 -1
  25. package/dist/src/index.js.map +1 -1
  26. package/dist/src/log.d.ts +62 -13
  27. package/dist/src/log.d.ts.map +1 -1
  28. package/dist/src/log.js +2282 -100
  29. package/dist/src/log.js.map +1 -1
  30. package/dist/src/runtime.d.ts +2 -0
  31. package/dist/src/runtime.d.ts.map +1 -0
  32. package/dist/src/runtime.js +10 -0
  33. package/dist/src/runtime.js.map +1 -0
  34. package/dist/src/trim.d.ts +14 -2
  35. package/dist/src/trim.d.ts.map +1 -1
  36. package/dist/src/trim.js +92 -4
  37. package/dist/src/trim.js.map +1 -1
  38. package/package.json +18 -15
  39. package/src/clock.ts +34 -0
  40. package/src/entry-create.ts +1 -0
  41. package/src/entry-index.ts +2232 -68
  42. package/src/entry-v0.ts +1488 -13
  43. package/src/entry.ts +235 -1
  44. package/src/index.ts +7 -1
  45. package/src/log.ts +3246 -206
  46. package/src/runtime.ts +16 -0
  47. package/src/trim.ts +133 -7
package/src/entry.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import { deserialize, serialize } from "@dao-xyz/borsh";
2
- import { type Blocks, type GetOptions } from "@peerbit/blocks-interface";
2
+ import {
3
+ type Blocks,
4
+ type GetOptions,
5
+ calculateRawCid,
6
+ cidifyString,
7
+ } from "@peerbit/blocks-interface";
3
8
  import type { PublicSignKey, SignatureWithKey } from "@peerbit/crypto";
4
9
  import type { CryptoKeychain } from "@peerbit/keychain";
5
10
  import { LamportClock as Clock } from "./clock.js";
@@ -10,6 +15,102 @@ import type { Payload } from "./payload.js";
10
15
 
11
16
  export type CanAppend<T> = (canAppend: Entry<T>) => Promise<boolean> | boolean;
12
17
  export type ShallowOrFullEntry<T> = ShallowEntry | Entry<T>;
18
+ export type PreparedEntryBlock = Awaited<ReturnType<typeof calculateRawCid>>;
19
+ export type PreparedAppendFacts = {
20
+ hash: string;
21
+ gid: string;
22
+ next: string[];
23
+ wallTime: bigint;
24
+ logical: number;
25
+ clockId?: Uint8Array;
26
+ type?: EntryType;
27
+ metaData?: Uint8Array;
28
+ payloadSize: number;
29
+ metaBytes?: Uint8Array;
30
+ hashDigestBytes?: Uint8Array;
31
+ };
32
+ export type PreparedNativeLogEntry = {
33
+ hash: string;
34
+ gid: string;
35
+ next: string[];
36
+ type: number;
37
+ head?: boolean;
38
+ payloadSize?: number;
39
+ data?: Uint8Array;
40
+ clock: {
41
+ timestamp: {
42
+ wallTime: bigint | number | string;
43
+ logical?: number;
44
+ };
45
+ };
46
+ };
47
+ export type PreparedAppendChain<T> = {
48
+ entries: Entry<T>[];
49
+ blocks?: PreparedEntryBlock[];
50
+ shallowEntries: ShallowEntry[];
51
+ appendFacts?: PreparedAppendFacts[];
52
+ nativeEntries?: PreparedNativeLogEntry[];
53
+ nativeGraphUpdated?: boolean;
54
+ nativeBlocksCommitted?: boolean;
55
+ };
56
+ export type PreparedAppendCommitOnlyChain<T> = {
57
+ materializeEntry: (index?: number) => Entry<T>;
58
+ materializeEntries: () => Entry<T>[];
59
+ blocks?: PreparedEntryBlock[];
60
+ shallowEntries: ShallowEntry[];
61
+ appendFacts: PreparedAppendFacts[];
62
+ nativeEntries?: PreparedNativeLogEntry[];
63
+ trimmedNativeEntries?: PreparedNativeLogEntry[];
64
+ trimmedNativeEntryHashes?: string[];
65
+ trimmedNativeBlocksDeleted?: boolean;
66
+ nativeGraphUpdated?: boolean;
67
+ nativeBlocksCommitted?: boolean;
68
+ };
69
+
70
+ const preparedEntryBlocks = new WeakMap<object, PreparedEntryBlock>();
71
+ const preparedShallowEntries = new WeakMap<object, ShallowEntry>();
72
+ const preparedNativeLogEntries = new WeakMap<object, PreparedNativeLogEntry>();
73
+
74
+ const preparedEntryBlockFromBytes = (
75
+ bytes: Uint8Array,
76
+ cid: string,
77
+ ): PreparedEntryBlock => {
78
+ let cidObject: ReturnType<typeof cidifyString> | undefined;
79
+ return {
80
+ block: {
81
+ bytes,
82
+ get cid() {
83
+ cidObject ??= cidifyString(cid);
84
+ return cidObject;
85
+ },
86
+ value: bytes,
87
+ } as PreparedEntryBlock["block"],
88
+ cid,
89
+ };
90
+ };
91
+
92
+ const preparedEntryBlockFromBytesSource = (
93
+ bytesSource: () => Uint8Array,
94
+ cid: string,
95
+ ): PreparedEntryBlock => {
96
+ let cidObject: ReturnType<typeof cidifyString> | undefined;
97
+ let bytesValue: Uint8Array | undefined;
98
+ return {
99
+ block: {
100
+ get bytes() {
101
+ return (bytesValue ??= bytesSource());
102
+ },
103
+ get cid() {
104
+ cidObject ??= cidifyString(cid);
105
+ return cidObject;
106
+ },
107
+ get value() {
108
+ return (bytesValue ??= bytesSource());
109
+ },
110
+ } as PreparedEntryBlock["block"],
111
+ cid,
112
+ };
113
+ };
13
114
 
14
115
  interface Meta {
15
116
  clock: Clock;
@@ -89,6 +190,138 @@ export abstract class Entry<T> {
89
190
  return store.put(bytes);
90
191
  }
91
192
 
193
+ static async prepareMultihash<T>(entry: Entry<T>): Promise<string> {
194
+ if (entry.hash) {
195
+ throw new Error("Expected hash to be missing");
196
+ }
197
+
198
+ const bytes = entry.getStorageBytes();
199
+ entry.size = bytes.length;
200
+ const prepared = await calculateRawCid(bytes);
201
+ preparedEntryBlocks.set(entry, prepared);
202
+ return prepared.cid;
203
+ }
204
+
205
+ static prepareMultihashBytes<T>(
206
+ entry: Entry<T>,
207
+ bytes: Uint8Array,
208
+ cid: string,
209
+ ): string {
210
+ if (entry.hash) {
211
+ throw new Error("Expected hash to be missing");
212
+ }
213
+
214
+ entry.size = bytes.length;
215
+ preparedEntryBlocks.set(entry, preparedEntryBlockFromBytes(bytes, cid));
216
+ return cid;
217
+ }
218
+
219
+ /**
220
+ * Like {@link Entry.prepareMultihashBytes} but defers pulling the block
221
+ * bytes until a consumer actually reads them (block store put, storage
222
+ * bytes). Callers that keep entry bytes in an external store (e.g. the
223
+ * native wire stash) use this so entries handed to change consumers do
224
+ * not copy bytes they may never touch.
225
+ */
226
+ static prepareMultihashBytesLazy<T>(
227
+ entry: Entry<T>,
228
+ cid: string,
229
+ size: number,
230
+ bytesSource: () => Uint8Array,
231
+ ): string {
232
+ if (entry.hash) {
233
+ throw new Error("Expected hash to be missing");
234
+ }
235
+
236
+ entry.size = size;
237
+ preparedEntryBlocks.set(
238
+ entry,
239
+ preparedEntryBlockFromBytesSource(bytesSource, cid),
240
+ );
241
+ return cid;
242
+ }
243
+
244
+ static preparedBlockFromBytes(bytes: Uint8Array, cid: string): PreparedEntryBlock {
245
+ return preparedEntryBlockFromBytes(bytes, cid);
246
+ }
247
+
248
+ static toMultihashBytes<T>(
249
+ store: Blocks,
250
+ entry: Entry<T>,
251
+ bytes: Uint8Array,
252
+ cid: string,
253
+ ): Promise<string> | string {
254
+ if (entry.hash) {
255
+ throw new Error("Expected hash to be missing");
256
+ }
257
+
258
+ entry.size = bytes.length;
259
+ return store.put(preparedEntryBlockFromBytes(bytes, cid));
260
+ }
261
+
262
+ static takePreparedBlock<T>(entry: Entry<T>): PreparedEntryBlock | undefined {
263
+ const prepared = preparedEntryBlocks.get(entry);
264
+ if (prepared) {
265
+ preparedEntryBlocks.delete(entry);
266
+ }
267
+ return prepared;
268
+ }
269
+
270
+ static hasPreparedBlock<T>(entry: Entry<T>): boolean {
271
+ return preparedEntryBlocks.has(entry);
272
+ }
273
+
274
+ static getPreparedStorageBytes<T>(entry: Entry<T>): Uint8Array | undefined {
275
+ const prepared = preparedEntryBlocks.get(entry);
276
+ const block = prepared?.block as
277
+ | { bytes?: Uint8Array; value?: Uint8Array }
278
+ | undefined;
279
+ return block?.bytes ?? block?.value;
280
+ }
281
+
282
+ static prepareShallowEntry<T>(entry: Entry<T>, shallow: ShallowEntry): void {
283
+ preparedShallowEntries.set(entry, shallow);
284
+ }
285
+
286
+ static hasPreparedShallowEntry<T>(entry: Entry<T>): boolean {
287
+ return preparedShallowEntries.has(entry);
288
+ }
289
+
290
+ static takePreparedShallowEntry<T>(
291
+ entry: Entry<T>,
292
+ isHead: boolean,
293
+ ): ShallowEntry | undefined {
294
+ const prepared = preparedShallowEntries.get(entry);
295
+ if (prepared) {
296
+ preparedShallowEntries.delete(entry);
297
+ prepared.head = isHead;
298
+ }
299
+ return prepared;
300
+ }
301
+
302
+ static prepareNativeLogEntry<T>(
303
+ entry: Entry<T>,
304
+ nativeEntry: PreparedNativeLogEntry,
305
+ ): void {
306
+ preparedNativeLogEntries.set(entry, nativeEntry);
307
+ }
308
+
309
+ static hasPreparedNativeLogEntry<T>(entry: Entry<T>): boolean {
310
+ return preparedNativeLogEntries.has(entry);
311
+ }
312
+
313
+ static takePreparedNativeLogEntry<T>(
314
+ entry: Entry<T>,
315
+ isHead: boolean,
316
+ ): PreparedNativeLogEntry | undefined {
317
+ const prepared = preparedNativeLogEntries.get(entry);
318
+ if (prepared) {
319
+ preparedNativeLogEntries.delete(entry);
320
+ prepared.head = isHead;
321
+ }
322
+ return prepared;
323
+ }
324
+
92
325
  static fromMultihash = async <T>(
93
326
  store: Blocks,
94
327
  hash: string,
@@ -102,6 +335,7 @@ export abstract class Entry<T> {
102
335
  throw new Error("Failed to resolve block: " + hash);
103
336
  }
104
337
  const entry = deserialize(bytes, Entry);
338
+ Entry.prepareMultihashBytes(entry, bytes, hash);
105
339
  entry.hash = hash;
106
340
  entry.size = bytes.length;
107
341
  return entry as Entry<T>;
package/src/index.ts CHANGED
@@ -2,7 +2,13 @@ export * from "./log.js";
2
2
  export * from "./log-sorting.js";
3
3
  export * from "./log-errors.js";
4
4
  export * from "./snapshot.js";
5
- export * from "./entry.js";
5
+ export {
6
+ Entry,
7
+ type CanAppend,
8
+ type PreparedAppendFacts,
9
+ type PreparedNativeLogEntry,
10
+ type ShallowOrFullEntry,
11
+ } from "./entry.js";
6
12
  export * from "./entry-type.js";
7
13
  export * from "./entry-with-refs.js";
8
14
  export * from "./entry-shallow.js";