applesauce-core 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/event-store/event-set.d.ts +2 -0
  2. package/dist/event-store/event-set.js +15 -3
  3. package/dist/event-store/event-store.d.ts +54 -24
  4. package/dist/event-store/event-store.js +139 -47
  5. package/dist/event-store/interface.d.ts +36 -18
  6. package/dist/helpers/calendar-event.d.ts +36 -0
  7. package/dist/helpers/calendar-event.js +110 -0
  8. package/dist/helpers/calendar-rsvp.d.ts +15 -0
  9. package/dist/helpers/calendar-rsvp.js +38 -0
  10. package/dist/helpers/calendar.d.ts +6 -0
  11. package/dist/helpers/calendar.js +11 -0
  12. package/dist/helpers/encrypted-content-cache.js +16 -12
  13. package/dist/helpers/encrypted-content.d.ts +18 -10
  14. package/dist/helpers/encrypted-content.js +11 -3
  15. package/dist/helpers/event-cache.d.ts +15 -0
  16. package/dist/helpers/event-cache.js +32 -0
  17. package/dist/helpers/event.d.ts +1 -1
  18. package/dist/helpers/event.js +1 -1
  19. package/dist/helpers/expiration.js +1 -2
  20. package/dist/helpers/gift-wraps.d.ts +33 -13
  21. package/dist/helpers/gift-wraps.js +154 -58
  22. package/dist/helpers/hidden-content.d.ts +3 -3
  23. package/dist/helpers/hidden-content.js +2 -2
  24. package/dist/helpers/hidden-tags.d.ts +5 -10
  25. package/dist/helpers/hidden-tags.js +3 -3
  26. package/dist/helpers/highlight.d.ts +45 -0
  27. package/dist/helpers/highlight.js +76 -0
  28. package/dist/helpers/index.d.ts +8 -0
  29. package/dist/helpers/index.js +8 -0
  30. package/dist/helpers/pointers.js +1 -1
  31. package/dist/helpers/poll.d.ts +46 -0
  32. package/dist/helpers/poll.js +78 -0
  33. package/dist/helpers/stream-chat.d.ts +4 -0
  34. package/dist/helpers/stream-chat.js +9 -0
  35. package/dist/helpers/stream.d.ts +31 -0
  36. package/dist/helpers/stream.js +81 -0
  37. package/dist/logger.d.ts +1 -0
  38. package/dist/logger.js +1 -0
  39. package/dist/models/blossom.d.ts +2 -1
  40. package/dist/models/blossom.js +4 -2
  41. package/dist/models/calendar.d.ts +6 -0
  42. package/dist/models/calendar.js +15 -0
  43. package/dist/models/common.d.ts +14 -10
  44. package/dist/models/common.js +47 -76
  45. package/dist/models/contacts.d.ts +1 -1
  46. package/dist/models/contacts.js +4 -2
  47. package/dist/models/index.d.ts +1 -0
  48. package/dist/models/index.js +1 -0
  49. package/dist/models/mailboxes.d.ts +2 -1
  50. package/dist/models/mailboxes.js +4 -2
  51. package/dist/models/mutes.d.ts +3 -2
  52. package/dist/models/mutes.js +4 -2
  53. package/dist/models/profile.d.ts +2 -1
  54. package/dist/models/profile.js +4 -2
  55. package/package.json +1 -1
  56. package/dist/event-store/common.d.ts +0 -1
  57. package/dist/event-store/common.js +0 -1
@@ -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: "nip04" | "nip44"): number;
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 store An optional EventStore to notify about the update
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 store An optional EventStore to notify about the update
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
+ }
@@ -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";
@@ -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";
@@ -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;
@@ -0,0 +1,78 @@
1
+ import { getOrComputeCachedValue } from "./cache.js";
2
+ import { getTagValue } from "./event-tags.js";
3
+ // NIP-88 Poll kinds
4
+ export const POLL_KIND = 1068;
5
+ export const POLL_RESPONSE_KIND = 1018;
6
+ // Cache symbols
7
+ export const PollOptionsSymbol = Symbol.for("poll-options");
8
+ /**
9
+ * Get the poll question/label from a poll event
10
+ * Returns the content field which contains the poll question
11
+ */
12
+ export function getPollQuestion(event) {
13
+ return event.content;
14
+ }
15
+ /**
16
+ * Get the poll options from a poll event
17
+ * Returns array of options with id and label
18
+ */
19
+ export function getPollOptions(event) {
20
+ return getOrComputeCachedValue(event, PollOptionsSymbol, () => {
21
+ return event.tags
22
+ .filter((tag) => tag[0] === "option" && tag.length >= 3)
23
+ .map((tag) => ({
24
+ id: tag[1],
25
+ label: tag[2],
26
+ }));
27
+ });
28
+ }
29
+ /**
30
+ * Get the relays specified for poll responses (from 'relay' tags)
31
+ * Returns undefined if no relays are specified
32
+ */
33
+ export function getPollRelays(event) {
34
+ return event.tags.filter((tag) => tag[0] === "relay" && tag.length >= 2).map((tag) => tag[1]);
35
+ }
36
+ /**
37
+ * Get the poll type from a poll event (from 'polltype' tag)
38
+ * Returns "singlechoice" or "multiplechoice", defaults to "singlechoice"
39
+ */
40
+ export function getPollType(event) {
41
+ const type = getTagValue(event, "polltype");
42
+ return type === "multiplechoice" || type === "singlechoice" ? type : "singlechoice";
43
+ }
44
+ /**
45
+ * Get the poll expiration timestamp (from 'endsAt' tag)
46
+ * Returns undefined if no expiration is set
47
+ */
48
+ export function getPollEndsAt(event) {
49
+ const endsAt = getTagValue(event, "endsAt");
50
+ return endsAt ? parseInt(endsAt, 10) : undefined;
51
+ }
52
+ /**
53
+ * Get the poll ID that a response is referencing (from 'e' tag)
54
+ * Returns undefined if no poll reference is found
55
+ */
56
+ export function getPollResponsePollId(event) {
57
+ return getTagValue(event, "e");
58
+ }
59
+ /** Get the selected option IDs from a poll response event (from 'response' tags) */
60
+ export function getPollResponseOptions(event) {
61
+ return event.tags.filter((tag) => tag[0] === "response" && tag.length >= 2).map((tag) => tag[1]);
62
+ }
63
+ /**
64
+ * Gets the options that a user has voted for in a poll event
65
+ * Returns undefined if the response is not valid
66
+ */
67
+ export function getPollResponseVotes(poll, response) {
68
+ if (poll.id !== getPollResponsePollId(response))
69
+ return;
70
+ const pollOptions = getPollOptions(poll);
71
+ const responseOptions = getPollResponseOptions(response);
72
+ const votes = responseOptions.filter((opts) => pollOptions.some((option) => option.id === opts));
73
+ const type = getPollType(poll);
74
+ // If its a single choice poll, return the first vote
75
+ if (type === "singlechoice")
76
+ return votes.length === 1 ? [votes[0]] : undefined;
77
+ return Array.from(new Set(votes));
78
+ }
@@ -0,0 +1,4 @@
1
+ import { AddressPointer } from "nostr-tools/nip19";
2
+ import { NostrEvent } from "nostr-tools";
3
+ /** Returns the pointer to the stream chat message stream */
4
+ export declare function getStreamChatMessageStream(message: NostrEvent): AddressPointer | undefined;
@@ -0,0 +1,9 @@
1
+ import { getAddressPointerFromATag } from "./pointers.js";
2
+ import { isATag } from "./tags.js";
3
+ /** Returns the pointer to the stream chat message stream */
4
+ export function getStreamChatMessageStream(message) {
5
+ const tag = message.tags.find(isATag);
6
+ if (!tag)
7
+ return undefined;
8
+ return getAddressPointerFromATag(tag);
9
+ }
@@ -0,0 +1,31 @@
1
+ import { NostrEvent } from "nostr-tools";
2
+ import { EventPointer, ProfilePointer } from "nostr-tools/nip19";
3
+ export type StreamStatus = "live" | "ended" | "planned";
4
+ export type StreamRole = "host" | "participant" | "speaker";
5
+ export declare function getStreamTitle(stream: NostrEvent): string | undefined;
6
+ export declare function getStreamSummary(stream: NostrEvent): string | undefined;
7
+ export declare function getStreamImage(stream: NostrEvent): string | undefined;
8
+ /** Returns the status of the stream, defaults to ended if the stream is older than 2 weeks */
9
+ export declare function getStreamStatus(stream: NostrEvent): StreamStatus;
10
+ /** Returns the pubkey of the host of the stream */
11
+ export declare function getStreamHost(stream: NostrEvent): ProfilePointer;
12
+ /** Returns the participants of a stream */
13
+ export declare function getStreamParticipants(stream: NostrEvent): (ProfilePointer & {
14
+ role: StreamRole;
15
+ })[];
16
+ export declare function getStreamGoalPointer(stream: NostrEvent): EventPointer | undefined;
17
+ /** Gets all the streaming urls for a stream */
18
+ export declare function getStreamStreamingURLs(stream: NostrEvent): string[];
19
+ export declare function getStreamRecording(stream: NostrEvent): string | undefined;
20
+ /** Gets the relays for a stream */
21
+ export declare function getStreamRelays(stream: NostrEvent): string[] | undefined;
22
+ /** Gets the stream start time if it has one */
23
+ export declare function getStreamStartTime(stream: NostrEvent): number | undefined;
24
+ /** Gets the stream end time if it has one */
25
+ export declare function getStreamEndTime(stream: NostrEvent): number | undefined;
26
+ /** Returns the current number of participants in the stream */
27
+ export declare function getStreamViewers(stream: NostrEvent): number | undefined;
28
+ /** Returns the maximum number of participants in the stream */
29
+ export declare function getStreamMaxViewers(stream: NostrEvent): number | undefined;
30
+ /** Returns the hashtags for a stream */
31
+ export declare function getStreamHashtags(stream: NostrEvent): string[];
@@ -0,0 +1,81 @@
1
+ import { getTagValue } from "./event-tags.js";
2
+ import { addRelayHintsToPointer, getEventPointerFromETag, getProfilePointerFromPTag } from "./pointers.js";
3
+ import { mergeRelaySets } from "./relays.js";
4
+ import { isPTag } from "./tags.js";
5
+ import { unixNow } from "./time.js";
6
+ export function getStreamTitle(stream) {
7
+ return getTagValue(stream, "title");
8
+ }
9
+ export function getStreamSummary(stream) {
10
+ return getTagValue(stream, "summary");
11
+ }
12
+ export function getStreamImage(stream) {
13
+ return getTagValue(stream, "image");
14
+ }
15
+ const TWO_WEEKS = 60 * 60 * 24 * 14;
16
+ /** Returns the status of the stream, defaults to ended if the stream is older than 2 weeks */
17
+ export function getStreamStatus(stream) {
18
+ if (stream.created_at < unixNow() - TWO_WEEKS)
19
+ return "ended";
20
+ else
21
+ return getTagValue(stream, "status") || "ended";
22
+ }
23
+ /** Returns the pubkey of the host of the stream */
24
+ export function getStreamHost(stream) {
25
+ let host = undefined;
26
+ for (const tag of stream.tags) {
27
+ if (isPTag(tag) && (!host || (tag[3] && tag[3].toLowerCase() === "host"))) {
28
+ host = getProfilePointerFromPTag(tag);
29
+ }
30
+ }
31
+ return host || { pubkey: stream.pubkey };
32
+ }
33
+ /** Returns the participants of a stream */
34
+ export function getStreamParticipants(stream) {
35
+ return stream.tags
36
+ .filter((t) => isPTag(t) && t[3])
37
+ .map((t) => ({ ...getProfilePointerFromPTag(t), role: t[3].toLowerCase() }));
38
+ }
39
+ export function getStreamGoalPointer(stream) {
40
+ const goalTag = stream.tags.find((t) => t[0] === "goal");
41
+ return goalTag && addRelayHintsToPointer(getEventPointerFromETag(goalTag), getStreamRelays(stream));
42
+ }
43
+ /** Gets all the streaming urls for a stream */
44
+ export function getStreamStreamingURLs(stream) {
45
+ return stream.tags.filter((t) => t[0] === "streaming").map((t) => t[1]);
46
+ }
47
+ export function getStreamRecording(stream) {
48
+ return getTagValue(stream, "recording");
49
+ }
50
+ /** Gets the relays for a stream */
51
+ export function getStreamRelays(stream) {
52
+ for (const tag of stream.tags) {
53
+ if (tag[0] === "relays")
54
+ return mergeRelaySets(tag.slice(1));
55
+ }
56
+ return undefined;
57
+ }
58
+ /** Gets the stream start time if it has one */
59
+ export function getStreamStartTime(stream) {
60
+ const str = getTagValue(stream, "starts");
61
+ return str ? parseInt(str) : undefined;
62
+ }
63
+ /** Gets the stream end time if it has one */
64
+ export function getStreamEndTime(stream) {
65
+ const str = getTagValue(stream, "ends");
66
+ return str ? parseInt(str) : getStreamStatus(stream) === "ended" ? stream.created_at : undefined;
67
+ }
68
+ /** Returns the current number of participants in the stream */
69
+ export function getStreamViewers(stream) {
70
+ const viewers = getTagValue(stream, "current_participants");
71
+ return viewers ? parseInt(viewers) : undefined;
72
+ }
73
+ /** Returns the maximum number of participants in the stream */
74
+ export function getStreamMaxViewers(stream) {
75
+ const viewers = getTagValue(stream, "total_participants");
76
+ return viewers ? parseInt(viewers) : undefined;
77
+ }
78
+ /** Returns the hashtags for a stream */
79
+ export function getStreamHashtags(stream) {
80
+ return stream.tags.filter((t) => t[0] === "t").map((t) => t[1]);
81
+ }
package/dist/logger.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  import debug from "debug";
2
+ /** @hidden */
2
3
  export declare const logger: debug.Debugger;
package/dist/logger.js CHANGED
@@ -1,2 +1,3 @@
1
1
  import debug from "debug";
2
+ /** @hidden */
2
3
  export const logger = debug("applesauce");
@@ -1,3 +1,4 @@
1
+ import { ProfilePointer } from "nostr-tools/nip19";
1
2
  import { Model } from "../event-store/interface.js";
2
3
  /** A model that returns a users blossom servers */
3
- export declare function UserBlossomServersModel(pubkey: string): Model<URL[]>;
4
+ export declare function UserBlossomServersModel(user: string | ProfilePointer): Model<URL[]>;
@@ -1,8 +1,10 @@
1
1
  import { map } from "rxjs/operators";
2
2
  import { BLOSSOM_SERVER_LIST_KIND, getBlossomServersFromList } from "../helpers/blossom.js";
3
3
  /** A model that returns a users blossom servers */
4
- export function UserBlossomServersModel(pubkey) {
4
+ export function UserBlossomServersModel(user) {
5
+ if (typeof user === "string")
6
+ user = { pubkey: user };
5
7
  return (store) => store
6
- .replaceable(BLOSSOM_SERVER_LIST_KIND, pubkey)
8
+ .replaceable({ kind: BLOSSOM_SERVER_LIST_KIND, pubkey: user.pubkey, relays: user.relays })
7
9
  .pipe(map((event) => (event ? getBlossomServersFromList(event) : [])));
8
10
  }
@@ -0,0 +1,6 @@
1
+ import { NostrEvent } from "nostr-tools";
2
+ import { Model } from "../event-store/interface.js";
3
+ /** A model that gets all the events for a calendar */
4
+ export declare function CalendarEventsModel(calendar: NostrEvent): Model<NostrEvent[]>;
5
+ /** A model that gets all the RSVPs for a calendar event */
6
+ export declare function CalendarEventRSVPsModel(event: NostrEvent): Model<NostrEvent[]>;
@@ -0,0 +1,15 @@
1
+ import { combineLatest } from "rxjs";
2
+ import { CALENDAR_EVENT_RSVP_KIND } from "../helpers/calendar-rsvp.js";
3
+ import { getCalendarAddressPointers } from "../helpers/calendar.js";
4
+ import { getReplaceableAddress } from "../helpers/index.js";
5
+ import { defined } from "../observable/defined.js";
6
+ /** A model that gets all the events for a calendar */
7
+ export function CalendarEventsModel(calendar) {
8
+ return (events) => combineLatest(getCalendarAddressPointers(calendar).map((p) => events.replaceable(p.kind, p.pubkey, p.identifier).pipe(defined())));
9
+ }
10
+ /** A model that gets all the RSVPs for a calendar event */
11
+ export function CalendarEventRSVPsModel(event) {
12
+ return (events) => {
13
+ return events.timeline({ kinds: [CALENDAR_EVENT_RSVP_KIND], "#a": [getReplaceableAddress(event)] });
14
+ };
15
+ }
@@ -1,16 +1,20 @@
1
1
  import { Filter, NostrEvent } from "nostr-tools";
2
+ import { AddressPointer, EventPointer } from "nostr-tools/nip19";
2
3
  import { Model } from "../event-store/interface.js";
4
+ import { AddressPointerWithoutD } from "../helpers/index.js";
3
5
  /** A model that returns a single event or undefined when its removed */
4
- export declare function EventModel(id: string): Model<NostrEvent | undefined>;
6
+ export declare function EventModel(pointer: string | EventPointer): Model<NostrEvent | undefined>;
5
7
  /** A model that returns the latest version of a replaceable event or undefined if its removed */
6
- export declare function ReplaceableModel(kind: number, pubkey: string, d?: string): Model<NostrEvent | undefined>;
8
+ export declare function ReplaceableModel(pointer: AddressPointer | AddressPointerWithoutD): Model<NostrEvent | undefined>;
7
9
  /** A model that returns an array of sorted events matching the filters */
8
10
  export declare function TimelineModel(filters: Filter | Filter[], includeOldVersion?: boolean): Model<NostrEvent[]>;
9
- /** A model that returns a multiple events in a map */
10
- export declare function EventsModel(ids: string[]): Model<Record<string, NostrEvent>>;
11
- /** A model that returns a directory of events by their UID */
12
- export declare function ReplaceableSetModel(pointers: {
13
- kind: number;
14
- pubkey: string;
15
- identifier?: string;
16
- }[]): Model<Record<string, NostrEvent>>;
11
+ /**
12
+ * A model that returns a multiple events in a map
13
+ * @deprecated use multiple {@link EventModel} instead
14
+ */
15
+ export declare function EventsModel(ids: string[]): Model<Record<string, NostrEvent | undefined>>;
16
+ /**
17
+ * A model that returns a directory of events by their UID
18
+ * @deprecated use multiple {@link ReplaceableModel} instead
19
+ */
20
+ export declare function ReplaceableSetModel(pointers: (AddressPointer | AddressPointerWithoutD)[]): Model<Record<string, NostrEvent | undefined>>;