nostr-idb 0.2.0 → 1.0.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 +11 -0
- package/dist/database.d.ts +1 -1
- package/dist/database.js +11 -8
- package/dist/ingest.d.ts +4 -10
- package/dist/ingest.js +14 -24
- package/dist/query-filter.d.ts +3 -3
- package/dist/query-filter.js +36 -22
- package/dist/query-misc.d.ts +5 -2
- package/dist/query-misc.js +6 -7
- package/dist/relay.js +7 -4
- package/dist/schema.d.ts +4 -19
- package/dist/write-queue.d.ts +9 -5
- package/dist/write-queue.js +32 -14
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# nostr-idb
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 9bbdbc7: Upgrade nostr-tools to v2
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- 9bbdbc7: Support ephemeral events
|
|
12
|
+
- 446cb1e: Support replaceable and parameterized replaceable events
|
|
13
|
+
|
|
3
14
|
## 0.2.0
|
|
4
15
|
|
|
5
16
|
### Minor Changes
|
package/dist/database.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DeleteDBCallbacks, OpenDBCallbacks } from "idb";
|
|
2
2
|
import { NostrIDB, Schema } from "./schema.js";
|
|
3
3
|
export declare const NOSTR_IDB_NAME = "nostr-idb";
|
|
4
|
-
export declare const NOSTR_IDB_VERSION =
|
|
4
|
+
export declare const NOSTR_IDB_VERSION = 2;
|
|
5
5
|
export declare function openDB(name?: string, callbacks?: OpenDBCallbacks<Schema>): Promise<import("idb").IDBPDatabase<Schema>>;
|
|
6
6
|
export declare function deleteDB(name?: string, callbacks?: DeleteDBCallbacks): Promise<void>;
|
|
7
7
|
export declare function clearDB(db: NostrIDB): Promise<void>;
|
package/dist/database.js
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
import { deleteDB as idbDeleteDB, openDB as idbOpenDB, } from "idb";
|
|
2
2
|
export const NOSTR_IDB_NAME = "nostr-idb";
|
|
3
|
-
export const NOSTR_IDB_VERSION =
|
|
3
|
+
export const NOSTR_IDB_VERSION = 2;
|
|
4
4
|
export async function openDB(name = NOSTR_IDB_NAME, callbacks) {
|
|
5
5
|
return await idbOpenDB(name, NOSTR_IDB_VERSION, {
|
|
6
6
|
...callbacks,
|
|
7
7
|
upgrade(db, oldVersion, newVersion, transaction, event) {
|
|
8
|
-
|
|
8
|
+
if (oldVersion < 2) {
|
|
9
|
+
debugger;
|
|
10
|
+
console.log("resetting DB");
|
|
11
|
+
db.deleteObjectStore("events");
|
|
12
|
+
db.deleteObjectStore("used");
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
db.deleteObjectStore("seen");
|
|
15
|
+
}
|
|
16
|
+
const events = db.createObjectStore("events");
|
|
9
17
|
events.createIndex("id", "event.id", { unique: true });
|
|
10
18
|
events.createIndex("pubkey", "event.pubkey");
|
|
11
19
|
events.createIndex("kind", "event.kind");
|
|
12
20
|
events.createIndex("created_at", "event.created_at");
|
|
13
21
|
events.createIndex("tags", "tags", { multiEntry: true });
|
|
14
|
-
|
|
15
|
-
const seen = db.createObjectStore("seen", { keyPath: "id" });
|
|
16
|
-
seen.createIndex("date", "date");
|
|
17
|
-
seen.createIndex("relay", "relays", { multiEntry: true });
|
|
18
|
-
const used = db.createObjectStore("used", { keyPath: "id" });
|
|
22
|
+
const used = db.createObjectStore("used", { keyPath: "uid" });
|
|
19
23
|
used.createIndex("date", "date");
|
|
20
24
|
if (callbacks?.upgrade)
|
|
21
25
|
callbacks.upgrade(db, oldVersion, newVersion, transaction, event);
|
|
@@ -28,5 +32,4 @@ export async function deleteDB(name = NOSTR_IDB_NAME, callbacks) {
|
|
|
28
32
|
export async function clearDB(db) {
|
|
29
33
|
await db.clear("events");
|
|
30
34
|
await db.clear("used");
|
|
31
|
-
await db.clear("seen");
|
|
32
35
|
}
|
package/dist/ingest.d.ts
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import { IDBPTransaction } from "idb";
|
|
2
2
|
import { Event } from "nostr-tools";
|
|
3
3
|
import type { NostrIDB, Schema } from "./schema.js";
|
|
4
|
-
/**
|
|
5
|
-
* Returns an events tags as an array of string for indexing
|
|
6
|
-
*/
|
|
4
|
+
/** Returns an events tags as an array of string for indexing */
|
|
7
5
|
export declare function getEventTags(event: Event): string[];
|
|
8
|
-
|
|
9
|
-
export
|
|
10
|
-
kind: number;
|
|
11
|
-
pubkey: string;
|
|
12
|
-
identifier?: string;
|
|
13
|
-
};
|
|
6
|
+
/** returns the events Unique ID */
|
|
7
|
+
export declare function getEventUID(event: Event): string;
|
|
14
8
|
export declare function addEvent(db: NostrIDB, event: Event, transaction?: IDBPTransaction<Schema, ["events"], "readwrite">): Promise<void>;
|
|
15
9
|
export declare function addEvents(db: NostrIDB, events: Event[]): Promise<void>;
|
|
16
|
-
export declare function updateUsed(db: NostrIDB,
|
|
10
|
+
export declare function updateUsed(db: NostrIDB, uids: Iterable<string>): Promise<void>;
|
package/dist/ingest.js
CHANGED
|
@@ -1,28 +1,19 @@
|
|
|
1
|
-
import { validateEvent } from "nostr-tools";
|
|
1
|
+
import { kinds, validateEvent } from "nostr-tools";
|
|
2
2
|
import { GENERIC_TAGS } from "./common.js";
|
|
3
|
-
/**
|
|
4
|
-
* Returns an events tags as an array of string for indexing
|
|
5
|
-
*/
|
|
3
|
+
/** Returns an events tags as an array of string for indexing */
|
|
6
4
|
export function getEventTags(event) {
|
|
7
5
|
return event.tags
|
|
8
6
|
.filter((t) => t.length >= 2 && t[0].length === 1 && GENERIC_TAGS.includes(t[0]))
|
|
9
7
|
.map((t) => t[0] + t[1]);
|
|
10
8
|
}
|
|
11
|
-
|
|
12
|
-
export function
|
|
13
|
-
|
|
14
|
-
(kind
|
|
15
|
-
|
|
16
|
-
kind
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
function getReplaceableEventAddress(event) {
|
|
20
|
-
// only create addresses for replaceable events
|
|
21
|
-
if (!isReplaceable(event.kind))
|
|
22
|
-
return undefined;
|
|
23
|
-
// get d tag
|
|
24
|
-
const identifier = event.tags.find((t) => t[0] === "d" && t[1])?.[1];
|
|
25
|
-
return { kind: event.kind, pubkey: event.pubkey, identifier };
|
|
9
|
+
/** returns the events Unique ID */
|
|
10
|
+
export function getEventUID(event) {
|
|
11
|
+
if (kinds.isReplaceableKind(event.kind) ||
|
|
12
|
+
kinds.isParameterizedReplaceableKind(event.kind)) {
|
|
13
|
+
const d = event.tags.find((t) => t[0] === "d")?.[1];
|
|
14
|
+
return `${event.kind}:${event.pubkey}:${d ?? ""}`;
|
|
15
|
+
}
|
|
16
|
+
return event.id;
|
|
26
17
|
}
|
|
27
18
|
export async function addEvent(db, event, transaction) {
|
|
28
19
|
if (!validateEvent(event))
|
|
@@ -31,8 +22,7 @@ export async function addEvent(db, event, transaction) {
|
|
|
31
22
|
trans.objectStore("events").put({
|
|
32
23
|
event,
|
|
33
24
|
tags: getEventTags(event),
|
|
34
|
-
|
|
35
|
-
});
|
|
25
|
+
}, getEventUID(event));
|
|
36
26
|
if (!transaction)
|
|
37
27
|
await trans.commit();
|
|
38
28
|
}
|
|
@@ -43,12 +33,12 @@ export async function addEvents(db, events) {
|
|
|
43
33
|
}
|
|
44
34
|
await trans.commit();
|
|
45
35
|
}
|
|
46
|
-
export async function updateUsed(db,
|
|
36
|
+
export async function updateUsed(db, uids) {
|
|
47
37
|
const trans = db.transaction("used", "readwrite");
|
|
48
38
|
const nowUnix = Math.floor(new Date().valueOf() / 1000);
|
|
49
|
-
for (const
|
|
39
|
+
for (const uid of uids) {
|
|
50
40
|
trans.objectStore("used").put({
|
|
51
|
-
|
|
41
|
+
uid,
|
|
52
42
|
date: nowUnix,
|
|
53
43
|
});
|
|
54
44
|
}
|
package/dist/query-filter.d.ts
CHANGED
|
@@ -4,10 +4,10 @@ import { IndexCache } from "./index-cache";
|
|
|
4
4
|
export declare function queryForPubkeys(db: NostrIDB, authors?: Filter["authors"], indexCache?: IndexCache): Set<string> | Promise<Set<string>>;
|
|
5
5
|
export declare function queryForTag(db: NostrIDB, tag: string, values: string[], indexCache?: IndexCache): Set<string> | Promise<Set<string>>;
|
|
6
6
|
export declare function queryForKinds(db: NostrIDB, kinds?: Filter["kinds"], indexCache?: IndexCache): Set<string> | Promise<Set<string>>;
|
|
7
|
-
export declare function queryForTime(db: NostrIDB, since: number | undefined, until: number | undefined): Promise<
|
|
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): Promise<Event[]>;
|
|
11
|
+
export declare function getEventsForFilters(db: NostrIDB, filters: Filter[], indexCache?: IndexCache): 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>;
|
package/dist/query-filter.js
CHANGED
|
@@ -107,8 +107,7 @@ export async function queryForTime(db, since, until) {
|
|
|
107
107
|
range = IDBKeyRange.upperBound(until);
|
|
108
108
|
else
|
|
109
109
|
throw new Error("Missing since or until");
|
|
110
|
-
const
|
|
111
|
-
const ids = new Set(arr);
|
|
110
|
+
const ids = (await db.getAllKeysFromIndex("events", "created_at", range)).reverse();
|
|
112
111
|
return ids;
|
|
113
112
|
}
|
|
114
113
|
export async function getIdsForFilter(db, filter, indexCache) {
|
|
@@ -118,18 +117,22 @@ export async function getIdsForFilter(db, filter, indexCache) {
|
|
|
118
117
|
if (filter.ids)
|
|
119
118
|
return new Set(filter.ids);
|
|
120
119
|
let ids = null;
|
|
121
|
-
const and = (
|
|
120
|
+
const and = (iterable) => {
|
|
121
|
+
const set = iterable instanceof Set ? iterable : new Set(iterable);
|
|
122
122
|
if (!ids)
|
|
123
123
|
ids = set;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
else
|
|
125
|
+
for (const id of ids)
|
|
126
|
+
if (!set.has(id))
|
|
127
|
+
ids.delete(id);
|
|
128
128
|
return ids;
|
|
129
129
|
};
|
|
130
|
-
|
|
131
|
-
if
|
|
132
|
-
|
|
130
|
+
let timeFilterIds = null;
|
|
131
|
+
// query for time first if since is set
|
|
132
|
+
if (filter.since) {
|
|
133
|
+
timeFilterIds = await queryForTime(db, filter.since, filter.until);
|
|
134
|
+
and(timeFilterIds);
|
|
135
|
+
}
|
|
133
136
|
for (const t of GENERIC_TAGS) {
|
|
134
137
|
const key = `#${t}`;
|
|
135
138
|
const values = filter[key];
|
|
@@ -140,10 +143,22 @@ export async function getIdsForFilter(db, filter, indexCache) {
|
|
|
140
143
|
and(await queryForPubkeys(db, filter.authors, indexCache));
|
|
141
144
|
if (filter.kinds)
|
|
142
145
|
and(await queryForKinds(db, filter.kinds, indexCache));
|
|
143
|
-
// query for time last if only
|
|
144
|
-
if (
|
|
145
|
-
(filter.since
|
|
146
|
-
and(
|
|
146
|
+
// query for time last if only until is set
|
|
147
|
+
if (filter.since === undefined && filter.until) {
|
|
148
|
+
timeFilterIds = await queryForTime(db, filter.since, filter.until);
|
|
149
|
+
and(timeFilterIds);
|
|
150
|
+
}
|
|
151
|
+
// if the filter queried on time and has a limit. truncate the ids now
|
|
152
|
+
if (filter.limit && timeFilterIds) {
|
|
153
|
+
const limitIds = new Set();
|
|
154
|
+
for (const id of timeFilterIds) {
|
|
155
|
+
if (limitIds.size >= filter.limit)
|
|
156
|
+
break;
|
|
157
|
+
if (ids.has(id))
|
|
158
|
+
limitIds.add(id);
|
|
159
|
+
}
|
|
160
|
+
return limitIds;
|
|
161
|
+
}
|
|
147
162
|
if (ids === null)
|
|
148
163
|
throw new Error("Empty filter");
|
|
149
164
|
return ids;
|
|
@@ -165,15 +180,14 @@ export async function getIdsForFilters(db, filters, indexCache) {
|
|
|
165
180
|
throw new Error("Empty filters");
|
|
166
181
|
return ids;
|
|
167
182
|
}
|
|
168
|
-
async function
|
|
169
|
-
const
|
|
183
|
+
async function loadEventsByUID(db, uids, filters) {
|
|
184
|
+
const eventBuffer = [];
|
|
170
185
|
const trans = db.transaction("events", "readonly");
|
|
171
186
|
const objectStore = trans.objectStore("events");
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
const promises = Array.from(ids).map((id) => index.get(id).then(handleEntry));
|
|
175
|
-
const sorted = await Promise.all(promises).then(() => events.sort(sortByDate));
|
|
187
|
+
const handleEntry = (e) => e && eventBuffer.push(e.event);
|
|
188
|
+
const promises = Array.from(uids).map((uid) => objectStore.get(uid).then(handleEntry));
|
|
176
189
|
trans.commit();
|
|
190
|
+
const sorted = await Promise.all(promises).then(() => eventBuffer.sort(sortByDate));
|
|
177
191
|
let minLimit = Infinity;
|
|
178
192
|
for (const filter of filters) {
|
|
179
193
|
if (filter.limit && filter.limit < minLimit)
|
|
@@ -185,11 +199,11 @@ async function loadEventsById(db, ids, filters) {
|
|
|
185
199
|
}
|
|
186
200
|
export async function getEventsForFilter(db, filter, indexCache) {
|
|
187
201
|
const ids = await getIdsForFilter(db, filter, indexCache);
|
|
188
|
-
return await
|
|
202
|
+
return await loadEventsByUID(db, Array.from(ids), [filter]);
|
|
189
203
|
}
|
|
190
204
|
export async function getEventsForFilters(db, filters, indexCache) {
|
|
191
205
|
const ids = await getIdsForFilters(db, filters, indexCache);
|
|
192
|
-
return await
|
|
206
|
+
return await loadEventsByUID(db, Array.from(ids), filters);
|
|
193
207
|
}
|
|
194
208
|
export async function countEventsForFilter(db, filter, indexCache) {
|
|
195
209
|
const ids = await getIdsForFilter(db, filter, indexCache);
|
package/dist/query-misc.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { Event } from "nostr-tools";
|
|
2
2
|
import { NostrIDB } from "./schema.js";
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
export declare function getEventsFromAddressPointers(db: NostrIDB, pointers: {
|
|
4
|
+
kind: number;
|
|
5
|
+
pubkey: string;
|
|
6
|
+
identifier?: string;
|
|
7
|
+
}[]): Promise<Event[]>;
|
|
5
8
|
export declare function countEventsByPubkeys(db: NostrIDB): Promise<Record<string, number>>;
|
|
6
9
|
export declare function countEventsByKind(db: NostrIDB): Promise<Record<string, number>>;
|
|
7
10
|
export declare function countEvents(db: NostrIDB): Promise<number>;
|
package/dist/query-misc.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
export async function getEventsFromAddressPointers(db, pointers) {
|
|
2
2
|
const trans = db.transaction("events", "readonly");
|
|
3
|
-
const
|
|
3
|
+
const objectStore = trans.objectStore("events");
|
|
4
4
|
const events = {};
|
|
5
5
|
const promises = pointers.map(async (pointer) => {
|
|
6
|
-
const key =
|
|
7
|
-
const row = await
|
|
6
|
+
const key = `${pointer.kind}:${pointer.pubkey}:${pointer.identifier ?? ""}`;
|
|
7
|
+
const row = await objectStore.get(key);
|
|
8
8
|
if (row) {
|
|
9
|
-
const
|
|
10
|
-
const existing = events[keyStr];
|
|
9
|
+
const existing = events[key];
|
|
11
10
|
if (!existing || row.event.created_at > existing.created_at)
|
|
12
|
-
events[
|
|
11
|
+
events[key] = row.event;
|
|
13
12
|
}
|
|
14
13
|
});
|
|
15
|
-
const sorted = await Promise.all(promises).then(() => Object.values(events).sort((a, b) => b.created_at - a.created_at));
|
|
16
14
|
trans.commit();
|
|
15
|
+
const sorted = await Promise.all(promises).then(() => Object.values(events).sort((a, b) => b.created_at - a.created_at));
|
|
17
16
|
return sorted;
|
|
18
17
|
}
|
|
19
18
|
export async function countEventsByPubkeys(db) {
|
package/dist/relay.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { matchFilters } from "nostr-tools";
|
|
1
|
+
import { kinds, matchFilters } from "nostr-tools";
|
|
2
2
|
import { WriteQueue } from "./write-queue";
|
|
3
3
|
import { countEventsForFilters, getEventsForFilters } from "./query-filter";
|
|
4
4
|
import { sortByDate } from "./utils";
|
|
@@ -41,8 +41,10 @@ export class CacheRelay {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
async publish(event) {
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
if (!kinds.isEphemeralKind(event.kind)) {
|
|
45
|
+
this.writeQueue.addEvent(event);
|
|
46
|
+
this.indexCache.addEventToIndexes(event);
|
|
47
|
+
}
|
|
46
48
|
let subs = 0;
|
|
47
49
|
for (const { onevent, filters } of this.subscriptions) {
|
|
48
50
|
if (onevent && matchFilters(filters, event)) {
|
|
@@ -57,7 +59,7 @@ export class CacheRelay {
|
|
|
57
59
|
}
|
|
58
60
|
async executeSubscription(sub) {
|
|
59
61
|
// load any events from the write queue
|
|
60
|
-
const eventsFromQueue = this.writeQueue.
|
|
62
|
+
const eventsFromQueue = this.writeQueue.matchPending(sub.filters);
|
|
61
63
|
// get events
|
|
62
64
|
await getEventsForFilters(this.db, sub.filters, this.indexCache).then((filterEvents) => {
|
|
63
65
|
if (sub.onevent) {
|
|
@@ -70,6 +72,7 @@ export class CacheRelay {
|
|
|
70
72
|
: filterEvents;
|
|
71
73
|
for (const event of events) {
|
|
72
74
|
sub.onevent(event);
|
|
75
|
+
this.writeQueue.useEvent(event);
|
|
73
76
|
}
|
|
74
77
|
}
|
|
75
78
|
if (sub.oneose)
|
package/dist/schema.d.ts
CHANGED
|
@@ -3,11 +3,10 @@ import type { Event } from "nostr-tools";
|
|
|
3
3
|
export type NostrIDB = IDBPDatabase<Schema>;
|
|
4
4
|
export interface Schema extends DBSchema {
|
|
5
5
|
events: {
|
|
6
|
-
key:
|
|
6
|
+
key: string;
|
|
7
7
|
value: {
|
|
8
8
|
event: Event;
|
|
9
9
|
tags: string[];
|
|
10
|
-
identifier?: string;
|
|
11
10
|
};
|
|
12
11
|
indexes: {
|
|
13
12
|
id: string;
|
|
@@ -15,30 +14,16 @@ export interface Schema extends DBSchema {
|
|
|
15
14
|
kind: number;
|
|
16
15
|
created_at: number;
|
|
17
16
|
tags: string;
|
|
18
|
-
addressPointer: [number, string, string | undefined];
|
|
19
|
-
};
|
|
20
|
-
};
|
|
21
|
-
seen: {
|
|
22
|
-
key: "id";
|
|
23
|
-
value: {
|
|
24
|
-
id: string;
|
|
25
|
-
date: number;
|
|
26
|
-
relays: string[];
|
|
27
|
-
};
|
|
28
|
-
indexes: {
|
|
29
|
-
id: string;
|
|
30
|
-
date: string;
|
|
31
|
-
relay: string;
|
|
32
17
|
};
|
|
33
18
|
};
|
|
34
19
|
used: {
|
|
35
|
-
key:
|
|
20
|
+
key: string;
|
|
36
21
|
value: {
|
|
37
|
-
|
|
22
|
+
uid: string;
|
|
38
23
|
date: number;
|
|
39
24
|
};
|
|
40
25
|
indexes: {
|
|
41
|
-
|
|
26
|
+
uid: string;
|
|
42
27
|
date: string;
|
|
43
28
|
};
|
|
44
29
|
};
|
package/dist/write-queue.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Filter, type NostrEvent } from "nostr-tools";
|
|
2
2
|
import { NostrIDB } from "./schema";
|
|
3
3
|
export declare class WriteQueue {
|
|
4
4
|
db: NostrIDB;
|
|
5
|
-
|
|
5
|
+
private eventQueue;
|
|
6
|
+
private lastUsedQueue;
|
|
6
7
|
constructor(db: NostrIDB);
|
|
7
|
-
addEvent(event:
|
|
8
|
-
addEvents(events:
|
|
9
|
-
|
|
8
|
+
addEvent(event: NostrEvent): void;
|
|
9
|
+
addEvents(events: NostrEvent[]): void;
|
|
10
|
+
useEvent(event: NostrEvent): void;
|
|
11
|
+
useEvents(events: NostrEvent[]): void;
|
|
12
|
+
matchPending(filters: Filter[]): import("nostr-tools").Event[];
|
|
13
|
+
flush(count?: number): Promise<void>;
|
|
10
14
|
clear(): void;
|
|
11
15
|
}
|
package/dist/write-queue.js
CHANGED
|
@@ -1,29 +1,47 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { matchFilters } from "nostr-tools";
|
|
2
|
+
import { addEvents, getEventUID, updateUsed } from "./ingest";
|
|
2
3
|
export class WriteQueue {
|
|
3
4
|
db;
|
|
4
|
-
|
|
5
|
+
eventQueue = [];
|
|
6
|
+
lastUsedQueue = new Set();
|
|
5
7
|
constructor(db) {
|
|
6
8
|
this.db = db;
|
|
7
9
|
}
|
|
8
10
|
addEvent(event) {
|
|
9
|
-
this.
|
|
11
|
+
this.eventQueue.push(event);
|
|
10
12
|
}
|
|
11
13
|
addEvents(events) {
|
|
12
|
-
this.
|
|
14
|
+
this.eventQueue.push(...events);
|
|
15
|
+
}
|
|
16
|
+
useEvent(event) {
|
|
17
|
+
this.lastUsedQueue.add(getEventUID(event));
|
|
18
|
+
}
|
|
19
|
+
useEvents(events) {
|
|
20
|
+
for (const event of events)
|
|
21
|
+
this.lastUsedQueue.add(getEventUID(event));
|
|
22
|
+
}
|
|
23
|
+
matchPending(filters) {
|
|
24
|
+
return this.eventQueue.filter((e) => matchFilters(filters, e));
|
|
13
25
|
}
|
|
14
26
|
async flush(count = 1000) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
if (this.eventQueue.length > 0) {
|
|
28
|
+
const events = [];
|
|
29
|
+
for (let i = 0; i < count; i++) {
|
|
30
|
+
const event = this.eventQueue.shift();
|
|
31
|
+
if (!event)
|
|
32
|
+
break;
|
|
33
|
+
events.push(event);
|
|
34
|
+
}
|
|
35
|
+
await addEvents(this.db, events);
|
|
36
|
+
}
|
|
37
|
+
if (this.lastUsedQueue.size > 0) {
|
|
38
|
+
console.time("Save Used");
|
|
39
|
+
await updateUsed(this.db, this.lastUsedQueue);
|
|
40
|
+
console.timeEnd("Save Used");
|
|
41
|
+
this.lastUsedQueue.clear();
|
|
21
42
|
}
|
|
22
|
-
await addEvents(this.db, events);
|
|
23
|
-
await updateUsed(this.db, events.map((e) => e.id));
|
|
24
|
-
return events.length;
|
|
25
43
|
}
|
|
26
44
|
clear() {
|
|
27
|
-
this.
|
|
45
|
+
this.eventQueue = [];
|
|
28
46
|
}
|
|
29
47
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nostr-idb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "A collection of helper methods for storing nostr events in IndexedDB",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "hzrd149"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"idb": "^8.0.0",
|
|
27
|
-
"nostr-tools": "^1.
|
|
27
|
+
"nostr-tools": "^2.1.3"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@changesets/cli": "^2.27.1",
|