weifuwu 0.17.2 → 0.17.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.
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ 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
- export { tsx, TsxContext, useCtx } from './tsx.ts';
7
+ export { tsx, TsxContext, useCtx, setCtx } from './tsx.ts';
8
8
  export type { TsxOptions } from './tsx.ts';
9
9
  export { auth, cors, logger } from './middleware.ts';
10
10
  export type { AuthOptions, CORSOptions, LoggerOptions } from './middleware.ts';
package/dist/index.js CHANGED
@@ -578,25 +578,43 @@ import { createRequire } from "node:module";
578
578
  import chokidar from "chokidar";
579
579
 
580
580
  // tsx-context.ts
581
- import { createContext, useContext } from "react";
582
- var TsxContext = createContext({ params: {}, query: {} });
581
+ import { useSyncExternalStore, createContext } from "react";
582
+ var _ctx = { params: {}, query: {} };
583
+ var _listeners = /* @__PURE__ */ new Set();
584
+ function setCtx(value) {
585
+ _ctx = { ..._ctx, ...value };
586
+ _listeners.forEach((fn) => fn());
587
+ }
588
+ function _buildT() {
589
+ const messages2 = typeof window !== "undefined" ? window.__LOCALE_DATA__ : globalThis.__LOCALE_DATA__;
590
+ if (!messages2) return void 0;
591
+ return (key, params, fallback) => {
592
+ const msg = key.split(".").reduce((o, k) => o?.[k], messages2);
593
+ if (msg === void 0 || msg === null) return fallback ?? key;
594
+ if (!params) return String(msg);
595
+ let result = String(msg);
596
+ for (const [k, v] of Object.entries(params)) result = result.replace(`{${k}}`, v);
597
+ return result;
598
+ };
599
+ }
583
600
  function useCtx() {
584
- if (typeof window !== "undefined") {
585
- const wc = window.__WEIFUWU_CTX;
586
- if (wc) {
587
- const messages2 = window.__LOCALE_DATA__;
588
- if (messages2 && !wc.t) {
589
- wc.t = (key, params) => {
590
- let msg = messages2[key] ?? key;
591
- if (params) for (const [k, v] of Object.entries(params)) msg = msg.replace(`{${k}}`, v);
592
- return msg;
593
- };
594
- }
595
- return wc;
596
- }
597
- }
598
- return useContext(TsxContext);
601
+ useSyncExternalStore(
602
+ (cb) => {
603
+ _listeners.add(cb);
604
+ return () => {
605
+ _listeners.delete(cb);
606
+ };
607
+ },
608
+ () => _ctx,
609
+ () => _ctx
610
+ );
611
+ const data = typeof window !== "undefined" ? window.__WEIFUWU_CTX : null;
612
+ const t = data?.t ?? _ctx.t ?? _buildT();
613
+ const result = { ..._ctx, ...data };
614
+ if (t) result.t = t;
615
+ return result;
599
616
  }
617
+ var TsxContext = createContext({ params: {}, query: {} });
600
618
 
601
619
  // tsx-instance.ts
602
620
  var liveReloadClients = /* @__PURE__ */ new Set();
@@ -880,19 +898,18 @@ var TsxInstance = class {
880
898
  const nfMod = this.pageModules.get(nfPath);
881
899
  if (!nfMod) return new Response("Not Found", { status: 404 });
882
900
  const NfComponent = nfMod.default;
883
- let element = createElement(TsxContext.Provider, {
884
- value: {
885
- params: ctx.params,
886
- query: ctx.query,
887
- user: ctx.user,
888
- parsed: ctx.parsed,
889
- prefs: ctx.prefs,
890
- locale: ctx.locale,
891
- theme: ctx.theme,
892
- t: ctx.t,
893
- env: ctx.env
894
- }
895
- }, createElement(NfComponent, { params: ctx.params, query: ctx.query }));
901
+ setCtx({
902
+ params: ctx.params,
903
+ query: ctx.query,
904
+ user: ctx.user,
905
+ parsed: ctx.parsed,
906
+ prefs: ctx.prefs,
907
+ locale: ctx.locale,
908
+ theme: ctx.theme,
909
+ t: ctx.t,
910
+ env: ctx.env
911
+ });
912
+ let element = createElement(NfComponent, { params: ctx.params, query: ctx.query });
896
913
  for (let i = rootLayouts.length - 1; i >= 0; i--) {
897
914
  const LMod = this.layoutModules.get(rootLayouts[i]);
898
915
  if (!LMod) continue;
@@ -1052,22 +1069,21 @@ ${src}`;
1052
1069
  const loadFn = loadMod?.default;
1053
1070
  const loadProps = loadFn ? await loadFn({ params: ctx.params, query: ctx.query }) : {};
1054
1071
  const allProps = { ...loadProps, params: ctx.params, query: ctx.query };
1072
+ setCtx({
1073
+ params: ctx.params,
1074
+ query: ctx.query,
1075
+ user: ctx.user,
1076
+ parsed: ctx.parsed,
1077
+ prefs: ctx.prefs,
1078
+ locale: ctx.locale,
1079
+ theme: ctx.theme,
1080
+ t: ctx.t,
1081
+ env: ctx.env
1082
+ });
1055
1083
  let element = createElement(
1056
1084
  "div",
1057
1085
  { id: "__weifuwu_root" },
1058
- createElement(TsxContext.Provider, {
1059
- value: {
1060
- params: ctx.params,
1061
- query: ctx.query,
1062
- user: ctx.user,
1063
- parsed: ctx.parsed,
1064
- prefs: ctx.prefs,
1065
- locale: ctx.locale,
1066
- theme: ctx.theme,
1067
- t: ctx.t,
1068
- env: ctx.env
1069
- }
1070
- }, createElement(Component, allProps))
1086
+ createElement(Component, allProps)
1071
1087
  );
1072
1088
  if (layoutPaths.length === 0) {
1073
1089
  element = createElement(
@@ -1091,7 +1107,7 @@ ${src}`;
1091
1107
  const isRoot = i === 0;
1092
1108
  element = createElement(
1093
1109
  Layout,
1094
- isRoot ? { children: element, req, ctx } : { children: element }
1110
+ isRoot ? { children: element, req } : { children: element }
1095
1111
  );
1096
1112
  }
1097
1113
  }
@@ -3193,7 +3209,7 @@ h2{color:#dc2626}.desc{color:#555}</style>
3193
3209
  <body><h2>${error}</h2>${description ? `<p class="desc">${description}</p>` : ""}</body>
3194
3210
  </html>`, { status: 400, headers: { "Content-Type": "text/html; charset=utf-8" } });
3195
3211
  }
3196
- async function authorizeHandler(req, _ctx) {
3212
+ async function authorizeHandler(req, _ctx2) {
3197
3213
  const url = new URL(req.url);
3198
3214
  const clientId = url.searchParams.get("client_id") || "";
3199
3215
  const redirectUri = url.searchParams.get("redirect_uri") || "";
@@ -4578,23 +4594,23 @@ function buildGraphQLHandler(sql2) {
4578
4594
  });
4579
4595
  return Response.json(result, { status: result.errors ? 400 : 200 });
4580
4596
  });
4581
- r.get("/", async (req, _ctx) => {
4597
+ r.get("/", async (req, _ctx2) => {
4582
4598
  const url = new URL(req.url);
4583
4599
  if (url.searchParams.has("query")) {
4584
- return handleGET(req, _ctx);
4600
+ return handleGET(req, _ctx2);
4585
4601
  }
4586
4602
  return new Response("GraphQL endpoint. Send POST /graphql with { query, variables }", {
4587
4603
  status: 200,
4588
4604
  headers: { "Content-Type": "text/plain" }
4589
4605
  });
4590
4606
  });
4591
- async function handleGET(req, _ctx) {
4607
+ async function handleGET(req, _ctx2) {
4592
4608
  const tables = await sql2`
4593
4609
  SELECT * FROM "_user_tables"
4594
- WHERE tenant_id = ${_ctx.tenant.id}
4610
+ WHERE tenant_id = ${_ctx2.tenant.id}
4595
4611
  ORDER BY created_at ASC
4596
4612
  `;
4597
- const buildCtx = { sql: sql2, tenantId: _ctx.tenant.id, tables };
4613
+ const buildCtx = { sql: sql2, tenantId: _ctx2.tenant.id, tables };
4598
4614
  const schema = new GraphQLSchema({
4599
4615
  query: new GraphQLObjectType({
4600
4616
  name: "Query",
@@ -4614,7 +4630,7 @@ function buildGraphQLHandler(sql2) {
4614
4630
  source: query,
4615
4631
  variableValues: variables,
4616
4632
  operationName: url.searchParams.get("operationName") || void 0,
4617
- contextValue: _ctx
4633
+ contextValue: _ctx2
4618
4634
  });
4619
4635
  return Response.json(result, { status: result.errors ? 400 : 200 });
4620
4636
  }
@@ -6618,7 +6634,7 @@ function createWSHandler2(deps) {
6618
6634
  clients.delete(ws);
6619
6635
  }
6620
6636
  },
6621
- error(ws, _ctx, _err) {
6637
+ error(ws, _ctx2, _err) {
6622
6638
  const client = clients.get(ws);
6623
6639
  if (client) {
6624
6640
  client.abortController?.abort();
@@ -6790,9 +6806,9 @@ var defaults = {
6790
6806
  locale: { default: "en", cookie: "locale", fromAcceptLanguage: true },
6791
6807
  theme: { default: "system", cookie: "theme" }
6792
6808
  };
6793
- function translate(msgs, key, params) {
6809
+ function translate(msgs, key, params, fallback) {
6794
6810
  const msg = key.split(".").reduce((o, k) => o?.[k], msgs);
6795
- if (msg === void 0 || msg === null) return key;
6811
+ if (msg === void 0 || msg === null) return fallback ?? key;
6796
6812
  if (!params) return String(msg);
6797
6813
  let result = String(msg);
6798
6814
  for (const [k, v] of Object.entries(params)) {
@@ -6837,7 +6853,7 @@ function preferences(options) {
6837
6853
  ctx.theme = theme;
6838
6854
  if (dir) {
6839
6855
  const msgs = await load(locale);
6840
- ctx.t = (key, params) => translate(msgs, key, params);
6856
+ ctx.t = (key, params, fallback) => translate(msgs, key, params, fallback);
6841
6857
  globalThis.__LOCALE_DATA__ = msgs;
6842
6858
  }
6843
6859
  ctx.setPref = (name, value) => {
@@ -7644,7 +7660,7 @@ function createWsHandler(deps) {
7644
7660
  return wsToWorkerId.get(ws) || "";
7645
7661
  }
7646
7662
  return {
7647
- open(_ws, _ctx) {
7663
+ open(_ws, _ctx2) {
7648
7664
  },
7649
7665
  async message(ws, ctx, data) {
7650
7666
  let msg;
@@ -8300,6 +8316,7 @@ export {
8300
8316
  serve,
8301
8317
  serveStatic,
8302
8318
  setCookie,
8319
+ setCtx,
8303
8320
  smoothStream,
8304
8321
  streamObject,
8305
8322
  streamText,
package/dist/react.d.ts CHANGED
@@ -3,7 +3,7 @@ export type { UseWebsocketOptions, UseWebsocketReturn } from './use-websocket.ts
3
3
  export { useAction } from './use-action.ts';
4
4
  export type { UseActionOptions, UseActionReturn } from './use-action.ts';
5
5
  export { Link, useNavigate, navigate, useNavigating } from './client-router.ts';
6
- export { TsxContext, useCtx } from './tsx-context.ts';
6
+ export { TsxContext, useCtx, setCtx } from './tsx-context.ts';
7
7
  export { Head } from './head.tsx';
8
8
  export { createStore, useData, useQueryState } from './client-state.ts';
9
9
  export type { StoreApi } from './client-state.ts';
package/dist/react.js CHANGED
@@ -316,25 +316,43 @@ async function prefetchPage(href) {
316
316
  }
317
317
 
318
318
  // tsx-context.ts
319
- import { createContext, useContext } from "react";
320
- var TsxContext = createContext({ params: {}, query: {} });
319
+ import { useSyncExternalStore, createContext } from "react";
320
+ var _ctx = { params: {}, query: {} };
321
+ var _listeners2 = /* @__PURE__ */ new Set();
322
+ function setCtx(value) {
323
+ _ctx = { ..._ctx, ...value };
324
+ _listeners2.forEach((fn) => fn());
325
+ }
326
+ function _buildT() {
327
+ const messages = typeof window !== "undefined" ? window.__LOCALE_DATA__ : globalThis.__LOCALE_DATA__;
328
+ if (!messages) return void 0;
329
+ return (key, params, fallback) => {
330
+ const msg = key.split(".").reduce((o, k) => o?.[k], messages);
331
+ if (msg === void 0 || msg === null) return fallback ?? key;
332
+ if (!params) return String(msg);
333
+ let result = String(msg);
334
+ for (const [k, v] of Object.entries(params)) result = result.replace(`{${k}}`, v);
335
+ return result;
336
+ };
337
+ }
321
338
  function useCtx() {
322
- if (typeof window !== "undefined") {
323
- const wc = window.__WEIFUWU_CTX;
324
- if (wc) {
325
- const messages = window.__LOCALE_DATA__;
326
- if (messages && !wc.t) {
327
- wc.t = (key, params) => {
328
- let msg = messages[key] ?? key;
329
- if (params) for (const [k, v] of Object.entries(params)) msg = msg.replace(`{${k}}`, v);
330
- return msg;
331
- };
332
- }
333
- return wc;
334
- }
335
- }
336
- return useContext(TsxContext);
339
+ useSyncExternalStore(
340
+ (cb) => {
341
+ _listeners2.add(cb);
342
+ return () => {
343
+ _listeners2.delete(cb);
344
+ };
345
+ },
346
+ () => _ctx,
347
+ () => _ctx
348
+ );
349
+ const data = typeof window !== "undefined" ? window.__WEIFUWU_CTX : null;
350
+ const t = data?.t ?? _ctx.t ?? _buildT();
351
+ const result = { ..._ctx, ...data };
352
+ if (t) result.t = t;
353
+ return result;
337
354
  }
355
+ var TsxContext = createContext({ params: {}, query: {} });
338
356
 
339
357
  // head.tsx
340
358
  import { createElement as createElement2 } from "react";
@@ -343,7 +361,7 @@ function Head({ children }) {
343
361
  }
344
362
 
345
363
  // client-state.ts
346
- import { useSyncExternalStore, useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
364
+ import { useSyncExternalStore as useSyncExternalStore2, useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
347
365
  function createStore(initial) {
348
366
  let state = { ...initial };
349
367
  const listeners = /* @__PURE__ */ new Set();
@@ -359,7 +377,7 @@ function createStore(initial) {
359
377
  listeners.delete(listener);
360
378
  };
361
379
  };
362
- const useStore = ((selector) => useSyncExternalStore(
380
+ const useStore = ((selector) => useSyncExternalStore2(
363
381
  subscribe,
364
382
  () => selector ? selector(state) : state
365
383
  ));
@@ -450,7 +468,7 @@ function useQueryState(key, defaultValue = "") {
450
468
  const params = new URLSearchParams(window.location.search);
451
469
  return params.get(key) ?? defaultValue;
452
470
  }
453
- const value = useSyncExternalStore(
471
+ const value = useSyncExternalStore2(
454
472
  (cb) => {
455
473
  if (typeof window === "undefined") return () => {
456
474
  };
@@ -480,6 +498,7 @@ export {
480
498
  TsxContext,
481
499
  createStore,
482
500
  navigate,
501
+ setCtx,
483
502
  useAction,
484
503
  useCtx,
485
504
  useData,
@@ -1,4 +1,4 @@
1
- export declare const TsxContext: import("react").Context<{
1
+ export interface CtxValue {
2
2
  params: Record<string, string>;
3
3
  query: Record<string, string>;
4
4
  user?: unknown;
@@ -6,7 +6,9 @@ export declare const TsxContext: import("react").Context<{
6
6
  prefs?: Record<string, string>;
7
7
  locale?: string;
8
8
  theme?: string;
9
- t?: (key: string, params?: Record<string, string>) => string;
9
+ t?: (key: string, params?: Record<string, string>, fallback?: string) => string;
10
10
  env?: Record<string, string>;
11
- }>;
12
- export declare function useCtx(): any;
11
+ }
12
+ export declare function setCtx(value: Partial<CtxValue>): void;
13
+ export declare function useCtx(): CtxValue;
14
+ export declare const TsxContext: import("react").Context<CtxValue>;
@@ -1,6 +1,6 @@
1
1
  import { Router } from './router.ts';
2
- import { TsxContext, useCtx } from './tsx-context.ts';
3
- export { TsxContext, useCtx };
2
+ import { TsxContext, useCtx, setCtx } from './tsx-context.ts';
3
+ export { TsxContext, useCtx, setCtx };
4
4
  export interface TsxOptions {
5
5
  dir: string;
6
6
  }
package/dist/tsx.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { TsxContext, useCtx } from './tsx-instance.ts';
1
+ import { TsxContext, useCtx, setCtx } from './tsx-instance.ts';
2
2
  import type { TsxOptions } from './tsx-instance.ts';
3
3
  import type { Router } from './router.ts';
4
- export { TsxContext, useCtx };
4
+ export { TsxContext, useCtx, setCtx };
5
5
  export type { TsxOptions };
6
6
  export declare function tsx(options: TsxOptions): Promise<Router>;
package/dist/types.d.ts CHANGED
@@ -5,7 +5,7 @@ export interface Context {
5
5
  parsed?: Record<string, unknown>;
6
6
  mountPath?: string;
7
7
  locale?: string;
8
- t?: (key: string, params?: Record<string, string>) => string;
8
+ t?: (key: string, params?: Record<string, string>, fallback?: string) => string;
9
9
  requestId?: string;
10
10
  prefs?: Record<string, string>;
11
11
  theme?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "weifuwu",
3
- "version": "0.17.2",
3
+ "version": "0.17.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",