applesauce-core 0.0.0-next-20250213191824 → 0.0.0-next-20250213194606
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.
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { Observable } from "rxjs";
|
|
2
2
|
import { Filter, NostrEvent } from "nostr-tools";
|
|
3
3
|
import { EventStore } from "../event-store/event-store.js";
|
|
4
|
-
import { LRU } from "../helpers/lru.js";
|
|
5
4
|
import * as Queries from "../queries/index.js";
|
|
6
5
|
import { AddressPointer, EventPointer } from "nostr-tools/nip19";
|
|
7
6
|
export type Query<T extends unknown> = {
|
|
8
|
-
/**
|
|
9
|
-
* A unique key for this query. this is used to detect duplicate queries
|
|
10
|
-
*/
|
|
7
|
+
/** A unique key for this query. this is used to detect duplicate queries */
|
|
11
8
|
key: string;
|
|
12
|
-
/**
|
|
13
|
-
* The meat of the query, this should return an Observables that subscribes to the eventStore in some way
|
|
14
|
-
*/
|
|
9
|
+
/** The meat of the query, this should return an Observables that subscribes to the eventStore in some way */
|
|
15
10
|
run: (events: EventStore, store: QueryStore) => Observable<T>;
|
|
16
11
|
};
|
|
17
12
|
export type QueryConstructor<T extends unknown, Args extends Array<any>> = (...args: Args) => Query<T>;
|
|
@@ -19,18 +14,11 @@ export declare class QueryStore {
|
|
|
19
14
|
static Queries: typeof Queries;
|
|
20
15
|
store: EventStore;
|
|
21
16
|
constructor(store: EventStore);
|
|
22
|
-
queries:
|
|
23
|
-
observables: WeakMap<Query<any>, Observable<any>>;
|
|
17
|
+
queries: Map<QueryConstructor<any, any[]>, Map<string, Observable<any>>>;
|
|
24
18
|
/** Creates a cached query */
|
|
25
|
-
createQuery<T extends unknown, Args extends Array<any>>(queryConstructor:
|
|
26
|
-
key: string;
|
|
27
|
-
run: (events: EventStore, store: QueryStore) => Observable<T>;
|
|
28
|
-
}, ...args: Args): Observable<T | undefined>;
|
|
19
|
+
createQuery<T extends unknown, Args extends Array<any>>(queryConstructor: QueryConstructor<T, Args>, ...args: Args): Observable<T | undefined>;
|
|
29
20
|
/** Creates a query and waits for the next value */
|
|
30
|
-
executeQuery<T extends unknown, Args extends Array<any>>(queryConstructor:
|
|
31
|
-
key: string;
|
|
32
|
-
run: (events: EventStore, store: QueryStore) => Observable<T>;
|
|
33
|
-
}, ...args: Args): Promise<T>;
|
|
21
|
+
executeQuery<T extends unknown, Args extends Array<any>>(queryConstructor: QueryConstructor<T, Args>, ...args: Args): Promise<T>;
|
|
34
22
|
/** Creates a SingleEventQuery */
|
|
35
23
|
event(id: string): Observable<import("nostr-tools").Event | undefined>;
|
|
36
24
|
/** Creates a MultipleEventsQuery */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { filter, ReplaySubject, share, startWith, timer } from "rxjs";
|
|
2
|
-
import
|
|
1
|
+
import { filter, finalize, ReplaySubject, share, startWith, timer } from "rxjs";
|
|
2
|
+
import hash_sum from "hash-sum";
|
|
3
3
|
import * as Queries from "../queries/index.js";
|
|
4
4
|
import { getObservableValue } from "../observable/get-observable-value.js";
|
|
5
5
|
export class QueryStore {
|
|
@@ -10,24 +10,33 @@ export class QueryStore {
|
|
|
10
10
|
throw new Error("EventStore required");
|
|
11
11
|
this.store = store;
|
|
12
12
|
}
|
|
13
|
-
queries = new
|
|
14
|
-
observables = new WeakMap();
|
|
13
|
+
queries = new Map();
|
|
15
14
|
/** Creates a cached query */
|
|
16
15
|
createQuery(queryConstructor, ...args) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
query = tempQuery;
|
|
22
|
-
this.queries.set(key, tempQuery);
|
|
16
|
+
let observables = this.queries.get(queryConstructor);
|
|
17
|
+
if (!observables) {
|
|
18
|
+
observables = new Map();
|
|
19
|
+
this.queries.set(queryConstructor, observables);
|
|
23
20
|
}
|
|
24
|
-
|
|
21
|
+
const key = hash_sum(args);
|
|
22
|
+
let observable = observables.get(key);
|
|
25
23
|
if (!observable) {
|
|
26
|
-
const
|
|
24
|
+
const cleanup = () => {
|
|
25
|
+
if (observables.get(key) === observable)
|
|
26
|
+
observables.delete(key);
|
|
27
|
+
};
|
|
28
|
+
observable = queryConstructor(...args)
|
|
27
29
|
.run(this.store, this)
|
|
28
|
-
.pipe(
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
.pipe(
|
|
31
|
+
// always emit undefined so the observable is sync
|
|
32
|
+
startWith(undefined),
|
|
33
|
+
// remove the observable when its subscribed
|
|
34
|
+
finalize(cleanup),
|
|
35
|
+
// only create a single observable for all components
|
|
36
|
+
share({ connector: () => new ReplaySubject(1), resetOnComplete: () => timer(60_000) }));
|
|
37
|
+
// set debug fields
|
|
38
|
+
Reflect.set(observable, "queryArgs", args);
|
|
39
|
+
observables.set(key, observable);
|
|
31
40
|
}
|
|
32
41
|
return observable;
|
|
33
42
|
}
|