applesauce-core 0.2.0 → 0.4.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 (54) hide show
  1. package/README.md +38 -0
  2. package/dist/event-store/event-store.d.ts +3 -1
  3. package/dist/event-store/event-store.js +6 -2
  4. package/dist/helpers/channel.d.ts +15 -0
  5. package/dist/helpers/channel.js +27 -0
  6. package/dist/helpers/event.d.ts +17 -1
  7. package/dist/helpers/event.js +22 -9
  8. package/dist/helpers/index.d.ts +2 -1
  9. package/dist/helpers/index.js +2 -1
  10. package/dist/helpers/json.d.ts +1 -0
  11. package/dist/helpers/json.js +8 -0
  12. package/dist/helpers/mailboxes.d.ts +10 -2
  13. package/dist/helpers/mailboxes.js +10 -9
  14. package/dist/helpers/mailboxes.test.d.ts +1 -0
  15. package/dist/helpers/mailboxes.test.js +80 -0
  16. package/dist/helpers/mute.d.ts +21 -0
  17. package/dist/helpers/mute.js +52 -0
  18. package/dist/helpers/pointers.d.ts +22 -0
  19. package/dist/helpers/pointers.js +127 -0
  20. package/dist/helpers/profile.d.ts +7 -0
  21. package/dist/helpers/profile.js +4 -4
  22. package/dist/helpers/relays.d.ts +6 -0
  23. package/dist/helpers/relays.js +7 -6
  24. package/dist/helpers/threading.d.ts +55 -0
  25. package/dist/helpers/threading.js +61 -0
  26. package/dist/index.d.ts +1 -0
  27. package/dist/index.js +1 -0
  28. package/dist/observable/stateful.d.ts +1 -1
  29. package/dist/observable/stateful.js +1 -1
  30. package/dist/observable/throttle.d.ts +1 -0
  31. package/dist/observable/throttle.js +1 -0
  32. package/dist/promise/index.d.ts +1 -1
  33. package/dist/promise/index.js +1 -1
  34. package/dist/queries/channel.d.ts +11 -0
  35. package/dist/queries/channel.js +72 -0
  36. package/dist/queries/index.d.ts +7 -0
  37. package/dist/queries/index.js +7 -0
  38. package/dist/queries/mailboxes.d.ts +5 -0
  39. package/dist/queries/mailboxes.js +11 -0
  40. package/dist/queries/mute.d.ts +7 -0
  41. package/dist/queries/mute.js +16 -0
  42. package/dist/queries/profile.d.ts +3 -0
  43. package/dist/queries/profile.js +10 -0
  44. package/dist/queries/reactions.d.ts +4 -0
  45. package/dist/queries/reactions.js +19 -0
  46. package/dist/queries/simple.d.ts +5 -0
  47. package/dist/queries/simple.js +20 -0
  48. package/dist/queries/thread.d.ts +23 -0
  49. package/dist/queries/thread.js +65 -0
  50. package/dist/query-store/index.d.ts +35 -15
  51. package/dist/query-store/index.js +42 -57
  52. package/package.json +21 -2
  53. package/dist/helpers/symbols.d.ts +0 -17
  54. package/dist/helpers/symbols.js +0 -10
@@ -1,71 +1,56 @@
1
- import { kinds } from "nostr-tools";
2
- import stringify from "json-stringify-deterministic";
3
1
  import { stateful } from "../observable/stateful.js";
4
- import { getProfileContent } from "../helpers/profile.js";
5
- import { getEventUID, getReplaceableUID, isReplaceable } from "../helpers/event.js";
6
- import { getInboxes, getOutboxes } from "../helpers/mailboxes.js";
7
2
  import { LRU } from "../utils/lru.js";
3
+ import * as Queries from "../queries/index.js";
8
4
  export class QueryStore {
5
+ static Queries = Queries;
9
6
  store;
10
7
  constructor(store) {
11
8
  this.store = store;
12
9
  }
13
- singleEvents = new LRU();
14
- getEvent(id) {
15
- if (!this.singleEvents.has(id)) {
16
- const observable = stateful(this.store.single(id));
17
- this.singleEvents.set(id, observable);
18
- }
19
- return this.singleEvents.get(id);
10
+ queries = new LRU();
11
+ /** 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 = stateful(query.run(this.store, this));
18
+ this.queries.set(key, observable);
19
+ return observable;
20
+ }
21
+ return this.queries.get(key);
22
+ };
20
23
  }
21
- getReplaceable(kind, pubkey, d) {
22
- return this.getEvent(getReplaceableUID(kind, pubkey, d));
24
+ /** Returns a single event */
25
+ event(id) {
26
+ return this.runQuery(Queries.SingleEventQuery)(id);
23
27
  }
24
- timelines = new LRU();
25
- getTimeline(filters) {
26
- const key = stringify(filters);
27
- if (!this.singleEvents.has(key)) {
28
- const observable = stateful(this.store.timeline(filters));
29
- this.timelines.set(key, observable);
30
- }
31
- return this.timelines.get(key);
28
+ /** Returns the latest version of a replaceable event */
29
+ replaceable(kind, pubkey, d) {
30
+ return this.runQuery(Queries.ReplaceableQuery)(kind, pubkey, d);
32
31
  }
33
- profiles = new LRU();
34
- getProfile(pubkey) {
35
- if (!this.profiles.has(pubkey)) {
36
- const observable = stateful(this.getReplaceable(kinds.Metadata, pubkey).map((event) => event && getProfileContent(event)));
37
- this.profiles.set(pubkey, observable);
38
- }
39
- return this.profiles.get(pubkey);
32
+ /** Returns an array of events that match the filter */
33
+ timeline(filters) {
34
+ return this.runQuery(Queries.TimelineQuery)(filters);
40
35
  }
41
- reactions = new LRU();
42
- getReactions(event) {
43
- const uid = getEventUID(event);
44
- if (!this.reactions.has(uid)) {
45
- const observable = this.getTimeline(isReplaceable(event.kind)
46
- ? [
47
- { kinds: [kinds.Reaction], "#e": [event.id] },
48
- { kinds: [kinds.Reaction], "#a": [uid] },
49
- ]
50
- : [
51
- {
52
- kinds: [kinds.Reaction],
53
- "#e": [event.id],
54
- },
55
- ]);
56
- this.reactions.set(uid, observable);
57
- }
58
- return this.reactions.get(uid);
36
+ /** Returns the parsed profile (0) for a pubkey */
37
+ profile(pubkey) {
38
+ return this.runQuery(Queries.ProfileQuery)(pubkey);
59
39
  }
60
- mailboxes = new LRU();
61
- getMailboxes(pubkey) {
62
- if (!this.mailboxes.has(pubkey)) {
63
- const observable = stateful(this.getReplaceable(kinds.RelayList, pubkey).map((event) => event && {
64
- inboxes: getInboxes(event),
65
- outboxes: getOutboxes(event),
66
- }));
67
- this.mailboxes.set(pubkey, observable);
68
- }
69
- return this.mailboxes.get(pubkey);
40
+ /** Returns all reactions for an event (supports replaceable events) */
41
+ reactions(event) {
42
+ return this.runQuery(Queries.ReactionsQuery)(event);
43
+ }
44
+ /** Returns the parsed relay list (10002) for the pubkey */
45
+ mailboxes(pubkey) {
46
+ return this.runQuery(Queries.MailboxesQuery)(pubkey);
47
+ }
48
+ /** Returns the parsed mute list for the pubkey */
49
+ mute(pubkey) {
50
+ return this.runQuery(Queries.UserMuteQuery)(pubkey);
51
+ }
52
+ thread(root) {
53
+ return this.runQuery(Queries.ThreadQuery)(root);
70
54
  }
71
55
  }
56
+ export { Queries };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-core",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -33,6 +33,10 @@
33
33
  "./event-store": {
34
34
  "import": "./dist/event-store/index.js",
35
35
  "types": "./dist/event-store/index.d.ts"
36
+ },
37
+ "./queries": {
38
+ "import": "./dist/queries/index.js",
39
+ "types": "./dist/queries/index.d.ts"
36
40
  }
37
41
  },
38
42
  "dependencies": {
@@ -44,11 +48,26 @@
44
48
  "zen-push": "^0.3.1"
45
49
  },
46
50
  "devDependencies": {
51
+ "@jest/globals": "^29.7.0",
47
52
  "@types/debug": "^4.1.12",
53
+ "@types/jest": "^29.5.13",
48
54
  "@types/zen-observable": "^0.8.7",
55
+ "jest": "^29.7.0",
56
+ "jest-extended": "^4.0.2",
49
57
  "zen-observable": "^0.10.0"
50
58
  },
59
+ "jest": {
60
+ "roots": [
61
+ "dist"
62
+ ],
63
+ "setupFilesAfterEnv": [
64
+ "jest-extended/all"
65
+ ]
66
+ },
51
67
  "scripts": {
52
- "build": "tsc"
68
+ "build": "tsc",
69
+ "watch:build": "tsc --watch > /dev/null",
70
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
71
+ "watch:test": "(trap 'kill 0' SIGINT; pnpm run build -w > /dev/null & pnpm run test --watch)"
53
72
  }
54
73
  }
@@ -1,17 +0,0 @@
1
- import { ProfileContent as TProfileContent } from "./profile.js";
2
- export declare const EventUID: unique symbol;
3
- export declare const EventIndexableTags: unique symbol;
4
- export declare const MailboxesInboxes: unique symbol;
5
- export declare const MailboxesOutboxes: unique symbol;
6
- export declare const ProfileContent: unique symbol;
7
- export declare const FromRelays: unique symbol;
8
- declare module "nostr-tools" {
9
- interface Event {
10
- [EventUID]?: string;
11
- [MailboxesInboxes]?: Set<string>;
12
- [MailboxesOutboxes]?: Set<string>;
13
- [ProfileContent]?: TProfileContent | Error;
14
- [EventIndexableTags]?: Set<string>;
15
- [FromRelays]?: Set<string>;
16
- }
17
- }
@@ -1,10 +0,0 @@
1
- // event
2
- export const EventUID = Symbol.for("event-uid");
3
- export const EventIndexableTags = Symbol.for("indexable-tags");
4
- // mailboxes
5
- export const MailboxesInboxes = Symbol.for("mailboxes-inboxes");
6
- export const MailboxesOutboxes = Symbol.for("mailboxes-outboxes");
7
- // profile
8
- export const ProfileContent = Symbol.for("profile-content");
9
- // event relays
10
- export const FromRelays = Symbol.for("from-relays");