From 6040e3c2a5675e3ae3a89411e4bf6f4bdf1b104d Mon Sep 17 00:00:00 2001 From: "planetrenox@protonmail.com" Date: Mon, 19 Oct 2026 21:46:00 +0000 Subject: [PATCH] Add /api Pages Functions: now, now/{unit}, from, to Co-Authored-By: Claude Opus 5.5 --- .gitignore | 2 ++ README.md | 22 ++++++++++++++++++++-- functions/api/[[path]].js | 36 ++++++++++++++++++++++++++++++++++++ index.html | 2 +- package-lock.json | 19 +++++++++++++++++++ package.json | 11 +++++++++++ 6 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 .gitignore create mode 100644 functions/api/[[path]].js create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1048609 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +.wrangler diff --git a/README.md b/README.md index 75a8f9d..f8be443 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,28 @@ Live **PRT (Planet Renox Time)**, milliseconds since `1998-03-14T03:00:00.000Z`, Also on the page: PRT day/week progress, upcoming round-number milestones, next equinox/solstice, a subsolar marker with hover readout (lat/lon, sun altitude, solar time), and a Date ⇄ PRT converter. -Static site, no build step. `ortus` loads from jsDelivr via an import map. Land dots come from Natural Earth 50m land, rasterized to a half-degree RLE mask in `land.js`. +## API + +Cloudflare Pages Functions in `functions/api/`, built on `ortus`. JSON responses carry every unit plus `unixMs` and `iso`; CORS is open. + +| | | +|---|---| +| `GET /api` | Epoch, units, endpoint list | +| `GET /api/now` | Current PRT in every unit | +| `GET /api/now/{unit}` | Current PRT in one unit, plain text | +| `GET /api/from/{iso\|unixMs}` | PRT at a date, e.g. `/api/from/2010-06-01` | +| `GET /api/to/{n}/{unit?}` | Date at a PRT value, e.g. `/api/to/11111/d` | ```sh -python3 -m http.server # then open http://localhost:8000 +curl https://time.planetrenox.com/api/now/d # 10446 +``` + +## Site + +Static page, no build step. `ortus` loads from jsDelivr via an import map. Land dots come from Natural Earth 50m land, rasterized to a half-degree RLE mask in `land.js`. + +```sh +npm i && npm run dev # wrangler pages dev, serves the site and /api ``` Cloudflare Pages: no build command, output directory `/`. diff --git a/functions/api/[[path]].js b/functions/api/[[path]].js new file mode 100644 index 0000000..9f5054d --- /dev/null +++ b/functions/api/[[path]].js @@ -0,0 +1,36 @@ +import { PRT } from 'ortus' + +const U = ['ms', 's', 'm', 'h', 'd', 'w'] +const CORS = { 'access-control-allow-origin': '*' } +const LIVE = { ...CORS, 'cache-control': 'no-store' } +const FIXED = { ...CORS, 'cache-control': 'public, max-age=31536000, immutable' } +const json = (o, headers = LIVE, status = 200) => Response.json(o, { status, headers }) +const at = t => ({ ...Object.fromEntries(U.map(u => [u, PRT.fromUnixMs(t, u)])), unixMs: t, iso: new Date(t).toISOString() }) +const HELP = { + name: 'PRT (Planet Renox Time)', + epoch: new Date(PRT.toUnixMs(0)).toISOString(), + units: U, + endpoints: { + '/api/now': 'current PRT in every unit', + '/api/now/{unit}': 'current PRT in one unit, plain text', + '/api/from/{iso|unixMs}': 'PRT at a date', + '/api/to/{n}/{unit?}': 'date at a PRT value, unit defaults to ms', + }, +} + +export const onRequestGet = ({ params: { path = [] } }) => { + const [a, b, c, d] = path + try { + if (a == 'now' && !c) { + const t = Date.now() + return b ? new Response(PRT.fromUnixMs(t, b) + '\n', { headers: { ...LIVE, 'content-type': 'text/plain' } }) : json(at(t)) + } + if (a == 'from' && b && !c) { + const t = new Date(/^-?\d+$/.test(b) ? +b : decodeURIComponent(b)) + return PRT.fromDate(t), json(at(+t), FIXED) + } + if (a == 'to' && b && !d) return json(at(PRT.toUnixMs(Number(b), c)), FIXED) + } catch (e) { return json({ error: e.message }, CORS, 400) } + return json(HELP, CORS, a ? 404 : 200) +} +export const onRequestHead = onRequestGet diff --git a/index.html b/index.html index 7da2437..6aea3d1 100644 --- a/index.html +++ b/index.html @@ -22,7 +22,7 @@
PRT - +
diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a0ed650 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,19 @@ +{ + "name": "time.planetrenox.com", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "time.planetrenox.com", + "dependencies": { + "ortus": "^0.1.3" + } + }, + "node_modules/ortus": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ortus/-/ortus-0.1.3.tgz", + "integrity": "sha512-sojVnSVzJ4hRpqA9JREqxLIAgxIaSMVpQQILWPpuWGLI9XJxsK75wUCzEPyo51vHGzYQVcs/ZZrdDyc7mCCrrw==", + "license": "0BSD" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..c1c39fa --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "time.planetrenox.com", + "private": true, + "type": "module", + "scripts": { + "dev": "wrangler pages dev ." + }, + "dependencies": { + "ortus": "^0.1.3" + } +}