馃搨馃寠 An event stream of ATProto blobs
blobstream.zio.blue
atproto
deno
jetstream
1export default class SubscribeFilters {
2 collections?: string[];
3 dids?: string[];
4 mimeTypes?: string[];
5 pdses?: string[];
6
7 constructor(
8 collections?: string[] | undefined,
9 dids?: string[] | undefined,
10 mimeTypes?: string[] | undefined,
11 pdses?: string[] | undefined
12 ) {
13 this.collections = collections && collections.length
14 ? Array.from(new Set(collections))
15 : undefined;
16 this.dids = dids && dids.length
17 ? Array.from(new Set(dids))
18 : undefined;
19 this.mimeTypes = mimeTypes && mimeTypes.length
20 ? Array.from(new Set(mimeTypes))
21 : undefined;
22 this.pdses = pdses && pdses.length
23 ? Array.from(new Set(pdses))
24 : undefined;
25 }
26
27 private static splitParamValues(values: string[]): string[] {
28 return values
29 .flatMap((v) => v.split(","))
30 .map((s) => s.trim())
31 .filter(Boolean);
32 }
33
34 static fromSearchParams(params: URLSearchParams): SubscribeFilters {
35 const collections = SubscribeFilters.splitParamValues(params.getAll("wantedCollections"));
36 const dids = SubscribeFilters.splitParamValues(params.getAll("wantedDids"));
37 const mimeTypes = SubscribeFilters.splitParamValues(params.getAll("wantedMimeTypes"));
38 const pdses = SubscribeFilters.splitParamValues(params.getAll("wantedPdses"))
39 .map(p => `https://${p.replace(/^\/+/, '')}`);
40 return new SubscribeFilters(collections, dids, mimeTypes, pdses);
41 }
42
43 matches(data: any): boolean {
44 const col = data?.source?.collection;
45 const did = data?.source?.did;
46 const mtype = data?.blob?.mimeType;
47 const pds = data?.source?.pds;
48
49 const matchesCollection = !this.collections ||
50 (col !== undefined && this.collections.includes(col));
51 const matchesDid = !this.dids ||
52 (did !== undefined && this.dids.includes(did));
53 const matchesMimeType = !this.mimeTypes ||
54 (mtype !== undefined && this.mimeTypes.includes(mtype));
55 const matchesPds = !this.pdses ||
56 (pds !== undefined && this.pdses.includes(pds));
57
58 return matchesCollection && matchesDid && matchesMimeType && matchesPds;
59 }
60
61 toString(): string {
62 const parts: string[] = [];
63 if (this.collections) parts.push(`collection=${this.collections.join(",")}`);
64 if (this.dids) parts.push(`did=${this.dids.join(",")}`);
65 if (this.mimeTypes) parts.push(`mimeType=${this.mimeTypes.join(",")}`);
66 if (this.pdses) parts.push(`pds=${this.pdses.join(",")}`)
67 return parts.length ? parts.join(", ") : "any";
68 }
69}