applesauce-core 6.0.2 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/casts/cast.d.ts +1 -19
- package/dist/casts/cast.js +1 -43
- package/dist/casts/event.d.ts +33 -0
- package/dist/casts/event.js +65 -0
- package/dist/casts/index.d.ts +1 -0
- package/dist/casts/index.js +1 -0
- package/dist/casts/pubkey.d.ts +0 -1
- package/dist/casts/pubkey.js +0 -1
- package/dist/casts/user.d.ts +13 -1
- package/dist/casts/user.js +24 -0
- package/dist/event-store/async-event-store.js +29 -12
- package/dist/event-store/event-store.js +29 -12
- package/dist/helpers/pointers.d.ts +2 -0
- package/dist/helpers/pointers.js +7 -0
- package/dist/helpers/regexp.js +4 -4
- package/dist/observable/cast-stream.d.ts +8 -0
- package/dist/observable/cast-stream.js +29 -0
- package/package.json +1 -1
package/dist/casts/cast.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { Observable } from "rxjs";
|
|
2
1
|
import { EventModels, IEventStoreStreams, IEventSubscriptions } from "../event-store/index.js";
|
|
3
2
|
import { NostrEvent } from "../helpers/event.js";
|
|
4
|
-
import {
|
|
5
|
-
import { User } from "./user.js";
|
|
3
|
+
import { EventCast } from "./event.js";
|
|
6
4
|
/** The type of event store that is passed to cast references */
|
|
7
5
|
export type CastRefEventStore = IEventSubscriptions & EventModels & IEventStoreStreams;
|
|
8
6
|
/** A symbol used to store all the cast instances for a given event */
|
|
@@ -13,19 +11,3 @@ export declare const CASTS_SYMBOL: unique symbol;
|
|
|
13
11
|
export type CastConstructor<C extends EventCast<NostrEvent>> = new (event: NostrEvent, store: CastRefEventStore) => C;
|
|
14
12
|
/** Cast a Nostr event to a specific class */
|
|
15
13
|
export declare function castEvent<C extends EventCast<NostrEvent>>(event: NostrEvent, cls: CastConstructor<C>, store?: CastRefEventStore): C;
|
|
16
|
-
/** The base class for all casts */
|
|
17
|
-
export declare class EventCast<T extends NostrEvent = NostrEvent> {
|
|
18
|
-
#private;
|
|
19
|
-
readonly event: T;
|
|
20
|
-
readonly store: CastRefEventStore;
|
|
21
|
-
get id(): string;
|
|
22
|
-
get uid(): string;
|
|
23
|
-
get createdAt(): Date;
|
|
24
|
-
/** Get the {@link User} that authored this event */
|
|
25
|
-
get author(): User;
|
|
26
|
-
/** Return the set of relays this event was seen on */
|
|
27
|
-
get seen(): Set<string> | undefined;
|
|
28
|
-
constructor(event: T, store: CastRefEventStore);
|
|
29
|
-
/** Internal method for creating a reference */
|
|
30
|
-
protected $$ref<Return extends unknown>(key: string, builder: (store: CastRefEventStore) => Observable<Return>): ChainableObservable<Return>;
|
|
31
|
-
}
|
package/dist/casts/cast.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getSeenRelays } from "../helpers/relays.js";
|
|
3
|
-
import { chainable } from "../observable/chainable.js";
|
|
4
|
-
import { castUser } from "./user.js";
|
|
1
|
+
import { getParentEventStore } from "../helpers/event.js";
|
|
5
2
|
/** A symbol used to store all the cast instances for a given event */
|
|
6
3
|
export const CAST_REF_SYMBOL = Symbol.for("cast-ref");
|
|
7
4
|
/** A symbol used to store all the casts for an event */
|
|
@@ -26,42 +23,3 @@ export function castEvent(event, cls, store) {
|
|
|
26
23
|
casts.set(cls, cast);
|
|
27
24
|
return cast;
|
|
28
25
|
}
|
|
29
|
-
/** The base class for all casts */
|
|
30
|
-
export class EventCast {
|
|
31
|
-
event;
|
|
32
|
-
store;
|
|
33
|
-
get id() {
|
|
34
|
-
return this.event.id;
|
|
35
|
-
}
|
|
36
|
-
get uid() {
|
|
37
|
-
return getEventUID(this.event);
|
|
38
|
-
}
|
|
39
|
-
get createdAt() {
|
|
40
|
-
return new Date(this.event.created_at * 1000);
|
|
41
|
-
}
|
|
42
|
-
/** Get the {@link User} that authored this event */
|
|
43
|
-
get author() {
|
|
44
|
-
return castUser(this.event, this.store);
|
|
45
|
-
}
|
|
46
|
-
/** Return the set of relays this event was seen on */
|
|
47
|
-
get seen() {
|
|
48
|
-
return getSeenRelays(this.event);
|
|
49
|
-
}
|
|
50
|
-
// Enfore kind check in constructor. this will force child classes to verify the event before calling super()
|
|
51
|
-
constructor(event, store) {
|
|
52
|
-
this.event = event;
|
|
53
|
-
this.store = store;
|
|
54
|
-
}
|
|
55
|
-
/** A cache of observable references */
|
|
56
|
-
#refs = {};
|
|
57
|
-
/** Internal method for creating a reference */
|
|
58
|
-
$$ref(key, builder) {
|
|
59
|
-
// Return cached observable
|
|
60
|
-
if (this.#refs[key])
|
|
61
|
-
return this.#refs[key];
|
|
62
|
-
// Build a new observable and cache it
|
|
63
|
-
const observable = chainable(builder(this.store));
|
|
64
|
-
this.#refs[key] = observable;
|
|
65
|
-
return observable;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Observable } from "rxjs";
|
|
2
|
+
import { NostrEvent } from "../helpers/event.js";
|
|
3
|
+
import { AddressPointer, EventPointer } from "../helpers/pointers.js";
|
|
4
|
+
import { ChainableObservable } from "../observable/chainable.js";
|
|
5
|
+
import { CastRefEventStore } from "./cast.js";
|
|
6
|
+
import { User } from "./user.js";
|
|
7
|
+
/** The base class for all casts */
|
|
8
|
+
export declare class EventCast<T extends NostrEvent = NostrEvent> {
|
|
9
|
+
#private;
|
|
10
|
+
readonly event: T;
|
|
11
|
+
readonly store: CastRefEventStore;
|
|
12
|
+
/** Alias for event.id */
|
|
13
|
+
get id(): string;
|
|
14
|
+
/** Alias for event.kind */
|
|
15
|
+
get kind(): number;
|
|
16
|
+
/** Returns the unique identifier for this event */
|
|
17
|
+
get uid(): string;
|
|
18
|
+
/** Returns the created_at timestamp as a Date object */
|
|
19
|
+
get createdAt(): Date;
|
|
20
|
+
/** Get the {@link User} that authored this event */
|
|
21
|
+
get author(): User;
|
|
22
|
+
/** Return the set of relays this event was seen on */
|
|
23
|
+
get seen(): Set<string> | undefined;
|
|
24
|
+
/** Returns the NIP-01 address string for this event if its replaceable or addressable, otherwise returns null */
|
|
25
|
+
get coordinate(): string | null;
|
|
26
|
+
/** Alias for {@link coordinate} */
|
|
27
|
+
get replaceableAddress(): string | null;
|
|
28
|
+
/** Returns a single {@link EventPointer} or {@link AddressPointer} for this event */
|
|
29
|
+
get pointer(): EventPointer | AddressPointer;
|
|
30
|
+
constructor(event: T, store: CastRefEventStore);
|
|
31
|
+
/** Internal method for creating a reference */
|
|
32
|
+
protected $$ref<Return extends unknown>(key: string, builder: (store: CastRefEventStore) => Observable<Return>): ChainableObservable<Return>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { getEventUID, isAddressableKind, isReplaceableKind } from "../helpers/event.js";
|
|
2
|
+
import { getAddressPointerForEvent, getEventPointerForEvent, getReplaceableAddressForEvent, } from "../helpers/pointers.js";
|
|
3
|
+
import { getSeenRelays } from "../helpers/relays.js";
|
|
4
|
+
import { chainable } from "../observable/chainable.js";
|
|
5
|
+
import { castUser } from "./user.js";
|
|
6
|
+
/** The base class for all casts */
|
|
7
|
+
export class EventCast {
|
|
8
|
+
event;
|
|
9
|
+
store;
|
|
10
|
+
/** Alias for event.id */
|
|
11
|
+
get id() {
|
|
12
|
+
return this.event.id;
|
|
13
|
+
}
|
|
14
|
+
/** Alias for event.kind */
|
|
15
|
+
get kind() {
|
|
16
|
+
return this.event.kind;
|
|
17
|
+
}
|
|
18
|
+
/** Returns the unique identifier for this event */
|
|
19
|
+
get uid() {
|
|
20
|
+
return getEventUID(this.event);
|
|
21
|
+
}
|
|
22
|
+
/** Returns the created_at timestamp as a Date object */
|
|
23
|
+
get createdAt() {
|
|
24
|
+
return new Date(this.event.created_at * 1000);
|
|
25
|
+
}
|
|
26
|
+
/** Get the {@link User} that authored this event */
|
|
27
|
+
get author() {
|
|
28
|
+
return castUser(this.event, this.store);
|
|
29
|
+
}
|
|
30
|
+
/** Return the set of relays this event was seen on */
|
|
31
|
+
get seen() {
|
|
32
|
+
return getSeenRelays(this.event);
|
|
33
|
+
}
|
|
34
|
+
/** Returns the NIP-01 address string for this event if its replaceable or addressable, otherwise returns null */
|
|
35
|
+
get coordinate() {
|
|
36
|
+
return getReplaceableAddressForEvent(this.event);
|
|
37
|
+
}
|
|
38
|
+
/** Alias for {@link coordinate} */
|
|
39
|
+
get replaceableAddress() {
|
|
40
|
+
return this.coordinate;
|
|
41
|
+
}
|
|
42
|
+
/** Returns a single {@link EventPointer} or {@link AddressPointer} for this event */
|
|
43
|
+
get pointer() {
|
|
44
|
+
if (isReplaceableKind(this.kind) || isAddressableKind(this.kind))
|
|
45
|
+
return getAddressPointerForEvent(this.event) || getEventPointerForEvent(this.event);
|
|
46
|
+
return getEventPointerForEvent(this.event);
|
|
47
|
+
}
|
|
48
|
+
// Enfore kind check in constructor. this will force child classes to verify the event before calling super()
|
|
49
|
+
constructor(event, store) {
|
|
50
|
+
this.event = event;
|
|
51
|
+
this.store = store;
|
|
52
|
+
}
|
|
53
|
+
/** A cache of observable references */
|
|
54
|
+
#refs = {};
|
|
55
|
+
/** Internal method for creating a reference */
|
|
56
|
+
$$ref(key, builder) {
|
|
57
|
+
// Return cached observable
|
|
58
|
+
if (this.#refs[key])
|
|
59
|
+
return this.#refs[key];
|
|
60
|
+
// Build a new observable and cache it
|
|
61
|
+
const observable = chainable(builder(this.store));
|
|
62
|
+
this.#refs[key] = observable;
|
|
63
|
+
return observable;
|
|
64
|
+
}
|
|
65
|
+
}
|
package/dist/casts/index.d.ts
CHANGED
package/dist/casts/index.js
CHANGED
package/dist/casts/pubkey.d.ts
CHANGED
package/dist/casts/pubkey.js
CHANGED
package/dist/casts/user.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { Observable } from "rxjs";
|
|
1
2
|
import { NostrEvent } from "../helpers/event.js";
|
|
3
|
+
import { Filter } from "../helpers/filter.js";
|
|
2
4
|
import { ProfilePointer } from "../helpers/pointers.js";
|
|
3
5
|
import { ChainableObservable } from "../observable/chainable.js";
|
|
4
|
-
import type { CastRefEventStore } from "./cast.js";
|
|
6
|
+
import type { CastConstructor, CastRefEventStore } from "./cast.js";
|
|
5
7
|
import { PubkeyCast } from "./pubkey.js";
|
|
8
|
+
import { EventCast } from "./event.js";
|
|
6
9
|
/** Cast a Nostr event or pointer into a {@link User} */
|
|
7
10
|
export declare function castUser(event: NostrEvent, store: CastRefEventStore): User;
|
|
8
11
|
export declare function castUser(user: string | ProfilePointer, store: CastRefEventStore): User;
|
|
@@ -10,10 +13,19 @@ export declare function castUser(user: string | ProfilePointer, store: CastRefEv
|
|
|
10
13
|
export declare class User extends PubkeyCast {
|
|
11
14
|
/** A global cache of pubkey -> {@link User} */
|
|
12
15
|
static cache: Map<string, User>;
|
|
16
|
+
/** Returns the NIP-19 npub for this user */
|
|
13
17
|
get npub(): `npub1${string}`;
|
|
18
|
+
/** Returns the NIP-19 nprofile for this user */
|
|
14
19
|
get nprofile(): `nprofile1${string}`;
|
|
15
20
|
/** Subscribe to a replaceable event for this user */
|
|
16
21
|
replaceable(kind: number, identifier?: string, relays?: string[]): ChainableObservable<NostrEvent | undefined>;
|
|
17
22
|
/** Subscribe to an addressable event for this user */
|
|
18
23
|
addressable(kind: number, identifier: string, relays?: string[]): ChainableObservable<NostrEvent | undefined>;
|
|
24
|
+
/**
|
|
25
|
+
* Creates an observable of a timeline of events created by this user
|
|
26
|
+
* @param input - The filter(s) for the timeline or kind(s)
|
|
27
|
+
* @returns A timeline observable of events by the user rom the event store
|
|
28
|
+
*/
|
|
29
|
+
timeline$(input: Omit<Filter, "authors"> | Omit<Filter, "authors">[] | number | number[]): Observable<NostrEvent[]>;
|
|
30
|
+
timeline$<T extends EventCast>(input: Omit<Filter, "authors"> | Omit<Filter, "authors">[] | number | number[], cast?: CastConstructor<T>): Observable<T[]>;
|
|
19
31
|
}
|
package/dist/casts/user.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import hash_sum from "hash-sum";
|
|
1
2
|
import { nprofileEncode, npubEncode } from "../helpers/pointers.js";
|
|
2
3
|
import { chainable } from "../observable/chainable.js";
|
|
3
4
|
import { castPubkey, PubkeyCast } from "./pubkey.js";
|
|
5
|
+
import { castTimelineStream } from "../observable/cast-stream.js";
|
|
4
6
|
export function castUser(user, store) {
|
|
5
7
|
return castPubkey(user, User, store);
|
|
6
8
|
}
|
|
@@ -8,9 +10,11 @@ export function castUser(user, store) {
|
|
|
8
10
|
export class User extends PubkeyCast {
|
|
9
11
|
/** A global cache of pubkey -> {@link User} */
|
|
10
12
|
static cache = new Map();
|
|
13
|
+
/** Returns the NIP-19 npub for this user */
|
|
11
14
|
get npub() {
|
|
12
15
|
return npubEncode(this.pubkey);
|
|
13
16
|
}
|
|
17
|
+
/** Returns the NIP-19 nprofile for this user */
|
|
14
18
|
get nprofile() {
|
|
15
19
|
return nprofileEncode(this.pointer);
|
|
16
20
|
}
|
|
@@ -22,4 +26,24 @@ export class User extends PubkeyCast {
|
|
|
22
26
|
addressable(kind, identifier, relays) {
|
|
23
27
|
return chainable(this.store.addressable({ kind, pubkey: this.pointer.pubkey, identifier, relays }));
|
|
24
28
|
}
|
|
29
|
+
timeline$(input, cast) {
|
|
30
|
+
let filters = [];
|
|
31
|
+
if (typeof input === "number") {
|
|
32
|
+
filters.push({ kinds: [input] });
|
|
33
|
+
}
|
|
34
|
+
else if (Array.isArray(input)) {
|
|
35
|
+
filters.push(...input.map((f) => (typeof f === "number" ? { kinds: [f] } : f)));
|
|
36
|
+
}
|
|
37
|
+
else if (input instanceof Object) {
|
|
38
|
+
filters.push(input);
|
|
39
|
+
}
|
|
40
|
+
// Use hash_sum to create a unique key for the timeline observable
|
|
41
|
+
const key = "timeline$|" + hash_sum(filters);
|
|
42
|
+
const base$ = this.$$ref(key, (store) => store.timeline(filters.map((f) => ({ ...f, authors: [this.pubkey] }))));
|
|
43
|
+
// Cast the timeline stream into a cast if provided
|
|
44
|
+
if (cast)
|
|
45
|
+
return base$.pipe(castTimelineStream(cast));
|
|
46
|
+
else
|
|
47
|
+
return base$;
|
|
48
|
+
}
|
|
25
49
|
}
|
|
@@ -137,14 +137,24 @@ export class AsyncEventStore extends EventModels {
|
|
|
137
137
|
addSeenRelay(event, fromRelay);
|
|
138
138
|
// Get the replaceable identifier
|
|
139
139
|
const identifier = isReplaceable(event.kind) ? getReplaceableIdentifier(event) : undefined;
|
|
140
|
-
// Don't insert the event if there is already a
|
|
140
|
+
// Don't insert the event if there is already a winning version
|
|
141
|
+
// (NIP-01: newer created_at wins; on tie, lexicographically lower id wins).
|
|
141
142
|
if (this.keepOldVersions === false && isReplaceable(event.kind)) {
|
|
142
143
|
const existing = await this.database.getReplaceableHistory(event.kind, event.pubkey, identifier);
|
|
143
|
-
// If
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
// If the existing set has any event that beats the incoming one per
|
|
145
|
+
// NIP-01, the incoming event is rejected.
|
|
146
|
+
if (existing && existing.length > 0) {
|
|
147
|
+
let winner = existing[0];
|
|
148
|
+
for (const e of existing) {
|
|
149
|
+
if (e.created_at > winner.created_at || (e.created_at === winner.created_at && e.id < winner.id))
|
|
150
|
+
winner = e;
|
|
151
|
+
}
|
|
152
|
+
const incomingBeatsWinner = event.created_at > winner.created_at || (event.created_at === winner.created_at && event.id < winner.id);
|
|
153
|
+
if (!incomingBeatsWinner) {
|
|
154
|
+
if (EventStore.copySymbolsToDuplicateEvent(event, winner))
|
|
155
|
+
await this.update(winner);
|
|
156
|
+
return winner;
|
|
157
|
+
}
|
|
148
158
|
}
|
|
149
159
|
}
|
|
150
160
|
// Verify event before inserting into the database
|
|
@@ -173,17 +183,24 @@ export class AsyncEventStore extends EventModels {
|
|
|
173
183
|
if (EventStore.copySymbolsToDuplicateEvent(event, inserted))
|
|
174
184
|
await this.update(inserted);
|
|
175
185
|
}
|
|
176
|
-
// remove all
|
|
186
|
+
// remove all losing versions of the replaceable event
|
|
187
|
+
// (NIP-01: keep newest created_at; on tie, keep lowest id).
|
|
177
188
|
if (this.keepOldVersions === false && isReplaceable(event.kind)) {
|
|
178
189
|
const existing = await this.database.getReplaceableHistory(event.kind, event.pubkey, identifier);
|
|
179
190
|
if (existing && existing.length > 0) {
|
|
180
|
-
|
|
181
|
-
|
|
191
|
+
// Find the NIP-01 winner across all stored versions.
|
|
192
|
+
let winner = existing[0];
|
|
193
|
+
for (const e of existing) {
|
|
194
|
+
if (e.created_at > winner.created_at || (e.created_at === winner.created_at && e.id < winner.id))
|
|
195
|
+
winner = e;
|
|
196
|
+
}
|
|
197
|
+
const losers = existing.filter((e) => e !== winner);
|
|
198
|
+
for (const old of losers)
|
|
182
199
|
await this.remove(old);
|
|
183
|
-
// return the
|
|
200
|
+
// return the winning version of the replaceable event
|
|
184
201
|
// most of the time this will be === event, but not always
|
|
185
|
-
if (
|
|
186
|
-
return
|
|
202
|
+
if (losers.length > 0)
|
|
203
|
+
return winner;
|
|
187
204
|
}
|
|
188
205
|
}
|
|
189
206
|
// Add event to expiration manager if it has an expiration tag
|
|
@@ -161,14 +161,24 @@ export class EventStore extends EventModels {
|
|
|
161
161
|
addSeenRelay(event, fromRelay);
|
|
162
162
|
// Get the replaceable identifier
|
|
163
163
|
const identifier = isReplaceable(event.kind) ? getReplaceableIdentifier(event) : undefined;
|
|
164
|
-
// Don't insert the event if there is already a
|
|
164
|
+
// Don't insert the event if there is already a winning version
|
|
165
|
+
// (NIP-01: newer created_at wins; on tie, lexicographically lower id wins).
|
|
165
166
|
if (this.keepOldVersions === false && isReplaceable(event.kind)) {
|
|
166
167
|
const existing = this.database.getReplaceableHistory(event.kind, event.pubkey, identifier);
|
|
167
|
-
// If
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
168
|
+
// If the existing set has any event that beats the incoming one per
|
|
169
|
+
// NIP-01, the incoming event is rejected.
|
|
170
|
+
if (existing && existing.length > 0) {
|
|
171
|
+
let winner = existing[0];
|
|
172
|
+
for (const e of existing) {
|
|
173
|
+
if (e.created_at > winner.created_at || (e.created_at === winner.created_at && e.id < winner.id))
|
|
174
|
+
winner = e;
|
|
175
|
+
}
|
|
176
|
+
const incomingBeatsWinner = event.created_at > winner.created_at || (event.created_at === winner.created_at && event.id < winner.id);
|
|
177
|
+
if (!incomingBeatsWinner) {
|
|
178
|
+
if (EventStore.copySymbolsToDuplicateEvent(event, winner))
|
|
179
|
+
this.update(winner);
|
|
180
|
+
return winner;
|
|
181
|
+
}
|
|
172
182
|
}
|
|
173
183
|
}
|
|
174
184
|
// Verify event before inserting into the database
|
|
@@ -197,17 +207,24 @@ export class EventStore extends EventModels {
|
|
|
197
207
|
if (EventStore.copySymbolsToDuplicateEvent(event, inserted))
|
|
198
208
|
this.update(inserted);
|
|
199
209
|
}
|
|
200
|
-
// remove all
|
|
210
|
+
// remove all losing versions of the replaceable event
|
|
211
|
+
// (NIP-01: keep newest created_at; on tie, keep lowest id).
|
|
201
212
|
if (this.keepOldVersions === false && isReplaceable(event.kind)) {
|
|
202
213
|
const existing = this.database.getReplaceableHistory(event.kind, event.pubkey, identifier);
|
|
203
214
|
if (existing && existing.length > 0) {
|
|
204
|
-
|
|
205
|
-
|
|
215
|
+
// Find the NIP-01 winner across all stored versions.
|
|
216
|
+
let winner = existing[0];
|
|
217
|
+
for (const e of existing) {
|
|
218
|
+
if (e.created_at > winner.created_at || (e.created_at === winner.created_at && e.id < winner.id))
|
|
219
|
+
winner = e;
|
|
220
|
+
}
|
|
221
|
+
const losers = existing.filter((e) => e !== winner);
|
|
222
|
+
for (const old of losers)
|
|
206
223
|
this.remove(old);
|
|
207
|
-
// return the
|
|
224
|
+
// return the winning version of the replaceable event
|
|
208
225
|
// most of the time this will be === event, but not always
|
|
209
|
-
if (
|
|
210
|
-
return
|
|
226
|
+
if (losers.length > 0)
|
|
227
|
+
return winner;
|
|
211
228
|
}
|
|
212
229
|
}
|
|
213
230
|
// Add event to expiration manager if it has an expiration tag
|
|
@@ -39,6 +39,8 @@ export declare function isProfilePointer(pointer: any): pointer is ProfilePointe
|
|
|
39
39
|
export declare function isEventPointer(pointer: any): pointer is EventPointer;
|
|
40
40
|
/** Returns the stringified NIP-19 encoded naddr address pointer for an AddressPointer. */
|
|
41
41
|
export declare function getReplaceableAddressFromPointer(pointer: AddressPointer): string;
|
|
42
|
+
/** Returns the replaceable coordinate for a replaceable event ( used for "a" tags to reference replaceable events ). */
|
|
43
|
+
export declare function getReplaceableAddressForEvent(event: NostrEvent): string | null;
|
|
42
44
|
/** Returns an AddressPointer for a replaceable event. Returns null if the event is not addressable or replaceable. */
|
|
43
45
|
export declare function getAddressPointerForEvent(event: NostrEvent, relays?: string[]): AddressPointer | null;
|
|
44
46
|
/** Returns an EventPointer for an event */
|
package/dist/helpers/pointers.js
CHANGED
|
@@ -204,6 +204,13 @@ export function isEventPointer(pointer) {
|
|
|
204
204
|
export function getReplaceableAddressFromPointer(pointer) {
|
|
205
205
|
return pointer.kind + ":" + pointer.pubkey + ":" + pointer.identifier;
|
|
206
206
|
}
|
|
207
|
+
/** Returns the replaceable coordinate for a replaceable event ( used for "a" tags to reference replaceable events ). */
|
|
208
|
+
export function getReplaceableAddressForEvent(event) {
|
|
209
|
+
if (!isReplaceableKind(event.kind) && !isAddressableKind(event.kind))
|
|
210
|
+
return null;
|
|
211
|
+
const d = getReplaceableIdentifier(event);
|
|
212
|
+
return event.kind + ":" + event.pubkey + ":" + d;
|
|
213
|
+
}
|
|
207
214
|
/** Returns an AddressPointer for a replaceable event. Returns null if the event is not addressable or replaceable. */
|
|
208
215
|
export function getAddressPointerForEvent(event, relays) {
|
|
209
216
|
if (!isAddressableKind(event.kind) && !isReplaceableKind(event.kind))
|
package/dist/helpers/regexp.js
CHANGED
|
@@ -34,10 +34,10 @@ export const Tokens = {
|
|
|
34
34
|
return Expressions.link;
|
|
35
35
|
},
|
|
36
36
|
get cashu() {
|
|
37
|
-
return new RegExp(`(?<=^|\\s)${Expressions.cashu.source}`, "gi");
|
|
37
|
+
return new RegExp(`(?<=^|\\s|\\s\\()${Expressions.cashu.source}`, "gi");
|
|
38
38
|
},
|
|
39
39
|
get nostrLink() {
|
|
40
|
-
return new RegExp(`(?<=^|\\s)${Expressions.nostrLink.source}`, "gi");
|
|
40
|
+
return new RegExp(`(?<=^|\\s|\\s\\()${Expressions.nostrLink.source}`, "gi");
|
|
41
41
|
},
|
|
42
42
|
get emoji() {
|
|
43
43
|
return Expressions.emoji;
|
|
@@ -46,9 +46,9 @@ export const Tokens = {
|
|
|
46
46
|
return Expressions.hashtag;
|
|
47
47
|
},
|
|
48
48
|
get lightning() {
|
|
49
|
-
return new RegExp(`(?<=^|\\s)${Expressions.lightning.source}`, "gim");
|
|
49
|
+
return new RegExp(`(?<=^|\\s|\\s\\()${Expressions.lightning.source}`, "gim");
|
|
50
50
|
},
|
|
51
51
|
get blossom() {
|
|
52
|
-
return new RegExp(`(?<=^|\\s)${Expressions.blossom.source}`, "g");
|
|
52
|
+
return new RegExp(`(?<=^|\\s|\\s\\()${Expressions.blossom.source}`, "g");
|
|
53
53
|
},
|
|
54
54
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { OperatorFunction } from "rxjs";
|
|
2
|
+
import type { CastConstructor, CastRefEventStore } from "../casts/cast.js";
|
|
3
|
+
import { EventCast } from "../casts/index.js";
|
|
4
|
+
import { NostrEvent } from "../helpers/event.js";
|
|
5
|
+
/** Casts an event to a specific type */
|
|
6
|
+
export declare function castEventStream<C extends EventCast>(cls: CastConstructor<C>, store?: CastRefEventStore): OperatorFunction<NostrEvent | undefined, C | undefined>;
|
|
7
|
+
/** Casts and array of events to an array of casted events and filters out undefined values */
|
|
8
|
+
export declare function castTimelineStream<C extends EventCast>(cls: CastConstructor<C>, store?: CastRefEventStore): OperatorFunction<NostrEvent[], C[]>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { map } from "rxjs";
|
|
2
|
+
import { castEvent } from "../casts/index.js";
|
|
3
|
+
import { defined } from "./defined.js";
|
|
4
|
+
/** Casts an event to a specific type */
|
|
5
|
+
export function castEventStream(cls, store) {
|
|
6
|
+
return (source) => source.pipe(map((event) => {
|
|
7
|
+
if (!event)
|
|
8
|
+
return undefined;
|
|
9
|
+
try {
|
|
10
|
+
return castEvent(event, cls, store);
|
|
11
|
+
}
|
|
12
|
+
catch { }
|
|
13
|
+
return undefined;
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
/** Casts and array of events to an array of casted events and filters out undefined values */
|
|
17
|
+
export function castTimelineStream(cls, store) {
|
|
18
|
+
return (source) => source.pipe(map((events) => {
|
|
19
|
+
const castedEvents = [];
|
|
20
|
+
for (const event of events) {
|
|
21
|
+
try {
|
|
22
|
+
const casted = castEvent(event, cls, store);
|
|
23
|
+
castedEvents.push(casted);
|
|
24
|
+
}
|
|
25
|
+
catch { }
|
|
26
|
+
}
|
|
27
|
+
return castedEvents;
|
|
28
|
+
}), defined());
|
|
29
|
+
}
|