applesauce-core 2.3.0 → 3.0.1
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-store/event-set.js +5 -3
- package/dist/event-store/event-store.d.ts +54 -24
- package/dist/event-store/event-store.js +139 -47
- package/dist/event-store/interface.d.ts +36 -18
- package/dist/helpers/calendar-event.d.ts +36 -0
- package/dist/helpers/calendar-event.js +110 -0
- package/dist/helpers/calendar-rsvp.d.ts +15 -0
- package/dist/helpers/calendar-rsvp.js +38 -0
- package/dist/helpers/calendar.d.ts +6 -0
- package/dist/helpers/calendar.js +11 -0
- package/dist/helpers/encrypted-content.d.ts +18 -10
- package/dist/helpers/encrypted-content.js +11 -3
- package/dist/helpers/event-cache.d.ts +15 -0
- package/dist/helpers/event-cache.js +32 -0
- package/dist/helpers/event.d.ts +1 -4
- package/dist/helpers/event.js +2 -10
- package/dist/helpers/expiration.js +1 -2
- package/dist/helpers/hidden-content.d.ts +3 -3
- package/dist/helpers/hidden-content.js +2 -2
- package/dist/helpers/hidden-tags.d.ts +5 -10
- package/dist/helpers/hidden-tags.js +3 -3
- package/dist/helpers/highlight.d.ts +45 -0
- package/dist/helpers/highlight.js +76 -0
- package/dist/helpers/index.d.ts +8 -0
- package/dist/helpers/index.js +8 -0
- package/dist/helpers/pointers.js +1 -1
- package/dist/helpers/poll.d.ts +46 -0
- package/dist/helpers/poll.js +78 -0
- package/dist/helpers/stream-chat.d.ts +4 -0
- package/dist/helpers/stream-chat.js +9 -0
- package/dist/helpers/stream.d.ts +31 -0
- package/dist/helpers/stream.js +81 -0
- package/dist/logger.d.ts +1 -0
- package/dist/logger.js +1 -0
- package/dist/models/blossom.d.ts +2 -1
- package/dist/models/blossom.js +4 -2
- package/dist/models/calendar.d.ts +6 -0
- package/dist/models/calendar.js +15 -0
- package/dist/models/common.d.ts +14 -10
- package/dist/models/common.js +47 -76
- package/dist/models/contacts.d.ts +1 -1
- package/dist/models/contacts.js +4 -2
- package/dist/models/index.d.ts +1 -0
- package/dist/models/index.js +1 -0
- package/dist/models/mailboxes.d.ts +2 -1
- package/dist/models/mailboxes.js +4 -2
- package/dist/models/mutes.d.ts +3 -2
- package/dist/models/mutes.js +4 -2
- package/dist/models/profile.d.ts +2 -1
- package/dist/models/profile.js +4 -2
- package/package.json +1 -1
- package/dist/event-store/common.d.ts +0 -1
- package/dist/event-store/common.js +0 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { getTagValue } from "./event-tags.js";
|
|
2
|
+
import { getAddressPointerFromATag, getEventPointerFromETag, getProfilePointerFromPTag } from "./pointers.js";
|
|
3
|
+
import { isATag, isETag, isPTag } from "./tags.js";
|
|
4
|
+
export const CALENDAR_EVENT_RSVP_KIND = 31925;
|
|
5
|
+
/** Gets the RSVP status from a calendar event RSVP */
|
|
6
|
+
export function getRSVPStatus(event) {
|
|
7
|
+
const status = getTagValue(event, "status");
|
|
8
|
+
return status && ["accepted", "declined", "tentative"].includes(status) ? status : undefined;
|
|
9
|
+
}
|
|
10
|
+
/** Gets the free/busy status from a calendar event RSVP (will be undefined if the RSVP is declined) */
|
|
11
|
+
export function getRSVPFreeBusy(event) {
|
|
12
|
+
const status = getRSVPStatus(event);
|
|
13
|
+
if (status === "declined")
|
|
14
|
+
return undefined;
|
|
15
|
+
const fb = getTagValue(event, "fb");
|
|
16
|
+
return fb && ["free", "busy"].includes(fb) ? fb : undefined;
|
|
17
|
+
}
|
|
18
|
+
/** Gets the referenced calendar event coordinate that the RSVP is responding to */
|
|
19
|
+
export function getRSVPAddressPointer(event) {
|
|
20
|
+
const tag = event.tags.find(isATag);
|
|
21
|
+
if (!tag)
|
|
22
|
+
return undefined;
|
|
23
|
+
return getAddressPointerFromATag(tag);
|
|
24
|
+
}
|
|
25
|
+
/** Gets the referenced calendar event pointer that the RSVP is responding to */
|
|
26
|
+
export function getRSVPEventPointer(event) {
|
|
27
|
+
const tag = event.tags.find(isETag);
|
|
28
|
+
if (!tag)
|
|
29
|
+
return undefined;
|
|
30
|
+
return getEventPointerFromETag(tag);
|
|
31
|
+
}
|
|
32
|
+
/** Gets the profile pointer that the RSVP is responding to */
|
|
33
|
+
export function getRSVPProfilePointer(event) {
|
|
34
|
+
const tag = event.tags.find(isPTag);
|
|
35
|
+
if (!tag)
|
|
36
|
+
return undefined;
|
|
37
|
+
return getProfilePointerFromPTag(tag);
|
|
38
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NostrEvent } from "nostr-tools";
|
|
2
|
+
import { AddressPointer } from "nostr-tools/nip19";
|
|
3
|
+
/** Gets the title of a calendar */
|
|
4
|
+
export declare function getCalendarTitle(event: NostrEvent): string | undefined;
|
|
5
|
+
/** Gets the address pointers to all the events on the calendar */
|
|
6
|
+
export declare function getCalendarAddressPointers(event: NostrEvent): AddressPointer[];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getTagValue } from "./event-tags.js";
|
|
2
|
+
import { getAddressPointerFromATag } from "./pointers.js";
|
|
3
|
+
import { isATag } from "./tags.js";
|
|
4
|
+
/** Gets the title of a calendar */
|
|
5
|
+
export function getCalendarTitle(event) {
|
|
6
|
+
return getTagValue(event, "title");
|
|
7
|
+
}
|
|
8
|
+
/** Gets the address pointers to all the events on the calendar */
|
|
9
|
+
export function getCalendarAddressPointers(event) {
|
|
10
|
+
return event.tags.filter(isATag).map(getAddressPointerFromATag);
|
|
11
|
+
}
|
|
@@ -10,18 +10,26 @@ export interface EncryptedContentSigner {
|
|
|
10
10
|
decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export declare function setEncryptedContentEncryptionMethod(kind: number, method: "nip04" | "nip44"): number;
|
|
17
|
-
/** Returns either nip04 or nip44 encryption methods depending on event kind */
|
|
18
|
-
export declare function getEncryptedContentEncryptionMethods(kind: number, signer: EncryptedContentSigner): {
|
|
13
|
+
export type EncryptionMethod = "nip04" | "nip44";
|
|
14
|
+
/** A pair of encryption methods for encrypting and decrypting event content */
|
|
15
|
+
export interface EncryptionMethods {
|
|
19
16
|
encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
|
|
20
17
|
decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
}
|
|
19
|
+
/** Various event kinds that can have encrypted content and which encryption method they use */
|
|
20
|
+
export declare const EventContentEncryptionMethod: Record<number, EncryptionMethod>;
|
|
21
|
+
/** Sets the encryption method that is used for the contents of a specific event kind */
|
|
22
|
+
export declare function setEncryptedContentEncryptionMethod(kind: number, method: EncryptionMethod): number;
|
|
23
|
+
/**
|
|
24
|
+
* Returns either nip04 or nip44 encryption methods depending on event kind
|
|
25
|
+
* @param kind The event kind to get the encryption method for
|
|
26
|
+
* @param signer The signer to use to get the encryption methods
|
|
27
|
+
* @param override The encryption method to use instead of the default
|
|
28
|
+
* @throws If the event kind does not support encrypted content
|
|
29
|
+
* @throws If the signer does not support the encryption method
|
|
30
|
+
* @returns The encryption methods for the event kind
|
|
31
|
+
*/
|
|
32
|
+
export declare function getEncryptedContentEncryptionMethods(kind: number, signer: EncryptedContentSigner, override?: EncryptionMethod): EncryptionMethods;
|
|
25
33
|
/** Checks if an event can have encrypted content */
|
|
26
34
|
export declare function canHaveEncryptedContent(kind: number): boolean;
|
|
27
35
|
/** Checks if an event has encrypted content */
|
|
@@ -13,9 +13,17 @@ export function setEncryptedContentEncryptionMethod(kind, method) {
|
|
|
13
13
|
EventContentEncryptionMethod[kind] = method;
|
|
14
14
|
return kind;
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Returns either nip04 or nip44 encryption methods depending on event kind
|
|
18
|
+
* @param kind The event kind to get the encryption method for
|
|
19
|
+
* @param signer The signer to use to get the encryption methods
|
|
20
|
+
* @param override The encryption method to use instead of the default
|
|
21
|
+
* @throws If the event kind does not support encrypted content
|
|
22
|
+
* @throws If the signer does not support the encryption method
|
|
23
|
+
* @returns The encryption methods for the event kind
|
|
24
|
+
*/
|
|
25
|
+
export function getEncryptedContentEncryptionMethods(kind, signer, override) {
|
|
26
|
+
const method = override ?? EventContentEncryptionMethod[kind];
|
|
19
27
|
if (!method)
|
|
20
28
|
throw new Error(`Event kind ${kind} does not support encrypted content`);
|
|
21
29
|
const encryption = signer[method];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { NostrEvent } from "nostr-tools";
|
|
2
|
+
import { IEventStoreStreams } from "../event-store/interface.js";
|
|
3
|
+
/**
|
|
4
|
+
* Setups a process to write batches of new events from an event store to a cache
|
|
5
|
+
* @param eventStore - The event store to read from
|
|
6
|
+
* @param write - The function to write the events to the cache
|
|
7
|
+
* @param opts - The options for the process
|
|
8
|
+
* @param opts.batchTime - The time to wait before writing a batch (default: 5 seconds)
|
|
9
|
+
* @param opts.maxBatchSize - The maximum number of events to write in a batch
|
|
10
|
+
* @returns A function to stop the process
|
|
11
|
+
*/
|
|
12
|
+
export declare function presistEventsToCache(eventStore: IEventStoreStreams, write: (events: NostrEvent[]) => Promise<void>, opts?: {
|
|
13
|
+
maxBatchSize?: number;
|
|
14
|
+
batchTime?: number;
|
|
15
|
+
}): () => void;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { bufferTime, filter } from "rxjs";
|
|
2
|
+
import { logger } from "../logger.js";
|
|
3
|
+
import { isFromCache } from "./index.js";
|
|
4
|
+
const log = logger.extend("event-cache");
|
|
5
|
+
/**
|
|
6
|
+
* Setups a process to write batches of new events from an event store to a cache
|
|
7
|
+
* @param eventStore - The event store to read from
|
|
8
|
+
* @param write - The function to write the events to the cache
|
|
9
|
+
* @param opts - The options for the process
|
|
10
|
+
* @param opts.batchTime - The time to wait before writing a batch (default: 5 seconds)
|
|
11
|
+
* @param opts.maxBatchSize - The maximum number of events to write in a batch
|
|
12
|
+
* @returns A function to stop the process
|
|
13
|
+
*/
|
|
14
|
+
export function presistEventsToCache(eventStore, write, opts) {
|
|
15
|
+
const time = opts?.batchTime ?? 5_000;
|
|
16
|
+
// Save all new events to the cache
|
|
17
|
+
const sub = eventStore.insert$
|
|
18
|
+
.pipe(
|
|
19
|
+
// Only select events that are not from the cache
|
|
20
|
+
filter((e) => !isFromCache(e)),
|
|
21
|
+
// Buffer events for 5 seconds
|
|
22
|
+
opts?.maxBatchSize ? bufferTime(time, undefined, opts?.maxBatchSize ?? 100) : bufferTime(time),
|
|
23
|
+
// Only select buffers with events
|
|
24
|
+
filter((b) => b.length > 0))
|
|
25
|
+
.subscribe((events) => {
|
|
26
|
+
// Save all new events to the cache
|
|
27
|
+
write(events)
|
|
28
|
+
.then(() => log(`Saved ${events.length} events to cache`))
|
|
29
|
+
.catch((e) => log(`Failed to save ${events.length} events to cache`, e));
|
|
30
|
+
});
|
|
31
|
+
return () => sub.unsubscribe();
|
|
32
|
+
}
|
package/dist/helpers/event.d.ts
CHANGED
|
@@ -39,10 +39,7 @@ export declare function isFromCache(event: NostrEvent): boolean;
|
|
|
39
39
|
export declare function getParentEventStore<T extends object>(event: T): IEventStore | undefined;
|
|
40
40
|
/** Notifies the events parent store that an event has been updated */
|
|
41
41
|
export declare function notifyEventUpdate(event: NostrEvent): void;
|
|
42
|
-
/**
|
|
43
|
-
* Returns the replaceable identifier for a replaceable event
|
|
44
|
-
* @throws
|
|
45
|
-
*/
|
|
42
|
+
/** Returns the replaceable identifier for a replaceable event */
|
|
46
43
|
export declare function getReplaceableIdentifier(event: NostrEvent): string;
|
|
47
44
|
/** Checks if an event is a NIP-70 protected event */
|
|
48
45
|
export declare function isProtectedEvent(event: NostrEvent): boolean;
|
package/dist/helpers/event.js
CHANGED
|
@@ -85,18 +85,10 @@ export function notifyEventUpdate(event) {
|
|
|
85
85
|
if (eventStore)
|
|
86
86
|
eventStore.update(event);
|
|
87
87
|
}
|
|
88
|
-
/**
|
|
89
|
-
* Returns the replaceable identifier for a replaceable event
|
|
90
|
-
* @throws
|
|
91
|
-
*/
|
|
88
|
+
/** Returns the replaceable identifier for a replaceable event */
|
|
92
89
|
export function getReplaceableIdentifier(event) {
|
|
93
|
-
if (!isAddressableKind(event.kind))
|
|
94
|
-
throw new Error("Event is not addressable");
|
|
95
90
|
return getOrComputeCachedValue(event, ReplaceableIdentifierSymbol, () => {
|
|
96
|
-
|
|
97
|
-
if (d === undefined)
|
|
98
|
-
throw new Error("Event missing identifier");
|
|
99
|
-
return d;
|
|
91
|
+
return event.tags.find((t) => t[0] === "d")?.[1] ?? "";
|
|
100
92
|
});
|
|
101
93
|
}
|
|
102
94
|
/** Checks if an event is a NIP-70 protected event */
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { getOrComputeCachedValue } from "./cache.js";
|
|
2
2
|
import { unixNow } from "./time.js";
|
|
3
|
-
import { getTagValue } from "./event-tags.js";
|
|
4
3
|
export const ExpirationTimestampSymbol = Symbol("expiration-timestamp");
|
|
5
4
|
/** Returns the NIP-40 expiration timestamp for an event */
|
|
6
5
|
export function getExpirationTimestamp(event) {
|
|
7
6
|
return getOrComputeCachedValue(event, ExpirationTimestampSymbol, () => {
|
|
8
|
-
const expiration =
|
|
7
|
+
const expiration = event.tags.find((t) => t[0] === "expiration")?.[1];
|
|
9
8
|
return expiration ? parseInt(expiration) : undefined;
|
|
10
9
|
});
|
|
11
10
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EncryptedContentSigner, getEncryptedContentEncryptionMethods } from "./encrypted-content.js";
|
|
1
|
+
import { EncryptedContentSigner, EncryptionMethod, getEncryptedContentEncryptionMethods } from "./encrypted-content.js";
|
|
2
2
|
export declare const HiddenContentSymbol: symbol;
|
|
3
3
|
export interface HiddenContentSigner extends EncryptedContentSigner {
|
|
4
4
|
}
|
|
@@ -6,7 +6,7 @@ export declare const getHiddenContentEncryptionMethods: typeof getEncryptedConte
|
|
|
6
6
|
/** Various event kinds that can have hidden content */
|
|
7
7
|
export declare const HiddenContentKinds: Set<number>;
|
|
8
8
|
/** Sets the encryption method for hidden content on a kind */
|
|
9
|
-
export declare function setHiddenContentEncryptionMethod(kind: number, method:
|
|
9
|
+
export declare function setHiddenContentEncryptionMethod(kind: number, method: EncryptionMethod): number;
|
|
10
10
|
/** Checks if an event can have hidden content */
|
|
11
11
|
export declare function canHaveHiddenContent(kind: number): boolean;
|
|
12
12
|
/** Checks if an event has hidden content */
|
|
@@ -31,7 +31,7 @@ export declare function unlockHiddenContent<T extends {
|
|
|
31
31
|
kind: number;
|
|
32
32
|
pubkey: string;
|
|
33
33
|
content: string;
|
|
34
|
-
}>(event: T, signer: EncryptedContentSigner): Promise<string>;
|
|
34
|
+
}>(event: T, signer: EncryptedContentSigner, override?: EncryptionMethod): Promise<string>;
|
|
35
35
|
/**
|
|
36
36
|
* Sets the hidden content on an event and updates it if its part of an event store
|
|
37
37
|
* @throws
|
|
@@ -34,10 +34,10 @@ export function getHiddenContent(event) {
|
|
|
34
34
|
* @param signer A signer to use to decrypt the content
|
|
35
35
|
* @throws
|
|
36
36
|
*/
|
|
37
|
-
export async function unlockHiddenContent(event, signer) {
|
|
37
|
+
export async function unlockHiddenContent(event, signer, override) {
|
|
38
38
|
if (!canHaveHiddenContent(event.kind))
|
|
39
39
|
throw new Error("Event kind does not support hidden content");
|
|
40
|
-
const encryption = getEncryptedContentEncryptionMethods(event.kind, signer);
|
|
40
|
+
const encryption = getEncryptedContentEncryptionMethods(event.kind, signer, override);
|
|
41
41
|
const plaintext = await encryption.decrypt(event.pubkey, event.content);
|
|
42
42
|
setHiddenContentCache(event, plaintext);
|
|
43
43
|
return plaintext;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { HiddenContentSigner } from "./hidden-content.js";
|
|
2
|
+
import { EncryptionMethod } from "./encrypted-content.js";
|
|
2
3
|
export declare const HiddenTagsSymbol: unique symbol;
|
|
3
4
|
/** Various event kinds that can have hidden tags */
|
|
4
5
|
export declare const HiddenTagsKinds: Set<number>;
|
|
5
6
|
/** Checks if an event can have hidden tags */
|
|
6
7
|
export declare function canHaveHiddenTags(kind: number): boolean;
|
|
7
8
|
/** Sets the type of encryption to use for hidden tags on a kind */
|
|
8
|
-
export declare function setHiddenTagsEncryptionMethod(kind: number, method:
|
|
9
|
+
export declare function setHiddenTagsEncryptionMethod(kind: number, method: EncryptionMethod): number;
|
|
9
10
|
/** Checks if an event has hidden tags */
|
|
10
11
|
export declare function hasHiddenTags<T extends {
|
|
11
12
|
kind: number;
|
|
@@ -19,25 +20,19 @@ export declare function getHiddenTags<T extends {
|
|
|
19
20
|
/** Checks if the hidden tags are locked */
|
|
20
21
|
export declare function isHiddenTagsLocked<T extends object>(event: T): boolean;
|
|
21
22
|
/** Returns either nip04 or nip44 encryption method depending on list kind */
|
|
22
|
-
export declare function getHiddenTagsEncryptionMethods(kind: number, signer: HiddenContentSigner):
|
|
23
|
-
encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
|
|
24
|
-
decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
|
|
25
|
-
} | {
|
|
26
|
-
encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
|
|
27
|
-
decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
|
|
28
|
-
};
|
|
23
|
+
export declare function getHiddenTagsEncryptionMethods(kind: number, signer: HiddenContentSigner): import("./encrypted-content.js").EncryptionMethods;
|
|
29
24
|
/**
|
|
30
25
|
* Decrypts the private list
|
|
31
26
|
* @param event The list event to decrypt
|
|
32
27
|
* @param signer A signer to use to decrypt the tags
|
|
33
|
-
* @param
|
|
28
|
+
* @param override The encryption method to use instead of the default
|
|
34
29
|
* @throws
|
|
35
30
|
*/
|
|
36
31
|
export declare function unlockHiddenTags<T extends {
|
|
37
32
|
kind: number;
|
|
38
33
|
pubkey: string;
|
|
39
34
|
content: string;
|
|
40
|
-
}>(event: T, signer: HiddenContentSigner): Promise<string[][]>;
|
|
35
|
+
}>(event: T, signer: HiddenContentSigner, override?: EncryptionMethod): Promise<string[][]>;
|
|
41
36
|
/**
|
|
42
37
|
* Sets the hidden tags on an event and updates it if its part of an event store
|
|
43
38
|
* @throws
|
|
@@ -58,15 +58,15 @@ export function getHiddenTagsEncryptionMethods(kind, signer) {
|
|
|
58
58
|
* Decrypts the private list
|
|
59
59
|
* @param event The list event to decrypt
|
|
60
60
|
* @param signer A signer to use to decrypt the tags
|
|
61
|
-
* @param
|
|
61
|
+
* @param override The encryption method to use instead of the default
|
|
62
62
|
* @throws
|
|
63
63
|
*/
|
|
64
|
-
export async function unlockHiddenTags(event, signer) {
|
|
64
|
+
export async function unlockHiddenTags(event, signer, override) {
|
|
65
65
|
if (!canHaveHiddenTags(event.kind))
|
|
66
66
|
throw new Error("Event kind does not support hidden tags");
|
|
67
67
|
// unlock hidden content is needed
|
|
68
68
|
if (isHiddenContentLocked(event))
|
|
69
|
-
await unlockHiddenContent(event, signer);
|
|
69
|
+
await unlockHiddenContent(event, signer, override);
|
|
70
70
|
return getHiddenTags(event);
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { NostrEvent } from "nostr-tools";
|
|
2
|
+
import { AddressPointer, EventPointer, ProfilePointer } from "nostr-tools/nip19";
|
|
3
|
+
export declare const HighlightSourceEventPointerSymbol: unique symbol;
|
|
4
|
+
export declare const HighlightSourceAddressPointerSymbol: unique symbol;
|
|
5
|
+
export declare const HighlightAttributionSymbol: unique symbol;
|
|
6
|
+
/**
|
|
7
|
+
* Get the highlighted content from a highlight event
|
|
8
|
+
* Returns the content field which contains the highlighted text
|
|
9
|
+
*/
|
|
10
|
+
export declare function getHighlightText(event: NostrEvent): string;
|
|
11
|
+
/**
|
|
12
|
+
* Get the source event pointer that was highlighted (from 'e' tag)
|
|
13
|
+
* Returns undefined if no event reference is found
|
|
14
|
+
*/
|
|
15
|
+
export declare function getHighlightSourceEventPointer(event: NostrEvent): EventPointer | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Get the source address pointer that was highlighted (from 'a' tag)
|
|
18
|
+
* Returns undefined if no address reference is found
|
|
19
|
+
*/
|
|
20
|
+
export declare function getHighlightSourceAddressPointer(event: NostrEvent): AddressPointer | undefined;
|
|
21
|
+
/** Get the source URL that was highlighted (from 'r' tag) */
|
|
22
|
+
export declare function getHighlightSourceUrl(event: NostrEvent): string | undefined;
|
|
23
|
+
/** Role of an attributed profiles in a highlight */
|
|
24
|
+
export type HighlightAttributionRole = "author" | "editor" | "mention" | string;
|
|
25
|
+
/** Attribution information for a highlight */
|
|
26
|
+
export type HighlightAttribution = ProfilePointer & {
|
|
27
|
+
/** Role of the attributed profile */
|
|
28
|
+
role?: HighlightAttributionRole;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Get attribution information from p tags
|
|
32
|
+
* Parses p tags to extract authors, editors, and other attributed individuals
|
|
33
|
+
*/
|
|
34
|
+
export declare function getHighlightAttributions(event: NostrEvent): HighlightAttribution[];
|
|
35
|
+
/**
|
|
36
|
+
* Get the context text for a highlight (from 'context' tag)
|
|
37
|
+
* This provides surrounding content to give context to the highlight
|
|
38
|
+
*/
|
|
39
|
+
export declare function getHighlightContext(event: NostrEvent): string | undefined;
|
|
40
|
+
/** Get the comment for a highlight (from 'comment' tag) */
|
|
41
|
+
export declare function getHighlightComment(event: NostrEvent): string | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Check if the highlight has any source reference (event, address, or URL)
|
|
44
|
+
*/
|
|
45
|
+
export declare function hasHighlightSource(event: NostrEvent): boolean;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { getOrComputeCachedValue } from "./cache.js";
|
|
2
|
+
import { getTagValue } from "./event-tags.js";
|
|
3
|
+
import { getAddressPointerFromATag, getEventPointerFromETag, getProfilePointerFromPTag } from "./pointers.js";
|
|
4
|
+
import { isATag, isETag, isPTag } from "./tags.js";
|
|
5
|
+
// Symbol constants for caching
|
|
6
|
+
export const HighlightSourceEventPointerSymbol = Symbol.for("highlight-source-event-pointer");
|
|
7
|
+
export const HighlightSourceAddressPointerSymbol = Symbol.for("highlight-source-address-pointer");
|
|
8
|
+
export const HighlightAttributionSymbol = Symbol.for("highlight-attribution");
|
|
9
|
+
/**
|
|
10
|
+
* Get the highlighted content from a highlight event
|
|
11
|
+
* Returns the content field which contains the highlighted text
|
|
12
|
+
*/
|
|
13
|
+
export function getHighlightText(event) {
|
|
14
|
+
return event.content;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get the source event pointer that was highlighted (from 'e' tag)
|
|
18
|
+
* Returns undefined if no event reference is found
|
|
19
|
+
*/
|
|
20
|
+
export function getHighlightSourceEventPointer(event) {
|
|
21
|
+
return getOrComputeCachedValue(event, HighlightSourceEventPointerSymbol, () => {
|
|
22
|
+
const eTag = event.tags.find(isETag);
|
|
23
|
+
return eTag ? getEventPointerFromETag(eTag) : undefined;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get the source address pointer that was highlighted (from 'a' tag)
|
|
28
|
+
* Returns undefined if no address reference is found
|
|
29
|
+
*/
|
|
30
|
+
export function getHighlightSourceAddressPointer(event) {
|
|
31
|
+
return getOrComputeCachedValue(event, HighlightSourceAddressPointerSymbol, () => {
|
|
32
|
+
const aTag = event.tags.find(isATag);
|
|
33
|
+
return aTag ? getAddressPointerFromATag(aTag) : undefined;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/** Get the source URL that was highlighted (from 'r' tag) */
|
|
37
|
+
export function getHighlightSourceUrl(event) {
|
|
38
|
+
return getTagValue(event, "r");
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get attribution information from p tags
|
|
42
|
+
* Parses p tags to extract authors, editors, and other attributed individuals
|
|
43
|
+
*/
|
|
44
|
+
export function getHighlightAttributions(event) {
|
|
45
|
+
return getOrComputeCachedValue(event, HighlightAttributionSymbol, () => {
|
|
46
|
+
const attributions = [];
|
|
47
|
+
const pTags = event.tags.filter(isPTag);
|
|
48
|
+
for (const pTag of pTags) {
|
|
49
|
+
const pointer = getProfilePointerFromPTag(pTag);
|
|
50
|
+
const role = pTag[3] || "other"; // Role is the 4th element (index 3)
|
|
51
|
+
const entry = { ...pointer, role };
|
|
52
|
+
// Categorize by role
|
|
53
|
+
attributions.push(entry);
|
|
54
|
+
}
|
|
55
|
+
return attributions;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get the context text for a highlight (from 'context' tag)
|
|
60
|
+
* This provides surrounding content to give context to the highlight
|
|
61
|
+
*/
|
|
62
|
+
export function getHighlightContext(event) {
|
|
63
|
+
return getTagValue(event, "context");
|
|
64
|
+
}
|
|
65
|
+
/** Get the comment for a highlight (from 'comment' tag) */
|
|
66
|
+
export function getHighlightComment(event) {
|
|
67
|
+
return getTagValue(event, "comment");
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if the highlight has any source reference (event, address, or URL)
|
|
71
|
+
*/
|
|
72
|
+
export function hasHighlightSource(event) {
|
|
73
|
+
return !!(getHighlightSourceEventPointer(event) ||
|
|
74
|
+
getHighlightSourceAddressPointer(event) ||
|
|
75
|
+
getHighlightSourceUrl(event));
|
|
76
|
+
}
|
package/dist/helpers/index.d.ts
CHANGED
|
@@ -4,6 +4,9 @@ export * from "./blossom.js";
|
|
|
4
4
|
export * from "./bolt11.js";
|
|
5
5
|
export * from "./bookmarks.js";
|
|
6
6
|
export * from "./cache.js";
|
|
7
|
+
export * from "./calendar-event.js";
|
|
8
|
+
export * from "./calendar-rsvp.js";
|
|
9
|
+
export * from "./calendar.js";
|
|
7
10
|
export * from "./channels.js";
|
|
8
11
|
export * from "./comment.js";
|
|
9
12
|
export * from "./contacts.js";
|
|
@@ -14,6 +17,7 @@ export * from "./emoji.js";
|
|
|
14
17
|
export * from "./encrypted-content-cache.js";
|
|
15
18
|
export * from "./encrypted-content.js";
|
|
16
19
|
export * from "./encryption.js";
|
|
20
|
+
export * from "./event-cache.js";
|
|
17
21
|
export * from "./event-tags.js";
|
|
18
22
|
export * from "./event.js";
|
|
19
23
|
export * from "./expiration.js";
|
|
@@ -25,6 +29,7 @@ export * from "./groups.js";
|
|
|
25
29
|
export * from "./hashtag.js";
|
|
26
30
|
export * from "./hidden-content.js";
|
|
27
31
|
export * from "./hidden-tags.js";
|
|
32
|
+
export * from "./highlight.js";
|
|
28
33
|
export * from "./json.js";
|
|
29
34
|
export * from "./legacy-messages.js";
|
|
30
35
|
export * from "./lists.js";
|
|
@@ -35,11 +40,14 @@ export * from "./messages.js";
|
|
|
35
40
|
export * from "./mutes.js";
|
|
36
41
|
export * from "./picture-post.js";
|
|
37
42
|
export * from "./pointers.js";
|
|
43
|
+
export * from "./poll.js";
|
|
38
44
|
export * from "./profile.js";
|
|
39
45
|
export * from "./reactions.js";
|
|
40
46
|
export * from "./relays.js";
|
|
41
47
|
export * from "./reports.js";
|
|
42
48
|
export * from "./share.js";
|
|
49
|
+
export * from "./stream-chat.js";
|
|
50
|
+
export * from "./stream.js";
|
|
43
51
|
export * from "./string.js";
|
|
44
52
|
export * from "./tags.js";
|
|
45
53
|
export * from "./threading.js";
|
package/dist/helpers/index.js
CHANGED
|
@@ -4,6 +4,9 @@ export * from "./blossom.js";
|
|
|
4
4
|
export * from "./bolt11.js";
|
|
5
5
|
export * from "./bookmarks.js";
|
|
6
6
|
export * from "./cache.js";
|
|
7
|
+
export * from "./calendar-event.js";
|
|
8
|
+
export * from "./calendar-rsvp.js";
|
|
9
|
+
export * from "./calendar.js";
|
|
7
10
|
export * from "./channels.js";
|
|
8
11
|
export * from "./comment.js";
|
|
9
12
|
export * from "./contacts.js";
|
|
@@ -14,6 +17,7 @@ export * from "./emoji.js";
|
|
|
14
17
|
export * from "./encrypted-content-cache.js";
|
|
15
18
|
export * from "./encrypted-content.js";
|
|
16
19
|
export * from "./encryption.js";
|
|
20
|
+
export * from "./event-cache.js";
|
|
17
21
|
export * from "./event-tags.js";
|
|
18
22
|
export * from "./event.js";
|
|
19
23
|
export * from "./expiration.js";
|
|
@@ -25,6 +29,7 @@ export * from "./groups.js";
|
|
|
25
29
|
export * from "./hashtag.js";
|
|
26
30
|
export * from "./hidden-content.js";
|
|
27
31
|
export * from "./hidden-tags.js";
|
|
32
|
+
export * from "./highlight.js";
|
|
28
33
|
export * from "./json.js";
|
|
29
34
|
export * from "./legacy-messages.js";
|
|
30
35
|
export * from "./lists.js";
|
|
@@ -35,11 +40,14 @@ export * from "./messages.js";
|
|
|
35
40
|
export * from "./mutes.js";
|
|
36
41
|
export * from "./picture-post.js";
|
|
37
42
|
export * from "./pointers.js";
|
|
43
|
+
export * from "./poll.js";
|
|
38
44
|
export * from "./profile.js";
|
|
39
45
|
export * from "./reactions.js";
|
|
40
46
|
export * from "./relays.js";
|
|
41
47
|
export * from "./reports.js";
|
|
42
48
|
export * from "./share.js";
|
|
49
|
+
export * from "./stream-chat.js";
|
|
50
|
+
export * from "./stream.js";
|
|
43
51
|
export * from "./string.js";
|
|
44
52
|
export * from "./tags.js";
|
|
45
53
|
export * from "./threading.js";
|
package/dist/helpers/pointers.js
CHANGED
|
@@ -187,7 +187,7 @@ export function addRelayHintsToPointer(pointer, relays) {
|
|
|
187
187
|
/** Gets the hex pubkey from any nip-19 encoded string */
|
|
188
188
|
export function normalizeToPubkey(str) {
|
|
189
189
|
if (isHexKey(str))
|
|
190
|
-
return str;
|
|
190
|
+
return str.toLowerCase();
|
|
191
191
|
else {
|
|
192
192
|
const decode = nip19.decode(str);
|
|
193
193
|
const pubkey = getPubkeyFromDecodeResult(decode);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { NostrEvent } from "nostr-tools";
|
|
2
|
+
export declare const POLL_KIND = 1068;
|
|
3
|
+
export declare const POLL_RESPONSE_KIND = 1018;
|
|
4
|
+
export declare const PollOptionsSymbol: unique symbol;
|
|
5
|
+
export interface PollOption {
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
}
|
|
9
|
+
export type PollType = "singlechoice" | "multiplechoice";
|
|
10
|
+
/**
|
|
11
|
+
* Get the poll question/label from a poll event
|
|
12
|
+
* Returns the content field which contains the poll question
|
|
13
|
+
*/
|
|
14
|
+
export declare function getPollQuestion(event: NostrEvent): string;
|
|
15
|
+
/**
|
|
16
|
+
* Get the poll options from a poll event
|
|
17
|
+
* Returns array of options with id and label
|
|
18
|
+
*/
|
|
19
|
+
export declare function getPollOptions(event: NostrEvent): PollOption[];
|
|
20
|
+
/**
|
|
21
|
+
* Get the relays specified for poll responses (from 'relay' tags)
|
|
22
|
+
* Returns undefined if no relays are specified
|
|
23
|
+
*/
|
|
24
|
+
export declare function getPollRelays(event: NostrEvent): string[];
|
|
25
|
+
/**
|
|
26
|
+
* Get the poll type from a poll event (from 'polltype' tag)
|
|
27
|
+
* Returns "singlechoice" or "multiplechoice", defaults to "singlechoice"
|
|
28
|
+
*/
|
|
29
|
+
export declare function getPollType(event: NostrEvent): PollType;
|
|
30
|
+
/**
|
|
31
|
+
* Get the poll expiration timestamp (from 'endsAt' tag)
|
|
32
|
+
* Returns undefined if no expiration is set
|
|
33
|
+
*/
|
|
34
|
+
export declare function getPollEndsAt(event: NostrEvent): number | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Get the poll ID that a response is referencing (from 'e' tag)
|
|
37
|
+
* Returns undefined if no poll reference is found
|
|
38
|
+
*/
|
|
39
|
+
export declare function getPollResponsePollId(event: NostrEvent): string | undefined;
|
|
40
|
+
/** Get the selected option IDs from a poll response event (from 'response' tags) */
|
|
41
|
+
export declare function getPollResponseOptions(event: NostrEvent): string[];
|
|
42
|
+
/**
|
|
43
|
+
* Gets the options that a user has voted for in a poll event
|
|
44
|
+
* Returns undefined if the response is not valid
|
|
45
|
+
*/
|
|
46
|
+
export declare function getPollResponseVotes(poll: NostrEvent, response: NostrEvent): string[] | undefined;
|