weifuwu 0.17.1 → 0.17.3
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/README.md +6 -1
- package/dist/index.js +44 -17
- package/dist/react.js +13 -12
- package/dist/tsx-context.d.ts +1 -0
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1173,11 +1173,13 @@ app.use(preferences({
|
|
|
1173
1173
|
}))
|
|
1174
1174
|
|
|
1175
1175
|
// In handlers: ctx.t('greeting') → "Hello"
|
|
1176
|
+
// ctx.t('tools.uppercase.title') → "Uppercase" (nested key)
|
|
1176
1177
|
// ctx.locale → "en"
|
|
1177
1178
|
// ctx.theme → "light"
|
|
1178
1179
|
// ctx.prefs → { locale: 'en', theme: 'light' }
|
|
1179
1180
|
// ctx.setPref('locale', 'zh') → 302 + cookie
|
|
1180
1181
|
// ctx.setPref('flash', '{"type":"success","message":"Done"}') → flash message
|
|
1182
|
+
// ctx.env → { WEIFUWU_PUBLIC_API_URL: '...' } (public env vars)
|
|
1181
1183
|
|
|
1182
1184
|
// In tsx components:
|
|
1183
1185
|
const { t, locale, theme } = useCtx()
|
|
@@ -1187,6 +1189,9 @@ Locale detection priority: cookie → `Accept-Language` → default.
|
|
|
1187
1189
|
Theme detection: cookie → default (`'system'`).
|
|
1188
1190
|
Flash messages: set via `ctx.setPref('flash', ...)` → auto-read from cookie → cleared after rendering.
|
|
1189
1191
|
|
|
1192
|
+
`ctx.t()` supports dot-path nested keys: `t('tools.uppercase.title')` traverses the JSON structure.
|
|
1193
|
+
`ctx.env` exposes `WEIFUWU_PUBLIC_*` environment variables on both server and client (via `useCtx().env`).
|
|
1194
|
+
|
|
1190
1195
|
---
|
|
1191
1196
|
|
|
1192
1197
|
## Email
|
|
@@ -1234,7 +1239,7 @@ app.get('/stream', (req, ctx) => createSSEStream(events()))
|
|
|
1234
1239
|
|
|
1235
1240
|
| Hook / Component | Description |
|
|
1236
1241
|
|-----------------|-------------|
|
|
1237
|
-
| `useCtx()` | Unified context — `{ prefs, locale, theme, t, params, query }` (requires `preferences` middleware) |
|
|
1242
|
+
| `useCtx()` | Unified context — `{ prefs, locale, theme, t, params, query, env }` (requires `preferences` middleware) |
|
|
1238
1243
|
| `createStore(initial)` | Zustand-compatible shared state — `getState`, `setState`, `subscribe` |
|
|
1239
1244
|
| `useData(url, opts?)` | SWR-style data fetching — cache, dedup, mutate, fallback |
|
|
1240
1245
|
| `useQueryState(key, default)` | URL query param sync — `?page=1` via `useSyncExternalStore` |
|
package/dist/index.js
CHANGED
|
@@ -581,19 +581,20 @@ import chokidar from "chokidar";
|
|
|
581
581
|
import { createContext, useContext } from "react";
|
|
582
582
|
var TsxContext = createContext({ params: {}, query: {} });
|
|
583
583
|
function useCtx() {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
};
|
|
594
|
-
|
|
595
|
-
|
|
584
|
+
const wc = typeof window !== "undefined" ? window.__WEIFUWU_CTX : globalThis.__WEIFUWU_CTX;
|
|
585
|
+
if (wc) {
|
|
586
|
+
const messages2 = typeof window !== "undefined" ? window.__LOCALE_DATA__ : globalThis.__LOCALE_DATA__;
|
|
587
|
+
if (messages2 && typeof wc.t !== "function") {
|
|
588
|
+
wc.t = (key, params) => {
|
|
589
|
+
const msg = key.split(".").reduce((o, k) => o?.[k], messages2);
|
|
590
|
+
if (msg === void 0 || msg === null) return key;
|
|
591
|
+
if (!params) return String(msg);
|
|
592
|
+
let result = String(msg);
|
|
593
|
+
for (const [k, v] of Object.entries(params)) result = result.replace(`{${k}}`, v);
|
|
594
|
+
return result;
|
|
595
|
+
};
|
|
596
596
|
}
|
|
597
|
+
return wc;
|
|
597
598
|
}
|
|
598
599
|
return useContext(TsxContext);
|
|
599
600
|
}
|
|
@@ -889,7 +890,8 @@ var TsxInstance = class {
|
|
|
889
890
|
prefs: ctx.prefs,
|
|
890
891
|
locale: ctx.locale,
|
|
891
892
|
theme: ctx.theme,
|
|
892
|
-
t: ctx.t
|
|
893
|
+
t: ctx.t,
|
|
894
|
+
env: ctx.env
|
|
893
895
|
}
|
|
894
896
|
}, createElement(NfComponent, { params: ctx.params, query: ctx.query }));
|
|
895
897
|
for (let i = rootLayouts.length - 1; i >= 0; i--) {
|
|
@@ -897,6 +899,7 @@ var TsxInstance = class {
|
|
|
897
899
|
if (!LMod) continue;
|
|
898
900
|
element = createElement(LMod.default, { children: element });
|
|
899
901
|
}
|
|
902
|
+
setGlobalCtx(ctx);
|
|
900
903
|
const stream = await renderToReadableStream(element);
|
|
901
904
|
return streamResponse(stream, {
|
|
902
905
|
ctx,
|
|
@@ -1063,7 +1066,8 @@ ${src}`;
|
|
|
1063
1066
|
prefs: ctx.prefs,
|
|
1064
1067
|
locale: ctx.locale,
|
|
1065
1068
|
theme: ctx.theme,
|
|
1066
|
-
t: ctx.t
|
|
1069
|
+
t: ctx.t,
|
|
1070
|
+
env: ctx.env
|
|
1067
1071
|
}
|
|
1068
1072
|
}, createElement(Component, allProps))
|
|
1069
1073
|
);
|
|
@@ -1094,6 +1098,7 @@ ${src}`;
|
|
|
1094
1098
|
}
|
|
1095
1099
|
}
|
|
1096
1100
|
const bundle = await this.getOrBuildClientBundle(entryPath, layoutPaths, this.pagesDir);
|
|
1101
|
+
setGlobalCtx(ctx);
|
|
1097
1102
|
const stream = await renderToReadableStream(element);
|
|
1098
1103
|
return streamResponse(stream, {
|
|
1099
1104
|
ctx,
|
|
@@ -1267,6 +1272,18 @@ ${src}`;
|
|
|
1267
1272
|
}
|
|
1268
1273
|
}
|
|
1269
1274
|
};
|
|
1275
|
+
function setGlobalCtx(ctx) {
|
|
1276
|
+
;
|
|
1277
|
+
globalThis.__WEIFUWU_CTX = {
|
|
1278
|
+
params: ctx.params,
|
|
1279
|
+
query: ctx.query,
|
|
1280
|
+
user: ctx.user,
|
|
1281
|
+
parsed: ctx.parsed,
|
|
1282
|
+
prefs: ctx.prefs,
|
|
1283
|
+
locale: ctx.locale,
|
|
1284
|
+
theme: ctx.theme
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1270
1287
|
function streamResponse(reactStream, opts) {
|
|
1271
1288
|
const decoder = new TextDecoder();
|
|
1272
1289
|
const encoder2 = new TextEncoder();
|
|
@@ -1349,6 +1366,15 @@ function buildHeadPayload(opts) {
|
|
|
1349
1366
|
if (ctx.prefs) ctxData.prefs = ctx.prefs;
|
|
1350
1367
|
if (ctx.locale) ctxData.locale = ctx.locale;
|
|
1351
1368
|
if (ctx.theme) ctxData.theme = ctx.theme;
|
|
1369
|
+
const publicEnv = {};
|
|
1370
|
+
for (const key of Object.keys(process.env)) {
|
|
1371
|
+
if (key.startsWith("WEIFUWU_PUBLIC_")) {
|
|
1372
|
+
publicEnv[key] = process.env[key];
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
if (Object.keys(publicEnv).length > 0) {
|
|
1376
|
+
ctxData.env = publicEnv;
|
|
1377
|
+
}
|
|
1352
1378
|
result += `<script>window.__WEIFUWU_CTX=${JSON.stringify(ctxData)}</script>
|
|
1353
1379
|
`;
|
|
1354
1380
|
return result;
|
|
@@ -6780,9 +6806,10 @@ var defaults = {
|
|
|
6780
6806
|
theme: { default: "system", cookie: "theme" }
|
|
6781
6807
|
};
|
|
6782
6808
|
function translate(msgs, key, params) {
|
|
6783
|
-
const msg =
|
|
6784
|
-
if (
|
|
6785
|
-
|
|
6809
|
+
const msg = key.split(".").reduce((o, k) => o?.[k], msgs);
|
|
6810
|
+
if (msg === void 0 || msg === null) return key;
|
|
6811
|
+
if (!params) return String(msg);
|
|
6812
|
+
let result = String(msg);
|
|
6786
6813
|
for (const [k, v] of Object.entries(params)) {
|
|
6787
6814
|
result = result.replace(`{${k}}`, v);
|
|
6788
6815
|
}
|
package/dist/react.js
CHANGED
|
@@ -319,19 +319,20 @@ async function prefetchPage(href) {
|
|
|
319
319
|
import { createContext, useContext } from "react";
|
|
320
320
|
var TsxContext = createContext({ params: {}, query: {} });
|
|
321
321
|
function useCtx() {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
|
|
322
|
+
const wc = typeof window !== "undefined" ? window.__WEIFUWU_CTX : globalThis.__WEIFUWU_CTX;
|
|
323
|
+
if (wc) {
|
|
324
|
+
const messages = typeof window !== "undefined" ? window.__LOCALE_DATA__ : globalThis.__LOCALE_DATA__;
|
|
325
|
+
if (messages && typeof wc.t !== "function") {
|
|
326
|
+
wc.t = (key, params) => {
|
|
327
|
+
const msg = key.split(".").reduce((o, k) => o?.[k], messages);
|
|
328
|
+
if (msg === void 0 || msg === null) return key;
|
|
329
|
+
if (!params) return String(msg);
|
|
330
|
+
let result = String(msg);
|
|
331
|
+
for (const [k, v] of Object.entries(params)) result = result.replace(`{${k}}`, v);
|
|
332
|
+
return result;
|
|
333
|
+
};
|
|
334
334
|
}
|
|
335
|
+
return wc;
|
|
335
336
|
}
|
|
336
337
|
return useContext(TsxContext);
|
|
337
338
|
}
|
package/dist/tsx-context.d.ts
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export interface Context {
|
|
|
10
10
|
prefs?: Record<string, string>;
|
|
11
11
|
theme?: string;
|
|
12
12
|
setPref?: (name: string, value: string) => Response;
|
|
13
|
+
env?: Record<string, string>;
|
|
13
14
|
}
|
|
14
15
|
export type Handler = (req: Request, ctx: Context) => Response | Promise<Response>;
|
|
15
16
|
export type Middleware = (req: Request, ctx: Context, next: Handler) => Response | Promise<Response>;
|