@finesoft/front 0.1.13 → 0.1.14

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../../core/src/actions/types.ts","../../core/src/actions/dispatcher.ts","../../core/src/intents/dispatcher.ts","../../core/src/dependencies/container.ts","../../core/src/logger/base.ts","../../core/src/logger/local-storage-filter.ts","../../core/src/logger/console.ts","../../core/src/dependencies/make-dependencies.ts","../../core/src/router/router.ts","../../core/src/logger/composite.ts","../../core/src/prefetched-intents/stable-stringify.ts","../../core/src/prefetched-intents/prefetched-intents.ts","../../core/src/framework.ts","../../core/src/http/client.ts","../../core/src/intents/base-controller.ts","../../core/src/data/mapper.ts","../../core/src/bootstrap/define-routes.ts","../../core/src/utils/lru-map.ts","../../core/src/utils/optional.ts","../../core/src/utils/url.ts","../../core/src/utils/uuid.ts","../../browser/src/action-handlers/external-url-action.ts","../../browser/src/utils/try-scroll.ts","../../browser/src/utils/history.ts","../../browser/src/action-handlers/flow-action.ts","../../browser/src/action-handlers/register.ts","../../browser/src/server-data.ts","../../browser/src/start-app.ts","../../ssr/src/render.ts","../../ssr/src/create-render.ts","../../ssr/src/inject.ts","../../ssr/src/server-data.ts","../../server/src/app.ts","../../server/src/locale.ts","../../server/src/create-server.ts","../../server/src/runtime.ts","../../server/src/start.ts"],"sourcesContent":["/// <reference path=\"./shims/server-peer-modules.d.ts\" />\n\n// ===== Core =====\nexport * from \"@finesoft/core\";\n\n// ===== Browser (unique exports only) =====\nexport {\n\tcreatePrefetchedIntentsFromDom,\n\tdeserializeServerData,\n\tHistory,\n\tregisterActionHandlers,\n\tregisterExternalUrlHandler,\n\tregisterFlowActionHandler,\n\tstartBrowserApp,\n\ttryScroll,\n} from \"@finesoft/browser\";\nexport type {\n\tActionHandlerDependencies,\n\tBrowserAppConfig,\n\tExternalUrlDependencies,\n\tFlowActionCallbacks,\n\tFlowActionDependencies,\n} from \"@finesoft/browser\";\n\n// ===== SSR (unique exports only) =====\nexport {\n\tcreateSSRRender,\n\tinjectSSRContent,\n\tserializeServerData,\n\tSSR_PLACEHOLDERS,\n\tssrRender,\n} from \"@finesoft/ssr\";\nexport type {\n\tInjectSSROptions,\n\tSSRRenderConfig,\n\tSSRRenderOptions,\n\tSSRRenderResult,\n} from \"@finesoft/ssr\";\n\n// ===== Server =====\nexport * from \"@finesoft/server\";\n","/**\n * Action 类型定义\n *\n * FlowAction — SPA 内部导航\n * ExternalUrlAction — 打开外部链接\n * CompoundAction — 组合多个 Action\n */\n\n/** Action Kind 常量 */\nexport const ACTION_KINDS = {\n\tFLOW: \"flow\" as const,\n\tEXTERNAL_URL: \"externalUrl\" as const,\n\tCOMPOUND: \"compound\" as const,\n};\n\n/** FlowAction — SPA 导航 */\nexport interface FlowAction {\n\tkind: typeof ACTION_KINDS.FLOW;\n\turl: string;\n\t/** 展示方式: 默认 push,modal 弹窗 */\n\tpresentationContext?: \"default\" | \"modal\";\n}\n\n/** ExternalUrlAction — 外部链接 */\nexport interface ExternalUrlAction {\n\tkind: typeof ACTION_KINDS.EXTERNAL_URL;\n\turl: string;\n}\n\n/** CompoundAction — 组合 Action */\nexport interface CompoundAction {\n\tkind: typeof ACTION_KINDS.COMPOUND;\n\tactions: Action[];\n}\n\n/** 所有 Action 的联合类型 */\nexport type Action = FlowAction | ExternalUrlAction | CompoundAction;\n\n// ===== Type Guards =====\n\nexport function isFlowAction(action: Action): action is FlowAction {\n\treturn action.kind === ACTION_KINDS.FLOW;\n}\n\nexport function isExternalUrlAction(\n\taction: Action,\n): action is ExternalUrlAction {\n\treturn action.kind === ACTION_KINDS.EXTERNAL_URL;\n}\n\nexport function isCompoundAction(action: Action): action is CompoundAction {\n\treturn action.kind === ACTION_KINDS.COMPOUND;\n}\n\n// ===== Factory =====\n\nexport function makeFlowAction(\n\turl: string,\n\tpresentationContext?: FlowAction[\"presentationContext\"],\n): FlowAction {\n\treturn { kind: ACTION_KINDS.FLOW, url, presentationContext };\n}\n\nexport function makeExternalUrlAction(url: string): ExternalUrlAction {\n\treturn { kind: ACTION_KINDS.EXTERNAL_URL, url };\n}\n","/**\n * ActionDispatcher — Action 分发器\n *\n * 注册不同 kind 的 handler,按类型分发。\n * CompoundAction 自动展开递归执行。\n */\n\nimport type { Action } from \"./types\";\nimport { isCompoundAction } from \"./types\";\n\n/** Action 处理器函数类型 */\nexport type ActionHandler<A extends Action = Action> = (\n\taction: A,\n) => Promise<void> | void;\n\nexport class ActionDispatcher {\n\tprivate handlers = new Map<string, ActionHandler>();\n\tprivate wiredActions = new Set<string>();\n\n\t/** 注册指定 kind 的 handler(防止重复注册) */\n\tonAction<A extends Action>(kind: string, handler: ActionHandler<A>): void {\n\t\tif (this.wiredActions.has(kind)) {\n\t\t\tconsole.warn(\n\t\t\t\t`[ActionDispatcher] kind=\"${kind}\" already registered, skipping`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tthis.wiredActions.add(kind);\n\t\tthis.handlers.set(kind, handler as ActionHandler);\n\t}\n\n\t/** 执行一个 Action(CompoundAction 递归展开) */\n\tasync perform(action: Action): Promise<void> {\n\t\tif (isCompoundAction(action)) {\n\t\t\tfor (const subAction of action.actions) {\n\t\t\t\tawait this.perform(subAction);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst handler = this.handlers.get(action.kind);\n\t\tif (!handler) {\n\t\t\tconsole.warn(\n\t\t\t\t`[ActionDispatcher] No handler for kind=\"${action.kind}\"`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tawait handler(action);\n\t}\n}\n","/**\n * IntentDispatcher — Intent 分发器\n *\n * 注册 IntentController,按 intentId 分发。\n */\n\nimport type { Container } from \"../dependencies/container\";\nimport type { Intent, IntentController } from \"./types\";\n\nexport class IntentDispatcher {\n\tprivate controllers = new Map<string, IntentController>();\n\n\t/** 注册一个 IntentController */\n\tregister(controller: IntentController): void {\n\t\tthis.controllers.set(controller.intentId, controller);\n\t}\n\n\t/** 分发 Intent 到对应 Controller */\n\tasync dispatch<T>(intent: Intent<T>, container: Container): Promise<T> {\n\t\tconst controller = this.controllers.get(intent.id);\n\t\tif (!controller) {\n\t\t\tthrow new Error(\n\t\t\t\t`[IntentDispatcher] No controller for \"${intent.id}\". ` +\n\t\t\t\t\t`Registered: [${Array.from(this.controllers.keys()).join(\", \")}]`,\n\t\t\t);\n\t\t}\n\t\treturn controller.perform(intent, container) as Promise<T>;\n\t}\n\n\t/** 检查是否已注册某个 Intent */\n\thas(intentId: string): boolean {\n\t\treturn this.controllers.has(intentId);\n\t}\n}\n","/**\n * Container — 通用的依赖注入容器\n */\n\ntype Factory<T> = () => T;\n\ninterface Registration<T> {\n\tfactory: Factory<T>;\n\tsingleton: boolean;\n\tinstance?: T;\n}\n\nexport class Container {\n\tprivate registrations = new Map<string, Registration<unknown>>();\n\n\t/** 注册依赖(默认单例) */\n\tregister<T>(key: string, factory: Factory<T>, singleton = true): this {\n\t\tthis.registrations.set(key, { factory, singleton });\n\t\treturn this;\n\t}\n\n\t/** 解析依赖 */\n\tresolve<T>(key: string): T {\n\t\tconst reg = this.registrations.get(key);\n\t\tif (!reg) {\n\t\t\tthrow new Error(`[Container] No registration for key: \"${key}\"`);\n\t\t}\n\n\t\tif (reg.singleton) {\n\t\t\tif (reg.instance === undefined) {\n\t\t\t\treg.instance = reg.factory();\n\t\t\t}\n\t\t\treturn reg.instance as T;\n\t\t}\n\t\treturn reg.factory() as T;\n\t}\n\n\t/** 检查是否已注册 */\n\thas(key: string): boolean {\n\t\treturn this.registrations.has(key);\n\t}\n\n\t/** 销毁容器,清除所有缓存 */\n\tdispose(): void {\n\t\tfor (const reg of this.registrations.values()) {\n\t\t\treg.instance = undefined;\n\t\t}\n\t\tthis.registrations.clear();\n\t}\n}\n","/**\n * BaseLogger — 抽象日志基类\n */\n\nimport type { Logger } from \"./types\";\n\nexport abstract class BaseLogger implements Logger {\n\tprotected category: string;\n\n\tconstructor(category: string) {\n\t\tthis.category = category;\n\t}\n\n\tabstract debug(...args: unknown[]): string;\n\tabstract info(...args: unknown[]): string;\n\tabstract warn(...args: unknown[]): string;\n\tabstract error(...args: unknown[]): string;\n}\n","/**\n * localStorage 日志级别过滤\n *\n * 通过 localStorage.onyxLog 控制日志级别:\n * '*=info' — 全局 info 及以上\n * '*=info,Foo=off' — 全局 info,Foo 静默\n * 'Bar=error,Baz=warn' — Bar 只输出 error,Baz 输出 warn+\n */\n\nimport type { Level } from \"./types\";\n\ntype LevelNum = 4 | 3 | 2 | 1 | 0;\n\nconst LEVEL_TO_NUM: Record<string, LevelNum> = {\n\t\"*\": 4,\n\tdebug: 4,\n\tinfo: 3,\n\twarn: 2,\n\terror: 1,\n\toff: 0,\n\t\"\": 0,\n};\n\ninterface Rules {\n\tnamed?: Record<string, LevelNum>;\n\tdefaultLevel?: LevelNum;\n}\n\nlet cachedRules: Rules | undefined;\nlet cachedRaw: string | undefined;\n\nfunction parseRules(): Rules {\n\tif (typeof globalThis.localStorage === \"undefined\") {\n\t\treturn {};\n\t}\n\n\tlet raw: string | null;\n\ttry {\n\t\traw = globalThis.localStorage.getItem(\"onyxLog\");\n\t} catch {\n\t\treturn {};\n\t}\n\n\tif (!raw) return {};\n\n\tif (raw === cachedRaw && cachedRules) return cachedRules;\n\tcachedRaw = raw;\n\n\tconst rules: Rules = {};\n\tconst parts = raw.split(\",\");\n\n\tfor (const part of parts) {\n\t\tconst [name, level] = part.trim().split(\"=\");\n\t\tif (!name || level === undefined) continue;\n\n\t\tconst num = LEVEL_TO_NUM[level.toLowerCase()] ?? undefined;\n\t\tif (num === undefined) continue;\n\n\t\tif (name === \"*\") {\n\t\t\trules.defaultLevel = num;\n\t\t} else {\n\t\t\trules.named ??= {};\n\t\t\trules.named[name] = num;\n\t\t}\n\t}\n\n\tcachedRules = rules;\n\treturn rules;\n}\n\nexport function shouldLog(name: string, level: Level): boolean {\n\tconst rules = parseRules();\n\n\tif (rules.defaultLevel === undefined && !rules.named) {\n\t\treturn true;\n\t}\n\n\tconst currentNum = LEVEL_TO_NUM[level] ?? 4;\n\n\tif (rules.named?.[name] !== undefined) {\n\t\treturn currentNum <= rules.named[name];\n\t}\n\n\tif (rules.defaultLevel !== undefined) {\n\t\treturn currentNum <= rules.defaultLevel;\n\t}\n\n\treturn true;\n}\n\nexport function resetFilterCache(): void {\n\tcachedRules = undefined;\n\tcachedRaw = undefined;\n}\n","/**\n * ConsoleLogger — 基于 console 的日志实现\n */\n\nimport { BaseLogger } from \"./base\";\nimport { shouldLog } from \"./local-storage-filter\";\nimport type { Logger, LoggerFactory } from \"./types\";\n\nexport class ConsoleLogger extends BaseLogger {\n\tdebug(...args: unknown[]): string {\n\t\tif (shouldLog(this.category, \"debug\")) {\n\t\t\tconsole.debug(`[${this.category}]`, ...args);\n\t\t}\n\t\treturn \"\";\n\t}\n\n\tinfo(...args: unknown[]): string {\n\t\tif (shouldLog(this.category, \"info\")) {\n\t\t\tconsole.info(`[${this.category}]`, ...args);\n\t\t}\n\t\treturn \"\";\n\t}\n\n\twarn(...args: unknown[]): string {\n\t\tif (shouldLog(this.category, \"warn\")) {\n\t\t\tconsole.warn(`[${this.category}]`, ...args);\n\t\t}\n\t\treturn \"\";\n\t}\n\n\terror(...args: unknown[]): string {\n\t\tconsole.error(`[${this.category}]`, ...args);\n\t\treturn \"\";\n\t}\n}\n\nexport class ConsoleLoggerFactory implements LoggerFactory {\n\tloggerFor(category: string): Logger {\n\t\treturn new ConsoleLogger(category);\n\t}\n}\n","/**\n * 依赖工厂 — 创建所有基础依赖\n */\n\nimport { ConsoleLoggerFactory } from \"../logger/console\";\nimport type { Logger, LoggerFactory } from \"../logger/types\";\nimport { Container } from \"./container\";\n\n// ===== 重新导出 Logger 类型 =====\nexport type { Logger, LoggerFactory };\n\n// ===== 依赖接口 =====\n\n/** 网络请求层 */\nexport interface Net {\n\tfetch(url: string, options?: RequestInit): Promise<Response>;\n}\n\n/** 多语言状态 */\nexport interface Locale {\n\tlanguage: string;\n\tstorefront: string;\n\tsetActiveLocale(language: string, storefront: string): void;\n}\n\n/** 存储接口 */\nexport interface Storage {\n\tget(key: string): string | undefined;\n\tset(key: string, value: string): void;\n\tdelete(key: string): void;\n}\n\n/** Feature Flags */\nexport interface FeatureFlags {\n\tisEnabled(key: string): boolean;\n\tgetString(key: string): string | undefined;\n\tgetNumber(key: string): number | undefined;\n}\n\n/** Metrics 记录器 */\nexport interface MetricsRecorder {\n\trecordPageView(page: string, fields?: Record<string, unknown>): void;\n\trecordEvent(name: string, fields?: Record<string, unknown>): void;\n}\n\n// ===== 依赖 Key 常量 =====\n\nexport const DEP_KEYS = {\n\tLOGGER: \"logger\",\n\tLOGGER_FACTORY: \"loggerFactory\",\n\tNET: \"net\",\n\tLOCALE: \"locale\",\n\tSTORAGE: \"storage\",\n\tFEATURE_FLAGS: \"featureFlags\",\n\tMETRICS: \"metrics\",\n\tFETCH: \"fetch\",\n} as const;\n\n// ===== 默认实现 =====\n\nclass DefaultLocale implements Locale {\n\tlanguage = \"en\";\n\tstorefront = \"us\";\n\tsetActiveLocale(language: string, storefront: string) {\n\t\tthis.language = language;\n\t\tthis.storefront = storefront;\n\t}\n}\n\nclass MemoryStorage implements Storage {\n\tprivate store = new Map<string, string>();\n\tget(key: string) {\n\t\treturn this.store.get(key);\n\t}\n\tset(key: string, value: string) {\n\t\tthis.store.set(key, value);\n\t}\n\tdelete(key: string) {\n\t\tthis.store.delete(key);\n\t}\n}\n\nclass DefaultFeatureFlags implements FeatureFlags {\n\tprivate flags: Record<string, boolean | string | number>;\n\tconstructor(flags: Record<string, boolean | string | number> = {}) {\n\t\tthis.flags = flags;\n\t}\n\tisEnabled(key: string) {\n\t\treturn this.flags[key] === true;\n\t}\n\tgetString(key: string) {\n\t\tconst v = this.flags[key];\n\t\treturn typeof v === \"string\" ? v : undefined;\n\t}\n\tgetNumber(key: string) {\n\t\tconst v = this.flags[key];\n\t\treturn typeof v === \"number\" ? v : undefined;\n\t}\n}\n\nclass ConsoleMetrics implements MetricsRecorder {\n\trecordPageView(page: string, fields?: Record<string, unknown>) {\n\t\tconsole.info(`[Metrics:PageView] ${page}`, fields ?? \"\");\n\t}\n\trecordEvent(name: string, fields?: Record<string, unknown>) {\n\t\tconsole.info(`[Metrics:Event] ${name}`, fields ?? \"\");\n\t}\n}\n\n// ===== 依赖工厂 =====\n\nexport interface MakeDependenciesOptions {\n\tfetch?: typeof globalThis.fetch;\n\tlanguage?: string;\n\tstorefront?: string;\n\tfeatureFlags?: Record<string, boolean | string | number>;\n}\n\nexport function makeDependencies(\n\tcontainer: Container,\n\toptions: MakeDependenciesOptions = {},\n): void {\n\tconst {\n\t\tfetch: fetchFn = globalThis.fetch?.bind(globalThis),\n\t\tlanguage = \"en\",\n\t\tstorefront = \"us\",\n\t\tfeatureFlags = {},\n\t} = options;\n\n\tconst loggerFactory = new ConsoleLoggerFactory();\n\tcontainer.register<LoggerFactory>(\n\t\tDEP_KEYS.LOGGER_FACTORY,\n\t\t() => loggerFactory,\n\t);\n\n\tcontainer.register<Logger>(DEP_KEYS.LOGGER, () =>\n\t\tloggerFactory.loggerFor(\"framework\"),\n\t);\n\n\tcontainer.register<Net>(DEP_KEYS.NET, () => ({\n\t\tfetch: (url: string, opts?: RequestInit) => fetchFn(url, opts),\n\t}));\n\n\tcontainer.register<Locale>(DEP_KEYS.LOCALE, () => {\n\t\tconst locale = new DefaultLocale();\n\t\tlocale.setActiveLocale(language, storefront);\n\t\treturn locale;\n\t});\n\n\tcontainer.register<Storage>(DEP_KEYS.STORAGE, () => new MemoryStorage());\n\n\tcontainer.register<FeatureFlags>(\n\t\tDEP_KEYS.FEATURE_FLAGS,\n\t\t() => new DefaultFeatureFlags(featureFlags),\n\t);\n\n\tcontainer.register<MetricsRecorder>(\n\t\tDEP_KEYS.METRICS,\n\t\t() => new ConsoleMetrics(),\n\t);\n\n\tcontainer.register(DEP_KEYS.FETCH, () => fetchFn);\n}\n","/**\n * URL 路由器 — URL pattern → Intent + FlowAction\n */\n\nimport { makeFlowAction, type FlowAction } from \"../actions/types\";\nimport type { Intent } from \"../intents/types\";\n\n/** 路由匹配结果 */\nexport interface RouteMatch {\n\tintent: Intent;\n\taction: FlowAction;\n}\n\ninterface RouteDefinition {\n\tpattern: string;\n\tintentId: string;\n\tregex: RegExp;\n\tparamNames: string[];\n}\n\nexport class Router {\n\tprivate routes: RouteDefinition[] = [];\n\n\t/** 添加路由规则 */\n\tadd(pattern: string, intentId: string): this {\n\t\tconst paramNames: string[] = [];\n\n\t\tconst regexStr = pattern.replace(\n\t\t\t/\\/:(\\w+)(\\?)?/g,\n\t\t\t(_, name: string, optional: string) => {\n\t\t\t\tparamNames.push(name);\n\t\t\t\treturn optional ? \"(?:/([^/]+))?\" : \"/([^/]+)\";\n\t\t\t},\n\t\t);\n\n\t\tthis.routes.push({\n\t\t\tpattern,\n\t\t\tintentId,\n\t\t\tregex: new RegExp(`^${regexStr}/?$`),\n\t\t\tparamNames,\n\t\t});\n\n\t\treturn this;\n\t}\n\n\t/** 解析 URL → RouteMatch */\n\tresolve(urlOrPath: string): RouteMatch | null {\n\t\tconst path = this.extractPath(urlOrPath);\n\t\tconst queryParams = this.extractQueryParams(urlOrPath);\n\n\t\tfor (const route of this.routes) {\n\t\t\tconst match = path.match(route.regex);\n\t\t\tif (match) {\n\t\t\t\tconst params: Record<string, string> = {};\n\t\t\t\troute.paramNames.forEach((name, index) => {\n\t\t\t\t\tconst value = match[index + 1];\n\t\t\t\t\tif (value) params[name] = value;\n\t\t\t\t});\n\t\t\t\tfor (const [k, v] of Object.entries(queryParams)) {\n\t\t\t\t\tif (!(k in params)) params[k] = v;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tintent: { id: route.intentId, params },\n\t\t\t\t\taction: makeFlowAction(urlOrPath),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/** 获取所有已注册的路由 */\n\tgetRoutes(): string[] {\n\t\treturn this.routes.map((r) => `${r.pattern} → ${r.intentId}`);\n\t}\n\n\tprivate extractPath(url: string): string {\n\t\ttry {\n\t\t\tconst parsed = new URL(url, \"http://localhost\");\n\t\t\treturn parsed.pathname;\n\t\t} catch {\n\t\t\treturn url.split(\"?\")[0].split(\"#\")[0];\n\t\t}\n\t}\n\n\tprivate extractQueryParams(url: string): Record<string, string> {\n\t\ttry {\n\t\t\tconst parsed = new URL(url, \"http://localhost\");\n\t\t\tconst params: Record<string, string> = {};\n\t\t\tparsed.searchParams.forEach((v, k) => {\n\t\t\t\tparams[k] = v;\n\t\t\t});\n\t\t\treturn params;\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}\n}\n","/**\n * Composite Logger — 组合日志,广播到多个后端\n */\n\nimport type { Logger, LoggerFactory } from \"./types\";\n\nexport class CompositeLoggerFactory implements LoggerFactory {\n\tconstructor(private readonly factories: LoggerFactory[]) {}\n\n\tloggerFor(name: string): Logger {\n\t\treturn new CompositeLogger(\n\t\t\tthis.factories.map((f) => f.loggerFor(name)),\n\t\t);\n\t}\n}\n\nexport class CompositeLogger implements Logger {\n\tconstructor(private readonly loggers: Logger[]) {}\n\n\tdebug(...args: unknown[]): string {\n\t\treturn this.callAll(\"debug\", args);\n\t}\n\n\tinfo(...args: unknown[]): string {\n\t\treturn this.callAll(\"info\", args);\n\t}\n\n\twarn(...args: unknown[]): string {\n\t\treturn this.callAll(\"warn\", args);\n\t}\n\n\terror(...args: unknown[]): string {\n\t\treturn this.callAll(\"error\", args);\n\t}\n\n\tprivate callAll(\n\t\tmethod: \"debug\" | \"info\" | \"warn\" | \"error\",\n\t\targs: unknown[],\n\t): string {\n\t\tfor (const logger of this.loggers) {\n\t\t\tlogger[method](...args);\n\t\t}\n\t\treturn \"\";\n\t}\n}\n","/**\n * stableStringify — 确定性 JSON 序列化(keys 按字母排序)\n *\n * 用作缓存 key:相同内容的对象始终产生相同字符串。\n */\n\nexport function stableStringify(obj: unknown): string {\n\tif (obj === null || obj === undefined) return String(obj);\n\tif (typeof obj !== \"object\") return JSON.stringify(obj);\n\tif (Array.isArray(obj)) {\n\t\treturn \"[\" + obj.map(stableStringify).join(\",\") + \"]\";\n\t}\n\tconst keys = Object.keys(obj as Record<string, unknown>).sort();\n\tconst parts = keys\n\t\t.filter((k) => (obj as Record<string, unknown>)[k] !== undefined)\n\t\t.map(\n\t\t\t(k) =>\n\t\t\t\tJSON.stringify(k) +\n\t\t\t\t\":\" +\n\t\t\t\tstableStringify((obj as Record<string, unknown>)[k]),\n\t\t);\n\treturn \"{\" + parts.join(\",\") + \"}\";\n}\n","/**\n * PrefetchedIntents — SSR 数据缓存\n *\n * 服务端渲染时将 Intent→Data 映射序列化嵌入 HTML,\n * 客户端 hydrate 时提取缓存。Framework.dispatch() 优先查缓存,\n * 命中则直接返回,未命中则走 Controller 调度。\n */\n\nimport type { Intent } from \"../intents/types\";\nimport { stableStringify } from \"./stable-stringify\";\n\n/** 预获取的 Intent-Data 对 */\nexport interface PrefetchedIntent {\n\tintent: Intent;\n\tdata: unknown;\n}\n\nexport class PrefetchedIntents {\n\tprivate intents: Map<string, unknown>;\n\n\tprivate constructor(intents: Map<string, unknown>) {\n\t\tthis.intents = intents;\n\t}\n\n\t/** 从 PrefetchedIntent 数组创建缓存实例 */\n\tstatic fromArray(items: PrefetchedIntent[]): PrefetchedIntents {\n\t\tconst map = new Map<string, unknown>();\n\t\tfor (const item of items) {\n\t\t\tif (item.intent && item.data !== undefined) {\n\t\t\t\tconst key = stableStringify(item.intent);\n\t\t\t\tmap.set(key, item.data);\n\t\t\t}\n\t\t}\n\t\treturn new PrefetchedIntents(map);\n\t}\n\n\t/** 创建空缓存实例 */\n\tstatic empty(): PrefetchedIntents {\n\t\treturn new PrefetchedIntents(new Map());\n\t}\n\n\t/**\n\t * 获取缓存的 Intent 结果(一次性使用)。\n\t * 命中后从缓存中删除。\n\t */\n\tget<T>(intent: Intent<T>): T | undefined {\n\t\tconst key = stableStringify(intent);\n\t\tconst data = this.intents.get(key);\n\t\tif (data !== undefined) {\n\t\t\tthis.intents.delete(key);\n\t\t\treturn data as T;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/** 检查缓存中是否有某个 Intent 的数据 */\n\thas(intent: Intent): boolean {\n\t\treturn this.intents.has(stableStringify(intent));\n\t}\n\n\t/** 缓存中的条目数 */\n\tget size(): number {\n\t\treturn this.intents.size;\n\t}\n}\n","/**\n * Framework — 框架核心类\n *\n * 对应原版 Jet 类,统一管理: DI 容器、Intent 分发、Action 分发、路由、Metrics。\n * 纯 TypeScript,不依赖任何 UI 框架。\n */\n\nimport { ActionDispatcher, type ActionHandler } from \"./actions/dispatcher\";\nimport type { Action } from \"./actions/types\";\nimport { Container } from \"./dependencies/container\";\nimport type { MetricsRecorder } from \"./dependencies/make-dependencies\";\nimport {\n\tDEP_KEYS,\n\tmakeDependencies,\n\ttype MakeDependenciesOptions,\n} from \"./dependencies/make-dependencies\";\nimport { IntentDispatcher } from \"./intents/dispatcher\";\nimport type { Intent, IntentController } from \"./intents/types\";\nimport type { Logger } from \"./logger/types\";\nimport type { BasePage } from \"./models/page\";\nimport { PrefetchedIntents } from \"./prefetched-intents/prefetched-intents\";\nimport { Router, type RouteMatch } from \"./router/router\";\n\n/** Framework 初始化配置 */\nexport interface FrameworkConfig extends MakeDependenciesOptions {\n\tsetupRoutes?: (router: Router) => void;\n\tprefetchedIntents?: PrefetchedIntents;\n}\n\nexport class Framework {\n\treadonly container: Container;\n\treadonly intentDispatcher: IntentDispatcher;\n\treadonly actionDispatcher: ActionDispatcher;\n\treadonly router: Router;\n\treadonly prefetchedIntents: PrefetchedIntents;\n\n\tprivate constructor(\n\t\tcontainer: Container,\n\t\tprefetchedIntents: PrefetchedIntents,\n\t) {\n\t\tthis.container = container;\n\t\tthis.intentDispatcher = new IntentDispatcher();\n\t\tthis.actionDispatcher = new ActionDispatcher();\n\t\tthis.router = new Router();\n\t\tthis.prefetchedIntents = prefetchedIntents;\n\t}\n\n\t/** 创建并初始化 Framework 实例 */\n\tstatic create(config: FrameworkConfig = {}): Framework {\n\t\tconst container = new Container();\n\t\tmakeDependencies(container, config);\n\n\t\tconst fw = new Framework(\n\t\t\tcontainer,\n\t\t\tconfig.prefetchedIntents ?? PrefetchedIntents.empty(),\n\t\t);\n\n\t\tconfig.setupRoutes?.(fw.router);\n\n\t\treturn fw;\n\t}\n\n\t/** 分发 Intent — 获取页面数据 */\n\tasync dispatch<T>(intent: Intent<T>): Promise<T> {\n\t\tconst logger = this.container.resolve<Logger>(DEP_KEYS.LOGGER);\n\n\t\tconst cached = this.prefetchedIntents.get(intent);\n\t\tif (cached !== undefined) {\n\t\t\tlogger.debug(\n\t\t\t\t`[Framework] re-using prefetched intent response for: ${intent.id}`,\n\t\t\t\tintent.params,\n\t\t\t);\n\t\t\treturn cached;\n\t\t}\n\n\t\tlogger.debug(\n\t\t\t`[Framework] dispatch intent: ${intent.id}`,\n\t\t\tintent.params,\n\t\t);\n\t\treturn this.intentDispatcher.dispatch(intent, this.container);\n\t}\n\n\t/** 执行 Action — 处理用户交互 */\n\tasync perform(action: Action): Promise<void> {\n\t\tconst logger = this.container.resolve<Logger>(DEP_KEYS.LOGGER);\n\t\tlogger.debug(`[Framework] perform action: ${action.kind}`);\n\t\treturn this.actionDispatcher.perform(action);\n\t}\n\n\t/** 路由 URL — 将 URL 解析为 Intent + Action */\n\trouteUrl(url: string): RouteMatch | null {\n\t\treturn this.router.resolve(url);\n\t}\n\n\t/** 记录页面访问事件 */\n\tdidEnterPage(page: BasePage): void {\n\t\tconst metrics = this.container.resolve<MetricsRecorder>(\n\t\t\tDEP_KEYS.METRICS,\n\t\t);\n\t\tmetrics.recordPageView(page.pageType, {\n\t\t\tpageId: page.id,\n\t\t\ttitle: page.title,\n\t\t});\n\t}\n\n\t/** 注册 Action 处理器 */\n\tonAction<A extends Action>(kind: string, handler: ActionHandler<A>): void {\n\t\tthis.actionDispatcher.onAction(kind, handler);\n\t}\n\n\t/** 注册 Intent Controller */\n\tregisterIntent(controller: IntentController): void {\n\t\tthis.intentDispatcher.register(controller);\n\t}\n\n\t/** 销毁 Framework 实例 */\n\tdispose(): void {\n\t\tthis.container.dispose();\n\t}\n}\n","/**\n * HttpClient — 通用 HTTP 客户端基类\n *\n * 为 API Client 提供标准化的 HTTP 请求能力。\n * 子类继承后只需关注业务端点定义,不需要重复实现 fetch / JSON 解析 / 错误处理。\n */\n\n/** HTTP 请求错误 */\nexport class HttpError extends Error {\n\tconstructor(\n\t\tpublic readonly status: number,\n\t\tpublic readonly statusText: string,\n\t\tpublic readonly body?: string,\n\t) {\n\t\tsuper(`HTTP ${status}: ${statusText}`);\n\t\tthis.name = \"HttpError\";\n\t}\n}\n\n/** HttpClient 构造配置 */\nexport interface HttpClientConfig {\n\t/** API base URL(如 \"/api\" 或 \"https://example.com/api\") */\n\tbaseUrl: string;\n\t/** 默认请求头 */\n\tdefaultHeaders?: Record<string, string>;\n\t/** 自定义 fetch 实现(便于测试或 SSR) */\n\tfetch?: typeof globalThis.fetch;\n}\n\n/**\n * 通用 HTTP 客户端基类\n *\n * 使用方式: 创建子类继承 HttpClient,定义业务方法调用 this.get() / this.post() 等。\n *\n * @example\n * ```ts\n * class MyApiClient extends HttpClient {\n * async getUser(id: string) {\n * return this.get<User>(`/users/${id}`);\n * }\n * }\n * ```\n */\nexport abstract class HttpClient {\n\tprotected readonly baseUrl: string;\n\tprotected readonly defaultHeaders: Record<string, string>;\n\tprotected readonly fetchFn: typeof globalThis.fetch;\n\n\tconstructor(config: HttpClientConfig) {\n\t\tthis.baseUrl = config.baseUrl;\n\t\tthis.defaultHeaders = config.defaultHeaders ?? {};\n\t\tthis.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n\t}\n\n\t/** GET 请求,返回解析后的 JSON */\n\tprotected async get<T>(\n\t\tpath: string,\n\t\tparams?: Record<string, string>,\n\t): Promise<T> {\n\t\treturn this.request<T>(\"GET\", path, { params });\n\t}\n\n\t/** POST 请求,自动序列化 body 为 JSON */\n\tprotected async post<T>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\tparams?: Record<string, string>,\n\t): Promise<T> {\n\t\treturn this.request<T>(\"POST\", path, { body, params });\n\t}\n\n\t/** PUT 请求 */\n\tprotected async put<T>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\tparams?: Record<string, string>,\n\t): Promise<T> {\n\t\treturn this.request<T>(\"PUT\", path, { body, params });\n\t}\n\n\t/** DELETE 请求 */\n\tprotected async del<T>(\n\t\tpath: string,\n\t\tparams?: Record<string, string>,\n\t): Promise<T> {\n\t\treturn this.request<T>(\"DELETE\", path, { params });\n\t}\n\n\t/**\n\t * 底层请求方法 — 子类可覆写以自定义行为\n\t *\n\t * 自动处理:\n\t * - URL 拼接 (baseUrl + path + params)\n\t * - 默认 headers 合并\n\t * - JSON body 序列化\n\t * - 响应 JSON 解析\n\t * - 非 2xx 状态码抛出 HttpError\n\t */\n\tprotected async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\toptions?: {\n\t\t\tparams?: Record<string, string>;\n\t\t\tbody?: unknown;\n\t\t\theaders?: Record<string, string>;\n\t\t},\n\t): Promise<T> {\n\t\tconst url = this.buildUrl(path, options?.params);\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t...this.defaultHeaders,\n\t\t\t...options?.headers,\n\t\t};\n\n\t\tconst init: RequestInit = { method, headers };\n\n\t\tif (options?.body !== undefined) {\n\t\t\theaders[\"Content-Type\"] =\n\t\t\t\theaders[\"Content-Type\"] ?? \"application/json\";\n\t\t\tinit.body = JSON.stringify(options.body);\n\t\t}\n\n\t\tconst response = await this.fetchFn(url, init);\n\n\t\tif (!response.ok) {\n\t\t\tconst body = await response.text().catch(() => undefined);\n\t\t\tthrow new HttpError(response.status, response.statusText, body);\n\t\t}\n\n\t\treturn response.json();\n\t}\n\n\t/** 构建完整 URL — 子类可覆写以自定义 URL 拼接逻辑 */\n\tprotected buildUrl(path: string, params?: Record<string, string>): string {\n\t\tconst base = this.baseUrl.endsWith(\"/\")\n\t\t\t? this.baseUrl.slice(0, -1)\n\t\t\t: this.baseUrl;\n\t\tconst normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n\t\tconst url = new URL(`${base}${normalizedPath}`, \"http://placeholder\");\n\n\t\tif (params) {\n\t\t\tfor (const [k, v] of Object.entries(params)) {\n\t\t\t\turl.searchParams.set(k, v);\n\t\t\t}\n\t\t}\n\n\t\t// 如果 baseUrl 是绝对 URL,返回完整 URL;否则只返回 path + search\n\t\tif (this.baseUrl.startsWith(\"http\")) {\n\t\t\treturn url.toString();\n\t\t}\n\t\treturn `${url.pathname}${url.search}`;\n\t}\n}\n","/**\n * BaseController — 抽象 Intent Controller 基类\n *\n * 提供标准化的 try/catch → fallback 模式。\n * 子类只需实现 execute() 和可选的 fallback()。\n */\n\nimport type { Container } from \"../dependencies/container\";\nimport type { Intent, IntentController } from \"./types\";\n\n/**\n * 抽象 Controller 基类\n *\n * 统一处理:\n * - 类型安全的参数提取 (TParams)\n * - 返回类型约束 (TResult)\n * - try/catch 错误处理 + 可选 fallback\n *\n * @example\n * ```ts\n * class ProductController extends BaseController<{ productId: string }, ProductPage> {\n * readonly intentId = \"product-page\";\n *\n * async execute(params: { productId: string }, container: Container) {\n * const api = container.resolve<ApiClient>(\"api\");\n * return api.getProduct(params.productId);\n * }\n *\n * fallback(params: { productId: string }, error: Error) {\n * return getMockProduct(params.productId);\n * }\n * }\n * ```\n */\nexport abstract class BaseController<\n\tTParams extends Record<string, string | undefined> = Record<string, string>,\n\tTResult = unknown,\n> implements IntentController<TResult> {\n\t/** Controller 对应的 Intent ID */\n\tabstract readonly intentId: string;\n\n\t/**\n\t * 执行业务逻辑 — 子类必须实现\n\t *\n\t * @param params - Intent 参数(已类型化)\n\t * @param container - DI 容器\n\t * @returns 页面数据\n\t */\n\tabstract execute(\n\t\tparams: TParams,\n\t\tcontainer: Container,\n\t): Promise<TResult> | TResult;\n\n\t/**\n\t * 错误回退 — 子类可选覆写\n\t *\n\t * 当 execute() 抛出异常时调用。\n\t * 默认行为: 重新抛出原始错误。\n\t *\n\t * @param params - Intent 参数\n\t * @param error - execute() 抛出的错误\n\t * @returns 回退数据\n\t */\n\tfallback(params: TParams, error: Error): Promise<TResult> | TResult {\n\t\tthrow error;\n\t}\n\n\t/**\n\t * IntentController.perform() 实现\n\t *\n\t * 自动 try/catch → fallback 模式。\n\t */\n\tasync perform(\n\t\tintent: Intent<TResult>,\n\t\tcontainer: Container,\n\t): Promise<TResult> {\n\t\tconst params = (intent.params ?? {}) as TParams;\n\t\ttry {\n\t\t\treturn await this.execute(params, container);\n\t\t} catch (e) {\n\t\t\treturn this.fallback(\n\t\t\t\tparams,\n\t\t\t\te instanceof Error ? e : new Error(String(e)),\n\t\t\t);\n\t\t}\n\t}\n}\n","/**\n * Mapper 类型工具 — 标准化数据转换管线\n *\n * 提供类型约定和组合函数,让 API 响应 → 页面模型 的转换有统一的签名模式。\n */\n\n/** 同步映射函数 */\nexport type Mapper<TInput, TOutput> = (input: TInput) => TOutput;\n\n/** 异步映射函数 */\nexport type AsyncMapper<TInput, TOutput> = (\n\tinput: TInput,\n) => TOutput | Promise<TOutput>;\n\n/**\n * 组合两个同步 Mapper: A → B → C\n */\nexport function pipe<A, B, C>(m1: Mapper<A, B>, m2: Mapper<B, C>): Mapper<A, C>;\n/**\n * 组合三个同步 Mapper: A → B → C → D\n */\nexport function pipe<A, B, C, D>(\n\tm1: Mapper<A, B>,\n\tm2: Mapper<B, C>,\n\tm3: Mapper<C, D>,\n): Mapper<A, D>;\n/**\n * 组合四个同步 Mapper: A → B → C → D → E\n */\nexport function pipe<A, B, C, D, E>(\n\tm1: Mapper<A, B>,\n\tm2: Mapper<B, C>,\n\tm3: Mapper<C, D>,\n\tm4: Mapper<D, E>,\n): Mapper<A, E>;\n/**\n * 组合任意数量的同步 Mapper\n */\nexport function pipe(\n\t...mappers: Mapper<unknown, unknown>[]\n): Mapper<unknown, unknown>;\nexport function pipe(\n\t...mappers: Mapper<unknown, unknown>[]\n): Mapper<unknown, unknown> {\n\treturn (input: unknown) =>\n\t\tmappers.reduce((acc, mapper) => mapper(acc), input);\n}\n\n/**\n * 组合两个可能异步的 Mapper: A → B → C\n */\nexport function pipeAsync<A, B, C>(\n\tm1: AsyncMapper<A, B>,\n\tm2: AsyncMapper<B, C>,\n): AsyncMapper<A, C>;\n/**\n * 组合三个可能异步的 Mapper\n */\nexport function pipeAsync<A, B, C, D>(\n\tm1: AsyncMapper<A, B>,\n\tm2: AsyncMapper<B, C>,\n\tm3: AsyncMapper<C, D>,\n): AsyncMapper<A, D>;\nexport function pipeAsync(\n\t...mappers: AsyncMapper<unknown, unknown>[]\n): AsyncMapper<unknown, unknown> {\n\treturn async (input: unknown) => {\n\t\tlet acc = input;\n\t\tfor (const mapper of mappers) {\n\t\t\tacc = await mapper(acc);\n\t\t}\n\t\treturn acc;\n\t};\n}\n\n/**\n * 将一个 Mapper 应用到数组的每个元素\n */\nexport function mapEach<TInput, TOutput>(\n\tmapper: Mapper<TInput, TOutput>,\n): Mapper<TInput[], TOutput[]> {\n\treturn (items) => items.map(mapper);\n}\n","/**\n * defineRoutes — 声明式路由 + Controller 注册\n *\n * 将命令式的路由注册 (20+ 行 framework.router.add / framework.registerIntent)\n * 简化为声明式配置数组。\n */\n\nimport type { Framework } from \"../framework\";\nimport type { IntentController } from \"../intents/types\";\n\n/** 单条路由定义 */\nexport interface RouteDefinition {\n\t/** URL pattern (如 \"/product/:productId\") */\n\tpath: string;\n\t/** Intent ID (如 \"product-page\") */\n\tintentId: string;\n\t/**\n\t * Controller 实例(可选)。\n\t * 同一个 intentId 的多条路由只需在第一条提供 controller。\n\t */\n\tcontroller?: IntentController;\n}\n\n/**\n * 声明式注册路由和 Controller\n *\n * - 自动去重: 同一 intentId 的 controller 只注册一次\n * - 路由和 controller 在同一个配置数组中,方便检查一致性\n *\n * @example\n * ```ts\n * defineRoutes(framework, [\n * { path: \"/\", intentId: \"home\", controller: new HomeController() },\n * { path: \"/product/:id\", intentId: \"product\", controller: new ProductController() },\n * { path: \"/search\", intentId: \"search\", controller: new SearchController() },\n * { path: \"/charts/:type\", intentId: \"charts\", controller: new ChartsController() },\n * { path: \"/charts\", intentId: \"charts\" }, // 同 intentId,不需要重复 controller\n * ]);\n * ```\n */\nexport function defineRoutes(\n\tframework: Framework,\n\tdefinitions: RouteDefinition[],\n): void {\n\tconst registeredIntents = new Set<string>();\n\n\tfor (const def of definitions) {\n\t\t// 注册 Controller(每个 intentId 只注册一次)\n\t\tif (def.controller && !registeredIntents.has(def.intentId)) {\n\t\t\tframework.registerIntent(def.controller);\n\t\t\tregisteredIntents.add(def.intentId);\n\t\t}\n\n\t\t// 注册路由\n\t\tframework.router.add(def.path, def.intentId);\n\t}\n}\n","/**\n * LruMap — 固定容量的 LRU 缓存\n */\n\nexport class LruMap<K, V> {\n\tprivate map = new Map<K, V>();\n\tprivate readonly capacity: number;\n\n\tconstructor(capacity: number) {\n\t\tthis.capacity = capacity;\n\t}\n\n\tget(key: K): V | undefined {\n\t\tconst value = this.map.get(key);\n\t\tif (value !== undefined) {\n\t\t\t// 移到末尾(最近使用)\n\t\t\tthis.map.delete(key);\n\t\t\tthis.map.set(key, value);\n\t\t}\n\t\treturn value;\n\t}\n\n\tset(key: K, value: V): void {\n\t\tif (this.map.has(key)) {\n\t\t\tthis.map.delete(key);\n\t\t} else if (this.map.size >= this.capacity) {\n\t\t\t// 删除最旧的(第一个)\n\t\t\tconst oldest = this.map.keys().next().value;\n\t\t\tif (oldest !== undefined) {\n\t\t\t\tthis.map.delete(oldest);\n\t\t\t}\n\t\t}\n\t\tthis.map.set(key, value);\n\t}\n\n\thas(key: K): boolean {\n\t\treturn this.map.has(key);\n\t}\n\n\tdelete(key: K): boolean {\n\t\treturn this.map.delete(key);\n\t}\n\n\tget size(): number {\n\t\treturn this.map.size;\n\t}\n\n\tclear(): void {\n\t\tthis.map.clear();\n\t}\n}\n","/**\n * Optional 类型工具\n */\n\nexport type None = null | undefined;\nexport type Optional<T> = T | None;\n\nexport function isSome<T>(value: Optional<T>): value is T {\n\treturn value !== null && value !== undefined;\n}\n\nexport function isNone<T>(value: Optional<T>): value is None {\n\treturn value === null || value === undefined;\n}\n","/**\n * URL 工具函数\n */\n\n/** 移除 URL scheme (https://, http://) */\nexport function removeScheme(url: string): string {\n\treturn url.replace(/^https?:\\/\\//, \"\");\n}\n\n/** 移除 URL host 部分,保留路径 */\nexport function removeHost(url: string): string {\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\treturn parsed.pathname + parsed.search + parsed.hash;\n\t} catch {\n\t\treturn url;\n\t}\n}\n\n/** 移除 query 参数 */\nexport function removeQueryParams(url: string): string {\n\treturn url.split(\"?\")[0];\n}\n\n/** 获取 URL 的基础路径(无 query、hash) */\nexport function getBaseUrl(url: string): string {\n\treturn url.split(\"?\")[0].split(\"#\")[0];\n}\n\n/** 构建 URL(路径 + query 参数) */\nexport function buildUrl(\n\tpath: string,\n\tparams?: Record<string, string | undefined>,\n): string {\n\tif (!params) return path;\n\n\tconst searchParams = new URLSearchParams();\n\tfor (const [key, value] of Object.entries(params)) {\n\t\tif (value !== undefined) {\n\t\t\tsearchParams.set(key, value);\n\t\t}\n\t}\n\n\tconst qs = searchParams.toString();\n\treturn qs ? `${path}?${qs}` : path;\n}\n","/**\n * UUID v4 生成器\n */\n\nexport function generateUuid(): string {\n\tif (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n\t\treturn crypto.randomUUID();\n\t}\n\t// Fallback\n\treturn \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n\t\tconst r = (Math.random() * 16) | 0;\n\t\tconst v = c === \"x\" ? r : (r & 0x3) | 0x8;\n\t\treturn v.toString(16);\n\t});\n}\n","/**\n * ExternalUrl Action Handler — 外部链接处理器\n */\n\nimport type { ExternalUrlAction, Framework, Logger } from \"@finesoft/core\";\nimport { ACTION_KINDS } from \"@finesoft/core\";\n\nexport interface ExternalUrlDependencies {\n\tframework: Framework;\n\tlog: Logger;\n}\n\nexport function registerExternalUrlHandler(\n\tdeps: ExternalUrlDependencies,\n): void {\n\tconst { framework, log } = deps;\n\n\tframework.onAction(\n\t\tACTION_KINDS.EXTERNAL_URL,\n\t\t(action: ExternalUrlAction) => {\n\t\t\tlog.debug(`ExternalUrlAction → ${action.url}`);\n\t\t\twindow.open(action.url, \"_blank\", \"noopener,noreferrer\");\n\t\t},\n\t);\n}\n","/**\n * tryScroll — 渐进式滚动位置恢复\n *\n * 使用 rAF 循环等待页面高度足够后恢复滚动位置。\n */\n\nimport type { Logger } from \"@finesoft/core\";\n\nconst MAX_TRIES = 100;\nconst FUDGE = 16;\n\nlet pendingFrame: number | null = null;\n\nexport function tryScroll(\n\tlog: Logger,\n\tgetScrollableElement: () => HTMLElement | null,\n\tscrollY: number,\n): void {\n\tif (pendingFrame !== null) {\n\t\tcancelAnimationFrame(pendingFrame);\n\t\tpendingFrame = null;\n\t}\n\n\tlet tries = 0;\n\n\tpendingFrame = requestAnimationFrame(function attempt() {\n\t\tif (++tries >= MAX_TRIES) {\n\t\t\tlog.warn(\n\t\t\t\t`tryScroll: gave up after ${MAX_TRIES} frames, target=${scrollY}`,\n\t\t\t);\n\t\t\tpendingFrame = null;\n\t\t\treturn;\n\t\t}\n\n\t\tconst el = getScrollableElement();\n\t\tif (!el) {\n\t\t\tlog.warn(\n\t\t\t\t\"could not restore scroll: the scrollable element is missing\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { scrollHeight, offsetHeight } = el;\n\t\tconst canScroll = scrollY + offsetHeight <= scrollHeight + FUDGE;\n\n\t\tif (!canScroll) {\n\t\t\tlog.info(\"page is not tall enough for scroll yet\", {\n\t\t\t\tscrollHeight,\n\t\t\t\toffsetHeight,\n\t\t\t});\n\t\t\tpendingFrame = requestAnimationFrame(attempt);\n\t\t\treturn;\n\t\t}\n\n\t\tel.scrollTop = scrollY;\n\t\tlog.info(\"scroll restored to\", scrollY);\n\t\tpendingFrame = null;\n\t});\n}\n","/**\n * History 管理器 — 浏览器历史状态 + 滚动位置\n */\n\nimport type { Logger } from \"@finesoft/core\";\nimport { LruMap, generateUuid } from \"@finesoft/core\";\nimport { tryScroll } from \"./try-scroll\";\n\nconst HISTORY_SIZE_LIMIT = 10;\n\ninterface HistoryEntry<State> {\n\tstate: State;\n\tscrollY: number;\n}\n\ninterface HistoryOptions {\n\tgetScrollablePageElement: () => HTMLElement | null;\n}\n\nexport class History<State> {\n\tprivate readonly entries: LruMap<string, HistoryEntry<State>>;\n\tprivate readonly log: Logger;\n\tprivate readonly getScrollablePageElement: () => HTMLElement | null;\n\tprivate currentStateId: string | undefined;\n\n\tconstructor(\n\t\tlog: Logger,\n\t\toptions: HistoryOptions,\n\t\tsizeLimit = HISTORY_SIZE_LIMIT,\n\t) {\n\t\tthis.entries = new LruMap(sizeLimit);\n\t\tthis.log = log;\n\t\tthis.getScrollablePageElement = options.getScrollablePageElement;\n\t}\n\n\treplaceState(state: State, url: string): void {\n\t\tconst id = generateUuid();\n\t\twindow.history.replaceState({ id }, \"\", url);\n\t\tthis.currentStateId = id;\n\t\tthis.entries.set(id, { state, scrollY: 0 });\n\t\tthis.scrollTop = 0;\n\t\tthis.log.info(\"replaceState\", state, url, id);\n\t}\n\n\tpushState(state: State, url: string): void {\n\t\tconst id = generateUuid();\n\t\twindow.history.pushState({ id }, \"\", url);\n\t\tthis.currentStateId = id;\n\t\tthis.entries.set(id, { state, scrollY: 0 });\n\t\tthis.scrollTop = 0;\n\t\tthis.log.info(\"pushState\", state, url, id);\n\t}\n\n\tbeforeTransition(): void {\n\t\tconst { state } = window.history;\n\t\tif (!state) return;\n\n\t\tconst oldEntry = this.entries.get(state.id);\n\t\tif (!oldEntry) {\n\t\t\tthis.log.info(\n\t\t\t\t\"current history state evicted from LRU, not saving scroll position\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { scrollTop } = this;\n\t\tthis.entries.set(state.id, { ...oldEntry, scrollY: scrollTop });\n\t\tthis.log.info(\"saving scroll position\", scrollTop);\n\t}\n\n\tonPopState(listener: (url: string, state?: State) => void): void {\n\t\twindow.addEventListener(\"popstate\", (event: PopStateEvent) => {\n\t\t\tthis.currentStateId = event.state?.id;\n\n\t\t\tif (!this.currentStateId) {\n\t\t\t\tthis.log.warn(\n\t\t\t\t\t\"encountered a null event.state.id in onPopState event:\",\n\t\t\t\t\twindow.location.href,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.log.info(\"popstate\", this.entries, this.currentStateId);\n\n\t\t\tconst entry = this.currentStateId\n\t\t\t\t? this.entries.get(this.currentStateId)\n\t\t\t\t: undefined;\n\n\t\t\tlistener(window.location.href, entry?.state);\n\n\t\t\tif (!entry) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { scrollY } = entry;\n\t\t\tthis.log.info(\"restoring scroll to\", scrollY);\n\t\t\ttryScroll(this.log, () => this.getScrollablePageElement(), scrollY);\n\t\t});\n\t}\n\n\tupdateState(update: (current?: State) => State): void {\n\t\tif (!this.currentStateId) {\n\t\t\tthis.log.warn(\n\t\t\t\t\"failed: encountered a null currentStateId inside updateState\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentState = this.entries.get(this.currentStateId);\n\t\tconst newState = update(currentState?.state);\n\t\tthis.log.info(\"updateState\", newState, this.currentStateId);\n\t\tthis.entries.set(this.currentStateId, {\n\t\t\t...(currentState as HistoryEntry<State>),\n\t\t\tstate: newState,\n\t\t});\n\t}\n\n\tprivate get scrollTop(): number {\n\t\treturn this.getScrollablePageElement()?.scrollTop || 0;\n\t}\n\n\tprivate set scrollTop(scrollTop: number) {\n\t\tconst element = this.getScrollablePageElement();\n\t\tif (element) {\n\t\t\telement.scrollTop = scrollTop;\n\t\t}\n\t}\n}\n","/**\n * FlowAction Handler — 核心 SPA 导航处理器\n *\n * 通过 FlowActionCallbacks 注入 UI 更新回调,\n * 不直接依赖任何 UI 框架的 store。\n */\n\nimport type { BasePage, FlowAction, Framework, Logger } from \"@finesoft/core\";\nimport { ACTION_KINDS } from \"@finesoft/core\";\nimport { History } from \"../utils/history\";\n\n/** FlowAction handler 的 History state */\ninterface FlowState {\n\tpage: BasePage;\n}\n\n/** UI 框架回调 — 解耦 Svelte store 等依赖 */\nexport interface FlowActionCallbacks {\n\t/** 导航后更新当前路径(替代 currentPath.set()) */\n\tonNavigate(pathname: string): void;\n\t/** 模态页面展示(替代 openModal()) */\n\tonModal(page: BasePage): void;\n}\n\n/** 注册 FlowAction handler 所需的依赖 */\nexport interface FlowActionDependencies {\n\tframework: Framework;\n\tlog: Logger;\n\tcallbacks: FlowActionCallbacks;\n\t/** 更新应用 UI 的回调,page 可以是 Promise */\n\tupdateApp: (props: {\n\t\tpage: Promise<BasePage> | BasePage;\n\t\tisFirstPage?: boolean;\n\t}) => void;\n}\n\nexport function registerFlowActionHandler(deps: FlowActionDependencies): void {\n\tconst { framework, log, callbacks, updateApp } = deps;\n\tlet isFirstPage = true;\n\n\tconst history = new History<FlowState>(log, {\n\t\tgetScrollablePageElement: () =>\n\t\t\tdocument.getElementById(\"scrollable-page-override\") ||\n\t\t\tdocument.getElementById(\"scrollable-page\") ||\n\t\t\tdocument.documentElement,\n\t});\n\n\t// ===== FlowAction handler =====\n\tframework.onAction(ACTION_KINDS.FLOW, async (action) => {\n\t\tconst flowAction = action as FlowAction;\n\t\tconst url = flowAction.url;\n\t\tlog.debug(`FlowAction → ${url}`);\n\n\t\t// 模态展示\n\t\tif (flowAction.presentationContext === \"modal\") {\n\t\t\tconst match = framework.routeUrl(url);\n\t\t\tif (match) {\n\t\t\t\tconst page = (await framework.dispatch(\n\t\t\t\t\tmatch.intent,\n\t\t\t\t)) as BasePage;\n\t\t\t\tcallbacks.onModal(page);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst shouldReplace = isFirstPage;\n\n\t\tconst match = framework.routeUrl(url);\n\t\tif (!match) {\n\t\t\tlog.warn(`FlowAction: no route for ${url}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst pagePromise = framework.dispatch(\n\t\t\tmatch.intent,\n\t\t) as Promise<BasePage>;\n\n\t\tawait Promise.race([\n\t\t\tpagePromise,\n\t\t\tnew Promise((r) => setTimeout(r, 500)),\n\t\t]).catch(() => {});\n\n\t\thistory.beforeTransition();\n\n\t\tupdateApp({\n\t\t\tpage: pagePromise.then((page: BasePage): BasePage => {\n\t\t\t\tconst canonicalURL = url;\n\n\t\t\t\tif (shouldReplace) {\n\t\t\t\t\thistory.replaceState({ page }, canonicalURL);\n\t\t\t\t} else {\n\t\t\t\t\thistory.pushState({ page }, canonicalURL);\n\t\t\t\t}\n\n\t\t\t\tcallbacks.onNavigate(\n\t\t\t\t\tnew URL(canonicalURL, window.location.origin).pathname,\n\t\t\t\t);\n\n\t\t\t\tdidEnterPage(page);\n\t\t\t\treturn page;\n\t\t\t}),\n\t\t\tisFirstPage,\n\t\t});\n\n\t\tisFirstPage = false;\n\t});\n\n\t// ===== popstate handler =====\n\thistory.onPopState(async (url, cachedState) => {\n\t\tlog.debug(`popstate → ${url}, cached=${!!cachedState}`);\n\n\t\tcallbacks.onNavigate(new URL(url).pathname);\n\n\t\tif (cachedState) {\n\t\t\tconst { page } = cachedState;\n\t\t\tdidEnterPage(page);\n\t\t\tupdateApp({ page, isFirstPage });\n\t\t\treturn;\n\t\t}\n\n\t\tconst parsed = new URL(url);\n\t\tconst routeMatch = framework.routeUrl(parsed.pathname + parsed.search);\n\t\tif (!routeMatch) {\n\t\t\tlog.error(\n\t\t\t\t\"received popstate without data, but URL was unroutable:\",\n\t\t\t\turl,\n\t\t\t);\n\t\t\tdidEnterPage(null);\n\t\t\tupdateApp({\n\t\t\t\tpage: Promise.reject(new Error(\"404\")),\n\t\t\t\tisFirstPage,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tconst pagePromise = framework.dispatch(\n\t\t\trouteMatch.intent,\n\t\t) as Promise<BasePage>;\n\n\t\tawait Promise.race([\n\t\t\tpagePromise,\n\t\t\tnew Promise((r) => setTimeout(r, 500)),\n\t\t]).catch(() => {});\n\n\t\tupdateApp({\n\t\t\tpage: pagePromise.then((page: BasePage): BasePage => {\n\t\t\t\tdidEnterPage(page);\n\t\t\t\treturn page;\n\t\t\t}),\n\t\t\tisFirstPage,\n\t\t});\n\t});\n\n\tfunction didEnterPage(page: BasePage | null): void {\n\t\t(async (): Promise<void> => {\n\t\t\ttry {\n\t\t\t\tif (page) {\n\t\t\t\t\tawait framework.didEnterPage(page);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tlog.error(\"didEnterPage error:\", e);\n\t\t\t}\n\t\t})();\n\t}\n}\n","/**\n * Action Handler 统一注册入口\n */\n\nimport type { BasePage, Framework, Logger } from \"@finesoft/core\";\nimport { registerExternalUrlHandler } from \"./external-url-action\";\nimport {\n\tregisterFlowActionHandler,\n\ttype FlowActionCallbacks,\n} from \"./flow-action\";\n\nexport type { FlowActionCallbacks };\n\nexport interface ActionHandlerDependencies {\n\tframework: Framework;\n\tlog: Logger;\n\tcallbacks: FlowActionCallbacks;\n\tupdateApp: (props: {\n\t\tpage: Promise<BasePage> | BasePage;\n\t\tisFirstPage?: boolean;\n\t}) => void;\n}\n\nexport function registerActionHandlers(deps: ActionHandlerDependencies): void {\n\tconst { framework, log, callbacks, updateApp } = deps;\n\n\tregisterFlowActionHandler({\n\t\tframework,\n\t\tlog,\n\t\tcallbacks,\n\t\tupdateApp,\n\t});\n\n\tregisterExternalUrlHandler({ framework, log });\n}\n","/**\n * Server Data (browser side) — 从 DOM 反序列化服务端嵌入数据\n */\n\nimport { PrefetchedIntents, type PrefetchedIntent } from \"@finesoft/core\";\n\n/** DOM 中嵌入数据的 script 标签 ID */\nexport const SERVER_DATA_ID = \"serialized-server-data\";\n\n/**\n * 从 DOM 反序列化服务端嵌入的数据。\n * 读取 `<script id=\"serialized-server-data\">` 的内容并移除标签。\n */\nexport function deserializeServerData(): PrefetchedIntent[] | undefined {\n\tconst script = document.getElementById(SERVER_DATA_ID);\n\tif (!script?.textContent) return undefined;\n\n\tscript.parentNode?.removeChild(script);\n\n\ttry {\n\t\treturn JSON.parse(script.textContent);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * 从 DOM 提取 SSR 数据并构建 PrefetchedIntents 实例。\n * 替代原来的 PrefetchedIntents.fromDom()。\n */\nexport function createPrefetchedIntentsFromDom(): PrefetchedIntents {\n\tconst data = deserializeServerData();\n\tif (!data || !Array.isArray(data)) {\n\t\treturn PrefetchedIntents.empty();\n\t}\n\treturn PrefetchedIntents.fromArray(data);\n}\n","/**\n * startBrowserApp — 客户端 hydration 一站式启动\n *\n * 封装:\n * 1. PrefetchedIntents 从 DOM 提取\n * 2. Framework 创建 + 引导\n * 3. 应用层挂载(通过 mount 回调,框架无关)\n * 4. Action handlers 注册\n * 5. 初始页面触发\n */\n\nimport type { BasePage, Logger } from \"@finesoft/core\";\nimport { DEP_KEYS, Framework, type LoggerFactory } from \"@finesoft/core\";\nimport {\n\tregisterActionHandlers,\n\ttype FlowActionCallbacks,\n} from \"./action-handlers/register\";\nimport { createPrefetchedIntentsFromDom } from \"./server-data\";\n\nexport interface BrowserAppConfig {\n\t/** 注册 controllers 和路由的引导函数 */\n\tbootstrap: (framework: Framework) => void;\n\n\t/** 默认语言(回退值) */\n\tdefaultLocale?: string;\n\n\t/** DOM 挂载点 ID(默认 \"app\") */\n\tmountId?: string;\n\n\t/**\n\t * 挂载应用到 DOM\n\t *\n\t * 框架无关 — Svelte / React / Vue 均可通过此回调实现。\n\t *\n\t * @param target - DOM 挂载点\n\t * @param context - Framework 实例 + 语言\n\t * @returns 更新函数,用于后续页面切换\n\t */\n\tmount: (\n\t\ttarget: HTMLElement,\n\t\tcontext: { framework: Framework; locale: string },\n\t) => (props: {\n\t\tpage: Promise<BasePage> | BasePage;\n\t\tisFirstPage?: boolean;\n\t}) => void;\n\n\t/** FlowAction / ExternalUrl 回调 */\n\tcallbacks: FlowActionCallbacks;\n}\n\n/**\n * 启动客户端应用\n *\n * 自动执行 hydration 全流程。\n */\nexport async function startBrowserApp(config: BrowserAppConfig): Promise<void> {\n\tconst {\n\t\tbootstrap,\n\t\tdefaultLocale = \"en\",\n\t\tmountId = \"app\",\n\t\tmount,\n\t\tcallbacks,\n\t} = config;\n\n\t// 1. 从 DOM 提取 PrefetchedIntents 缓存\n\tconst prefetchedIntents = createPrefetchedIntentsFromDom();\n\n\t// 2. 初始化 Framework + 注册 Controllers\n\tconst framework = Framework.create({ prefetchedIntents });\n\tbootstrap(framework);\n\n\tconst loggerFactory = framework.container.resolve<LoggerFactory>(\n\t\tDEP_KEYS.LOGGER_FACTORY,\n\t);\n\tconst log: Logger = loggerFactory.loggerFor(\"browser\");\n\n\t// 3. 路由初始 URL\n\tconst initialAction = framework.routeUrl(\n\t\twindow.location.pathname + window.location.search,\n\t);\n\n\t// 4. 挂载应用(框架无关)\n\tconst locale = document.documentElement.lang || defaultLocale;\n\tconst target = document.getElementById(mountId)!;\n\tconst updateApp = mount(target, { framework, locale });\n\n\t// 5. 注册 Action Handlers\n\tregisterActionHandlers({\n\t\tframework,\n\t\tlog,\n\t\tcallbacks,\n\t\tupdateApp,\n\t});\n\n\t// 6. 触发初始页面\n\tif (initialAction) {\n\t\tawait framework.perform(initialAction.action);\n\t} else {\n\t\tupdateApp({\n\t\t\tpage: Promise.reject(new Error(\"404\")),\n\t\t\tisFirstPage: true,\n\t\t});\n\t}\n}\n","/**\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}\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}\n\nexport async function ssrRender(\n\toptions: SSRRenderOptions,\n): Promise<SSRRenderResult> {\n\tconst { url, frameworkConfig, bootstrap, getErrorPage, renderApp } =\n\t\toptions;\n\n\tconst framework = Framework.create(frameworkConfig);\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\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};\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 { ssrRender, type SSRAppResult, type SSRRenderResult } 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)` — 供 @finesoft/server SSRModule 使用\n */\nexport function createSSRRender(\n\tconfig: SSRRenderConfig,\n): (url: string, locale: string) => Promise<SSRRenderResult> {\n\tconst { bootstrap, getErrorPage, renderApp, frameworkConfig } = config;\n\n\treturn (url: string, locale: string) =>\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});\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 * 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","/**\n * createSSRApp — 创建 Hono SSR 应用\n *\n * 提供 SSR 通配路由,读取模板、加载 SSR 模块、渲染。\n * 应用层可在此之上追加自定义路由(API 代理等)。\n */\n\nimport { injectSSRContent } from \"@finesoft/ssr\";\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { parseAcceptLanguage } from \"./locale\";\n\nexport interface SSRModule {\n\trender: (\n\t\turl: string,\n\t\tlocale: string,\n\t) => Promise<{\n\t\thtml: string;\n\t\thead: string;\n\t\tcss: string;\n\t\tserverData: unknown;\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}\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} = options;\n\n\tconst app = new Hono();\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(ssrProductionModule) 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(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\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} = await render(url, locale);\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\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 * Accept-Language 解析\n */\n\nexport function parseAcceptLanguage(\n\theader: string | undefined,\n\tsupported?: string[],\n\tfallback?: string,\n): string {\n\tconst effectiveSupported = supported ?? [\"zh\", \"en\"];\n\tconst effectiveFallback = fallback ?? effectiveSupported[0] ?? \"en\";\n\tif (!header) return effectiveFallback;\n\tconst langs = header\n\t\t.split(\",\")\n\t\t.map((part) => {\n\t\t\tconst [lang, q] = part.trim().split(\";q=\");\n\t\t\treturn {\n\t\t\t\tlang: lang.trim().toLowerCase(),\n\t\t\t\tq: q ? parseFloat(q) : 1,\n\t\t\t};\n\t\t})\n\t\t.sort((a, b) => b.q - a.q);\n\n\tfor (const { lang } of langs) {\n\t\tconst prefix = lang.split(\"-\")[0];\n\t\tif (effectiveSupported.includes(prefix)) {\n\t\t\treturn prefix;\n\t\t}\n\t}\n\treturn effectiveFallback;\n}\n","/**\n * createServer — 一站式服务器工厂\n *\n * 封装 env 加载、运行时检测、Vite 创建、Hono app、SSR、启动。\n * 保留 setup() 钩子用于注册业务路由。\n */\n\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { createSSRApp, type SSRAppOptions } from \"./app\";\nimport { detectRuntime, type RuntimeInfo } from \"./runtime\";\nimport { startServer } from \"./start\";\n\nexport interface ServerConfig {\n\t/** 项目根路径(默认 process.cwd()) */\n\troot?: string;\n\t/** 支持的语言列表 */\n\tlocales?: string[];\n\t/** 默认语言 */\n\tdefaultLocale?: string;\n\t/** 端口号(默认 3000) */\n\tport?: number;\n\t/** 注册业务路由(在 SSR catch-all 之前调用) */\n\tsetup?: (app: Hono) => void | Promise<void>;\n\t/** SSR 相关选项(透传给 createSSRApp) */\n\tssr?: Pick<SSRAppOptions, \"ssrEntryPath\" | \"ssrProductionModule\">;\n}\n\nexport interface ServerInstance {\n\tapp: Hono;\n\tvite?: ViteDevServer;\n\truntime: RuntimeInfo;\n}\n\n/**\n * 创建并启动 SSR 服务器\n *\n * @example\n * ```ts\n * const { app } = await createServer({\n * locales: [\"zh\", \"en\"],\n * setup: (app) => registerProxies(app),\n * });\n * export { app };\n * ```\n */\nexport async function createServer(\n\tconfig: ServerConfig = {},\n): Promise<ServerInstance> {\n\tconst {\n\t\troot: rootOverride,\n\t\tlocales,\n\t\tdefaultLocale,\n\t\tport = Number(process.env.PORT) || 3000,\n\t\tsetup,\n\t\tssr,\n\t} = config;\n\n\t// 1. 路径 + .env\n\tconst root = rootOverride ?? process.cwd();\n\tconst { existsSync } = await import(/* @vite-ignore */ \"node:fs\");\n\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\tconst envPath = resolve(root, \".env\");\n\tif (existsSync(envPath)) {\n\t\ttry {\n\t\t\tconst { config: dotenvConfig } = await import(\n\t\t\t\t/* @vite-ignore */ \"dotenv\"\n\t\t\t);\n\t\t\tdotenvConfig({ path: envPath });\n\t\t} catch {\n\t\t\t// dotenv 未安装则跳过,调用方可自行加载 .env\n\t\t}\n\t}\n\n\t// 2. 运行时检测\n\tconst runtime = detectRuntime();\n\n\t// 3. Vite(仅开发模式)\n\tlet vite: ViteDevServer | undefined;\n\tif (!runtime.isProduction && !runtime.isVercel) {\n\t\tconst { createServer: createViteServer } = await import(\n\t\t\t/* @vite-ignore */ \"vite\"\n\t\t);\n\t\tvite = await createViteServer({\n\t\t\troot,\n\t\t\tserver: { middlewareMode: true },\n\t\t\tappType: \"custom\",\n\t\t});\n\t}\n\n\t// 4. Hono app + 业务路由\n\tconst app = new Hono();\n\tif (setup) {\n\t\tawait setup(app);\n\t}\n\n\t// 5. SSR catch-all\n\tconst ssrApp = createSSRApp({\n\t\troot,\n\t\tvite,\n\t\tisProduction: runtime.isProduction,\n\t\tsupportedLocales: locales,\n\t\tdefaultLocale,\n\t\t...ssr,\n\t});\n\tapp.route(\"/\", ssrApp);\n\n\t// 6. 启动\n\tawait startServer({\n\t\tapp,\n\t\troot,\n\t\tport,\n\t\tisProduction: runtime.isProduction,\n\t\tvite,\n\t\truntime,\n\t\tlocales,\n\t\tssrEntryPath: ssr?.ssrEntryPath,\n\t});\n\n\treturn { app, vite, runtime };\n}\n","/**\n * runtime — 运行时检测 + 项目根路径推导\n */\n\nexport interface RuntimeInfo {\n\tisDeno: boolean;\n\tisBun: boolean;\n\tisVercel: boolean;\n\tisProduction: boolean;\n}\n\n/** 检测当前运行时环境 */\nexport function detectRuntime(): RuntimeInfo {\n\treturn {\n\t\tisDeno: typeof (globalThis as any).Deno !== \"undefined\",\n\t\tisBun: typeof (globalThis as any).Bun !== \"undefined\",\n\t\tisVercel: !!process.env.VERCEL,\n\t\tisProduction: process.env.NODE_ENV === \"production\",\n\t};\n}\n\n/**\n * 从 `import.meta.url` 推导项目根路径\n *\n * @param importMetaUrl - 调用方的 `import.meta.url`\n * @param levelsUp - 向上移动多少级(默认 0,即调用方所在目录就是项目根)\n */\nexport async function resolveRoot(\n\timportMetaUrl: string,\n\tlevelsUp = 0,\n): Promise<string> {\n\tconst isDeno = typeof (globalThis as any).Deno !== \"undefined\";\n\n\tif (isDeno) {\n\t\tlet url = new URL(importMetaUrl);\n\t\tfor (let i = 0; i < levelsUp; i++) {\n\t\t\turl = new URL(\"..\", url);\n\t\t}\n\t\treturn url.pathname;\n\t}\n\n\tconst { dirname, resolve, normalize } = await import(\n\t\t/* @vite-ignore */ \"node:path\"\n\t);\n\tconst { fileURLToPath } = await import(/* @vite-ignore */ \"node:url\");\n\tlet dir = normalize(dirname(fileURLToPath(importMetaUrl)));\n\tfor (let i = 0; i < levelsUp; i++) {\n\t\tdir = resolve(dir, \"..\");\n\t}\n\treturn dir;\n}\n","/**\n * startServer — 多运行时自动启动\n *\n * 支持 Node.js (dev HMR + prod)、Deno、Bun、Vercel。\n */\n\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { detectRuntime, type RuntimeInfo } from \"./runtime\";\n\nexport interface StartServerOptions {\n\t/** 最终的 Hono app(已包含 SSR + 自定义路由) */\n\tapp: Hono;\n\t/** 项目根路径 */\n\troot: string;\n\t/** 端口号 */\n\tport?: number;\n\t/** 是否生产环境 */\n\tisProduction: boolean;\n\t/** Vite dev server(仅开发模式传入) */\n\tvite?: ViteDevServer;\n\t/** 运行时信息(可选,不传时自动检测) */\n\truntime?: RuntimeInfo;\n\t/** 已注册的路由列表(用于启动日志) */\n\troutes?: string[];\n\t/** 支持的语言列表(用于启动日志) */\n\tlocales?: string[];\n\t/** SSR 入口路径(用于启动日志) */\n\tssrEntryPath?: string;\n}\n\nexport async function startServer(\n\toptions: StartServerOptions,\n): Promise<{ vite?: ViteDevServer }> {\n\tconst {\n\t\tapp,\n\t\troot,\n\t\tport = 3000,\n\t\tisProduction,\n\t\tvite,\n\t\troutes,\n\t\tlocales,\n\t\tssrEntryPath,\n\t} = options;\n\n\tconst { isDeno, isBun, isVercel } = options.runtime ?? detectRuntime();\n\n\tfunction printStartupBanner() {\n\t\tconst lines: string[] = [\n\t\t\t`\\n Server running at http://localhost:${port}\\n`,\n\t\t];\n\t\tif (routes && routes.length > 0) {\n\t\t\tlines.push(\" Routes:\");\n\t\t\tfor (const r of routes) {\n\t\t\t\tlines.push(` ${r}`);\n\t\t\t}\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tif (locales && locales.length > 0) {\n\t\t\tlines.push(` Locales: ${locales.join(\", \")}`);\n\t\t}\n\t\tif (ssrEntryPath) {\n\t\t\tlines.push(` SSR Entry: ${ssrEntryPath}`);\n\t\t}\n\t\tif (locales?.length || ssrEntryPath) {\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tconsole.log(lines.join(\"\\n\"));\n\t}\n\n\tif (isVercel) {\n\t\treturn { vite };\n\t}\n\n\tif (!isProduction) {\n\t\tlet devVite = vite;\n\t\tif (!devVite) {\n\t\t\tconst { createServer: createViteServer } = await import(\n\t\t\t\t/* @vite-ignore */ \"vite\"\n\t\t\t);\n\t\t\tdevVite = await createViteServer({\n\t\t\t\troot,\n\t\t\t\tserver: { middlewareMode: true },\n\t\t\t\tappType: \"custom\",\n\t\t\t});\n\t\t}\n\n\t\tconst { getRequestListener } = await import(\n\t\t\t/* @vite-ignore */ \"@hono/node-server\"\n\t\t);\n\t\tconst { createServer } = await import(/* @vite-ignore */ \"node:http\");\n\t\tconst listener = getRequestListener(app.fetch);\n\t\tconst server = createServer((req: any, res: any) => {\n\t\t\tdevVite!.middlewares(req, res, () => listener(req, res));\n\t\t});\n\t\tserver.listen(port, () => {\n\t\t\tprintStartupBanner();\n\t\t});\n\t\treturn { vite: devVite };\n\t}\n\n\tif (isDeno) {\n\t\t(globalThis as any).Deno.serve({ port }, app.fetch);\n\t} else if (isBun) {\n\t\t// Bun uses export default\n\t} else {\n\t\t// Node.js production\n\t\tconst { serveStatic } = await import(\n\t\t\t/* @vite-ignore */ \"@hono/node-server/serve-static\"\n\t\t);\n\t\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\t\tconst prodApp = new Hono();\n\t\tconst clientDir = resolve(root, \"dist/client\");\n\t\tprodApp.use(\n\t\t\t\"/*\",\n\t\t\tserveStatic({\n\t\t\t\troot: clientDir,\n\t\t\t\t// 禁止目录路径自动提供 index.html,让其 fall through 到 SSR\n\t\t\t\trewriteRequestPath: (path: string) =>\n\t\t\t\t\tpath.endsWith(\"/\") ? \"/__nosuchfile__\" : path,\n\t\t\t}),\n\t\t);\n\t\tprodApp.route(\"/\", app);\n\n\t\tconst { serve } = await import(/* @vite-ignore */ \"@hono/node-server\");\n\t\tserve({ fetch: prodApp.fetch, port }, () => {\n\t\t\tprintStartupBanner();\n\t\t});\n\t}\n\n\treturn { vite };\n}\n"],"mappings":"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","names":["match","readFileSync","resolve","serializeServerData","import_hono","import_hono","createServer"]}
1
+ {"version":3,"sources":["../../core/src/actions/types.ts","../../core/src/actions/dispatcher.ts","../../core/src/intents/dispatcher.ts","../../core/src/dependencies/container.ts","../../core/src/logger/base.ts","../../core/src/logger/local-storage-filter.ts","../../core/src/logger/console.ts","../../core/src/dependencies/make-dependencies.ts","../../core/src/router/router.ts","../../core/src/logger/composite.ts","../../core/src/prefetched-intents/stable-stringify.ts","../../core/src/prefetched-intents/prefetched-intents.ts","../../core/src/framework.ts","../../core/src/http/client.ts","../../core/src/intents/base-controller.ts","../../core/src/data/mapper.ts","../../core/src/bootstrap/define-routes.ts","../../core/src/utils/lru-map.ts","../../core/src/utils/optional.ts","../../core/src/utils/url.ts","../../core/src/utils/uuid.ts","../../core/src/index.ts","../../ssr/src/render.ts","../../ssr/src/create-render.ts","../../ssr/src/inject.ts","../../ssr/src/server-data.ts","../../ssr/src/index.ts","../../server/src/locale.ts","../../server/src/app.ts","../src/index.ts","../../browser/src/action-handlers/external-url-action.ts","../../browser/src/action-handlers/flow-action.ts","../../browser/src/utils/history.ts","../../browser/src/utils/try-scroll.ts","../../browser/src/action-handlers/register.ts","../../browser/src/start-app.ts","../../browser/src/server-data.ts","../../browser/src/index.ts","../../server/src/adapters/shared.ts","../../server/src/adapters/cloudflare.ts","../../server/src/adapters/netlify.ts","../../server/src/adapters/node.ts","../../server/src/adapters/static.ts","../../server/src/adapters/vercel.ts","../../server/src/adapters/resolve.ts","../../server/src/adapters/auto.ts","../../server/src/index.ts","../../server/src/create-server.ts","../../server/src/runtime.ts","../../server/src/start.ts","../../server/src/vite-plugin.ts"],"sourcesContent":["/**\n * Action 类型定义\n *\n * FlowAction — SPA 内部导航\n * ExternalUrlAction — 打开外部链接\n * CompoundAction — 组合多个 Action\n */\n\n/** Action Kind 常量 */\nexport const ACTION_KINDS = {\n\tFLOW: \"flow\" as const,\n\tEXTERNAL_URL: \"externalUrl\" as const,\n\tCOMPOUND: \"compound\" as const,\n};\n\n/** FlowAction — SPA 导航 */\nexport interface FlowAction {\n\tkind: typeof ACTION_KINDS.FLOW;\n\turl: string;\n\t/** 展示方式: 默认 push,modal 弹窗 */\n\tpresentationContext?: \"default\" | \"modal\";\n}\n\n/** ExternalUrlAction — 外部链接 */\nexport interface ExternalUrlAction {\n\tkind: typeof ACTION_KINDS.EXTERNAL_URL;\n\turl: string;\n}\n\n/** CompoundAction — 组合 Action */\nexport interface CompoundAction {\n\tkind: typeof ACTION_KINDS.COMPOUND;\n\tactions: Action[];\n}\n\n/** 所有 Action 的联合类型 */\nexport type Action = FlowAction | ExternalUrlAction | CompoundAction;\n\n// ===== Type Guards =====\n\nexport function isFlowAction(action: Action): action is FlowAction {\n\treturn action.kind === ACTION_KINDS.FLOW;\n}\n\nexport function isExternalUrlAction(\n\taction: Action,\n): action is ExternalUrlAction {\n\treturn action.kind === ACTION_KINDS.EXTERNAL_URL;\n}\n\nexport function isCompoundAction(action: Action): action is CompoundAction {\n\treturn action.kind === ACTION_KINDS.COMPOUND;\n}\n\n// ===== Factory =====\n\nexport function makeFlowAction(\n\turl: string,\n\tpresentationContext?: FlowAction[\"presentationContext\"],\n): FlowAction {\n\treturn { kind: ACTION_KINDS.FLOW, url, presentationContext };\n}\n\nexport function makeExternalUrlAction(url: string): ExternalUrlAction {\n\treturn { kind: ACTION_KINDS.EXTERNAL_URL, url };\n}\n","/**\n * ActionDispatcher — Action 分发器\n *\n * 注册不同 kind 的 handler,按类型分发。\n * CompoundAction 自动展开递归执行。\n */\n\nimport type { Action } from \"./types\";\nimport { isCompoundAction } from \"./types\";\n\n/** Action 处理器函数类型 */\nexport type ActionHandler<A extends Action = Action> = (\n\taction: A,\n) => Promise<void> | void;\n\nexport class ActionDispatcher {\n\tprivate handlers = new Map<string, ActionHandler>();\n\tprivate wiredActions = new Set<string>();\n\n\t/** 注册指定 kind 的 handler(防止重复注册) */\n\tonAction<A extends Action>(kind: string, handler: ActionHandler<A>): void {\n\t\tif (this.wiredActions.has(kind)) {\n\t\t\tconsole.warn(\n\t\t\t\t`[ActionDispatcher] kind=\"${kind}\" already registered, skipping`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tthis.wiredActions.add(kind);\n\t\tthis.handlers.set(kind, handler as ActionHandler);\n\t}\n\n\t/** 执行一个 Action(CompoundAction 递归展开) */\n\tasync perform(action: Action): Promise<void> {\n\t\tif (isCompoundAction(action)) {\n\t\t\tfor (const subAction of action.actions) {\n\t\t\t\tawait this.perform(subAction);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst handler = this.handlers.get(action.kind);\n\t\tif (!handler) {\n\t\t\tconsole.warn(\n\t\t\t\t`[ActionDispatcher] No handler for kind=\"${action.kind}\"`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tawait handler(action);\n\t}\n}\n","/**\n * IntentDispatcher — Intent 分发器\n *\n * 注册 IntentController,按 intentId 分发。\n */\n\nimport type { Container } from \"../dependencies/container\";\nimport type { Intent, IntentController } from \"./types\";\n\nexport class IntentDispatcher {\n\tprivate controllers = new Map<string, IntentController>();\n\n\t/** 注册一个 IntentController */\n\tregister(controller: IntentController): void {\n\t\tthis.controllers.set(controller.intentId, controller);\n\t}\n\n\t/** 分发 Intent 到对应 Controller */\n\tasync dispatch<T>(intent: Intent<T>, container: Container): Promise<T> {\n\t\tconst controller = this.controllers.get(intent.id);\n\t\tif (!controller) {\n\t\t\tthrow new Error(\n\t\t\t\t`[IntentDispatcher] No controller for \"${intent.id}\". ` +\n\t\t\t\t\t`Registered: [${Array.from(this.controllers.keys()).join(\", \")}]`,\n\t\t\t);\n\t\t}\n\t\treturn controller.perform(intent, container) as Promise<T>;\n\t}\n\n\t/** 检查是否已注册某个 Intent */\n\thas(intentId: string): boolean {\n\t\treturn this.controllers.has(intentId);\n\t}\n}\n","/**\n * Container — 通用的依赖注入容器\n */\n\ntype Factory<T> = () => T;\n\ninterface Registration<T> {\n\tfactory: Factory<T>;\n\tsingleton: boolean;\n\tinstance?: T;\n}\n\nexport class Container {\n\tprivate registrations = new Map<string, Registration<unknown>>();\n\n\t/** 注册依赖(默认单例) */\n\tregister<T>(key: string, factory: Factory<T>, singleton = true): this {\n\t\tthis.registrations.set(key, { factory, singleton });\n\t\treturn this;\n\t}\n\n\t/** 解析依赖 */\n\tresolve<T>(key: string): T {\n\t\tconst reg = this.registrations.get(key);\n\t\tif (!reg) {\n\t\t\tthrow new Error(`[Container] No registration for key: \"${key}\"`);\n\t\t}\n\n\t\tif (reg.singleton) {\n\t\t\tif (reg.instance === undefined) {\n\t\t\t\treg.instance = reg.factory();\n\t\t\t}\n\t\t\treturn reg.instance as T;\n\t\t}\n\t\treturn reg.factory() as T;\n\t}\n\n\t/** 检查是否已注册 */\n\thas(key: string): boolean {\n\t\treturn this.registrations.has(key);\n\t}\n\n\t/** 销毁容器,清除所有缓存 */\n\tdispose(): void {\n\t\tfor (const reg of this.registrations.values()) {\n\t\t\treg.instance = undefined;\n\t\t}\n\t\tthis.registrations.clear();\n\t}\n}\n","/**\n * BaseLogger — 抽象日志基类\n */\n\nimport type { Logger } from \"./types\";\n\nexport abstract class BaseLogger implements Logger {\n\tprotected category: string;\n\n\tconstructor(category: string) {\n\t\tthis.category = category;\n\t}\n\n\tabstract debug(...args: unknown[]): string;\n\tabstract info(...args: unknown[]): string;\n\tabstract warn(...args: unknown[]): string;\n\tabstract error(...args: unknown[]): string;\n}\n","/**\n * localStorage 日志级别过滤\n *\n * 通过 localStorage.onyxLog 控制日志级别:\n * '*=info' — 全局 info 及以上\n * '*=info,Foo=off' — 全局 info,Foo 静默\n * 'Bar=error,Baz=warn' — Bar 只输出 error,Baz 输出 warn+\n */\n\nimport type { Level } from \"./types\";\n\ntype LevelNum = 4 | 3 | 2 | 1 | 0;\n\nconst LEVEL_TO_NUM: Record<string, LevelNum> = {\n\t\"*\": 4,\n\tdebug: 4,\n\tinfo: 3,\n\twarn: 2,\n\terror: 1,\n\toff: 0,\n\t\"\": 0,\n};\n\ninterface Rules {\n\tnamed?: Record<string, LevelNum>;\n\tdefaultLevel?: LevelNum;\n}\n\nlet cachedRules: Rules | undefined;\nlet cachedRaw: string | undefined;\n\nfunction parseRules(): Rules {\n\tif (typeof globalThis.localStorage === \"undefined\") {\n\t\treturn {};\n\t}\n\n\tlet raw: string | null;\n\ttry {\n\t\traw = globalThis.localStorage.getItem(\"onyxLog\");\n\t} catch {\n\t\treturn {};\n\t}\n\n\tif (!raw) return {};\n\n\tif (raw === cachedRaw && cachedRules) return cachedRules;\n\tcachedRaw = raw;\n\n\tconst rules: Rules = {};\n\tconst parts = raw.split(\",\");\n\n\tfor (const part of parts) {\n\t\tconst [name, level] = part.trim().split(\"=\");\n\t\tif (!name || level === undefined) continue;\n\n\t\tconst num = LEVEL_TO_NUM[level.toLowerCase()] ?? undefined;\n\t\tif (num === undefined) continue;\n\n\t\tif (name === \"*\") {\n\t\t\trules.defaultLevel = num;\n\t\t} else {\n\t\t\trules.named ??= {};\n\t\t\trules.named[name] = num;\n\t\t}\n\t}\n\n\tcachedRules = rules;\n\treturn rules;\n}\n\nexport function shouldLog(name: string, level: Level): boolean {\n\tconst rules = parseRules();\n\n\tif (rules.defaultLevel === undefined && !rules.named) {\n\t\treturn true;\n\t}\n\n\tconst currentNum = LEVEL_TO_NUM[level] ?? 4;\n\n\tif (rules.named?.[name] !== undefined) {\n\t\treturn currentNum <= rules.named[name];\n\t}\n\n\tif (rules.defaultLevel !== undefined) {\n\t\treturn currentNum <= rules.defaultLevel;\n\t}\n\n\treturn true;\n}\n\nexport function resetFilterCache(): void {\n\tcachedRules = undefined;\n\tcachedRaw = undefined;\n}\n","/**\n * ConsoleLogger — 基于 console 的日志实现\n */\n\nimport { BaseLogger } from \"./base\";\nimport { shouldLog } from \"./local-storage-filter\";\nimport type { Logger, LoggerFactory } from \"./types\";\n\nexport class ConsoleLogger extends BaseLogger {\n\tdebug(...args: unknown[]): string {\n\t\tif (shouldLog(this.category, \"debug\")) {\n\t\t\tconsole.debug(`[${this.category}]`, ...args);\n\t\t}\n\t\treturn \"\";\n\t}\n\n\tinfo(...args: unknown[]): string {\n\t\tif (shouldLog(this.category, \"info\")) {\n\t\t\tconsole.info(`[${this.category}]`, ...args);\n\t\t}\n\t\treturn \"\";\n\t}\n\n\twarn(...args: unknown[]): string {\n\t\tif (shouldLog(this.category, \"warn\")) {\n\t\t\tconsole.warn(`[${this.category}]`, ...args);\n\t\t}\n\t\treturn \"\";\n\t}\n\n\terror(...args: unknown[]): string {\n\t\tconsole.error(`[${this.category}]`, ...args);\n\t\treturn \"\";\n\t}\n}\n\nexport class ConsoleLoggerFactory implements LoggerFactory {\n\tloggerFor(category: string): Logger {\n\t\treturn new ConsoleLogger(category);\n\t}\n}\n","/**\n * 依赖工厂 — 创建所有基础依赖\n */\n\nimport { ConsoleLoggerFactory } from \"../logger/console\";\nimport type { Logger, LoggerFactory } from \"../logger/types\";\nimport { Container } from \"./container\";\n\n// ===== 重新导出 Logger 类型 =====\nexport type { Logger, LoggerFactory };\n\n// ===== 依赖接口 =====\n\n/** 网络请求层 */\nexport interface Net {\n\tfetch(url: string, options?: RequestInit): Promise<Response>;\n}\n\n/** 多语言状态 */\nexport interface Locale {\n\tlanguage: string;\n\tstorefront: string;\n\tsetActiveLocale(language: string, storefront: string): void;\n}\n\n/** 存储接口 */\nexport interface Storage {\n\tget(key: string): string | undefined;\n\tset(key: string, value: string): void;\n\tdelete(key: string): void;\n}\n\n/** Feature Flags */\nexport interface FeatureFlags {\n\tisEnabled(key: string): boolean;\n\tgetString(key: string): string | undefined;\n\tgetNumber(key: string): number | undefined;\n}\n\n/** Metrics 记录器 */\nexport interface MetricsRecorder {\n\trecordPageView(page: string, fields?: Record<string, unknown>): void;\n\trecordEvent(name: string, fields?: Record<string, unknown>): void;\n}\n\n// ===== 依赖 Key 常量 =====\n\nexport const DEP_KEYS = {\n\tLOGGER: \"logger\",\n\tLOGGER_FACTORY: \"loggerFactory\",\n\tNET: \"net\",\n\tLOCALE: \"locale\",\n\tSTORAGE: \"storage\",\n\tFEATURE_FLAGS: \"featureFlags\",\n\tMETRICS: \"metrics\",\n\tFETCH: \"fetch\",\n} as const;\n\n// ===== 默认实现 =====\n\nclass DefaultLocale implements Locale {\n\tlanguage = \"en\";\n\tstorefront = \"us\";\n\tsetActiveLocale(language: string, storefront: string) {\n\t\tthis.language = language;\n\t\tthis.storefront = storefront;\n\t}\n}\n\nclass MemoryStorage implements Storage {\n\tprivate store = new Map<string, string>();\n\tget(key: string) {\n\t\treturn this.store.get(key);\n\t}\n\tset(key: string, value: string) {\n\t\tthis.store.set(key, value);\n\t}\n\tdelete(key: string) {\n\t\tthis.store.delete(key);\n\t}\n}\n\nclass DefaultFeatureFlags implements FeatureFlags {\n\tprivate flags: Record<string, boolean | string | number>;\n\tconstructor(flags: Record<string, boolean | string | number> = {}) {\n\t\tthis.flags = flags;\n\t}\n\tisEnabled(key: string) {\n\t\treturn this.flags[key] === true;\n\t}\n\tgetString(key: string) {\n\t\tconst v = this.flags[key];\n\t\treturn typeof v === \"string\" ? v : undefined;\n\t}\n\tgetNumber(key: string) {\n\t\tconst v = this.flags[key];\n\t\treturn typeof v === \"number\" ? v : undefined;\n\t}\n}\n\nclass ConsoleMetrics implements MetricsRecorder {\n\trecordPageView(page: string, fields?: Record<string, unknown>) {\n\t\tconsole.info(`[Metrics:PageView] ${page}`, fields ?? \"\");\n\t}\n\trecordEvent(name: string, fields?: Record<string, unknown>) {\n\t\tconsole.info(`[Metrics:Event] ${name}`, fields ?? \"\");\n\t}\n}\n\n// ===== 依赖工厂 =====\n\nexport interface MakeDependenciesOptions {\n\tfetch?: typeof globalThis.fetch;\n\tlanguage?: string;\n\tstorefront?: string;\n\tfeatureFlags?: Record<string, boolean | string | number>;\n}\n\nexport function makeDependencies(\n\tcontainer: Container,\n\toptions: MakeDependenciesOptions = {},\n): void {\n\tconst {\n\t\tfetch: fetchFn = globalThis.fetch?.bind(globalThis),\n\t\tlanguage = \"en\",\n\t\tstorefront = \"us\",\n\t\tfeatureFlags = {},\n\t} = options;\n\n\tconst loggerFactory = new ConsoleLoggerFactory();\n\tcontainer.register<LoggerFactory>(\n\t\tDEP_KEYS.LOGGER_FACTORY,\n\t\t() => loggerFactory,\n\t);\n\n\tcontainer.register<Logger>(DEP_KEYS.LOGGER, () =>\n\t\tloggerFactory.loggerFor(\"framework\"),\n\t);\n\n\tcontainer.register<Net>(DEP_KEYS.NET, () => ({\n\t\tfetch: (url: string, opts?: RequestInit) => fetchFn(url, opts),\n\t}));\n\n\tcontainer.register<Locale>(DEP_KEYS.LOCALE, () => {\n\t\tconst locale = new DefaultLocale();\n\t\tlocale.setActiveLocale(language, storefront);\n\t\treturn locale;\n\t});\n\n\tcontainer.register<Storage>(DEP_KEYS.STORAGE, () => new MemoryStorage());\n\n\tcontainer.register<FeatureFlags>(\n\t\tDEP_KEYS.FEATURE_FLAGS,\n\t\t() => new DefaultFeatureFlags(featureFlags),\n\t);\n\n\tcontainer.register<MetricsRecorder>(\n\t\tDEP_KEYS.METRICS,\n\t\t() => new ConsoleMetrics(),\n\t);\n\n\tcontainer.register(DEP_KEYS.FETCH, () => fetchFn);\n}\n","/**\n * URL 路由器 — URL pattern → Intent + FlowAction\n */\n\nimport { makeFlowAction, type FlowAction } from \"../actions/types\";\nimport type { Intent } from \"../intents/types\";\n\n/** 路由匹配结果 */\nexport interface RouteMatch {\n\tintent: Intent;\n\taction: FlowAction;\n}\n\ninterface RouteDefinition {\n\tpattern: string;\n\tintentId: string;\n\tregex: RegExp;\n\tparamNames: string[];\n}\n\nexport class Router {\n\tprivate routes: RouteDefinition[] = [];\n\n\t/** 添加路由规则 */\n\tadd(pattern: string, intentId: string): this {\n\t\tconst paramNames: string[] = [];\n\n\t\tconst regexStr = pattern.replace(\n\t\t\t/\\/:(\\w+)(\\?)?/g,\n\t\t\t(_, name: string, optional: string) => {\n\t\t\t\tparamNames.push(name);\n\t\t\t\treturn optional ? \"(?:/([^/]+))?\" : \"/([^/]+)\";\n\t\t\t},\n\t\t);\n\n\t\tthis.routes.push({\n\t\t\tpattern,\n\t\t\tintentId,\n\t\t\tregex: new RegExp(`^${regexStr}/?$`),\n\t\t\tparamNames,\n\t\t});\n\n\t\treturn this;\n\t}\n\n\t/** 解析 URL → RouteMatch */\n\tresolve(urlOrPath: string): RouteMatch | null {\n\t\tconst path = this.extractPath(urlOrPath);\n\t\tconst queryParams = this.extractQueryParams(urlOrPath);\n\n\t\tfor (const route of this.routes) {\n\t\t\tconst match = path.match(route.regex);\n\t\t\tif (match) {\n\t\t\t\tconst params: Record<string, string> = {};\n\t\t\t\troute.paramNames.forEach((name, index) => {\n\t\t\t\t\tconst value = match[index + 1];\n\t\t\t\t\tif (value) params[name] = value;\n\t\t\t\t});\n\t\t\t\tfor (const [k, v] of Object.entries(queryParams)) {\n\t\t\t\t\tif (!(k in params)) params[k] = v;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tintent: { id: route.intentId, params },\n\t\t\t\t\taction: makeFlowAction(urlOrPath),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/** 获取所有已注册的路由 */\n\tgetRoutes(): string[] {\n\t\treturn this.routes.map((r) => `${r.pattern} → ${r.intentId}`);\n\t}\n\n\tprivate extractPath(url: string): string {\n\t\ttry {\n\t\t\tconst parsed = new URL(url, \"http://localhost\");\n\t\t\treturn parsed.pathname;\n\t\t} catch {\n\t\t\treturn url.split(\"?\")[0].split(\"#\")[0];\n\t\t}\n\t}\n\n\tprivate extractQueryParams(url: string): Record<string, string> {\n\t\ttry {\n\t\t\tconst parsed = new URL(url, \"http://localhost\");\n\t\t\tconst params: Record<string, string> = {};\n\t\t\tparsed.searchParams.forEach((v, k) => {\n\t\t\t\tparams[k] = v;\n\t\t\t});\n\t\t\treturn params;\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}\n}\n","/**\n * Composite Logger — 组合日志,广播到多个后端\n */\n\nimport type { Logger, LoggerFactory } from \"./types\";\n\nexport class CompositeLoggerFactory implements LoggerFactory {\n\tconstructor(private readonly factories: LoggerFactory[]) {}\n\n\tloggerFor(name: string): Logger {\n\t\treturn new CompositeLogger(\n\t\t\tthis.factories.map((f) => f.loggerFor(name)),\n\t\t);\n\t}\n}\n\nexport class CompositeLogger implements Logger {\n\tconstructor(private readonly loggers: Logger[]) {}\n\n\tdebug(...args: unknown[]): string {\n\t\treturn this.callAll(\"debug\", args);\n\t}\n\n\tinfo(...args: unknown[]): string {\n\t\treturn this.callAll(\"info\", args);\n\t}\n\n\twarn(...args: unknown[]): string {\n\t\treturn this.callAll(\"warn\", args);\n\t}\n\n\terror(...args: unknown[]): string {\n\t\treturn this.callAll(\"error\", args);\n\t}\n\n\tprivate callAll(\n\t\tmethod: \"debug\" | \"info\" | \"warn\" | \"error\",\n\t\targs: unknown[],\n\t): string {\n\t\tfor (const logger of this.loggers) {\n\t\t\tlogger[method](...args);\n\t\t}\n\t\treturn \"\";\n\t}\n}\n","/**\n * stableStringify — 确定性 JSON 序列化(keys 按字母排序)\n *\n * 用作缓存 key:相同内容的对象始终产生相同字符串。\n */\n\nexport function stableStringify(obj: unknown): string {\n\tif (obj === null || obj === undefined) return String(obj);\n\tif (typeof obj !== \"object\") return JSON.stringify(obj);\n\tif (Array.isArray(obj)) {\n\t\treturn \"[\" + obj.map(stableStringify).join(\",\") + \"]\";\n\t}\n\tconst keys = Object.keys(obj as Record<string, unknown>).sort();\n\tconst parts = keys\n\t\t.filter((k) => (obj as Record<string, unknown>)[k] !== undefined)\n\t\t.map(\n\t\t\t(k) =>\n\t\t\t\tJSON.stringify(k) +\n\t\t\t\t\":\" +\n\t\t\t\tstableStringify((obj as Record<string, unknown>)[k]),\n\t\t);\n\treturn \"{\" + parts.join(\",\") + \"}\";\n}\n","/**\n * PrefetchedIntents — SSR 数据缓存\n *\n * 服务端渲染时将 Intent→Data 映射序列化嵌入 HTML,\n * 客户端 hydrate 时提取缓存。Framework.dispatch() 优先查缓存,\n * 命中则直接返回,未命中则走 Controller 调度。\n */\n\nimport type { Intent } from \"../intents/types\";\nimport { stableStringify } from \"./stable-stringify\";\n\n/** 预获取的 Intent-Data 对 */\nexport interface PrefetchedIntent {\n\tintent: Intent;\n\tdata: unknown;\n}\n\nexport class PrefetchedIntents {\n\tprivate intents: Map<string, unknown>;\n\n\tprivate constructor(intents: Map<string, unknown>) {\n\t\tthis.intents = intents;\n\t}\n\n\t/** 从 PrefetchedIntent 数组创建缓存实例 */\n\tstatic fromArray(items: PrefetchedIntent[]): PrefetchedIntents {\n\t\tconst map = new Map<string, unknown>();\n\t\tfor (const item of items) {\n\t\t\tif (item.intent && item.data !== undefined) {\n\t\t\t\tconst key = stableStringify(item.intent);\n\t\t\t\tmap.set(key, item.data);\n\t\t\t}\n\t\t}\n\t\treturn new PrefetchedIntents(map);\n\t}\n\n\t/** 创建空缓存实例 */\n\tstatic empty(): PrefetchedIntents {\n\t\treturn new PrefetchedIntents(new Map());\n\t}\n\n\t/**\n\t * 获取缓存的 Intent 结果(一次性使用)。\n\t * 命中后从缓存中删除。\n\t */\n\tget<T>(intent: Intent<T>): T | undefined {\n\t\tconst key = stableStringify(intent);\n\t\tconst data = this.intents.get(key);\n\t\tif (data !== undefined) {\n\t\t\tthis.intents.delete(key);\n\t\t\treturn data as T;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/** 检查缓存中是否有某个 Intent 的数据 */\n\thas(intent: Intent): boolean {\n\t\treturn this.intents.has(stableStringify(intent));\n\t}\n\n\t/** 缓存中的条目数 */\n\tget size(): number {\n\t\treturn this.intents.size;\n\t}\n}\n","/**\n * Framework — 框架核心类\n *\n * 对应原版 Jet 类,统一管理: DI 容器、Intent 分发、Action 分发、路由、Metrics。\n * 纯 TypeScript,不依赖任何 UI 框架。\n */\n\nimport { ActionDispatcher, type ActionHandler } from \"./actions/dispatcher\";\nimport type { Action } from \"./actions/types\";\nimport { Container } from \"./dependencies/container\";\nimport type { MetricsRecorder } from \"./dependencies/make-dependencies\";\nimport {\n\tDEP_KEYS,\n\tmakeDependencies,\n\ttype MakeDependenciesOptions,\n} from \"./dependencies/make-dependencies\";\nimport { IntentDispatcher } from \"./intents/dispatcher\";\nimport type { Intent, IntentController } from \"./intents/types\";\nimport type { Logger } from \"./logger/types\";\nimport type { BasePage } from \"./models/page\";\nimport { PrefetchedIntents } from \"./prefetched-intents/prefetched-intents\";\nimport { Router, type RouteMatch } from \"./router/router\";\n\n/** Framework 初始化配置 */\nexport interface FrameworkConfig extends MakeDependenciesOptions {\n\tsetupRoutes?: (router: Router) => void;\n\tprefetchedIntents?: PrefetchedIntents;\n}\n\nexport class Framework {\n\treadonly container: Container;\n\treadonly intentDispatcher: IntentDispatcher;\n\treadonly actionDispatcher: ActionDispatcher;\n\treadonly router: Router;\n\treadonly prefetchedIntents: PrefetchedIntents;\n\n\tprivate constructor(\n\t\tcontainer: Container,\n\t\tprefetchedIntents: PrefetchedIntents,\n\t) {\n\t\tthis.container = container;\n\t\tthis.intentDispatcher = new IntentDispatcher();\n\t\tthis.actionDispatcher = new ActionDispatcher();\n\t\tthis.router = new Router();\n\t\tthis.prefetchedIntents = prefetchedIntents;\n\t}\n\n\t/** 创建并初始化 Framework 实例 */\n\tstatic create(config: FrameworkConfig = {}): Framework {\n\t\tconst container = new Container();\n\t\tmakeDependencies(container, config);\n\n\t\tconst fw = new Framework(\n\t\t\tcontainer,\n\t\t\tconfig.prefetchedIntents ?? PrefetchedIntents.empty(),\n\t\t);\n\n\t\tconfig.setupRoutes?.(fw.router);\n\n\t\treturn fw;\n\t}\n\n\t/** 分发 Intent — 获取页面数据 */\n\tasync dispatch<T>(intent: Intent<T>): Promise<T> {\n\t\tconst logger = this.container.resolve<Logger>(DEP_KEYS.LOGGER);\n\n\t\tconst cached = this.prefetchedIntents.get(intent);\n\t\tif (cached !== undefined) {\n\t\t\tlogger.debug(\n\t\t\t\t`[Framework] re-using prefetched intent response for: ${intent.id}`,\n\t\t\t\tintent.params,\n\t\t\t);\n\t\t\treturn cached;\n\t\t}\n\n\t\tlogger.debug(\n\t\t\t`[Framework] dispatch intent: ${intent.id}`,\n\t\t\tintent.params,\n\t\t);\n\t\treturn this.intentDispatcher.dispatch(intent, this.container);\n\t}\n\n\t/** 执行 Action — 处理用户交互 */\n\tasync perform(action: Action): Promise<void> {\n\t\tconst logger = this.container.resolve<Logger>(DEP_KEYS.LOGGER);\n\t\tlogger.debug(`[Framework] perform action: ${action.kind}`);\n\t\treturn this.actionDispatcher.perform(action);\n\t}\n\n\t/** 路由 URL — 将 URL 解析为 Intent + Action */\n\trouteUrl(url: string): RouteMatch | null {\n\t\treturn this.router.resolve(url);\n\t}\n\n\t/** 记录页面访问事件 */\n\tdidEnterPage(page: BasePage): void {\n\t\tconst metrics = this.container.resolve<MetricsRecorder>(\n\t\t\tDEP_KEYS.METRICS,\n\t\t);\n\t\tmetrics.recordPageView(page.pageType, {\n\t\t\tpageId: page.id,\n\t\t\ttitle: page.title,\n\t\t});\n\t}\n\n\t/** 注册 Action 处理器 */\n\tonAction<A extends Action>(kind: string, handler: ActionHandler<A>): void {\n\t\tthis.actionDispatcher.onAction(kind, handler);\n\t}\n\n\t/** 注册 Intent Controller */\n\tregisterIntent(controller: IntentController): void {\n\t\tthis.intentDispatcher.register(controller);\n\t}\n\n\t/** 销毁 Framework 实例 */\n\tdispose(): void {\n\t\tthis.container.dispose();\n\t}\n}\n","/**\n * HttpClient — 通用 HTTP 客户端基类\n *\n * 为 API Client 提供标准化的 HTTP 请求能力。\n * 子类继承后只需关注业务端点定义,不需要重复实现 fetch / JSON 解析 / 错误处理。\n */\n\n/** HTTP 请求错误 */\nexport class HttpError extends Error {\n\tconstructor(\n\t\tpublic readonly status: number,\n\t\tpublic readonly statusText: string,\n\t\tpublic readonly body?: string,\n\t) {\n\t\tsuper(`HTTP ${status}: ${statusText}`);\n\t\tthis.name = \"HttpError\";\n\t}\n}\n\n/** HttpClient 构造配置 */\nexport interface HttpClientConfig {\n\t/** API base URL(如 \"/api\" 或 \"https://example.com/api\") */\n\tbaseUrl: string;\n\t/** 默认请求头 */\n\tdefaultHeaders?: Record<string, string>;\n\t/** 自定义 fetch 实现(便于测试或 SSR) */\n\tfetch?: typeof globalThis.fetch;\n}\n\n/**\n * 通用 HTTP 客户端基类\n *\n * 使用方式: 创建子类继承 HttpClient,定义业务方法调用 this.get() / this.post() 等。\n *\n * @example\n * ```ts\n * class MyApiClient extends HttpClient {\n * async getUser(id: string) {\n * return this.get<User>(`/users/${id}`);\n * }\n * }\n * ```\n */\nexport abstract class HttpClient {\n\tprotected readonly baseUrl: string;\n\tprotected readonly defaultHeaders: Record<string, string>;\n\tprotected readonly fetchFn: typeof globalThis.fetch;\n\n\tconstructor(config: HttpClientConfig) {\n\t\tthis.baseUrl = config.baseUrl;\n\t\tthis.defaultHeaders = config.defaultHeaders ?? {};\n\t\tthis.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n\t}\n\n\t/** GET 请求,返回解析后的 JSON */\n\tprotected async get<T>(\n\t\tpath: string,\n\t\tparams?: Record<string, string>,\n\t): Promise<T> {\n\t\treturn this.request<T>(\"GET\", path, { params });\n\t}\n\n\t/** POST 请求,自动序列化 body 为 JSON */\n\tprotected async post<T>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\tparams?: Record<string, string>,\n\t): Promise<T> {\n\t\treturn this.request<T>(\"POST\", path, { body, params });\n\t}\n\n\t/** PUT 请求 */\n\tprotected async put<T>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\tparams?: Record<string, string>,\n\t): Promise<T> {\n\t\treturn this.request<T>(\"PUT\", path, { body, params });\n\t}\n\n\t/** DELETE 请求 */\n\tprotected async del<T>(\n\t\tpath: string,\n\t\tparams?: Record<string, string>,\n\t): Promise<T> {\n\t\treturn this.request<T>(\"DELETE\", path, { params });\n\t}\n\n\t/**\n\t * 底层请求方法 — 子类可覆写以自定义行为\n\t *\n\t * 自动处理:\n\t * - URL 拼接 (baseUrl + path + params)\n\t * - 默认 headers 合并\n\t * - JSON body 序列化\n\t * - 响应 JSON 解析\n\t * - 非 2xx 状态码抛出 HttpError\n\t */\n\tprotected async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\toptions?: {\n\t\t\tparams?: Record<string, string>;\n\t\t\tbody?: unknown;\n\t\t\theaders?: Record<string, string>;\n\t\t},\n\t): Promise<T> {\n\t\tconst url = this.buildUrl(path, options?.params);\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t...this.defaultHeaders,\n\t\t\t...options?.headers,\n\t\t};\n\n\t\tconst init: RequestInit = { method, headers };\n\n\t\tif (options?.body !== undefined) {\n\t\t\theaders[\"Content-Type\"] =\n\t\t\t\theaders[\"Content-Type\"] ?? \"application/json\";\n\t\t\tinit.body = JSON.stringify(options.body);\n\t\t}\n\n\t\tconst response = await this.fetchFn(url, init);\n\n\t\tif (!response.ok) {\n\t\t\tconst body = await response.text().catch(() => undefined);\n\t\t\tthrow new HttpError(response.status, response.statusText, body);\n\t\t}\n\n\t\treturn response.json();\n\t}\n\n\t/** 构建完整 URL — 子类可覆写以自定义 URL 拼接逻辑 */\n\tprotected buildUrl(path: string, params?: Record<string, string>): string {\n\t\tconst base = this.baseUrl.endsWith(\"/\")\n\t\t\t? this.baseUrl.slice(0, -1)\n\t\t\t: this.baseUrl;\n\t\tconst normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n\t\tconst url = new URL(`${base}${normalizedPath}`, \"http://placeholder\");\n\n\t\tif (params) {\n\t\t\tfor (const [k, v] of Object.entries(params)) {\n\t\t\t\turl.searchParams.set(k, v);\n\t\t\t}\n\t\t}\n\n\t\t// 如果 baseUrl 是绝对 URL,返回完整 URL;否则只返回 path + search\n\t\tif (this.baseUrl.startsWith(\"http\")) {\n\t\t\treturn url.toString();\n\t\t}\n\t\treturn `${url.pathname}${url.search}`;\n\t}\n}\n","/**\n * BaseController — 抽象 Intent Controller 基类\n *\n * 提供标准化的 try/catch → fallback 模式。\n * 子类只需实现 execute() 和可选的 fallback()。\n */\n\nimport type { Container } from \"../dependencies/container\";\nimport type { Intent, IntentController } from \"./types\";\n\n/**\n * 抽象 Controller 基类\n *\n * 统一处理:\n * - 类型安全的参数提取 (TParams)\n * - 返回类型约束 (TResult)\n * - try/catch 错误处理 + 可选 fallback\n *\n * @example\n * ```ts\n * class ProductController extends BaseController<{ productId: string }, ProductPage> {\n * readonly intentId = \"product-page\";\n *\n * async execute(params: { productId: string }, container: Container) {\n * const api = container.resolve<ApiClient>(\"api\");\n * return api.getProduct(params.productId);\n * }\n *\n * fallback(params: { productId: string }, error: Error) {\n * return getMockProduct(params.productId);\n * }\n * }\n * ```\n */\nexport abstract class BaseController<\n\tTParams extends Record<string, string | undefined> = Record<string, string>,\n\tTResult = unknown,\n> implements IntentController<TResult> {\n\t/** Controller 对应的 Intent ID */\n\tabstract readonly intentId: string;\n\n\t/**\n\t * 执行业务逻辑 — 子类必须实现\n\t *\n\t * @param params - Intent 参数(已类型化)\n\t * @param container - DI 容器\n\t * @returns 页面数据\n\t */\n\tabstract execute(\n\t\tparams: TParams,\n\t\tcontainer: Container,\n\t): Promise<TResult> | TResult;\n\n\t/**\n\t * 错误回退 — 子类可选覆写\n\t *\n\t * 当 execute() 抛出异常时调用。\n\t * 默认行为: 重新抛出原始错误。\n\t *\n\t * @param params - Intent 参数\n\t * @param error - execute() 抛出的错误\n\t * @returns 回退数据\n\t */\n\tfallback(params: TParams, error: Error): Promise<TResult> | TResult {\n\t\tthrow error;\n\t}\n\n\t/**\n\t * IntentController.perform() 实现\n\t *\n\t * 自动 try/catch → fallback 模式。\n\t */\n\tasync perform(\n\t\tintent: Intent<TResult>,\n\t\tcontainer: Container,\n\t): Promise<TResult> {\n\t\tconst params = (intent.params ?? {}) as TParams;\n\t\ttry {\n\t\t\treturn await this.execute(params, container);\n\t\t} catch (e) {\n\t\t\treturn this.fallback(\n\t\t\t\tparams,\n\t\t\t\te instanceof Error ? e : new Error(String(e)),\n\t\t\t);\n\t\t}\n\t}\n}\n","/**\n * Mapper 类型工具 — 标准化数据转换管线\n *\n * 提供类型约定和组合函数,让 API 响应 → 页面模型 的转换有统一的签名模式。\n */\n\n/** 同步映射函数 */\nexport type Mapper<TInput, TOutput> = (input: TInput) => TOutput;\n\n/** 异步映射函数 */\nexport type AsyncMapper<TInput, TOutput> = (\n\tinput: TInput,\n) => TOutput | Promise<TOutput>;\n\n/**\n * 组合两个同步 Mapper: A → B → C\n */\nexport function pipe<A, B, C>(m1: Mapper<A, B>, m2: Mapper<B, C>): Mapper<A, C>;\n/**\n * 组合三个同步 Mapper: A → B → C → D\n */\nexport function pipe<A, B, C, D>(\n\tm1: Mapper<A, B>,\n\tm2: Mapper<B, C>,\n\tm3: Mapper<C, D>,\n): Mapper<A, D>;\n/**\n * 组合四个同步 Mapper: A → B → C → D → E\n */\nexport function pipe<A, B, C, D, E>(\n\tm1: Mapper<A, B>,\n\tm2: Mapper<B, C>,\n\tm3: Mapper<C, D>,\n\tm4: Mapper<D, E>,\n): Mapper<A, E>;\n/**\n * 组合任意数量的同步 Mapper\n */\nexport function pipe(\n\t...mappers: Mapper<unknown, unknown>[]\n): Mapper<unknown, unknown>;\nexport function pipe(\n\t...mappers: Mapper<unknown, unknown>[]\n): Mapper<unknown, unknown> {\n\treturn (input: unknown) =>\n\t\tmappers.reduce((acc, mapper) => mapper(acc), input);\n}\n\n/**\n * 组合两个可能异步的 Mapper: A → B → C\n */\nexport function pipeAsync<A, B, C>(\n\tm1: AsyncMapper<A, B>,\n\tm2: AsyncMapper<B, C>,\n): AsyncMapper<A, C>;\n/**\n * 组合三个可能异步的 Mapper\n */\nexport function pipeAsync<A, B, C, D>(\n\tm1: AsyncMapper<A, B>,\n\tm2: AsyncMapper<B, C>,\n\tm3: AsyncMapper<C, D>,\n): AsyncMapper<A, D>;\nexport function pipeAsync(\n\t...mappers: AsyncMapper<unknown, unknown>[]\n): AsyncMapper<unknown, unknown> {\n\treturn async (input: unknown) => {\n\t\tlet acc = input;\n\t\tfor (const mapper of mappers) {\n\t\t\tacc = await mapper(acc);\n\t\t}\n\t\treturn acc;\n\t};\n}\n\n/**\n * 将一个 Mapper 应用到数组的每个元素\n */\nexport function mapEach<TInput, TOutput>(\n\tmapper: Mapper<TInput, TOutput>,\n): Mapper<TInput[], TOutput[]> {\n\treturn (items) => items.map(mapper);\n}\n","/**\n * defineRoutes — 声明式路由 + Controller 注册\n *\n * 将命令式的路由注册 (20+ 行 framework.router.add / framework.registerIntent)\n * 简化为声明式配置数组。\n */\n\nimport type { Framework } from \"../framework\";\nimport type { IntentController } from \"../intents/types\";\n\n/** 单条路由定义 */\nexport interface RouteDefinition {\n\t/** URL pattern (如 \"/product/:productId\") */\n\tpath: string;\n\t/** Intent ID (如 \"product-page\") */\n\tintentId: string;\n\t/**\n\t * Controller 实例(可选)。\n\t * 同一个 intentId 的多条路由只需在第一条提供 controller。\n\t */\n\tcontroller?: IntentController;\n}\n\n/**\n * 声明式注册路由和 Controller\n *\n * - 自动去重: 同一 intentId 的 controller 只注册一次\n * - 路由和 controller 在同一个配置数组中,方便检查一致性\n *\n * @example\n * ```ts\n * defineRoutes(framework, [\n * { path: \"/\", intentId: \"home\", controller: new HomeController() },\n * { path: \"/product/:id\", intentId: \"product\", controller: new ProductController() },\n * { path: \"/search\", intentId: \"search\", controller: new SearchController() },\n * { path: \"/charts/:type\", intentId: \"charts\", controller: new ChartsController() },\n * { path: \"/charts\", intentId: \"charts\" }, // 同 intentId,不需要重复 controller\n * ]);\n * ```\n */\nexport function defineRoutes(\n\tframework: Framework,\n\tdefinitions: RouteDefinition[],\n): void {\n\tconst registeredIntents = new Set<string>();\n\n\tfor (const def of definitions) {\n\t\t// 注册 Controller(每个 intentId 只注册一次)\n\t\tif (def.controller && !registeredIntents.has(def.intentId)) {\n\t\t\tframework.registerIntent(def.controller);\n\t\t\tregisteredIntents.add(def.intentId);\n\t\t}\n\n\t\t// 注册路由\n\t\tframework.router.add(def.path, def.intentId);\n\t}\n}\n","/**\n * LruMap — 固定容量的 LRU 缓存\n */\n\nexport class LruMap<K, V> {\n\tprivate map = new Map<K, V>();\n\tprivate readonly capacity: number;\n\n\tconstructor(capacity: number) {\n\t\tthis.capacity = capacity;\n\t}\n\n\tget(key: K): V | undefined {\n\t\tconst value = this.map.get(key);\n\t\tif (value !== undefined) {\n\t\t\t// 移到末尾(最近使用)\n\t\t\tthis.map.delete(key);\n\t\t\tthis.map.set(key, value);\n\t\t}\n\t\treturn value;\n\t}\n\n\tset(key: K, value: V): void {\n\t\tif (this.map.has(key)) {\n\t\t\tthis.map.delete(key);\n\t\t} else if (this.map.size >= this.capacity) {\n\t\t\t// 删除最旧的(第一个)\n\t\t\tconst oldest = this.map.keys().next().value;\n\t\t\tif (oldest !== undefined) {\n\t\t\t\tthis.map.delete(oldest);\n\t\t\t}\n\t\t}\n\t\tthis.map.set(key, value);\n\t}\n\n\thas(key: K): boolean {\n\t\treturn this.map.has(key);\n\t}\n\n\tdelete(key: K): boolean {\n\t\treturn this.map.delete(key);\n\t}\n\n\tget size(): number {\n\t\treturn this.map.size;\n\t}\n\n\tclear(): void {\n\t\tthis.map.clear();\n\t}\n}\n","/**\n * Optional 类型工具\n */\n\nexport type None = null | undefined;\nexport type Optional<T> = T | None;\n\nexport function isSome<T>(value: Optional<T>): value is T {\n\treturn value !== null && value !== undefined;\n}\n\nexport function isNone<T>(value: Optional<T>): value is None {\n\treturn value === null || value === undefined;\n}\n","/**\n * URL 工具函数\n */\n\n/** 移除 URL scheme (https://, http://) */\nexport function removeScheme(url: string): string {\n\treturn url.replace(/^https?:\\/\\//, \"\");\n}\n\n/** 移除 URL host 部分,保留路径 */\nexport function removeHost(url: string): string {\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\treturn parsed.pathname + parsed.search + parsed.hash;\n\t} catch {\n\t\treturn url;\n\t}\n}\n\n/** 移除 query 参数 */\nexport function removeQueryParams(url: string): string {\n\treturn url.split(\"?\")[0];\n}\n\n/** 获取 URL 的基础路径(无 query、hash) */\nexport function getBaseUrl(url: string): string {\n\treturn url.split(\"?\")[0].split(\"#\")[0];\n}\n\n/** 构建 URL(路径 + query 参数) */\nexport function buildUrl(\n\tpath: string,\n\tparams?: Record<string, string | undefined>,\n): string {\n\tif (!params) return path;\n\n\tconst searchParams = new URLSearchParams();\n\tfor (const [key, value] of Object.entries(params)) {\n\t\tif (value !== undefined) {\n\t\t\tsearchParams.set(key, value);\n\t\t}\n\t}\n\n\tconst qs = searchParams.toString();\n\treturn qs ? `${path}?${qs}` : path;\n}\n","/**\n * UUID v4 生成器\n */\n\nexport function generateUuid(): string {\n\tif (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n\t\treturn crypto.randomUUID();\n\t}\n\t// Fallback\n\treturn \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n\t\tconst r = (Math.random() * 16) | 0;\n\t\tconst v = c === \"x\" ? r : (r & 0x3) | 0x8;\n\t\treturn v.toString(16);\n\t});\n}\n","// ===== Actions =====\nexport { ActionDispatcher } from \"./actions/dispatcher\";\nexport type { ActionHandler } from \"./actions/dispatcher\";\nexport {\n\tACTION_KINDS,\n\tisCompoundAction,\n\tisExternalUrlAction,\n\tisFlowAction,\n\tmakeExternalUrlAction,\n\tmakeFlowAction,\n} from \"./actions/types\";\nexport type {\n\tAction,\n\tCompoundAction,\n\tExternalUrlAction,\n\tFlowAction,\n} from \"./actions/types\";\n\n// ===== Intents =====\nexport { IntentDispatcher } from \"./intents/dispatcher\";\nexport type { Intent, IntentController } from \"./intents/types\";\n\n// ===== Dependencies =====\nexport { Container } from \"./dependencies/container\";\nexport { DEP_KEYS, makeDependencies } from \"./dependencies/make-dependencies\";\nexport type {\n\tFeatureFlags,\n\tLocale,\n\tLogger,\n\tMetricsRecorder,\n\tNet,\n\tStorage,\n} from \"./dependencies/make-dependencies\";\n\n// ===== Router =====\nexport { Router } from \"./router/router\";\nexport type { RouteMatch } from \"./router/router\";\n\n// ===== Logger =====\nexport { BaseLogger } from \"./logger/base\";\nexport { CompositeLogger, CompositeLoggerFactory } from \"./logger/composite\";\nexport { ConsoleLogger, ConsoleLoggerFactory } from \"./logger/console\";\nexport { resetFilterCache, shouldLog } from \"./logger/local-storage-filter\";\nexport type { LoggerFactory, Logger as LoggerInterface } from \"./logger/types\";\n\n// ===== Framework =====\nexport { Framework } from \"./framework\";\nexport type { FrameworkConfig } from \"./framework\";\n\n// ===== Models =====\nexport type { BasePage } from \"./models/page\";\nexport type { BaseItem, BaseShelf } from \"./models/shelf\";\n\n// ===== Prefetched Intents =====\nexport { PrefetchedIntents } from \"./prefetched-intents/prefetched-intents\";\nexport type { PrefetchedIntent } from \"./prefetched-intents/prefetched-intents\";\nexport { stableStringify } from \"./prefetched-intents/stable-stringify\";\n\n// ===== HTTP =====\nexport { HttpClient, HttpError } from \"./http/client\";\nexport type { HttpClientConfig } from \"./http/client\";\n\n// ===== Base Controller =====\nexport { BaseController } from \"./intents/base-controller\";\n\n// ===== Data / Mapper =====\nexport { mapEach, pipe, pipeAsync } from \"./data/mapper\";\nexport type { AsyncMapper, Mapper } from \"./data/mapper\";\n\n// ===== Bootstrap =====\nexport { defineRoutes } from \"./bootstrap/define-routes\";\nexport type { RouteDefinition } from \"./bootstrap/define-routes\";\n\n// ===== Utils =====\nexport { LruMap } from \"./utils/lru-map\";\nexport { isNone, isSome, type None, type Optional } from \"./utils/optional\";\nexport {\n\tbuildUrl,\n\tgetBaseUrl,\n\tremoveHost,\n\tremoveQueryParams,\n\tremoveScheme,\n} from \"./utils/url\";\nexport { generateUuid } from \"./utils/uuid\";\n","/**\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}\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}\n\nexport async function ssrRender(\n\toptions: SSRRenderOptions,\n): Promise<SSRRenderResult> {\n\tconst { url, frameworkConfig, bootstrap, getErrorPage, renderApp } =\n\t\toptions;\n\n\tconst framework = Framework.create(frameworkConfig);\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\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};\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 { ssrRender, type SSRAppResult, type SSRRenderResult } 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)` — 供 @finesoft/server SSRModule 使用\n */\nexport function createSSRRender(\n\tconfig: SSRRenderConfig,\n): (url: string, locale: string) => Promise<SSRRenderResult> {\n\tconst { bootstrap, getErrorPage, renderApp, frameworkConfig } = config;\n\n\treturn (url: string, locale: string) =>\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});\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 * 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","export { createSSRRender, type SSRRenderConfig } from \"./create-render\";\nexport {\n\tSSR_PLACEHOLDERS,\n\tinjectSSRContent,\n\ttype InjectSSROptions,\n} from \"./inject\";\nexport {\n\tssrRender,\n\ttype SSRRenderOptions,\n\ttype SSRRenderResult,\n} from \"./render\";\nexport { serializeServerData } from \"./server-data\";\n\n// ===== Re-exports from @finesoft/core (convenience) =====\nexport { Framework } from \"@finesoft/core\";\nexport type { BasePage } from \"@finesoft/core\";\n","/**\n * Accept-Language 解析\n */\n\nexport function parseAcceptLanguage(\n\theader: string | undefined,\n\tsupported?: string[],\n\tfallback?: string,\n): string {\n\tconst effectiveSupported = supported ?? [\"zh\", \"en\"];\n\tconst effectiveFallback = fallback ?? effectiveSupported[0] ?? \"en\";\n\tif (!header) return effectiveFallback;\n\tconst langs = header\n\t\t.split(\",\")\n\t\t.map((part) => {\n\t\t\tconst [lang, q] = part.trim().split(\";q=\");\n\t\t\treturn {\n\t\t\t\tlang: lang.trim().toLowerCase(),\n\t\t\t\tq: q ? parseFloat(q) : 1,\n\t\t\t};\n\t\t})\n\t\t.sort((a, b) => b.q - a.q);\n\n\tfor (const { lang } of langs) {\n\t\tconst prefix = lang.split(\"-\")[0];\n\t\tif (effectiveSupported.includes(prefix)) {\n\t\t\treturn prefix;\n\t\t}\n\t}\n\treturn effectiveFallback;\n}\n","/**\n * createSSRApp — 创建 Hono SSR 应用\n *\n * 提供 SSR 通配路由,读取模板、加载 SSR 模块、渲染。\n * 应用层可在此之上追加自定义路由(API 代理等)。\n */\n\nimport { injectSSRContent } from \"@finesoft/ssr\";\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { parseAcceptLanguage } from \"./locale\";\n\nexport interface SSRModule {\n\trender: (\n\t\turl: string,\n\t\tlocale: string,\n\t) => Promise<{\n\t\thtml: string;\n\t\thead: string;\n\t\tcss: string;\n\t\tserverData: unknown;\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}\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} = options;\n\n\tconst app = new Hono();\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(ssrProductionModule) 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(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\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} = await render(url, locale);\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\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","/// <reference path=\"./shims/server-peer-modules.d.ts\" />\n\n// ===== Core =====\nexport * from \"@finesoft/core\";\n\n// ===== Browser (unique exports only) =====\nexport {\n\tHistory,\n\tcreatePrefetchedIntentsFromDom,\n\tdeserializeServerData,\n\tregisterActionHandlers,\n\tregisterExternalUrlHandler,\n\tregisterFlowActionHandler,\n\tstartBrowserApp,\n\ttryScroll,\n} from \"@finesoft/browser\";\nexport type {\n\tActionHandlerDependencies,\n\tBrowserAppConfig,\n\tExternalUrlDependencies,\n\tFlowActionCallbacks,\n\tFlowActionDependencies,\n} from \"@finesoft/browser\";\n\n// ===== SSR (unique exports only) =====\nexport {\n\tSSR_PLACEHOLDERS,\n\tcreateSSRRender,\n\tinjectSSRContent,\n\tserializeServerData,\n\tssrRender,\n} from \"@finesoft/ssr\";\nexport type {\n\tInjectSSROptions,\n\tSSRRenderConfig,\n\tSSRRenderOptions,\n\tSSRRenderResult,\n} from \"@finesoft/ssr\";\n\n// ===== Server =====\nexport * from \"@finesoft/server\";\n","/**\n * ExternalUrl Action Handler — 外部链接处理器\n */\n\nimport type { ExternalUrlAction, Framework, Logger } from \"@finesoft/core\";\nimport { ACTION_KINDS } from \"@finesoft/core\";\n\nexport interface ExternalUrlDependencies {\n\tframework: Framework;\n\tlog: Logger;\n}\n\nexport function registerExternalUrlHandler(\n\tdeps: ExternalUrlDependencies,\n): void {\n\tconst { framework, log } = deps;\n\n\tframework.onAction(\n\t\tACTION_KINDS.EXTERNAL_URL,\n\t\t(action: ExternalUrlAction) => {\n\t\t\tlog.debug(`ExternalUrlAction → ${action.url}`);\n\t\t\twindow.open(action.url, \"_blank\", \"noopener,noreferrer\");\n\t\t},\n\t);\n}\n","/**\n * FlowAction Handler — 核心 SPA 导航处理器\n *\n * 通过 FlowActionCallbacks 注入 UI 更新回调,\n * 不直接依赖任何 UI 框架的 store。\n */\n\nimport type { BasePage, FlowAction, Framework, Logger } from \"@finesoft/core\";\nimport { ACTION_KINDS } from \"@finesoft/core\";\nimport { History } from \"../utils/history\";\n\n/** FlowAction handler 的 History state */\ninterface FlowState {\n\tpage: BasePage;\n}\n\n/** UI 框架回调 — 解耦 Svelte store 等依赖 */\nexport interface FlowActionCallbacks {\n\t/** 导航后更新当前路径(替代 currentPath.set()) */\n\tonNavigate(pathname: string): void;\n\t/** 模态页面展示(替代 openModal()) */\n\tonModal(page: BasePage): void;\n}\n\n/** 注册 FlowAction handler 所需的依赖 */\nexport interface FlowActionDependencies {\n\tframework: Framework;\n\tlog: Logger;\n\tcallbacks: FlowActionCallbacks;\n\t/** 更新应用 UI 的回调,page 可以是 Promise */\n\tupdateApp: (props: {\n\t\tpage: Promise<BasePage> | BasePage;\n\t\tisFirstPage?: boolean;\n\t}) => void;\n}\n\nexport function registerFlowActionHandler(deps: FlowActionDependencies): void {\n\tconst { framework, log, callbacks, updateApp } = deps;\n\tlet isFirstPage = true;\n\n\tconst history = new History<FlowState>(log, {\n\t\tgetScrollablePageElement: () =>\n\t\t\tdocument.getElementById(\"scrollable-page-override\") ||\n\t\t\tdocument.getElementById(\"scrollable-page\") ||\n\t\t\tdocument.documentElement,\n\t});\n\n\t// ===== FlowAction handler =====\n\tframework.onAction(ACTION_KINDS.FLOW, async (action) => {\n\t\tconst flowAction = action as FlowAction;\n\t\tconst url = flowAction.url;\n\t\tlog.debug(`FlowAction → ${url}`);\n\n\t\t// 模态展示\n\t\tif (flowAction.presentationContext === \"modal\") {\n\t\t\tconst match = framework.routeUrl(url);\n\t\t\tif (match) {\n\t\t\t\tconst page = (await framework.dispatch(\n\t\t\t\t\tmatch.intent,\n\t\t\t\t)) as BasePage;\n\t\t\t\tcallbacks.onModal(page);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst shouldReplace = isFirstPage;\n\n\t\tconst match = framework.routeUrl(url);\n\t\tif (!match) {\n\t\t\tlog.warn(`FlowAction: no route for ${url}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst pagePromise = framework.dispatch(\n\t\t\tmatch.intent,\n\t\t) as Promise<BasePage>;\n\n\t\tawait Promise.race([\n\t\t\tpagePromise,\n\t\t\tnew Promise((r) => setTimeout(r, 500)),\n\t\t]).catch(() => {});\n\n\t\thistory.beforeTransition();\n\n\t\tupdateApp({\n\t\t\tpage: pagePromise.then((page: BasePage): BasePage => {\n\t\t\t\tconst canonicalURL = url;\n\n\t\t\t\tif (shouldReplace) {\n\t\t\t\t\thistory.replaceState({ page }, canonicalURL);\n\t\t\t\t} else {\n\t\t\t\t\thistory.pushState({ page }, canonicalURL);\n\t\t\t\t}\n\n\t\t\t\tcallbacks.onNavigate(\n\t\t\t\t\tnew URL(canonicalURL, window.location.origin).pathname,\n\t\t\t\t);\n\n\t\t\t\tdidEnterPage(page);\n\t\t\t\treturn page;\n\t\t\t}),\n\t\t\tisFirstPage,\n\t\t});\n\n\t\tisFirstPage = false;\n\t});\n\n\t// ===== popstate handler =====\n\thistory.onPopState(async (url, cachedState) => {\n\t\tlog.debug(`popstate → ${url}, cached=${!!cachedState}`);\n\n\t\tcallbacks.onNavigate(new URL(url).pathname);\n\n\t\tif (cachedState) {\n\t\t\tconst { page } = cachedState;\n\t\t\tdidEnterPage(page);\n\t\t\tupdateApp({ page, isFirstPage });\n\t\t\treturn;\n\t\t}\n\n\t\tconst parsed = new URL(url);\n\t\tconst routeMatch = framework.routeUrl(parsed.pathname + parsed.search);\n\t\tif (!routeMatch) {\n\t\t\tlog.error(\n\t\t\t\t\"received popstate without data, but URL was unroutable:\",\n\t\t\t\turl,\n\t\t\t);\n\t\t\tdidEnterPage(null);\n\t\t\tupdateApp({\n\t\t\t\tpage: Promise.reject(new Error(\"404\")),\n\t\t\t\tisFirstPage,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tconst pagePromise = framework.dispatch(\n\t\t\trouteMatch.intent,\n\t\t) as Promise<BasePage>;\n\n\t\tawait Promise.race([\n\t\t\tpagePromise,\n\t\t\tnew Promise((r) => setTimeout(r, 500)),\n\t\t]).catch(() => {});\n\n\t\tupdateApp({\n\t\t\tpage: pagePromise.then((page: BasePage): BasePage => {\n\t\t\t\tdidEnterPage(page);\n\t\t\t\treturn page;\n\t\t\t}),\n\t\t\tisFirstPage,\n\t\t});\n\t});\n\n\tfunction didEnterPage(page: BasePage | null): void {\n\t\t(async (): Promise<void> => {\n\t\t\ttry {\n\t\t\t\tif (page) {\n\t\t\t\t\tawait framework.didEnterPage(page);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tlog.error(\"didEnterPage error:\", e);\n\t\t\t}\n\t\t})();\n\t}\n}\n","/**\n * History 管理器 — 浏览器历史状态 + 滚动位置\n */\n\nimport type { Logger } from \"@finesoft/core\";\nimport { LruMap, generateUuid } from \"@finesoft/core\";\nimport { tryScroll } from \"./try-scroll\";\n\nconst HISTORY_SIZE_LIMIT = 10;\n\ninterface HistoryEntry<State> {\n\tstate: State;\n\tscrollY: number;\n}\n\ninterface HistoryOptions {\n\tgetScrollablePageElement: () => HTMLElement | null;\n}\n\nexport class History<State> {\n\tprivate readonly entries: LruMap<string, HistoryEntry<State>>;\n\tprivate readonly log: Logger;\n\tprivate readonly getScrollablePageElement: () => HTMLElement | null;\n\tprivate currentStateId: string | undefined;\n\n\tconstructor(\n\t\tlog: Logger,\n\t\toptions: HistoryOptions,\n\t\tsizeLimit = HISTORY_SIZE_LIMIT,\n\t) {\n\t\tthis.entries = new LruMap(sizeLimit);\n\t\tthis.log = log;\n\t\tthis.getScrollablePageElement = options.getScrollablePageElement;\n\t}\n\n\treplaceState(state: State, url: string): void {\n\t\tconst id = generateUuid();\n\t\twindow.history.replaceState({ id }, \"\", url);\n\t\tthis.currentStateId = id;\n\t\tthis.entries.set(id, { state, scrollY: 0 });\n\t\tthis.scrollTop = 0;\n\t\tthis.log.info(\"replaceState\", state, url, id);\n\t}\n\n\tpushState(state: State, url: string): void {\n\t\tconst id = generateUuid();\n\t\twindow.history.pushState({ id }, \"\", url);\n\t\tthis.currentStateId = id;\n\t\tthis.entries.set(id, { state, scrollY: 0 });\n\t\tthis.scrollTop = 0;\n\t\tthis.log.info(\"pushState\", state, url, id);\n\t}\n\n\tbeforeTransition(): void {\n\t\tconst { state } = window.history;\n\t\tif (!state) return;\n\n\t\tconst oldEntry = this.entries.get(state.id);\n\t\tif (!oldEntry) {\n\t\t\tthis.log.info(\n\t\t\t\t\"current history state evicted from LRU, not saving scroll position\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { scrollTop } = this;\n\t\tthis.entries.set(state.id, { ...oldEntry, scrollY: scrollTop });\n\t\tthis.log.info(\"saving scroll position\", scrollTop);\n\t}\n\n\tonPopState(listener: (url: string, state?: State) => void): void {\n\t\twindow.addEventListener(\"popstate\", (event: PopStateEvent) => {\n\t\t\tthis.currentStateId = event.state?.id;\n\n\t\t\tif (!this.currentStateId) {\n\t\t\t\tthis.log.warn(\n\t\t\t\t\t\"encountered a null event.state.id in onPopState event:\",\n\t\t\t\t\twindow.location.href,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.log.info(\"popstate\", this.entries, this.currentStateId);\n\n\t\t\tconst entry = this.currentStateId\n\t\t\t\t? this.entries.get(this.currentStateId)\n\t\t\t\t: undefined;\n\n\t\t\tlistener(window.location.href, entry?.state);\n\n\t\t\tif (!entry) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { scrollY } = entry;\n\t\t\tthis.log.info(\"restoring scroll to\", scrollY);\n\t\t\ttryScroll(this.log, () => this.getScrollablePageElement(), scrollY);\n\t\t});\n\t}\n\n\tupdateState(update: (current?: State) => State): void {\n\t\tif (!this.currentStateId) {\n\t\t\tthis.log.warn(\n\t\t\t\t\"failed: encountered a null currentStateId inside updateState\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentState = this.entries.get(this.currentStateId);\n\t\tconst newState = update(currentState?.state);\n\t\tthis.log.info(\"updateState\", newState, this.currentStateId);\n\t\tthis.entries.set(this.currentStateId, {\n\t\t\t...(currentState as HistoryEntry<State>),\n\t\t\tstate: newState,\n\t\t});\n\t}\n\n\tprivate get scrollTop(): number {\n\t\treturn this.getScrollablePageElement()?.scrollTop || 0;\n\t}\n\n\tprivate set scrollTop(scrollTop: number) {\n\t\tconst element = this.getScrollablePageElement();\n\t\tif (element) {\n\t\t\telement.scrollTop = scrollTop;\n\t\t}\n\t}\n}\n","/**\n * tryScroll — 渐进式滚动位置恢复\n *\n * 使用 rAF 循环等待页面高度足够后恢复滚动位置。\n */\n\nimport type { Logger } from \"@finesoft/core\";\n\nconst MAX_TRIES = 100;\nconst FUDGE = 16;\n\nlet pendingFrame: number | null = null;\n\nexport function tryScroll(\n\tlog: Logger,\n\tgetScrollableElement: () => HTMLElement | null,\n\tscrollY: number,\n): void {\n\tif (pendingFrame !== null) {\n\t\tcancelAnimationFrame(pendingFrame);\n\t\tpendingFrame = null;\n\t}\n\n\tlet tries = 0;\n\n\tpendingFrame = requestAnimationFrame(function attempt() {\n\t\tif (++tries >= MAX_TRIES) {\n\t\t\tlog.warn(\n\t\t\t\t`tryScroll: gave up after ${MAX_TRIES} frames, target=${scrollY}`,\n\t\t\t);\n\t\t\tpendingFrame = null;\n\t\t\treturn;\n\t\t}\n\n\t\tconst el = getScrollableElement();\n\t\tif (!el) {\n\t\t\tlog.warn(\n\t\t\t\t\"could not restore scroll: the scrollable element is missing\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { scrollHeight, offsetHeight } = el;\n\t\tconst canScroll = scrollY + offsetHeight <= scrollHeight + FUDGE;\n\n\t\tif (!canScroll) {\n\t\t\tlog.info(\"page is not tall enough for scroll yet\", {\n\t\t\t\tscrollHeight,\n\t\t\t\toffsetHeight,\n\t\t\t});\n\t\t\tpendingFrame = requestAnimationFrame(attempt);\n\t\t\treturn;\n\t\t}\n\n\t\tel.scrollTop = scrollY;\n\t\tlog.info(\"scroll restored to\", scrollY);\n\t\tpendingFrame = null;\n\t});\n}\n","/**\n * Action Handler 统一注册入口\n */\n\nimport type { BasePage, Framework, Logger } from \"@finesoft/core\";\nimport { registerExternalUrlHandler } from \"./external-url-action\";\nimport {\n\tregisterFlowActionHandler,\n\ttype FlowActionCallbacks,\n} from \"./flow-action\";\n\nexport type { FlowActionCallbacks };\n\nexport interface ActionHandlerDependencies {\n\tframework: Framework;\n\tlog: Logger;\n\tcallbacks: FlowActionCallbacks;\n\tupdateApp: (props: {\n\t\tpage: Promise<BasePage> | BasePage;\n\t\tisFirstPage?: boolean;\n\t}) => void;\n}\n\nexport function registerActionHandlers(deps: ActionHandlerDependencies): void {\n\tconst { framework, log, callbacks, updateApp } = deps;\n\n\tregisterFlowActionHandler({\n\t\tframework,\n\t\tlog,\n\t\tcallbacks,\n\t\tupdateApp,\n\t});\n\n\tregisterExternalUrlHandler({ framework, log });\n}\n","/**\n * startBrowserApp — 客户端 hydration 一站式启动\n *\n * 封装:\n * 1. PrefetchedIntents 从 DOM 提取\n * 2. Framework 创建 + 引导\n * 3. 应用层挂载(通过 mount 回调,框架无关)\n * 4. Action handlers 注册\n * 5. 初始页面触发\n */\n\nimport type { BasePage, Logger } from \"@finesoft/core\";\nimport { DEP_KEYS, Framework, type LoggerFactory } from \"@finesoft/core\";\nimport {\n\tregisterActionHandlers,\n\ttype FlowActionCallbacks,\n} from \"./action-handlers/register\";\nimport { createPrefetchedIntentsFromDom } from \"./server-data\";\n\nexport interface BrowserAppConfig {\n\t/** 注册 controllers 和路由的引导函数 */\n\tbootstrap: (framework: Framework) => void;\n\n\t/** 默认语言(回退值) */\n\tdefaultLocale?: string;\n\n\t/** DOM 挂载点 ID(默认 \"app\") */\n\tmountId?: string;\n\n\t/**\n\t * 挂载应用到 DOM\n\t *\n\t * 框架无关 — Svelte / React / Vue 均可通过此回调实现。\n\t *\n\t * @param target - DOM 挂载点\n\t * @param context - Framework 实例 + 语言\n\t * @returns 更新函数,用于后续页面切换\n\t */\n\tmount: (\n\t\ttarget: HTMLElement,\n\t\tcontext: { framework: Framework; locale: string },\n\t) => (props: {\n\t\tpage: Promise<BasePage> | BasePage;\n\t\tisFirstPage?: boolean;\n\t}) => void;\n\n\t/** FlowAction / ExternalUrl 回调 */\n\tcallbacks: FlowActionCallbacks;\n}\n\n/**\n * 启动客户端应用\n *\n * 自动执行 hydration 全流程。\n */\nexport async function startBrowserApp(config: BrowserAppConfig): Promise<void> {\n\tconst {\n\t\tbootstrap,\n\t\tdefaultLocale = \"en\",\n\t\tmountId = \"app\",\n\t\tmount,\n\t\tcallbacks,\n\t} = config;\n\n\t// 1. 从 DOM 提取 PrefetchedIntents 缓存\n\tconst prefetchedIntents = createPrefetchedIntentsFromDom();\n\n\t// 2. 初始化 Framework + 注册 Controllers\n\tconst framework = Framework.create({ prefetchedIntents });\n\tbootstrap(framework);\n\n\tconst loggerFactory = framework.container.resolve<LoggerFactory>(\n\t\tDEP_KEYS.LOGGER_FACTORY,\n\t);\n\tconst log: Logger = loggerFactory.loggerFor(\"browser\");\n\n\t// 3. 路由初始 URL\n\tconst initialAction = framework.routeUrl(\n\t\twindow.location.pathname + window.location.search,\n\t);\n\n\t// 4. 挂载应用(框架无关)\n\tconst locale = document.documentElement.lang || defaultLocale;\n\tconst target = document.getElementById(mountId)!;\n\tconst updateApp = mount(target, { framework, locale });\n\n\t// 5. 注册 Action Handlers\n\tregisterActionHandlers({\n\t\tframework,\n\t\tlog,\n\t\tcallbacks,\n\t\tupdateApp,\n\t});\n\n\t// 6. 触发初始页面\n\tif (initialAction) {\n\t\tawait framework.perform(initialAction.action);\n\t} else {\n\t\tupdateApp({\n\t\t\tpage: Promise.reject(new Error(\"404\")),\n\t\t\tisFirstPage: true,\n\t\t});\n\t}\n}\n","/**\n * Server Data (browser side) — 从 DOM 反序列化服务端嵌入数据\n */\n\nimport { PrefetchedIntents, type PrefetchedIntent } from \"@finesoft/core\";\n\n/** DOM 中嵌入数据的 script 标签 ID */\nexport const SERVER_DATA_ID = \"serialized-server-data\";\n\n/**\n * 从 DOM 反序列化服务端嵌入的数据。\n * 读取 `<script id=\"serialized-server-data\">` 的内容并移除标签。\n */\nexport function deserializeServerData(): PrefetchedIntent[] | undefined {\n\tconst script = document.getElementById(SERVER_DATA_ID);\n\tif (!script?.textContent) return undefined;\n\n\tscript.parentNode?.removeChild(script);\n\n\ttry {\n\t\treturn JSON.parse(script.textContent);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * 从 DOM 提取 SSR 数据并构建 PrefetchedIntents 实例。\n * 替代原来的 PrefetchedIntents.fromDom()。\n */\nexport function createPrefetchedIntentsFromDom(): PrefetchedIntents {\n\tconst data = deserializeServerData();\n\tif (!data || !Array.isArray(data)) {\n\t\treturn PrefetchedIntents.empty();\n\t}\n\treturn PrefetchedIntents.fromArray(data);\n}\n","// ===== Action Handlers =====\nexport {\n\tregisterExternalUrlHandler,\n\ttype ExternalUrlDependencies,\n} from \"./action-handlers/external-url-action\";\nexport {\n\tregisterFlowActionHandler,\n\ttype FlowActionCallbacks,\n\ttype FlowActionDependencies,\n} from \"./action-handlers/flow-action\";\nexport {\n\tregisterActionHandlers,\n\ttype ActionHandlerDependencies,\n} from \"./action-handlers/register\";\n\n// ===== Browser App =====\nexport { startBrowserApp, type BrowserAppConfig } from \"./start-app\";\n\n// ===== Browser Utils =====\nexport { History } from \"./utils/history\";\nexport { tryScroll } from \"./utils/try-scroll\";\n\n// ===== Server Data (browser side) =====\nexport {\n\tcreatePrefetchedIntentsFromDom,\n\tdeserializeServerData,\n} from \"./server-data\";\n\n// ===== Re-exports from @finesoft/core (convenience) =====\nexport {\n\tBaseController,\n\tdefineRoutes,\n\tFramework,\n\tHttpClient,\n\tHttpError,\n\tisExternalUrlAction,\n\tisFlowAction,\n\tmakeExternalUrlAction,\n\tmakeFlowAction,\n} from \"@finesoft/core\";\nexport type {\n\tAction,\n\tBaseItem,\n\tBasePage,\n\tBaseShelf,\n\tContainer,\n\tExternalUrlAction,\n\tFlowAction,\n\tIntent,\n\tRouteDefinition,\n} from \"@finesoft/core\";\n","/**\n * 适配器共享工具函数\n *\n * 提供 generateSSREntry / buildBundle / copyStaticAssets 三个方法,\n * 避免各适配器重复实现相同逻辑。\n */\n\nimport type {\n\tAdapterContext,\n\tBuildBundleOptions,\n\tCopyStaticAssetsOptions,\n\tGenerateSSREntryOptions,\n} from \"./types\";\n\nconst BUILD_TOOL_EXTERNALS = [\n\t\"vite\",\n\t\"esbuild\",\n\t\"rollup\",\n\t\"fsevents\",\n\t\"lightningcss\",\n];\n\n/**\n * 生成 SSR serverless/edge 入口源码\n *\n * 内联 parseAcceptLanguage / injectSSR 以避免\n * @finesoft/front → @finesoft/server → vite-plugin → import(\"vite\") 依赖链。\n */\nexport function generateSSREntry(\n\tctx: AdapterContext,\n\topts: GenerateSSREntryOptions,\n): string {\n\tconst setupImport = ctx.setupPath\n\t\t? `import _setupDefault from \"./${ctx.setupPath}\";`\n\t\t: ``;\n\tconst setupCall = ctx.setupPath\n\t\t? `if (typeof _setupDefault === \"function\") await _setupDefault(app);`\n\t\t: ``;\n\n\tconst locales = JSON.stringify(ctx.locales);\n\tconst defaultLocale = JSON.stringify(ctx.defaultLocale);\n\n\treturn `\nimport { Hono } from \"hono\";\n${opts.platformImport}\nimport { render, serializeServerData } from \"./${ctx.ssrEntry}\";\n${setupImport}\n\nconst TEMPLATE = ${JSON.stringify(ctx.templateHtml)};\nconst LOCALES = ${locales};\nconst DEFAULT_LOCALE = ${defaultLocale};\n\nfunction parseAcceptLanguage(header) {\n if (!header) return DEFAULT_LOCALE;\n const langs = header.split(\",\").map(p => {\n const [l, q] = p.trim().split(\";q=\");\n return { l: l.trim().toLowerCase(), q: q ? +q : 1 };\n }).sort((a, b) => b.q - a.q);\n for (const { l } of langs) {\n const prefix = l.split(\"-\")[0];\n if (LOCALES.includes(prefix)) return prefix;\n }\n return DEFAULT_LOCALE;\n}\n\nfunction injectSSR(t, locale, head, css, html, data) {\n return t\n .replace(\"<!--ssr-lang-->\", locale)\n .replace(\"<!--ssr-head-->\", head + \"\\\\n<style>\" + css + \"</style>\")\n .replace(\"<!--ssr-body-->\", html)\n .replace(\"<!--ssr-data-->\", '<script id=\"serialized-server-data\" type=\"application/json\">' + data + \"</script>\");\n}\n\nconst app = new Hono();\n${setupCall}\n\napp.get(\"*\", async (c) => {\n const url = c.req.path + (c.req.url.includes(\"?\") ? \"?\" + c.req.url.split(\"?\")[1] : \"\");\n try {\n const locale = parseAcceptLanguage(c.req.header(\"accept-language\"));\n const { html: appHtml, head, css, serverData } = await render(url, locale);\n const serializedData = serializeServerData(serverData);\n return c.html(injectSSR(TEMPLATE, locale, head, css, appHtml, serializedData));\n } catch (e) {\n console.error(\"[SSR Error]\", e);\n return c.text(\"Internal Server Error\", 500);\n }\n});\n\n${opts.platformExport}\n`;\n}\n\n/** 用 Vite SSR 模式构建 bundle */\nexport async function buildBundle(\n\tctx: AdapterContext,\n\topts: BuildBundleOptions,\n): Promise<void> {\n\tawait ctx.vite.build({\n\t\troot: ctx.root,\n\t\tbuild: {\n\t\t\tssr: opts.entry,\n\t\t\toutDir: opts.outDir,\n\t\t\temptyOutDir: true,\n\t\t\ttarget: opts.target ?? \"node18\",\n\t\t\trollupOptions: {\n\t\t\t\toutput: { entryFileNames: opts.fileName ?? \"index.mjs\" },\n\t\t\t},\n\t\t},\n\t\tssr: {\n\t\t\tnoExternal: opts.noExternal !== false,\n\t\t\texternal: opts.external ?? BUILD_TOOL_EXTERNALS,\n\t\t},\n\t\tresolve: ctx.resolvedResolve,\n\t\tcss: ctx.resolvedCss,\n\t});\n}\n\n/** 复制 dist/client 静态资源到目标目录 */\nexport function copyStaticAssets(\n\tctx: AdapterContext,\n\tdestDir: string,\n\topts?: CopyStaticAssetsOptions,\n): void {\n\tconst { fs, path } = ctx;\n\tfs.cpSync(path.resolve(ctx.root, \"dist/client\"), destDir, {\n\t\trecursive: true,\n\t});\n\tif (opts?.excludeHtml !== false) {\n\t\tfs.rmSync(path.join(destDir, \"index.html\"), { force: true });\n\t}\n}\n","/**\n * Cloudflare Pages 适配器\n *\n * 生成 dist/cloudflare/ 目录:\n * - _worker.js — Workers 入口(Hono 原生支持 CF fetch 接口)\n * - assets/ — 静态资源\n *\n * 注意:Cloudflare Workers 不支持原生 Node.js API。\n * 若 setup 代理使用了 process.env,需在 wrangler.toml 启用 nodejs_compat。\n */\n\nimport { buildBundle, copyStaticAssets, generateSSREntry } from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function cloudflareAdapter(): Adapter {\n\treturn {\n\t\tname: \"cloudflare\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\t\t\tconst outputDir = path.resolve(root, \"dist/cloudflare\");\n\n\t\t\tfs.rmSync(outputDir, { recursive: true, force: true });\n\n\t\t\t// Hono 原生支持 CF Workers 的 fetch 接口,直接 export default app\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: ``,\n\t\t\t\tplatformExport: `export default app;`,\n\t\t\t});\n\n\t\t\tconst tempEntry = path.resolve(root, \".cf-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".cf-entry.tmp.mjs\",\n\t\t\t\t\toutDir: outputDir,\n\t\t\t\t\ttarget: \"es2022\",\n\t\t\t\t\tfileName: \"_worker.js\",\n\t\t\t\t\texternal: [], // CF Workers 需全部打包\n\t\t\t\t});\n\n\t\t\t\t// 静态资源\n\t\t\t\tcopyStaticAssets(ctx, path.resolve(outputDir, \"assets\"));\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\n\t\t\tconsole.log(\" Cloudflare output → dist/cloudflare/\\n\");\n\t\t},\n\t};\n}\n","/**\n * Netlify 适配器 — Netlify Functions v2\n *\n * 生成:\n * - .netlify/functions-internal/ssr/index.mjs — Serverless Function\n * - dist/client/_redirects — 路由重写规则\n */\n\nimport { buildBundle, generateSSREntry } from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function netlifyAdapter(): Adapter {\n\treturn {\n\t\tname: \"netlify\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\t\t\tconst funcDir = path.resolve(\n\t\t\t\troot,\n\t\t\t\t\".netlify/functions-internal/ssr\",\n\t\t\t);\n\n\t\t\tfs.rmSync(path.resolve(root, \".netlify\"), {\n\t\t\t\trecursive: true,\n\t\t\t\tforce: true,\n\t\t\t});\n\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: `import { handle } from \"hono/netlify\";`,\n\t\t\t\tplatformExport: `export default handle(app);`,\n\t\t\t});\n\n\t\t\tconst tempEntry = path.resolve(root, \".netlify-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".netlify-entry.tmp.mjs\",\n\t\t\t\t\toutDir: funcDir,\n\t\t\t\t\ttarget: \"node18\",\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\n\t\t\t// _redirects — 静态文件优先,其余走 SSR function\n\t\t\tconst redirects = `/* /.netlify/functions/ssr 200\\n`;\n\t\t\tfs.writeFileSync(\n\t\t\t\tpath.resolve(root, \"dist/client/_redirects\"),\n\t\t\t\tredirects,\n\t\t\t);\n\n\t\t\tconsole.log(\n\t\t\t\t\" Netlify output → .netlify/functions-internal/ssr/\\n\" +\n\t\t\t\t\t\" Publish dir: dist/client/\\n\",\n\t\t\t);\n\t\t},\n\t};\n}\n","/**\n * Node 适配器 — 独立 HTTP 服务器\n *\n * 生成 dist/server/index.mjs,使用 @hono/node-server 监听端口。\n * 运行:node dist/server/index.mjs\n */\n\nimport { buildBundle, generateSSREntry } from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function nodeAdapter(): Adapter {\n\treturn {\n\t\tname: \"node\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: `import { serve } from \"@hono/node-server\";`,\n\t\t\t\tplatformExport: `\nconst port = +(process.env.PORT || 3000);\nserve({ fetch: app.fetch, port }, (info) => {\n console.log(\\`Server running at http://localhost:\\${info.port}\\`);\n});\n`,\n\t\t\t});\n\n\t\t\tconst tempEntry = path.resolve(root, \".node-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".node-entry.tmp.mjs\",\n\t\t\t\t\toutDir: path.resolve(root, \"dist/server\"),\n\t\t\t\t\ttarget: \"node18\",\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t\" Node output → dist/server/index.mjs\\n\" +\n\t\t\t\t\t\" Run: node dist/server/index.mjs\\n\",\n\t\t\t);\n\t\t},\n\t};\n}\n","/**\n * Static 适配器 — 构建时预渲染\n *\n * 加载 SSR 模块和路由定义,将无参数路由自动预渲染为静态 HTML。\n * 动态参数路由通过 dynamicRoutes 选项补充具体 URL。\n *\n * 输出:dist/static/ — 纯静态站点,可部署到任何静态托管。\n */\n\nimport type { Adapter, AdapterContext } from \"./types\";\n\nexport interface StaticAdapterOptions {\n\t/**\n\t * 导出 routes 数组的文件路径(相对于项目根目录)。\n\t * 默认 \"src/lib/bootstrap.ts\"。\n\t * 文件需 export 一个 RouteDefinition[] 类型的 routes 变量。\n\t */\n\troutesExport?: string;\n\t/**\n\t * 额外的动态路由 URL(带具体参数值),如:\n\t * [\"/product/123\", \"/list/games\"]\n\t */\n\tdynamicRoutes?: string[];\n}\n\nexport function staticAdapter(opts: StaticAdapterOptions = {}): Adapter {\n\treturn {\n\t\tname: \"static\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root, vite } = ctx;\n\t\t\tconst outputDir = path.resolve(root, \"dist/static\");\n\n\t\t\tfs.rmSync(outputDir, { recursive: true, force: true });\n\t\t\tfs.mkdirSync(outputDir, { recursive: true });\n\n\t\t\t// 加载 SSR 模块\n\t\t\tconst { pathToFileURL } = await import(\n\t\t\t\t/* @vite-ignore */ \"node:url\"\n\t\t\t);\n\t\t\tconst ssrPath = pathToFileURL(\n\t\t\t\tpath.resolve(root, \"dist/server/ssr.js\"),\n\t\t\t).href;\n\t\t\tconst ssrModule = await import(/* @vite-ignore */ ssrPath);\n\n\t\t\t// 提取路由列表\n\t\t\tconst routePaths = await extractRoutes(ctx, opts);\n\t\t\tconst allUrls: string[] = [];\n\n\t\t\t// 对每个路由 × 每个 locale 生成 URL\n\t\t\tfor (const routePath of routePaths) {\n\t\t\t\tfor (const locale of ctx.locales) {\n\t\t\t\t\tconst url =\n\t\t\t\t\t\tlocale === ctx.defaultLocale\n\t\t\t\t\t\t\t? routePath\n\t\t\t\t\t\t\t: `/${locale}${routePath === \"/\" ? \"\" : routePath}`;\n\t\t\t\t\tallUrls.push(url);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t` Pre-rendering ${allUrls.length} pages (${routePaths.length} routes × ${ctx.locales.length} locales)...\\n`,\n\t\t\t);\n\n\t\t\t// 预渲染每个 URL\n\t\t\tfor (const url of allUrls) {\n\t\t\t\ttry {\n\t\t\t\t\t// 从 URL 推断 locale\n\t\t\t\t\tconst locale = inferLocale(\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tctx.locales,\n\t\t\t\t\t\tctx.defaultLocale,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst {\n\t\t\t\t\t\thtml: appHtml,\n\t\t\t\t\t\thead,\n\t\t\t\t\t\tcss,\n\t\t\t\t\t\tserverData,\n\t\t\t\t\t} = await ssrModule.render(url, locale);\n\n\t\t\t\t\tconst serializedData =\n\t\t\t\t\t\tssrModule.serializeServerData(serverData);\n\n\t\t\t\t\tconst finalHtml = injectSSRForStatic(\n\t\t\t\t\t\tctx.templateHtml,\n\t\t\t\t\t\tlocale,\n\t\t\t\t\t\thead,\n\t\t\t\t\t\tcss,\n\t\t\t\t\t\tappHtml,\n\t\t\t\t\t\tserializedData,\n\t\t\t\t\t);\n\n\t\t\t\t\t// 写入文件:/foo → dist/static/foo/index.html\n\t\t\t\t\tconst filePath =\n\t\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t\t? path.join(outputDir, \"index.html\")\n\t\t\t\t\t\t\t: path.join(outputDir, url, \"index.html\");\n\n\t\t\t\t\tfs.mkdirSync(path.resolve(filePath, \"..\"), {\n\t\t\t\t\t\trecursive: true,\n\t\t\t\t\t});\n\t\t\t\t\tfs.writeFileSync(filePath, finalHtml);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.warn(` [static] Failed to render ${url}:`, e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 复制静态资源\n\t\t\tctx.copyStaticAssets(outputDir, { excludeHtml: true });\n\n\t\t\tconsole.log(` Static output → dist/static/\\n`);\n\t\t},\n\t};\n}\n\n/** 从路由文件提取无参数路由 + 合并 dynamicRoutes */\nasync function extractRoutes(\n\tctx: AdapterContext,\n\topts: StaticAdapterOptions,\n): Promise<string[]> {\n\tconst routesFile = opts.routesExport ?? \"src/lib/bootstrap.ts\";\n\tconst paths: string[] = [];\n\n\ttry {\n\t\t// 使用 Vite SSR 构建加载路由文件\n\t\tconst { pathToFileURL } = await import(/* @vite-ignore */ \"node:url\");\n\n\t\t// 先构建路由文件\n\t\tawait ctx.vite.build({\n\t\t\troot: ctx.root,\n\t\t\tbuild: {\n\t\t\t\tssr: routesFile,\n\t\t\t\toutDir: ctx.path.resolve(ctx.root, \"dist/server\"),\n\t\t\t\temptyOutDir: false,\n\t\t\t\trollupOptions: {\n\t\t\t\t\toutput: { entryFileNames: \"_routes.mjs\" },\n\t\t\t\t},\n\t\t\t},\n\t\t\tresolve: ctx.resolvedResolve,\n\t\t});\n\n\t\tconst routesPath = pathToFileURL(\n\t\t\tctx.path.resolve(ctx.root, \"dist/server/_routes.mjs\"),\n\t\t).href;\n\t\tconst routesMod = await import(/* @vite-ignore */ routesPath);\n\n\t\t// 查找导出的 routes 数组\n\t\tconst routes: Array<{ path: string }> =\n\t\t\troutesMod.routes ?? routesMod.default;\n\n\t\tif (Array.isArray(routes)) {\n\t\t\tfor (const r of routes) {\n\t\t\t\tif (r.path && !r.path.includes(\":\")) {\n\t\t\t\t\tpaths.push(r.path);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 清理临时文件\n\t\tctx.fs.rmSync(ctx.path.resolve(ctx.root, \"dist/server/_routes.mjs\"), {\n\t\t\tforce: true,\n\t\t});\n\t} catch (e) {\n\t\tconsole.warn(\n\t\t\t` [static] Could not load routes from \"${routesFile}\". Using \"/\" only.`,\n\t\t\te,\n\t\t);\n\t\tif (paths.length === 0) paths.push(\"/\");\n\t}\n\n\t// 合并 dynamicRoutes\n\tif (opts.dynamicRoutes) {\n\t\tfor (const r of opts.dynamicRoutes) {\n\t\t\tif (!paths.includes(r)) paths.push(r);\n\t\t}\n\t}\n\n\t// 至少包含根路径\n\tif (paths.length === 0) paths.push(\"/\");\n\n\treturn paths;\n}\n\n/** 从 URL 推断 locale */\nfunction inferLocale(\n\turl: string,\n\tlocales: string[],\n\tdefaultLocale: string,\n): string {\n\tconst segments = url.split(\"/\").filter(Boolean);\n\tif (segments.length > 0 && locales.includes(segments[0])) {\n\t\treturn segments[0];\n\t}\n\treturn defaultLocale;\n}\n\n/** 内联 SSR 注入(同 shared 中的逻辑) */\nfunction injectSSRForStatic(\n\ttemplate: string,\n\tlocale: string,\n\thead: string,\n\tcss: string,\n\thtml: string,\n\tserializedData: string,\n): string {\n\treturn template\n\t\t.replace(\"<!--ssr-lang-->\", locale)\n\t\t.replace(\"<!--ssr-head-->\", head + \"\\n<style>\" + css + \"</style>\")\n\t\t.replace(\"<!--ssr-body-->\", html)\n\t\t.replace(\n\t\t\t\"<!--ssr-data-->\",\n\t\t\t'<script id=\"serialized-server-data\" type=\"application/json\">' +\n\t\t\t\tserializedData +\n\t\t\t\t\"</script>\",\n\t\t);\n}\n","/**\n * Vercel 适配器 — Build Output API v3\n *\n * 生成 .vercel/output/ 目录:\n * - config.json — 路由规则\n * - static/ — 静态资源\n * - functions/ssr.func/ — Serverless Function\n */\n\nimport { buildBundle, copyStaticAssets, generateSSREntry } from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function vercelAdapter(): Adapter {\n\treturn {\n\t\tname: \"vercel\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\t\t\tconst outputDir = path.resolve(root, \".vercel/output\");\n\n\t\t\t// 清理旧输出\n\t\t\tfs.rmSync(outputDir, { recursive: true, force: true });\n\n\t\t\t// 生成入口源码\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: `import { handle } from \"hono/vercel\";`,\n\t\t\t\tplatformExport: `export default handle(app);`,\n\t\t\t});\n\n\t\t\t// 写入临时入口文件\n\t\t\tconst tempEntry = path.resolve(root, \".vercel-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tconst funcDir = path.resolve(\n\t\t\t\t\troot,\n\t\t\t\t\t\".vercel/output/functions/ssr.func\",\n\t\t\t\t);\n\n\t\t\t\t// 构建 serverless function\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".vercel-entry.tmp.mjs\",\n\t\t\t\t\toutDir: funcDir,\n\t\t\t\t\ttarget: \"node18\",\n\t\t\t\t});\n\n\t\t\t\t// .vc-config.json\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tpath.resolve(funcDir, \".vc-config.json\"),\n\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\truntime: \"nodejs20.x\",\n\t\t\t\t\t\t\thandler: \"index.mjs\",\n\t\t\t\t\t\t\tlauncherType: \"Nodejs\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\t2,\n\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\t// 静态资源\n\t\t\t\tcopyStaticAssets(\n\t\t\t\t\tctx,\n\t\t\t\t\tpath.resolve(root, \".vercel/output/static\"),\n\t\t\t\t);\n\n\t\t\t\t// 路由配置\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tpath.resolve(root, \".vercel/output/config.json\"),\n\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tversion: 3,\n\t\t\t\t\t\t\troutes: [\n\t\t\t\t\t\t\t\t{ handle: \"filesystem\" },\n\t\t\t\t\t\t\t\t{ src: \"/(.*)\", dest: \"/ssr\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\t2,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\n\t\t\tconsole.log(\" Vercel output → .vercel/output/\\n\");\n\t\t},\n\t};\n}\n","/**\n * resolveAdapter — 字符串 → Adapter 映射\n */\n\nimport { autoAdapter } from \"./auto\";\nimport { cloudflareAdapter } from \"./cloudflare\";\nimport { netlifyAdapter } from \"./netlify\";\nimport { nodeAdapter } from \"./node\";\nimport { staticAdapter } from \"./static\";\nimport type { Adapter } from \"./types\";\nimport { vercelAdapter } from \"./vercel\";\n\nexport function resolveAdapter(value: string | Adapter): Adapter {\n\tif (typeof value !== \"string\") return value;\n\n\tswitch (value) {\n\t\tcase \"vercel\":\n\t\t\treturn vercelAdapter();\n\t\tcase \"cloudflare\":\n\t\t\treturn cloudflareAdapter();\n\t\tcase \"netlify\":\n\t\t\treturn netlifyAdapter();\n\t\tcase \"node\":\n\t\t\treturn nodeAdapter();\n\t\tcase \"static\":\n\t\t\treturn staticAdapter();\n\t\tcase \"auto\":\n\t\t\treturn autoAdapter();\n\t\tdefault:\n\t\t\tthrow new Error(\n\t\t\t\t`[finesoft] Unknown adapter: \"${value}\". ` +\n\t\t\t\t\t`Available: vercel, cloudflare, netlify, node, static, auto`,\n\t\t\t);\n\t}\n}\n","/**\n * Auto 适配器 — 根据环境变量自动选择目标平台\n *\n * 检测顺序:\n * VERCEL → vercel\n * CF_PAGES → cloudflare\n * NETLIFY → netlify\n * (default) → node\n */\n\nimport { resolveAdapter } from \"./resolve\";\nimport type { Adapter } from \"./types\";\n\nexport function autoAdapter(): Adapter {\n\treturn {\n\t\tname: \"auto\",\n\t\tasync build(ctx) {\n\t\t\tconst detected = detectPlatform();\n\t\t\tconsole.log(` [auto] Detected platform: ${detected}\\n`);\n\t\t\tconst adapter = resolveAdapter(detected);\n\t\t\treturn adapter.build(ctx);\n\t\t},\n\t};\n}\n\nfunction detectPlatform(): string {\n\tif (process.env.VERCEL) return \"vercel\";\n\tif (process.env.CF_PAGES) return \"cloudflare\";\n\tif (process.env.NETLIFY) return \"netlify\";\n\treturn \"node\";\n}\n","export { autoAdapter } from \"./adapters/auto\";\nexport { cloudflareAdapter } from \"./adapters/cloudflare\";\nexport { netlifyAdapter } from \"./adapters/netlify\";\nexport { nodeAdapter } from \"./adapters/node\";\nexport { resolveAdapter } from \"./adapters/resolve\";\nexport { staticAdapter } from \"./adapters/static\";\nexport type { Adapter, AdapterContext } from \"./adapters/types\";\nexport { vercelAdapter } from \"./adapters/vercel\";\nexport { createSSRApp, type SSRAppOptions, type SSRModule } from \"./app\";\nexport {\n\tcreateServer,\n\ttype ServerConfig,\n\ttype ServerInstance,\n} from \"./create-server\";\nexport { parseAcceptLanguage } from \"./locale\";\nexport { detectRuntime, resolveRoot, type RuntimeInfo } from \"./runtime\";\nexport { startServer, type StartServerOptions } from \"./start\";\nexport {\n\tfinesoftFrontViteConfig,\n\ttype FinesoftFrontViteOptions,\n} from \"./vite-plugin\";\n","/**\n * createServer — 一站式服务器工厂\n *\n * 封装 env 加载、运行时检测、Vite 创建、Hono app、SSR、启动。\n * 保留 setup() 钩子用于注册业务路由。\n */\n\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { createSSRApp, type SSRAppOptions } from \"./app\";\nimport { detectRuntime, type RuntimeInfo } from \"./runtime\";\nimport { startServer } from \"./start\";\n\nexport interface ServerConfig {\n\t/** 项目根路径(默认 process.cwd()) */\n\troot?: string;\n\t/** 支持的语言列表 */\n\tlocales?: string[];\n\t/** 默认语言 */\n\tdefaultLocale?: string;\n\t/** 端口号(默认 3000) */\n\tport?: number;\n\t/** 注册业务路由(在 SSR catch-all 之前调用) */\n\tsetup?: (app: Hono) => void | Promise<void>;\n\t/** SSR 相关选项(透传给 createSSRApp) */\n\tssr?: Pick<SSRAppOptions, \"ssrEntryPath\" | \"ssrProductionModule\">;\n}\n\nexport interface ServerInstance {\n\tapp: Hono;\n\tvite?: ViteDevServer;\n\truntime: RuntimeInfo;\n}\n\n/**\n * 创建并启动 SSR 服务器\n *\n * @example\n * ```ts\n * const { app } = await createServer({\n * locales: [\"zh\", \"en\"],\n * setup: (app) => registerProxies(app),\n * });\n * export { app };\n * ```\n */\nexport async function createServer(\n\tconfig: ServerConfig = {},\n): Promise<ServerInstance> {\n\tconst {\n\t\troot: rootOverride,\n\t\tlocales,\n\t\tdefaultLocale,\n\t\tport = Number(process.env.PORT) || 3000,\n\t\tsetup,\n\t\tssr,\n\t} = config;\n\n\t// 1. 路径 + .env\n\tconst root = rootOverride ?? process.cwd();\n\tconst { existsSync } = await import(/* @vite-ignore */ \"node:fs\");\n\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\tconst envPath = resolve(root, \".env\");\n\tif (existsSync(envPath)) {\n\t\ttry {\n\t\t\tconst { config: dotenvConfig } = await import(\n\t\t\t\t/* @vite-ignore */ \"dotenv\"\n\t\t\t);\n\t\t\tdotenvConfig({ path: envPath });\n\t\t} catch {\n\t\t\t// dotenv 未安装则跳过,调用方可自行加载 .env\n\t\t}\n\t}\n\n\t// 2. 运行时检测\n\tconst runtime = detectRuntime();\n\n\t// 3. Vite(仅开发模式)\n\tlet vite: ViteDevServer | undefined;\n\tif (!runtime.isProduction && !runtime.isVercel) {\n\t\tconst { createServer: createViteServer } = await import(\n\t\t\t/* @vite-ignore */ \"vite\"\n\t\t);\n\t\tvite = await createViteServer({\n\t\t\troot,\n\t\t\tserver: { middlewareMode: true },\n\t\t\tappType: \"custom\",\n\t\t});\n\t}\n\n\t// 4. Hono app + 业务路由\n\tconst app = new Hono();\n\tif (setup) {\n\t\tawait setup(app);\n\t}\n\n\t// 5. SSR catch-all\n\tconst ssrApp = createSSRApp({\n\t\troot,\n\t\tvite,\n\t\tisProduction: runtime.isProduction,\n\t\tsupportedLocales: locales,\n\t\tdefaultLocale,\n\t\t...ssr,\n\t});\n\tapp.route(\"/\", ssrApp);\n\n\t// 6. 启动\n\tawait startServer({\n\t\tapp,\n\t\troot,\n\t\tport,\n\t\tisProduction: runtime.isProduction,\n\t\tvite,\n\t\truntime,\n\t\tlocales,\n\t\tssrEntryPath: ssr?.ssrEntryPath,\n\t});\n\n\treturn { app, vite, runtime };\n}\n","/**\n * runtime — 运行时检测 + 项目根路径推导\n */\n\nexport interface RuntimeInfo {\n\tisDeno: boolean;\n\tisBun: boolean;\n\tisVercel: boolean;\n\tisProduction: boolean;\n}\n\n/** 检测当前运行时环境 */\nexport function detectRuntime(): RuntimeInfo {\n\treturn {\n\t\tisDeno: typeof (globalThis as any).Deno !== \"undefined\",\n\t\tisBun: typeof (globalThis as any).Bun !== \"undefined\",\n\t\tisVercel: !!process.env.VERCEL,\n\t\tisProduction: process.env.NODE_ENV === \"production\",\n\t};\n}\n\n/**\n * 从 `import.meta.url` 推导项目根路径\n *\n * @param importMetaUrl - 调用方的 `import.meta.url`\n * @param levelsUp - 向上移动多少级(默认 0,即调用方所在目录就是项目根)\n */\nexport async function resolveRoot(\n\timportMetaUrl: string,\n\tlevelsUp = 0,\n): Promise<string> {\n\tconst isDeno = typeof (globalThis as any).Deno !== \"undefined\";\n\n\tif (isDeno) {\n\t\tlet url = new URL(importMetaUrl);\n\t\tfor (let i = 0; i < levelsUp; i++) {\n\t\t\turl = new URL(\"..\", url);\n\t\t}\n\t\treturn url.pathname;\n\t}\n\n\tconst { dirname, resolve, normalize } = await import(\n\t\t/* @vite-ignore */ \"node:path\"\n\t);\n\tconst { fileURLToPath } = await import(/* @vite-ignore */ \"node:url\");\n\tlet dir = normalize(dirname(fileURLToPath(importMetaUrl)));\n\tfor (let i = 0; i < levelsUp; i++) {\n\t\tdir = resolve(dir, \"..\");\n\t}\n\treturn dir;\n}\n","/**\n * startServer — 多运行时自动启动\n *\n * 支持 Node.js (dev HMR + prod)、Deno、Bun、Vercel。\n */\n\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { detectRuntime, type RuntimeInfo } from \"./runtime\";\n\nexport interface StartServerOptions {\n\t/** 最终的 Hono app(已包含 SSR + 自定义路由) */\n\tapp: Hono;\n\t/** 项目根路径 */\n\troot: string;\n\t/** 端口号 */\n\tport?: number;\n\t/** 是否生产环境 */\n\tisProduction: boolean;\n\t/** Vite dev server(仅开发模式传入) */\n\tvite?: ViteDevServer;\n\t/** 运行时信息(可选,不传时自动检测) */\n\truntime?: RuntimeInfo;\n\t/** 已注册的路由列表(用于启动日志) */\n\troutes?: string[];\n\t/** 支持的语言列表(用于启动日志) */\n\tlocales?: string[];\n\t/** SSR 入口路径(用于启动日志) */\n\tssrEntryPath?: string;\n}\n\nexport async function startServer(\n\toptions: StartServerOptions,\n): Promise<{ vite?: ViteDevServer }> {\n\tconst {\n\t\tapp,\n\t\troot,\n\t\tport = 3000,\n\t\tisProduction,\n\t\tvite,\n\t\troutes,\n\t\tlocales,\n\t\tssrEntryPath,\n\t} = options;\n\n\tconst { isDeno, isBun, isVercel } = options.runtime ?? detectRuntime();\n\n\tfunction printStartupBanner() {\n\t\tconst lines: string[] = [\n\t\t\t`\\n Server running at http://localhost:${port}\\n`,\n\t\t];\n\t\tif (routes && routes.length > 0) {\n\t\t\tlines.push(\" Routes:\");\n\t\t\tfor (const r of routes) {\n\t\t\t\tlines.push(` ${r}`);\n\t\t\t}\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tif (locales && locales.length > 0) {\n\t\t\tlines.push(` Locales: ${locales.join(\", \")}`);\n\t\t}\n\t\tif (ssrEntryPath) {\n\t\t\tlines.push(` SSR Entry: ${ssrEntryPath}`);\n\t\t}\n\t\tif (locales?.length || ssrEntryPath) {\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tconsole.log(lines.join(\"\\n\"));\n\t}\n\n\tif (isVercel) {\n\t\treturn { vite };\n\t}\n\n\tif (!isProduction) {\n\t\tlet devVite = vite;\n\t\tif (!devVite) {\n\t\t\tconst { createServer: createViteServer } = await import(\n\t\t\t\t/* @vite-ignore */ \"vite\"\n\t\t\t);\n\t\t\tdevVite = await createViteServer({\n\t\t\t\troot,\n\t\t\t\tserver: { middlewareMode: true },\n\t\t\t\tappType: \"custom\",\n\t\t\t});\n\t\t}\n\n\t\tconst { getRequestListener } = await import(\n\t\t\t/* @vite-ignore */ \"@hono/node-server\"\n\t\t);\n\t\tconst { createServer } = await import(/* @vite-ignore */ \"node:http\");\n\t\tconst listener = getRequestListener(app.fetch);\n\t\tconst server = createServer((req: any, res: any) => {\n\t\t\tdevVite!.middlewares(req, res, () => listener(req, res));\n\t\t});\n\t\tserver.listen(port, () => {\n\t\t\tprintStartupBanner();\n\t\t});\n\t\treturn { vite: devVite };\n\t}\n\n\tif (isDeno) {\n\t\t(globalThis as any).Deno.serve({ port }, app.fetch);\n\t} else if (isBun) {\n\t\t// Bun uses export default\n\t} else {\n\t\t// Node.js production\n\t\tconst { serveStatic } = await import(\n\t\t\t/* @vite-ignore */ \"@hono/node-server/serve-static\"\n\t\t);\n\t\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\t\tconst prodApp = new Hono();\n\t\tconst clientDir = resolve(root, \"dist/client\");\n\t\tprodApp.use(\n\t\t\t\"/*\",\n\t\t\tserveStatic({\n\t\t\t\troot: clientDir,\n\t\t\t\t// 禁止目录路径自动提供 index.html,让其 fall through 到 SSR\n\t\t\t\trewriteRequestPath: (path: string) =>\n\t\t\t\t\tpath.endsWith(\"/\") ? \"/__nosuchfile__\" : path,\n\t\t\t}),\n\t\t);\n\t\tprodApp.route(\"/\", app);\n\n\t\tconst { serve } = await import(/* @vite-ignore */ \"@hono/node-server\");\n\t\tserve({ fetch: prodApp.fetch, port }, () => {\n\t\t\tprintStartupBanner();\n\t\t});\n\t}\n\n\treturn { vite };\n}\n","/**\n * finesoftFrontViteConfig — Vite 插件\n *\n * 将 Hono SSR 服务器集成到 Vite 的 dev / build / preview 生命周期中,\n * 使 template-project 只需 `vite` / `vite build` / `vite preview` 即可运行。\n *\n * 支持多平台 adapter: \"vercel\" | \"cloudflare\" | \"netlify\" | \"node\" | \"static\" | \"auto\"\n * 或自定义 Adapter 对象。\n */\n\nimport type { Hono } from \"hono\";\nimport { resolveAdapter } from \"./adapters/resolve\";\nimport {\n\tbuildBundle,\n\tcopyStaticAssets,\n\tgenerateSSREntry,\n} from \"./adapters/shared\";\nimport type { Adapter } from \"./adapters/types\";\nimport type { SSRModule } from \"./app\";\n\nexport interface FinesoftFrontViteOptions {\n\t/** 支持的语言列表 */\n\tlocales?: string[];\n\t/** 默认语言 */\n\tdefaultLocale?: string;\n\t/** SSR 配置 */\n\tssr?: {\n\t\t/** SSR 入口文件路径(默认 \"src/ssr.ts\") */\n\t\tentry?: string;\n\t};\n\t/**\n\t * 注册业务路由(API 代理等)。\n\t * - 传入 Function:仅 dev/preview 时可用。\n\t * - 传入 string(文件路径):dev/preview/adapter 均可用,\n\t * 文件需 export default 一个 (app: Hono) => void 函数。\n\t */\n\tsetup?: ((app: Hono) => void | Promise<void>) | string;\n\t/**\n\t * 部署适配器。\n\t * - 字符串快捷方式:\"vercel\" | \"cloudflare\" | \"netlify\" | \"node\" | \"static\" | \"auto\"\n\t * - 自定义 Adapter 对象:{ name, build(ctx) }\n\t * - 不设置则不生成部署产物\n\t */\n\tadapter?: string | Adapter;\n}\n\n/**\n * 从 setup 模块中查找 setup 函数:优先 default,其次 setup 命名导出。\n */\nfunction resolveSetupFn(\n\tmod: Record<string, unknown>,\n): ((app: any) => void | Promise<void>) | null {\n\tif (typeof mod.default === \"function\") return mod.default as any;\n\tif (typeof mod.setup === \"function\") return mod.setup as any;\n\tconst first = Object.values(mod).find((v) => typeof v === \"function\");\n\treturn (first as any) ?? null;\n}\n\nexport function finesoftFrontViteConfig(\n\toptions: FinesoftFrontViteOptions = {},\n) {\n\tconst ssrEntry = options.ssr?.entry ?? \"src/ssr.ts\";\n\tlet root = process.cwd();\n\tlet resolvedCommand: string | undefined;\n\tlet resolvedResolve: unknown;\n\tlet resolvedCss: unknown;\n\n\treturn {\n\t\tname: \"finesoft-front\",\n\n\t\tconfig(userConfig: Record<string, any>, env: { command: string }) {\n\t\t\tconst overrides: Record<string, any> = {\n\t\t\t\tappType: \"custom\",\n\t\t\t};\n\t\t\tif (\n\t\t\t\tenv.command === \"build\" &&\n\t\t\t\t!process.env.__FINESOFT_SUB_BUILD__\n\t\t\t) {\n\t\t\t\toverrides.build = {\n\t\t\t\t\toutDir: userConfig.build?.outDir ?? \"dist/client\",\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn overrides;\n\t\t},\n\n\t\tconfigResolved(config: Record<string, any>) {\n\t\t\tresolvedCommand = config.command as string;\n\t\t\tresolvedResolve = config.resolve;\n\t\t\tresolvedCss = config.css;\n\t\t\troot = config.root as string;\n\t\t},\n\n\t\t// ─── Dev ───────────────────────────────────────────────\n\t\tconfigureServer(server: any) {\n\t\t\treturn async () => {\n\t\t\t\tconst { Hono: HonoClass } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"hono\"\n\t\t\t\t);\n\t\t\t\tconst { createSSRApp } = await import(\"./app\");\n\t\t\t\tconst { getRequestListener } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"@hono/node-server\"\n\t\t\t\t);\n\n\t\t\t\tconst app = new HonoClass();\n\n\t\t\t\t// Setup: 函数直接调用,文件路径通过 ssrLoadModule 加载\n\t\t\t\tif (typeof options.setup === \"function\") {\n\t\t\t\t\tawait options.setup(app);\n\t\t\t\t} else if (typeof options.setup === \"string\") {\n\t\t\t\t\tconst mod = await server.ssrLoadModule(\"/\" + options.setup);\n\t\t\t\t\tconst fn = resolveSetupFn(mod);\n\t\t\t\t\tif (fn) await fn(app);\n\t\t\t\t}\n\n\t\t\t\tconst ssrApp = createSSRApp({\n\t\t\t\t\troot,\n\t\t\t\t\tvite: server,\n\t\t\t\t\tisProduction: false,\n\t\t\t\t\tssrEntryPath: \"/\" + ssrEntry,\n\t\t\t\t\tsupportedLocales: options.locales,\n\t\t\t\t\tdefaultLocale: options.defaultLocale,\n\t\t\t\t});\n\t\t\t\tapp.route(\"/\", ssrApp);\n\n\t\t\t\tconst listener = getRequestListener(app.fetch);\n\n\t\t\t\tserver.middlewares.use((req: any, res: any) => {\n\t\t\t\t\tlistener(req, res);\n\t\t\t\t});\n\t\t\t};\n\t\t},\n\n\t\t// ─── Preview ───────────────────────────────────────────\n\t\tconfigurePreviewServer(server: any) {\n\t\t\treturn async () => {\n\t\t\t\tconst { readFileSync } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"node:fs\"\n\t\t\t\t);\n\t\t\t\tconst { resolve } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"node:path\"\n\t\t\t\t);\n\t\t\t\tconst { pathToFileURL } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"node:url\"\n\t\t\t\t);\n\t\t\t\tconst { Hono: HonoClass } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"hono\"\n\t\t\t\t);\n\t\t\t\tconst { injectSSRContent } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"@finesoft/ssr\"\n\t\t\t\t);\n\t\t\t\tconst { parseAcceptLanguage } = await import(\"./locale\");\n\t\t\t\tconst { getRequestListener } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"@hono/node-server\"\n\t\t\t\t);\n\n\t\t\t\tconst app = new HonoClass();\n\n\t\t\t\t// Setup: 函数直接调用,文件路径从构建产物加载\n\t\t\t\tif (typeof options.setup === \"function\") {\n\t\t\t\t\tawait options.setup(app);\n\t\t\t\t} else if (typeof options.setup === \"string\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst setupPath = pathToFileURL(\n\t\t\t\t\t\t\tresolve(root, \"dist/server/setup.mjs\"),\n\t\t\t\t\t\t).href;\n\t\t\t\t\t\tconst mod = await import(/* @vite-ignore */ setupPath);\n\t\t\t\t\t\tconst fn = resolveSetupFn(\n\t\t\t\t\t\t\tmod as Record<string, unknown>,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (fn) await fn(app);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\"[finesoft] Could not load setup module for preview. API routes disabled.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst templatePath = resolve(root, \"dist/client/index.html\");\n\t\t\t\tconst template = readFileSync(templatePath, \"utf-8\");\n\n\t\t\t\tconst ssrPath = pathToFileURL(\n\t\t\t\t\tresolve(root, \"dist/server/ssr.js\"),\n\t\t\t\t).href;\n\t\t\t\tconst ssrModule = (await import(\n\t\t\t\t\t/* @vite-ignore */ ssrPath\n\t\t\t\t)) as SSRModule;\n\n\t\t\t\tapp.get(\"*\", async (c: any) => {\n\t\t\t\t\tconst url =\n\t\t\t\t\t\tc.req.path +\n\t\t\t\t\t\t(c.req.url.includes(\"?\")\n\t\t\t\t\t\t\t? \"?\" + c.req.url.split(\"?\")[1]\n\t\t\t\t\t\t\t: \"\");\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst locale = parseAcceptLanguage(\n\t\t\t\t\t\t\tc.req.header(\"accept-language\"),\n\t\t\t\t\t\t\toptions.locales,\n\t\t\t\t\t\t\toptions.defaultLocale,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\thtml: appHtml,\n\t\t\t\t\t\t\thead,\n\t\t\t\t\t\t\tcss,\n\t\t\t\t\t\t\tserverData,\n\t\t\t\t\t\t} = await ssrModule.render(url, locale);\n\n\t\t\t\t\t\tconst serializedData =\n\t\t\t\t\t\t\tssrModule.serializeServerData(serverData);\n\n\t\t\t\t\t\tconst finalHtml = injectSSRContent({\n\t\t\t\t\t\t\ttemplate,\n\t\t\t\t\t\t\tlocale,\n\t\t\t\t\t\t\thead,\n\t\t\t\t\t\t\tcss,\n\t\t\t\t\t\t\thtml: appHtml,\n\t\t\t\t\t\t\tserializedData,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn c.html(finalHtml);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.error(\"[SSR Preview Error]\", e);\n\t\t\t\t\t\treturn c.text(\"Internal Server Error\", 500);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst listener = getRequestListener(app.fetch);\n\n\t\t\t\tserver.middlewares.use((req: any, res: any) => {\n\t\t\t\t\tlistener(req, res);\n\t\t\t\t});\n\t\t\t};\n\t\t},\n\n\t\t// ─── Build ─────────────────────────────────────────────\n\t\tasync closeBundle() {\n\t\t\tif (process.env.__FINESOFT_SUB_BUILD__) return;\n\t\t\tif (resolvedCommand !== \"build\") return;\n\n\t\t\tprocess.env.__FINESOFT_SUB_BUILD__ = \"1\";\n\t\t\ttry {\n\t\t\t\tconst vite: any = await import(/* @vite-ignore */ \"vite\");\n\t\t\t\tconst fs = await import(/* @vite-ignore */ \"node:fs\");\n\t\t\t\tconst path = await import(/* @vite-ignore */ \"node:path\");\n\n\t\t\t\t// ── 1. SSR 构建 ──\n\t\t\t\tconsole.log(\"\\n Building SSR bundle...\\n\");\n\t\t\t\tawait vite.build({\n\t\t\t\t\troot,\n\t\t\t\t\tbuild: {\n\t\t\t\t\t\tssr: ssrEntry,\n\t\t\t\t\t\toutDir: \"dist/server\",\n\t\t\t\t\t},\n\t\t\t\t\tresolve: resolvedResolve,\n\t\t\t\t\tcss: resolvedCss,\n\t\t\t\t});\n\n\t\t\t\t// ── 2. Setup 模块构建(仅当 setup 是文件路径时) ──\n\t\t\t\tif (typeof options.setup === \"string\") {\n\t\t\t\t\tconsole.log(\" Building setup module...\\n\");\n\t\t\t\t\tawait vite.build({\n\t\t\t\t\t\troot,\n\t\t\t\t\t\tbuild: {\n\t\t\t\t\t\t\tssr: options.setup,\n\t\t\t\t\t\t\toutDir: \"dist/server\",\n\t\t\t\t\t\t\temptyOutDir: false,\n\t\t\t\t\t\t\trollupOptions: {\n\t\t\t\t\t\t\t\toutput: { entryFileNames: \"setup.mjs\" },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresolve: resolvedResolve,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// ── 3. Adapter 构建 ──\n\t\t\t\tif (options.adapter) {\n\t\t\t\t\tconst adapter = resolveAdapter(options.adapter);\n\n\t\t\t\t\tconst locales = options.locales ?? [\"zh\", \"en\"];\n\t\t\t\t\tconst defaultLocale =\n\t\t\t\t\t\toptions.defaultLocale ?? locales[0] ?? \"en\";\n\t\t\t\t\tconst templateHtml = fs.readFileSync(\n\t\t\t\t\t\tpath.resolve(root, \"dist/client/index.html\"),\n\t\t\t\t\t\t\"utf-8\",\n\t\t\t\t\t);\n\n\t\t\t\t\tconst ctx = {\n\t\t\t\t\t\troot,\n\t\t\t\t\t\tssrEntry,\n\t\t\t\t\t\tsetupPath:\n\t\t\t\t\t\t\ttypeof options.setup === \"string\"\n\t\t\t\t\t\t\t\t? options.setup\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tlocales,\n\t\t\t\t\t\tdefaultLocale,\n\t\t\t\t\t\ttemplateHtml,\n\t\t\t\t\t\tresolvedResolve,\n\t\t\t\t\t\tresolvedCss,\n\t\t\t\t\t\tvite,\n\t\t\t\t\t\tfs,\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\tgenerateSSREntry(opts: any) {\n\t\t\t\t\t\t\treturn generateSSREntry(ctx, opts);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbuildBundle(opts: any) {\n\t\t\t\t\t\t\treturn buildBundle(ctx, opts);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcopyStaticAssets(destDir: string, opts?: any) {\n\t\t\t\t\t\t\treturn copyStaticAssets(ctx, destDir, opts);\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\n\t\t\t\t\tconsole.log(` Running adapter: ${adapter.name}...\\n`);\n\t\t\t\t\tawait adapter.build(ctx);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tdelete process.env.__FINESOFT_SUB_BUILD__;\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":"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","names":["init_dispatcher","init_dispatcher","init_dispatcher","init_src","readFileSync","resolve","serializeServerData","init_src","match","init_src","import_hono","import_hono","createServer","createSSRApp","injectSSRContent","parseAcceptLanguage"]}