{"_id":"@ailnaf/uai","name":"@ailnaf/uai","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@ailnaf/uai","publishConfig":{"access":"public"},"version":"0.1.0","description":"Minimal Bun-native HTTP framework. Express-style routing, WebSocket, GraphQL.","module":"index.ts","type":"module","repository":{"type":"git","url":"git+https://github.com/anomalyco/uai.git"},"license":"MIT","devDependencies":{"@types/bun":"latest","autocannon":"^8.0.0","express":"^5.2.1","fastify":"^5.8.5","hono":"^4.12.18"},"peerDependencies":{"typescript":"^5"},"dependencies":{"@graphql-tools/schema":"^10.0.33","graphql":"^16.14.0"},"_id":"@ailnaf/uai@0.1.0","gitHead":"49f899c346c6eeb8b5db8346b68e1c8e7de12d8c","bugs":{"url":"https://github.com/anomalyco/uai/issues"},"homepage":"https://github.com/anomalyco/uai#readme","_nodeVersion":"24.3.0","_npmVersion":"11.4.2","dist":{"integrity":"sha512-nUvWCpfikxLVMMz1DjtFLffdVDrx1yQCkcti3XfuPkqZ/Z8FpSdPQ706DgeZTvsAFgmp19IET7IF+J3nzede7w==","shasum":"0200384143b7f9bb9eea73d69c252a2c9a91a6da","tarball":"https://registry.npmjs.org/@ailnaf/uai/-/uai-0.1.0.tgz","fileCount":9,"unpackedSize":29628,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD/yElKyyL8gSWeqHHN2F1q6JZmBd6moqCYmPnkzLHrTwIhAMt1BV9gIAggxXPAQw2OmnMFBjQ4gfnIWPvTl7eTWIlb"}]},"_npmUser":{"name":"ailnaf","email":"3093932086@qq.com"},"directories":{},"maintainers":[{"name":"ailnaf","email":"3093932086@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/uai_0.1.0_1778671393798_0.7409183196521967"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-13T11:23:13.720Z","0.1.0":"2026-05-13T11:23:13.984Z","modified":"2026-05-13T11:23:14.280Z"},"maintainers":[{"name":"ailnaf","email":"3093932086@qq.com"}],"description":"Minimal Bun-native HTTP framework. Express-style routing, WebSocket, GraphQL.","homepage":"https://github.com/anomalyco/uai#readme","repository":{"type":"git","url":"git+https://github.com/anomalyco/uai.git"},"bugs":{"url":"https://github.com/anomalyco/uai/issues"},"license":"MIT","readme":"# uai\n\nMinimal [Bun](https://bun.sh)-native HTTP framework. Express-style routing,\nWebSocket, and GraphQL — zero abstractions, no polyfills.\n\n```ts\nimport { Router, cors, logger } from 'fuai'\n\nconst app = new Router()\n  .use(cors({ origin: '*' }))\n  .use(logger())\n  .get('/users/:id', (req, ctx) => Response.json({ id: ctx.params.id! }))\n  .post('/users', authMiddleware, async (req, ctx) => {\n    const body = await req.json()\n    return Response.json(body, { status: 201 })\n  })\n  .ws('/chat', { open(ws) { ws.send('connected!') } })\n  .graphql('/graphql', { schema, resolvers })\n\nBun.serve({ fetch: app.fetch(), websocket: app.websocket() })\n```\n\n## Features\n\n- **Express-style** — `.get(path, ...middlewares, handler)`, `.use(mw)`, `.use('/path', router)`\n- **WebSocket** — built-in, no `ws` package needed\n- **GraphQL** — built-in via `.graphql()` with optional GraphiQL\n- **Type-safe** — `defineMiddleware<T>()` for ctx extension\n- **Fast** — trie-based routing, ~57k req/s on a simple route\n- **Zero deps** — only `graphql` and `@graphql-tools/schema` (optional, only for `.graphql()`)\n\n## Quick Start\n\n```ts\nimport { Router } from 'uai'\n\nconst router = new Router()\n  .get('/', () => Response.json({ hello: 'world' }))\n\nconst server = Bun.serve({ fetch: router.fetch() })\n```\n\n## API\n\n### Route Methods\n\n```ts\n.get(path, ...middlewares, handler)\n.post(path, ...middlewares, handler)\n.put(path, ...middlewares, handler)\n.delete(path, ...middlewares, handler)\n.patch(path, ...middlewares, handler)\n.head(path, ...middlewares, handler)\n.options(path, ...middlewares, handler)\n.all(path, ...middlewares, handler)     // matches any method\n.route(method, path, ...middlewares, handler)\n```\n\n### Middleware\n\n```ts\n// Global\n.use((req, ctx, next) => {\n  console.log(`${req.method} ${new URL(req.url).pathname}`)\n  return next(req, ctx)\n})\n\n// Path-scoped\n.use('/api', authMiddleware)\n\n// Sub-router\n.use('/api', apiRouter)\n\n// Per-route\n.get('/admin', authMiddleware, adminHandler)\n```\n\n### Error Handling\n\n```ts\n.onError((err, req, ctx) =>\n  Response.json({ error: err.message }, { status: 500 }),\n)\n.onWsError((err, ws, ctx) => console.error('WS error:', err))\n```\n\n### Type-safe Context\n\n```ts\nimport { defineMiddleware, defineRoute } from 'uai'\n\nconst auth = defineMiddleware<{ user: { name: string } }>((req, ctx, next) => {\n  ctx.user = { name: req.headers.get('Authorization') ?? 'guest' }\n  return next(req, ctx)\n})\n\nconst handler = defineRoute<{ user: { name: string } }>((req, ctx) =>\n  Response.json({ name: ctx.user.name }),\n)\n\nrouter.get('/profile', auth, handler)\n```\n\nOr augment the global context:\n\n```ts\ndeclare module 'uai' {\n  interface Context {\n    user?: { name: string }\n  }\n}\n```\n\n### WebSocket\n\n```ts\n.ws('/ws', { \n  open(ws, ctx) { ws.send('connected') },\n  message(ws, ctx, data) { ws.send(`echo: ${data}`) },\n  close(ws, ctx) { console.log('disconnected') },\n})\n```\n\n### GraphQL\n\n```ts\n.graphql('/graphql', {\n  schema: `type Query { hello: String }`,\n  resolvers: { Query: { hello: () => 'world' } },\n  graphiql: true,  // enables GraphiQL UI at GET /graphql\n})\n```\n\n## Benchmarks\n\n`GET /hello`, 100 concurrent connections:\n\n| Framework | Req/s |\n|-----------|-------|\n| **UAI**  | **57,572** |\n| Hono     | 14,128 |\n| Express  | 13,162 |\n| Fastify  | 13,735 |\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-89bcec87c1c8160b5ee858f47ebcee76"}