Repository Wiki
Naptie/endfield-docmaker

项目概览

endfield-docmaker(终末地文档生成器) 是一个纯前端的静态 Web 应用,用于在浏览器中实时生成《明日方舟:终末地》游戏世界观中各机构签发的文档(红头公文、试卷等),并通过 WebAssembly 版 Typst 排版引擎即时输出 PDF。整个工具无需任何后端服务,所有编译、渲染与数据持久化均发生在用户浏览器内。

目的与范围(Purpose and Scope)

本页面是 endfield-docmaker 仓库的顶层概览,目标是让读者在最短时间内建立对整个项目的全局认知,包括:

  • 项目的定位、功能特性与免责声明边界;
  • 技术栈选型(SvelteKit 2 + Svelte 5 Runes、Typst WASM、Tailwind CSS 4、Paraglide JS 等)及其设计意图;
  • 整体架构分层:路由层、组件层、业务 hooks 层、Typst 编译层、数据存储层、i18n 层;
  • 端到端核心数据流:从用户填写表单到浏览器内编译 Typst 并输出 PDF 的完整链路;
  • 目录结构与各模块职责的映射关系;
  • 构建、检查、部署相关的工程化配置。

本页面刻意不深入的内容(留待兄弟页面单独展开):

  • Typst WASM 初始化与编译管线的逐行实现(src/lib/typst.svelte.ts);
  • 表单/模板参数体系的详细定义与动态表单渲染机制;
  • 本地存储与云同步 store 的具体读写逻辑;
  • 各 Typst 模板(official-doc.typ 红头公文、tuzhang.typ 公章、试卷模板)的排版语法细节;
  • 国际化文案管理脚本 scripts/manage-messages.ts 的用法。

对于上述主题,本页只在"架构分层"与"相关链接"中给出入口指引。

概述(Overview)

项目定位

endfield-docmaker 是一个"娱乐与学习交流"用途的文档生成工具(README 顶部以 IMPORTANT 提示块明确声明了使用边界:该工具在不修改代码的前提下无法仿造真实文件或真实存在机构签发的文件)。它的核心价值主张是:

  1. 完全在浏览器内运行——PDF 生成不依赖服务器,隐私友好、零后端成本,可部署为纯静态站点(GitHub Pages / Cloudflare / Vercel 三处官方部署)。
  2. 多模板 + 可自定义参数——每个模板(红头公文、试卷等)支持数个自定义参数;试卷模板能按单题分数自动计算板块总分与整卷总分;公文模板自动生成带随机偏移和旋转的圆形公章。
  3. Typst 标记语法支持——内容区域直接支持 Typst 标记语法,排版能力远超普通 HTML 富文本。
  4. 完整的用户体验闭环——PDF 实时预览、新标签页打开、下载、二维码分享;表单内容自动持久化到浏览器本地存储;字体文件缓存至 IndexedDB;明暗主题切换;中英双语界面;设置页支持管理字体与一键清空数据。

关键概念

概念含义
模板(Template)一份 Typst 源文件(如 official-doc.typ、tuzhang.typ),定义文档的排版结构
机构(Authority)游戏世界观中的签发机构(罗德岛、宏科院、联盟工团、环塔商会等),对应 src/lib/assets/logos/ 中的矢量 Logo 与 AuthoritiesList.svelte 列表
Typst WASM通过 @myriaddreamin/typst.ts 系列包在浏览器中运行的 Typst 编译器,负责把源码编译为 PDF
本地持久化表单状态存入浏览器本地存储,字体文件存入 IndexedDB,均可在设置页清空
Paraglide JS基于 Inlang 的国际化方案,文案源文件为 messages/en.json 与 messages/zh.json

架构(Architecture)

endfield-docmaker 是单页 SvelteKit 静态应用,所有逻辑都在客户端完成。整体可分为五层:路由与布局层、UI 组件层、业务逻辑层(hooks 与工具)、Typst 编译层、数据与资源层。下面的架构图基于仓库实际目录结构绘制(依据 README 的项目结构说明与 src/ 下真实文件清单):

Loading diagram...

架构分层解读

  • 路由层(src/routes/):应用只有一个主页面 +page.svelte(表单 + PDF 预览),配合 +layout.svelte 根布局与 +layout.ts 加载逻辑、layout.css 全局样式与主题变量。src/hooks.server.ts 与 src/hooks.ts 是 SvelteKit 的服务端/通用钩子入口。由于采用 @sveltejs/adapter-static,构建产物是纯静态站点。
  • UI 组件层(src/lib/components/):DynamicForm.svelte 负责按所选模板动态渲染参数表单;AuthoritiesList.svelte 提供机构选择;DocLibrary.svelte、FileList.svelte、DraggableList.svelte 构成文档/附件管理;CompileError.svelte 展示 Typst 编译错误;SettingsModal.svelte、ShareQrModal.svelte、LocaleSwitch.svelte、ThemeToggle.svelte、PageImageViewer.svelte、KvGrid.svelte、DateInput.svelte 等覆盖各自交互场景;ui/ 目录是 shadcn-svelte 基础组件(button、card、dialog、input、select、tabs、textarea、tooltip 等)。
  • 业务逻辑层(src/lib/):hooks/ 目录承载业务 hooks,constants.ts 定义常量,utils.ts 提供通用工具,tint.ts 处理颜色,index.ts 作为公共导出入口。
  • Typst 编译层:typst.svelte.ts 封装 Typst WASM 的初始化与编译(文件名后缀 .svelte.ts 表明它使用 Svelte 5 Runes 编写响应式模块级状态);模板源文件位于 assets/typst/(official-doc.typ 红头公文模板、tuzhang.typ 圆形公章生成器);底层依赖 @myriaddreamin/typst.ts、typst-ts-web-compiler、typst-ts-renderer(版本均为 0.8.0-rc3)。
  • 数据与资源层:stores/db.ts 与 stores/cloud.ts 是 Svelte store 风格的数据模块;assets/fonts/ 存放字体(配合 IndexedDB 缓存),assets/logos/ 存放机构矢量 Logo。
  • i18n 层:messages/en.json / messages/zh.json 为文案源,经 Paraglide JS 生成 src/lib/paraglide/ 供运行时使用,scripts/manage-messages.ts 用于文案管理与同步(pnpm m / pnpm mw)。

核心流程(Core Flow)

从用户填写表单到看到 PDF 预览,端到端链路如下:

Loading diagram...

流程要点与设计意图

  1. 表单驱动、即时编译:参数任一变化即触发重新编译,Typst WASM 在浏览器内完成排版,天然实现"实时预览"而无任何服务端往返。这是该工具选择纯前端架构的根本原因——零后端成本与零数据外泄。
  2. 持久化先于渲染:表单内容每次变更即写入本地存储(stores/db.ts),保证刷新不丢稿;字体文件单独缓存到 IndexedDB,避免重复下载大体积字体资源,两者都可以在设置页(SettingsModal.svelte)中管理或一键清空。
  3. 错误路径显式化:Typst 源码由用户输入(内容区支持 Typst 标记语法),编译失败是常态路径而非异常路径,因此专门有 CompileError.svelte 承载错误展示,而不是静默失败。
  4. 模板自动计算:试卷模板按单题分数自动计算板块总分与整卷总分;公文模板自动生成带随机偏移和旋转的圆形公章(tuzhang.typ)——这些"自动化"减少了用户手工填错的概率,同时让产物更逼真。

目录结构与职责映射

路径职责
messages/en.json、messages/zh.json英文/中文文案源文件
scripts/manage-messages.tsi18n 文案管理脚本(pnpm m / pnpm mw)
src/routes/+layout.svelte、+layout.ts根布局与加载逻辑
src/routes/+page.svelte主页面:表单 + PDF 预览
src/routes/layout.css全局样式与主题变量
src/hooks.server.ts、src/hooks.tsSvelteKit 服务端/通用钩子
src/lib/constants.ts常量定义
src/lib/index.ts公共导出入口
src/lib/tint.ts颜色处理
src/lib/typst.svelte.tsTypst WASM 初始化与编译逻辑
src/lib/utils.ts工具函数
src/lib/hooks/业务 hooks
src/lib/stores/db.ts、stores/cloud.ts本地数据存储与云端同步 store
src/lib/assets/fonts/字体资源(配合 IndexedDB 缓存)
src/lib/assets/logos/机构 Logo(罗德岛、宏科院、联盟工团、环塔商会等)
src/lib/assets/typst/official-doc.typ红头公文模板
src/lib/assets/typst/tuzhang.typ圆形公章生成器
src/lib/components/业务组件(DynamicForm、DocLibrary、SettingsModal 等)
src/lib/components/ui/shadcn-svelte 基础组件
src/lib/paraglide/Paraglide JS 生成的 i18n 文件

技术栈

层级技术版本(来自 package.json)选型意图
框架SvelteKit + Svelte 5(Runes 模式)@sveltejs/kit ^2.69.0、svelte ^5.56.4编译型响应式框架,产物小、运行时开销低,适合纯静态工具站
排版引擎Typst(WebAssembly)@myriaddreamin/typst.ts 0.8.0-rc3、typst-ts-web-compiler 0.8.0-rc3、typst-ts-renderer 0.8.0-rc3在浏览器内完成专业排版并输出 PDF,免除后端渲染服务
PDF 渲染pdfjs-dist^4.10.38在预览区渲染 PDF 内容
组件库shadcn-svelte + Bits UIshadcn-svelte ^1.3.0、bits-ui ^2.18.1可复制进仓库的可控组件体系,便于深度定制
样式Tailwind CSS 4tailwindcss ^4.3.2原子化样式 + 主题变量(配合 layout.css 明暗主题)
国际化Paraglide JS(Inlang)@inlang/paraglide-js ^2.20.2极小运行时的 i18n,中英双语文案源在 messages/
图标Phosphor + Lucidephosphor-svelte ^3.1.0、@lucide/svelte ^1.23.0双图标库覆盖不同视觉风格
主题mode-watcher^1.1.0明暗主题切换(ThemeToggle.svelte)
其他依赖fflate、qrcode-generator、@vercel/analytics^0.8.3、^2.0.4、^2.0.1压缩/解压、二维码生成(分享)、访问统计
构建工具Vite^8.1.2极快的开发与构建体验
部署静态站点 @sveltejs/adapter-static^3.0.10构建为纯静态资源,可托管于任意静态托管平台

配置选项(Configuration Options)

配置项类型默认/示例说明
主题light / dark跟随系统明暗主题切换,由 mode-watcher 与 ThemeToggle.svelte 实现
界面语言zh / en跟随浏览器中英双语界面,LocaleSwitch.svelte + Paraglide JS,文案源在 messages/*.json
模板类型模板枚举红头公文 / 试卷 等决定表单参数集合与 Typst 模板文件
机构机构枚举罗德岛、宏科院、联盟工团、环塔商会等决定公文抬头与 Logo(assets/logos/)
字体缓存开关 + 数据自动缓存至 IndexedDB设置页可管理字体、一键清空数据
表单持久化自动自动写入浏览器本地存储刷新后自动恢复表单内容
部署地址URLGitHub Pages / Cloudflare / Vercel三处官方部署,均为纯静态站点

本地开发(Usage Examples)

项目使用 pnpm 作为包管理器(packageManager: pnpm@12.3.4),脚本定义如下:

json
1{ 2 "scripts": { 3 "dev": "vite dev", 4 "build": "node -e \"fs.rmSync('build',{recursive:true,force:true})\" && vite build", 5 "preview": "vite preview", 6 "prepare": "svelte-kit sync || echo ''", 7 "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 8 "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 9 "format": "prettier --write .", 10 "lint": "prettier --check . && eslint .", 11 "fl": "prettier --write . && eslint . --fix", 12 "m": "tsx ./scripts/manage-messages.js", 13 "mw": "tsx ./scripts/manage-messages.js --write && prettier --write ./messages" 14 } 15}

Source: package.json

常用命令(来自 README 的"本地开发"章节):

bash
1# 安装依赖 2pnpm install 3 4# 启动开发服务器 5pnpm dev 6 7# 类型检查 8pnpm check 9 10# 格式化 + 检查 11pnpm fl 12 13# 构建静态站点 14pnpm build

Source: README.md

几点说明:

  • build 脚本先用 Node 内联命令删除旧的 build 目录再执行 vite build,保证产物干净;配合 adapter-static 输出可直接托管的静态文件。
  • prepare 在安装依赖后执行 svelte-kit sync(失败时静默 || echo ''),生成 SvelteKit 类型环境,避免首次 check 报错。
  • m / mw 走 scripts/manage-messages.ts(通过 tsx 直接运行 TS 脚本)管理 messages/ 下的多语言文案;mw 还会写入并用 prettier 格式化文案文件。

功能特性清单

以下特性列表摘自 README 的"功能特性"章节,是理解产品边界的第一手材料:

  • 在浏览器中实时生成 PDF 文件,无需后端服务
  • 支持多个模板,每个模板分别支持数个自定义参数
  • 试卷模板自动根据单题分数计算板块总分与整卷总分
  • 公文模板自动生成带有随机偏移和旋转的圆形公章
  • 基于 Typst 排版引擎,内容区域支持 Typst 标记语法
  • PDF 实时预览、在新标签页中打开、下载
  • 表单内容自动持久化至浏览器本地存储
  • 字体文件自动缓存至浏览器 IndexedDB
  • 可在设置页面管理字体、一键清空数据
  • 明暗主题切换
  • 中英双语界面

Source: README.md

部署与运维(Performance / Operational Notes)

  • 部署形态:adapter-static 输出纯静态资源,因此可无成本地同时部署到 GitHub Pages(https://naptie.github.io/endfield-docmaker/)、Cloudflare(https://endfield-docmaker.phi.zone/)与 Vercel(https://endfield.phi.zone/docmaker/),三处均为同一份构建产物。
  • 性能关键路径:Typst WASM 编译是计算热点。字体与模板资源通过 IndexedDB 缓存(首次加载后不再重复下载),缓解了 WASM 编译器与字体体积带来的首屏成本。
  • 可观测性:引入 @vercel/analytics 做轻量访问统计,无后端日志体系。
  • 合规与免责边界:README 明确声明工具仅供娱乐与学习交流,且在不修改代码的前提下无法仿造真实机构文件;运维与使用者需遵守该边界。

扩展点(Extension Points)

想在 endfield-docmaker 上扩展时,典型的切入路径有:

  1. 新增模板:在 src/lib/assets/typst/ 下新增 Typst 模板文件,并为模板声明参数集合,DynamicForm.svelte 会按参数动态渲染表单;内容区天然支持 Typst 标记语法。
  2. 新增机构:向 src/lib/assets/logos/ 添加矢量 Logo,并在机构列表(AuthoritiesList.svelte 相关数据)中登记。
  3. 新增语言:在 messages/ 下新增文案文件,用 scripts/manage-messages.ts(pnpm mw)同步维护,Paraglide 会生成对应运行时代码。
  4. 新增基础 UI 能力:组件体系基于 shadcn-svelte(可复制式组件),直接在 src/lib/components/ui/ 增删组件即可。
  5. 调整编译行为:Typst 初始化与编译集中在 src/lib/typst.svelte.ts(Svelte 5 Runes 模块),是接自定义字体加载、缓存策略或编译管线的唯一入口。

Sources

(2 files)