← Public packages
@kentcdodds/package-app-kit
Design tokens, PWA install/update, About/version, cache helpers, and optional realtime notes sync for Kody package apps.
app/router.ts
65 lines · 2.2 KB · TypeScriptimport { packageContext } from 'kody:runtime'
import { createRouter } from 'remix/router'
import { formData } from 'remix/middleware/form-data'
import { requestId } from './middleware/request-id.ts'
import { routes } from './routes.ts'
import home from './controllers/home.tsx'
import about from './controllers/about.tsx'
import notes from './controllers/notes.tsx'
import manifest from './controllers/manifest.ts'
import version from './controllers/version.ts'
import { icon192, icon512 } from './controllers/icons.ts'
import { logoBust, logoFull } from './controllers/brand.ts'
import { serverCachified } from '../src/server-cache.ts'
import { handleRealtimeEvent as kitHandleRealtimeEvent } from '../src/realtime.ts'
const router = createRouter({ middleware: [requestId(), formData()] })
router.map(routes.home, home)
router.map(routes.about, about)
router.map(routes.notes, notes)
router.map(routes.manifest, manifest)
router.map(routes.versionApi, version)
router.map(routes.icon192, icon192)
router.map(routes.icon512, icon512)
router.map(routes.logoBust, logoBust)
router.map(routes.logoFull, logoFull)
async function demoHealth() {
let fresh = false
const value = await serverCachified({
key: 'demo-health',
ttl: 15_000,
getFreshValue: async () => {
fresh = true
return {
ok: true,
generatedAt: new Date().toISOString(),
cache: 'cachified+packageStorage',
}
},
})
return { ...value, fresh }
}
router.get(routes.health, async () => Response.json(await demoHealth()))
// Host strips the mount before forwarding. Remix route contracts that include
// appBasePath need the hosted pathname, so remount here.
function remountRequest(request: Request) {
const appBasePath = String(packageContext?.appBasePath ?? '').replace(/\/+$/, '')
if (!appBasePath) return request
const url = new URL(request.url)
url.pathname = url.pathname === '/' ? appBasePath : appBasePath + url.pathname
return new Request(url, request)
}
/** Package realtime hook — notes topic subscribe + ping/pong (see `./realtime`). */
export const handleRealtimeEvent = kitHandleRealtimeEvent
// Default-export { fetch } — do not export the router object (Worker env is not RequestInit).
export default {
fetch(request: Request) {
return router.fetch(remountRequest(request))
},
}