Files
zpan/server/entry-lambda.ts
T
saltbo 53ca110218 feat(about): split runtime into runtime engine + deployment platform
Flatten the instance `runtime` object into two fields: `runtime` (the JS engine,
node | workerd) and `platform` (the deployment host). The About page shows each
as its own row with friendly labels (e.g. "workerd" + "Cloudflare Workers",
"Node.js" + "Docker").

- Detect the platform from the entry file (entry === target): each serverless
  entry declares it; entry-node sniffs Cloud Run (K_SERVICE) / Docker
  (ZPAN_RUNTIME, set in the Dockerfile) / bare node. Cloudflare is detected from
  the D1 binding.
- Decouple the cloud payload: zpan-cloud-sdk fixes runtime { provider, target },
  so CloudInstanceInfo keeps that shape and buildCloudInstanceInfo maps to it;
  buildInstanceInfo serves the richer flat shape to the About API.
- Migrate PostHog instance telemetry to the runtime/platform shape and merge the
  duplicate runtimeInfo in licensing-admin into the shared one.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 14:56:29 -04:00

55 lines
1.8 KiB
TypeScript

import { existsSync, readFileSync } from 'node:fs'
import { extname, join } from 'node:path'
import { Hono } from 'hono'
import { handle } from 'hono/aws-lambda'
import { createBootstrap } from './bootstrap'
import { createLibsqlPlatform } from './platform/libsql'
import { setDeployPlatform } from './runtime-platform'
setDeployPlatform('aws-lambda')
const MIME: Record<string, string> = {
'.html': 'text/html; charset=utf-8',
'.js': 'application/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.svg': 'image/svg+xml',
'.ico': 'image/x-icon',
'.woff': 'font/woff',
'.woff2': 'font/woff2',
'.webp': 'image/webp',
}
// Initialized once per Lambda container; reused across warm invocations.
let cachedHandler: ReturnType<typeof handle> | undefined
async function init(): Promise<ReturnType<typeof handle>> {
if (cachedHandler) return cachedHandler
const platform = await createLibsqlPlatform({
TURSO_DATABASE_URL: process.env.TURSO_DATABASE_URL!,
TURSO_AUTH_TOKEN: process.env.TURSO_AUTH_TOKEN,
})
const app = await createBootstrap(platform)
const server = new Hono()
server.route('/', app)
server.get('/*', (c) => {
const filePath = join('./dist', c.req.path === '/' ? 'index.html' : c.req.path)
if (existsSync(filePath)) {
const content = readFileSync(filePath)
const mime = MIME[extname(filePath)] ?? 'application/octet-stream'
return c.body(content, 200, { 'Content-Type': mime })
}
return c.html(readFileSync('./dist/index.html', 'utf-8'))
})
cachedHandler = handle(server)
return cachedHandler
}
// biome-ignore lint/suspicious/noExplicitAny: Lambda event/context types vary by invocation model
export const handler = async (event: any, context: any) => (await init())(event, context)