applesauce-core 0.9.0 → 0.11.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 (153) hide show
  1. package/README.md +1 -1
  2. package/dist/__tests__/fixtures.d.ts +8 -0
  3. package/dist/__tests__/fixtures.js +20 -0
  4. package/dist/event-store/__tests__/event-store.test.js +259 -0
  5. package/dist/event-store/database.d.ts +22 -16
  6. package/dist/event-store/database.js +62 -39
  7. package/dist/event-store/event-store.d.ts +52 -15
  8. package/dist/event-store/event-store.js +283 -191
  9. package/dist/helpers/__tests__/blossom.test.d.ts +1 -0
  10. package/dist/helpers/__tests__/blossom.test.js +13 -0
  11. package/dist/helpers/__tests__/comment.test.d.ts +1 -0
  12. package/dist/helpers/__tests__/comment.test.js +235 -0
  13. package/dist/helpers/__tests__/emoji.test.d.ts +1 -0
  14. package/dist/helpers/__tests__/emoji.test.js +15 -0
  15. package/dist/helpers/__tests__/event.test.d.ts +1 -0
  16. package/dist/helpers/__tests__/event.test.js +36 -0
  17. package/dist/helpers/__tests__/file-metadata.test.d.ts +1 -0
  18. package/dist/helpers/__tests__/file-metadata.test.js +103 -0
  19. package/dist/helpers/__tests__/hidden-tags.test.d.ts +1 -0
  20. package/dist/helpers/__tests__/hidden-tags.test.js +29 -0
  21. package/dist/helpers/__tests__/mailboxes.test.d.ts +1 -0
  22. package/dist/helpers/{mailboxes.test.js → __tests__/mailboxes.test.js} +14 -13
  23. package/dist/helpers/__tests__/relays.test.d.ts +1 -0
  24. package/dist/helpers/__tests__/relays.test.js +21 -0
  25. package/dist/helpers/__tests__/tags.test.d.ts +1 -0
  26. package/dist/helpers/__tests__/tags.test.js +24 -0
  27. package/dist/helpers/__tests__/threading.test.d.ts +1 -0
  28. package/dist/helpers/__tests__/threading.test.js +41 -0
  29. package/dist/helpers/blossom.d.ts +9 -0
  30. package/dist/helpers/blossom.js +22 -0
  31. package/dist/helpers/bolt11.d.ts +1 -0
  32. package/dist/helpers/bolt11.js +1 -0
  33. package/dist/helpers/bookmarks.d.ts +15 -0
  34. package/dist/helpers/bookmarks.js +27 -0
  35. package/dist/helpers/channels.d.ts +10 -0
  36. package/dist/helpers/channels.js +27 -0
  37. package/dist/helpers/comment.d.ts +47 -0
  38. package/dist/helpers/comment.js +120 -0
  39. package/dist/helpers/contacts.d.ts +3 -0
  40. package/dist/helpers/contacts.js +25 -0
  41. package/dist/helpers/content.d.ts +3 -0
  42. package/dist/helpers/content.js +8 -0
  43. package/dist/helpers/delete.d.ts +3 -0
  44. package/dist/helpers/delete.js +7 -0
  45. package/dist/helpers/dns-identity.d.ts +7 -0
  46. package/dist/helpers/dns-identity.js +10 -0
  47. package/dist/helpers/emoji.d.ts +12 -1
  48. package/dist/helpers/emoji.js +13 -1
  49. package/dist/helpers/event.d.ts +17 -3
  50. package/dist/helpers/event.js +54 -12
  51. package/dist/helpers/external-id.d.ts +29 -0
  52. package/dist/helpers/external-id.js +20 -0
  53. package/dist/helpers/file-metadata.d.ts +55 -0
  54. package/dist/helpers/file-metadata.js +99 -0
  55. package/dist/helpers/filter.d.ts +4 -2
  56. package/dist/helpers/filter.js +36 -7
  57. package/dist/helpers/groups.d.ts +24 -0
  58. package/dist/helpers/groups.js +39 -0
  59. package/dist/helpers/hidden-tags.d.ts +48 -0
  60. package/dist/helpers/hidden-tags.js +86 -0
  61. package/dist/helpers/index.d.ts +28 -8
  62. package/dist/helpers/index.js +28 -8
  63. package/dist/helpers/json.d.ts +1 -0
  64. package/dist/helpers/json.js +1 -0
  65. package/dist/helpers/lists.d.ts +28 -0
  66. package/dist/helpers/lists.js +65 -0
  67. package/dist/helpers/lnurl.d.ts +4 -0
  68. package/dist/helpers/lnurl.js +40 -0
  69. package/dist/helpers/mailboxes.js +16 -9
  70. package/dist/helpers/mutes.d.ts +14 -0
  71. package/dist/helpers/mutes.js +23 -0
  72. package/dist/helpers/picture-post.d.ts +4 -0
  73. package/dist/helpers/picture-post.js +6 -0
  74. package/dist/helpers/pointers.d.ts +38 -5
  75. package/dist/helpers/pointers.js +105 -25
  76. package/dist/helpers/profile.d.ts +6 -1
  77. package/dist/helpers/profile.js +5 -1
  78. package/dist/helpers/relays.d.ts +6 -3
  79. package/dist/helpers/relays.js +25 -18
  80. package/dist/helpers/share.d.ts +4 -0
  81. package/dist/helpers/share.js +12 -0
  82. package/dist/helpers/string.d.ts +6 -0
  83. package/dist/helpers/string.js +2 -0
  84. package/dist/helpers/tags.d.ts +23 -0
  85. package/dist/helpers/tags.js +34 -6
  86. package/dist/helpers/threading.d.ts +6 -6
  87. package/dist/helpers/threading.js +30 -9
  88. package/dist/helpers/url.d.ts +11 -1
  89. package/dist/helpers/url.js +31 -3
  90. package/dist/helpers/user-status.d.ts +18 -0
  91. package/dist/helpers/user-status.js +21 -0
  92. package/dist/helpers/zap.d.ts +25 -0
  93. package/dist/helpers/zap.js +32 -3
  94. package/dist/observable/__tests__/claim-events.test.d.ts +1 -0
  95. package/dist/observable/__tests__/claim-events.test.js +23 -0
  96. package/dist/observable/__tests__/claim-latest.test.d.ts +1 -0
  97. package/dist/observable/__tests__/claim-latest.test.js +37 -0
  98. package/dist/observable/__tests__/simple-timeout.test.d.ts +1 -0
  99. package/dist/observable/__tests__/simple-timeout.test.js +34 -0
  100. package/dist/observable/claim-events.d.ts +5 -0
  101. package/dist/observable/claim-events.js +28 -0
  102. package/dist/observable/claim-latest.d.ts +4 -0
  103. package/dist/observable/claim-latest.js +20 -0
  104. package/dist/observable/get-observable-value.d.ts +3 -0
  105. package/dist/observable/get-observable-value.js +9 -0
  106. package/dist/observable/index.d.ts +2 -1
  107. package/dist/observable/index.js +2 -1
  108. package/dist/observable/share-latest-value.d.ts +2 -4
  109. package/dist/observable/share-latest-value.js +19 -16
  110. package/dist/observable/simple-timeout.d.ts +4 -0
  111. package/dist/observable/simple-timeout.js +6 -0
  112. package/dist/promise/deferred.d.ts +1 -0
  113. package/dist/promise/deferred.js +1 -0
  114. package/dist/queries/blossom.d.ts +2 -0
  115. package/dist/queries/blossom.js +10 -0
  116. package/dist/queries/bookmarks.d.ts +8 -0
  117. package/dist/queries/bookmarks.js +23 -0
  118. package/dist/queries/channels.d.ts +11 -0
  119. package/dist/queries/channels.js +73 -0
  120. package/dist/queries/comments.d.ts +4 -0
  121. package/dist/queries/comments.js +14 -0
  122. package/dist/queries/contacts.d.ts +3 -0
  123. package/dist/queries/contacts.js +12 -0
  124. package/dist/queries/index.d.ts +9 -2
  125. package/dist/queries/index.js +9 -2
  126. package/dist/queries/mailboxes.d.ts +1 -0
  127. package/dist/queries/mailboxes.js +1 -0
  128. package/dist/queries/mutes.d.ts +8 -0
  129. package/dist/queries/mutes.js +23 -0
  130. package/dist/queries/pins.d.ts +3 -0
  131. package/dist/queries/pins.js +12 -0
  132. package/dist/queries/profile.d.ts +1 -0
  133. package/dist/queries/profile.js +1 -0
  134. package/dist/queries/reactions.d.ts +1 -1
  135. package/dist/queries/reactions.js +1 -1
  136. package/dist/queries/simple.d.ts +4 -4
  137. package/dist/queries/simple.js +13 -13
  138. package/dist/queries/thread.d.ts +2 -0
  139. package/dist/queries/thread.js +30 -4
  140. package/dist/queries/user-status.d.ts +11 -0
  141. package/dist/queries/user-status.js +39 -0
  142. package/dist/queries/zaps.d.ts +1 -0
  143. package/dist/queries/zaps.js +1 -0
  144. package/dist/query-store/index.d.ts +1 -47
  145. package/dist/query-store/index.js +1 -60
  146. package/dist/query-store/query-store.d.ts +51 -0
  147. package/dist/query-store/query-store.js +88 -0
  148. package/dist/query-store/query-store.test.d.ts +1 -0
  149. package/dist/query-store/query-store.test.js +33 -0
  150. package/package.json +24 -21
  151. package/dist/observable/getValue.d.ts +0 -2
  152. package/dist/observable/getValue.js +0 -13
  153. /package/dist/{helpers/mailboxes.test.d.ts → event-store/__tests__/event-store.test.d.ts} +0 -0
@@ -0,0 +1,88 @@
1
+ import { filter, finalize, ReplaySubject, share, startWith, timer } from "rxjs";
2
+ import hash_sum from "hash-sum";
3
+ import * as Queries from "../queries/index.js";
4
+ import { getObservableValue } from "../observable/get-observable-value.js";
5
+ export class QueryStore {
6
+ static Queries = Queries;
7
+ store;
8
+ constructor(store) {
9
+ if (!store)
10
+ throw new Error("EventStore required");
11
+ this.store = store;
12
+ }
13
+ /** A directory of all active queries */
14
+ queries = new Map();
15
+ /** How long a query should be kept "warm" while nothing is subscribed to it */
16
+ queryKeepWarmTimeout = 60_000;
17
+ /** Creates a cached query */
18
+ createQuery(queryConstructor, ...args) {
19
+ let observables = this.queries.get(queryConstructor);
20
+ if (!observables) {
21
+ observables = new Map();
22
+ this.queries.set(queryConstructor, observables);
23
+ }
24
+ const key = hash_sum(args);
25
+ let observable = observables.get(key);
26
+ if (!observable) {
27
+ const cleanup = () => {
28
+ if (observables.get(key) === observable)
29
+ observables.delete(key);
30
+ };
31
+ observable = queryConstructor(...args)
32
+ .run(this.store, this)
33
+ .pipe(
34
+ // always emit undefined so the observable is sync
35
+ startWith(undefined),
36
+ // remove the observable when its subscribed
37
+ finalize(cleanup),
38
+ // only create a single observable for all components
39
+ share({ connector: () => new ReplaySubject(1), resetOnComplete: () => timer(this.queryKeepWarmTimeout) }));
40
+ // set debug fields
41
+ Reflect.set(observable, "queryArgs", args);
42
+ observables.set(key, observable);
43
+ }
44
+ return observable;
45
+ }
46
+ /** Creates a query and waits for the next value */
47
+ async executeQuery(queryConstructor, ...args) {
48
+ const query = this.createQuery(queryConstructor, ...args).pipe(filter((v) => v !== undefined));
49
+ return getObservableValue(query);
50
+ }
51
+ /** Creates a SingleEventQuery */
52
+ event(id) {
53
+ return this.createQuery(Queries.SingleEventQuery, id);
54
+ }
55
+ /** Creates a MultipleEventsQuery */
56
+ events(ids) {
57
+ return this.createQuery(Queries.MultipleEventsQuery, ids);
58
+ }
59
+ /** Creates a ReplaceableQuery */
60
+ replaceable(kind, pubkey, d) {
61
+ return this.createQuery(Queries.ReplaceableQuery, kind, pubkey, d);
62
+ }
63
+ /** Creates a ReplaceableSetQuery */
64
+ replaceableSet(pointers) {
65
+ return this.createQuery(Queries.ReplaceableSetQuery, pointers);
66
+ }
67
+ /** Creates a TimelineQuery */
68
+ timeline(filters, keepOldVersions) {
69
+ return this.createQuery(Queries.TimelineQuery, filters, keepOldVersions);
70
+ }
71
+ /** Creates a ProfileQuery */
72
+ profile(pubkey) {
73
+ return this.createQuery(Queries.ProfileQuery, pubkey);
74
+ }
75
+ /** Creates a ReactionsQuery */
76
+ reactions(event) {
77
+ return this.createQuery(Queries.ReactionsQuery, event);
78
+ }
79
+ /** Creates a MailboxesQuery */
80
+ mailboxes(pubkey) {
81
+ return this.createQuery(Queries.MailboxesQuery, pubkey);
82
+ }
83
+ /** Creates a ThreadQuery */
84
+ thread(root) {
85
+ return this.createQuery(Queries.ThreadQuery, root);
86
+ }
87
+ }
88
+ export { Queries };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ import { describe, it, expect, beforeEach } from "vitest";
2
+ import { EventStore } from "../event-store/event-store.js";
3
+ import { QueryStore } from "./query-store.js";
4
+ import { ProfileQuery } from "../queries/profile.js";
5
+ let eventStore;
6
+ let queryStore;
7
+ const event = {
8
+ 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":""}',
9
+ created_at: 1738362529,
10
+ id: "e9df8d5898c4ccfbd21fcd59f3f48abb3ff0ab7259b19570e2f1756de1e9306b",
11
+ kind: 0,
12
+ pubkey: "266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5",
13
+ sig: "465a47b93626a587bf81dadc2b306b8f713a62db31d6ce1533198e9ae1e665a6eaf376a03250bf9ffbb02eb9059c8eafbd37ae1092d05d215757575bd8357586",
14
+ tags: [],
15
+ };
16
+ beforeEach(() => {
17
+ eventStore = new EventStore();
18
+ queryStore = new QueryStore(eventStore);
19
+ });
20
+ describe("executeQuery", () => {
21
+ it("should resolve when value is already present", async () => {
22
+ eventStore.add(event);
23
+ expect(await queryStore.executeQuery(ProfileQuery, event.pubkey)).toEqual(expect.objectContaining({ name: "hzrd149" }));
24
+ });
25
+ it("should resolve when value is added to event store", async () => {
26
+ const p = queryStore.executeQuery(ProfileQuery, event.pubkey);
27
+ // delay adding the event
28
+ setTimeout(() => {
29
+ eventStore.add(event);
30
+ }, 10);
31
+ await expect(p).resolves.toEqual(expect.objectContaining({ name: "hzrd149" }));
32
+ });
33
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-core",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,69 +11,72 @@
11
11
  "author": "hzrd149",
12
12
  "license": "MIT",
13
13
  "files": [
14
- "dist"
14
+ "dist",
15
+ "applesauce"
15
16
  ],
16
17
  "exports": {
17
18
  ".": {
18
19
  "import": "./dist/index.js",
20
+ "require": "./dist/index.js",
19
21
  "types": "./dist/index.d.ts"
20
22
  },
21
23
  "./helpers": {
22
24
  "import": "./dist/helpers/index.js",
25
+ "require": "./dist/helpers/index.js",
23
26
  "types": "./dist/helpers/index.d.ts"
24
27
  },
25
28
  "./helpers/*": {
26
29
  "import": "./dist/helpers/*.js",
30
+ "require": "./dist/helpers/*.js",
27
31
  "types": "./dist/helpers/*.d.ts"
28
32
  },
29
33
  "./queries": {
30
34
  "import": "./dist/queries/index.js",
35
+ "require": "./dist/queries/index.js",
31
36
  "types": "./dist/queries/index.d.ts"
32
37
  },
33
38
  "./queries/*": {
34
39
  "import": "./dist/queries/*.js",
40
+ "require": "./dist/queries/*.js",
35
41
  "types": "./dist/queries/*.d.ts"
36
42
  },
37
43
  "./observable": {
38
44
  "import": "./dist/observable/index.js",
45
+ "require": "./dist/observable/index.js",
39
46
  "types": "./dist/observable/index.d.ts"
40
47
  },
41
48
  "./promise": {
42
49
  "import": "./dist/promise/index.js",
50
+ "require": "./dist/promise/index.js",
43
51
  "types": "./dist/promise/index.d.ts"
44
52
  },
45
53
  "./query-store": {
46
54
  "import": "./dist/query-store/index.js",
55
+ "require": "./dist/query-store/index.js",
47
56
  "types": "./dist/query-store/index.d.ts"
48
57
  },
49
58
  "./event-store": {
50
59
  "import": "./dist/event-store/index.js",
60
+ "require": "./dist/event-store/index.js",
51
61
  "types": "./dist/event-store/index.d.ts"
52
62
  }
53
63
  },
54
64
  "dependencies": {
55
- "debug": "^4.3.7",
56
- "json-stringify-deterministic": "^1.0.12",
65
+ "@scure/base": "^1.2.4",
66
+ "debug": "^4.4.0",
67
+ "fast-deep-equal": "^3.1.3",
68
+ "hash-sum": "^2.0.0",
57
69
  "light-bolt11-decoder": "^3.2.0",
58
- "nanoid": "^5.0.7",
59
- "nostr-tools": "^2.10.1",
70
+ "nanoid": "^5.0.9",
71
+ "nostr-tools": "^2.10.4",
60
72
  "rxjs": "^7.8.1"
61
73
  },
62
74
  "devDependencies": {
63
- "@jest/globals": "^29.7.0",
75
+ "@hirez_io/observer-spy": "^2.2.0",
64
76
  "@types/debug": "^4.1.12",
65
- "@types/jest": "^29.5.13",
66
- "jest": "^29.7.0",
67
- "jest-extended": "^4.0.2",
68
- "typescript": "^5.6.3"
69
- },
70
- "jest": {
71
- "roots": [
72
- "dist"
73
- ],
74
- "setupFilesAfterEnv": [
75
- "jest-extended/all"
76
- ]
77
+ "@types/hash-sum": "^1.0.2",
78
+ "typescript": "^5.7.3",
79
+ "vitest": "^3.0.5"
77
80
  },
78
81
  "funding": {
79
82
  "type": "lightning",
@@ -82,7 +85,7 @@
82
85
  "scripts": {
83
86
  "build": "tsc",
84
87
  "watch:build": "tsc --watch > /dev/null",
85
- "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
86
- "watch:test": "(trap 'kill 0' SIGINT; pnpm run build -w > /dev/null & pnpm run test --watch)"
88
+ "test": "vitest run --passWithNoTests",
89
+ "watch:test": "vitest"
87
90
  }
88
91
  }
@@ -1,2 +0,0 @@
1
- import { Observable } from "rxjs";
2
- export declare function getValue<T>(observable: Observable<T>): T | Promise<T>;
@@ -1,13 +0,0 @@
1
- import { BehaviorSubject } from "rxjs";
2
- export function getValue(observable) {
3
- if (observable instanceof BehaviorSubject)
4
- return observable.value;
5
- if (Reflect.has(observable, "value"))
6
- return Reflect.get(observable, "value");
7
- return new Promise((res) => {
8
- const sub = observable.subscribe((v) => {
9
- res(v);
10
- sub.unsubscribe();
11
- });
12
- });
13
- }