@_tc/template-core 0.3.1 → 0.3.2
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/AGENT_README.md +1 -1
- package/CHANGE.md +1 -0
- package/README.md +2 -2
- package/cjs/packages/common/index.js +1 -1
- package/cjs/packages/common/ssr/hydration.js +1 -1
- package/cjs/packages/common/ssr/index.js +1 -1
- package/esm/packages/common/index.js +4 -4
- package/esm/packages/common/ssr/hydration.js +1 -1
- package/esm/packages/common/ssr/index.js +13 -13
- package/fe/frontend/src/components/AsyncSelect/AsyncSelect.d.ts +1 -1
- package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/PopFrom.js +3 -2
- package/fe/packages/common/index.js +2 -2
- package/fe/packages/common/ssr/hydration.d.ts +2 -0
- package/fe/packages/common/ssr/hydration.js +1 -1
- package/fe/packages/common/ssr/index.js +2 -2
- package/fe/ssr/components/StreamingRender/StreamingRender.js +2 -2
- package/fe/ssr/components/StreamingRender/StreamingScript.js +9 -3
- package/models/frontend/src/components/AsyncSelect/AsyncSelect.d.ts +1 -1
- package/models/packages/common/ssr/hydration.d.ts +2 -0
- package/package.json +1 -1
- package/types/packages/common/ssr/hydration.d.ts +2 -0
package/AGENT_README.md
CHANGED
|
@@ -538,7 +538,7 @@ await buildSSR({ baseDir, output: 'run' })
|
|
|
538
538
|
await watchSSRFiles({ baseDir, output: 'run' })
|
|
539
539
|
```
|
|
540
540
|
|
|
541
|
-
SSR 入口约定为 `ssr/apps/{page}/{page}.entry.tsx`,客户端 hydration 工厂从 `@_tc/template-core/ssr/createSSREntry` 引入。页面可导出静态字符串或函数式 `pageTitle` / `pageDescription`,函数会在 `getServerProps()` 后执行,入参包含 `params`、`query`、`path`、`app`、`ctx` 和 `props`。组件级流式异步数据用 `@_tc/template-core/ssr/components` 的 `StreamingRender`;底层 Suspense Promise hook 从 `@_tc/template-core/ssr/hooks` 引入。`buildSSR()` 会输出私有 `{ssrPrivateRoot}/ssr-server/{page}.mjs`、私有 `{ssrPrivateRoot}/ssr-manifest/manifest.json`,SSR hydration 入口并入 FE browser build,页面默认通过 `/fessr/:page` 访问,浏览器静态资源走普通 `/dist/assets/*`;`/dist/ssr-server/*` 和 `/dist/.vite/*` 会被拦截为 404。成功 SSR 会用 React streaming bootstrap 动态 import 客户端入口,带 `Suspense` 边界的 shell 可以先启动 hydration,pending 内容继续 stream。入口文件会被 server/client 两次构建,顶层代码必须同时兼容 Node 和浏览器。`getServerProps()` 运行在 Node 侧,不要直接复用依赖 `window` / `localStorage` 的前端 API 层;服务端请求逻辑拆到 `*.server.ts` 并在 `getServerProps()` 内动态导入。`StreamingRender` 的 `getData()`
|
|
541
|
+
SSR 入口约定为 `ssr/apps/{page}/{page}.entry.tsx`,客户端 hydration 工厂从 `@_tc/template-core/ssr/createSSREntry` 引入。页面可导出静态字符串或函数式 `pageTitle` / `pageDescription`,函数会在 `getServerProps()` 后执行,入参包含 `params`、`query`、`path`、`app`、`ctx` 和 `props`。组件级流式异步数据用 `@_tc/template-core/ssr/components` 的 `StreamingRender`;底层 Suspense Promise hook 从 `@_tc/template-core/ssr/hooks` 引入。`buildSSR()` 会输出私有 `{ssrPrivateRoot}/ssr-server/{page}.mjs`、私有 `{ssrPrivateRoot}/ssr-manifest/manifest.json`,SSR hydration 入口并入 FE browser build,页面默认通过 `/fessr/:page` 访问,浏览器静态资源走普通 `/dist/assets/*`;`/dist/ssr-server/*` 和 `/dist/.vite/*` 会被拦截为 404。成功 SSR 会用 React streaming bootstrap 动态 import 客户端入口,带 `Suspense` 边界的 shell 可以先启动 hydration,pending 内容继续 stream。入口文件会被 server/client 两次构建,顶层代码必须同时兼容 Node 和浏览器。`getServerProps()` 运行在 Node 侧,不要直接复用依赖 `window` / `localStorage` 的前端 API 层;服务端请求逻辑拆到 `*.server.ts` 并在 `getServerProps()` 内动态导入。`StreamingRender` 的 `getData()` 返回值会 JSON 序列化后以 base64 写入 HTML;base64 可逆,不等于加密,不能包含 token、密钥等敏感信息;客户端找不到注入数据时也可能执行 `getData()`,需要兼容浏览器 fallback。
|
|
542
542
|
|
|
543
543
|
Node/backend 构建:
|
|
544
544
|
|
package/CHANGE.md
CHANGED
|
@@ -13,6 +13,7 @@ TemplateCore v0.3 的首个版本,核心是正式引入 SSR V1。这个版本
|
|
|
13
13
|
- SSR / CSR HTML shell 会注入 `window._renderMode` 和 `window._isSSR`,Dash 共用路由守卫可按渲染模式分别处理跳转。
|
|
14
14
|
- 新增 SSR document shell 与错误 fallback,非法页面、bundle 缺失、render / getServerProps 异常都会返回统一 HTML 错误页。
|
|
15
15
|
- SSR 成功渲染支持 shell 到达后提前启动客户端入口;带 `Suspense` 边界的 pending 内容可继续流式补齐。
|
|
16
|
+
- `StreamingRender` 组件级流式数据注入改为 JSON 序列化后 base64 写入 script,避免 HTML 中直接暴露明文 JSON。
|
|
16
17
|
|
|
17
18
|
## 构建与产物
|
|
18
19
|
|
package/README.md
CHANGED
|
@@ -184,7 +184,7 @@ SSR 运行时会通过 React streaming bootstrap 动态 import 客户端入口
|
|
|
184
184
|
|
|
185
185
|
`pageTitle` / `pageDescription` 可以导出字符串,也可以导出同步或异步函数。函数会在 `getServerProps()` 之后执行,入参包含 `params`、`query`、`path`、`app`、`ctx` 和 `props`。
|
|
186
186
|
|
|
187
|
-
组件级流式异步数据可以使用 `StreamingRender`。它会在服务端 Suspense 中等待 `getData()
|
|
187
|
+
组件级流式异步数据可以使用 `StreamingRender`。它会在服务端 Suspense 中等待 `getData()`,把结果 JSON 序列化后转成 base64,再随 HTML 片段写入 script;客户端 hydration 时会先解码并复用这份数据。
|
|
188
188
|
|
|
189
189
|
```tsx
|
|
190
190
|
import { StreamingRender } from '@_tc/template-core/ssr/components'
|
|
@@ -202,7 +202,7 @@ function OverviewPanel() {
|
|
|
202
202
|
}
|
|
203
203
|
```
|
|
204
204
|
|
|
205
|
-
`keyName` 需要在页面内稳定且唯一;`getData()` 的返回值必须可 JSON
|
|
205
|
+
`keyName` 需要在页面内稳定且唯一;`getData()` 的返回值必须可 JSON 序列化。注入内容会以 base64 形式进入 HTML,避免明文 JSON,但 base64 可逆,不等于加密,不能包含 token、密钥等敏感信息。客户端找不到对应注入数据时也可能执行 `getData()`,因此数据函数需要兼容浏览器 fallback,或在函数内部显式区分服务端和客户端逻辑。底层 Suspense Promise hook 可从 `@_tc/template-core/ssr/hooks` 或 `@_tc/template-core/ssr/hooks/useSuspensePromise` 引入。
|
|
206
206
|
|
|
207
207
|
启动时构建 SSR 双产物:
|
|
208
208
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./i18n/default.js`),t=require(`./i18n/en-US.js`),n=require(`./i18n/locales.js`),r=require(`./i18n/index.js`),i=require(`./guards/index.js`),a=require(`./array/index.js`),o=require(`./cache/LRUCache.js`),s=require(`./http/index.js`),c=require(`./log/index.js`),l=require(`./number/index.js`),u=require(`./object/filterEmpty.js`),d=require(`./object/index.js`),f=require(`./rafTimer.js`),p=require(`./ssr/hydration.js`),m=require(`./ssr/index.js`),h=require(`./string/index.js`);exports.ANSI_RESET=c.ANSI_RESET,exports.FetchAxios=s.FetchAxios,exports.LRUCache=o.LRUCache,exports.SSR_DATA_KEY=p.SSR_DATA_KEY,exports.ansiColors=c.ansiColors,exports.axios=s.axios,exports.capitalize=h.capitalize,exports.chunk=a.chunk,exports.clamp=l.clamp,exports.clearHydrationData=p.clearHydrationData,exports.clearRafTimer=f.clearRafTimer,exports.clientOnly=m.clientOnly,exports.colorLog=c.colorLog,exports.colorize=c.colorize,exports.compact=a.compact,exports.createHydrationData=p.createHydrationData,exports.createInstance=s.createInstance,exports.defaultEnglishResources=t.defaultEnglishResources,exports.defaultLanguage=n.defaultLanguage,exports.defaultLanguageResources=e.defaultLanguageResources,exports.filterEmpty=u.filterEmpty,exports.filtereEmpty=u.filtereEmpty,exports.getI18nPathValue=r.getI18nPathValue,exports.getLanguage=r.getLanguage,exports.groupBy=a.groupBy,exports.i18n=r.i18n,exports.i18nStore=r.i18nStore,exports.interpolateI18nMessage=r.interpolateI18nMessage,exports.isBlank=h.isBlank,exports.isBoolean=i.isBoolean,exports.isBrowser=m.isBrowser,exports.isFunction=i.isFunction,exports.isNil=i.isNil,exports.isNonNullable=i.isNonNullable,exports.isNumber=i.isNumber,exports.isPlainI18nDictionary=r.isPlainI18nDictionary,exports.isPlainObject=i.isPlainObject,exports.isServer=m.isServer,exports.isString=i.isString,exports.joinColorized=c.joinColorized,exports.joinStr=h.joinStr,exports.kebabCase=h.kebabCase,exports.languageLocalKey=n.languageLocalKey,exports.logColor=c.logColor,exports.logColorized=c.logColorized,exports.logGreen=c.logGreen,exports.logJoinColorized=c.logJoinColorized,exports.logPink=c.logPink,exports.logRed=c.logRed,exports.logWhite=c.logWhite,exports.logYellow=c.logYellow,exports.mapValues=d.mapValues,exports.mergeI18nDictionary=r.mergeI18nDictionary,exports.mergeI18nResources=r.mergeI18nResources,exports.omit=d.omit,exports.peekHydrationData=p.peekHydrationData,exports.pick=d.pick,exports.rafClearInterval=f.rafClearInterval,exports.rafClearTimeout=f.rafClearTimeout,exports.rafSetInterval=f.rafSetInterval,exports.rafSetTimeout=f.rafSetTimeout,exports.readHydrationData=p.readHydrationData,exports.safeDocument=m.safeDocument,exports.safeLocalStorage=m.safeLocalStorage,exports.safeSetLocalStorage=m.safeSetLocalStorage,exports.safeWindow=m.safeWindow,exports.serializeHydrationData=p.serializeHydrationData,exports.serializeHydrationDataScriptContent=p.serializeHydrationDataScriptContent,exports.t=r.t,exports.toArray=a.toArray,exports.toFiniteNumber=l.toFiniteNumber,exports.translate=r.translate,exports.translations=n.translations,exports.uniqueBy=a.uniqueBy;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./i18n/default.js`),t=require(`./i18n/en-US.js`),n=require(`./i18n/locales.js`),r=require(`./i18n/index.js`),i=require(`./guards/index.js`),a=require(`./array/index.js`),o=require(`./cache/LRUCache.js`),s=require(`./http/index.js`),c=require(`./log/index.js`),l=require(`./number/index.js`),u=require(`./object/filterEmpty.js`),d=require(`./object/index.js`),f=require(`./rafTimer.js`),p=require(`./ssr/hydration.js`),m=require(`./ssr/index.js`),h=require(`./string/index.js`);exports.ANSI_RESET=c.ANSI_RESET,exports.FetchAxios=s.FetchAxios,exports.LRUCache=o.LRUCache,exports.SSR_DATA_KEY=p.SSR_DATA_KEY,exports.ansiColors=c.ansiColors,exports.axios=s.axios,exports.capitalize=h.capitalize,exports.chunk=a.chunk,exports.clamp=l.clamp,exports.clearHydrationData=p.clearHydrationData,exports.clearRafTimer=f.clearRafTimer,exports.clientOnly=m.clientOnly,exports.colorLog=c.colorLog,exports.colorize=c.colorize,exports.compact=a.compact,exports.createHydrationData=p.createHydrationData,exports.createInstance=s.createInstance,exports.decodeBase64ToUtf8=p.decodeBase64ToUtf8,exports.defaultEnglishResources=t.defaultEnglishResources,exports.defaultLanguage=n.defaultLanguage,exports.defaultLanguageResources=e.defaultLanguageResources,exports.encodeUtf8ToBase64=p.encodeUtf8ToBase64,exports.filterEmpty=u.filterEmpty,exports.filtereEmpty=u.filtereEmpty,exports.getI18nPathValue=r.getI18nPathValue,exports.getLanguage=r.getLanguage,exports.groupBy=a.groupBy,exports.i18n=r.i18n,exports.i18nStore=r.i18nStore,exports.interpolateI18nMessage=r.interpolateI18nMessage,exports.isBlank=h.isBlank,exports.isBoolean=i.isBoolean,exports.isBrowser=m.isBrowser,exports.isFunction=i.isFunction,exports.isNil=i.isNil,exports.isNonNullable=i.isNonNullable,exports.isNumber=i.isNumber,exports.isPlainI18nDictionary=r.isPlainI18nDictionary,exports.isPlainObject=i.isPlainObject,exports.isServer=m.isServer,exports.isString=i.isString,exports.joinColorized=c.joinColorized,exports.joinStr=h.joinStr,exports.kebabCase=h.kebabCase,exports.languageLocalKey=n.languageLocalKey,exports.logColor=c.logColor,exports.logColorized=c.logColorized,exports.logGreen=c.logGreen,exports.logJoinColorized=c.logJoinColorized,exports.logPink=c.logPink,exports.logRed=c.logRed,exports.logWhite=c.logWhite,exports.logYellow=c.logYellow,exports.mapValues=d.mapValues,exports.mergeI18nDictionary=r.mergeI18nDictionary,exports.mergeI18nResources=r.mergeI18nResources,exports.omit=d.omit,exports.peekHydrationData=p.peekHydrationData,exports.pick=d.pick,exports.rafClearInterval=f.rafClearInterval,exports.rafClearTimeout=f.rafClearTimeout,exports.rafSetInterval=f.rafSetInterval,exports.rafSetTimeout=f.rafSetTimeout,exports.readHydrationData=p.readHydrationData,exports.safeDocument=m.safeDocument,exports.safeLocalStorage=m.safeLocalStorage,exports.safeSetLocalStorage=m.safeSetLocalStorage,exports.safeWindow=m.safeWindow,exports.serializeHydrationData=p.serializeHydrationData,exports.serializeHydrationDataScriptContent=p.serializeHydrationDataScriptContent,exports.t=r.t,exports.toArray=a.toArray,exports.toFiniteNumber=l.toFiniteNumber,exports.translate=r.translate,exports.translations=n.translations,exports.uniqueBy=a.uniqueBy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`__SSR_DATA__`;function t(){return globalThis.Buffer}function n(e){let n=t();if(n)return n.from(e,`utf-8`).toString(`base64`);let r=new TextEncoder().encode(e),i=``;return r.forEach(e=>{i+=String.fromCharCode(e)}),btoa(i)}function r(e){let n=t();if(n)return n.from(e,`base64`).toString(`utf-8`);let r=atob(e),i=Uint8Array.from(r,e=>e.charCodeAt(0));return new TextDecoder().decode(i)}function i(e){return typeof e==`string`?JSON.parse(r(e)):e}function a(t){let r=n(JSON.stringify(t));return`window.${e}=${JSON.stringify(r)}`}function o(e){return`<script>${a(e)}<\/script>`}function s(){if(typeof window>`u`)return null;let t=window[e];if(!t)return null;let n=i(t);return window[e]=n,n}function c(){typeof window>`u`||delete window[e]}function l(){let e=s();return e?(c(),e):null}function u(e,t,n){return{props:e,state:n??{},meta:{...t,renderedAt:Date.now()}}}exports.SSR_DATA_KEY=e,exports.clearHydrationData=c,exports.createHydrationData=u,exports.peekHydrationData=s,exports.readHydrationData=l,exports.serializeHydrationData=o,exports.serializeHydrationDataScriptContent=a;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`__SSR_DATA__`;function t(){return globalThis.Buffer}function n(e){let n=t();if(n)return n.from(e,`utf-8`).toString(`base64`);let r=new TextEncoder().encode(e),i=``;return r.forEach(e=>{i+=String.fromCharCode(e)}),btoa(i)}function r(e){let n=t();if(n)return n.from(e,`base64`).toString(`utf-8`);let r=atob(e),i=Uint8Array.from(r,e=>e.charCodeAt(0));return new TextDecoder().decode(i)}function i(e){return typeof e==`string`?JSON.parse(r(e)):e}function a(t){let r=n(JSON.stringify(t));return`window.${e}=${JSON.stringify(r)}`}function o(e){return`<script>${a(e)}<\/script>`}function s(){if(typeof window>`u`)return null;let t=window[e];if(!t)return null;let n=i(t);return window[e]=n,n}function c(){typeof window>`u`||delete window[e]}function l(){let e=s();return e?(c(),e):null}function u(e,t,n){return{props:e,state:n??{},meta:{...t,renderedAt:Date.now()}}}exports.SSR_DATA_KEY=e,exports.clearHydrationData=c,exports.createHydrationData=u,exports.decodeBase64ToUtf8=r,exports.encodeUtf8ToBase64=n,exports.peekHydrationData=s,exports.readHydrationData=l,exports.serializeHydrationData=o,exports.serializeHydrationDataScriptContent=a;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./hydration.js`);var t=typeof window<`u`&&typeof document<`u`,n=!t;function r(e,t){return n?t:e()}function i(){if(!n)return window}function a(){if(!n)return document}function o(e,t=``){return n?t:localStorage.getItem(e)??t}function s(e,t){n||localStorage.setItem(e,t)}exports.SSR_DATA_KEY=e.SSR_DATA_KEY,exports.clearHydrationData=e.clearHydrationData,exports.clientOnly=r,exports.createHydrationData=e.createHydrationData,exports.isBrowser=t,exports.isServer=n,exports.peekHydrationData=e.peekHydrationData,exports.readHydrationData=e.readHydrationData,exports.safeDocument=a,exports.safeLocalStorage=o,exports.safeSetLocalStorage=s,exports.safeWindow=i,exports.serializeHydrationData=e.serializeHydrationData,exports.serializeHydrationDataScriptContent=e.serializeHydrationDataScriptContent;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./hydration.js`);var t=typeof window<`u`&&typeof document<`u`,n=!t;function r(e,t){return n?t:e()}function i(){if(!n)return window}function a(){if(!n)return document}function o(e,t=``){return n?t:localStorage.getItem(e)??t}function s(e,t){n||localStorage.setItem(e,t)}exports.SSR_DATA_KEY=e.SSR_DATA_KEY,exports.clearHydrationData=e.clearHydrationData,exports.clientOnly=r,exports.createHydrationData=e.createHydrationData,exports.decodeBase64ToUtf8=e.decodeBase64ToUtf8,exports.encodeUtf8ToBase64=e.encodeUtf8ToBase64,exports.isBrowser=t,exports.isServer=n,exports.peekHydrationData=e.peekHydrationData,exports.readHydrationData=e.readHydrationData,exports.safeDocument=a,exports.safeLocalStorage=o,exports.safeSetLocalStorage=s,exports.safeWindow=i,exports.serializeHydrationData=e.serializeHydrationData,exports.serializeHydrationDataScriptContent=e.serializeHydrationDataScriptContent;
|
|
@@ -11,7 +11,7 @@ import { clamp as W, toFiniteNumber as G } from "./number/index.js";
|
|
|
11
11
|
import { filterEmpty as K, filtereEmpty as q } from "./object/filterEmpty.js";
|
|
12
12
|
import { mapValues as J, omit as Y, pick as X } from "./object/index.js";
|
|
13
13
|
import { clearRafTimer as Z, rafClearInterval as Q, rafClearTimeout as $, rafSetInterval as ee, rafSetTimeout as te } from "./rafTimer.js";
|
|
14
|
-
import { SSR_DATA_KEY as ne, clearHydrationData as re, createHydrationData as ie,
|
|
15
|
-
import { clientOnly as
|
|
16
|
-
import { capitalize as
|
|
17
|
-
export { j as ANSI_RESET, O as FetchAxios, D as LRUCache, ne as SSR_DATA_KEY, M as ansiColors, k as axios,
|
|
14
|
+
import { SSR_DATA_KEY as ne, clearHydrationData as re, createHydrationData as ie, decodeBase64ToUtf8 as ae, encodeUtf8ToBase64 as oe, peekHydrationData as se, readHydrationData as ce, serializeHydrationData as le, serializeHydrationDataScriptContent as ue } from "./ssr/hydration.js";
|
|
15
|
+
import { clientOnly as de, isBrowser as fe, isServer as pe, safeDocument as me, safeLocalStorage as he, safeSetLocalStorage as ge, safeWindow as _e } from "./ssr/index.js";
|
|
16
|
+
import { capitalize as ve, isBlank as ye, joinStr as be, kebabCase as xe } from "./string/index.js";
|
|
17
|
+
export { j as ANSI_RESET, O as FetchAxios, D as LRUCache, ne as SSR_DATA_KEY, M as ansiColors, k as axios, ve as capitalize, S as chunk, W as clamp, re as clearHydrationData, Z as clearRafTimer, de as clientOnly, N as colorLog, P as colorize, C as compact, ie as createHydrationData, A as createInstance, ae as decodeBase64ToUtf8, t as defaultEnglishResources, n as defaultLanguage, e as defaultLanguageResources, oe as encodeUtf8ToBase64, K as filterEmpty, q as filtereEmpty, a as getI18nPathValue, o as getLanguage, w as groupBy, s as i18n, c as i18nStore, l as interpolateI18nMessage, ye as isBlank, h as isBoolean, fe as isBrowser, g as isFunction, _ as isNil, v as isNonNullable, y as isNumber, u as isPlainI18nDictionary, b as isPlainObject, pe as isServer, x as isString, F as joinColorized, be as joinStr, xe as kebabCase, r as languageLocalKey, I as logColor, L as logColorized, R as logGreen, z as logJoinColorized, B as logPink, V as logRed, H as logWhite, U as logYellow, J as mapValues, d as mergeI18nDictionary, f as mergeI18nResources, Y as omit, se as peekHydrationData, X as pick, Q as rafClearInterval, $ as rafClearTimeout, ee as rafSetInterval, te as rafSetTimeout, ce as readHydrationData, me as safeDocument, he as safeLocalStorage, ge as safeSetLocalStorage, _e as safeWindow, le as serializeHydrationData, ue as serializeHydrationDataScriptContent, p as t, T as toArray, G as toFiniteNumber, m as translate, i as translations, E as uniqueBy };
|
|
@@ -52,4 +52,4 @@ function u(e, t, n) {
|
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
//#endregion
|
|
55
|
-
export { e as SSR_DATA_KEY, c as clearHydrationData, u as createHydrationData, s as peekHydrationData, l as readHydrationData, o as serializeHydrationData, a as serializeHydrationDataScriptContent };
|
|
55
|
+
export { e as SSR_DATA_KEY, c as clearHydrationData, u as createHydrationData, r as decodeBase64ToUtf8, n as encodeUtf8ToBase64, s as peekHydrationData, l as readHydrationData, o as serializeHydrationData, a as serializeHydrationDataScriptContent };
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { SSR_DATA_KEY as e, clearHydrationData as t, createHydrationData as n,
|
|
1
|
+
import { SSR_DATA_KEY as e, clearHydrationData as t, createHydrationData as n, decodeBase64ToUtf8 as r, encodeUtf8ToBase64 as i, peekHydrationData as a, readHydrationData as o, serializeHydrationData as s, serializeHydrationDataScriptContent as c } from "./hydration.js";
|
|
2
2
|
//#region packages/common/ssr/index.ts
|
|
3
|
-
var
|
|
4
|
-
function
|
|
5
|
-
return
|
|
3
|
+
var l = typeof window < "u" && typeof document < "u", u = !l;
|
|
4
|
+
function d(e, t) {
|
|
5
|
+
return u ? t : e();
|
|
6
6
|
}
|
|
7
|
-
function
|
|
8
|
-
if (!
|
|
7
|
+
function f() {
|
|
8
|
+
if (!u) return window;
|
|
9
9
|
}
|
|
10
|
-
function
|
|
11
|
-
if (!
|
|
10
|
+
function p() {
|
|
11
|
+
if (!u) return document;
|
|
12
12
|
}
|
|
13
|
-
function
|
|
14
|
-
return
|
|
13
|
+
function m(e, t = "") {
|
|
14
|
+
return u ? t : localStorage.getItem(e) ?? t;
|
|
15
15
|
}
|
|
16
|
-
function
|
|
17
|
-
|
|
16
|
+
function h(e, t) {
|
|
17
|
+
u || localStorage.setItem(e, t);
|
|
18
18
|
}
|
|
19
19
|
//#endregion
|
|
20
|
-
export { e as SSR_DATA_KEY, t as clearHydrationData,
|
|
20
|
+
export { e as SSR_DATA_KEY, t as clearHydrationData, d as clientOnly, n as createHydrationData, r as decodeBase64ToUtf8, i as encodeUtf8ToBase64, l as isBrowser, u as isServer, a as peekHydrationData, o as readHydrationData, p as safeDocument, m as safeLocalStorage, h as safeSetLocalStorage, f as safeWindow, s as serializeHydrationData, c as serializeHydrationDataScriptContent };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MergeType, MOmit } from "../../../../typings/type";
|
|
2
|
-
import { FetchInfo } from "../../../../models/types/data/fetchInfo";
|
|
2
|
+
import type { FetchInfo } from "../../../../models/types/data/fetchInfo";
|
|
3
3
|
import { SelectProps } from "../../../../packages/react/ui/index";
|
|
4
4
|
export interface AsyncSelectProps extends MergeType<[MOmit<FetchInfo, 'fetchKey'>, MOmit<SelectProps, 'options'>]> {
|
|
5
5
|
}
|
|
@@ -76,8 +76,9 @@ var PopForm = memo((props) => {
|
|
|
76
76
|
/**
|
|
77
77
|
* 编辑弹窗需要 获取一下数据
|
|
78
78
|
*/
|
|
79
|
-
if (props.comName === "editForm"
|
|
80
|
-
const
|
|
79
|
+
if (props.comName === "editForm") {
|
|
80
|
+
const fetchKey = config?.fetchKey;
|
|
81
|
+
if (!fetchKey) return;
|
|
81
82
|
const params = { [fetchKey]: props.data[fetchKey] };
|
|
82
83
|
const { url = api, method = "get" } = config?.fetchConfig ?? {};
|
|
83
84
|
setLoading(true);
|
|
@@ -11,7 +11,7 @@ import { clamp, toFiniteNumber } from "./number/index.js";
|
|
|
11
11
|
import { filterEmpty, filtereEmpty } from "./object/filterEmpty.js";
|
|
12
12
|
import { mapValues, omit, pick } from "./object/index.js";
|
|
13
13
|
import { clearRafTimer, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout } from "./rafTimer.js";
|
|
14
|
-
import { SSR_DATA_KEY, clearHydrationData, createHydrationData, peekHydrationData, readHydrationData, serializeHydrationData, serializeHydrationDataScriptContent } from "./ssr/hydration.js";
|
|
14
|
+
import { SSR_DATA_KEY, clearHydrationData, createHydrationData, decodeBase64ToUtf8, encodeUtf8ToBase64, peekHydrationData, readHydrationData, serializeHydrationData, serializeHydrationDataScriptContent } from "./ssr/hydration.js";
|
|
15
15
|
import { clientOnly, isBrowser, isServer, safeDocument, safeLocalStorage, safeSetLocalStorage, safeWindow } from "./ssr/index.js";
|
|
16
16
|
import { capitalize, isBlank, joinStr, kebabCase } from "./string/index.js";
|
|
17
|
-
export { ANSI_RESET, FetchAxios, LRUCache, SSR_DATA_KEY, ansiColors, axios, capitalize, chunk, clamp, clearHydrationData, clearRafTimer, clientOnly, colorLog, colorize, compact, createHydrationData, createInstance, defaultEnglishResources, defaultLanguage, defaultLanguageResources, filterEmpty, filtereEmpty, getI18nPathValue, getLanguage, groupBy, i18n, i18nStore, interpolateI18nMessage, isBlank, isBoolean, isBrowser, isFunction, isNil, isNonNullable, isNumber, isPlainI18nDictionary, isPlainObject, isServer, isString, joinColorized, joinStr, kebabCase, languageLocalKey, logColor, logColorized, logGreen, logJoinColorized, logPink, logRed, logWhite, logYellow, mapValues, mergeI18nDictionary, mergeI18nResources, omit, peekHydrationData, pick, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout, readHydrationData, safeDocument, safeLocalStorage, safeSetLocalStorage, safeWindow, serializeHydrationData, serializeHydrationDataScriptContent, t, toArray, toFiniteNumber, translate, translations, uniqueBy };
|
|
17
|
+
export { ANSI_RESET, FetchAxios, LRUCache, SSR_DATA_KEY, ansiColors, axios, capitalize, chunk, clamp, clearHydrationData, clearRafTimer, clientOnly, colorLog, colorize, compact, createHydrationData, createInstance, decodeBase64ToUtf8, defaultEnglishResources, defaultLanguage, defaultLanguageResources, encodeUtf8ToBase64, filterEmpty, filtereEmpty, getI18nPathValue, getLanguage, groupBy, i18n, i18nStore, interpolateI18nMessage, isBlank, isBoolean, isBrowser, isFunction, isNil, isNonNullable, isNumber, isPlainI18nDictionary, isPlainObject, isServer, isString, joinColorized, joinStr, kebabCase, languageLocalKey, logColor, logColorized, logGreen, logJoinColorized, logPink, logRed, logWhite, logYellow, mapValues, mergeI18nDictionary, mergeI18nResources, omit, peekHydrationData, pick, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout, readHydrationData, safeDocument, safeLocalStorage, safeSetLocalStorage, safeWindow, serializeHydrationData, serializeHydrationDataScriptContent, t, toArray, toFiniteNumber, translate, translations, uniqueBy };
|
|
@@ -15,6 +15,8 @@ declare global {
|
|
|
15
15
|
[SSR_DATA_KEY]?: SSRHydrationData | string;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
export declare function encodeUtf8ToBase64(value: string): string;
|
|
19
|
+
export declare function decodeBase64ToUtf8(value: string): string;
|
|
18
20
|
export declare function serializeHydrationDataScriptContent(data: SSRHydrationData): string;
|
|
19
21
|
export declare function serializeHydrationData(data: SSRHydrationData): string;
|
|
20
22
|
export declare function peekHydrationData<Props = Record<string, unknown>, State = Record<string, unknown>>(): SSRHydrationData<Props, State> | null;
|
|
@@ -85,4 +85,4 @@ function createHydrationData(props, meta, state) {
|
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
87
|
//#endregion
|
|
88
|
-
export { SSR_DATA_KEY, clearHydrationData, createHydrationData, peekHydrationData, readHydrationData, serializeHydrationData, serializeHydrationDataScriptContent };
|
|
88
|
+
export { SSR_DATA_KEY, clearHydrationData, createHydrationData, decodeBase64ToUtf8, encodeUtf8ToBase64, peekHydrationData, readHydrationData, serializeHydrationData, serializeHydrationDataScriptContent };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SSR_DATA_KEY, clearHydrationData, createHydrationData, peekHydrationData, readHydrationData, serializeHydrationData, serializeHydrationDataScriptContent } from "./hydration.js";
|
|
1
|
+
import { SSR_DATA_KEY, clearHydrationData, createHydrationData, decodeBase64ToUtf8, encodeUtf8ToBase64, peekHydrationData, readHydrationData, serializeHydrationData, serializeHydrationDataScriptContent } from "./hydration.js";
|
|
2
2
|
//#region packages/common/ssr/index.ts
|
|
3
3
|
/**
|
|
4
4
|
* SSR 环境检测与守卫工具
|
|
@@ -49,4 +49,4 @@ function safeSetLocalStorage(key, value) {
|
|
|
49
49
|
localStorage.setItem(key, value);
|
|
50
50
|
}
|
|
51
51
|
//#endregion
|
|
52
|
-
export { SSR_DATA_KEY, clearHydrationData, clientOnly, createHydrationData, isBrowser, isServer, peekHydrationData, readHydrationData, safeDocument, safeLocalStorage, safeSetLocalStorage, safeWindow, serializeHydrationData, serializeHydrationDataScriptContent };
|
|
52
|
+
export { SSR_DATA_KEY, clearHydrationData, clientOnly, createHydrationData, decodeBase64ToUtf8, encodeUtf8ToBase64, isBrowser, isServer, peekHydrationData, readHydrationData, safeDocument, safeLocalStorage, safeSetLocalStorage, safeWindow, serializeHydrationData, serializeHydrationDataScriptContent };
|
|
@@ -28,10 +28,10 @@ var RenderCom = (props) => {
|
|
|
28
28
|
/**
|
|
29
29
|
* 组件级流式异步数据渲染组件。
|
|
30
30
|
*
|
|
31
|
-
* - 服务端通过 Suspense 等待 getData()
|
|
31
|
+
* - 服务端通过 Suspense 等待 getData(),并把结果 JSON 序列化后以 base64 注入到 HTML script 中。
|
|
32
32
|
* - 客户端 hydration 优先读取服务端注入数据,读取失败时才会走 getData() fallback。
|
|
33
33
|
* - keyName 需要同请求内稳定;多请求数据可能不同时,应拼入非敏感的请求维度。
|
|
34
|
-
* - getData()
|
|
34
|
+
* - getData() 返回值会以 base64 进入 HTML;base64 可逆,不能包含 token、密钥、未脱敏个人信息等敏感数据。
|
|
35
35
|
*/
|
|
36
36
|
var StreamingRender = (props) => {
|
|
37
37
|
const { fallback, name, ...ext } = props;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { decodeBase64ToUtf8, encodeUtf8ToBase64 } from "../../../packages/common/ssr/hydration.js";
|
|
1
2
|
import { useEffect, useState } from "react";
|
|
2
3
|
import { jsx } from "react/jsx-runtime";
|
|
3
4
|
//#region ssr/components/StreamingRender/StreamingScript.tsx
|
|
@@ -14,11 +15,11 @@ var StreamingRenderGetDataScript = (props) => {
|
|
|
14
15
|
const timer = setTimeout(() => setHidden(true), 3e3);
|
|
15
16
|
return () => clearTimeout(timer);
|
|
16
17
|
}, []);
|
|
17
|
-
const
|
|
18
|
+
const encodedData = encodeUtf8ToBase64(JSON.stringify(data) ?? "null");
|
|
18
19
|
return !hidden && /* @__PURE__ */ jsx("script", {
|
|
19
20
|
type: "application/json",
|
|
20
21
|
id: getStreamingRenderGetDataScriptId(keyName),
|
|
21
|
-
dangerouslySetInnerHTML: { __html:
|
|
22
|
+
dangerouslySetInnerHTML: { __html: JSON.stringify(encodedData) }
|
|
22
23
|
});
|
|
23
24
|
};
|
|
24
25
|
var clientDataCache = /* @__PURE__ */ new Map();
|
|
@@ -43,7 +44,12 @@ var readClientStreamData = (key) => {
|
|
|
43
44
|
data: null
|
|
44
45
|
};
|
|
45
46
|
const dataStr = sDom.textContent;
|
|
46
|
-
|
|
47
|
+
if (!dataStr) return {
|
|
48
|
+
found: false,
|
|
49
|
+
data: null
|
|
50
|
+
};
|
|
51
|
+
const encodedData = JSON.parse(dataStr);
|
|
52
|
+
scriptData = JSON.parse(decodeBase64ToUtf8(encodedData));
|
|
47
53
|
found = true;
|
|
48
54
|
clientDataCache.set(key, scriptData);
|
|
49
55
|
} catch (error) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MergeType, MOmit } from "../../../../../types/typings/type";
|
|
2
|
-
import { FetchInfo } from "@model/data/fetchInfo";
|
|
2
|
+
import type { FetchInfo } from "@model/data/fetchInfo";
|
|
3
3
|
import { SelectProps } from "../../../../../fe/packages/react/ui/index";
|
|
4
4
|
export interface AsyncSelectProps extends MergeType<[MOmit<FetchInfo, 'fetchKey'>, MOmit<SelectProps, 'options'>]> {
|
|
5
5
|
}
|
|
@@ -15,6 +15,8 @@ declare global {
|
|
|
15
15
|
[SSR_DATA_KEY]?: SSRHydrationData | string;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
export declare function encodeUtf8ToBase64(value: string): string;
|
|
19
|
+
export declare function decodeBase64ToUtf8(value: string): string;
|
|
18
20
|
export declare function serializeHydrationDataScriptContent(data: SSRHydrationData): string;
|
|
19
21
|
export declare function serializeHydrationData(data: SSRHydrationData): string;
|
|
20
22
|
export declare function peekHydrationData<Props = Record<string, unknown>, State = Record<string, unknown>>(): SSRHydrationData<Props, State> | null;
|
package/package.json
CHANGED
|
@@ -42,6 +42,8 @@ declare global {
|
|
|
42
42
|
[SSR_DATA_KEY]?: SSRHydrationData | string;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
+
export declare function encodeUtf8ToBase64(value: string): string;
|
|
46
|
+
export declare function decodeBase64ToUtf8(value: string): string;
|
|
45
47
|
/**
|
|
46
48
|
* 服务端:将注水数据序列化为 inline script 内容。
|
|
47
49
|
* 数据内容以 base64 字符串注入,避免在 HTML 中明文暴露 JSON。
|