diff --git a/package.json b/package.json index 896b2d1..c4ff91f 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "react": "^19.0.0", "react-dom": "^19.0.0", "swr": "^2.3.3", + "temporal-polyfill": "^0.3.0", "uuid": "^11.1.0", "valibot": "^1.1.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 400f85d..3bef106 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ importers: swr: specifier: ^2.3.3 version: 2.3.5(react@19.1.1) + temporal-polyfill: + specifier: ^0.3.0 + version: 0.3.0 uuid: specifier: ^11.1.0 version: 11.1.0 @@ -803,6 +806,12 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + temporal-polyfill@0.3.0: + resolution: {integrity: sha512-qNsTkX9K8hi+FHDfHmf22e/OGuXmfBm9RqNismxBrnSmZVJKegQ+HYYXT+R7Ha8F/YSm2Y34vmzD4cxMu2u95g==} + + temporal-spec@0.3.0: + resolution: {integrity: sha512-n+noVpIqz4hYgFSMOSiINNOUOMFtV5cZQNCmmszA6GiVFVRt3G7AqVyhXjhCSmowvQn+NsGn+jMDMKJYHd3bSQ==} + tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} @@ -1769,6 +1778,12 @@ snapshots: symbol-tree@3.2.4: {} + temporal-polyfill@0.3.0: + dependencies: + temporal-spec: 0.3.0 + + temporal-spec@0.3.0: {} + tldts-core@6.1.86: {} tldts@6.1.86: diff --git a/src/app/List.tsx b/src/app/List.tsx index 3db41d0..36fd430 100644 --- a/src/app/List.tsx +++ b/src/app/List.tsx @@ -10,6 +10,7 @@ import { Section } from "@colonydb/anthill/Section"; import { Stack } from "@colonydb/anthill/Stack"; import { type ReactNode, useEffect, useState } from "react"; import useSWR from "swr/immutable"; +import { Temporal } from "temporal-polyfill"; import type { ListConfig, ListResult } from "."; type Props = { @@ -68,7 +69,20 @@ const List = ({ headingLevel={2} spacing="00" title={ -
+
+ Updated:{" "} + {Temporal.Instant.from(data?.fetchedAt).toLocaleString(undefined, { + timeStyle: "long", + dateStyle: "medium", + })} + + ) : null + } + > {name} diff --git a/src/app/api/route.ts b/src/app/api/route.ts index c96197e..e92a320 100644 --- a/src/app/api/route.ts +++ b/src/app/api/route.ts @@ -1,4 +1,5 @@ import { JSDOM, VirtualConsole } from "jsdom"; +import { toTemporalInstant } from "temporal-polyfill"; import type { ListResult } from ".."; export const GET = async (request: Request) => { @@ -27,6 +28,10 @@ export const GET = async (request: Request) => { if (response.ok === false) throw Error("Failed to fetch URL"); + const dateHeader = response.headers.get("date"); + + const instant = toTemporalInstant.apply(dateHeader ? new Date(dateHeader) : new Date(Date.now())); + const html = await response.text(); const dom = await createDOM(html, url); @@ -38,13 +43,14 @@ export const GET = async (request: Request) => { const items = selectAll(dom.window.document, itemSelector); const result: ListResult = { - items: [], debug: { firstLink: undefined, firstTitle: undefined, itemsAfterFilter: 0, itemsFound: items.length, }, + fetchedAt: instant.toString(), + items: [], }; for (const item of items ?? []) { diff --git a/src/app/index.ts b/src/app/index.ts index 6e96f84..98c60fb 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -10,11 +10,12 @@ export type ListConfig = { }; export type ListResult = { - items: Array<{ title: string; url: string | undefined }>; debug: { itemsFound: number; itemsAfterFilter: number; firstTitle: string | undefined; firstLink: string | undefined; }; + fetchedAt: string; + items: Array<{ title: string; url: string | undefined }>; };