applesauce-core 0.0.0-next-20250120191411 → 0.0.0-next-20250123214405

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 (115) hide show
  1. package/package.json +1 -1
  2. package/dist/event-store/common.d.ts +0 -1
  3. package/dist/event-store/common.js +0 -2
  4. package/dist/event-store/database.d.ts +0 -64
  5. package/dist/event-store/database.js +0 -311
  6. package/dist/event-store/event-store.d.ts +0 -49
  7. package/dist/event-store/event-store.js +0 -389
  8. package/dist/event-store/index.d.ts +0 -2
  9. package/dist/event-store/index.js +0 -2
  10. package/dist/helpers/bolt11.d.ts +0 -9
  11. package/dist/helpers/bolt11.js +0 -15
  12. package/dist/helpers/cache.d.ts +0 -5
  13. package/dist/helpers/cache.js +0 -17
  14. package/dist/helpers/comment.d.ts +0 -47
  15. package/dist/helpers/comment.js +0 -116
  16. package/dist/helpers/content.d.ts +0 -3
  17. package/dist/helpers/content.js +0 -8
  18. package/dist/helpers/delete.d.ts +0 -3
  19. package/dist/helpers/delete.js +0 -7
  20. package/dist/helpers/emoji.d.ts +0 -11
  21. package/dist/helpers/emoji.js +0 -16
  22. package/dist/helpers/event.d.ts +0 -48
  23. package/dist/helpers/event.js +0 -105
  24. package/dist/helpers/external-id.d.ts +0 -29
  25. package/dist/helpers/external-id.js +0 -20
  26. package/dist/helpers/file-metadata.d.ts +0 -53
  27. package/dist/helpers/file-metadata.js +0 -90
  28. package/dist/helpers/file-metadata.test.d.ts +0 -1
  29. package/dist/helpers/file-metadata.test.js +0 -103
  30. package/dist/helpers/filter.d.ts +0 -10
  31. package/dist/helpers/filter.js +0 -46
  32. package/dist/helpers/hashtag.d.ts +0 -2
  33. package/dist/helpers/hashtag.js +0 -7
  34. package/dist/helpers/hidden-tags.d.ts +0 -48
  35. package/dist/helpers/hidden-tags.js +0 -108
  36. package/dist/helpers/hidden-tags.test.d.ts +0 -1
  37. package/dist/helpers/hidden-tags.test.js +0 -28
  38. package/dist/helpers/index.d.ts +0 -26
  39. package/dist/helpers/index.js +0 -26
  40. package/dist/helpers/json.d.ts +0 -2
  41. package/dist/helpers/json.js +0 -9
  42. package/dist/helpers/lnurl.d.ts +0 -4
  43. package/dist/helpers/lnurl.js +0 -40
  44. package/dist/helpers/lru.d.ts +0 -32
  45. package/dist/helpers/lru.js +0 -148
  46. package/dist/helpers/mailboxes.d.ts +0 -11
  47. package/dist/helpers/mailboxes.js +0 -36
  48. package/dist/helpers/mailboxes.test.d.ts +0 -1
  49. package/dist/helpers/mailboxes.test.js +0 -81
  50. package/dist/helpers/media-attachment.d.ts +0 -42
  51. package/dist/helpers/media-attachment.js +0 -72
  52. package/dist/helpers/media-attachment.test.d.ts +0 -1
  53. package/dist/helpers/media-attachment.test.js +0 -59
  54. package/dist/helpers/media-post.d.ts +0 -4
  55. package/dist/helpers/media-post.js +0 -6
  56. package/dist/helpers/picture-post.d.ts +0 -4
  57. package/dist/helpers/picture-post.js +0 -6
  58. package/dist/helpers/pipe.d.ts +0 -10
  59. package/dist/helpers/pipe.js +0 -3
  60. package/dist/helpers/pointers.d.ts +0 -55
  61. package/dist/helpers/pointers.js +0 -205
  62. package/dist/helpers/profile.d.ts +0 -20
  63. package/dist/helpers/profile.js +0 -31
  64. package/dist/helpers/relays.d.ts +0 -12
  65. package/dist/helpers/relays.js +0 -31
  66. package/dist/helpers/string.d.ts +0 -10
  67. package/dist/helpers/string.js +0 -15
  68. package/dist/helpers/tags.d.ts +0 -25
  69. package/dist/helpers/tags.js +0 -42
  70. package/dist/helpers/tags.test.d.ts +0 -1
  71. package/dist/helpers/tags.test.js +0 -16
  72. package/dist/helpers/threading.d.ts +0 -55
  73. package/dist/helpers/threading.js +0 -94
  74. package/dist/helpers/threading.test.d.ts +0 -1
  75. package/dist/helpers/threading.test.js +0 -41
  76. package/dist/helpers/time.d.ts +0 -2
  77. package/dist/helpers/time.js +0 -4
  78. package/dist/helpers/url.d.ts +0 -14
  79. package/dist/helpers/url.js +0 -30
  80. package/dist/helpers/zap.d.ts +0 -39
  81. package/dist/helpers/zap.js +0 -95
  82. package/dist/index.d.ts +0 -5
  83. package/dist/index.js +0 -5
  84. package/dist/logger.d.ts +0 -2
  85. package/dist/logger.js +0 -2
  86. package/dist/observable/get-value.d.ts +0 -3
  87. package/dist/observable/get-value.js +0 -14
  88. package/dist/observable/index.d.ts +0 -2
  89. package/dist/observable/index.js +0 -2
  90. package/dist/observable/share-latest-value.d.ts +0 -8
  91. package/dist/observable/share-latest-value.js +0 -21
  92. package/dist/promise/deferred.d.ts +0 -6
  93. package/dist/promise/deferred.js +0 -15
  94. package/dist/promise/index.d.ts +0 -1
  95. package/dist/promise/index.js +0 -1
  96. package/dist/queries/comment.d.ts +0 -4
  97. package/dist/queries/comment.js +0 -14
  98. package/dist/queries/comments.d.ts +0 -4
  99. package/dist/queries/comments.js +0 -14
  100. package/dist/queries/index.d.ts +0 -7
  101. package/dist/queries/index.js +0 -7
  102. package/dist/queries/mailboxes.d.ts +0 -6
  103. package/dist/queries/mailboxes.js +0 -13
  104. package/dist/queries/profile.d.ts +0 -4
  105. package/dist/queries/profile.js +0 -12
  106. package/dist/queries/reactions.d.ts +0 -4
  107. package/dist/queries/reactions.js +0 -19
  108. package/dist/queries/simple.d.ts +0 -16
  109. package/dist/queries/simple.js +0 -38
  110. package/dist/queries/thread.d.ts +0 -25
  111. package/dist/queries/thread.js +0 -92
  112. package/dist/queries/zaps.d.ts +0 -5
  113. package/dist/queries/zaps.js +0 -21
  114. package/dist/query-store/index.d.ts +0 -57
  115. package/dist/query-store/index.js +0 -68
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-core",
3
- "version": "0.0.0-next-20250120191411",
3
+ "version": "0.0.0-next-20250123214405",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1 +0,0 @@
1
- export declare const INDEXABLE_TAGS: Set<string>;
@@ -1,2 +0,0 @@
1
- const LETTERS = "abcdefghijklmnopqrstuvwxyz";
2
- export const INDEXABLE_TAGS = new Set((LETTERS + LETTERS.toUpperCase()).split(""));
@@ -1,64 +0,0 @@
1
- import { Filter, NostrEvent } from "nostr-tools";
2
- import { Subject } from "rxjs";
3
- import { LRU } from "../helpers/lru.js";
4
- /**
5
- * An in-memory database for nostr events
6
- * NOTE: does not handle replaceable events
7
- */
8
- export declare class Database {
9
- protected log: import("debug").Debugger;
10
- /** Indexes */
11
- protected kinds: Map<number, Set<import("nostr-tools").Event>>;
12
- protected authors: Map<string, Set<import("nostr-tools").Event>>;
13
- protected tags: LRU<Set<import("nostr-tools").Event>>;
14
- protected created_at: NostrEvent[];
15
- /** LRU cache of last events touched */
16
- events: LRU<import("nostr-tools").Event>;
17
- protected replaceable: Map<string, import("nostr-tools").Event[]>;
18
- /** A stream of events inserted into the database */
19
- inserted: Subject<import("nostr-tools").Event>;
20
- /** A stream of events that have been updated */
21
- updated: Subject<import("nostr-tools").Event>;
22
- /** A stream of events removed of the database */
23
- deleted: Subject<import("nostr-tools").Event>;
24
- get size(): number;
25
- protected claims: WeakMap<import("nostr-tools").Event, any>;
26
- /** Index helper methods */
27
- protected getKindIndex(kind: number): Set<import("nostr-tools").Event>;
28
- protected getAuthorsIndex(author: string): Set<import("nostr-tools").Event>;
29
- protected getTagIndex(tagAndValue: string): Set<import("nostr-tools").Event>;
30
- /** Moves an event to the top of the LRU cache */
31
- touch(event: NostrEvent): void;
32
- /** Checks if the database contains an event without touching it */
33
- hasEvent(id: string): boolean;
34
- /** Gets a single event based on id */
35
- getEvent(id: string): NostrEvent | undefined;
36
- /** Checks if the database contains a replaceable event without touching it */
37
- hasReplaceable(kind: number, pubkey: string, d?: string): boolean;
38
- /** Gets an array of replaceable events */
39
- getReplaceable(kind: number, pubkey: string, d?: string): NostrEvent[] | undefined;
40
- /** Inserts an event into the database and notifies all subscriptions */
41
- addEvent(event: NostrEvent): NostrEvent;
42
- /** Inserts and event into the database and notifies all subscriptions that the event has updated */
43
- updateEvent(event: NostrEvent): NostrEvent;
44
- /** Deletes an event from the database and notifies all subscriptions */
45
- deleteEvent(eventOrId: string | NostrEvent): boolean;
46
- /** Sets the claim on the event and touches it */
47
- claimEvent(event: NostrEvent, claim: any): void;
48
- /** Checks if an event is claimed by anything */
49
- isClaimed(event: NostrEvent): boolean;
50
- /** Removes a claim from an event */
51
- removeClaim(event: NostrEvent, claim: any): void;
52
- /** Removes all claims on an event */
53
- clearClaim(event: NostrEvent): void;
54
- iterateAuthors(authors: Iterable<string>): Generator<NostrEvent>;
55
- iterateTag(tag: string, values: Iterable<string>): Generator<NostrEvent>;
56
- iterateKinds(kinds: Iterable<number>): Generator<NostrEvent>;
57
- iterateTime(since: number | undefined, until: number | undefined): Generator<NostrEvent>;
58
- iterateIds(ids: Iterable<string>): Generator<NostrEvent>;
59
- /** Returns all events that match the filter */
60
- getEventsForFilter(filter: Filter): Set<NostrEvent>;
61
- getForFilters(filters: Filter[]): Set<NostrEvent>;
62
- /** Remove the oldest events that are not claimed */
63
- prune(limit?: number): number;
64
- }
@@ -1,311 +0,0 @@
1
- import { binarySearch, insertEventIntoDescendingList } from "nostr-tools/utils";
2
- import { Subject } from "rxjs";
3
- import { FromCacheSymbol, getEventUID, getIndexableTags, getReplaceableUID, isReplaceable } from "../helpers/event.js";
4
- import { INDEXABLE_TAGS } from "./common.js";
5
- import { logger } from "../logger.js";
6
- import { LRU } from "../helpers/lru.js";
7
- /**
8
- * An in-memory database for nostr events
9
- * NOTE: does not handle replaceable events
10
- */
11
- export class Database {
12
- log = logger.extend("Database");
13
- /** Indexes */
14
- kinds = new Map();
15
- authors = new Map();
16
- tags = new LRU();
17
- created_at = [];
18
- /** LRU cache of last events touched */
19
- events = new LRU();
20
- replaceable = new Map();
21
- /** A stream of events inserted into the database */
22
- inserted = new Subject();
23
- /** A stream of events that have been updated */
24
- updated = new Subject();
25
- /** A stream of events removed of the database */
26
- deleted = new Subject();
27
- get size() {
28
- return this.events.size;
29
- }
30
- claims = new WeakMap();
31
- /** Index helper methods */
32
- getKindIndex(kind) {
33
- if (!this.kinds.has(kind))
34
- this.kinds.set(kind, new Set());
35
- return this.kinds.get(kind);
36
- }
37
- getAuthorsIndex(author) {
38
- if (!this.authors.has(author))
39
- this.authors.set(author, new Set());
40
- return this.authors.get(author);
41
- }
42
- getTagIndex(tagAndValue) {
43
- if (!this.tags.has(tagAndValue)) {
44
- // build new tag index from existing events
45
- const events = new Set();
46
- const ts = Date.now();
47
- for (const event of this.events.values()) {
48
- if (getIndexableTags(event).has(tagAndValue)) {
49
- events.add(event);
50
- }
51
- }
52
- const took = Date.now() - ts;
53
- if (took > 100)
54
- this.log(`Built index ${tagAndValue} took ${took}ms`);
55
- this.tags.set(tagAndValue, events);
56
- }
57
- return this.tags.get(tagAndValue);
58
- }
59
- /** Moves an event to the top of the LRU cache */
60
- touch(event) {
61
- this.events.set(event.id, event);
62
- }
63
- /** Checks if the database contains an event without touching it */
64
- hasEvent(id) {
65
- return this.events.has(id);
66
- }
67
- /** Gets a single event based on id */
68
- getEvent(id) {
69
- return this.events.get(id);
70
- }
71
- /** Checks if the database contains a replaceable event without touching it */
72
- hasReplaceable(kind, pubkey, d) {
73
- const events = this.replaceable.get(getReplaceableUID(kind, pubkey, d));
74
- return !!events && events.length > 0;
75
- }
76
- /** Gets an array of replaceable events */
77
- getReplaceable(kind, pubkey, d) {
78
- return this.replaceable.get(getReplaceableUID(kind, pubkey, d));
79
- }
80
- /** Inserts an event into the database and notifies all subscriptions */
81
- addEvent(event) {
82
- const id = event.id;
83
- const current = this.events.get(id);
84
- if (current) {
85
- // if this is a duplicate event, transfer some import symbols
86
- if (event[FromCacheSymbol])
87
- current[FromCacheSymbol] = event[FromCacheSymbol];
88
- return current;
89
- }
90
- this.events.set(id, event);
91
- this.getKindIndex(event.kind).add(event);
92
- this.getAuthorsIndex(event.pubkey).add(event);
93
- for (const tag of getIndexableTags(event)) {
94
- if (this.tags.has(tag)) {
95
- this.getTagIndex(tag).add(event);
96
- }
97
- }
98
- // insert into time index
99
- insertEventIntoDescendingList(this.created_at, event);
100
- // insert into replaceable index
101
- if (isReplaceable(event.kind)) {
102
- const uid = getEventUID(event);
103
- let array = this.replaceable.get(uid);
104
- if (!this.replaceable.has(uid)) {
105
- array = [];
106
- this.replaceable.set(uid, array);
107
- }
108
- insertEventIntoDescendingList(array, event);
109
- }
110
- this.inserted.next(event);
111
- return event;
112
- }
113
- /** Inserts and event into the database and notifies all subscriptions that the event has updated */
114
- updateEvent(event) {
115
- const inserted = this.addEvent(event);
116
- this.updated.next(inserted);
117
- return inserted;
118
- }
119
- /** Deletes an event from the database and notifies all subscriptions */
120
- deleteEvent(eventOrId) {
121
- let event = typeof eventOrId === "string" ? this.events.get(eventOrId) : eventOrId;
122
- if (!event)
123
- throw new Error("Missing event");
124
- const id = event.id;
125
- // only remove events that are known
126
- if (!this.events.has(id))
127
- return false;
128
- this.getAuthorsIndex(event.pubkey).delete(event);
129
- this.getKindIndex(event.kind).delete(event);
130
- for (const tag of getIndexableTags(event)) {
131
- if (this.tags.has(tag)) {
132
- this.getTagIndex(tag).delete(event);
133
- }
134
- }
135
- // remove from created_at index
136
- const i = this.created_at.indexOf(event);
137
- this.created_at.splice(i, 1);
138
- this.events.delete(id);
139
- // remove from replaceable index
140
- if (isReplaceable(event.kind)) {
141
- const uid = getEventUID(event);
142
- const array = this.replaceable.get(uid);
143
- if (array && array.includes(event)) {
144
- const idx = array.indexOf(event);
145
- array.splice(idx, 1);
146
- }
147
- }
148
- this.deleted.next(event);
149
- return true;
150
- }
151
- /** Sets the claim on the event and touches it */
152
- claimEvent(event, claim) {
153
- if (!this.claims.has(event)) {
154
- this.claims.set(event, claim);
155
- }
156
- // always touch event
157
- this.touch(event);
158
- }
159
- /** Checks if an event is claimed by anything */
160
- isClaimed(event) {
161
- return this.claims.has(event);
162
- }
163
- /** Removes a claim from an event */
164
- removeClaim(event, claim) {
165
- const current = this.claims.get(event);
166
- if (current === claim)
167
- this.claims.delete(event);
168
- }
169
- /** Removes all claims on an event */
170
- clearClaim(event) {
171
- this.claims.delete(event);
172
- }
173
- *iterateAuthors(authors) {
174
- for (const author of authors) {
175
- const events = this.authors.get(author);
176
- if (events) {
177
- for (const event of events)
178
- yield event;
179
- }
180
- }
181
- }
182
- *iterateTag(tag, values) {
183
- for (const value of values) {
184
- const events = this.getTagIndex(tag + ":" + value);
185
- if (events) {
186
- for (const event of events)
187
- yield event;
188
- }
189
- }
190
- }
191
- *iterateKinds(kinds) {
192
- for (const kind of kinds) {
193
- const events = this.kinds.get(kind);
194
- if (events) {
195
- for (const event of events)
196
- yield event;
197
- }
198
- }
199
- }
200
- *iterateTime(since, until) {
201
- let untilIndex = 0;
202
- let sinceIndex = this.created_at.length - 1;
203
- let start = until
204
- ? binarySearch(this.created_at, (mid) => {
205
- return mid.created_at - until;
206
- })
207
- : undefined;
208
- if (start)
209
- untilIndex = start[0];
210
- const end = since
211
- ? binarySearch(this.created_at, (mid) => {
212
- return mid.created_at - since;
213
- })
214
- : undefined;
215
- if (end)
216
- sinceIndex = end[0];
217
- for (let i = untilIndex; i < sinceIndex; i++) {
218
- yield this.created_at[i];
219
- }
220
- }
221
- *iterateIds(ids) {
222
- for (const id of ids) {
223
- if (this.events.has(id))
224
- yield this.events.get(id);
225
- }
226
- }
227
- /** Returns all events that match the filter */
228
- getEventsForFilter(filter) {
229
- // search is not supported, return an empty set
230
- if (filter.search)
231
- return new Set();
232
- let first = true;
233
- let events = new Set();
234
- const and = (iterable) => {
235
- const set = iterable instanceof Set ? iterable : new Set(iterable);
236
- if (first) {
237
- events = set;
238
- first = false;
239
- }
240
- else {
241
- for (const event of events) {
242
- if (!set.has(event))
243
- events.delete(event);
244
- }
245
- }
246
- return events;
247
- };
248
- if (filter.ids)
249
- and(this.iterateIds(filter.ids));
250
- let time = null;
251
- // query for time first if since is set
252
- if (filter.since !== undefined) {
253
- time = Array.from(this.iterateTime(filter.since, filter.until));
254
- and(time);
255
- }
256
- for (const t of INDEXABLE_TAGS) {
257
- const key = `#${t}`;
258
- const values = filter[key];
259
- if (values?.length)
260
- and(this.iterateTag(t, values));
261
- }
262
- if (filter.authors)
263
- and(this.iterateAuthors(filter.authors));
264
- if (filter.kinds)
265
- and(this.iterateKinds(filter.kinds));
266
- // query for time last if only until is set
267
- if (filter.since === undefined && filter.until !== undefined) {
268
- time = Array.from(this.iterateTime(filter.since, filter.until));
269
- and(time);
270
- }
271
- // if the filter queried on time and has a limit. truncate the events now
272
- if (filter.limit && time) {
273
- const limited = new Set();
274
- for (const event of time) {
275
- if (limited.size >= filter.limit)
276
- break;
277
- if (events.has(event))
278
- limited.add(event);
279
- }
280
- return limited;
281
- }
282
- return events;
283
- }
284
- getForFilters(filters) {
285
- if (filters.length === 0)
286
- throw new Error("No Filters");
287
- let events = new Set();
288
- for (const filter of filters) {
289
- const filtered = this.getEventsForFilter(filter);
290
- for (const event of filtered)
291
- events.add(event);
292
- }
293
- return events;
294
- }
295
- /** Remove the oldest events that are not claimed */
296
- prune(limit = 1000) {
297
- let removed = 0;
298
- let cursor = this.events.first;
299
- while (cursor) {
300
- const event = cursor.value;
301
- if (!this.isClaimed(event)) {
302
- this.deleteEvent(event);
303
- removed++;
304
- if (removed >= limit)
305
- break;
306
- }
307
- cursor = cursor.next;
308
- }
309
- return removed;
310
- }
311
- }
@@ -1,49 +0,0 @@
1
- import { Filter, NostrEvent } from "nostr-tools";
2
- import { Observable } from "rxjs";
3
- import { Database } from "./database.js";
4
- export declare class EventStore {
5
- database: Database;
6
- /** Enable this to keep old versions of replaceable events */
7
- keepOldVersions: boolean;
8
- constructor();
9
- /** Adds an event to the database and update subscriptions */
10
- add(event: NostrEvent, fromRelay?: string): NostrEvent;
11
- /** Removes an event from the database and updates subscriptions */
12
- remove(event: string | NostrEvent): boolean;
13
- protected deletedIds: Set<string>;
14
- protected deletedCoords: Map<string, number>;
15
- protected handleDeleteEvent(deleteEvent: NostrEvent): void;
16
- protected checkDeleted(event: NostrEvent): boolean;
17
- /** Removes any event that is not being used by a subscription */
18
- prune(max?: number): number;
19
- /** Add an event to the store and notifies all subscribes it has updated */
20
- update(event: NostrEvent): NostrEvent;
21
- getAll(filters: Filter[]): Set<NostrEvent>;
22
- hasEvent(uid: string): boolean;
23
- getEvent(uid: string): NostrEvent | undefined;
24
- hasReplaceable(kind: number, pubkey: string, d?: string): boolean;
25
- /** Gets the latest version of a replaceable event */
26
- getReplaceable(kind: number, pubkey: string, d?: string): NostrEvent | undefined;
27
- /** Returns all versions of a replaceable event */
28
- getReplaceableHistory(kind: number, pubkey: string, d?: string): NostrEvent[] | undefined;
29
- /** Creates an observable that updates a single event */
30
- event(id: string): Observable<NostrEvent | undefined>;
31
- /** Creates an observable that subscribes to multiple events */
32
- events(ids: string[]): Observable<Record<string, NostrEvent>>;
33
- /** Creates an observable with the latest version of a replaceable event */
34
- replaceable(kind: number, pubkey: string, d?: string): Observable<NostrEvent | undefined>;
35
- /** Creates an observable with the latest versions of replaceable events */
36
- replaceableSet(pointers: {
37
- kind: number;
38
- pubkey: string;
39
- identifier?: string;
40
- }[]): Observable<Record<string, NostrEvent>>;
41
- /**
42
- * Creates an observable that streams all events that match the filter
43
- * @param filters
44
- * @param [onlyNew=false] Only subscribe to new events
45
- */
46
- stream(filters: Filter | Filter[], onlyNew?: boolean): Observable<NostrEvent>;
47
- /** Creates an observable that updates with an array of sorted events */
48
- timeline(filters: Filter | Filter[], keepOldVersions?: boolean): Observable<NostrEvent[]>;
49
- }