applesauce-core 1.0.0 → 2.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 (194) hide show
  1. package/README.md +7 -13
  2. package/dist/event-store/{database.d.ts → event-set.d.ts} +35 -20
  3. package/dist/event-store/{database.js → event-set.js} +91 -60
  4. package/dist/event-store/event-store.d.ts +64 -25
  5. package/dist/event-store/event-store.js +163 -206
  6. package/dist/event-store/index.d.ts +1 -1
  7. package/dist/event-store/index.js +1 -1
  8. package/dist/event-store/interface.d.ts +71 -13
  9. package/dist/helpers/app-handlers.d.ts +23 -0
  10. package/dist/helpers/app-handlers.js +68 -0
  11. package/dist/helpers/article.d.ts +9 -0
  12. package/dist/helpers/article.js +21 -0
  13. package/dist/helpers/blossom.d.ts +2 -0
  14. package/dist/helpers/blossom.js +18 -0
  15. package/dist/helpers/bolt11.d.ts +1 -0
  16. package/dist/helpers/bolt11.js +2 -0
  17. package/dist/helpers/bookmarks.js +1 -2
  18. package/dist/helpers/emoji.d.ts +10 -2
  19. package/dist/helpers/emoji.js +21 -3
  20. package/dist/helpers/encrypted-content-cache.d.ts +15 -0
  21. package/dist/helpers/encrypted-content-cache.js +125 -0
  22. package/dist/helpers/encrypted-content.d.ts +48 -0
  23. package/dist/helpers/encrypted-content.js +65 -0
  24. package/dist/helpers/encryption.d.ts +5 -0
  25. package/dist/helpers/encryption.js +10 -0
  26. package/dist/helpers/event.d.ts +4 -1
  27. package/dist/helpers/event.js +13 -3
  28. package/dist/helpers/expiration.d.ts +6 -0
  29. package/dist/helpers/expiration.js +16 -0
  30. package/dist/helpers/filter.d.ts +1 -3
  31. package/dist/helpers/filter.js +1 -3
  32. package/dist/helpers/gift-wraps.d.ts +17 -5
  33. package/dist/helpers/gift-wraps.js +65 -27
  34. package/dist/helpers/groups.d.ts +5 -0
  35. package/dist/helpers/groups.js +12 -2
  36. package/dist/helpers/hidden-content.d.ts +27 -32
  37. package/dist/helpers/hidden-content.js +35 -65
  38. package/dist/helpers/hidden-tags.d.ts +23 -4
  39. package/dist/helpers/hidden-tags.js +39 -4
  40. package/dist/helpers/index.d.ts +11 -1
  41. package/dist/helpers/index.js +11 -1
  42. package/dist/helpers/legacy-messages.d.ts +21 -0
  43. package/dist/helpers/legacy-messages.js +39 -0
  44. package/dist/helpers/lists.d.ts +1 -1
  45. package/dist/helpers/lists.js +2 -2
  46. package/dist/helpers/messages.d.ts +11 -0
  47. package/dist/helpers/messages.js +19 -0
  48. package/dist/helpers/mutes.js +1 -1
  49. package/dist/helpers/pointers.d.ts +33 -9
  50. package/dist/helpers/pointers.js +80 -44
  51. package/dist/helpers/profile.d.ts +10 -2
  52. package/dist/helpers/profile.js +33 -4
  53. package/dist/helpers/reactions.d.ts +8 -0
  54. package/dist/helpers/reactions.js +56 -0
  55. package/dist/helpers/reports.d.ts +28 -0
  56. package/dist/helpers/reports.js +38 -0
  57. package/dist/helpers/share.d.ts +10 -1
  58. package/dist/helpers/share.js +22 -8
  59. package/dist/helpers/url.d.ts +4 -0
  60. package/dist/helpers/url.js +20 -0
  61. package/dist/helpers/user-status.js +2 -1
  62. package/dist/helpers/wrapped-messages.d.ts +23 -0
  63. package/dist/helpers/wrapped-messages.js +38 -0
  64. package/dist/helpers/zap.d.ts +8 -5
  65. package/dist/helpers/zap.js +11 -6
  66. package/dist/index.d.ts +2 -2
  67. package/dist/index.js +2 -2
  68. package/dist/models/blossom.d.ts +3 -0
  69. package/dist/models/blossom.js +8 -0
  70. package/dist/models/bookmarks.d.ts +8 -0
  71. package/dist/{queries → models}/bookmarks.js +9 -9
  72. package/dist/models/channels.d.ts +11 -0
  73. package/dist/{queries → models}/channels.js +9 -9
  74. package/dist/models/comments.d.ts +4 -0
  75. package/dist/models/comments.js +11 -0
  76. package/dist/models/common.d.ts +16 -0
  77. package/dist/models/common.js +176 -0
  78. package/dist/models/contacts.d.ts +8 -0
  79. package/dist/{queries → models}/contacts.js +10 -10
  80. package/dist/models/encrypted-content.d.ts +4 -0
  81. package/dist/models/encrypted-content.js +11 -0
  82. package/dist/models/gift-wrap.d.ts +7 -0
  83. package/dist/models/gift-wrap.js +20 -0
  84. package/dist/{queries → models}/index.d.ts +6 -2
  85. package/dist/{queries → models}/index.js +6 -2
  86. package/dist/models/legacy-messages.d.ts +8 -0
  87. package/dist/models/legacy-messages.js +29 -0
  88. package/dist/models/mailboxes.d.ts +6 -0
  89. package/dist/{queries → models}/mailboxes.js +2 -2
  90. package/dist/models/mutes.d.ts +8 -0
  91. package/dist/{queries → models}/mutes.js +9 -9
  92. package/dist/models/pins.d.ts +4 -0
  93. package/dist/{queries → models}/pins.js +3 -3
  94. package/dist/models/profile.d.ts +4 -0
  95. package/dist/models/profile.js +14 -0
  96. package/dist/models/reactions.d.ts +4 -0
  97. package/dist/{queries → models}/reactions.js +2 -2
  98. package/dist/models/relays.d.ts +27 -0
  99. package/dist/{queries → models}/relays.js +13 -13
  100. package/dist/{queries → models}/thread.d.ts +6 -5
  101. package/dist/{queries → models}/thread.js +4 -3
  102. package/dist/models/user-status.d.ts +11 -0
  103. package/dist/{queries → models}/user-status.js +5 -5
  104. package/dist/models/wrapped-messages.d.ts +25 -0
  105. package/dist/models/wrapped-messages.js +61 -0
  106. package/dist/models/zaps.d.ts +9 -0
  107. package/dist/{queries → models}/zaps.js +11 -3
  108. package/dist/observable/claim-events.d.ts +3 -3
  109. package/dist/observable/claim-events.js +4 -4
  110. package/dist/observable/claim-latest.d.ts +3 -3
  111. package/dist/observable/claim-latest.js +4 -4
  112. package/dist/observable/index.d.ts +5 -1
  113. package/dist/observable/index.js +6 -1
  114. package/dist/observable/map-events-timeline.d.ts +7 -0
  115. package/dist/observable/map-events-timeline.js +9 -0
  116. package/dist/observable/map-events-to-store.d.ts +5 -0
  117. package/dist/observable/map-events-to-store.js +12 -0
  118. package/dist/observable/simple-timeout.d.ts +1 -0
  119. package/dist/observable/simple-timeout.js +1 -0
  120. package/dist/observable/watch-event-updates.d.ts +7 -0
  121. package/dist/observable/watch-event-updates.js +25 -0
  122. package/package.json +11 -16
  123. package/dist/__tests__/fixtures.d.ts +0 -8
  124. package/dist/__tests__/fixtures.js +0 -20
  125. package/dist/event-store/__tests__/event-store.test.d.ts +0 -1
  126. package/dist/event-store/__tests__/event-store.test.js +0 -354
  127. package/dist/helpers/__tests__/blossom.test.d.ts +0 -1
  128. package/dist/helpers/__tests__/blossom.test.js +0 -13
  129. package/dist/helpers/__tests__/bookmarks.test.d.ts +0 -1
  130. package/dist/helpers/__tests__/bookmarks.test.js +0 -88
  131. package/dist/helpers/__tests__/comment.test.d.ts +0 -1
  132. package/dist/helpers/__tests__/comment.test.js +0 -249
  133. package/dist/helpers/__tests__/contacts.test.d.ts +0 -1
  134. package/dist/helpers/__tests__/contacts.test.js +0 -34
  135. package/dist/helpers/__tests__/emoji.test.d.ts +0 -1
  136. package/dist/helpers/__tests__/emoji.test.js +0 -15
  137. package/dist/helpers/__tests__/event.test.d.ts +0 -1
  138. package/dist/helpers/__tests__/event.test.js +0 -36
  139. package/dist/helpers/__tests__/events.test.d.ts +0 -1
  140. package/dist/helpers/__tests__/events.test.js +0 -32
  141. package/dist/helpers/__tests__/file-metadata.test.d.ts +0 -1
  142. package/dist/helpers/__tests__/file-metadata.test.js +0 -103
  143. package/dist/helpers/__tests__/hidden-tags.test.d.ts +0 -1
  144. package/dist/helpers/__tests__/hidden-tags.test.js +0 -29
  145. package/dist/helpers/__tests__/mailboxes.test.d.ts +0 -1
  146. package/dist/helpers/__tests__/mailboxes.test.js +0 -81
  147. package/dist/helpers/__tests__/mutes.test.d.ts +0 -1
  148. package/dist/helpers/__tests__/mutes.test.js +0 -55
  149. package/dist/helpers/__tests__/nip-19.test.d.ts +0 -1
  150. package/dist/helpers/__tests__/nip-19.test.js +0 -42
  151. package/dist/helpers/__tests__/relays.test.d.ts +0 -1
  152. package/dist/helpers/__tests__/relays.test.js +0 -21
  153. package/dist/helpers/__tests__/tags.test.d.ts +0 -1
  154. package/dist/helpers/__tests__/tags.test.js +0 -24
  155. package/dist/helpers/__tests__/threading.test.d.ts +0 -1
  156. package/dist/helpers/__tests__/threading.test.js +0 -41
  157. package/dist/helpers/direct-messages.d.ts +0 -4
  158. package/dist/helpers/direct-messages.js +0 -5
  159. package/dist/helpers/nip-19.d.ts +0 -18
  160. package/dist/helpers/nip-19.js +0 -56
  161. package/dist/observable/__tests__/claim-events.test.d.ts +0 -1
  162. package/dist/observable/__tests__/claim-events.test.js +0 -23
  163. package/dist/observable/__tests__/claim-latest.test.d.ts +0 -1
  164. package/dist/observable/__tests__/claim-latest.test.js +0 -37
  165. package/dist/observable/__tests__/listen-latest-updates.test.d.ts +0 -1
  166. package/dist/observable/__tests__/listen-latest-updates.test.js +0 -55
  167. package/dist/observable/__tests__/simple-timeout.test.d.ts +0 -1
  168. package/dist/observable/__tests__/simple-timeout.test.js +0 -34
  169. package/dist/observable/listen-latest-updates.d.ts +0 -5
  170. package/dist/observable/listen-latest-updates.js +0 -12
  171. package/dist/queries/blossom.d.ts +0 -2
  172. package/dist/queries/blossom.js +0 -5
  173. package/dist/queries/bookmarks.d.ts +0 -8
  174. package/dist/queries/channels.d.ts +0 -11
  175. package/dist/queries/comments.d.ts +0 -4
  176. package/dist/queries/comments.js +0 -11
  177. package/dist/queries/contacts.d.ts +0 -8
  178. package/dist/queries/mailboxes.d.ts +0 -6
  179. package/dist/queries/mutes.d.ts +0 -8
  180. package/dist/queries/pins.d.ts +0 -4
  181. package/dist/queries/profile.d.ts +0 -4
  182. package/dist/queries/profile.js +0 -7
  183. package/dist/queries/reactions.d.ts +0 -4
  184. package/dist/queries/relays.d.ts +0 -27
  185. package/dist/queries/simple.d.ts +0 -16
  186. package/dist/queries/simple.js +0 -21
  187. package/dist/queries/user-status.d.ts +0 -11
  188. package/dist/queries/zaps.d.ts +0 -5
  189. package/dist/query-store/__tests__/query-store.test.d.ts +0 -1
  190. package/dist/query-store/__tests__/query-store.test.js +0 -63
  191. package/dist/query-store/index.d.ts +0 -1
  192. package/dist/query-store/index.js +0 -1
  193. package/dist/query-store/query-store.d.ts +0 -54
  194. package/dist/query-store/query-store.js +0 -102
@@ -1,55 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { matchMutes } from "../mutes.js";
3
- import { FakeUser } from "../../__tests__/fixtures.js";
4
- const mutedUser = new FakeUser();
5
- const nonMutedUser = new FakeUser();
6
- const thread = nonMutedUser.note("Hello world");
7
- // Create a mutes object with a pubkey to mute
8
- const mutes = {
9
- pubkeys: new Set([mutedUser.pubkey]),
10
- threads: new Set([thread.id]),
11
- hashtags: new Set(["nostr"]),
12
- words: new Set(["GM"]),
13
- };
14
- describe("matchMutes", () => {
15
- it("should match events with muted pubkeys", () => {
16
- const mutedEvent = mutedUser.note("Hello world");
17
- const nonMutedEvent = nonMutedUser.note("Hello world");
18
- // The event with the muted pubkey should match
19
- expect(matchMutes(mutes, mutedEvent)).toBe(true);
20
- // The event with a different pubkey should not match
21
- expect(matchMutes(mutes, nonMutedEvent)).toBe(false);
22
- });
23
- it("should match events with muted hashtags", () => {
24
- // Create events with and without the muted hashtag
25
- const eventWithMutedHashtag = nonMutedUser.note("Hello world");
26
- eventWithMutedHashtag.tags.push(["t", "nostr"]);
27
- const eventWithDifferentHashtag = nonMutedUser.note("Hello world");
28
- eventWithDifferentHashtag.tags.push(["t", "bitcoin"]);
29
- const eventWithNoHashtag = nonMutedUser.note("Hello world");
30
- // The event with the muted hashtag should match
31
- expect(matchMutes(mutes, eventWithMutedHashtag)).toBe(true);
32
- // The events without the muted hashtag should not match
33
- expect(matchMutes(mutes, eventWithDifferentHashtag)).toBe(false);
34
- expect(matchMutes(mutes, eventWithNoHashtag)).toBe(false);
35
- });
36
- it("should match events within threads", () => {
37
- // Create a reply to the thread
38
- const reply = nonMutedUser.note("Hello world");
39
- reply.tags.push(["e", thread.id, "", "root"]);
40
- // The reply should match the mute
41
- expect(matchMutes(mutes, reply)).toBe(true);
42
- // The thread should not match the mute
43
- expect(matchMutes(mutes, thread)).toBe(false);
44
- });
45
- it("should match events with muted words", () => {
46
- // The event with the muted word should match
47
- expect(matchMutes(mutes, nonMutedUser.note("GM"))).toBe(true);
48
- // Should not match other words that contain the muted word
49
- expect(matchMutes(mutes, nonMutedUser.note("GMing"))).toBe(false);
50
- // Should be case-insensitive
51
- expect(matchMutes(mutes, nonMutedUser.note("gm"))).toBe(true);
52
- // Should match if the muted word
53
- expect(matchMutes(mutes, nonMutedUser.note("Hello GM world"))).toBe(true);
54
- });
55
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,42 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { bytesToHex } from "@noble/hashes/utils";
3
- import { normalizeToPubkey, normalizeToSecretKey } from "../nip-19.js";
4
- describe("normalizeToPubkey", () => {
5
- it("should get pubkey from npub", () => {
6
- expect(normalizeToPubkey("npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr")).toEqual("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5");
7
- });
8
- it("should get pubkey from nprofile", () => {
9
- expect(normalizeToPubkey("nprofile1qyw8wumn8ghj7umpw3jkcmrfw3jju6r6wfjrzdpe9e3k7mf0qyf8wumn8ghj7mn0wd68yat99e3k7mf0qqszv6q4uryjzr06xfxxew34wwc5hmjfmfpqn229d72gfegsdn2q3fg5g7lja")).toEqual("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5");
10
- });
11
- it("should return hex pubkey", () => {
12
- expect(normalizeToPubkey("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5")).toEqual("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5");
13
- });
14
- it("should throw on invalid hex pubkey", () => {
15
- expect(() => {
16
- normalizeToPubkey("5028372");
17
- }).toThrow();
18
- });
19
- it("should throw on invalid string", () => {
20
- expect(() => {
21
- normalizeToPubkey("testing");
22
- }).toThrow();
23
- });
24
- });
25
- describe("normalizeToSecretKey", () => {
26
- it("should get secret key from nsec", () => {
27
- expect(bytesToHex(normalizeToSecretKey("nsec1xe7znq745x5n68566l32ru72aajz3pk2cys9lnf3tuexvkw0dldsj8v2lm"))).toEqual("367c2983d5a1a93d1e9ad7e2a1f3caef642886cac1205fcd315f326659cf6fdb");
28
- });
29
- it("should get secret key from raw hex", () => {
30
- expect(bytesToHex(normalizeToSecretKey("367c2983d5a1a93d1e9ad7e2a1f3caef642886cac1205fcd315f326659cf6fdb"))).toEqual("367c2983d5a1a93d1e9ad7e2a1f3caef642886cac1205fcd315f326659cf6fdb");
31
- });
32
- it("should throw on invalid hex key", () => {
33
- expect(() => {
34
- normalizeToSecretKey("209573290");
35
- }).toThrow();
36
- });
37
- it("should throw on npub", () => {
38
- expect(() => {
39
- normalizeToSecretKey("npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr");
40
- }).toThrow();
41
- });
42
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,21 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { isSafeRelayURL } from "../relays.js";
3
- describe("isSafeRelayURL", () => {
4
- it("should correctly filter URLs", () => {
5
- // safe URLs
6
- expect(isSafeRelayURL("wss://relay.damus.io/")).toBe(true);
7
- expect(isSafeRelayURL("wss://nostrue.com")).toBe(true);
8
- expect(isSafeRelayURL("ws://192.168.0.194:8080")).toBe(true);
9
- expect(isSafeRelayURL("ws://localhost:4869/ws")).toBe(true);
10
- expect(isSafeRelayURL("ws://localhost/testing")).toBe(true);
11
- expect(isSafeRelayURL("ws://437fqnfqtcaquzvs5sd43ugznw7dsoatvtskoowgnpn6q5vqkljcrsyd.onion")).toBe(true);
12
- expect(isSafeRelayURL("ws://hypr1fk4trjnhjf62r6hhkpettmvxhxx2uvkkg4u4ea44va2fvxvfkl4s82m6dy.hyper")).toBe(true);
13
- // bad URLs
14
- expect(isSafeRelayURL("")).toBe(false);
15
- expect(isSafeRelayURL("bad")).toBe(false);
16
- expect(isSafeRelayURL("bad wss://nostr.wine")).toBe(false);
17
- expect(isSafeRelayURL("http://nostr.wine")).toBe(false);
18
- expect(isSafeRelayURL("http://cache-relay.com")).toBe(false);
19
- expect(isSafeRelayURL("wss://nostr.wine,wss://relayable.com")).toBe(false);
20
- });
21
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,24 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { isATag, isNameValueTag, processTags } from "../tags.js";
3
- import { getAddressPointerFromATag } from "../pointers.js";
4
- describe("isNameValueTag", () => {
5
- it("should return true if tag has at least two indexes", () => {
6
- expect(isNameValueTag(["a", "30000:pubkey:list"])).toBe(true);
7
- expect(isNameValueTag(["title", "article", "other-value"])).toBe(true);
8
- });
9
- it("should ignore tags without values", () => {
10
- expect(isNameValueTag(["a"])).toBe(false);
11
- expect(isNameValueTag(["title"])).toBe(false);
12
- });
13
- });
14
- describe("processTags", () => {
15
- it("should filter out errors", () => {
16
- expect(processTags([["a", "bad coordinate"], ["e"], ["a", "30000:pubkey:list"]], getAddressPointerFromATag)).toEqual([{ identifier: "list", kind: 30000, pubkey: "pubkey" }]);
17
- });
18
- it("should filter out undefined", () => {
19
- expect(processTags([["a", "bad coordinate"], ["e"], ["a", "30000:pubkey:list"]], (tag) => isATag(tag) ? tag : undefined)).toEqual([
20
- ["a", "bad coordinate"],
21
- ["a", "30000:pubkey:list"],
22
- ]);
23
- });
24
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,41 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { interpretThreadTags } from "../threading.js";
3
- describe("threading helpers", () => {
4
- describe("interpretThreadTags", () => {
5
- it("should handle legacy tags", () => {
6
- expect(interpretThreadTags([
7
- ["e", "root-id"],
8
- ["e", "reply-id"],
9
- ])).toEqual({ root: { a: undefined, e: ["e", "root-id"] }, reply: { a: undefined, e: ["e", "reply-id"] } });
10
- });
11
- it("should handle nip-10 tags", () => {
12
- expect(interpretThreadTags([
13
- ["e", "root-id", "relay", "root"],
14
- ["e", "reply-id", "relay", "reply"],
15
- ])).toEqual({
16
- root: { a: undefined, e: ["e", "root-id", "relay", "root"] },
17
- reply: { a: undefined, e: ["e", "reply-id", "relay", "reply"] },
18
- });
19
- });
20
- it("should ignore mention nip-10 tags", () => {
21
- expect(interpretThreadTags([
22
- ["e", "root-id", "relay", "root"],
23
- ["e", "mention-id", "relay", "mention"],
24
- ["e", "reply-id", "relay", "reply"],
25
- ])).toEqual({
26
- root: { a: undefined, e: ["e", "root-id", "relay", "root"] },
27
- reply: { a: undefined, e: ["e", "reply-id", "relay", "reply"] },
28
- });
29
- });
30
- it("should handle single nip-10 tags", () => {
31
- expect(interpretThreadTags([["e", "root-id", "relay", "root"]])).toEqual({
32
- root: { a: undefined, e: ["e", "root-id", "relay", "root"] },
33
- reply: { a: undefined, e: ["e", "root-id", "relay", "root"] },
34
- });
35
- expect(interpretThreadTags([["e", "reply-id", "relay", "reply"]])).toEqual({
36
- root: { a: undefined, e: ["e", "reply-id", "relay", "reply"] },
37
- reply: { a: undefined, e: ["e", "reply-id", "relay", "reply"] },
38
- });
39
- });
40
- });
41
- });
@@ -1,4 +0,0 @@
1
- import { NostrEvent } from "nostr-tools";
2
- import { HiddenContentSigner } from "./hidden-content.js";
3
- /** Returns the decrypted content of a direct message */
4
- export declare function decryptDirectMessage(message: NostrEvent, signer: HiddenContentSigner): Promise<string>;
@@ -1,5 +0,0 @@
1
- import { getHiddenContent, unlockHiddenContent } from "./hidden-content.js";
2
- /** Returns the decrypted content of a direct message */
3
- export async function decryptDirectMessage(message, signer) {
4
- return getHiddenContent(message) || (await unlockHiddenContent(message, signer));
5
- }
@@ -1,18 +0,0 @@
1
- import { AddressPointer, EventPointer, ProfilePointer } from "nostr-tools/nip19";
2
- /** Gets the hex pubkey from any nip-19 encoded string */
3
- export declare function normalizeToPubkey(str: string): string;
4
- /** Converts hex to nsec strings into Uint8 secret keys */
5
- export declare function normalizeToSecretKey(str: string): Uint8Array;
6
- /**
7
- * Merges two event points and keeps all relays
8
- * @throws if the ids are different
9
- */
10
- export declare function mergeEventPointers(a: EventPointer, b: EventPointer): EventPointer;
11
- /** Merges two address pointers and keeps all relays
12
- * @throws if the kinds, pubkeys, or identifiers are different
13
- */
14
- export declare function mergeAddressPointers(a: AddressPointer, b: AddressPointer): AddressPointer;
15
- /** Merges two profile pointers and keeps all relays
16
- * @throws if the pubkeys are different
17
- */
18
- export declare function mergeProfilePointers(a: ProfilePointer, b: ProfilePointer): ProfilePointer;
@@ -1,56 +0,0 @@
1
- import { nip19 } from "nostr-tools";
2
- import { hexToBytes } from "@noble/hashes/utils";
3
- import { isHexKey } from "./string.js";
4
- import { getPubkeyFromDecodeResult } from "./pointers.js";
5
- import { mergeRelaySets } from "./relays.js";
6
- /** Gets the hex pubkey from any nip-19 encoded string */
7
- export function normalizeToPubkey(str) {
8
- if (isHexKey(str))
9
- return str;
10
- else {
11
- const decode = nip19.decode(str);
12
- const pubkey = getPubkeyFromDecodeResult(decode);
13
- if (!pubkey)
14
- throw new Error(`Cant find pubkey in ${decode.type}`);
15
- return pubkey;
16
- }
17
- }
18
- /** Converts hex to nsec strings into Uint8 secret keys */
19
- export function normalizeToSecretKey(str) {
20
- if (isHexKey(str))
21
- return hexToBytes(str);
22
- else {
23
- const decode = nip19.decode(str);
24
- if (decode.type !== "nsec")
25
- throw new Error(`Cant get secret key from ${decode.type}`);
26
- return decode.data;
27
- }
28
- }
29
- /**
30
- * Merges two event points and keeps all relays
31
- * @throws if the ids are different
32
- */
33
- export function mergeEventPointers(a, b) {
34
- if (a.id !== b.id)
35
- throw new Error("Cant merge event pointers with different ids");
36
- const relays = mergeRelaySets(a.relays, b.relays);
37
- return { id: a.id, kind: a.kind ?? b.kind, author: a.author ?? b.author, relays };
38
- }
39
- /** Merges two address pointers and keeps all relays
40
- * @throws if the kinds, pubkeys, or identifiers are different
41
- */
42
- export function mergeAddressPointers(a, b) {
43
- if (a.kind !== b.kind || a.pubkey !== b.pubkey || a.identifier !== b.identifier)
44
- throw new Error("Cant merge address pointers with different kinds, pubkeys, or identifiers");
45
- const relays = mergeRelaySets(a.relays, b.relays);
46
- return { ...a, relays };
47
- }
48
- /** Merges two profile pointers and keeps all relays
49
- * @throws if the pubkeys are different
50
- */
51
- export function mergeProfilePointers(a, b) {
52
- if (a.pubkey !== b.pubkey)
53
- throw new Error("Cant merge profile pointers with different pubkeys");
54
- const relays = mergeRelaySets(a.relays, b.relays);
55
- return { ...a, relays };
56
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,23 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { Database } from "../../event-store/database.js";
3
- import { claimEvents } from "../claim-events.js";
4
- const event = {
5
- content: '{"name":"hzrd149","picture":"https://cdn.hzrd149.com/5ed3fe5df09a74e8c126831eac999364f9eb7624e2b86d521521b8021de20bdc.png","about":"JavaScript developer working on some nostr stuff\\n- noStrudel https://nostrudel.ninja/ \\n- Blossom https://github.com/hzrd149/blossom \\n- Applesauce https://hzrd149.github.io/applesauce/","website":"https://hzrd149.com","nip05":"_@hzrd149.com","lud16":"hzrd1499@minibits.cash","pubkey":"266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5","display_name":"hzrd149","displayName":"hzrd149","banner":""}',
6
- created_at: 1738362529,
7
- id: "e9df8d5898c4ccfbd21fcd59f3f48abb3ff0ab7259b19570e2f1756de1e9306b",
8
- kind: 0,
9
- pubkey: "266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5",
10
- relays: [""],
11
- sig: "465a47b93626a587bf81dadc2b306b8f713a62db31d6ce1533198e9ae1e665a6eaf376a03250bf9ffbb02eb9059c8eafbd37ae1092d05d215757575bd8357586",
12
- tags: [],
13
- };
14
- describe("claimEvents", () => {
15
- it("it should claim events", () => {
16
- const database = new Database();
17
- const sub = database.inserted.pipe(claimEvents(database)).subscribe();
18
- database.addEvent(event);
19
- expect(database.isClaimed(event)).toBe(true);
20
- sub.unsubscribe();
21
- expect(database.isClaimed(event)).toBe(false);
22
- });
23
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,37 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { Database } from "../../event-store/database.js";
3
- import { claimLatest } from "../claim-latest.js";
4
- const event1 = {
5
- content: '{"name":"hzrd149","picture":"https://cdn.hzrd149.com/5ed3fe5df09a74e8c126831eac999364f9eb7624e2b86d521521b8021de20bdc.png","about":"JavaScript developer working on some nostr stuff\\n- noStrudel https://nostrudel.ninja/ \\n- Blossom https://github.com/hzrd149/blossom \\n- Applesauce https://hzrd149.github.io/applesauce/","website":"https://hzrd149.com","nip05":"_@hzrd149.com","lud16":"hzrd1499@minibits.cash","pubkey":"266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5","display_name":"hzrd149","displayName":"hzrd149","banner":""}',
6
- created_at: 1738362529,
7
- id: "e9df8d5898c4ccfbd21fcd59f3f48abb3ff0ab7259b19570e2f1756de1e9306b",
8
- kind: 0,
9
- pubkey: "266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5",
10
- relays: [""],
11
- sig: "465a47b93626a587bf81dadc2b306b8f713a62db31d6ce1533198e9ae1e665a6eaf376a03250bf9ffbb02eb9059c8eafbd37ae1092d05d215757575bd8357586",
12
- tags: [],
13
- };
14
- const event2 = {
15
- content: '{"name":"Cesar Dias","website":"dev.nosotros.app","picture":"https://nostr.build/i/5b0e4387b0fdfff9897ee7f8dcc554761fe377583a5fb71bbf3b915e7c4971c2.jpg","display_name":"Cesar Dias","nip05":"_@nosotros.app","lud16":"cesardias@getalby.com","about":"Developer 🇧🇷, building a client https://dev.nosotros.app and nostr-editor https://github.com/cesardeazevedo/nostr-editor","banner":"https://image.nostr.build/87dbc55a6391d15bddda206561d53867a5679dd95e84fe8ed62bfe2e3adcadf3.jpg\\",\\"ox 87dbc55a6391d15bddda206561d53867a5679dd95e84fe8ed62bfe2e3adcadf3"}',
16
- created_at: 1727998492,
17
- id: "c771fe19ac255ea28690c5547258a5e146d2f47805f7f48093b773478bdd137c",
18
- kind: 0,
19
- pubkey: "c6603b0f1ccfec625d9c08b753e4f774eaf7d1cf2769223125b5fd4da728019e",
20
- relays: [""],
21
- sig: "5220d6a8cdb4837b2569c26a84a2ac6a44427a224cb1602c05c578c6a63fe122a37e16455b09cb38bf297fc8161a8e715d7b444d017624c044d87a77e092c881",
22
- tags: [["alt", "User profile for Cesar Dias"]],
23
- };
24
- describe("claimLatest", () => {
25
- it("it should claim events", () => {
26
- const database = new Database();
27
- const sub = database.inserted.pipe(claimLatest(database)).subscribe();
28
- database.addEvent(event1);
29
- expect(database.isClaimed(event1)).toBe(true);
30
- database.addEvent(event2);
31
- expect(database.isClaimed(event1)).toBe(false);
32
- expect(database.isClaimed(event2)).toBe(true);
33
- sub.unsubscribe();
34
- expect(database.isClaimed(event1)).toBe(false);
35
- expect(database.isClaimed(event2)).toBe(false);
36
- });
37
- });
@@ -1,55 +0,0 @@
1
- import { beforeEach, describe, expect, it } from "vitest";
2
- import { subscribeSpyTo } from "@hirez_io/observer-spy";
3
- import { of } from "rxjs";
4
- import { EventStore } from "../../event-store/event-store.js";
5
- import { listenLatestUpdates } from "../listen-latest-updates.js";
6
- import { FakeUser } from "../../__tests__/fixtures.js";
7
- let eventStore;
8
- let user;
9
- let event;
10
- beforeEach(() => {
11
- eventStore = new EventStore();
12
- user = new FakeUser();
13
- event = user.note("original content");
14
- });
15
- describe("listenLatestUpdates", () => {
16
- it("should emit the initial event", () => {
17
- const source = of(event);
18
- const spy = subscribeSpyTo(source.pipe(listenLatestUpdates(eventStore)));
19
- expect(spy.getValues()).toEqual([event]);
20
- });
21
- it("should emit the event again when it's updated in the event store", () => {
22
- // Add the event to the store first
23
- eventStore.add(event);
24
- // Create a source that emits the event
25
- const source = of(event);
26
- const spy = subscribeSpyTo(source.pipe(listenLatestUpdates(eventStore)));
27
- // Create an updated version of the event
28
- Reflect.set(event, Symbol.for("new-prop"), "testing");
29
- // Update the event in the store
30
- eventStore.update(event);
31
- // Should have received both the original and updated event
32
- expect(spy.getValues()).toEqual([event, event]);
33
- });
34
- it("should not emit updates for other events", () => {
35
- // Add the event to the store
36
- eventStore.add(event);
37
- // Create a source that emits the event
38
- const source = of(event);
39
- const spy = subscribeSpyTo(source.pipe(listenLatestUpdates(eventStore)));
40
- // Create a different event
41
- const otherEvent = user.note("other content");
42
- // Add the other event to the store
43
- eventStore.add(otherEvent);
44
- // Should only have received the original event
45
- expect(spy.getValues()).toEqual([event]);
46
- });
47
- it("should handle undefined initial event", () => {
48
- const source = of(undefined);
49
- const spy = subscribeSpyTo(source.pipe(listenLatestUpdates(eventStore)));
50
- expect(spy.getValues()).toEqual([undefined]);
51
- // Adding events to the store should not trigger emissions
52
- eventStore.add(event);
53
- expect(spy.getValues()).toEqual([undefined]);
54
- });
55
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,34 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { Observable, Subject, firstValueFrom } from "rxjs";
3
- import { simpleTimeout, TimeoutError } from "../simple-timeout.js";
4
- describe("simpleTimeout operator", () => {
5
- it("should throw TimeoutError after specified timeout period", async () => {
6
- const subject = new Subject();
7
- const obs = subject.pipe(simpleTimeout(10));
8
- const promise = firstValueFrom(obs);
9
- await expect(promise).rejects.toThrow(TimeoutError);
10
- await expect(promise).rejects.toThrow("Timeout");
11
- });
12
- it("should throw TimeoutError with custom message", async () => {
13
- const subject = new Subject();
14
- const customMessage = "Custom timeout message";
15
- const obs = subject.pipe(simpleTimeout(10, customMessage));
16
- const promise = firstValueFrom(obs);
17
- await expect(promise).rejects.toThrow(TimeoutError);
18
- await expect(promise).rejects.toThrow(customMessage);
19
- });
20
- it("should not throw when value emitted before timeout", async () => {
21
- const subject = new Subject();
22
- const obs = subject.pipe(simpleTimeout(1000));
23
- const promise = firstValueFrom(obs);
24
- subject.next("test value");
25
- await expect(promise).resolves.toBe("test value");
26
- });
27
- it("should complete without error when source emits non-null value before timeout", async () => {
28
- const source = new Observable((subscriber) => {
29
- subscriber.next("test value");
30
- });
31
- const result = await firstValueFrom(source.pipe(simpleTimeout(10)));
32
- expect(result).toBe("test value");
33
- });
34
- });
@@ -1,5 +0,0 @@
1
- import { NostrEvent } from "nostr-tools";
2
- import { MonoTypeOperatorFunction } from "rxjs";
3
- import { IStreamEventStore } from "../event-store/interface.js";
4
- /** Lists for any updates to the latest event and remits it */
5
- export declare function listenLatestUpdates(eventStore: IStreamEventStore): MonoTypeOperatorFunction<NostrEvent | undefined>;
@@ -1,12 +0,0 @@
1
- import { filter, merge, tap } from "rxjs";
2
- /** Lists for any updates to the latest event and remits it */
3
- export function listenLatestUpdates(eventStore) {
4
- return (source) => {
5
- let latest;
6
- return merge(
7
- // Get the latest event
8
- source.pipe(tap((value) => (latest = value))),
9
- // listen for updates
10
- eventStore.updates.pipe(filter((e) => e.id === latest?.id)));
11
- };
12
- }
@@ -1,2 +0,0 @@
1
- import { Query } from "../query-store/index.js";
2
- export declare function UserBlossomServersQuery(pubkey: string): Query<URL[] | undefined>;
@@ -1,5 +0,0 @@
1
- import { map } from "rxjs/operators";
2
- import { BLOSSOM_SERVER_LIST_KIND, getBlossomServersFromList } from "../helpers/blossom.js";
3
- export function UserBlossomServersQuery(pubkey) {
4
- return (store) => store.replaceable(BLOSSOM_SERVER_LIST_KIND, pubkey).pipe(map((event) => event && getBlossomServersFromList(event)));
5
- }
@@ -1,8 +0,0 @@
1
- import { Bookmarks } from "../helpers/bookmarks.js";
2
- import { Query } from "../query-store/index.js";
3
- /** A query that returns all the bookmarks of a user */
4
- export declare function UserBookmarkQuery(pubkey: string): Query<Bookmarks | undefined>;
5
- /** A query that returns all the public bookmarks of a user */
6
- export declare function UserPublicBookmarkQuery(pubkey: string): Query<Bookmarks | undefined>;
7
- /** A query that returns all the hidden bookmarks of a user */
8
- export declare function UserHiddenBookmarkQuery(pubkey: string): Query<Bookmarks | null | undefined>;
@@ -1,11 +0,0 @@
1
- import { Query } from "applesauce-core";
2
- import { NostrEvent } from "nostr-tools";
3
- import { ChannelMetadataContent } from "../helpers/channels.js";
4
- /** A query that returns a map of hidden messages Map<id, reason> */
5
- export declare function ChannelHiddenQuery(channel: NostrEvent, authors?: string[]): Query<Map<string, string>>;
6
- /** A query that returns all messages in a channel */
7
- export declare function ChannelMessagesQuery(channel: NostrEvent): Query<NostrEvent[]>;
8
- /** A query that returns the latest parsed metadata */
9
- export declare function ChannelMetadataQuery(channel: NostrEvent): Query<ChannelMetadataContent | undefined>;
10
- /** A query that returns a map of muted users Map<pubkey, reason> */
11
- export declare function ChannelMutedQuery(channel: NostrEvent, authors?: string[]): Query<Map<string, string>>;
@@ -1,4 +0,0 @@
1
- import { NostrEvent } from "nostr-tools";
2
- import { Query } from "../query-store/index.js";
3
- /** Returns all NIP-22 comment replies for the event */
4
- export declare function CommentsQuery(parent: NostrEvent): Query<NostrEvent[]>;
@@ -1,11 +0,0 @@
1
- import { COMMENT_KIND, getEventUID } from "../helpers/index.js";
2
- import { isAddressableKind } from "nostr-tools/kinds";
3
- /** Returns all NIP-22 comment replies for the event */
4
- export function CommentsQuery(parent) {
5
- return (events) => {
6
- const filter = { kinds: [COMMENT_KIND], "#e": [parent.id] };
7
- if (isAddressableKind(parent.kind))
8
- filter["#a"] = [getEventUID(parent)];
9
- return events.timeline(filter);
10
- };
11
- }
@@ -1,8 +0,0 @@
1
- import { ProfilePointer } from "nostr-tools/nip19";
2
- import { Query } from "../query-store/index.js";
3
- /** A query that returns all contacts for a user */
4
- export declare function ContactsQuery(pubkey: string): Query<ProfilePointer[] | undefined>;
5
- /** A query that returns all public contacts for a user */
6
- export declare function PublicContactsQuery(pubkey: string): Query<ProfilePointer[] | undefined>;
7
- /** A query that returns all hidden contacts for a user */
8
- export declare function HiddenContactsQuery(pubkey: string): Query<ProfilePointer[] | null | undefined>;
@@ -1,6 +0,0 @@
1
- import { Query } from "../query-store/index.js";
2
- /** A query that gets and parses the inbox and outbox relays for a pubkey */
3
- export declare function MailboxesQuery(pubkey: string): Query<{
4
- inboxes: string[];
5
- outboxes: string[];
6
- } | undefined>;
@@ -1,8 +0,0 @@
1
- import { Mutes } from "../helpers/mutes.js";
2
- import { Query } from "../query-store/index.js";
3
- /** A query that returns all a users muted things */
4
- export declare function MuteQuery(pubkey: string): Query<Mutes | undefined>;
5
- /** A query that returns all a users public muted things */
6
- export declare function PublicMuteQuery(pubkey: string): Query<Mutes | undefined>;
7
- /** A query that returns all a users hidden muted things */
8
- export declare function HiddenMuteQuery(pubkey: string): Query<Mutes | null | undefined>;
@@ -1,4 +0,0 @@
1
- import { Query } from "applesauce-core";
2
- import { EventPointer } from "nostr-tools/nip19";
3
- /** A query that returns all pinned pointers for a user */
4
- export declare function UserPinnedQuery(pubkey: string): Query<EventPointer[] | undefined>;
@@ -1,4 +0,0 @@
1
- import { ProfileContent } from "../helpers/profile.js";
2
- import { Query } from "../query-store/index.js";
3
- /** A query that gets and parses the kind 0 metadata for a pubkey */
4
- export declare function ProfileQuery(pubkey: string): Query<ProfileContent | undefined>;
@@ -1,7 +0,0 @@
1
- import { kinds } from "nostr-tools";
2
- import { filter, map } from "rxjs/operators";
3
- import { getProfileContent, isValidProfile } from "../helpers/profile.js";
4
- /** A query that gets and parses the kind 0 metadata for a pubkey */
5
- export function ProfileQuery(pubkey) {
6
- return (events) => events.replaceable(kinds.Metadata, pubkey).pipe(filter(isValidProfile), map((event) => event && getProfileContent(event)));
7
- }
@@ -1,4 +0,0 @@
1
- import { NostrEvent } from "nostr-tools";
2
- import { Query } from "../query-store/index.js";
3
- /** A query that returns all reactions to an event (supports replaceable events) */
4
- export declare function ReactionsQuery(event: NostrEvent): Query<NostrEvent[]>;
@@ -1,27 +0,0 @@
1
- import { AddressPointer } from "nostr-tools/nip19";
2
- import { ReadListTags } from "../helpers/lists.js";
3
- import { Query } from "../query-store/query-store.js";
4
- /**
5
- * A query that returns all favorite relays for a pubkey
6
- * @param pubkey - The pubkey to get the favorite relays for
7
- * @param type - Which types of tags to read
8
- */
9
- export declare function FavoriteRelays(pubkey: string, type?: ReadListTags): Query<string[] | undefined>;
10
- /**
11
- * A query that returns all favorite relay sets for a pubkey
12
- * @param pubkey - The pubkey to get the favorite relay sets for
13
- * @param type - Which types of tags to read
14
- */
15
- export declare function FavoriteRelaySets(pubkey: string, type?: ReadListTags): Query<AddressPointer[] | undefined>;
16
- /**
17
- * A query that returns all search relays for a pubkey
18
- * @param pubkey - The pubkey to get the search relays for
19
- * @param type - Which types of tags to read
20
- */
21
- export declare function SearchRelays(pubkey: string, type?: ReadListTags): Query<string[] | undefined>;
22
- /**
23
- * A query that returns all blocked relays for a pubkey
24
- * @param pubkey - The pubkey to get the blocked relays for
25
- * @param type - Which types of tags to read
26
- */
27
- export declare function BlockedRelays(pubkey: string, type?: ReadListTags): Query<string[] | undefined>;