@finesoft/front 0.1.29 → 0.1.31
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/{app-QERC5VUP.js → app-IA6JQC7V.js} +3 -3
- package/dist/{chunk-WD72JAMS.js → chunk-M7VITIMR.js} +28 -25
- package/dist/chunk-M7VITIMR.js.map +1 -0
- package/dist/{chunk-N4AEOYUR.js → chunk-ZMOE42LB.js} +6 -2
- package/dist/chunk-ZMOE42LB.js.map +1 -0
- package/dist/index.cjs +67 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +43 -21
- package/dist/index.js.map +1 -1
- package/dist/{src-LYKZSLF7.js → src-B5YAJXIM.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-N4AEOYUR.js.map +0 -1
- package/dist/chunk-WD72JAMS.js.map +0 -1
- /package/dist/{app-QERC5VUP.js.map → app-IA6JQC7V.js.map} +0 -0
- /package/dist/{src-LYKZSLF7.js.map → src-B5YAJXIM.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../ssr/src/render.ts","../../ssr/src/create-render.ts","../../ssr/src/inject.ts","../../ssr/src/server-data.ts"],"sourcesContent":["/**\n * ssrRender — 通用 SSR 渲染管线\n *\n * 1. 创建 Framework + 注册 Controllers\n * 2. routeUrl → Intent\n * 3. dispatch → Page 数据\n * 4. 调用应用层提供的渲染函数\n */\n\nimport {\n\tFramework,\n\ttype BasePage,\n\ttype FrameworkConfig,\n\ttype PrefetchedIntent,\n} from \"@finesoft/core\";\n\nexport interface SSRRenderOptions {\n\t/** 请求 URL */\n\turl: string;\n\t/** Framework 配置(含路由注册等) */\n\tframeworkConfig: FrameworkConfig;\n\t/** 注册 controllers 和路由的引导函数 */\n\tbootstrap: (framework: Framework) => void;\n\t/** 获取错误页面 */\n\tgetErrorPage: (status: number, message: string) => BasePage;\n\t/** 应用层渲染函数(如 Svelte SSR render) */\n\trenderApp: (page: BasePage, framework: Framework) => SSRAppResult;\n\t/** 可选的 SSR 请求上下文(如自定义 fetch) */\n\tssrContext?: SSRContext;\n}\n\n/** SSR 请求级上下文 */\nexport interface SSRContext {\n\t/** 自定义 fetch(如 Hono 内部路由回环) */\n\tfetch?: typeof globalThis.fetch;\n}\n\nexport interface SSRAppResult {\n\thtml: string;\n\thead: string;\n\tcss: string;\n}\n\nexport interface SSRRenderResult {\n\thtml: string;\n\thead: string;\n\tcss: string;\n\tserverData: PrefetchedIntent[];\n\t/** 该路由的渲染模式(由 Router 返回) */\n\trenderMode?: string;\n}\n\nexport async function ssrRender(\n\toptions: SSRRenderOptions,\n): Promise<SSRRenderResult> {\n\tconst {\n\t\turl,\n\t\tframeworkConfig,\n\t\tbootstrap,\n\t\tgetErrorPage,\n\t\trenderApp,\n\t\tssrContext,\n\t} = options;\n\n\t// 将 SSR 上下文中的 fetch 合并到 frameworkConfig,注入 DI 容器\n\tconst mergedConfig: FrameworkConfig = ssrContext?.fetch\n\t\t? { ...frameworkConfig, fetch: ssrContext.fetch }\n\t\t: frameworkConfig;\n\n\tconst framework = Framework.create(mergedConfig);\n\tbootstrap(framework);\n\n\tconst parsed = new URL(url, \"http://localhost\");\n\tconst fullPath = parsed.pathname + parsed.search;\n\tconst match = framework.routeUrl(fullPath);\n\n\t// CSR 模式:跳过服务端渲染,返回空内容由客户端 JS 渲染\n\tif (match?.renderMode === \"csr\") {\n\t\tframework.dispose();\n\t\treturn {\n\t\t\thtml: \"\",\n\t\t\thead: \"\",\n\t\t\tcss: \"\",\n\t\t\tserverData: [],\n\t\t\trenderMode: \"csr\",\n\t\t};\n\t}\n\n\tlet page: BasePage;\n\tlet serverData: PrefetchedIntent[] = [];\n\n\tif (match) {\n\t\ttry {\n\t\t\tpage = (await framework.dispatch(match.intent)) as BasePage;\n\t\t\tserverData = [{ intent: match.intent, data: page }];\n\t\t} catch {\n\t\t\tpage = getErrorPage(500, \"Internal error\");\n\t\t}\n\t} else {\n\t\tpage = getErrorPage(404, \"Page not found\");\n\t}\n\n\tconst result = renderApp(page, framework);\n\n\tframework.dispose();\n\n\treturn {\n\t\thtml: result.html,\n\t\thead: result.head,\n\t\tcss: result.css,\n\t\tserverData,\n\t\trenderMode: match?.renderMode,\n\t};\n}\n","/**\n * createSSRRender — 工厂函数,返回可直接被 SSR 服务器调用的 render 函数\n *\n * 将一次性配置(bootstrap / getErrorPage / renderApp)绑定后,\n * 返回 `(url, locale) => Promise<SSRRenderResult>` 签名,\n * 与 @finesoft/server 的 SSRModule 接口对齐。\n */\n\nimport type { BasePage, Framework, FrameworkConfig } from \"@finesoft/core\";\nimport {\n\tssrRender,\n\ttype SSRAppResult,\n\ttype SSRContext,\n\ttype SSRRenderResult,\n} from \"./render\";\n\nexport interface SSRRenderConfig {\n\t/** 注册 controllers 和路由的引导函数 */\n\tbootstrap: (framework: Framework) => void;\n\n\t/** 获取错误页面 */\n\tgetErrorPage: (status: number, message: string) => BasePage;\n\n\t/**\n\t * 应用层渲染函数\n\t *\n\t * @param page - 当前页面数据\n\t * @param locale - 当前语言\n\t * @returns SSR 渲染结果 { html, head, css }\n\t */\n\trenderApp: (page: BasePage, locale: string) => SSRAppResult;\n\n\t/** Framework 构造配置(可选) */\n\tframeworkConfig?: FrameworkConfig;\n}\n\n/**\n * 创建 render 函数\n *\n * @returns `render(url, locale, ssrContext?)` — 供 @finesoft/server SSRModule 使用\n */\nexport function createSSRRender(\n\tconfig: SSRRenderConfig,\n): (\n\turl: string,\n\tlocale: string,\n\tssrContext?: SSRContext,\n) => Promise<SSRRenderResult> {\n\tconst { bootstrap, getErrorPage, renderApp, frameworkConfig } = config;\n\n\treturn (url: string, locale: string, ssrContext?: SSRContext) =>\n\t\tssrRender({\n\t\t\turl,\n\t\t\tframeworkConfig: frameworkConfig ?? {},\n\t\t\tbootstrap,\n\t\t\tgetErrorPage,\n\t\t\trenderApp: (page) => renderApp(page, locale),\n\t\t\tssrContext,\n\t\t});\n}\n","/**\n * injectSSRContent — 将 SSR 渲染结果注入 HTML 模板\n */\n\n/** SSR HTML 模板占位符常量 */\nexport const SSR_PLACEHOLDERS = {\n\tLANG: \"<!--ssr-lang-->\",\n\tHEAD: \"<!--ssr-head-->\",\n\tBODY: \"<!--ssr-body-->\",\n\tDATA: \"<!--ssr-data-->\",\n} as const;\n\nexport interface InjectSSROptions {\n\ttemplate: string;\n\tlocale: string;\n\thead: string;\n\tcss: string;\n\thtml: string;\n\tserializedData: string;\n}\n\nexport function injectSSRContent(options: InjectSSROptions): string {\n\tconst { template, locale, head, css, html, serializedData } = options;\n\tconst cssTag = css ? `<style>${css}</style>` : \"\";\n\n\treturn template\n\t\t.replace(SSR_PLACEHOLDERS.LANG, locale)\n\t\t.replace(SSR_PLACEHOLDERS.HEAD, `${head}\\n${cssTag}`)\n\t\t.replace(SSR_PLACEHOLDERS.BODY, html)\n\t\t.replace(\n\t\t\tSSR_PLACEHOLDERS.DATA,\n\t\t\t`<script id=\"serialized-server-data\" type=\"application/json\">${serializedData}</script>`,\n\t\t);\n}\n\n/**\n * CSR 空壳注入 — 只替换 lang,清空 body/head/data 占位符\n * 用于 renderMode === \"csr\" 的路由\n */\nexport function injectCSRShell(template: string, locale: string): string {\n\treturn template\n\t\t.replace(SSR_PLACEHOLDERS.LANG, locale)\n\t\t.replace(SSR_PLACEHOLDERS.HEAD, \"\")\n\t\t.replace(SSR_PLACEHOLDERS.BODY, \"\")\n\t\t.replace(SSR_PLACEHOLDERS.DATA, \"\");\n}\n","/**\n * serializeServerData — 将 PrefetchedIntents 数据序列化为安全的 JSON\n *\n * 返回值可安全嵌入 <script> 标签。\n */\n\nimport type { PrefetchedIntent } from \"@finesoft/core\";\n\nconst HTML_REPLACEMENTS: Record<string, string> = {\n\t\"<\": \"\\\\u003C\",\n\t\">\": \"\\\\u003E\",\n\t\"/\": \"\\\\u002F\",\n\t\"\\u2028\": \"\\\\u2028\",\n\t\"\\u2029\": \"\\\\u2029\",\n};\n\nconst HTML_ESCAPE_PATTERN = /[<>/\\u2028\\u2029]/g;\n\nexport function serializeServerData(data: PrefetchedIntent[]): string {\n\tconst json = JSON.stringify(data);\n\treturn json.replace(\n\t\tHTML_ESCAPE_PATTERN,\n\t\t(match) => HTML_REPLACEMENTS[match] ?? match,\n\t);\n}\n"],"mappings":";;;;;AAoDA,eAAsB,UACrB,SAC2B;AAC3B,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI;AAGJ,QAAM,eAAgC,YAAY,QAC/C,EAAE,GAAG,iBAAiB,OAAO,WAAW,MAAM,IAC9C;AAEH,QAAM,YAAY,UAAU,OAAO,YAAY;AAC/C,YAAU,SAAS;AAEnB,QAAM,SAAS,IAAI,IAAI,KAAK,kBAAkB;AAC9C,QAAM,WAAW,OAAO,WAAW,OAAO;AAC1C,QAAM,QAAQ,UAAU,SAAS,QAAQ;AAGzC,MAAI,OAAO,eAAe,OAAO;AAChC,cAAU,QAAQ;AAClB,WAAO;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,KAAK;AAAA,MACL,YAAY,CAAC;AAAA,MACb,YAAY;AAAA,IACb;AAAA,EACD;AAEA,MAAI;AACJ,MAAI,aAAiC,CAAC;AAEtC,MAAI,OAAO;AACV,QAAI;AACH,aAAQ,MAAM,UAAU,SAAS,MAAM,MAAM;AAC7C,mBAAa,CAAC,EAAE,QAAQ,MAAM,QAAQ,MAAM,KAAK,CAAC;AAAA,IACnD,QAAQ;AACP,aAAO,aAAa,KAAK,gBAAgB;AAAA,IAC1C;AAAA,EACD,OAAO;AACN,WAAO,aAAa,KAAK,gBAAgB;AAAA,EAC1C;AAEA,QAAM,SAAS,UAAU,MAAM,SAAS;AAExC,YAAU,QAAQ;AAElB,SAAO;AAAA,IACN,MAAM,OAAO;AAAA,IACb,MAAM,OAAO;AAAA,IACb,KAAK,OAAO;AAAA,IACZ;AAAA,IACA,YAAY,OAAO;AAAA,EACpB;AACD;;;ACxEO,SAAS,gBACf,QAK6B;AAC7B,QAAM,EAAE,WAAW,cAAc,WAAW,gBAAgB,IAAI;AAEhE,SAAO,CAAC,KAAa,QAAgB,eACpC,UAAU;AAAA,IACT;AAAA,IACA,iBAAiB,mBAAmB,CAAC;AAAA,IACrC;AAAA,IACA;AAAA,IACA,WAAW,CAAC,SAAS,UAAU,MAAM,MAAM;AAAA,IAC3C;AAAA,EACD,CAAC;AACH;;;ACtDO,IAAM,mBAAmB;AAAA,EAC/B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACP;AAWO,SAAS,iBAAiB,SAAmC;AACnE,QAAM,EAAE,UAAU,QAAQ,MAAM,KAAK,MAAM,eAAe,IAAI;AAC9D,QAAM,SAAS,MAAM,UAAU,GAAG,aAAa;AAE/C,SAAO,SACL,QAAQ,iBAAiB,MAAM,MAAM,EACrC,QAAQ,iBAAiB,MAAM,GAAG,IAAI;AAAA,EAAK,MAAM,EAAE,EACnD,QAAQ,iBAAiB,MAAM,IAAI,EACnC;AAAA,IACA,iBAAiB;AAAA,IACjB,+DAA+D,cAAc;AAAA,EAC9E;AACF;AAMO,SAAS,eAAe,UAAkB,QAAwB;AACxE,SAAO,SACL,QAAQ,iBAAiB,MAAM,MAAM,EACrC,QAAQ,iBAAiB,MAAM,EAAE,EACjC,QAAQ,iBAAiB,MAAM,EAAE,EACjC,QAAQ,iBAAiB,MAAM,EAAE;AACpC;;;ACrCA,IAAM,oBAA4C;AAAA,EACjD,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,UAAU;AAAA,EACV,UAAU;AACX;AAEA,IAAM,sBAAsB;AAErB,SAAS,oBAAoB,MAAkC;AACrE,QAAM,OAAO,KAAK,UAAU,IAAI;AAChC,SAAO,KAAK;AAAA,IACX;AAAA,IACA,CAAC,UAAU,kBAAkB,KAAK,KAAK;AAAA,EACxC;AACD;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../server/src/app.ts","../../server/src/internal-fetch.ts"],"sourcesContent":["/**\n * createSSRApp — 创建 Hono SSR 应用\n *\n * 提供 SSR 通配路由,读取模板、加载 SSR 模块、渲染。\n * 应用层可在此之上追加自定义路由(API 代理等)。\n */\n\nimport { injectCSRShell, injectSSRContent } from \"@finesoft/ssr\";\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { createInternalFetch } from \"./internal-fetch\";\nimport { parseAcceptLanguage } from \"./locale\";\n\nexport interface SSRModule {\n\trender: (\n\t\turl: string,\n\t\tlocale: string,\n\t\tssrContext?: { fetch?: typeof globalThis.fetch },\n\t) => Promise<{\n\t\thtml: string;\n\t\thead: string;\n\t\tcss: string;\n\t\tserverData: unknown;\n\t\trenderMode?: string;\n\t}>;\n\tserializeServerData: (data: unknown) => string;\n}\n\nexport interface SSRAppOptions {\n\t/** 项目根路径 */\n\troot: string;\n\t/** Vite dev server(仅开发模式) */\n\tvite?: ViteDevServer;\n\t/** 是否生产环境 */\n\tisProduction: boolean;\n\t/** SSR 入口文件路径(开发用,如 \"/src/ssr.ts\") */\n\tssrEntryPath?: string;\n\t/** 生产环境 SSR 模块路径(如 \"../dist/server/ssr.js\") */\n\tssrProductionModule?: string;\n\t/** 支持的语言列表 */\n\tsupportedLocales?: string[];\n\t/** 默认语言 */\n\tdefaultLocale?: string;\n\t/**\n\t * 父级 Hono app 的 fetch 函数,用于 SSR 内部路由回环。\n\t * SSR 渲染时,控制器的 fetch 请求(如 /api/apple/*)会通过此函数\n\t * 直接在进程内路由到代理 handler,避免网络自请求死锁。\n\t */\n\tparentFetch?: (request: Request) => Promise<Response>;\n}\n\nexport function createSSRApp(options: SSRAppOptions): Hono {\n\tconst {\n\t\troot,\n\t\tvite,\n\t\tisProduction,\n\t\tssrEntryPath = \"/src/ssr.ts\",\n\t\tssrProductionModule,\n\t\tsupportedLocales,\n\t\tdefaultLocale,\n\t\tparentFetch,\n\t} = options;\n\n\tconst app = new Hono();\n\n\tconst internalFetch = parentFetch\n\t\t? createInternalFetch(parentFetch)\n\t\t: undefined;\n\n\t/** ISR 内存缓存(prerender 路由首次请求后缓存,LRU 驱逐) */\n\tconst ISR_CACHE_MAX = 1000;\n\tconst isrCache = new Map<string, string>();\n\tfunction isrSet(key: string, val: string) {\n\t\tif (isrCache.size >= ISR_CACHE_MAX) {\n\t\t\tconst first = isrCache.keys().next().value;\n\t\t\tif (first !== undefined) isrCache.delete(first);\n\t\t}\n\t\tisrCache.set(key, val);\n\t}\n\n\tasync function readTemplate(url: string): Promise<string> {\n\t\tif (!isProduction && vite) {\n\t\t\tconst { readFileSync } = await import(/* @vite-ignore */ \"node:fs\");\n\t\t\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\t\t\tconst raw = readFileSync(resolve(root, \"index.html\"), \"utf-8\");\n\t\t\treturn vite.transformIndexHtml(url, raw);\n\t\t}\n\n\t\tconst isDeno = typeof (globalThis as any).Deno !== \"undefined\";\n\t\tif (isDeno) {\n\t\t\treturn (globalThis as any).Deno.readTextFileSync(\n\t\t\t\tnew URL(\"../dist/client/index.html\", import.meta.url),\n\t\t\t);\n\t\t}\n\n\t\tconst { readFileSync } = await import(/* @vite-ignore */ \"node:fs\");\n\t\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\t\treturn readFileSync(resolve(root, \"dist/client/index.html\"), \"utf-8\");\n\t}\n\n\tasync function loadSSRModule(): Promise<SSRModule> {\n\t\tif (!isProduction && vite) {\n\t\t\treturn (await vite.ssrLoadModule(ssrEntryPath)) as SSRModule;\n\t\t}\n\t\tif (ssrProductionModule) {\n\t\t\treturn import(\n\t\t\t\t/* @vite-ignore */ ssrProductionModule\n\t\t\t) as Promise<SSRModule>;\n\t\t}\n\t\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\t\tconst { pathToFileURL } = await import(/* @vite-ignore */ \"node:url\");\n\t\tconst absPath = pathToFileURL(resolve(root, \"dist/server/ssr.js\")).href;\n\t\treturn import(/* @vite-ignore */ absPath) as Promise<SSRModule>;\n\t}\n\n\tapp.get(\"*\", async (c) => {\n\t\tconst url =\n\t\t\tc.req.path +\n\t\t\t(c.req.url.includes(\"?\") ? \"?\" + c.req.url.split(\"?\")[1] : \"\");\n\n\t\ttry {\n\t\t\t// ISR 缓存命中\n\t\t\tconst cacheKey = url;\n\t\t\tconst cached = isrCache.get(cacheKey);\n\t\t\tif (cached) return c.html(cached);\n\n\t\t\tconst template = await readTemplate(url);\n\t\t\tconst { render, serializeServerData } = await loadSSRModule();\n\n\t\t\tconst locale = parseAcceptLanguage(\n\t\t\t\tc.req.header(\"accept-language\"),\n\t\t\t\tsupportedLocales,\n\t\t\t\tdefaultLocale,\n\t\t\t);\n\n\t\t\tconst {\n\t\t\t\thtml: appHtml,\n\t\t\t\thead,\n\t\t\t\tcss,\n\t\t\t\tserverData,\n\t\t\t\trenderMode,\n\t\t\t} = await render(\n\t\t\t\turl,\n\t\t\t\tlocale,\n\t\t\t\tinternalFetch ? { fetch: internalFetch } : undefined,\n\t\t\t);\n\n\t\t\t// CSR 模式:返回空壳 HTML\n\t\t\tif (renderMode === \"csr\") {\n\t\t\t\treturn c.html(injectCSRShell(template, locale));\n\t\t\t}\n\n\t\t\tconst serializedData = serializeServerData(serverData);\n\n\t\t\tconst finalHtml = injectSSRContent({\n\t\t\t\ttemplate,\n\t\t\t\tlocale,\n\t\t\t\thead,\n\t\t\t\tcss,\n\t\t\t\thtml: appHtml,\n\t\t\t\tserializedData,\n\t\t\t});\n\n\t\t\t// Prerender ISR 缓存\n\t\t\tif (renderMode === \"prerender\") {\n\t\t\t\tisrSet(cacheKey, finalHtml);\n\t\t\t}\n\n\t\t\treturn c.html(finalHtml);\n\t\t} catch (e) {\n\t\t\tif (!isProduction && vite) {\n\t\t\t\tvite.ssrFixStacktrace(e as Error);\n\t\t\t}\n\t\t\tconsole.error(\"[SSR Error]\", e);\n\t\t\treturn c.text(\"Internal Server Error\", 500);\n\t\t}\n\t});\n\n\treturn app;\n}\n","/**\n * createInternalFetch — SSR 内部路由回环 fetch 包装器\n *\n * 将相对路径(/api/…)请求转为 Hono app.fetch 内存调用,\n * 绝对 URL 和非字符串 input 走 globalThis.fetch(真实网络)。\n *\n * 内置递归深度保护:防止控制器误请求非 API 路径触发 catch-all SSR\n * 导致无限递归。\n */\n\nconst MAX_INTERNAL_FETCH_DEPTH = 5;\n\nexport function createInternalFetch(\n\tappFetch: (request: Request) => Promise<Response>,\n): typeof globalThis.fetch {\n\tlet depth = 0;\n\n\treturn ((input: RequestInfo | URL, init?: RequestInit) => {\n\t\t// 只拦截相对路径(以 / 开头),其他一律走真实网络\n\t\tif (typeof input === \"string\" && input.startsWith(\"/\")) {\n\t\t\tif (depth >= MAX_INTERNAL_FETCH_DEPTH) {\n\t\t\t\treturn Promise.resolve(\n\t\t\t\t\tnew Response(\"Internal fetch loop detected\", {\n\t\t\t\t\t\tstatus: 508,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tdepth++;\n\t\t\treturn appFetch(\n\t\t\t\tnew Request(`http://localhost${input}`, init),\n\t\t\t).finally(() => {\n\t\t\t\tdepth--;\n\t\t\t});\n\t\t}\n\n\t\t// 绝对 URL / URL 对象 / Request 对象 → 走正常网络\n\t\treturn globalThis.fetch(input, init);\n\t}) as typeof globalThis.fetch;\n}\n"],"mappings":"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","names":["readFileSync","resolve"]}
|
|
File without changes
|
|
File without changes
|