崮生(子虚)
|
d16aa46227
|
feat: 离线裁剪统计 + 企业服务板块 + SDK文档独立页(/docs) + 示例改用observeFont
|
2026-08-06 08:57:48 +08:00 |
|
崮生(子虚)
|
09f434bbcf
|
feat: 离线裁剪页面 + 增量预览 + DEV预览页 + tempUploads统计 + SDK缓存破坏 + UI优化
- 新增离线裁剪页面 /offline-subset(纯浏览器端字体裁剪)
- SDK subsetProvider 抽象,离线页面注入本地裁剪 provider
- 预览用增量裁剪(SDK自动去重),下载用全量裁剪
- 拖放区域支持点击和拖拽选择字体文件
- 新增 DEV 预览页 /__dev(仅 dev 模式路由可达)
- FontDebugPreview 从首页提取为独立页面
- tempUploads 统计字段(全链路+持久化)
- webfont-sdk.js 构建时戳缓存破坏
- 首页导航栏新增离线裁剪入口
- UploadSection 离线裁剪入口合并到游客上传卡片
- SDK 文档代码示例补充 HTML 用法
- 导航栏窄屏换行适配
|
2026-08-03 15:18:01 +08:00 |
|
崮生(子虚)
|
5a7c6a9913
|
fix: LLRT readdir 不兼容 withFileTypes 导致临时字体清理失效
根因:LLRT 的 fs.readdir 返回字符串数组而非 Dirent 对象,
entry.isFile() 抛 TypeError 被 catch 静默吞掉,
导致 evictIfNeeded 和 temp_cleaner 从未执行(线上堆积 108 个文件 992M)。
修复:
- node.ts: readdir 改为先拿文件名再 stat 判断
- temp_cleaner.ts: catch 块加日志不再静默吞错误
同时包含:
- font-config.json homepage 链接修复(删除 3 个 404,修正 2 个)
- FontDetail 字符预览改为可实时编辑
- 添加 scripts/bench.mjs 压测脚本
|
2026-08-01 08:03:33 +08:00 |
|
崮生(子虚)
|
98c3c5a6e2
|
fix: 路由切换后滚动到顶部
详情页→列表→另一个详情页时滚动位置保留在前一页的偏移,
用 router.afterEach 统一处理,每次导航回到顶部。
|
2026-07-31 00:06:05 +08:00 |
|
崮生(子虚)
|
3e3e8899d5
|
fix: 修复字体详情页字体未应用——@font-face 替代 link stylesheet
根因:API 返回二进制 woff2 字体文件,但前端用 <link rel="stylesheet">
引用它,浏览器无法将 woff2 二进制作为 CSS 解析,导致字体完全未加载。
修复:
- 用 watchEffect + document.createElement('style') 动态注入 @font-face
声明,通过 src: url(...) 引用 API 返回的 woff2 二进制
- 修正 usageCode 示例代码,展示正确的 @font-face 用法
- 添加 SSG/SSR 守卫(typeof document === 'undefined' 跳过)
验证:document.fonts.check() 返回 true,字体 status 为 loaded
|
2026-07-31 00:03:33 +08:00 |
|
崮生(子虚)
|
6421e7d059
|
fix: extractCodePoints 增加 glyph 轮廓验证 + 删除冗余正文预览卡片
- font_meta.ts: extractCodePoints 新增 createGlyphValidator,对 TrueType 字体
检查 loca 表确认 glyph 有真实轮廓数据(非空),CFF 字体保持原逻辑
- lint 同步去掉 bodyTitle/bodyText(FontDetail 已移除正文预览卡片)
- FontDetail.vue: 删除正文预览区块(与大标题预览功能重叠),移除对应 computed
- allPreviewText 只合并 previewText + charsetPreview
|
2026-07-30 23:50:27 +08:00 |
|
崮生(子虚)
|
afbd4db77c
|
fix: 字体加载合并所有预览文字(previewText+bodyTitle+bodyText+charsetPreview)
之前 <link> 只加载 previewText 的字符子集,导致 bodyTitle/bodyText/charsetPreview
区域显示 fallback serif 而非实际字体。现在 allPreviewText 合并所有预览文字请求子集。
|
2026-07-30 23:43:08 +08:00 |
|
崮生(子虚)
|
7638ce7e2d
|
fix: 移除 FontDetail fallback 默认值 + lint 检查缺失字段 + 使用 CodeBlock 组件
- FontDetail.vue: 移除 DEFAULT_PREVIEW 等硬编码 fallback,config 缺字段时不渲染对应区块(避免显示字体不支持的字符)
- lint-font-config.ts: 新增检查 font/ 目录下所有字体是否都在 config 中有完整配置(previewText/bodyTitle/bodyText/charsetPreview 四个必填字段)
- FontDetail.vue: 使用方法代码块从 <pre><code> 改为 CodeBlock 组件(语法高亮)
|
2026-07-30 23:37:18 +08:00 |
|
崮生(子虚)
|
a095cd0590
|
feat: 详情页全面接入 font-config + 防闪烁
- font-config.json: 新增 bodyTitle/bodyText/charsetPreview 字段
为每个字体配置通过 lint 检查的专属文案
- FontDetail.vue: 正文/字符预览使用 config 字段替代写死文案
大标题/正文/字符预览加 v-if=meta 守卫,消除 hydrate 闪烁
h1 标题使用 displayName
- lint-font-config.ts: 扩展检查范围至所有文本字段
- FontUserConfig 类型同步更新(后端+前端)
|
2026-07-30 23:30:40 +08:00 |
|
崮生(子虚)
|
9397e10aad
|
feat: 字体列表/详情页接入 font-config 配置 + lint 脚本
前端:
- FontList.vue: 卡片使用 router-link 跳转;
展示 displayName/description/previewText/tags;
底部添加字体投稿联系文案
- FontDetail.vue: 预览文字使用 config.previewText 替代写死文案
工具:
- scripts/lint-font-config.ts: 检查 previewText 字符是否被字体支持
- package.json: 添加 lint:font-config 脚本
|
2026-07-30 23:23:30 +08:00 |
|
崮生(子虚)
|
23728ba02b
|
refactor: 回退内存闸门为固定并发(保留分组调度) + 前端改进
后端:
- subset_queue.ts: 移除基于内存的门控(LLRT GC 不释放 RSS),
回退到固定并发模型,保留分组调度优化(相同字体批处理重用缓存)
- config.ts: 恢复 subsetConcurrency / subsetQueueTimeoutSeconds,
移除 subsetMemSoftLimitMB
- routes/subset.ts, app.ts, routes/config.ts: 同步恢复
- api.ts, README: 同步更新
前端:
- FontSelector.vue: 下拉项和触发器标记临时字体(橙色徽章)
- CodeBlock.vue: 新增轻量代码块组件,内置 CSS/HTML/JS 分词高亮(0依赖)
- Home.vue: 集成 CodeBlock 替换原始 <pre> 代码块
|
2026-07-30 23:11:54 +08:00 |
|
崮生(子虚)
|
7403414439
|
feat: 用内存水位闸门替代固定并发限制
- subset_queue: 新增 withMemoryGate,基于 RSS 决定排队/执行
- getRssMB: Node 用 process.memoryUsage(),LLRT 用 /proc/self/statm
- 请求完成后主动 __gc() 加速内存回收
- config: SUBSET_MEM_SOFT_LIMIT_MB=600 替代 SUBSET_CONCURRENCY=4
- 小请求可高并发(内存够),大请求自动排队(防 OOM)
|
2026-07-30 22:51:37 +08:00 |
|
崮生(子虚)
|
65ba984972
|
feat: 字体子集化并发队列控制(服务端+客户端)
后端:
- subset_queue.ts: Semaphore 并发控制器,排队超时返回 503
- subset.ts: fontSubset 调用包裹在 withConcurrencyLimit 中
- config.ts: 新增 SUBSET_CONCURRENCY 环境变量(默认 2)
- routes/config.ts: 暴露 subsetConcurrency 到配置 API
前端:
- api.ts: ServerConfig 新增 subsetConcurrency 字段
- webfont-sdk.js: 客户端并发池(默认 4),setMaxConcurrent API
通过 document.fonts.load 精确追踪字体加载完成释放槽位
|
2026-07-30 21:33:45 +08:00 |
|
崮生(子虚)
|
abd75985b7
|
feat: 临时字体保留时限改为秒为单位(TEMP_RETENTION_SECONDS)
- TEMP_RETENTION_HOURS → TEMP_RETENTION_SECONDS,默认 10800(3小时)
- 前端显示自适应:秒/分钟/小时
- README docker-compose 示例同步更新
|
2026-07-30 21:24:38 +08:00 |
|
崮生(子虚)
|
19b14f58ea
|
feat: 字体元数据三层架构 + 临时字体保留机制 + 列表页覆盖率排序
- font_meta.ts: cmap 解析覆盖率 + name 表提取字体信息(版权/作者/许可) + 人工配置(font-config.json)
- 三层缓存: 进程内存 → .meta.json 磁盘 → font-config.json stat mtime 热更新
- 临时字体保留机制: TEMP_RETENTION_HOURS(默认3h), 超时未使用自动删除
- 列表页: 覆盖率标签 + 按字符集覆盖率排序
- 详情页: 标签/开源链接/简介 + 字体信息面板(设计师/版权/许可)
- 首页: 红色警告提示切勿上传非商用字体 + 显示保留时限
- SSG noindex bug 修复
|
2026-07-30 21:19:09 +08:00 |
|
崮生(子虚)
|
5b82dec19a
|
fix: 首页 header 窄屏适配,按钮文字不换行
- header 外层 flex-wrap: wrap,窄屏时标题与按钮组自动换行
- 按钮组 flex-wrap: nowrap + flex-shrink: 0,保持在一行
- 所有按钮/链接 white-space: nowrap + flex-shrink: 0,文字不折行
|
2026-07-30 20:33:32 +08:00 |
|
崮生(子虚)
|
cdffd4cb57
|
feat: 字体列表页 + 详情页 SSG + LazyTrigger 懒加载组件
- FontList.vue: 字体列表页,卡片网格布局,支持拼音搜索,点击进入详情
- FontDetail.vue: 字体详情页,SSG 模板 + 服务端占位符替换
- LazyTrigger.vue: 可复用懒触发组件,IntersectionObserver 进入视口回调
- 首页添加字体列表入口,FontDetail 返回列表
- placeholders.ts: 前后端共享的占位符常量
- 后端 font_detail.ts: 读取 SSG 模板并替换占位符
|
2026-07-30 20:32:42 +08:00 |
|
崮生(子虚)
|
d064e9bc8f
|
fix: 进度条方向 + 宽度
- 进度条缺少 width:100%,导致 absolute 元素宽度为 0 不可见
- keyframes 改为 scaleX(0→1),从空到满增长(符合进度直觉)
|
2026-07-30 19:53:57 +08:00 |
|
崮生(子虚)
|
3af1a19dce
|
fix: StatsPanel 卡片不显示 — IntersectionObserver 死锁
根因: v-if=data 和 ref=rootRef 在同一元素,data 为 null 时
元素不存在 → observer 无法 observe → data 永远不会加载。
修复: initialLoad() 在 onMounted 时立即调用,不依赖 observer。
IntersectionObserver 仅负责后续轮询的暂停/恢复。
同时修复 formatUptime 中文分支的秒数计算 bug。
|
2026-07-30 17:33:20 +08:00 |
|
崮生(子虚)
|
8273508c79
|
feat: StatsPanel 视口内才轮询 + 底部进度条动画
- IntersectionObserver + document.visibilityState 双条件控制轮询
- 卡片底部进度条 (scaleX 动画),每次刷新数据后重启动画
- 避免不可见时浪费请求
- bump version to 1.11.1
|
2026-07-30 17:26:24 +08:00 |
|
崮生(子虚)
|
13787dfd22
|
refactor: 重命名 Skill 为 chinese-web-font,聚焦中文字体应用
- skills/chinese-web-typography.md → skills/chinese-web-font.md
- 移除路线图(不写规划)
- 移除英文 README 中不存在的 Typography Presets 表格
- 统一文案:Typography Skill → Chinese Font Skill
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-29 09:14:04 +08:00 |
|
崮生(子虚)
|
b4a7a820eb
|
feat: AI Typography Skill 系统 + 中英双语 i18n + Before/After Demo
- 新增 skills/chinese-web-typography.md 作为提供给 AI agent 的排版智能文件
- 重写 README.md(中文默认),新增 README.en.md(英文版),互相引用
- 新增 TypographyDemo.vue 前后对比组件,展示中文字体效果差异
- 新增 src/i18n.ts 轻量国际化方案,所有组件文案支持中英切换
- 后端 /api/fonts 返回 temporary 字段标识临时字体
- 升级至 v1.8.0
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-28 22:41:47 +08:00 |
|
崮生(子虚)
|
76ac23ad5d
|
fix build
|
2026-04-30 21:03:57 +08:00 |
|
崮生(子虚)
|
53d170dc90
|
feat: 前端迁移至 Vue3 + TS,后端构建迁移至 tsdown
- 前端从 SolidJS 迁移到 Vue3 Composition API(<script setup lang="ts">)
- 后端构建从 tsup 迁移到 tsdown,动态 import 改为静态以支持单文件输出
- FontSelector 添加 defineProps 修复下拉无选项问题
- StatsPanel 添加"服务状态"标题
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-04-30 20:46:30 +08:00 |
|
崮生(子虚)
|
68df9db2da
|
fix: 修复 StatsPanel 中 flex-wrap 属性的 JSX 语法错误
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-04-30 19:37:57 +08:00 |
|
崮生(子虚)
|
c18dc44e72
|
chore: 升级至 v1.7.0,新增内存缓存与运行时统计
- 新增通用 LruCache 类,支持按条目数/字节容量两种淘汰策略
- 字体裁剪结果 LRU 内存缓存(默认 10MB,X-Cache 响应头标识命中)
- 新增 GET /api/stats 运行时统计接口
- 前端统计面板(10s 轮询,页面不可见时暂停)
- API handler 拆分到 routes/ 目录,提取 shared.ts 共享模块
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-04-30 19:34:30 +08:00 |
|
崮生(子虚)
|
bd3189b459
|
优化性能
|
2026-04-11 17:53:57 +08:00 |
|
崮生(子虚)
|
97f4d72e6a
|
fix: 修复 OTF→TTF 转换字体在浏览器中渲染空白的问题
根因:optimizettf 中 maxPoints/maxContours 只在 TypedArray 格式(_xArr)
的字形分支中统计,OTF→TTF 转换的字形使用对象 contours 格式,
导致 maxp 表中这两个值为 0,浏览器据此跳过渲染。
同时包含 OTF 解析路径的多项性能优化和清理冗余测试文件。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
2026-04-09 20:46:48 +08:00 |
|
崮生(子虚)
|
18e60fe940
|
优化性能
|
2026-04-09 16:47:41 +08:00 |
|
崮生(子虚)
|
55aa492ce0
|
新增 ttf 随机选择和提示
|
2026-04-09 12:02:37 +08:00 |
|
崮生(子虚)
|
e2cc7c1144
|
feat: 前端格式选择器组件,服务端支持能力透传
- 新增 FontSelector.tsx 独立组件,字体和输出格式并排选择
- /api/config 新增 supportedOutTypes 字段(LLRT 仅 ttf)
- 前端加载配置后自动适配可用格式
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
2026-04-09 11:56:10 +08:00 |
|
崮生(子虚)
|
820fc71166
|
feat: 新增 woff2 输出格式支持,默认使用 woff2
- 后端支持 outType URL 参数(woff2/ttf),Node.js 默认 woff2,LLRT 默认 ttf
- woff2 wasm 延迟初始化,仅首次请求时加载(~8ms)
- SDK 三个入口函数支持 outType 选项,默认 woff2
- 前端 CSS、下载、使用说明适配 woff2
- 基准测试新增 woff2 测试(耗时、体积、压缩率)
- 构建脚本自动复制 woff2.wasm 到 dist 目录
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
2026-04-09 11:48:07 +08:00 |
|
崮生(子虚)
|
6d34a5e53a
|
feat: 标语随机使用字体展示,调整字号和位置
标语移至标题下方,每次加载随机选取字体列表中的一个字体渲染,
悬停显示字体名称,字号调至 24px。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
2026-04-09 11:34:02 +08:00 |
|
崮生(子虚)
|
4acb1c1e5d
|
docs: 添加品牌标语
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
2026-04-09 10:47:48 +08:00 |
|
崮生(子虚)
|
2f7ce0cb72
|
feat: SDK 多模式架构 + 首页输入事件驱动
- 重构 webfont-sdk.js 为核心增量引擎 + 多触发器架构
- 支持 loadFont(轮询)、observeFont(MutationObserver)、loadText(手动传文本)三种模式
- 三种模式共享 loadedChars,按 fontName|family 自动去重增量加载
- loadFont interval 可从外部配置
- 首页改用 loadText 模式,输入即时触发字体加载
- textarea 高度根据文本行数动态变化
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
2026-04-09 10:41:53 +08:00 |
|
崮生(子虚)
|
b902b4e1cc
|
增强安全性,重构代码
|
2026-04-08 22:05:17 +08:00 |
|
崮生(子虚)
|
3163e99534
|
重构上传组件为独立文件,移除 txikijs 依赖,调整布局顺序
- 提取 UploadSection 为 src/UploadSection.tsx,复用 FileUploader 组件和 useUpload hook
- 移除 @txikijs/types 包及所有相关配置引用
- 布局顺序调整:选择字体 → 预览 → CSS代码 → 上传 → 原理/SDK文档
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
2026-04-08 20:55:53 +08:00 |
|
崮生(子虚)
|
9da270733d
|
v1.2.0: 增量字体加载 SDK,优化预览体验
- 新增 webfont-sdk.js,支持按需增量加载字体片段,无闪烁
- 预览使用 SDK 增量加载,输入时不再重新加载已有字体
- SDK 根据元素类型(input/textarea vs 其他)正确获取文本
- SDK 支持重复调用同一选择器时自动清理旧状态
- 页面说明区分基础用法和进阶用法,提供 SDK 下载链接
- URL 改为完整域名(location.origin),方便用户直接复制使用
- 预览文本框字体大小调至 32px
- API Key 输入框改为 text 类型消除密码警告
- SEO 优化:添加 description meta,优化 title
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
2026-04-08 20:48:23 +08:00 |
|
崮生(子虚)
|
e0f34c36b6
|
修复上传功能和服务器健壮性问题
- 修复 multipart 解析器:endDelimiter 提前检查导致循环退出
- 修复 Node.js v24 兼容:改为先读取 body 再构造 Request
- 修复 HTTP keep-alive 死锁:按 Content-Length 精确读取 body
- 修复服务器崩溃:connectionHandle 加 try-catch,单连接错误不影响全局
- 修复 URL 写死:webfont.shenzilong.com 改为 localhost
- 复制按钮加"已复制/复制失败"反馈提示
- TEMP_MAX_FILES 改为环境变量可配置
- dev 环境默认启用临时上传和管理员上传
- CSS 代码默认展示,使用技巧不再折叠
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
2026-04-08 17:11:55 +08:00 |
|
崮生(子虚)
|
7fceccfe4d
|
重构前端UI,新增字体上传/下载/模糊匹配功能
- 前端UI重构:字体选择器、文本预览、CSS输出+复制、下载字体、上传区域
- 后端新增API:/api/fonts(列出字体)、/api/config(公开配置)、/api/upload(上传字体)
- 字体查找支持模糊匹配(精确 > 前缀 > 包含)
- 上传功能分两种模式:临时上传(ENV开关,FIFO上限10个)和管理员上传(API Key认证)
- 新增multipart解析器、配置模块、文件系统抽象(writeFile/readdir/mkdir/unlink)
- 后端启动时等待运行时初始化完成,确保接口可用
- dev-all.ts后端启用tsx watch模式自动重载
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
2026-04-08 16:18:46 +08:00 |
|
zixu
|
c6372ea8c3
|
typo
|
2024-08-29 09:44:00 +08:00 |
|
zixu
|
6b49d15eae
|
typo
|
2024-08-29 09:39:37 +08:00 |
|
zixu
|
c6567b8948
|
前端界面添加防抖
|
2024-08-29 09:38:47 +08:00 |
|
zixu
|
a1b5502891
|
支持使用 tjs 运行
|
2024-08-19 18:10:09 +08:00 |
|
zixu
|
a44f978ef5
|
改善前端页面
|
2024-08-18 17:46:13 +08:00 |
|
zixu
|
cae3bad5a9
|
更新文档
|
2024-08-18 16:29:18 +08:00 |
|
zixu
|
6b896d768e
|
init
|
2024-08-18 15:14:50 +08:00 |
|