weifuwu 0.18.3 → 0.18.4

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 (76) hide show
  1. package/cli.ts +10 -101
  2. package/dist/cli.js +7 -95
  3. package/dist/dist/agent/client.d.ts +2 -0
  4. package/dist/dist/agent/index.d.ts +2 -0
  5. package/dist/dist/agent/migrate.d.ts +6 -0
  6. package/dist/dist/agent/rest.d.ts +13 -0
  7. package/dist/dist/agent/run.d.ts +17 -0
  8. package/dist/dist/agent/types.d.ts +51 -0
  9. package/dist/dist/ai/workflow.d.ts +14 -0
  10. package/dist/dist/analytics.d.ts +15 -0
  11. package/dist/dist/client-locale.d.ts +5 -0
  12. package/dist/dist/client-pref.d.ts +3 -0
  13. package/dist/dist/client-state.d.ts +22 -0
  14. package/dist/dist/client-theme.d.ts +7 -0
  15. package/dist/dist/compress.d.ts +6 -0
  16. package/dist/dist/cookie.d.ts +12 -0
  17. package/dist/dist/deploy/config.d.ts +2 -0
  18. package/dist/dist/deploy/gateway.d.ts +2 -0
  19. package/dist/dist/deploy/index.d.ts +4 -0
  20. package/dist/dist/deploy/manager.d.ts +16 -0
  21. package/dist/dist/deploy/process.d.ts +14 -0
  22. package/dist/dist/deploy/types.d.ts +62 -0
  23. package/dist/dist/head.d.ts +6 -0
  24. package/dist/dist/helmet.d.ts +18 -0
  25. package/dist/dist/iii/client.d.ts +2 -0
  26. package/dist/dist/iii/index.d.ts +4 -0
  27. package/dist/dist/iii/register-worker.d.ts +10 -0
  28. package/dist/dist/iii/rest.d.ts +3 -0
  29. package/dist/dist/iii/stream.d.ts +82 -0
  30. package/dist/dist/iii/types.d.ts +133 -0
  31. package/dist/dist/iii/worker.d.ts +2 -0
  32. package/dist/dist/iii/ws.d.ts +29 -0
  33. package/dist/dist/index.js +8180 -0
  34. package/dist/dist/messager/agent.d.ts +6 -0
  35. package/dist/dist/messager/client.d.ts +2 -0
  36. package/dist/dist/messager/index.d.ts +2 -0
  37. package/dist/dist/messager/migrate.d.ts +2 -0
  38. package/dist/dist/messager/rest.d.ts +15 -0
  39. package/dist/dist/messager/types.d.ts +56 -0
  40. package/dist/dist/messager/ws.d.ts +14 -0
  41. package/dist/dist/preferences.d.ts +14 -0
  42. package/dist/dist/react.d.ts +12 -0
  43. package/dist/dist/react.js +637 -0
  44. package/dist/dist/request-id.d.ts +6 -0
  45. package/dist/dist/seo.d.ts +39 -0
  46. package/dist/dist/ssr/compile.d.ts +2 -0
  47. package/dist/dist/tenant/client.d.ts +2 -0
  48. package/dist/dist/tenant/graphql.d.ts +3 -0
  49. package/dist/dist/tenant/index.d.ts +2 -0
  50. package/dist/dist/tenant/migrate.d.ts +6 -0
  51. package/dist/dist/tenant/rest.d.ts +3 -0
  52. package/dist/dist/tenant/schema.d.ts +5 -0
  53. package/dist/dist/tenant/types.d.ts +48 -0
  54. package/dist/dist/tenant/utils.d.ts +10 -0
  55. package/dist/dist/types.d.ts +19 -0
  56. package/dist/dist/use-flash-message.d.ts +1 -0
  57. package/dist/error-boundary.d.ts +2 -0
  58. package/dist/index.d.ts +7 -0
  59. package/dist/index.js +185 -34
  60. package/dist/layout.d.ts +2 -0
  61. package/dist/live.d.ts +6 -0
  62. package/dist/not-found.d.ts +2 -0
  63. package/dist/ssr.d.ts +2 -0
  64. package/dist/stream.d.ts +14 -0
  65. package/dist/tailwind.d.ts +2 -0
  66. package/package.json +3 -4
  67. /package/dist/{ssr/compile.d.ts → compile.d.ts} +0 -0
  68. /package/dist/{ssr → dist/ssr}/error-boundary.d.ts +0 -0
  69. /package/dist/{ssr → dist/ssr}/index.d.ts +0 -0
  70. /package/dist/{ssr → dist/ssr}/index.js +0 -0
  71. /package/dist/{ssr → dist/ssr}/layout.d.ts +0 -0
  72. /package/dist/{ssr → dist/ssr}/live.d.ts +0 -0
  73. /package/dist/{ssr → dist/ssr}/not-found.d.ts +0 -0
  74. /package/dist/{ssr → dist/ssr}/ssr.d.ts +0 -0
  75. /package/dist/{ssr → dist/ssr}/stream.d.ts +0 -0
  76. /package/dist/{ssr → dist/ssr}/tailwind.d.ts +0 -0
@@ -0,0 +1,3 @@
1
+ import type { Sql } from '../vendor.ts';
2
+ import { Router } from '../router.ts';
3
+ export declare function buildRouter(sql: Sql<{}>, usersTable: string): Router;
@@ -0,0 +1,5 @@
1
+ import type { FieldDef } from './types.ts';
2
+ export declare function createTableSQL(tenantId: string, slug: string, fields: FieldDef[]): string;
3
+ export declare function addColumnSQL(tenantId: string, slug: string, field: FieldDef): string;
4
+ export declare function dropTableSQL(tenantId: string, slug: string): string;
5
+ export declare function createIndexesSQL(tenantId: string, slug: string, fields: FieldDef[]): string[];
@@ -0,0 +1,48 @@
1
+ import type { Context } from '../types.ts';
2
+ import type { Router } from '../router.ts';
3
+ import type { PostgresClient } from '../postgres/types.ts';
4
+ declare module '../types.ts' {
5
+ interface Context {
6
+ tenant: TenantContext;
7
+ }
8
+ }
9
+ export interface TenantContext {
10
+ id: string;
11
+ name: string;
12
+ role: string;
13
+ }
14
+ export type FieldType = 'string' | 'integer' | 'float' | 'boolean' | 'text' | 'datetime' | 'date' | 'enum' | 'json' | 'vector';
15
+ export interface RelationDef {
16
+ table: string;
17
+ field?: string;
18
+ onDelete?: 'cascade' | 'restrict' | 'setnull';
19
+ }
20
+ export interface FieldDef {
21
+ name: string;
22
+ type: FieldType;
23
+ required?: boolean;
24
+ unique?: boolean;
25
+ index?: boolean | 'desc' | 'gin' | 'hnsw';
26
+ default?: unknown;
27
+ options?: string[];
28
+ dimensions?: number;
29
+ relation?: RelationDef;
30
+ }
31
+ export interface UserTableRow {
32
+ id: number;
33
+ tenant_id: string;
34
+ slug: string;
35
+ label: string;
36
+ fields: FieldDef[];
37
+ created_at: string;
38
+ }
39
+ export interface TenantOptions {
40
+ pg: PostgresClient;
41
+ usersTable: string;
42
+ }
43
+ export interface TenantModule extends Router {
44
+ migrate: () => Promise<void>;
45
+ middleware: () => (req: Request, ctx: Context, next: any) => Promise<Response>;
46
+ graphql: () => any;
47
+ close: () => Promise<void>;
48
+ }
@@ -0,0 +1,10 @@
1
+ import type { FieldDef } from './types.ts';
2
+ export declare function internalTableName(tenantId: string, slug: string): string;
3
+ export declare function pascalCase(slug: string): string;
4
+ export declare function sqlTypeForField(field: FieldDef): string;
5
+ export declare function validateSlug(slug: string): string | null;
6
+ export declare function validateFieldDefs(fields: FieldDef[]): string[];
7
+ export declare function formatDefault(field: FieldDef): string;
8
+ export declare function mapFieldToZod(field: FieldDef): string;
9
+ export declare function getRelationFields(fields: FieldDef[]): FieldDef[];
10
+ export declare function findRelation(fields: FieldDef[], targetSlug: string): FieldDef | undefined;
@@ -0,0 +1,19 @@
1
+ export interface Context {
2
+ params: Record<string, string>;
3
+ query: Record<string, string>;
4
+ user?: unknown;
5
+ parsed?: Record<string, unknown>;
6
+ mountPath?: string;
7
+ t?: (key: string, params?: Record<string, string>, fallback?: string) => string;
8
+ setPref?: (name: string, value: string) => Response;
9
+ prefs?: Record<string, string>;
10
+ env?: Record<string, string>;
11
+ layoutStack?: {
12
+ path: string;
13
+ component: any;
14
+ }[];
15
+ [key: string]: unknown;
16
+ }
17
+ export type Handler = (req: Request, ctx: Context) => Response | Promise<Response>;
18
+ export type Middleware = (req: Request, ctx: Context, next: Handler) => Response | Promise<Response>;
19
+ export type ErrorHandler = (error: Error, req: Request, ctx: Context) => Response | Promise<Response>;
@@ -0,0 +1 @@
1
+ export declare function useFlashMessage<T = any>(): T | null;
@@ -0,0 +1,2 @@
1
+ import type { Middleware } from './types.ts';
2
+ export declare function errorBoundary(errorPath: string): Middleware;
package/dist/index.d.ts CHANGED
@@ -67,3 +67,10 @@ export { logdb } from './logdb/index.ts';
67
67
  export type { LogdbOptions, LogdbModule, LogEntry, LogEntryInput, } from './logdb/types.ts';
68
68
  export { iii, createWorker, registerWorker } from './iii/index.ts';
69
69
  export type { IIIModule, IIIOptions, WorkerInfo, FunctionInfo, TriggerInfo, FunctionHandler, FunctionContext, TriggerInput, RemoteWorker, TriggerRequest, } from './iii/types.ts';
70
+ export { ssr } from './ssr.ts';
71
+ export { layout } from './layout.ts';
72
+ export { liveReload } from './live.ts';
73
+ export { tailwind } from './tailwind.ts';
74
+ export { notFound } from './not-found.ts';
75
+ export { errorBoundary } from './error-boundary.ts';
76
+ export { clearCompileCache } from './compile.ts';
package/dist/index.js CHANGED
@@ -376,13 +376,13 @@ var Router = class _Router {
376
376
  const mw = match.middlewares[index++];
377
377
  return mw(innerReq, ctx2, dispatch);
378
378
  }
379
- return await new Promise((resolve12) => {
379
+ return await new Promise((resolve13) => {
380
380
  try {
381
381
  upgradeSocket(router.wss, req, socket, head, match.handler, ctx2);
382
- resolve12(new Response(null, { status: 101 }));
382
+ resolve13(new Response(null, { status: 101 }));
383
383
  } catch {
384
384
  socket.destroy();
385
- resolve12(new Response("WebSocket upgrade failed", { status: 500 }));
385
+ resolve13(new Response("WebSocket upgrade failed", { status: 500 }));
386
386
  }
387
387
  });
388
388
  };
@@ -2636,7 +2636,7 @@ function user(options) {
2636
2636
  async function migrate() {
2637
2637
  await users.create();
2638
2638
  if (!oauth2Enabled) return;
2639
- const clients2 = pgTable("_oauth2_clients", {
2639
+ const clients3 = pgTable("_oauth2_clients", {
2640
2640
  id: serial("id").primaryKey(),
2641
2641
  name: text("name").notNull(),
2642
2642
  client_id: text("client_id").unique().notNull(),
@@ -2645,7 +2645,7 @@ function user(options) {
2645
2645
  scopes: text("scopes").default(""),
2646
2646
  created_at: timestamptz("created_at").default(sql`NOW()`)
2647
2647
  });
2648
- await clients2.create(pg.sql);
2648
+ await clients3.create(pg.sql);
2649
2649
  const codes = pgTable("_oauth2_codes", {
2650
2650
  id: serial("id").primaryKey(),
2651
2651
  code: text("code").unique().notNull(),
@@ -2842,7 +2842,7 @@ function createHub(opts) {
2842
2842
  }
2843
2843
  });
2844
2844
  }
2845
- function join6(key, ws) {
2845
+ function join7(key, ws) {
2846
2846
  if (!channels.has(key)) {
2847
2847
  channels.set(key, /* @__PURE__ */ new Set());
2848
2848
  redisSub?.subscribe(`${prefix}${key}`);
@@ -2883,7 +2883,7 @@ function createHub(opts) {
2883
2883
  await redisSub.quit();
2884
2884
  }
2885
2885
  }
2886
- return { join: join6, leave, broadcast, close };
2886
+ return { join: join7, leave, broadcast, close };
2887
2887
  }
2888
2888
 
2889
2889
  // queue/index.ts
@@ -4693,14 +4693,14 @@ function forkApp(opts) {
4693
4693
  return { child, port: opts.port };
4694
4694
  }
4695
4695
  function stopProcess(mp, timeout = 1e4) {
4696
- return new Promise((resolve12) => {
4696
+ return new Promise((resolve13) => {
4697
4697
  const timer = setTimeout(() => {
4698
4698
  mp.child.kill("SIGKILL");
4699
- resolve12();
4699
+ resolve13();
4700
4700
  }, timeout);
4701
4701
  mp.child.on("exit", () => {
4702
4702
  clearTimeout(timer);
4703
- resolve12();
4703
+ resolve13();
4704
4704
  });
4705
4705
  mp.child.kill("SIGTERM");
4706
4706
  });
@@ -5132,13 +5132,13 @@ import { createOpenAI as createOpenAI3 } from "@ai-sdk/openai";
5132
5132
  // opencode/rest.ts
5133
5133
  import { join as join4 } from "node:path";
5134
5134
 
5135
- // ssr/ssr.ts
5135
+ // ssr.ts
5136
5136
  import { createElement } from "react";
5137
5137
  import { createHash as createHash3 } from "node:crypto";
5138
5138
  import { dirname as dirname2, resolve as resolve4 } from "node:path";
5139
5139
  import { AsyncLocalStorage } from "node:async_hooks";
5140
5140
 
5141
- // ssr/compile.ts
5141
+ // compile.ts
5142
5142
  import * as esbuild from "esbuild";
5143
5143
  import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2 } from "node:fs";
5144
5144
  import { join as join2, resolve as resolve3, dirname } from "node:path";
@@ -5186,6 +5186,10 @@ function resolveAliases() {
5186
5186
  function id(s) {
5187
5187
  return createHash2("md5").update(s).digest("hex").slice(0, 8);
5188
5188
  }
5189
+ function clearCompileCache() {
5190
+ cache.clear();
5191
+ _alias = null;
5192
+ }
5189
5193
  async function compileTsx(path2) {
5190
5194
  if (cache.has(path2)) return cache.get(path2);
5191
5195
  const absPath = resolve3(path2);
@@ -5210,7 +5214,7 @@ async function compileTsx(path2) {
5210
5214
  return mod;
5211
5215
  }
5212
5216
 
5213
- // ssr/stream.ts
5217
+ // stream.ts
5214
5218
  import { TextDecoder, TextEncoder as TextEncoder2 } from "node:util";
5215
5219
  var _publicEnv = null;
5216
5220
  function getPublicEnv() {
@@ -5331,7 +5335,7 @@ function streamResponse(reactStream, opts) {
5331
5335
  });
5332
5336
  }
5333
5337
 
5334
- // ssr/ssr.ts
5338
+ // ssr.ts
5335
5339
  var als = new AsyncLocalStorage();
5336
5340
  __registerAls(() => als.getStore());
5337
5341
  var isDev = process.env.NODE_ENV !== "production";
@@ -5473,7 +5477,7 @@ function ssr(path2) {
5473
5477
  return r;
5474
5478
  }
5475
5479
 
5476
- // ssr/layout.ts
5480
+ // layout.ts
5477
5481
  function layout(path2) {
5478
5482
  return async (req, ctx, next) => {
5479
5483
  const mod = await compileTsx(path2);
@@ -5484,15 +5488,6 @@ function layout(path2) {
5484
5488
  };
5485
5489
  }
5486
5490
 
5487
- // ssr/tailwind.ts
5488
- var isDev2 = process.env.NODE_ENV !== "production";
5489
-
5490
- // ssr/error-boundary.ts
5491
- import { createElement as createElement2 } from "react";
5492
-
5493
- // ssr/live.ts
5494
- import chokidar from "chokidar";
5495
-
5496
5491
  // opencode/session.ts
5497
5492
  import { randomUUID as randomUUID2 } from "node:crypto";
5498
5493
  import { join as join3 } from "node:path";
@@ -5729,10 +5724,10 @@ function createBashTool(ctx) {
5729
5724
  return { stdout: "", stderr: "Command denied: potentially dangerous command", exitCode: 1 };
5730
5725
  }
5731
5726
  const cwd = workdir ? `${ctx.workspace}/${workdir}` : ctx.workspace;
5732
- return new Promise((resolve12) => {
5727
+ return new Promise((resolve13) => {
5733
5728
  const child = exec(command, { cwd, timeout: timeout * 1e3, maxBuffer: 1024 * 1024 }, (error, stdout, stderr) => {
5734
5729
  const truncated = stdout.length > 1e6 || stderr.length > 1e6;
5735
- resolve12({
5730
+ resolve13({
5736
5731
  stdout: stdout.slice(0, 1e6),
5737
5732
  stderr: stderr.slice(0, 1e6),
5738
5733
  exitCode: error?.code ?? 0,
@@ -5973,7 +5968,7 @@ function createQuestionTool(ctx) {
5973
5968
  options: z12.array(z12.string()).optional().describe("Optional multiple choice options")
5974
5969
  }),
5975
5970
  execute: async ({ question, options }, { toolCallId }) => {
5976
- return new Promise((resolve12, reject) => {
5971
+ return new Promise((resolve13, reject) => {
5977
5972
  const timeout = setTimeout(() => {
5978
5973
  ctx.pendingQuestions.delete(toolCallId);
5979
5974
  reject(new Error("Question timed out"));
@@ -5981,7 +5976,7 @@ function createQuestionTool(ctx) {
5981
5976
  ctx.pendingQuestions.set(toolCallId, {
5982
5977
  resolve: (answer) => {
5983
5978
  clearTimeout(timeout);
5984
- resolve12(answer);
5979
+ resolve13(answer);
5985
5980
  },
5986
5981
  reject: (err) => {
5987
5982
  clearTimeout(timeout);
@@ -7726,12 +7721,12 @@ function iii(opts = {}) {
7726
7721
  const handler = async (payload) => {
7727
7722
  if (!worker.ws) throw new Error(`Worker "${worker.name}" disconnected`);
7728
7723
  const invocationId = crypto6.randomUUID();
7729
- return new Promise((resolve12, reject) => {
7724
+ return new Promise((resolve13, reject) => {
7730
7725
  const timer = setTimeout(() => {
7731
7726
  pending.delete(invocationId);
7732
7727
  reject(new Error(`Invocation timed out for "${id3}"`));
7733
7728
  }, 3e4);
7734
- pending.set(invocationId, { resolve: resolve12, reject, timer });
7729
+ pending.set(invocationId, { resolve: resolve13, reject, timer });
7735
7730
  worker.ws.send(JSON.stringify({
7736
7731
  type: "invoke",
7737
7732
  invocation_id: invocationId,
@@ -7972,8 +7967,8 @@ function registerWorker(url) {
7972
7967
  function connect() {
7973
7968
  if (intentionalClose) return;
7974
7969
  ws = new WebSocket(url);
7975
- ready = new Promise((resolve12) => {
7976
- resolveReady = resolve12;
7970
+ ready = new Promise((resolve13) => {
7971
+ resolveReady = resolve13;
7977
7972
  });
7978
7973
  ws.onopen = () => {
7979
7974
  reconnectAttempt = 0;
@@ -8093,13 +8088,13 @@ function registerWorker(url) {
8093
8088
  }
8094
8089
  return Promise.resolve(fn(request.payload, ctx));
8095
8090
  }
8096
- return new Promise((resolve12, reject) => {
8091
+ return new Promise((resolve13, reject) => {
8097
8092
  const invocationId = genId();
8098
8093
  const timer = setTimeout(() => {
8099
8094
  pendingInvocations.delete(invocationId);
8100
8095
  reject(new Error(`Invocation timed out for "${request.function_id}"`));
8101
8096
  }, request.timeout_ms || 3e4);
8102
- pendingInvocations.set(invocationId, { resolve: resolve12, reject, timer });
8097
+ pendingInvocations.set(invocationId, { resolve: resolve13, reject, timer });
8103
8098
  send({
8104
8099
  type: "invoke",
8105
8100
  invocation_id: invocationId,
@@ -8119,6 +8114,155 @@ function registerWorker(url) {
8119
8114
  }
8120
8115
  };
8121
8116
  }
8117
+
8118
+ // live.ts
8119
+ import chokidar from "chokidar";
8120
+ var clients2 = /* @__PURE__ */ new Set();
8121
+ function broadcastReload() {
8122
+ for (const ws of clients2) {
8123
+ try {
8124
+ ws.send("reload");
8125
+ } catch {
8126
+ clients2.delete(ws);
8127
+ }
8128
+ }
8129
+ }
8130
+ function liveReload(opts) {
8131
+ const r = new Router();
8132
+ r.ws("/__weifuwu/livereload", {
8133
+ open(ws) {
8134
+ clients2.add(ws);
8135
+ ws.on("close", () => clients2.delete(ws));
8136
+ ws.on("error", () => clients2.delete(ws));
8137
+ }
8138
+ });
8139
+ const watcher = chokidar.watch(opts.dirs, {
8140
+ ignored: /(^|[/\\])\.|node_modules|[/\\]\.weifuwu[/\\]/,
8141
+ ignoreInitial: true
8142
+ });
8143
+ watcher.on("change", (path2) => {
8144
+ if (!/\.tsx?$/.test(path2)) return;
8145
+ clearCompileCache();
8146
+ setTimeout(broadcastReload, 50);
8147
+ });
8148
+ r.close = () => {
8149
+ watcher.close();
8150
+ clients2.clear();
8151
+ };
8152
+ return r;
8153
+ }
8154
+
8155
+ // tailwind.ts
8156
+ import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
8157
+ import { relative, resolve as resolve12 } from "node:path";
8158
+ var isDev2 = process.env.NODE_ENV !== "production";
8159
+ function tailwind(cssPath, scanDir2) {
8160
+ let compiledCss = "";
8161
+ let twWatcher = null;
8162
+ return async (req, ctx, next) => {
8163
+ const url = new URL(req.url);
8164
+ if (url.pathname === "/__wfw/style.css") {
8165
+ if (!compiledCss) compiledCss = await compile(cssPath, scanDir2);
8166
+ return new Response(compiledCss || "", {
8167
+ headers: { "content-type": "text/css; charset=utf-8" }
8168
+ });
8169
+ }
8170
+ ctx.compiledTailwindCss = compiledCss;
8171
+ if (isDev2 && !twWatcher) {
8172
+ twWatcher = watchFile(cssPath, () => {
8173
+ compiledCss = "";
8174
+ });
8175
+ }
8176
+ return next(req, ctx);
8177
+ };
8178
+ }
8179
+ async function compile(cssPath, scanDir2) {
8180
+ try {
8181
+ const inputFile = resolve12(cssPath);
8182
+ if (!existsSync5(inputFile)) {
8183
+ mkdirSync3(dirname4(inputFile), { recursive: true });
8184
+ writeFileSync3(inputFile, '@import "tailwindcss"\n', "utf-8");
8185
+ }
8186
+ const { default: tailwindPlugin } = await import("@tailwindcss/postcss");
8187
+ const { default: postcss } = await import("postcss");
8188
+ let src = readFileSync5(inputFile, "utf-8");
8189
+ const scanSource = scanDir2 ? relative(dirname4(inputFile), scanDir2) || "." : ".";
8190
+ const sourcePath = scanSource === "." ? "./" : `./${scanSource}/`;
8191
+ src = `@source "${sourcePath}";
8192
+ ${src}`;
8193
+ const result = await postcss([tailwindPlugin()]).process(src, { from: inputFile });
8194
+ return result.css;
8195
+ } catch (err) {
8196
+ console.warn("Tailwind CSS processing failed:", err.message);
8197
+ return "";
8198
+ }
8199
+ }
8200
+ function dirname4(p) {
8201
+ return p.substring(0, p.lastIndexOf("/")) || "/";
8202
+ }
8203
+ function watchFile(path2, onChange) {
8204
+ let watcher = null;
8205
+ import("chokidar").then((chokidar2) => {
8206
+ watcher = chokidar2.default.watch(resolve12(path2), { persistent: false });
8207
+ watcher.on("change", onChange);
8208
+ });
8209
+ return watcher;
8210
+ }
8211
+
8212
+ // not-found.ts
8213
+ function notFound(path2) {
8214
+ return async (req, ctx) => {
8215
+ if (!path2) return new Response("Not Found", { status: 404 });
8216
+ const mod = await compileTsx(path2);
8217
+ const Component = mod?.default;
8218
+ const body = Component ? "404 - Not Found" : "404 - Not Found";
8219
+ return new Response(body, {
8220
+ status: 404,
8221
+ headers: { "content-type": "text/html; charset=utf-8" }
8222
+ });
8223
+ };
8224
+ }
8225
+
8226
+ // error-boundary.ts
8227
+ import { createElement as createElement2 } from "react";
8228
+ import { TextEncoder as TextEncoder3 } from "node:util";
8229
+ function errorBoundary(errorPath) {
8230
+ return async (req, ctx, next) => {
8231
+ try {
8232
+ return await next(req, ctx);
8233
+ } catch (err) {
8234
+ const mod = await compileTsx(errorPath);
8235
+ const ErrorComponent = mod.default;
8236
+ if (!ErrorComponent) throw err;
8237
+ const layouts = (ctx.layoutStack || []).map((l) => l.component);
8238
+ const stream = await import("react-dom/server").then((m) => m.renderToReadableStream(
8239
+ createElement2(ErrorComponent, {
8240
+ error: err instanceof Error ? err : new Error(String(err)),
8241
+ reset: () => {
8242
+ }
8243
+ })
8244
+ ));
8245
+ const reader = stream.getReader();
8246
+ const chunks = [];
8247
+ while (true) {
8248
+ const { done, value } = await reader.read();
8249
+ if (done) break;
8250
+ chunks.push(value);
8251
+ }
8252
+ const encoder2 = new TextEncoder3();
8253
+ const body = chunks.reduce((acc, c) => {
8254
+ const merged = new Uint8Array(acc.length + c.length);
8255
+ merged.set(acc);
8256
+ merged.set(c, acc.length);
8257
+ return merged;
8258
+ }, new Uint8Array(0));
8259
+ return new Response(body, {
8260
+ status: 500,
8261
+ headers: { "content-type": "text/html; charset=utf-8" }
8262
+ });
8263
+ }
8264
+ };
8265
+ }
8122
8266
  export {
8123
8267
  Router,
8124
8268
  TsxContext,
@@ -8126,6 +8270,7 @@ export {
8126
8270
  aiStream,
8127
8271
  analytics,
8128
8272
  auth,
8273
+ clearCompileCache,
8129
8274
  compress,
8130
8275
  cors,
8131
8276
  createHub,
@@ -8139,6 +8284,7 @@ export {
8139
8284
  deploy,
8140
8285
  embed,
8141
8286
  embedMany,
8287
+ errorBoundary,
8142
8288
  formatSSE,
8143
8289
  formatSSEData,
8144
8290
  generateObject,
@@ -8148,11 +8294,14 @@ export {
8148
8294
  health,
8149
8295
  helmet,
8150
8296
  iii,
8297
+ layout,
8298
+ liveReload,
8151
8299
  loadEnv,
8152
8300
  logdb,
8153
8301
  logger,
8154
8302
  mailer,
8155
8303
  messager,
8304
+ notFound,
8156
8305
  openai,
8157
8306
  opencode,
8158
8307
  postgres,
@@ -8170,8 +8319,10 @@ export {
8170
8319
  serveStatic,
8171
8320
  setCookie,
8172
8321
  smoothStream,
8322
+ ssr,
8173
8323
  streamObject,
8174
8324
  streamText,
8325
+ tailwind,
8175
8326
  tenant,
8176
8327
  tool2 as tool,
8177
8328
  upload,
@@ -0,0 +1,2 @@
1
+ import type { Middleware } from './types.ts';
2
+ export declare function layout(path: string): Middleware;
package/dist/live.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { Router } from './router.ts';
2
+ export declare function liveReload(opts: {
3
+ dirs: string[];
4
+ }): Router & {
5
+ close: () => void;
6
+ };
@@ -0,0 +1,2 @@
1
+ import type { Handler } from './types.ts';
2
+ export declare function notFound(path?: string): Handler;
package/dist/ssr.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { Router } from './router.ts';
2
+ export declare function ssr(path: string): Router;
@@ -0,0 +1,14 @@
1
+ import type { Context } from './types.ts';
2
+ export interface StreamOpts {
3
+ ctx: Context;
4
+ base: string;
5
+ compiledTailwindCss?: string;
6
+ isDev: boolean;
7
+ status?: number;
8
+ bundle?: {
9
+ url: string;
10
+ } | null;
11
+ loaderData?: Record<string, unknown>;
12
+ }
13
+ export declare function readStream(stream: ReadableStream): Promise<string>;
14
+ export declare function streamResponse(reactStream: ReadableStream, opts: StreamOpts): Response;
@@ -0,0 +1,2 @@
1
+ import type { Middleware } from './types.ts';
2
+ export declare function tailwind(cssPath: string, scanDir?: string): Middleware;
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "weifuwu",
3
- "version": "0.18.3",
3
+ "version": "0.18.4",
4
4
  "description": "Web-standard HTTP framework for Node.js — (req, ctx) => Response",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "exports": {
8
8
  ".": "./dist/index.js",
9
- "./react": "./dist/react.js",
10
- "./ssr": "./dist/ssr/index.js"
9
+ "./react": "./dist/react.js"
11
10
  },
12
11
  "bin": {
13
12
  "weifuwu": "dist/cli.js"
@@ -19,7 +18,7 @@
19
18
  "LICENSE"
20
19
  ],
21
20
  "scripts": {
22
- "build": "esbuild index.ts --bundle --format=esm --platform=node --outfile=dist/index.js --packages=external && esbuild cli.ts --bundle --format=esm --platform=node --outfile=dist/cli.js --packages=external && esbuild react.ts --bundle --format=esm --outfile=dist/react.js --external:react --external:react-dom && esbuild ssr/index.ts --bundle --format=esm --platform=node --outfile=dist/ssr/index.js --packages=external",
21
+ "build": "esbuild index.ts --bundle --format=esm --platform=node --outfile=dist/index.js --packages=external && esbuild cli.ts --bundle --format=esm --platform=node --outfile=dist/cli.js --packages=external && esbuild react.ts --bundle --format=esm --outfile=dist/react.js --external:react --external:react-dom",
23
22
  "prepublishOnly": "npm run build && tsc --emitDeclarationOnly --outdir dist",
24
23
  "test": "node --test 'test/**/*.test.ts'"
25
24
  },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes