@peerbit/log 2.1.10 → 3.0.2
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/lib/esm/clock.js.map +1 -1
- package/lib/esm/difference.js.map +1 -1
- package/lib/esm/encoding.js +1 -1
- package/lib/esm/encoding.js.map +1 -1
- package/lib/esm/entry-index.d.ts +1 -1
- package/lib/esm/entry-index.js +5 -5
- package/lib/esm/entry-index.js.map +1 -1
- package/lib/esm/entry.d.ts +3 -2
- package/lib/esm/entry.js +1 -1
- package/lib/esm/entry.js.map +1 -1
- package/lib/esm/heads-cache.d.ts +4 -4
- package/lib/esm/heads-cache.js +9 -13
- package/lib/esm/heads-cache.js.map +1 -1
- package/lib/esm/heads.d.ts +4 -4
- package/lib/esm/heads.js.map +1 -1
- package/lib/esm/hrtime.js +1 -1
- package/lib/esm/hrtime.js.map +1 -1
- package/lib/esm/log-sorting.js.map +1 -1
- package/lib/esm/log.d.ts +6 -5
- package/lib/esm/log.js +15 -12
- package/lib/esm/log.js.map +1 -1
- package/lib/esm/logger.d.ts +1 -1
- package/lib/esm/snapshot.d.ts +3 -3
- package/lib/esm/snapshot.js +2 -2
- package/lib/esm/snapshot.js.map +1 -1
- package/lib/esm/trim.d.ts +3 -0
- package/lib/esm/trim.js +7 -3
- package/lib/esm/trim.js.map +1 -1
- package/lib/esm/types.js.map +1 -1
- package/lib/esm/values.d.ts +2 -3
- package/lib/esm/values.js +4 -14
- package/lib/esm/values.js.map +1 -1
- package/package.json +8 -8
- package/src/encoding.ts +1 -1
- package/src/entry-index.ts +5 -5
- package/src/entry.ts +5 -7
- package/src/heads-cache.ts +14 -21
- package/src/heads.ts +4 -4
- package/src/hrtime.ts +2 -2
- package/src/log.ts +25 -21
- package/src/snapshot.ts +5 -5
- package/src/trim.ts +7 -1
- package/src/values.ts +5 -16
package/src/hrtime.ts
CHANGED
|
@@ -28,7 +28,7 @@ SOFTWARE.
|
|
|
28
28
|
const _perfomancePolyfill = () => {
|
|
29
29
|
// based on https://gist.github.com/paulirish/5438650 copyright Paul Irish 2015.
|
|
30
30
|
if ("performance" in window === false) {
|
|
31
|
-
(window.performance as any) = {};
|
|
31
|
+
((window as any).performance as any) = {};
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
Date.now =
|
|
@@ -45,7 +45,7 @@ const _perfomancePolyfill = () => {
|
|
|
45
45
|
nowOffset = performance.timing.navigationStart;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
window.performance
|
|
48
|
+
(window.performance as any)["now"] = () => Date.now() - nowOffset;
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
|
package/src/log.ts
CHANGED
|
@@ -3,11 +3,10 @@ import {
|
|
|
3
3
|
randomBytes,
|
|
4
4
|
sha256Base64Sync,
|
|
5
5
|
Identity,
|
|
6
|
-
Keychain,
|
|
7
6
|
X25519Keypair
|
|
8
7
|
} from "@peerbit/crypto";
|
|
9
8
|
import { Cache } from "@peerbit/cache";
|
|
10
|
-
import {
|
|
9
|
+
import { AnyStore } from "@peerbit/any-store";
|
|
11
10
|
|
|
12
11
|
import { EntryIndex } from "./entry-index.js";
|
|
13
12
|
import * as LogError from "./log-errors.js";
|
|
@@ -37,6 +36,7 @@ import { Change } from "./change.js";
|
|
|
37
36
|
import { EntryWithRefs } from "./entry-with-refs.js";
|
|
38
37
|
import { Blocks } from "@peerbit/blocks-interface";
|
|
39
38
|
import { cidifyString } from "@peerbit/blocks";
|
|
39
|
+
import { Keychain } from "@peerbit/keychain";
|
|
40
40
|
|
|
41
41
|
const { LastWriteWins, NoZeroes } = Sorting;
|
|
42
42
|
|
|
@@ -46,7 +46,7 @@ export type LogEvents<T> = {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
export type MemoryProperties = {
|
|
49
|
-
cache?:
|
|
49
|
+
cache?: AnyStore;
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
export type LogProperties<T> = {
|
|
@@ -110,7 +110,7 @@ export class Log<T> {
|
|
|
110
110
|
private _canAppend?: CanAppend<T>;
|
|
111
111
|
private _onChange?: (change: Change<T>) => void;
|
|
112
112
|
private _closed = true;
|
|
113
|
-
private _memory?:
|
|
113
|
+
private _memory?: AnyStore;
|
|
114
114
|
private _joining: Map<string, Promise<any>>; // entry hashes that are currently joining into this log
|
|
115
115
|
|
|
116
116
|
constructor(properties?: { id?: Uint8Array }) {
|
|
@@ -173,6 +173,7 @@ export class Log<T> {
|
|
|
173
173
|
this._values = new Values(this._entryIndex, this._sortFn);
|
|
174
174
|
this._trim = new Trim(
|
|
175
175
|
{
|
|
176
|
+
headsIndex: this._headsIndex,
|
|
176
177
|
deleteNode: async (node: EntryNode) => {
|
|
177
178
|
// TODO check if we have before delete?
|
|
178
179
|
const entry = await this.get(node.value);
|
|
@@ -180,19 +181,20 @@ export class Log<T> {
|
|
|
180
181
|
const a = this.values.length;
|
|
181
182
|
if (entry) {
|
|
182
183
|
this.values.deleteNode(node);
|
|
183
|
-
await
|
|
184
|
-
|
|
184
|
+
await Promise.all([
|
|
185
|
+
this.headsIndex.del(this.entryIndex.getShallow(node.value)!),
|
|
186
|
+
this.entryIndex.delete(node.value)
|
|
187
|
+
]);
|
|
185
188
|
this.nextsIndex.delete(node.value);
|
|
186
|
-
await this.
|
|
189
|
+
await this.blocks.rm(node.value);
|
|
187
190
|
}
|
|
188
191
|
const b = this.values.length;
|
|
189
192
|
if (a === b) {
|
|
190
|
-
throw new Error(
|
|
191
|
-
"
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
);
|
|
193
|
+
/* throw new Error(
|
|
194
|
+
"Unexpected miss match between log size and entry index size: " +
|
|
195
|
+
this.values.length +
|
|
196
|
+
this.entryIndex._index.size
|
|
197
|
+
); */
|
|
196
198
|
}
|
|
197
199
|
return entry;
|
|
198
200
|
},
|
|
@@ -276,7 +278,7 @@ export class Log<T> {
|
|
|
276
278
|
return this._headsIndex;
|
|
277
279
|
}
|
|
278
280
|
|
|
279
|
-
get memory():
|
|
281
|
+
get memory(): AnyStore | undefined {
|
|
280
282
|
return this._memory;
|
|
281
283
|
}
|
|
282
284
|
|
|
@@ -328,7 +330,7 @@ export class Log<T> {
|
|
|
328
330
|
return this._identity;
|
|
329
331
|
}
|
|
330
332
|
|
|
331
|
-
get
|
|
333
|
+
get blocks(): Blocks {
|
|
332
334
|
return this._storage;
|
|
333
335
|
}
|
|
334
336
|
|
|
@@ -554,7 +556,7 @@ export class Log<T> {
|
|
|
554
556
|
receiver: {
|
|
555
557
|
...options.encryption.receiver
|
|
556
558
|
}
|
|
557
|
-
|
|
559
|
+
}
|
|
558
560
|
: undefined,
|
|
559
561
|
canAppend: this._canAppend
|
|
560
562
|
});
|
|
@@ -581,7 +583,6 @@ export class Log<T> {
|
|
|
581
583
|
const removed = await this.processEntry(entry);
|
|
582
584
|
|
|
583
585
|
entry.init({ encoding: this._encoding, keychain: this._keychain });
|
|
584
|
-
// console.log('put entry', entry.hash, (await this._entryIndex._index.size));
|
|
585
586
|
|
|
586
587
|
const trimmed = await this.trim(options?.trim);
|
|
587
588
|
|
|
@@ -939,16 +940,15 @@ export class Log<T> {
|
|
|
939
940
|
const promises: Promise<void>[] = [];
|
|
940
941
|
let counter = 0;
|
|
941
942
|
const deleted: Entry<T>[] = [];
|
|
942
|
-
const deletedGids = new Set();
|
|
943
943
|
|
|
944
944
|
while (stack.length > 0) {
|
|
945
945
|
const entry = stack.pop()!;
|
|
946
946
|
if ((counter > 0 || !skipFirst) && this.has(entry.hash)) {
|
|
947
947
|
// 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.
|
|
948
948
|
this._trim.deleteFromCache(entry);
|
|
949
|
+
await this._headsIndex.del(entry);
|
|
949
950
|
await this._values.delete(entry);
|
|
950
951
|
await this._entryIndex.delete(entry.hash);
|
|
951
|
-
await this._headsIndex.del(entry);
|
|
952
952
|
|
|
953
953
|
this._nextsIndex.delete(entry.hash);
|
|
954
954
|
deleted.push(entry);
|
|
@@ -976,9 +976,9 @@ export class Log<T> {
|
|
|
976
976
|
|
|
977
977
|
async delete(entry: Entry<any>) {
|
|
978
978
|
this._trim.deleteFromCache(entry);
|
|
979
|
+
await this._headsIndex.del(entry);
|
|
979
980
|
await this._values.delete(entry);
|
|
980
981
|
await this._entryIndex.delete(entry.hash);
|
|
981
|
-
await this._headsIndex.del(entry);
|
|
982
982
|
this._nextsIndex.delete(entry.hash);
|
|
983
983
|
const newHeads: string[] = [];
|
|
984
984
|
for (const next of entry.next) {
|
|
@@ -1049,6 +1049,10 @@ export class Log<T> {
|
|
|
1049
1049
|
async drop() {
|
|
1050
1050
|
// Don't return early here if closed = true, because "load" might create processes that needs to be closed
|
|
1051
1051
|
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
|
|
1052
|
+
|
|
1053
|
+
await Promise.all(
|
|
1054
|
+
[...this.entryIndex._index.values()].map((x) => this.blocks.rm(x.hash))
|
|
1055
|
+
);
|
|
1052
1056
|
await this._headsIndex?.drop();
|
|
1053
1057
|
await this._entryCache?.clear();
|
|
1054
1058
|
await this._memory?.clear();
|
|
@@ -1107,7 +1111,7 @@ export class Log<T> {
|
|
|
1107
1111
|
timeout: opts.fetchEntryTimeout,
|
|
1108
1112
|
reload: opts.reload,
|
|
1109
1113
|
cache: { update: true, reset: true }
|
|
1110
|
-
|
|
1114
|
+
});
|
|
1111
1115
|
|
|
1112
1116
|
if (heads) {
|
|
1113
1117
|
// Load the log
|
package/src/snapshot.ts
CHANGED
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
variant,
|
|
11
11
|
vec
|
|
12
12
|
} from "@dao-xyz/borsh";
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
13
|
+
import { waitFor } from "@peerbit/time";
|
|
14
|
+
import { AnyStore } from "@peerbit/any-store";
|
|
15
15
|
import { logger } from "./logger.js";
|
|
16
16
|
|
|
17
17
|
@variant(0)
|
|
@@ -46,7 +46,7 @@ export class Snapshot {
|
|
|
46
46
|
export const save = async <T>(
|
|
47
47
|
snapshotPath: string,
|
|
48
48
|
blockstore: Blocks,
|
|
49
|
-
cache:
|
|
49
|
+
cache: AnyStore,
|
|
50
50
|
log: {
|
|
51
51
|
id: Uint8Array;
|
|
52
52
|
getHeads: () => Promise<string[]>;
|
|
@@ -68,7 +68,7 @@ export const save = async <T>(
|
|
|
68
68
|
writer.string(snapshot);
|
|
69
69
|
await cache.put(snapshotPath, writer.finalize());
|
|
70
70
|
|
|
71
|
-
await
|
|
71
|
+
await waitFor(async () => (await cache.get(snapshotPath)) != null, {
|
|
72
72
|
delayInterval: 200,
|
|
73
73
|
timeout: 10 * 1000
|
|
74
74
|
});
|
|
@@ -91,7 +91,7 @@ export const load = async (
|
|
|
91
91
|
export const loadFromCache = async (
|
|
92
92
|
path: string,
|
|
93
93
|
blockstore: Blocks,
|
|
94
|
-
cache:
|
|
94
|
+
cache: AnyStore
|
|
95
95
|
) => {
|
|
96
96
|
const snapshotOrCID = await cache.get(path);
|
|
97
97
|
if (!snapshotOrCID) {
|
package/src/trim.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Cache } from "@peerbit/cache";
|
|
|
2
2
|
import PQueue from "p-queue";
|
|
3
3
|
import { Entry, ShallowEntry } from "./entry.js";
|
|
4
4
|
import { EntryNode, Values } from "./values.js";
|
|
5
|
+
import { HeadsIndex } from "./heads.js";
|
|
5
6
|
|
|
6
7
|
const trimOptionsEqual = (a: TrimOptions, b: TrimOptions) => {
|
|
7
8
|
if (a.type === b.type) {
|
|
@@ -78,6 +79,7 @@ export type TrimCanAppendOption = {
|
|
|
78
79
|
export type TrimOptions = TrimCanAppendOption & TrimCondition;
|
|
79
80
|
|
|
80
81
|
interface Log<T> {
|
|
82
|
+
headsIndex: HeadsIndex<T>;
|
|
81
83
|
values: () => Values<T>;
|
|
82
84
|
deleteNode: (node: EntryNode) => Promise<Entry<T> | undefined>;
|
|
83
85
|
}
|
|
@@ -86,6 +88,8 @@ export class Trim<T> {
|
|
|
86
88
|
private _canTrimCacheLastNode: EntryNode | undefined | null;
|
|
87
89
|
private _trimLastHead: EntryNode | undefined | null;
|
|
88
90
|
private _trimLastTail: EntryNode | undefined | null;
|
|
91
|
+
private _trimLastLength = 0;
|
|
92
|
+
|
|
89
93
|
private _trimLastOptions: TrimOptions;
|
|
90
94
|
private _trimLastSeed: string | number | undefined;
|
|
91
95
|
private _canTrimCacheHashBreakpoint: Cache<boolean>;
|
|
@@ -177,9 +181,10 @@ export class Trim<T> {
|
|
|
177
181
|
!this._trimLastOptions ||
|
|
178
182
|
!trimOptionsEqual(this._trimLastOptions, option);
|
|
179
183
|
|
|
180
|
-
|
|
184
|
+
changed =
|
|
181
185
|
this._trimLastHead !== values.head ||
|
|
182
186
|
this._trimLastTail !== values.tail ||
|
|
187
|
+
this._trimLastLength !== this._log.headsIndex.size ||
|
|
183
188
|
trimOptionsChanged;
|
|
184
189
|
if (!changed) {
|
|
185
190
|
return [];
|
|
@@ -250,6 +255,7 @@ export class Trim<T> {
|
|
|
250
255
|
this._canTrimCacheLastNode = node || lastNode;
|
|
251
256
|
this._trimLastHead = values.head;
|
|
252
257
|
this._trimLastTail = values.tail;
|
|
258
|
+
this._trimLastLength = this._log.headsIndex.size;
|
|
253
259
|
this._trimLastOptions = option;
|
|
254
260
|
this._trimLastSeed = seed;
|
|
255
261
|
|
package/src/values.ts
CHANGED
|
@@ -61,29 +61,18 @@ export class Values<T> {
|
|
|
61
61
|
return this._values.length;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
private _putPromise: Map<string, Promise<any>> = new Map();
|
|
65
|
-
|
|
66
64
|
get entryIndex(): EntryIndex<T> {
|
|
67
65
|
return this._entryIndex;
|
|
68
66
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (promise) {
|
|
72
|
-
return promise;
|
|
73
|
-
}
|
|
74
|
-
promise = this._put(value).then((v) => {
|
|
75
|
-
this._putPromise.delete(value.hash);
|
|
76
|
-
return v;
|
|
77
|
-
});
|
|
78
|
-
this._putPromise.set(value.hash, promise);
|
|
79
|
-
return promise;
|
|
67
|
+
put(value: Entry<T>) {
|
|
68
|
+
return this._put(value);
|
|
80
69
|
}
|
|
81
|
-
|
|
70
|
+
_put(value: Entry<T>) {
|
|
82
71
|
// assume we want to insert at head (or somehere close)
|
|
83
72
|
let walker = this._values.head;
|
|
84
73
|
let last: EntryNode | undefined = undefined;
|
|
85
74
|
while (walker) {
|
|
86
|
-
const walkerValue =
|
|
75
|
+
const walkerValue = this._entryIndex.getShallow(walker.value);
|
|
87
76
|
if (!walkerValue) {
|
|
88
77
|
throw new Error("Missing walker value");
|
|
89
78
|
}
|
|
@@ -167,7 +156,7 @@ function _insertAfter(
|
|
|
167
156
|
null as any,
|
|
168
157
|
self.head as EntryNode | undefined,
|
|
169
158
|
self
|
|
170
|
-
|
|
159
|
+
)
|
|
171
160
|
: new yallist.Node(value, node, node.next as EntryNode | undefined, self);
|
|
172
161
|
|
|
173
162
|
// is tail
|