-
Notifications
You must be signed in to change notification settings - Fork 0
/
deno_feeder.ts
76 lines (66 loc) · 2.12 KB
/
deno_feeder.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
import type { Feeder } from "./feeder.ts";
import type { FeedEntry } from "./shared.ts";
import { fetchFeed } from "./shared.ts";
export class DenoFeeder implements Feeder {
public constructor(
private readonly kv: Deno.Kv,
private readonly kvKeyPrefix: Deno.KvKey = [],
) {}
public async cron(
url: string,
name: string,
schedule: string | Deno.CronSchedule,
handler: (entries: FeedEntry[]) => void | Promise<void>,
) {
await Deno.cron(
name,
schedule,
async () => {
const feed = await fetchFeed(url);
const entries = await this.ingest(feed.entries, name);
await handler(entries);
},
);
}
public async ingest(
entries: FeedEntry[],
name?: string,
): Promise<FeedEntry[]> {
if (entries.length === 0) {
return [];
}
// Prevent conflicts by adding cron job name to the key.
const previousPublishedDateKey = [];
previousPublishedDateKey.push(...this.kvKeyPrefix);
if (name !== undefined) {
previousPublishedDateKey.push(name);
}
previousPublishedDateKey.push("publishedDate");
// Find the previous published date.
const previousPublishedDateResult = await this.kv.get<number>(
previousPublishedDateKey,
);
const previousPublishedDate = previousPublishedDateResult?.value ?? 0;
// Find the next published date while filtering out old entries.
let nextPublishedDate = previousPublishedDate;
const newEntries = entries.filter((entry) => {
const publishedDate = entry.published?.getTime() ?? 0;
if (publishedDate > previousPublishedDate) {
if (publishedDate > nextPublishedDate) {
nextPublishedDate = publishedDate;
}
return true;
}
return false;
});
// Persist the published date.
await this.kv.atomic()
.check(previousPublishedDateResult)
.set(previousPublishedDateKey, nextPublishedDate)
.commit();
// Return new entries sorted by published date in ascending order.
return newEntries.toSorted((a, b) =>
(a.published?.getTime() ?? 0) - (b.published?.getTime() ?? 0)
);
}
}