diff options
Diffstat (limited to 'feed/service.js')
| -rw-r--r-- | feed/service.js | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/feed/service.js b/feed/service.js new file mode 100644 index 0000000..304b40f --- /dev/null +++ b/feed/service.js @@ -0,0 +1,29 @@ +import { SimplePool } from 'nostr-tools/pool'; +import { readFile, mkdir, writeFile, rename } from 'node:fs/promises'; +import { dirname } from 'node:path'; +import { buildSnapshot, createSnapshotCache, PUBLIC_FEED_RELAYS } from './cache.js'; + +export async function startFeedCache() { + const file = process.env.FEED_CACHE_FILE || new URL('../db/public-feed.json', import.meta.url).pathname; + let initial = null; + try { + const data = JSON.parse(await readFile(file, 'utf8')); + if (data.version === 1 && Number.isFinite(data.generatedAt) && Array.isArray(data.notes) && data.notes.length && Array.isArray(data.profiles)) initial = data; + } catch {} + // SimplePool verifies signatures and matches filters before accepting events. + const pool = new SimplePool(); + const cache = createSnapshotCache({ + initial, + build: () => buildSnapshot((filter) => pool.querySync(PUBLIC_FEED_RELAYS, filter, { maxWait: 4500 })), + save: async (data) => { + await mkdir(dirname(file), { recursive: true }); + await writeFile(file + '.tmp', JSON.stringify(data)); + await rename(file + '.tmp', file); + }, + onError: (e) => console.warn('[public feed]', e.message), + }); + cache.read(); // warm before the first visitor, reusing the persisted snapshot + const timer = setInterval(() => cache.read(), 15_000); + timer.unref(); + return cache; +} |
