weifuwu 0.19.8 → 0.19.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +63 -70
  2. package/cli/template/app.ts +3 -8
  3. package/cli/template/ui/{page.tsx → app/page.tsx} +2 -2
  4. package/cli/template/ui/components/Greeting.tsx +1 -1
  5. package/cli.ts +4 -11
  6. package/dist/auth.d.ts +8 -0
  7. package/dist/cli.js +5 -5
  8. package/dist/compile.d.ts +2 -0
  9. package/dist/cors.d.ts +10 -0
  10. package/dist/env.d.ts +2 -0
  11. package/dist/html-shell.d.ts +1 -0
  12. package/dist/index.d.ts +7 -10
  13. package/dist/index.js +823 -721
  14. package/dist/live.d.ts +4 -1
  15. package/dist/logger.d.ts +5 -0
  16. package/dist/rate-limit.d.ts +2 -2
  17. package/dist/router.d.ts +5 -3
  18. package/dist/ssr.d.ts +5 -1
  19. package/dist/stream.d.ts +0 -1
  20. package/dist/tailwind.d.ts +3 -1
  21. package/package.json +3 -3
  22. package/dist/agent/migrate.d.ts +0 -6
  23. package/dist/dist/agent/client.d.ts +0 -2
  24. package/dist/dist/agent/index.d.ts +0 -2
  25. package/dist/dist/agent/migrate.d.ts +0 -6
  26. package/dist/dist/agent/rest.d.ts +0 -13
  27. package/dist/dist/agent/run.d.ts +0 -17
  28. package/dist/dist/agent/types.d.ts +0 -51
  29. package/dist/dist/ai/workflow.d.ts +0 -14
  30. package/dist/dist/analytics.d.ts +0 -15
  31. package/dist/dist/client-locale.d.ts +0 -5
  32. package/dist/dist/client-pref.d.ts +0 -3
  33. package/dist/dist/client-state.d.ts +0 -22
  34. package/dist/dist/client-theme.d.ts +0 -7
  35. package/dist/dist/compress.d.ts +0 -6
  36. package/dist/dist/cookie.d.ts +0 -12
  37. package/dist/dist/deploy/config.d.ts +0 -2
  38. package/dist/dist/deploy/gateway.d.ts +0 -2
  39. package/dist/dist/deploy/index.d.ts +0 -4
  40. package/dist/dist/deploy/manager.d.ts +0 -16
  41. package/dist/dist/deploy/process.d.ts +0 -14
  42. package/dist/dist/deploy/types.d.ts +0 -62
  43. package/dist/dist/head.d.ts +0 -6
  44. package/dist/dist/helmet.d.ts +0 -18
  45. package/dist/dist/iii/client.d.ts +0 -2
  46. package/dist/dist/iii/index.d.ts +0 -4
  47. package/dist/dist/iii/register-worker.d.ts +0 -10
  48. package/dist/dist/iii/rest.d.ts +0 -3
  49. package/dist/dist/iii/stream.d.ts +0 -82
  50. package/dist/dist/iii/types.d.ts +0 -133
  51. package/dist/dist/iii/worker.d.ts +0 -2
  52. package/dist/dist/iii/ws.d.ts +0 -29
  53. package/dist/dist/index.js +0 -8180
  54. package/dist/dist/messager/agent.d.ts +0 -6
  55. package/dist/dist/messager/client.d.ts +0 -2
  56. package/dist/dist/messager/index.d.ts +0 -2
  57. package/dist/dist/messager/migrate.d.ts +0 -2
  58. package/dist/dist/messager/rest.d.ts +0 -15
  59. package/dist/dist/messager/types.d.ts +0 -56
  60. package/dist/dist/messager/ws.d.ts +0 -14
  61. package/dist/dist/preferences.d.ts +0 -14
  62. package/dist/dist/react.d.ts +0 -12
  63. package/dist/dist/react.js +0 -637
  64. package/dist/dist/request-id.d.ts +0 -6
  65. package/dist/dist/seo.d.ts +0 -39
  66. package/dist/dist/ssr/compile.d.ts +0 -2
  67. package/dist/dist/ssr/error-boundary.d.ts +0 -2
  68. package/dist/dist/ssr/index.d.ts +0 -7
  69. package/dist/dist/ssr/index.js +0 -933
  70. package/dist/dist/ssr/layout.d.ts +0 -2
  71. package/dist/dist/ssr/live.d.ts +0 -6
  72. package/dist/dist/ssr/not-found.d.ts +0 -2
  73. package/dist/dist/ssr/ssr.d.ts +0 -2
  74. package/dist/dist/ssr/stream.d.ts +0 -14
  75. package/dist/dist/ssr/tailwind.d.ts +0 -2
  76. package/dist/dist/tenant/client.d.ts +0 -2
  77. package/dist/dist/tenant/graphql.d.ts +0 -3
  78. package/dist/dist/tenant/index.d.ts +0 -2
  79. package/dist/dist/tenant/migrate.d.ts +0 -6
  80. package/dist/dist/tenant/rest.d.ts +0 -3
  81. package/dist/dist/tenant/schema.d.ts +0 -5
  82. package/dist/dist/tenant/types.d.ts +0 -48
  83. package/dist/dist/tenant/utils.d.ts +0 -10
  84. package/dist/dist/types.d.ts +0 -19
  85. package/dist/dist/use-flash-message.d.ts +0 -1
  86. package/dist/i18n.d.ts +0 -6
  87. package/dist/logdb/migrate.d.ts +0 -5
  88. package/dist/messager/migrate.d.ts +0 -2
  89. package/dist/middleware.d.ts +0 -21
  90. package/dist/opencode/migrate.d.ts +0 -2
  91. package/dist/postgres/migrate.d.ts +0 -3
  92. package/dist/postgres/table.d.ts +0 -4
  93. package/dist/root-layout.d.ts +0 -4
  94. package/dist/tenant/migrate.d.ts +0 -6
  95. package/dist/tsx-instance.d.ts +0 -43
  96. package/dist/tsx.d.ts +0 -8
  97. package/dist/user/migrate.d.ts +0 -6
  98. package/dist/workflow/engine.d.ts +0 -7
  99. package/dist/workflow/index.d.ts +0 -8
  100. package/dist/workflow/llm.d.ts +0 -10
  101. package/dist/workflow/nodes.d.ts +0 -10
  102. package/dist/workflow/reference.d.ts +0 -3
  103. package/dist/workflow/route.d.ts +0 -11
  104. package/dist/workflow/sse.d.ts +0 -2
  105. package/dist/workflow/tool.d.ts +0 -8
  106. package/dist/workflow/types.d.ts +0 -86
  107. /package/cli/template/ui/{app.css → app/globals.css} +0 -0
  108. /package/cli/template/ui/{layout.tsx → app/layout.tsx} +0 -0
  109. /package/opencode/ui/{app.css → app/globals.css} +0 -0
  110. /package/opencode/ui/{layout.tsx → app/layout.tsx} +0 -0
  111. /package/opencode/ui/{page.tsx → app/page.tsx} +0 -0
package/README.md CHANGED
@@ -15,11 +15,9 @@ serve((req, ctx) => new Response('Hello, World!'), { port: 3000 })
15
15
  ```
16
16
 
17
17
  ```ts
18
- import { serve, Router, preferences, ssr, rootLayout } from 'weifuwu'
18
+ import { serve, Router, ssr } from 'weifuwu'
19
19
  const app = new Router()
20
- app.use(preferences({ dir: './locales' }))
21
- app.use(rootLayout('./ui'))
22
- app.get('/', ssr('./ui/pages/home.tsx'))
20
+ app.use('/', ssr({ dir: './ui' }))
23
21
  serve(app.handler(), { port: 3000, websocket: app.websocketHandler() })
24
22
  ```
25
23
 
@@ -119,14 +117,14 @@ The `ctx` object accumulates properties as it passes through the middleware chai
119
117
  | `queue` | `queue()` | `Queue` | Job queue |
120
118
  | `prefs` | `preferences()` | `{ locale, theme }` | User preferences (locale, theme) |
121
119
  | `deploy` | `deploy()` | `{ appName? }` | Deploy gateway info |
122
- | `layoutStack` | `rootLayout()` / `layout()` | `LayoutEntry[]` | React layout component stack |
120
+ | `layoutStack` | `ssr()` internal | `LayoutEntry[]` | React layout component stack |
123
121
  | `loaderData` | User middleware | `Record<string, unknown>` | SSR data passed to client |
124
122
  | `user` | `auth()` / `user().middleware()` | `{ id?: string }` | Authenticated user |
125
123
  | `parsed` | `validate()` / `upload()` | `{ body, query, params, headers, files }` | Validated/parsed request data |
126
124
  | `t` | `preferences()` | `(key) => string` | Translation function |
127
125
  | `setPref` | `preferences()` | `(key, val) => Response` | Set preference cookie + redirect |
128
- | `compiledTailwindCss` | `tailwind()` | `string` | Compiled CSS content (internal) |
129
- | `tailwindCssUrl` | `tailwind()` | `string` | Compiled CSS route URL (internal) |
126
+ | `compiledTailwindCss` | `ssr()` internal | `string` | Compiled CSS content (internal) |
127
+ | `tailwindCssUrl` | `ssr()` internal | `string` | Compiled CSS route URL (internal) |
130
128
 
131
129
  ---
132
130
 
@@ -137,7 +135,7 @@ All modules follow one of **2 patterns** — learn these and you know every modu
137
135
  | Pattern | How to mount | Example |
138
136
  |---------|-------------|---------|
139
137
  | `[α]` | `app.use(mod())` | `compress()`, `preferences()`, `postgres()` |
140
- | `[β]` | `app.use('/path', mod())` | `health()`, `graphql(handler)`, `user()` |
138
+ | `[β]` | `app.use('/path', mod())` | `health()`, `ssr({dir})`, `graphql(handler)`, `user()` |
141
139
 
142
140
  ### Pattern α — Middleware
143
141
 
@@ -398,23 +396,7 @@ Restart=always
398
396
  | `buildCommand` | — | Build command |
399
397
  | `ports` | — | `[port, port+1]` for blue-green |
400
398
 
401
- ### errorBoundary(path) [β]
402
399
 
403
- Wraps child routes in an error boundary. If a page or middleware throws, the error component is rendered via SSR with head injection (CSS, theme, context) and layout wrapping.
404
-
405
- ```ts
406
- app.use('/blog', errorBoundary('./blog-error.tsx'))
407
- ```
408
-
409
- The error component receives `{ error, reset }` as props (`reset` is a no-op on the server):
410
-
411
- ```tsx
412
- export default function BlogError({ error, reset }: { error: Error; reset: () => void }) {
413
- return <div><h2>Error</h2><p>{error.message}</p></div>
414
- }
415
- ```
416
-
417
- Error boundaries nest — the nearest one up the middleware chain catches the error.
418
400
 
419
401
  ### health [β]
420
402
 
@@ -483,16 +465,7 @@ await engine.trigger({ function_id: 'orders::create', payload: { items: ['apple'
483
465
  | `.migrate()` | DB setup |
484
466
  | `.shutdown()` | Clean shutdown |
485
467
 
486
- ### layout(path) [β]
487
-
488
- Compiles a `.tsx` file and returns middleware that pushes the layout component onto `ctx.layoutStack`. Pages rendered by `ssr()` consume this stack. Use after `rootLayout()` to extend a shared structure.
489
-
490
- ```ts
491
- app.use(rootLayout('./ui'))
492
- app.use(layout('./extra.tsx')) // appended after rootLayout
493
- ```
494
468
 
495
- Layout components receive `{ children }` (the child page or nested layout). Multiple layouts wrap from outer to inner in `use()` order.
496
469
 
497
470
  ### logdb [β]
498
471
 
@@ -566,17 +539,7 @@ await msg.send(channelId, 'System message', { sender_type: 'system', sender_id:
566
539
  | `.send(channel, content, opts?)` | Send message to channel |
567
540
  | `.close()` | Cleanup |
568
541
 
569
- ### notFound(path) [β]
570
542
 
571
- Returns a catch-all handler for 404 pages. When a path is given, the component is rendered via SSR with layout support. Falls back to plain text if compilation fails or no path given.
572
-
573
- ```ts
574
- // No path — plain text
575
- app.all('/*', notFound())
576
-
577
- // Path to a .tsx component — renders via SSR
578
- app.all('/*', notFound('./not-found.tsx'))
579
- ```
580
543
 
581
544
  ### opencode [β]
582
545
 
@@ -825,20 +788,7 @@ app.use(requestId({ header: 'X-Request-Id', generator: () => crypto.randomUUID()
825
788
  | `header` | `string` | `'X-Request-ID'` | Header name to read/write |
826
789
  | `generator` | `() => string` | `crypto.randomUUID()` | ID generator |
827
790
 
828
- ### rootLayout(dir) [α]
829
-
830
- One-stop middleware for a page structure. Compiles `layout.tsx` and `app.css` from the given directory, and in dev mode registers vendor bundle, HMR WebSocket, and file watcher.
831
-
832
- ```ts
833
- app.use(rootLayout('./ui'))
834
- // Scans ./ui/layout.tsx → layout component
835
- // Scans ./ui/app.css → tailwind CSS at /{mountPath}/__wfw/style/{hash}.css
836
- // Dev: vendor bundle + HMR WS + file watcher
837
- ```
838
791
 
839
- - Sets `ctx.layoutStack` (consumed by `ssr()`)
840
- - Registers CSS route at `/__wfw/style/:hash.css` — Tailwind CSS compiled via `@tailwindcss/postcss` if `app.css` exists in the dir. Hash is content-based, ensuring cache invalidation on changes.
841
- - Each `rootLayout` instance is independent — sub-routes can define their own
842
792
 
843
793
  ### seo [β] + seoMiddleware [α]
844
794
 
@@ -858,21 +808,64 @@ Also exports `seoTags(config)` for generating meta/og/twitter tags as an HTML st
858
808
  | `sitemap` | `SitemapConfig` | — | Sitemap configuration (urls, resolve, cacheTTL) |
859
809
  | `headers` | `SeoHeadersConfig` | — | Response headers (e.g. `X-Robots-Tag`) |
860
810
 
861
- ### ssr(path) [β]
811
+ ### ssr({ dir }) [β]
812
+
813
+ One-stop Server-Side Rendering. Accepts a directory and returns a Router that handles all SSR routes, tailwind CSS, hydration bundles, and livereload — using Next.js-style file conventions.
862
814
 
863
- Compiles a `.tsx` file and returns a Router handler that renders the React component to HTML with streaming, client bundle injection, and context serialization.
815
+ ```ts
816
+ import { Router, ssr } from 'weifuwu'
817
+ const app = new Router()
818
+ app.use('/', ssr({ dir: './ui' }))
819
+ ```
820
+
821
+ **Directory conventions (Next.js-style):**
822
+
823
+ ```
824
+ ./ui/
825
+ ├── app/ ← only this directory affects routing
826
+ │ ├── globals.css ← tailwind CSS + CSS variables (optional)
827
+ │ ├── layout.tsx → root layout (wraps all pages)
828
+ │ ├── page.tsx → GET /
829
+ │ ├── not-found.tsx → 404 page (optional)
830
+ │ ├── error.tsx → error boundary (optional)
831
+ │ ├── about/
832
+ │ │ ├── page.tsx → GET /about
833
+ │ │ └── layout.tsx → group layout
834
+ │ └── posts/
835
+ │ ├── page.tsx → GET /posts
836
+ │ └── [id]/
837
+ │ └── page.tsx → GET /posts/:id
838
+ ├── components/ ← shared components (does not affect routing)
839
+ └── lib/ ← utilities (does not affect routing)
840
+ ```
841
+
842
+ | Location | Route |
843
+ |----------|-------|
844
+ | `app/page.tsx` | `GET /` |
845
+ | `app/[param]/page.tsx` | `GET /:param` |
846
+ | `app/layout.tsx` | Root layout (wraps all pages in its subtree) |
847
+ | `app/not-found.tsx` | 404 fallback for that subtree |
848
+ | `app/error.tsx` | Error boundary for that subtree |
849
+ | `app/globals.css` | Tailwind CSS entry (compiled via `@tailwindcss/postcss`) |
850
+
851
+ **How it works:**
852
+
853
+ - Each page is lazy-resolved on first request — only the `page.tsx` and its layout chain are compiled
854
+ - Hydration bundle generated per-page at `/__ssr/{hash}.js`
855
+ - Tailwind CSS served at `/__wfw/style/{hash}.css` (cached, content-hashed)
856
+ - Dev mode: vendor bundle, HMR WebSocket, file watcher — all automatic
857
+ - Page components and layouts are compiled via esbuild at runtime — no build step needed
864
858
 
865
859
  ```ts
866
- app.get('/about', ssr('./ui/pages/about.tsx'))
860
+ // Multiple independent SSR directories
861
+ app.use('/', ssr({ dir: './www' }))
862
+ app.use('/admin', ssr({ dir: './admin' }))
863
+
864
+ // API routes coexist normally
865
+ app.get('/api/ping', () => Response.json({ pong: true }))
867
866
  ```
868
867
 
869
- - Compiles via esbuild at runtime (no build step)
870
- - Reads `ctx.layoutStack` (set by `rootLayout()` or `layout()`) and wraps the component from outer to inner
871
- - Injects hydration script pointing to the auto-generated client bundle at `/__ssr/{entryId}.js`
872
- - Injects `<link>` for tailwind CSS from `ctx.tailwindCssUrl` (set by `rootLayout()`)
873
- - Serializes middleware-injected `ctx` data to `window.__WEIFUWU_CTX` for client-side hydration
874
- - **Dev mode:** uses `createRoot` instead of `hydrateRoot` — all hooks (`useState`, `useEffect`) work correctly; SSR content is still streamed for fast first paint
875
- - **Prod mode:** uses `hydrateRoot` for full SSR hydration
868
+ Layout components receive `{ children }` and wrap from outer to inner:
876
869
 
877
870
  ### tenant [β]
878
871
 
@@ -1084,9 +1077,9 @@ function Toast() {
1084
1077
 
1085
1078
  ### Dev mode
1086
1079
 
1087
- Auto-detected when `NODE_ENV !== 'production'`. `rootLayout(dir)` automatically registers vendor bundle, HMR WebSocket, and file watcher. No explicit setup needed.
1080
+ Auto-detected when `NODE_ENV !== 'production'`. `ssr({dir})` automatically registers vendor bundle, HMR WebSocket, and file watcher. No explicit setup needed.
1088
1081
 
1089
- When a `.tsx` or `.css` file changes under the `rootLayout` dir, the browser hot-updates without refreshing — `useState` values are preserved. Layout changes trigger a full page reload.
1082
+ When a `.tsx` or `.css` file changes under the `ssr` dir, the browser hot-updates without refreshing — `useState` values are preserved. Layout changes trigger a full page reload.
1090
1083
 
1091
1084
  ---
1092
1085
 
@@ -1125,7 +1118,7 @@ Every public symbol can be imported from `'weifuwu'`:
1125
1118
  ### Core
1126
1119
 
1127
1120
  ```ts
1128
- serve, createTestServer, Router,
1121
+ serve, createTestServer, Router, ssr,
1129
1122
  Context, Handler, Middleware, ErrorHandler, ServeOptions, Server,
1130
1123
  loadEnv
1131
1124
  ```
@@ -1172,7 +1165,7 @@ openai, createOpenAI
1172
1165
  ### Other modules
1173
1166
 
1174
1167
  ```ts
1175
- health, analytics, seo, seoMiddleware, seoTags,
1168
+ preferences, health, analytics, seo, seoMiddleware, seoTags,
1176
1169
  user, mailer, graphql, aiStream, runWorkflow,
1177
1170
  logdb, messager, agent, iii, createWorker, registerWorker,
1178
1171
  opencode, deploy, defineConfig,
@@ -1,12 +1,8 @@
1
- import { join } from 'node:path'
2
- import { Router, ssr, rootLayout, preferences } from '../../index.ts'
3
-
4
- const _ui = join(import.meta.dirname, 'ui')
5
- const _loc = join(import.meta.dirname, 'locales')
1
+ import { Router, ssr, preferences } from '../../index.ts'
6
2
 
7
3
  export const app = new Router()
8
- app.use(rootLayout(_ui))
9
- app.use(preferences({ dir: _loc, locale: { default: 'en' }, theme: { default: 'system' } }))
4
+ app.use('/', ssr({ dir: './ui' }))
5
+ app.use(preferences({ dir: './locales', locale: { default: 'en' }, theme: { default: 'system' } }))
10
6
  app.use(async (req, ctx, next) => {
11
7
  ctx.loaderData = {
12
8
  features: [
@@ -17,6 +13,5 @@ app.use(async (req, ctx, next) => {
17
13
  }
18
14
  return next(req, ctx)
19
15
  })
20
- app.get('/', ssr(join(_ui, 'page.tsx')))
21
16
  app.get('/api/ping', () => Response.json({ pong: true, time: new Date().toISOString() }))
22
17
  app.ws('/ws/echo', { message(ws, _ctx, data) { ws.send(`echo: ${data}`) } })
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'react'
2
- import { useWebsocket, useLoaderData, useLocale, useTheme } from '../../../react.ts'
3
- import Greeting from './components/Greeting.tsx'
2
+ import { useWebsocket, useLoaderData, useLocale, useTheme } from '../../../../react.ts'
3
+ import Greeting from '../components/Greeting.tsx'
4
4
 
5
5
  export default function Home() {
6
6
  const [input, setInput] = useState('')
@@ -1,3 +1,3 @@
1
1
  export default function Greeting({ name }: { name: string }) {
2
- return <span className="text-green-500 font-bold">{name}!</span>
2
+ return <span className="text-red-500 font-bold">{name}!</span>
3
3
  }
package/cli.ts CHANGED
@@ -36,19 +36,12 @@ async function cmdInit(name: string) {
36
36
  await cp(templateDir, targetDir, { recursive: true })
37
37
 
38
38
  // Rewrite local imports → package imports for the copied project
39
- for (const file of ['app.ts', 'index.ts', 'ui/page.tsx']) {
39
+ for (const file of ['app.ts', 'index.ts', 'ui/app/page.tsx']) {
40
40
  const fp = join(targetDir, file)
41
41
  let content = await readFile(fp, 'utf-8')
42
42
  content = content
43
43
  .replace(/from '\.\.\/\.\.\/index\.ts'/g, "from 'weifuwu'")
44
44
  .replace(/from '\.\.\/\.\.\/\.\.\/react\.ts'/g, "from 'weifuwu/react'")
45
- .replace(/import \{ join \} from 'node:path'\n/gm, '')
46
- .replace(/const _ui = join\(import\.meta\.dirname, 'ui'\)\n/gm, '')
47
- .replace(/const _loc = join\(import\.meta\.dirname, 'locales'\)\n\n/, '')
48
- .replace(/preferences\(\{ dir: _loc, locale: \{ default: 'en' \}, theme: \{ default: 'system' \} \}\)/g, "preferences({ dir: './locales' })")
49
- .replace(/rootLayout\(_ui\)/g, "rootLayout('./ui')")
50
- .replace(/ssr\(join\(_ui, 'page\.tsx'\)\)/g, "ssr('./ui/page.tsx')")
51
- .replace(/join\(import\.meta\.dirname, 'ui'\)/g, "'./ui'")
52
45
  await writeFile(fp, content)
53
46
  }
54
47
 
@@ -57,8 +50,8 @@ async function cmdInit(name: string) {
57
50
  name,
58
51
  type: 'module',
59
52
  scripts: {
60
- dev: 'node index.ts',
61
- start: 'NODE_ENV=production node index.ts',
53
+ dev: 'NODE_ENV=development node index.ts',
54
+ start: 'node index.ts',
62
55
  },
63
56
  dependencies: {
64
57
  weifuwu: `^${v}`,
@@ -98,7 +91,7 @@ async function cmdInit(name: string) {
98
91
  '## Commands',
99
92
  '',
100
93
  '- `npm run dev` — start dev server with `--watch`',
101
- '- `npm start` — start production server (NODE_ENV=production)',
94
+ '- `npm start` — start production server',
102
95
  '- `npm install` — install dependencies',
103
96
  '- `npx tsc --noEmit` — type-check without emitting',
104
97
  '',
package/dist/auth.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { Middleware } from './types.ts';
2
+ export interface AuthOptions {
3
+ token?: string;
4
+ verify?: (token: string, req: Request) => unknown | Promise<unknown>;
5
+ proxy?: string | URL;
6
+ header?: string;
7
+ }
8
+ export declare function auth(options: AuthOptions): Middleware;
package/dist/cli.js CHANGED
@@ -28,18 +28,18 @@ async function cmdInit(name) {
28
28
  await mkdir(targetDir, { recursive: true });
29
29
  const templateDir = join(pkgRoot, "cli", "template");
30
30
  await cp(templateDir, targetDir, { recursive: true });
31
- for (const file of ["app.ts", "index.ts", "ui/page.tsx"]) {
31
+ for (const file of ["app.ts", "index.ts", "ui/app/page.tsx"]) {
32
32
  const fp = join(targetDir, file);
33
33
  let content = await readFile(fp, "utf-8");
34
- content = content.replace(/from '\.\.\/\.\.\/index\.ts'/g, "from 'weifuwu'").replace(/from '\.\.\/\.\.\/\.\.\/react\.ts'/g, "from 'weifuwu/react'").replace(/import \{ join \} from 'node:path'\n/gm, "").replace(/const _ui = join\(import\.meta\.dirname, 'ui'\)\n/gm, "").replace(/const _loc = join\(import\.meta\.dirname, 'locales'\)\n\n/, "").replace(/preferences\(\{ dir: _loc, locale: \{ default: 'en' \}, theme: \{ default: 'system' \} \}\)/g, "preferences({ dir: './locales' })").replace(/rootLayout\(_ui\)/g, "rootLayout('./ui')").replace(/ssr\(join\(_ui, 'page\.tsx'\)\)/g, "ssr('./ui/page.tsx')").replace(/join\(import\.meta\.dirname, 'ui'\)/g, "'./ui'");
34
+ content = content.replace(/from '\.\.\/\.\.\/index\.ts'/g, "from 'weifuwu'").replace(/from '\.\.\/\.\.\/\.\.\/react\.ts'/g, "from 'weifuwu/react'");
35
35
  await writeFile(fp, content);
36
36
  }
37
37
  await writeFile(join(targetDir, "package.json"), JSON.stringify({
38
38
  name,
39
39
  type: "module",
40
40
  scripts: {
41
- dev: "node index.ts",
42
- start: "NODE_ENV=production node index.ts"
41
+ dev: "NODE_ENV=development node index.ts",
42
+ start: "node index.ts"
43
43
  },
44
44
  dependencies: {
45
45
  weifuwu: `^${v}`
@@ -76,7 +76,7 @@ async function cmdInit(name) {
76
76
  "## Commands",
77
77
  "",
78
78
  "- `npm run dev` \u2014 start dev server with `--watch`",
79
- "- `npm start` \u2014 start production server (NODE_ENV=production)",
79
+ "- `npm start` \u2014 start production server",
80
80
  "- `npm install` \u2014 install dependencies",
81
81
  "- `npx tsc --noEmit` \u2014 type-check without emitting",
82
82
  "",
package/dist/compile.d.ts CHANGED
@@ -12,3 +12,5 @@ export declare function compileHotComponent(path: string): Promise<{
12
12
  hash: string;
13
13
  code: string;
14
14
  }>;
15
+ /** Clean up esbuild's internal worker pool. Call when you're done compiling. */
16
+ export declare function closeCompile(): Promise<void>;
package/dist/cors.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { Middleware } from './types.ts';
2
+ export interface CORSOptions {
3
+ origin?: string | string[] | ((origin: string) => string | boolean | undefined);
4
+ methods?: string[];
5
+ allowedHeaders?: string[];
6
+ exposedHeaders?: string[];
7
+ credentials?: boolean;
8
+ maxAge?: number;
9
+ }
10
+ export declare function cors(options?: CORSOptions): Middleware;
package/dist/env.d.ts CHANGED
@@ -1 +1,3 @@
1
+ /** Whether NODE_ENV is explicitly set to 'development' */
2
+ export declare function isDev(): boolean;
1
3
  export declare function loadEnv(path?: string): void;
@@ -0,0 +1 @@
1
+ export declare function buildHtmlShell(title: string, bodyElement: any, layoutComponents: any[]): any;
package/dist/index.d.ts CHANGED
@@ -1,12 +1,16 @@
1
1
  export type { Context, Handler, Middleware, ErrorHandler } from './types.ts';
2
- export { loadEnv } from './env.ts';
2
+ export { loadEnv, isDev } from './env.ts';
3
3
  export { serve, createTestServer } from './serve.ts';
4
4
  export type { ServeOptions, Server } from './serve.ts';
5
5
  export { Router } from './router.ts';
6
6
  export type { WebSocketHandler } from './router.ts';
7
7
  export { TsxContext } from './tsx-context.ts';
8
- export { auth, cors, logger } from './middleware.ts';
9
- export type { AuthOptions, CORSOptions, LoggerOptions } from './middleware.ts';
8
+ export { logger } from './logger.ts';
9
+ export type { LoggerOptions } from './logger.ts';
10
+ export { cors } from './cors.ts';
11
+ export type { CORSOptions } from './cors.ts';
12
+ export { auth } from './auth.ts';
13
+ export type { AuthOptions } from './auth.ts';
10
14
  export { serveStatic } from './static.ts';
11
15
  export type { ServeStaticOptions } from './static.ts';
12
16
  export { validate } from './validate.ts';
@@ -68,10 +72,3 @@ export type { LogdbOptions, LogdbModule, LogEntry, LogEntryInput, } from './logd
68
72
  export { iii, createWorker, registerWorker } from './iii/index.ts';
69
73
  export type { IIIModule, IIIOptions, WorkerInfo, FunctionInfo, TriggerInfo, FunctionHandler, FunctionContext, TriggerInput, RemoteWorker, TriggerRequest, } from './iii/types.ts';
70
74
  export { ssr } from './ssr.ts';
71
- export { rootLayout } from './root-layout.ts';
72
- export { layout } from './layout.ts';
73
- export { notFound } from './not-found.ts';
74
- export { errorBoundary } from './error-boundary.ts';
75
- export { clearCompileCache } from './compile.ts';
76
- export { ssrEntries } from './ssr-entries.ts';
77
- export type { SsrEntry } from './ssr-entries.ts';