applesauce-core 0.0.0-next-20250808173123 → 0.0.0-next-20250820215033

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.
@@ -25,6 +25,8 @@ export declare function setEncryptedContentEncryptionMethod(kind: number, method
25
25
  * @param kind The event kind to get the encryption method for
26
26
  * @param signer The signer to use to get the encryption methods
27
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
28
30
  * @returns The encryption methods for the event kind
29
31
  */
30
32
  export declare function getEncryptedContentEncryptionMethods(kind: number, signer: EncryptedContentSigner, override?: EncryptionMethod): EncryptionMethods;
@@ -18,6 +18,8 @@ export function setEncryptedContentEncryptionMethod(kind, method) {
18
18
  * @param kind The event kind to get the encryption method for
19
19
  * @param signer The signer to use to get the encryption methods
20
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
21
23
  * @returns The encryption methods for the event kind
22
24
  */
23
25
  export function getEncryptedContentEncryptionMethods(kind, signer, override) {
@@ -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 {Error} if the event is not addressable or missing the "d" tag
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;
@@ -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 {Error} if the event is not addressable or missing the "d" tag
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
- const d = event.tags.find((t) => t[0] === "d")?.[1];
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 */
@@ -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
+ }
@@ -29,6 +29,7 @@ export * from "./groups.js";
29
29
  export * from "./hashtag.js";
30
30
  export * from "./hidden-content.js";
31
31
  export * from "./hidden-tags.js";
32
+ export * from "./highlight.js";
32
33
  export * from "./json.js";
33
34
  export * from "./legacy-messages.js";
34
35
  export * from "./lists.js";
@@ -39,6 +40,7 @@ export * from "./messages.js";
39
40
  export * from "./mutes.js";
40
41
  export * from "./picture-post.js";
41
42
  export * from "./pointers.js";
43
+ export * from "./poll.js";
42
44
  export * from "./profile.js";
43
45
  export * from "./reactions.js";
44
46
  export * from "./relays.js";
@@ -29,6 +29,7 @@ export * from "./groups.js";
29
29
  export * from "./hashtag.js";
30
30
  export * from "./hidden-content.js";
31
31
  export * from "./hidden-tags.js";
32
+ export * from "./highlight.js";
32
33
  export * from "./json.js";
33
34
  export * from "./legacy-messages.js";
34
35
  export * from "./lists.js";
@@ -39,6 +40,7 @@ export * from "./messages.js";
39
40
  export * from "./mutes.js";
40
41
  export * from "./picture-post.js";
41
42
  export * from "./pointers.js";
43
+ export * from "./poll.js";
42
44
  export * from "./profile.js";
43
45
  export * from "./reactions.js";
44
46
  export * from "./relays.js";
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-core",
3
- "version": "0.0.0-next-20250808173123",
3
+ "version": "0.0.0-next-20250820215033",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",