nostr-idb 2.0.1 → 2.1.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.
- package/CHANGELOG.md +6 -0
- package/dist/cache/write-queue.d.ts +1 -0
- package/dist/cache/write-queue.js +12 -4
- package/dist/database/query-filter.d.ts +3 -3
- package/dist/database/query-filter.js +19 -6
- package/dist/relay/relay-core.d.ts +2 -0
- package/dist/relay/relay-core.js +9 -2
- package/dist/worker/shared.js +7552 -4
- package/dist/worker/worker.js +7549 -4
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import { matchFilters } from "nostr-tools";
|
|
2
2
|
import { addEvents, getEventUID, updateUsed } from "../database/ingest.js";
|
|
3
3
|
import { logger } from "../debug.js";
|
|
4
|
-
const log = logger.extend("
|
|
4
|
+
const log = logger.extend("writeQueue");
|
|
5
5
|
export class WriteQueue {
|
|
6
6
|
db;
|
|
7
|
+
queuedIds = new Set();
|
|
7
8
|
eventQueue = [];
|
|
8
9
|
lastUsedQueue = new Set();
|
|
9
10
|
constructor(db) {
|
|
10
11
|
this.db = db;
|
|
11
12
|
}
|
|
12
13
|
addEvent(event) {
|
|
14
|
+
if (this.queuedIds.has(event.id))
|
|
15
|
+
return;
|
|
13
16
|
this.eventQueue.push(event);
|
|
17
|
+
this.queuedIds.add(event.id);
|
|
14
18
|
this.useEvent(event);
|
|
15
19
|
}
|
|
16
20
|
addEvents(events) {
|
|
17
|
-
this.
|
|
18
|
-
|
|
21
|
+
const arr = events.filter((e) => !this.queuedIds.has(e.id));
|
|
22
|
+
if (arr.length === 0)
|
|
23
|
+
return;
|
|
24
|
+
this.eventQueue.push(...arr);
|
|
25
|
+
this.useEvents(arr);
|
|
19
26
|
}
|
|
20
27
|
useEvent(event) {
|
|
21
28
|
this.lastUsedQueue.add(getEventUID(event));
|
|
@@ -35,9 +42,10 @@ export class WriteQueue {
|
|
|
35
42
|
if (!event)
|
|
36
43
|
break;
|
|
37
44
|
events.push(event);
|
|
45
|
+
this.queuedIds.delete(event.id);
|
|
38
46
|
}
|
|
39
47
|
await addEvents(this.db, events);
|
|
40
|
-
log(`Wrote ${events.length} to database
|
|
48
|
+
log(`Wrote ${events.length} to database ${this.eventQueue.length} events left`);
|
|
41
49
|
}
|
|
42
50
|
if (this.lastUsedQueue.size > 0) {
|
|
43
51
|
await updateUsed(this.db, this.lastUsedQueue);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Event, Filter } from "nostr-tools";
|
|
1
|
+
import type { Event, Filter, NostrEvent } from "nostr-tools";
|
|
2
2
|
import type { NostrIDB } from "./schema.js";
|
|
3
3
|
import { IndexCache } from "../cache/index-cache.js";
|
|
4
4
|
export declare function queryForPubkeys(db: NostrIDB, authors?: Filter["authors"], indexCache?: IndexCache): Set<string> | Promise<Set<string>>;
|
|
@@ -7,7 +7,7 @@ export declare function queryForKinds(db: NostrIDB, kinds?: Filter["kinds"], ind
|
|
|
7
7
|
export declare function queryForTime(db: NostrIDB, since: number | undefined, until: number | undefined): Promise<string[]>;
|
|
8
8
|
export declare function getIdsForFilter(db: NostrIDB, filter: Filter, indexCache?: IndexCache): Promise<Set<string>>;
|
|
9
9
|
export declare function getIdsForFilters(db: NostrIDB, filters: Filter[], indexCache?: IndexCache): Promise<Set<string>>;
|
|
10
|
-
export declare function getEventsForFilter(db: NostrIDB, filter: Filter, indexCache?: IndexCache): Promise<Event[]>;
|
|
11
|
-
export declare function getEventsForFilters(db: NostrIDB, filters: Filter[], indexCache?: IndexCache): Promise<Event[]>;
|
|
10
|
+
export declare function getEventsForFilter(db: NostrIDB, filter: Filter, indexCache?: IndexCache, eventMap?: Map<string, NostrEvent>): Promise<Event[]>;
|
|
11
|
+
export declare function getEventsForFilters(db: NostrIDB, filters: Filter[], indexCache?: IndexCache, eventMap?: Map<string, NostrEvent>): Promise<Event[]>;
|
|
12
12
|
export declare function countEventsForFilter(db: NostrIDB, filter: Filter, indexCache?: IndexCache): Promise<number>;
|
|
13
13
|
export declare function countEventsForFilters(db: NostrIDB, filters: Filter[], indexCache?: IndexCache): Promise<number>;
|
|
@@ -174,12 +174,25 @@ export async function getIdsForFilters(db, filters, indexCache) {
|
|
|
174
174
|
}
|
|
175
175
|
return ids;
|
|
176
176
|
}
|
|
177
|
-
async function loadEventsByUID(db, uids, filters) {
|
|
177
|
+
async function loadEventsByUID(db, uids, filters, eventMap) {
|
|
178
178
|
const eventBuffer = [];
|
|
179
|
+
// load from in-memory event map
|
|
180
|
+
let remainingIds = [];
|
|
181
|
+
if (eventMap) {
|
|
182
|
+
for (const uid of uids) {
|
|
183
|
+
const event = eventMap.get(uid);
|
|
184
|
+
if (event)
|
|
185
|
+
eventBuffer.push(event);
|
|
186
|
+
else
|
|
187
|
+
remainingIds.push(uid);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else
|
|
191
|
+
remainingIds = uids;
|
|
179
192
|
const trans = db.transaction("events", "readonly");
|
|
180
193
|
const objectStore = trans.objectStore("events");
|
|
181
194
|
const handleEntry = (e) => e && eventBuffer.push(e.event);
|
|
182
|
-
const promises = Array.from(
|
|
195
|
+
const promises = Array.from(remainingIds).map((uid) => objectStore.get(uid).then(handleEntry));
|
|
183
196
|
trans.commit();
|
|
184
197
|
const sorted = await Promise.all(promises).then(() => eventBuffer.sort(sortByDate));
|
|
185
198
|
let minLimit = Infinity;
|
|
@@ -191,13 +204,13 @@ async function loadEventsByUID(db, uids, filters) {
|
|
|
191
204
|
sorted.length = minLimit;
|
|
192
205
|
return sorted;
|
|
193
206
|
}
|
|
194
|
-
export async function getEventsForFilter(db, filter, indexCache) {
|
|
207
|
+
export async function getEventsForFilter(db, filter, indexCache, eventMap) {
|
|
195
208
|
const ids = await getIdsForFilter(db, filter, indexCache);
|
|
196
|
-
return await loadEventsByUID(db, Array.from(ids), [filter]);
|
|
209
|
+
return await loadEventsByUID(db, Array.from(ids), [filter], eventMap);
|
|
197
210
|
}
|
|
198
|
-
export async function getEventsForFilters(db, filters, indexCache) {
|
|
211
|
+
export async function getEventsForFilters(db, filters, indexCache, eventMap) {
|
|
199
212
|
const ids = await getIdsForFilters(db, filters, indexCache);
|
|
200
|
-
return await loadEventsByUID(db, Array.from(ids), filters);
|
|
213
|
+
return await loadEventsByUID(db, Array.from(ids), filters, eventMap);
|
|
201
214
|
}
|
|
202
215
|
export async function countEventsForFilter(db, filter, indexCache) {
|
|
203
216
|
const ids = await getIdsForFilter(db, filter, indexCache);
|
|
@@ -29,6 +29,7 @@ export declare class RelayCore {
|
|
|
29
29
|
private writeInterval?;
|
|
30
30
|
private pruneInterval?;
|
|
31
31
|
get running(): boolean;
|
|
32
|
+
private eventMap;
|
|
32
33
|
private writeQueue;
|
|
33
34
|
private indexCache;
|
|
34
35
|
db: NostrIDB;
|
|
@@ -38,6 +39,7 @@ export declare class RelayCore {
|
|
|
38
39
|
stop(): Promise<void>;
|
|
39
40
|
publish(event: Event): Promise<string>;
|
|
40
41
|
count(filters: Filter[]): Promise<number>;
|
|
42
|
+
private addToEventMaps;
|
|
41
43
|
private executeSubscription;
|
|
42
44
|
subscribe(filters: Filter[], options: Partial<SubscriptionOptions>): Subscription;
|
|
43
45
|
unsubscribe(id: string): void;
|
package/dist/relay/relay-core.js
CHANGED
|
@@ -5,7 +5,7 @@ import { getEventsForFilters, countEventsForFilters, } from "../database/query-f
|
|
|
5
5
|
import { sortByDate } from "../utils.js";
|
|
6
6
|
import { nanoid } from "../lib/nanoid.js";
|
|
7
7
|
import { logger } from "../debug.js";
|
|
8
|
-
import { pruneLastUsed } from "../index.js";
|
|
8
|
+
import { getEventUID, pruneLastUsed } from "../index.js";
|
|
9
9
|
const defaultOptions = {
|
|
10
10
|
batchWrite: 1000,
|
|
11
11
|
writeInterval: 100,
|
|
@@ -22,6 +22,7 @@ export class RelayCore {
|
|
|
22
22
|
get running() {
|
|
23
23
|
return !!this.writeInterval;
|
|
24
24
|
}
|
|
25
|
+
eventMap = new Map();
|
|
25
26
|
writeQueue;
|
|
26
27
|
indexCache;
|
|
27
28
|
db;
|
|
@@ -57,6 +58,7 @@ export class RelayCore {
|
|
|
57
58
|
if (!kinds.isEphemeralKind(event.kind)) {
|
|
58
59
|
this.writeQueue.addEvent(event);
|
|
59
60
|
this.indexCache.addEventToIndexes(event);
|
|
61
|
+
this.eventMap.set(getEventUID(event), event);
|
|
60
62
|
}
|
|
61
63
|
let subs = 0;
|
|
62
64
|
for (const [id, sub] of this.subscriptions) {
|
|
@@ -70,13 +72,18 @@ export class RelayCore {
|
|
|
70
72
|
async count(filters) {
|
|
71
73
|
return await countEventsForFilters(this.db, filters);
|
|
72
74
|
}
|
|
75
|
+
addToEventMaps(events) {
|
|
76
|
+
for (const event of events)
|
|
77
|
+
this.eventMap.set(getEventUID(event), event);
|
|
78
|
+
}
|
|
73
79
|
async executeSubscription(sub) {
|
|
74
80
|
const start = new Date().valueOf();
|
|
75
81
|
log(`Running ${sub.id}`, sub.filters);
|
|
76
82
|
// load any events from the write queue
|
|
77
83
|
const eventsFromQueue = this.writeQueue.matchPending(sub.filters);
|
|
78
84
|
// get events
|
|
79
|
-
await getEventsForFilters(this.db, sub.filters, this.indexCache).then((filterEvents) => {
|
|
85
|
+
await getEventsForFilters(this.db, sub.filters, this.indexCache, this.eventMap).then((filterEvents) => {
|
|
86
|
+
this.addToEventMaps(filterEvents);
|
|
80
87
|
if (sub.onevent) {
|
|
81
88
|
const idsFromQueue = new Set(eventsFromQueue.map((e) => e.id));
|
|
82
89
|
const events = eventsFromQueue.length > 0
|