From e2b1baa45f3d21b6c30bb3853f89cc0aadd961ef Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Sat, 31 Oct 2026 08:45:07 +0000 Subject: [PATCH] Remove the duplicate Pit network footer --- src/html.ts | 2 -- src/pit-footer.ts | 39 --------------------------------------- src/server.ts | 2 -- test/pit-footer.test.ts | 24 ++++++------------------ test/ring-footer.test.ts | 5 +++-- 5 files changed, 9 insertions(+), 63 deletions(-) delete mode 100644 src/pit-footer.ts diff --git a/src/html.ts b/src/html.ts index 2284e6c..465c42e 100644 --- a/src/html.ts +++ b/src/html.ts @@ -5,7 +5,6 @@ import { createHash } from 'node:crypto' import { readFileSync } from 'node:fs' import type { Campaign, DepositRow, Site, User, Withdrawal } from './db.js' -import { pitFooter } from './pit-footer.js' import { RING_PLACEHOLDER } from './ring.js' import { ringFooter } from './ring-footer.js' import type { PublicEndpoint } from '@profullstack/webhooks' @@ -77,7 +76,6 @@ ${RING_PLACEHOLDER} ${o.body} ${ringFooter()} -${pitFooter()} ` } diff --git a/src/pit-footer.ts b/src/pit-footer.ts deleted file mode 100644 index 0916749..0000000 --- a/src/pit-footer.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** - * The pit.world global footer: one line (site · Search · Ring · Publish here) - * that pit.world serves as an HTML fragment for every site on the network. - * - * We read https://pit.world/snippets/footer.html?site= in the background - * (3 s timeout, again every hour) and print the last good copy as the last thing - * in , so a page never waits on pit.world. Until the first read, or if - * pit.world is down, it renders nothing. The fragment carries data-pit-footer, - * which tells the pit.world relay not to add a second copy. - */ -const SNIPPET = 'https://pit.world/snippets/footer.html' - -let cached = '' - -/** The last good footer fragment, or '' before the first read. */ -export function pitFooter(): string { - return cached -} - -/** Accept a fragment only if it looks like the footer; anything else is ignored. */ -export function setPitFooter(html: unknown): boolean { - if (typeof html !== 'string' || !html.includes('data-pit-footer') || html.length > 64_000) return false - cached = html.trim() - return true -} - -/** Refresh from pit.world now and every `everyMs`. Failures keep the last good copy. */ -export function startPitFooterRefresh(site: string, fetchImpl: typeof fetch = fetch, everyMs = 60 * 60_000): () => void { - const url = `${SNIPPET}?site=${encodeURIComponent(site)}` - const refresh = () => - fetchImpl(url, { signal: AbortSignal.timeout(3000) }) - .then((r) => (r.ok ? r.text() : null)) - .then((html) => html && setPitFooter(html)) - .catch(() => {}) - refresh() - const timer = setInterval(refresh, everyMs) - timer.unref?.() - return () => clearInterval(timer) -} diff --git a/src/server.ts b/src/server.ts index 1088d7b..b2b2796 100644 --- a/src/server.ts +++ b/src/server.ts @@ -13,7 +13,6 @@ import { CoinPay } from '@profullstack/coinpay-onboard' import { Sealer, Store, type Campaign, type DepositRow, type Site, type User } from './db.js' import { adPage, advertisePage, depositPage, helpPage, homePage, installScript, inviteLandingPage, invitesPage, mePage, messagePage, pitchPage, publishPage, sitePage, SITE, type Ctx } from './html.js' import { ACCEPT_MESSAGES, Rewards, type RewardsConfig } from './rewards.js' -import { startPitFooterRefresh } from './pit-footer.js' import { RING_PLACEHOLDER, ringBar, startRingRefresh } from './ring.js' import { ringDescriptor, ringFooterScriptHashes, startRingFooterRefresh } from './ring-footer.js' import { AdNetwork, newApiKey, UserError, type Config } from './service.js' @@ -709,7 +708,6 @@ export function serve(options: { port?: number; hostname?: string } = {}) { }) const trustProxy = (env.ADNETWORK_TRUST_PROXY ?? '1') === '1' startRingRefresh() - startPitFooterRefresh('ad.network.pit.world') startRingFooterRefresh() net.startSweep() net.hooks.start() diff --git a/test/pit-footer.test.ts b/test/pit-footer.test.ts index 03e7e8d..cb529ce 100644 --- a/test/pit-footer.test.ts +++ b/test/pit-footer.test.ts @@ -1,22 +1,10 @@ import { expect, it } from 'bun:test' -import { pitFooter, setPitFooter, startPitFooterRefresh } from "../src/pit-footer.ts" -import { homePage } from "../src/html.ts" +import { homePage } from '../src/html.ts' -it('pit.world footer: nothing until read, then the last thing in , kept on failure', async () => { - expect(setPitFooter('

not the footer

')).toBe(false) - expect(pitFooter()).toBe('') - const frag = '' - const stop = startPitFooterRefresh('ad.network', (async (url: string) => { - expect(url).toBe('https://pit.world/snippets/footer.html?site=ad.network') - return new Response(frag) - }) as unknown as typeof fetch) - await new Promise((r) => setTimeout(r, 10)) - stop() +it('the universal footer is the only footer on ad.network pages', () => { const html = homePage({ user: null, csrf: 'x' }) - expect(html.match(/data-pit-footer/g)?.length).toBe(1) - expect(html).toMatch(/<\/footer>[\s\S]*data-pit-footer[\s\S]*<\/nav>\s*<\/body>/) - const stop2 = startPitFooterRefresh('ad.network', (async () => { throw new Error('down') }) as unknown as typeof fetch) - await new Promise((r) => setTimeout(r, 10)) - stop2() - expect(pitFooter()).toContain('data-pit-footer') + expect(html.match(/