applesauce-core 0.8.0 → 0.10.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 (78) hide show
  1. package/README.md +1 -1
  2. package/dist/event-store/database.d.ts +17 -14
  3. package/dist/event-store/database.js +50 -33
  4. package/dist/event-store/event-store.d.ts +37 -14
  5. package/dist/event-store/event-store.js +249 -96
  6. package/dist/helpers/bolt11.d.ts +9 -0
  7. package/dist/helpers/bolt11.js +15 -0
  8. package/dist/helpers/cache.js +9 -9
  9. package/dist/helpers/comment.d.ts +48 -0
  10. package/dist/helpers/comment.js +116 -0
  11. package/dist/helpers/content.d.ts +3 -0
  12. package/dist/helpers/content.js +8 -0
  13. package/dist/helpers/delete.d.ts +3 -0
  14. package/dist/helpers/delete.js +7 -0
  15. package/dist/helpers/emoji.d.ts +10 -1
  16. package/dist/helpers/emoji.js +12 -0
  17. package/dist/helpers/event.d.ts +9 -1
  18. package/dist/helpers/event.js +25 -1
  19. package/dist/helpers/external-id.d.ts +29 -0
  20. package/dist/helpers/external-id.js +20 -0
  21. package/dist/helpers/filter.d.ts +0 -2
  22. package/dist/helpers/filter.js +3 -7
  23. package/dist/helpers/hidden-tags.d.ts +48 -0
  24. package/dist/helpers/hidden-tags.js +108 -0
  25. package/dist/helpers/hidden-tags.test.d.ts +1 -0
  26. package/dist/helpers/hidden-tags.test.js +28 -0
  27. package/dist/helpers/index.d.ts +17 -7
  28. package/dist/helpers/index.js +17 -7
  29. package/dist/helpers/json.d.ts +1 -0
  30. package/dist/helpers/json.js +1 -0
  31. package/dist/helpers/lnurl.d.ts +4 -0
  32. package/dist/helpers/lnurl.js +40 -0
  33. package/dist/helpers/mailboxes.d.ts +0 -6
  34. package/dist/helpers/mailboxes.js +7 -8
  35. package/dist/helpers/mailboxes.test.js +13 -12
  36. package/dist/helpers/media-attachment.d.ts +33 -0
  37. package/dist/helpers/media-attachment.js +60 -0
  38. package/dist/helpers/pointers.d.ts +39 -6
  39. package/dist/helpers/pointers.js +102 -20
  40. package/dist/helpers/profile.d.ts +2 -7
  41. package/dist/helpers/profile.js +26 -23
  42. package/dist/helpers/string.d.ts +6 -0
  43. package/dist/helpers/string.js +2 -0
  44. package/dist/helpers/tags.d.ts +6 -0
  45. package/dist/helpers/tags.js +6 -0
  46. package/dist/helpers/threading.d.ts +10 -10
  47. package/dist/helpers/threading.js +52 -19
  48. package/dist/helpers/threading.test.d.ts +1 -0
  49. package/dist/helpers/threading.test.js +41 -0
  50. package/dist/helpers/url.d.ts +4 -1
  51. package/dist/helpers/url.js +4 -3
  52. package/dist/helpers/zap.d.ts +39 -0
  53. package/dist/helpers/zap.js +95 -0
  54. package/dist/observable/{getValue.d.ts → get-value.d.ts} +1 -0
  55. package/dist/observable/{getValue.js → get-value.js} +3 -0
  56. package/dist/observable/index.d.ts +1 -1
  57. package/dist/observable/index.js +1 -1
  58. package/dist/promise/deferred.d.ts +1 -0
  59. package/dist/promise/deferred.js +1 -0
  60. package/dist/queries/comments.d.ts +4 -0
  61. package/dist/queries/comments.js +14 -0
  62. package/dist/queries/index.d.ts +4 -2
  63. package/dist/queries/index.js +4 -2
  64. package/dist/queries/mailboxes.d.ts +1 -0
  65. package/dist/queries/mailboxes.js +1 -0
  66. package/dist/queries/profile.d.ts +1 -0
  67. package/dist/queries/profile.js +4 -3
  68. package/dist/queries/reactions.d.ts +1 -1
  69. package/dist/queries/reactions.js +1 -1
  70. package/dist/queries/simple.d.ts +3 -3
  71. package/dist/queries/simple.js +13 -13
  72. package/dist/queries/thread.d.ts +2 -0
  73. package/dist/queries/thread.js +29 -3
  74. package/dist/queries/zaps.d.ts +5 -0
  75. package/dist/queries/zaps.js +21 -0
  76. package/dist/query-store/index.d.ts +22 -12
  77. package/dist/query-store/index.js +36 -30
  78. package/package.json +14 -16
@@ -5,7 +5,15 @@ import { LRU } from "../helpers/lru.js";
5
5
  import * as Queries from "../queries/index.js";
6
6
  import { AddressPointer, EventPointer } from "nostr-tools/nip19";
7
7
  export type Query<T extends unknown> = {
8
+ /**
9
+ * A unique key for this query. this is used to detect duplicate queries
10
+ */
8
11
  key: string;
12
+ /** The args array this query was created with. This is mostly for debugging */
13
+ args?: Array<any>;
14
+ /**
15
+ * The meat of the query, this should return an Observables that subscribes to the eventStore in some way
16
+ */
9
17
  run: (events: EventStore, store: QueryStore) => Observable<T>;
10
18
  };
11
19
  export type QueryConstructor<T extends unknown, Args extends Array<any>> = (...args: Args) => Query<T>;
@@ -13,35 +21,37 @@ export declare class QueryStore {
13
21
  static Queries: typeof Queries;
14
22
  store: EventStore;
15
23
  constructor(store: EventStore);
16
- queries: LRU<Observable<any> | BehaviorSubject<any>>;
24
+ queries: LRU<Query<any>>;
25
+ observables: WeakMap<Query<any>, Observable<any> | BehaviorSubject<any>>;
17
26
  /** Creates a cached query */
18
- runQuery<T extends unknown, Args extends Array<any>>(queryConstructor: (...args: Args) => {
27
+ createQuery<T extends unknown, Args extends Array<any>>(queryConstructor: (...args: Args) => {
19
28
  key: string;
20
29
  run: (events: EventStore, store: QueryStore) => Observable<T>;
21
- }): (...args: Args) => Observable<T>;
22
- /** Returns a single event */
30
+ }, ...args: Args): Observable<T>;
31
+ /** Creates a SingleEventQuery */
23
32
  event(id: string): Observable<import("nostr-tools").Event | undefined>;
24
- /** Returns a single event */
33
+ /** Creates a MultipleEventsQuery */
25
34
  events(ids: string[]): Observable<Map<string, import("nostr-tools").Event>>;
26
- /** Returns the latest version of a replaceable event */
35
+ /** Creates a ReplaceableQuery */
27
36
  replaceable(kind: number, pubkey: string, d?: string): Observable<import("nostr-tools").Event | undefined>;
28
- /** Returns a directory of events by their UID */
37
+ /** Creates a ReplaceableSetQuery */
29
38
  replaceableSet(pointers: {
30
39
  kind: number;
31
40
  pubkey: string;
32
41
  identifier?: string;
33
42
  }[]): Observable<Map<string, import("nostr-tools").Event>>;
34
- /** Returns an array of events that match the filter */
35
- timeline(filters: Filter | Filter[]): Observable<import("nostr-tools").Event[]>;
36
- /** Returns the parsed profile (0) for a pubkey */
43
+ /** Creates a TimelineQuery */
44
+ timeline(filters: Filter | Filter[], keepOldVersions?: boolean): Observable<import("nostr-tools").Event[]>;
45
+ /** Creates a ProfileQuery */
37
46
  profile(pubkey: string): Observable<import("../helpers/profile.js").ProfileContent | undefined>;
38
- /** Returns all reactions for an event (supports replaceable events) */
47
+ /** Creates a ReactionsQuery */
39
48
  reactions(event: NostrEvent): Observable<import("nostr-tools").Event[]>;
40
- /** Returns the parsed relay list (10002) for the pubkey */
49
+ /** Creates a MailboxesQuery */
41
50
  mailboxes(pubkey: string): Observable<{
42
51
  inboxes: string[];
43
52
  outboxes: string[];
44
53
  } | undefined>;
54
+ /** Creates a ThreadQuery */
45
55
  thread(root: string | EventPointer | AddressPointer): Observable<Queries.Thread>;
46
56
  }
47
57
  export { Queries };
@@ -8,53 +8,59 @@ export class QueryStore {
8
8
  this.store = store;
9
9
  }
10
10
  queries = new LRU();
11
+ observables = new WeakMap();
11
12
  /** Creates a cached query */
12
- runQuery(queryConstructor) {
13
- return (...args) => {
14
- const query = queryConstructor(...args);
15
- const key = `${queryConstructor.name}|${query.key}`;
16
- if (!this.queries.has(key)) {
17
- const observable = query.run(this.store, this).pipe(shareLatestValue());
18
- this.queries.set(key, observable);
19
- return observable;
20
- }
21
- return this.queries.get(key);
22
- };
23
- }
24
- /** Returns a single event */
13
+ createQuery(queryConstructor, ...args) {
14
+ const tempQuery = queryConstructor(...args);
15
+ const key = `${queryConstructor.name}|${tempQuery.key}`;
16
+ let query = this.queries.get(key);
17
+ if (!query) {
18
+ query = tempQuery;
19
+ this.queries.set(key, tempQuery);
20
+ }
21
+ if (!this.observables.has(query)) {
22
+ query.args = args;
23
+ const observable = query.run(this.store, this).pipe(shareLatestValue());
24
+ this.observables.set(query, observable);
25
+ return observable;
26
+ }
27
+ return this.observables.get(query);
28
+ }
29
+ /** Creates a SingleEventQuery */
25
30
  event(id) {
26
- return this.runQuery(Queries.SingleEventQuery)(id);
31
+ return this.createQuery(Queries.SingleEventQuery, id);
27
32
  }
28
- /** Returns a single event */
33
+ /** Creates a MultipleEventsQuery */
29
34
  events(ids) {
30
- return this.runQuery(Queries.MultipleEventsQuery)(ids);
35
+ return this.createQuery(Queries.MultipleEventsQuery, ids);
31
36
  }
32
- /** Returns the latest version of a replaceable event */
37
+ /** Creates a ReplaceableQuery */
33
38
  replaceable(kind, pubkey, d) {
34
- return this.runQuery(Queries.ReplaceableQuery)(kind, pubkey, d);
39
+ return this.createQuery(Queries.ReplaceableQuery, kind, pubkey, d);
35
40
  }
36
- /** Returns a directory of events by their UID */
41
+ /** Creates a ReplaceableSetQuery */
37
42
  replaceableSet(pointers) {
38
- return this.runQuery(Queries.ReplaceableSetQuery)(pointers);
43
+ return this.createQuery(Queries.ReplaceableSetQuery, pointers);
39
44
  }
40
- /** Returns an array of events that match the filter */
41
- timeline(filters) {
42
- return this.runQuery(Queries.TimelineQuery)(filters);
45
+ /** Creates a TimelineQuery */
46
+ timeline(filters, keepOldVersions) {
47
+ return this.createQuery(Queries.TimelineQuery, filters, keepOldVersions);
43
48
  }
44
- /** Returns the parsed profile (0) for a pubkey */
49
+ /** Creates a ProfileQuery */
45
50
  profile(pubkey) {
46
- return this.runQuery(Queries.ProfileQuery)(pubkey);
51
+ return this.createQuery(Queries.ProfileQuery, pubkey);
47
52
  }
48
- /** Returns all reactions for an event (supports replaceable events) */
53
+ /** Creates a ReactionsQuery */
49
54
  reactions(event) {
50
- return this.runQuery(Queries.ReactionsQuery)(event);
55
+ return this.createQuery(Queries.ReactionsQuery, event);
51
56
  }
52
- /** Returns the parsed relay list (10002) for the pubkey */
57
+ /** Creates a MailboxesQuery */
53
58
  mailboxes(pubkey) {
54
- return this.runQuery(Queries.MailboxesQuery)(pubkey);
59
+ return this.createQuery(Queries.MailboxesQuery, pubkey);
55
60
  }
61
+ /** Creates a ThreadQuery */
56
62
  thread(root) {
57
- return this.runQuery(Queries.ThreadQuery)(root);
63
+ return this.createQuery(Queries.ThreadQuery, root);
58
64
  }
59
65
  }
60
66
  export { Queries };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-core",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -52,31 +52,29 @@
52
52
  }
53
53
  },
54
54
  "dependencies": {
55
+ "@scure/base": "^1.1.9",
55
56
  "debug": "^4.3.7",
56
- "json-stringify-deterministic": "^1.0.12",
57
+ "fast-deep-equal": "^3.1.3",
58
+ "hash-sum": "^2.0.0",
59
+ "light-bolt11-decoder": "^3.2.0",
57
60
  "nanoid": "^5.0.7",
58
- "nostr-tools": "^2.7.2",
61
+ "nostr-tools": "^2.10.3",
59
62
  "rxjs": "^7.8.1"
60
63
  },
61
64
  "devDependencies": {
62
- "@jest/globals": "^29.7.0",
63
65
  "@types/debug": "^4.1.12",
64
- "@types/jest": "^29.5.13",
65
- "jest": "^29.7.0",
66
- "jest-extended": "^4.0.2"
66
+ "@types/hash-sum": "^1.0.2",
67
+ "typescript": "^5.6.3",
68
+ "vitest": "^2.1.8"
67
69
  },
68
- "jest": {
69
- "roots": [
70
- "dist"
71
- ],
72
- "setupFilesAfterEnv": [
73
- "jest-extended/all"
74
- ]
70
+ "funding": {
71
+ "type": "lightning",
72
+ "url": "lightning:nostrudel@geyser.fund"
75
73
  },
76
74
  "scripts": {
77
75
  "build": "tsc",
78
76
  "watch:build": "tsc --watch > /dev/null",
79
- "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
80
- "watch:test": "(trap 'kill 0' SIGINT; pnpm run build -w > /dev/null & pnpm run test --watch)"
77
+ "test": "vitest run --passWithNoTests",
78
+ "watch:test": "vitest"
81
79
  }
82
80
  }