forked from adamritter/nostr-relaypool-ts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
merge-similar-filters.ts
80 lines (78 loc) · 2.26 KB
/
merge-similar-filters.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import {stringify} from "safe-stable-stringify";
import type {Filter} from "nostr-tools";
function indexForFilter(filter: Filter, key: string): string {
let new_filter = {...filter};
// @ts-ignore
delete new_filter[key];
return key + stringify(new_filter);
}
export function mergeSimilarAndRemoveEmptyFilters(filters: Filter[]): Filter[] {
let r = [];
let indexByFilter = new Map<string, number>();
let sets = [];
for (let filter of filters) {
let added = false;
for (let key in filter) {
if (
// @ts-ignore
filter[key] &&
(["ids", "authors", "kinds"].includes(key) || key.startsWith("#"))
) {
// @ts-ignore
if (filter[key].length === 0) {
added = true;
break;
}
let index_by = indexForFilter(filter, key);
let index = indexByFilter.get(index_by);
if (index !== undefined) {
// @ts-ignore
let extendedFilter = r[index];
// remove all other groupings for r[index]
for (let key2 in extendedFilter) {
if (key2 !== key) {
let index_by2 = indexForFilter(extendedFilter, key2);
indexByFilter.delete(index_by2);
}
}
// // @ts-ignore
// if (!r[index][key]?.includes(filter[key])) {
// // @ts-ignore
// r[index][key].push(filter[key]);
// }
if (r[index][key] instanceof Set) {
// @ts-ignore
for (let v of filter[key]) {
// @ts-ignore
r[index][key].add(v);
}
} else {
// @ts-ignore
r[index][key] = new Set(r[index][key].concat(filter[key]));
sets.push([index, key]);
}
added = true;
break;
}
}
}
if (!added) {
for (let key in filter) {
if (
// @ts-ignore
filter[key] &&
(["ids", "authors", "kinds"].includes(key) || key.startsWith("#"))
) {
let index_by = indexForFilter(filter, key);
indexByFilter.set(index_by, r.length);
}
}
r.push({...filter});
}
}
for (let [index, key] of sets) {
// @ts-ignore
r[index][key] = Array.from(r[index][key]);
}
return r;
}