nostr-idb 3.0.0 → 4.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.
Files changed (50) hide show
  1. package/README.md +0 -3
  2. package/package.json +22 -13
  3. package/dist/cache/index-cache.d.ts +0 -27
  4. package/dist/cache/index-cache.js +0 -106
  5. package/dist/cache/index.d.ts +0 -2
  6. package/dist/cache/index.js +0 -2
  7. package/dist/cache/write-queue.d.ts +0 -21
  8. package/dist/cache/write-queue.js +0 -70
  9. package/dist/database/common.d.ts +0 -9
  10. package/dist/database/common.js +0 -27
  11. package/dist/database/database.d.ts +0 -10
  12. package/dist/database/database.js +0 -72
  13. package/dist/database/delete.d.ts +0 -61
  14. package/dist/database/delete.js +0 -154
  15. package/dist/database/index.d.ts +0 -8
  16. package/dist/database/index.js +0 -8
  17. package/dist/database/insert.d.ts +0 -6
  18. package/dist/database/insert.js +0 -45
  19. package/dist/database/prune.d.ts +0 -8
  20. package/dist/database/prune.js +0 -40
  21. package/dist/database/query-filter.d.ts +0 -24
  22. package/dist/database/query-filter.js +0 -233
  23. package/dist/database/query-misc.d.ts +0 -14
  24. package/dist/database/query-misc.js +0 -56
  25. package/dist/database/schema.d.ts +0 -31
  26. package/dist/database/schema.js +0 -1
  27. package/dist/debug.d.ts +0 -2
  28. package/dist/debug.js +0 -2
  29. package/dist/index.d.ts +0 -3
  30. package/dist/index.js +0 -3
  31. package/dist/lib/nanoid.d.ts +0 -1
  32. package/dist/lib/nanoid.js +0 -17
  33. package/dist/nostrdb/index.d.ts +0 -2
  34. package/dist/nostrdb/index.js +0 -2
  35. package/dist/nostrdb/interface.d.ts +0 -41
  36. package/dist/nostrdb/interface.js +0 -6
  37. package/dist/nostrdb/nostrdb.d.ts +0 -84
  38. package/dist/nostrdb/nostrdb.js +0 -276
  39. package/dist/utils.d.ts +0 -3
  40. package/dist/utils.js +0 -4
  41. package/dist/worker/index.d.ts +0 -25
  42. package/dist/worker/index.js +0 -72
  43. package/dist/worker/shared.d.ts +0 -1
  44. package/dist/worker/shared.js +0 -16
  45. package/dist/worker/shared.js.map +0 -7
  46. package/dist/worker/utils.d.ts +0 -86
  47. package/dist/worker/utils.js +0 -254
  48. package/dist/worker/worker.d.ts +0 -1
  49. package/dist/worker/worker.js +0 -16
  50. package/dist/worker/worker.js.map +0 -7
package/README.md CHANGED
@@ -9,8 +9,6 @@ Live Examples: https://hzrd149.github.io/nostr-idb/
9
9
  - [openDB](#openDB)
10
10
  - [clearDB](#clearDB)
11
11
  - [deleteDB](#deleteDB)
12
- - [nostr-tools](#nostr-tools)
13
- - [CacheRelay](#CacheRelay)
14
12
  - [Performance](#Performance)
15
13
 
16
14
  ## Features
@@ -18,7 +16,6 @@ Live Examples: https://hzrd149.github.io/nostr-idb/
18
16
  - Built directly on top of IndexedDB for the lowest latency
19
17
  - Caches indexes in memory
20
18
  - `NostrIDB` class with full nostr relay-like API
21
- - `CacheRelay` class with similar API to nostr-tool `Relay` class
22
19
 
23
20
  ## NostrIDB Class
24
21
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nostr-idb",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "description": "A collection of helper methods for storing nostr events in IndexedDB",
5
5
  "author": "hzrd149",
6
6
  "license": "MIT",
@@ -30,20 +30,25 @@
30
30
  }
31
31
  },
32
32
  "dependencies": {
33
- "debug": "^4.3.6",
34
- "idb": "^8.0.0",
35
- "nostr-tools": "~2.17.0"
33
+ "debug": "^4.4.3",
34
+ "idb": "^8.0.3",
35
+ "nostr-tools": "~2.17.2"
36
36
  },
37
37
  "devDependencies": {
38
- "@changesets/cli": "^2.27.7",
39
- "@sveltejs/vite-plugin-svelte": "^3.1.1",
40
- "@tsconfig/svelte": "^5.0.4",
38
+ "@changesets/cli": "^2.29.7",
39
+ "@sveltejs/vite-plugin-svelte": "^3.1.2",
40
+ "@tsconfig/svelte": "^5.0.6",
41
41
  "@types/debug": "^4.1.12",
42
- "esbuild": "^0.25.10",
43
- "prettier": "^3.3.3",
44
- "svelte": "^4.2.18",
45
- "typescript": "^5.5.4",
46
- "vite": "^5.3.5"
42
+ "@types/node": "^24.10.1",
43
+ "@vitest/coverage-v8": "4.0.9",
44
+ "@vitest/ui": "^4.0.9",
45
+ "esbuild": "^0.25.12",
46
+ "fake-indexeddb": "^6.2.5",
47
+ "prettier": "^3.6.2",
48
+ "svelte": "^4.2.20",
49
+ "typescript": "^5.9.3",
50
+ "vite": "^5.4.21",
51
+ "vitest": "^4.0.9"
47
52
  },
48
53
  "funding": {
49
54
  "type": "lightning",
@@ -54,6 +59,10 @@
54
59
  "prebuild": "rm -rf dist",
55
60
  "build": "tsc && node build.js",
56
61
  "build:examples": "vite build && cp examples/index.html public/index.html",
57
- "format": "prettier -w ."
62
+ "format": "prettier -w .",
63
+ "test": "vitest",
64
+ "test:ui": "vitest --ui",
65
+ "test:run": "vitest run",
66
+ "test:coverage": "vitest run --coverage"
58
67
  }
59
68
  }
@@ -1,27 +0,0 @@
1
- import type { NostrEvent } from "nostr-tools/pure";
2
- declare class Index<T> extends Set<string> {
3
- type: "kind" | "pubkey" | "tag";
4
- key: T;
5
- constructor(values: Iterable<string> | null, type: "kind" | "pubkey" | "tag", key: T);
6
- }
7
- /** In-memory cache for indexes of events */
8
- export declare class IndexCache {
9
- kinds: Map<number, Index<number>>;
10
- pubkeys: Map<string, Index<string>>;
11
- tags: Map<string, Index<string>>;
12
- get count(): number;
13
- max: number;
14
- lastUsed: Index<any>[];
15
- private useIndex;
16
- getKindIndex(kind: number): Index<number> | undefined;
17
- setKindIndex(kind: number, uids: Iterable<string>): void;
18
- getPubkeyIndex(pubkey: string): Index<string> | undefined;
19
- setPubkeyIndex(pubkey: string, uids: Iterable<string>): void;
20
- getTagIndex(tagAndValue: string): Index<string> | undefined;
21
- setTagIndex(tagAndValue: string, uids: Iterable<string>): void;
22
- addEventToIndexes(event: NostrEvent): void;
23
- removeEvent(event: NostrEvent): void;
24
- clear(): void;
25
- pruneIndexes(): void;
26
- }
27
- export {};
@@ -1,106 +0,0 @@
1
- import { logger } from "../debug.js";
2
- import { getEventTags } from "../database/common.js";
3
- const log = logger.extend("cache:indexes");
4
- class Index extends Set {
5
- type;
6
- key;
7
- constructor(values, type, key) {
8
- super(values);
9
- this.type = type;
10
- this.key = key;
11
- }
12
- }
13
- /** In-memory cache for indexes of events */
14
- export class IndexCache {
15
- kinds = new Map();
16
- pubkeys = new Map();
17
- tags = new Map();
18
- get count() {
19
- return this.kinds.size + this.pubkeys.size + this.tags.size;
20
- }
21
- max = 1000;
22
- lastUsed = [];
23
- useIndex(index) {
24
- const i = this.lastUsed.indexOf(index);
25
- if (i !== -1)
26
- this.lastUsed.splice(i, i + 1);
27
- this.lastUsed.push(index);
28
- }
29
- getKindIndex(kind) {
30
- const index = this.kinds.get(kind);
31
- if (index)
32
- this.useIndex(index);
33
- return index;
34
- }
35
- setKindIndex(kind, uids) {
36
- const index = new Index(uids, "kind", kind);
37
- this.kinds.set(kind, index);
38
- this.useIndex(index);
39
- this.pruneIndexes();
40
- }
41
- getPubkeyIndex(pubkey) {
42
- const index = this.pubkeys.get(pubkey);
43
- if (index)
44
- this.useIndex(index);
45
- return index;
46
- }
47
- setPubkeyIndex(pubkey, uids) {
48
- const index = new Index(uids, "pubkey", pubkey);
49
- this.pubkeys.set(pubkey, index);
50
- this.useIndex(index);
51
- this.pruneIndexes();
52
- }
53
- getTagIndex(tagAndValue) {
54
- const index = this.tags.get(tagAndValue);
55
- if (index)
56
- this.useIndex(index);
57
- return index;
58
- }
59
- setTagIndex(tagAndValue, uids) {
60
- const index = new Index(uids, "tag", tagAndValue);
61
- this.tags.set(tagAndValue, index);
62
- this.useIndex(index);
63
- this.pruneIndexes();
64
- }
65
- addEventToIndexes(event) {
66
- this.getKindIndex(event.kind)?.add(event.id);
67
- this.getPubkeyIndex(event.pubkey)?.add(event.id);
68
- const tags = getEventTags(event);
69
- for (const tag of tags) {
70
- this.getTagIndex(tag)?.add(event.id);
71
- }
72
- }
73
- removeEvent(event) {
74
- this.getKindIndex(event.kind)?.delete(event.id);
75
- this.getPubkeyIndex(event.pubkey)?.delete(event.id);
76
- const tags = getEventTags(event);
77
- for (const tag of tags) {
78
- this.getTagIndex(tag)?.delete(event.id);
79
- }
80
- }
81
- clear() {
82
- this.kinds.clear();
83
- this.pubkeys.clear();
84
- this.tags.clear();
85
- this.lastUsed = [];
86
- }
87
- pruneIndexes() {
88
- while (this.lastUsed.length > 0 && this.lastUsed.length > this.max) {
89
- const index = this.lastUsed.shift();
90
- if (!index)
91
- return;
92
- log(`Forgetting ${index.type}:${index.key}`);
93
- switch (index.type) {
94
- case "kind":
95
- this.kinds.delete(index.key);
96
- break;
97
- case "pubkey":
98
- this.pubkeys.delete(index.key);
99
- break;
100
- case "tag":
101
- this.tags.delete(index.key);
102
- break;
103
- }
104
- }
105
- }
106
- }
@@ -1,2 +0,0 @@
1
- export * from "./write-queue.js";
2
- export * from "./index-cache.js";
@@ -1,2 +0,0 @@
1
- export * from "./write-queue.js";
2
- export * from "./index-cache.js";
@@ -1,21 +0,0 @@
1
- import type { NostrEvent } from "nostr-tools/pure";
2
- import { type Filter } from "nostr-tools/filter";
3
- import { NostrIDBDatabase } from "../database/schema.js";
4
- /** A queue of events to be written to the database */
5
- export declare class WriteQueue {
6
- db: NostrIDBDatabase;
7
- private queuedIds;
8
- private eventQueue;
9
- private lastUsedQueue;
10
- /** Called for each chunk of events before they are written to the database */
11
- processEvents: ((events: NostrEvent[]) => Promise<NostrEvent[] | void>) | null;
12
- constructor(db: NostrIDBDatabase);
13
- addEvent(event: NostrEvent): void;
14
- addEvents(events: NostrEvent[]): void;
15
- touch(event: NostrEvent | NostrEvent[]): void;
16
- matchPending(filters: Filter[]): import("nostr-tools/core").Event[];
17
- /** Write all events in the queue to the database */
18
- flush(count?: number): Promise<void>;
19
- /** Clear the queue */
20
- clear(): void;
21
- }
@@ -1,70 +0,0 @@
1
- import { matchFilters } from "nostr-tools/filter";
2
- import { addEvents, updateUsed, getEventUID } from "../database/index.js";
3
- import { logger } from "../debug.js";
4
- const log = logger.extend("WriteQueue");
5
- /** A queue of events to be written to the database */
6
- export class WriteQueue {
7
- db;
8
- queuedIds = new Set();
9
- eventQueue = [];
10
- lastUsedQueue = new Set();
11
- /** Called for each chunk of events before they are written to the database */
12
- processEvents = null;
13
- constructor(db) {
14
- this.db = db;
15
- }
16
- addEvent(event) {
17
- if (this.queuedIds.has(event.id))
18
- return;
19
- this.eventQueue.push(event);
20
- this.queuedIds.add(event.id);
21
- this.touch(event);
22
- }
23
- addEvents(events) {
24
- const arr = events.filter((e) => !this.queuedIds.has(e.id));
25
- if (arr.length === 0)
26
- return;
27
- this.eventQueue.push(...arr);
28
- this.touch(arr);
29
- }
30
- touch(event) {
31
- if (Array.isArray(event)) {
32
- for (const e of event)
33
- this.lastUsedQueue.add(getEventUID(e));
34
- }
35
- else {
36
- this.lastUsedQueue.add(getEventUID(event));
37
- }
38
- }
39
- matchPending(filters) {
40
- return this.eventQueue.filter((e) => matchFilters(filters, e));
41
- }
42
- /** Write all events in the queue to the database */
43
- async flush(count = 1000) {
44
- if (this.eventQueue.length > 0) {
45
- let events = [];
46
- for (let i = 0; i < count; i++) {
47
- const event = this.eventQueue.shift();
48
- if (!event)
49
- break;
50
- events.push(event);
51
- this.queuedIds.delete(event.id);
52
- }
53
- if (this.processEvents) {
54
- events = (await this.processEvents(events)) || events;
55
- }
56
- await addEvents(this.db, events);
57
- log(`Wrote ${events.length} to database`);
58
- if (this.eventQueue.length > 0)
59
- log(`${this.eventQueue.length} left`);
60
- }
61
- if (this.lastUsedQueue.size > 0) {
62
- await updateUsed(this.db, this.lastUsedQueue);
63
- this.lastUsedQueue.clear();
64
- }
65
- }
66
- /** Clear the queue */
67
- clear() {
68
- this.eventQueue = [];
69
- }
70
- }
@@ -1,9 +0,0 @@
1
- import { type NostrEvent } from "nostr-tools/pure";
2
- /** An array of common indexable tags */
3
- export declare const INDEXABLE_TAGS: string[];
4
- /** Cashing symbol for event UID */
5
- export declare const EventUIDSymbol: unique symbol;
6
- /** Returns an events tags as an array of string for indexing */
7
- export declare function getEventTags(event: NostrEvent): string[];
8
- /** Returns the events Unique ID */
9
- export declare function getEventUID(event: NostrEvent): string;
@@ -1,27 +0,0 @@
1
- import { isAddressableKind, isReplaceableKind } from "nostr-tools/kinds";
2
- const LETTERS = "abcdefghijklmnopqrstuvwxyz";
3
- /** An array of common indexable tags */
4
- export const INDEXABLE_TAGS = (LETTERS + LETTERS.toUpperCase()).split("");
5
- /** Cashing symbol for event UID */
6
- export const EventUIDSymbol = Symbol.for("event-uid");
7
- /** Returns an events tags as an array of string for indexing */
8
- export function getEventTags(event) {
9
- return event.tags
10
- .filter((t) => t.length >= 2 && t[0].length === 1 && INDEXABLE_TAGS.includes(t[0]))
11
- .map((t) => t[0] + t[1]);
12
- }
13
- /** Returns the events Unique ID */
14
- export function getEventUID(event) {
15
- if (Reflect.has(event, EventUIDSymbol))
16
- return Reflect.get(event, EventUIDSymbol);
17
- let uid;
18
- if (isReplaceableKind(event.kind) || isAddressableKind(event.kind)) {
19
- const d = event.tags.find((t) => t[0] === "d")?.[1];
20
- uid = "" + event.kind + ":" + event.pubkey + ":" + (d ?? "");
21
- }
22
- else {
23
- uid = event.id;
24
- }
25
- Reflect.set(event, EventUIDSymbol, uid);
26
- return uid;
27
- }
@@ -1,10 +0,0 @@
1
- import { DeleteDBCallbacks, OpenDBCallbacks } from "idb";
2
- import { NostrIDBDatabase, Schema } from "./schema.js";
3
- export declare const NOSTR_IDB_NAME = "nostr-idb";
4
- export declare const NOSTR_IDB_VERSION = 3;
5
- /** Open a database with the given name and version */
6
- export declare function openDB(name?: string, callbacks?: OpenDBCallbacks<Schema>): Promise<NostrIDBDatabase>;
7
- /** Delete a database with the given name and version */
8
- export declare function deleteDB(name?: string, callbacks?: DeleteDBCallbacks): Promise<void>;
9
- /** Clear all events and used from the database */
10
- export declare function clearDB(db: NostrIDBDatabase): Promise<void>;
@@ -1,72 +0,0 @@
1
- import { deleteDB as idbDeleteDB, openDB as idbOpenDB, } from "idb";
2
- import { isAddressableKind, isReplaceableKind } from "nostr-tools/kinds";
3
- import { getEventUID } from "./common.js";
4
- export const NOSTR_IDB_NAME = "nostr-idb";
5
- export const NOSTR_IDB_VERSION = 3;
6
- /** Open a database with the given name and version */
7
- export async function openDB(name = NOSTR_IDB_NAME, callbacks) {
8
- return await idbOpenDB(name, NOSTR_IDB_VERSION, {
9
- ...callbacks,
10
- async upgrade(db, oldVersion, newVersion, transaction, event) {
11
- if (oldVersion === 0) {
12
- const events = db.createObjectStore("events");
13
- events.createIndex("id", "event.id", { unique: true });
14
- events.createIndex("pubkey", "event.pubkey");
15
- events.createIndex("kind", "event.kind");
16
- events.createIndex("created_at", "event.created_at");
17
- events.createIndex("tags", "tags", { multiEntry: true });
18
- const used = db.createObjectStore("used", { keyPath: "uid" });
19
- used.createIndex("date", "date");
20
- }
21
- // Migrate from v1 to v2
22
- if (oldVersion === 1) {
23
- db.deleteObjectStore("events");
24
- db.deleteObjectStore("used");
25
- // @ts-ignore
26
- db.deleteObjectStore("seen");
27
- }
28
- // Migrate replaceable event UIDs for v3
29
- if (oldVersion <= 2)
30
- await migrateReplaceableEventUIDs(transaction);
31
- if (callbacks?.upgrade)
32
- callbacks.upgrade(db, oldVersion, newVersion, transaction, event);
33
- },
34
- });
35
- }
36
- /** Delete a database with the given name and version */
37
- export async function deleteDB(name = NOSTR_IDB_NAME, callbacks) {
38
- return await idbDeleteDB(name, callbacks);
39
- }
40
- /** Clear all events and used from the database */
41
- export async function clearDB(db) {
42
- await db.clear("events");
43
- await db.clear("used");
44
- }
45
- /** Migrate replaceable event UIDs for v3 */
46
- async function migrateReplaceableEventUIDs(transaction) {
47
- const objectStore = transaction.objectStore("events");
48
- let cursor = await objectStore.openCursor();
49
- const eventsToMigrate = [];
50
- // First pass: collect all events that need migration
51
- while (cursor) {
52
- const oldKey = cursor.primaryKey;
53
- const record = cursor.value;
54
- const event = record.event;
55
- // Check if this is a replaceable event that needs migration
56
- if (isReplaceableKind(event.kind) || isAddressableKind(event.kind)) {
57
- const newKey = getEventUID(event);
58
- // Only migrate if the key format has actually changed
59
- if (oldKey !== newKey) {
60
- eventsToMigrate.push({ oldKey, newKey, value: record });
61
- }
62
- }
63
- cursor = await cursor.continue();
64
- }
65
- // Second pass: perform the migration
66
- for (const { oldKey, newKey, value } of eventsToMigrate) {
67
- // Remove the old entry
68
- await objectStore.delete(oldKey);
69
- // Add it back with the new key
70
- await objectStore.put(value, newKey);
71
- }
72
- }
@@ -1,61 +0,0 @@
1
- import type { Filter } from "nostr-tools/filter";
2
- import { IndexCache } from "../cache/index-cache.js";
3
- import type { NostrIDBDatabase } from "./schema.js";
4
- /**
5
- * Delete a single event by its ID or UID
6
- * @param db - The database instance
7
- * @param eventId - The event ID or UID to delete
8
- * @param indexCache - Optional index cache to update
9
- * @returns Promise<boolean> - True if event was deleted, false if not found
10
- */
11
- export declare function deleteEvent(db: NostrIDBDatabase, eventId: string, indexCache?: IndexCache): Promise<boolean>;
12
- /**
13
- * Delete a replaceable event by pubkey and kind
14
- * @param db - The database instance
15
- * @param pubkey - The pubkey of the event author
16
- * @param kind - The kind of the replaceable event
17
- * @param identifier - Optional identifier for parameterized replaceable events
18
- * @param indexCache - Optional index cache to update
19
- * @returns Promise<boolean> - True if event was deleted, false if not found
20
- */
21
- export declare function deleteReplaceable(db: NostrIDBDatabase, pubkey: string, kind: number, identifier?: string, indexCache?: IndexCache): Promise<boolean>;
22
- /**
23
- * Delete all replaceable events for a given pubkey and kind
24
- * @param db - The database instance
25
- * @param pubkey - The pubkey of the event author
26
- * @param kind - The kind of the replaceable events
27
- * @param indexCache - Optional index cache to update
28
- * @returns Promise<number> - Number of events deleted
29
- */
30
- export declare function deleteAllReplaceable(db: NostrIDBDatabase, pubkey: string, kind: number, indexCache?: IndexCache): Promise<number>;
31
- /**
32
- * Delete events matching the given filter
33
- * @param db - The database instance
34
- * @param filter - The filter to match events for deletion
35
- * @param indexCache - Optional index cache to update
36
- * @returns Promise<number> - Number of events deleted
37
- */
38
- export declare function deleteByFilter(db: NostrIDBDatabase, filter: Filter, indexCache?: IndexCache): Promise<number>;
39
- /**
40
- * Delete events matching the given filters
41
- * @param db - The database instance
42
- * @param filters - Array of filters to match events for deletion
43
- * @param indexCache - Optional index cache to update
44
- * @returns Promise<number> - Number of events deleted
45
- */
46
- export declare function deleteByFilters(db: NostrIDBDatabase, filters: Filter[], indexCache?: IndexCache): Promise<number>;
47
- /**
48
- * Delete events by their IDs
49
- * @param db - The database instance
50
- * @param eventIds - Array of event IDs to delete
51
- * @param indexCache - Optional index cache to update
52
- * @returns Promise<number> - Number of events deleted
53
- */
54
- export declare function deleteEventsByIds(db: NostrIDBDatabase, eventIds: string[], indexCache?: IndexCache): Promise<number>;
55
- /**
56
- * Delete all events from the database
57
- * @param db - The database instance
58
- * @param indexCache - Optional index cache to clear
59
- * @returns Promise<void>
60
- */
61
- export declare function deleteAllEvents(db: NostrIDBDatabase, indexCache?: IndexCache): Promise<void>;
@@ -1,154 +0,0 @@
1
- import { isAddressableKind, isReplaceableKind } from "nostr-tools/kinds";
2
- import { getIdsForFilter, getIdsForFilters } from "./query-filter.js";
3
- /**
4
- * Delete a single event by its ID or UID
5
- * @param db - The database instance
6
- * @param eventId - The event ID or UID to delete
7
- * @param indexCache - Optional index cache to update
8
- * @returns Promise<boolean> - True if event was deleted, false if not found
9
- */
10
- export async function deleteEvent(db, eventId, indexCache) {
11
- const transaction = db.transaction("events", "readwrite");
12
- const objectStore = transaction.objectStore("events");
13
- // First check if the event exists
14
- const existingEvent = await objectStore.get(eventId);
15
- if (!existingEvent) {
16
- await transaction.commit();
17
- return false;
18
- }
19
- // Delete the event
20
- await objectStore.delete(eventId);
21
- await transaction.commit();
22
- // Update index cache if provided
23
- if (indexCache) {
24
- const event = existingEvent.event;
25
- indexCache.removeEvent(event);
26
- }
27
- return true;
28
- }
29
- /**
30
- * Delete a replaceable event by pubkey and kind
31
- * @param db - The database instance
32
- * @param pubkey - The pubkey of the event author
33
- * @param kind - The kind of the replaceable event
34
- * @param identifier - Optional identifier for parameterized replaceable events
35
- * @param indexCache - Optional index cache to update
36
- * @returns Promise<boolean> - True if event was deleted, false if not found
37
- */
38
- export async function deleteReplaceable(db, pubkey, kind, identifier, indexCache) {
39
- if (!isReplaceableKind(kind) && !isAddressableKind(kind)) {
40
- throw new Error(`Kind ${kind} is not replaceable`);
41
- }
42
- const uid = `${kind}:${pubkey}:${identifier ?? ""}`;
43
- return await deleteEvent(db, uid, indexCache);
44
- }
45
- /**
46
- * Delete all replaceable events for a given pubkey and kind
47
- * @param db - The database instance
48
- * @param pubkey - The pubkey of the event author
49
- * @param kind - The kind of the replaceable events
50
- * @param indexCache - Optional index cache to update
51
- * @returns Promise<number> - Number of events deleted
52
- */
53
- export async function deleteAllReplaceable(db, pubkey, kind, indexCache) {
54
- if (!isReplaceableKind(kind) && !isAddressableKind(kind)) {
55
- throw new Error(`Kind ${kind} is not replaceable`);
56
- }
57
- const transaction = db.transaction("events", "readwrite");
58
- const objectStore = transaction.objectStore("events");
59
- // Get all events for this pubkey and kind
60
- const pubkeyIndex = objectStore.index("pubkey");
61
- const kindIndex = objectStore.index("kind");
62
- const pubkeyEvents = await pubkeyIndex.getAllKeys(pubkey);
63
- const kindEvents = await kindIndex.getAllKeys(kind);
64
- // Find intersection of pubkey and kind events
65
- const matchingEvents = pubkeyEvents.filter((id) => kindEvents.includes(id));
66
- let deletedCount = 0;
67
- const eventsToDelete = [];
68
- // Collect events to delete and their data for cache update
69
- for (const uid of matchingEvents) {
70
- const eventData = await objectStore.get(uid);
71
- if (eventData) {
72
- eventsToDelete.push({ event: eventData.event, uid });
73
- await objectStore.delete(uid);
74
- deletedCount++;
75
- }
76
- }
77
- await transaction.commit();
78
- // Update index cache if provided
79
- if (indexCache && eventsToDelete.length > 0) {
80
- for (const { event } of eventsToDelete) {
81
- indexCache.removeEvent(event);
82
- }
83
- }
84
- return deletedCount;
85
- }
86
- /**
87
- * Delete events matching the given filter
88
- * @param db - The database instance
89
- * @param filter - The filter to match events for deletion
90
- * @param indexCache - Optional index cache to update
91
- * @returns Promise<number> - Number of events deleted
92
- */
93
- export async function deleteByFilter(db, filter, indexCache) {
94
- const eventIds = await getIdsForFilter(db, filter, indexCache);
95
- return await deleteEventsByIds(db, Array.from(eventIds), indexCache);
96
- }
97
- /**
98
- * Delete events matching the given filters
99
- * @param db - The database instance
100
- * @param filters - Array of filters to match events for deletion
101
- * @param indexCache - Optional index cache to update
102
- * @returns Promise<number> - Number of events deleted
103
- */
104
- export async function deleteByFilters(db, filters, indexCache) {
105
- const eventIds = await getIdsForFilters(db, filters, indexCache);
106
- return await deleteEventsByIds(db, Array.from(eventIds), indexCache);
107
- }
108
- /**
109
- * Delete events by their IDs
110
- * @param db - The database instance
111
- * @param eventIds - Array of event IDs to delete
112
- * @param indexCache - Optional index cache to update
113
- * @returns Promise<number> - Number of events deleted
114
- */
115
- export async function deleteEventsByIds(db, eventIds, indexCache) {
116
- if (eventIds.length === 0)
117
- return 0;
118
- const transaction = db.transaction("events", "readwrite");
119
- const objectStore = transaction.objectStore("events");
120
- let deletedCount = 0;
121
- const eventsToDelete = [];
122
- // Collect events to delete and their data for cache update
123
- for (const eventId of eventIds) {
124
- const eventData = await objectStore.get(eventId);
125
- if (eventData) {
126
- eventsToDelete.push(eventData.event);
127
- await objectStore.delete(eventId);
128
- deletedCount++;
129
- }
130
- }
131
- await transaction.commit();
132
- // Update index cache if provided
133
- if (indexCache && eventsToDelete.length > 0) {
134
- for (const event of eventsToDelete) {
135
- indexCache.removeEvent(event);
136
- }
137
- }
138
- return deletedCount;
139
- }
140
- /**
141
- * Delete all events from the database
142
- * @param db - The database instance
143
- * @param indexCache - Optional index cache to clear
144
- * @returns Promise<void>
145
- */
146
- export async function deleteAllEvents(db, indexCache) {
147
- const transaction = db.transaction("events", "readwrite");
148
- await transaction.objectStore("events").clear();
149
- await transaction.commit();
150
- // Clear index cache if provided
151
- if (indexCache) {
152
- indexCache.clear();
153
- }
154
- }
@@ -1,8 +0,0 @@
1
- export * from "./database.js";
2
- export * from "./query-filter.js";
3
- export * from "./query-misc.js";
4
- export * from "./insert.js";
5
- export * from "./prune.js";
6
- export * from "./schema.js";
7
- export * from "./common.js";
8
- export * from "./delete.js";
@@ -1,8 +0,0 @@
1
- export * from "./database.js";
2
- export * from "./query-filter.js";
3
- export * from "./query-misc.js";
4
- export * from "./insert.js";
5
- export * from "./prune.js";
6
- export * from "./schema.js";
7
- export * from "./common.js";
8
- export * from "./delete.js";
@@ -1,6 +0,0 @@
1
- import { type NostrEvent } from "nostr-tools/pure";
2
- import type { NostrIDBDatabase } from "./schema.js";
3
- /** Add events to the database */
4
- export declare function addEvents(db: NostrIDBDatabase, events: NostrEvent[]): Promise<void>;
5
- /** Update the last used timestamp of the given uids */
6
- export declare function updateUsed(db: NostrIDBDatabase, uids: Iterable<string>): Promise<void>;