applesauce-core 0.0.0-next-20251209200210 → 0.0.0-next-20251231055351
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/dist/event-factory/methods.js +4 -0
- package/dist/event-store/async-event-store.d.ts +4 -6
- package/dist/event-store/async-event-store.js +55 -56
- package/dist/event-store/event-memory.js +12 -4
- package/dist/event-store/event-models.d.ts +5 -22
- package/dist/event-store/event-models.js +10 -7
- package/dist/event-store/event-store.d.ts +4 -4
- package/dist/event-store/event-store.js +72 -46
- package/dist/event-store/interface.d.ts +29 -6
- package/dist/helpers/contacts.d.ts +1 -0
- package/dist/helpers/contacts.js +3 -3
- package/dist/helpers/encrypted-content.d.ts +3 -1
- package/dist/helpers/event-cache.d.ts +1 -1
- package/dist/helpers/event-cache.js +1 -1
- package/dist/helpers/event.d.ts +2 -2
- package/dist/helpers/hidden-content.js +4 -4
- package/dist/helpers/hidden-tags.d.ts +6 -2
- package/dist/helpers/hidden-tags.js +9 -3
- package/dist/helpers/pointers.d.ts +6 -2
- package/dist/helpers/pointers.js +33 -3
- package/dist/helpers/profile.d.ts +23 -2
- package/dist/helpers/profile.js +1 -1
- package/dist/helpers/relays.d.ts +2 -0
- package/dist/helpers/relays.js +4 -0
- package/dist/helpers/tags.d.ts +3 -1
- package/dist/helpers/tags.js +5 -1
- package/dist/models/base.js +43 -33
- package/dist/observable/watch-event-updates.d.ts +2 -0
- package/dist/observable/watch-event-updates.js +2 -0
- package/dist/operations/tag/common.d.ts +1 -1
- package/dist/operations/tag/common.js +1 -1
- package/package.json +1 -1
- package/dist/helpers/external-id.d.ts +0 -29
- package/dist/helpers/external-id.js +0 -20
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EncryptedContentSymbol } from "../helpers/encrypted-content.js";
|
|
2
|
+
import { isEvent } from "../helpers/event.js";
|
|
2
3
|
import { eventPipe } from "../helpers/pipeline.js";
|
|
3
4
|
import { unixNow } from "../helpers/time.js";
|
|
4
5
|
import { setClient } from "../operations/client.js";
|
|
@@ -36,5 +37,8 @@ export async function createEvent(context, blueprint, ...args) {
|
|
|
36
37
|
}
|
|
37
38
|
/** Modifies an event using a context and a set of operations */
|
|
38
39
|
export async function modifyEvent(event, context, ...operations) {
|
|
40
|
+
// NOTE: Unwrapping evnet object in order to handle cast events from applesauce-common
|
|
41
|
+
if ("event" in event && isEvent(event.event))
|
|
42
|
+
event = event.event;
|
|
39
43
|
return await wrapCommon(stripSignature(), stripStamp(), updateCreatedAt(), ...operations)(event, context);
|
|
40
44
|
}
|
|
@@ -4,7 +4,7 @@ import { Filter } from "../helpers/filter.js";
|
|
|
4
4
|
import { AddressPointer, AddressPointerWithoutD, EventPointer } from "../helpers/pointers.js";
|
|
5
5
|
import { EventMemory } from "./event-memory.js";
|
|
6
6
|
import { EventModels } from "./event-models.js";
|
|
7
|
-
import { IAsyncEventDatabase, IAsyncEventStore,
|
|
7
|
+
import { IAsyncDeleteManager, IAsyncEventDatabase, IAsyncEventStore, IExpirationManager } from "./interface.js";
|
|
8
8
|
export type AsyncEventStoreOptions = {
|
|
9
9
|
/** Keep deleted events in the store */
|
|
10
10
|
keepDeleted?: boolean;
|
|
@@ -44,7 +44,7 @@ export declare class AsyncEventStore extends EventModels implements IAsyncEventS
|
|
|
44
44
|
set verifyEvent(method: undefined | ((event: NostrEvent) => boolean));
|
|
45
45
|
/** A stream of new events added to the store */
|
|
46
46
|
insert$: Subject<import("nostr-tools/core").Event>;
|
|
47
|
-
/** A stream of events that have been updated */
|
|
47
|
+
/** A stream of events that have been updated (Warning: this is a very noisy stream, use with caution) */
|
|
48
48
|
update$: Subject<import("nostr-tools/core").Event>;
|
|
49
49
|
/** A stream of events that have been removed */
|
|
50
50
|
remove$: Subject<import("nostr-tools/core").Event>;
|
|
@@ -59,8 +59,6 @@ export declare class AsyncEventStore extends EventModels implements IAsyncEventS
|
|
|
59
59
|
private handleDeleteNotification;
|
|
60
60
|
/** Handle an expired event by id */
|
|
61
61
|
private handleExpiredNotification;
|
|
62
|
-
/** Copies important metadata from and identical event to another */
|
|
63
|
-
static mergeDuplicateEvent(source: NostrEvent, dest: NostrEvent): void;
|
|
64
62
|
/**
|
|
65
63
|
* Adds an event to the store and update subscriptions
|
|
66
64
|
* @returns The existing event or the event that was added, if it was ignored returns null
|
|
@@ -73,9 +71,9 @@ export declare class AsyncEventStore extends EventModels implements IAsyncEventS
|
|
|
73
71
|
/** Add an event to the store and notifies all subscribes it has updated */
|
|
74
72
|
update(event: NostrEvent): Promise<void>;
|
|
75
73
|
/** Check if the store has an event by id */
|
|
76
|
-
hasEvent(id: string): Promise<boolean>;
|
|
74
|
+
hasEvent(id: string | EventPointer | AddressPointer | AddressPointerWithoutD): Promise<boolean>;
|
|
77
75
|
/** Get an event by id from the store */
|
|
78
|
-
getEvent(id: string): Promise<NostrEvent | undefined>;
|
|
76
|
+
getEvent(id: string | EventPointer | AddressPointer | AddressPointerWithoutD): Promise<NostrEvent | undefined>;
|
|
79
77
|
/** Check if the store has a replaceable event */
|
|
80
78
|
hasReplaceable(kind: number, pubkey: string, d?: string): Promise<boolean>;
|
|
81
79
|
/** Gets the latest version of a replaceable event */
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
import { verifyEvent as coreVerifyEvent } from "nostr-tools/pure";
|
|
1
2
|
import { Subject } from "rxjs";
|
|
2
|
-
import { EventStoreSymbol,
|
|
3
|
+
import { EventStoreSymbol, getReplaceableIdentifier, isReplaceable, kinds } from "../helpers/event.js";
|
|
3
4
|
import { getExpirationTimestamp } from "../helpers/expiration.js";
|
|
4
|
-
import { eventMatchesPointer,
|
|
5
|
-
import { addSeenRelay
|
|
5
|
+
import { eventMatchesPointer, isAddressPointer, isEventPointer, } from "../helpers/pointers.js";
|
|
6
|
+
import { addSeenRelay } from "../helpers/relays.js";
|
|
6
7
|
import { unixNow } from "../helpers/time.js";
|
|
8
|
+
import { AsyncDeleteManager } from "./async-delete-manager.js";
|
|
7
9
|
import { EventMemory } from "./event-memory.js";
|
|
8
10
|
import { EventModels } from "./event-models.js";
|
|
9
|
-
import {
|
|
10
|
-
import { AsyncDeleteManager } from "./async-delete-manager.js";
|
|
11
|
+
import { EventStore } from "./event-store.js";
|
|
11
12
|
import { ExpirationManager } from "./expiration-manager.js";
|
|
12
13
|
/** An async wrapper around an async event database that handles replaceable events, deletes, and models */
|
|
13
14
|
export class AsyncEventStore extends EventModels {
|
|
@@ -38,7 +39,7 @@ export class AsyncEventStore extends EventModels {
|
|
|
38
39
|
}
|
|
39
40
|
/** A stream of new events added to the store */
|
|
40
41
|
insert$ = new Subject();
|
|
41
|
-
/** A stream of events that have been updated */
|
|
42
|
+
/** A stream of events that have been updated (Warning: this is a very noisy stream, use with caution) */
|
|
42
43
|
update$ = new Subject();
|
|
43
44
|
/** A stream of events that have been removed */
|
|
44
45
|
remove$ = new Subject();
|
|
@@ -75,14 +76,6 @@ export class AsyncEventStore extends EventModels {
|
|
|
75
76
|
console.error("[applesauce-core] Error handling expired notification:", error);
|
|
76
77
|
});
|
|
77
78
|
});
|
|
78
|
-
// when events are added to the database, add the symbol
|
|
79
|
-
this.insert$.subscribe((event) => {
|
|
80
|
-
Reflect.set(event, EventStoreSymbol, this);
|
|
81
|
-
});
|
|
82
|
-
// when events are removed from the database, remove the symbol
|
|
83
|
-
this.remove$.subscribe((event) => {
|
|
84
|
-
Reflect.deleteProperty(event, EventStoreSymbol);
|
|
85
|
-
});
|
|
86
79
|
}
|
|
87
80
|
mapToMemory(event) {
|
|
88
81
|
if (event === undefined)
|
|
@@ -122,18 +115,6 @@ export class AsyncEventStore extends EventModels {
|
|
|
122
115
|
return;
|
|
123
116
|
await this.remove(id);
|
|
124
117
|
}
|
|
125
|
-
/** Copies important metadata from and identical event to another */
|
|
126
|
-
static mergeDuplicateEvent(source, dest) {
|
|
127
|
-
const relays = getSeenRelays(source);
|
|
128
|
-
if (relays) {
|
|
129
|
-
for (const relay of relays)
|
|
130
|
-
addSeenRelay(dest, relay);
|
|
131
|
-
}
|
|
132
|
-
// copy the from cache symbol only if its true
|
|
133
|
-
const fromCache = Reflect.get(source, FromCacheSymbol);
|
|
134
|
-
if (fromCache && !Reflect.get(dest, FromCacheSymbol))
|
|
135
|
-
Reflect.set(dest, FromCacheSymbol, fromCache);
|
|
136
|
-
}
|
|
137
118
|
/**
|
|
138
119
|
* Adds an event to the store and update subscriptions
|
|
139
120
|
* @returns The existing event or the event that was added, if it was ignored returns null
|
|
@@ -151,6 +132,9 @@ export class AsyncEventStore extends EventModels {
|
|
|
151
132
|
const expiration = getExpirationTimestamp(event);
|
|
152
133
|
if (this.keepExpired === false && expiration && expiration <= unixNow())
|
|
153
134
|
return null;
|
|
135
|
+
// Attach relay this event was from
|
|
136
|
+
if (fromRelay)
|
|
137
|
+
addSeenRelay(event, fromRelay);
|
|
154
138
|
// Get the replaceable identifier
|
|
155
139
|
const identifier = isReplaceable(event.kind) ? getReplaceableIdentifier(event) : undefined;
|
|
156
140
|
// Don't insert the event if there is already a newer version
|
|
@@ -158,7 +142,8 @@ export class AsyncEventStore extends EventModels {
|
|
|
158
142
|
const existing = await this.database.getReplaceableHistory(event.kind, event.pubkey, identifier);
|
|
159
143
|
// If there is already a newer version, copy cached symbols and return existing event
|
|
160
144
|
if (existing && existing.length > 0 && existing[0].created_at >= event.created_at) {
|
|
161
|
-
|
|
145
|
+
if (EventStore.copySymbolsToDuplicateEvent(event, existing[0]))
|
|
146
|
+
await this.update(existing[0]);
|
|
162
147
|
return existing[0];
|
|
163
148
|
}
|
|
164
149
|
}
|
|
@@ -166,27 +151,28 @@ export class AsyncEventStore extends EventModels {
|
|
|
166
151
|
if (this.verifyEvent && this.verifyEvent(event) === false)
|
|
167
152
|
return null;
|
|
168
153
|
// Always add event to memory
|
|
169
|
-
const existing = this.memory
|
|
154
|
+
const existing = this.memory.add(event);
|
|
170
155
|
// If the memory returned a different instance, this is a duplicate event
|
|
171
156
|
if (existing && existing !== event) {
|
|
172
157
|
// Copy cached symbols and return existing event
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if (fromRelay)
|
|
176
|
-
addSeenRelay(existing, fromRelay);
|
|
158
|
+
if (EventStore.copySymbolsToDuplicateEvent(event, existing))
|
|
159
|
+
await this.update(existing);
|
|
177
160
|
return existing;
|
|
178
161
|
}
|
|
179
162
|
// Insert event into database
|
|
180
163
|
const inserted = this.mapToMemory(await this.database.add(event));
|
|
181
|
-
//
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
addSeenRelay(inserted, fromRelay);
|
|
187
|
-
// Emit insert$ signal
|
|
188
|
-
if (inserted === event)
|
|
164
|
+
// If the event is the same as the inserted event, its a new event
|
|
165
|
+
if (inserted === event) {
|
|
166
|
+
// Set the event store on the event
|
|
167
|
+
Reflect.set(inserted, EventStoreSymbol, this);
|
|
168
|
+
// Emit insert$ signal
|
|
189
169
|
this.insert$.next(inserted);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
// Copy cached data if its a duplicate event
|
|
173
|
+
if (EventStore.copySymbolsToDuplicateEvent(event, inserted))
|
|
174
|
+
await this.update(inserted);
|
|
175
|
+
}
|
|
190
176
|
// remove all old version of the replaceable event
|
|
191
177
|
if (this.keepOldVersions === false && isReplaceable(event.kind)) {
|
|
192
178
|
const existing = await this.database.getReplaceableHistory(event.kind, event.pubkey, identifier);
|
|
@@ -208,18 +194,20 @@ export class AsyncEventStore extends EventModels {
|
|
|
208
194
|
/** Removes an event from the store and updates subscriptions */
|
|
209
195
|
async remove(event) {
|
|
210
196
|
const eventId = typeof event === "string" ? event : event.id;
|
|
211
|
-
let instance = this.memory
|
|
197
|
+
let instance = this.memory.getEvent(eventId);
|
|
212
198
|
// Remove from expiration manager
|
|
213
199
|
this.expiration.forget(eventId);
|
|
200
|
+
// Remove the event store from the event
|
|
201
|
+
if (instance)
|
|
202
|
+
Reflect.deleteProperty(instance, EventStoreSymbol);
|
|
214
203
|
// Remove from memory if available
|
|
215
204
|
if (this.memory)
|
|
216
205
|
this.memory.remove(event);
|
|
217
206
|
// Remove the event from the database
|
|
218
207
|
const removed = await this.database.remove(event);
|
|
219
208
|
// If the event was removed, notify the subscriptions
|
|
220
|
-
if (removed && instance)
|
|
209
|
+
if (removed && instance)
|
|
221
210
|
this.remove$.next(instance);
|
|
222
|
-
}
|
|
223
211
|
return removed;
|
|
224
212
|
}
|
|
225
213
|
/** Remove multiple events that match the given filters */
|
|
@@ -252,29 +240,40 @@ export class AsyncEventStore extends EventModels {
|
|
|
252
240
|
}
|
|
253
241
|
/** Check if the store has an event by id */
|
|
254
242
|
async hasEvent(id) {
|
|
255
|
-
|
|
256
|
-
|
|
243
|
+
if (typeof id === "string")
|
|
244
|
+
return this.memory.hasEvent(id) || this.database.hasEvent(id);
|
|
245
|
+
// If its a pointer, use the advanced has event method to resolve
|
|
246
|
+
else if (isEventPointer(id))
|
|
247
|
+
return this.memory.hasEvent(id.id) || this.database.hasEvent(id.id);
|
|
248
|
+
else
|
|
249
|
+
return this.hasReplaceable(id.kind, id.pubkey, id.identifier);
|
|
257
250
|
}
|
|
258
251
|
/** Get an event by id from the store */
|
|
259
252
|
async getEvent(id) {
|
|
260
253
|
// Get the event from memory first, then from the database
|
|
261
|
-
|
|
254
|
+
if (typeof id === "string")
|
|
255
|
+
return this.memory.getEvent(id) ?? this.mapToMemory(await this.database.getEvent(id));
|
|
256
|
+
// If its a pointer, use the advanced get event method to resolve
|
|
257
|
+
else if (isEventPointer(id))
|
|
258
|
+
return this.memory.getEvent(id.id) ?? this.mapToMemory(await this.database.getEvent(id.id));
|
|
259
|
+
else
|
|
260
|
+
return this.getReplaceable(id.kind, id.pubkey, id.identifier);
|
|
262
261
|
}
|
|
263
262
|
/** Check if the store has a replaceable event */
|
|
264
263
|
async hasReplaceable(kind, pubkey, d) {
|
|
265
264
|
// Check if the event exists in memory first, then in the database
|
|
266
|
-
return
|
|
265
|
+
return this.memory.hasReplaceable(kind, pubkey, d) || this.database.hasReplaceable(kind, pubkey, d);
|
|
267
266
|
}
|
|
268
267
|
/** Gets the latest version of a replaceable event */
|
|
269
268
|
async getReplaceable(kind, pubkey, identifier) {
|
|
270
269
|
// Get the event from memory first, then from the database
|
|
271
|
-
return (this.memory
|
|
270
|
+
return (this.memory.getReplaceable(kind, pubkey, identifier) ??
|
|
272
271
|
this.mapToMemory(await this.database.getReplaceable(kind, pubkey, identifier)));
|
|
273
272
|
}
|
|
274
273
|
/** Returns all versions of a replaceable event */
|
|
275
274
|
async getReplaceableHistory(kind, pubkey, identifier) {
|
|
276
275
|
// Get the events from memory first, then from the database
|
|
277
|
-
return (this.memory
|
|
276
|
+
return (this.memory.getReplaceableHistory(kind, pubkey, identifier) ??
|
|
278
277
|
(await this.database.getReplaceableHistory(kind, pubkey, identifier))?.map((e) => this.mapToMemory(e) ?? e));
|
|
279
278
|
}
|
|
280
279
|
/** Get all events matching a filter */
|
|
@@ -297,30 +296,30 @@ export class AsyncEventStore extends EventModels {
|
|
|
297
296
|
}
|
|
298
297
|
/** Passthrough method for the database.touch */
|
|
299
298
|
touch(event) {
|
|
300
|
-
return this.memory
|
|
299
|
+
return this.memory.touch(event);
|
|
301
300
|
}
|
|
302
301
|
/** Increments the claim count on the event and touches it */
|
|
303
302
|
claim(event) {
|
|
304
|
-
return this.memory
|
|
303
|
+
return this.memory.claim(event);
|
|
305
304
|
}
|
|
306
305
|
/** Checks if an event is claimed by anything */
|
|
307
306
|
isClaimed(event) {
|
|
308
|
-
return this.memory
|
|
307
|
+
return this.memory.isClaimed(event) ?? false;
|
|
309
308
|
}
|
|
310
309
|
/** Decrements the claim count on an event */
|
|
311
310
|
removeClaim(event) {
|
|
312
|
-
return this.memory
|
|
311
|
+
return this.memory.removeClaim(event);
|
|
313
312
|
}
|
|
314
313
|
/** Removes all claims on an event */
|
|
315
314
|
clearClaim(event) {
|
|
316
|
-
return this.memory
|
|
315
|
+
return this.memory.clearClaim(event);
|
|
317
316
|
}
|
|
318
317
|
/** Pass through method for the database.unclaimed */
|
|
319
318
|
unclaimed() {
|
|
320
|
-
return this.memory
|
|
319
|
+
return this.memory.unclaimed() || (function* () { })();
|
|
321
320
|
}
|
|
322
321
|
/** Removes any event that is not being used by a subscription */
|
|
323
322
|
prune(limit) {
|
|
324
|
-
return this.memory
|
|
323
|
+
return this.memory.prune(limit) ?? 0;
|
|
325
324
|
}
|
|
326
325
|
}
|
|
@@ -312,6 +312,9 @@ export class EventMemory {
|
|
|
312
312
|
}
|
|
313
313
|
/** Iterates over all events by time */
|
|
314
314
|
*iterateTime(since, until) {
|
|
315
|
+
// Early return if array is empty
|
|
316
|
+
if (this.created_at.length === 0)
|
|
317
|
+
return;
|
|
315
318
|
let startIndex = 0;
|
|
316
319
|
let endIndex = this.created_at.length - 1;
|
|
317
320
|
// If until is set, use binary search to find better start index
|
|
@@ -320,16 +323,21 @@ export class EventMemory {
|
|
|
320
323
|
return mid.created_at - until;
|
|
321
324
|
})
|
|
322
325
|
: undefined;
|
|
323
|
-
if (start)
|
|
324
|
-
startIndex = start[0];
|
|
326
|
+
if (start) {
|
|
327
|
+
startIndex = Math.max(0, Math.min(start[0], this.created_at.length - 1));
|
|
328
|
+
}
|
|
325
329
|
// If since is set, use binary search to find better end index
|
|
326
330
|
const end = since
|
|
327
331
|
? binarySearch(this.created_at, (mid) => {
|
|
328
332
|
return mid.created_at - since;
|
|
329
333
|
})
|
|
330
334
|
: undefined;
|
|
331
|
-
if (end)
|
|
332
|
-
endIndex = end[0];
|
|
335
|
+
if (end) {
|
|
336
|
+
endIndex = Math.max(0, Math.min(end[0], this.created_at.length - 1));
|
|
337
|
+
}
|
|
338
|
+
// Ensure startIndex <= endIndex
|
|
339
|
+
if (startIndex > endIndex)
|
|
340
|
+
return;
|
|
333
341
|
// Yield events in the range, filtering by exact bounds
|
|
334
342
|
for (let i = startIndex; i <= endIndex; i++) {
|
|
335
343
|
const event = this.created_at[i];
|
|
@@ -2,24 +2,7 @@ import { Observable } from "rxjs";
|
|
|
2
2
|
import { NostrEvent } from "../helpers/event.js";
|
|
3
3
|
import { Filter } from "../helpers/filter.js";
|
|
4
4
|
import { AddressPointer, AddressPointerWithoutD, EventPointer, ProfilePointer } from "../helpers/pointers.js";
|
|
5
|
-
import {
|
|
6
|
-
import { IAsyncEventStore, IEventStore, ModelConstructor } from "./interface.js";
|
|
7
|
-
/**
|
|
8
|
-
* Core helpful subscriptions interface.
|
|
9
|
-
* Contains only methods that use models from the core package.
|
|
10
|
-
* Other packages (like applesauce-common) can extend this interface via module augmentation.
|
|
11
|
-
*/
|
|
12
|
-
export interface IEventStoreModels {
|
|
13
|
-
/** Subscribe to a users profile */
|
|
14
|
-
profile(user: string | ProfilePointer): Observable<ProfileContent | undefined>;
|
|
15
|
-
/** Subscribe to a users contacts */
|
|
16
|
-
contacts(user: string | ProfilePointer): Observable<ProfilePointer[]>;
|
|
17
|
-
/** Subscribe to a users mailboxes */
|
|
18
|
-
mailboxes(user: string | ProfilePointer): Observable<{
|
|
19
|
-
inboxes: string[];
|
|
20
|
-
outboxes: string[];
|
|
21
|
-
} | undefined>;
|
|
22
|
-
}
|
|
5
|
+
import { IAsyncEventStore, IEventStore, IEventSubscriptions, ModelConstructor } from "./interface.js";
|
|
23
6
|
/**
|
|
24
7
|
* Base class that provides model functionality for both sync and async event stores.
|
|
25
8
|
* This class can be extended by other packages to add additional helpful subscription methods.
|
|
@@ -42,7 +25,7 @@ export interface IEventStoreModels {
|
|
|
42
25
|
* }
|
|
43
26
|
* ```
|
|
44
27
|
*/
|
|
45
|
-
export declare class EventModels<TStore extends IEventStore | IAsyncEventStore = IEventStore | IAsyncEventStore> implements
|
|
28
|
+
export declare class EventModels<TStore extends IEventStore | IAsyncEventStore = IEventStore | IAsyncEventStore> implements IEventSubscriptions {
|
|
46
29
|
/** A directory of all active models */
|
|
47
30
|
models: Map<ModelConstructor<any, any[], TStore>, Map<string, Observable<any>>>;
|
|
48
31
|
/** How long a model should be kept "warm" while nothing is subscribed to it */
|
|
@@ -55,8 +38,8 @@ export declare class EventModels<TStore extends IEventStore | IAsyncEventStore =
|
|
|
55
38
|
* @param [onlyNew=false] Only subscribe to new events
|
|
56
39
|
*/
|
|
57
40
|
filters(filters: Filter | Filter[], onlyNew?: boolean): Observable<NostrEvent>;
|
|
58
|
-
/**
|
|
59
|
-
event(pointer: string | EventPointer): Observable<NostrEvent | undefined>;
|
|
41
|
+
/** Subscribe to an event by pointer */
|
|
42
|
+
event(pointer: string | EventPointer | AddressPointer | AddressPointerWithoutD): Observable<NostrEvent | undefined>;
|
|
60
43
|
/** Subscribe to a replaceable event by pointer */
|
|
61
44
|
replaceable(pointer: AddressPointer | AddressPointerWithoutD): Observable<NostrEvent | undefined>;
|
|
62
45
|
replaceable(kind: number, pubkey: string, identifier?: string): Observable<NostrEvent | undefined>;
|
|
@@ -65,7 +48,7 @@ export declare class EventModels<TStore extends IEventStore | IAsyncEventStore =
|
|
|
65
48
|
/** Creates a {@link TimelineModel} */
|
|
66
49
|
timeline(filters: Filter | Filter[], includeOldVersion?: boolean): Observable<NostrEvent[]>;
|
|
67
50
|
/** Subscribe to a users profile */
|
|
68
|
-
profile(user: string | ProfilePointer): Observable<ProfileContent | undefined>;
|
|
51
|
+
profile(user: string | ProfilePointer): Observable<import("../helpers/profile.js").ProfileContent | undefined>;
|
|
69
52
|
/** Subscribe to a users contacts */
|
|
70
53
|
contacts(user: string | ProfilePointer): Observable<ProfilePointer[]>;
|
|
71
54
|
/** Subscribe to a users mailboxes */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import hash_sum from "hash-sum";
|
|
2
|
-
import {
|
|
2
|
+
import { finalize, ReplaySubject, share, timer } from "rxjs";
|
|
3
|
+
import { isEventPointer, } from "../helpers/pointers.js";
|
|
3
4
|
import { EventModel, FiltersModel, ReplaceableModel, TimelineModel } from "../models/base.js";
|
|
4
5
|
import { ContactsModel } from "../models/contacts.js";
|
|
5
6
|
import { MailboxesModel } from "../models/mailboxes.js";
|
|
@@ -67,14 +68,16 @@ export class EventModels {
|
|
|
67
68
|
* @param [onlyNew=false] Only subscribe to new events
|
|
68
69
|
*/
|
|
69
70
|
filters(filters, onlyNew = false) {
|
|
71
|
+
if (!Array.isArray(filters))
|
|
72
|
+
filters = [filters];
|
|
70
73
|
return this.model(FiltersModel, filters, onlyNew);
|
|
71
74
|
}
|
|
72
|
-
|
|
73
|
-
/** Creates a {@link EventModel} */
|
|
75
|
+
/** Subscribe to an event by pointer */
|
|
74
76
|
event(pointer) {
|
|
75
|
-
if (typeof pointer === "string")
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
if (typeof pointer === "string" || isEventPointer(pointer))
|
|
78
|
+
return this.model(EventModel, pointer);
|
|
79
|
+
else
|
|
80
|
+
return this.replaceable(pointer);
|
|
78
81
|
}
|
|
79
82
|
replaceable(...args) {
|
|
80
83
|
let pointer;
|
|
@@ -92,7 +95,7 @@ export class EventModels {
|
|
|
92
95
|
}
|
|
93
96
|
/** Subscribe to an addressable event by pointer */
|
|
94
97
|
addressable(pointer) {
|
|
95
|
-
return this.
|
|
98
|
+
return this.replaceable(pointer);
|
|
96
99
|
}
|
|
97
100
|
/** Creates a {@link TimelineModel} */
|
|
98
101
|
timeline(filters, includeOldVersion = false) {
|
|
@@ -44,7 +44,7 @@ export declare class EventStore extends EventModels implements IEventStore {
|
|
|
44
44
|
set verifyEvent(method: undefined | ((event: NostrEvent) => boolean));
|
|
45
45
|
/** A stream of new events added to the store */
|
|
46
46
|
insert$: Subject<import("nostr-tools/core").Event>;
|
|
47
|
-
/** A stream of events that have been updated */
|
|
47
|
+
/** A stream of events that have been updated (Warning: this is a very noisy stream, use with caution) */
|
|
48
48
|
update$: Subject<import("nostr-tools/core").Event>;
|
|
49
49
|
/** A stream of events that have been removed */
|
|
50
50
|
remove$: Subject<import("nostr-tools/core").Event>;
|
|
@@ -58,7 +58,7 @@ export declare class EventStore extends EventModels implements IEventStore {
|
|
|
58
58
|
/** Handle an expired event by id */
|
|
59
59
|
private handleExpiredNotification;
|
|
60
60
|
/** Copies important metadata from and identical event to another */
|
|
61
|
-
static
|
|
61
|
+
static copySymbolsToDuplicateEvent(source: NostrEvent, dest: NostrEvent): boolean;
|
|
62
62
|
/**
|
|
63
63
|
* Adds an event to the store and update subscriptions
|
|
64
64
|
* @returns The existing event or the event that was added, if it was ignored returns null
|
|
@@ -71,9 +71,9 @@ export declare class EventStore extends EventModels implements IEventStore {
|
|
|
71
71
|
/** Add an event to the store and notifies all subscribes it has updated */
|
|
72
72
|
update(event: NostrEvent): boolean;
|
|
73
73
|
/** Check if the store has an event by id */
|
|
74
|
-
hasEvent(id: string): boolean;
|
|
74
|
+
hasEvent(id: string | EventPointer | AddressPointer | AddressPointerWithoutD): boolean;
|
|
75
75
|
/** Get an event by id from the store */
|
|
76
|
-
getEvent(id: string): NostrEvent | undefined;
|
|
76
|
+
getEvent(id: string | EventPointer | AddressPointer | AddressPointerWithoutD): NostrEvent | undefined;
|
|
77
77
|
/** Check if the store has a replaceable event */
|
|
78
78
|
hasReplaceable(kind: number, pubkey: string, d?: string): boolean;
|
|
79
79
|
/** Gets the latest version of a replaceable event */
|