@auto-hwp/engine

中文文档
0.0.22发布于 2026/11/05Apache-2.0TypeScriptES Module零依赖构建来源已验证近 30 天下载 2357

自动hwp引擎作为WebAssembly:在浏览器中打开.hwp/.hwpx,向SVG渲染页面,通过Intent JSON编辑,导出HTML/PDF/HWPX. 没有LLM,没有文件系统,没有捆绑的字体.

中文使用文档
文档目录11 节
  1. 在SDK( 层图) 中的位置
  2. 安装快速启动( S)
  3. 原出处(0.0.3+)
  4. API 密码
  5. ===========================================================…
  6. 用 Web Worker 运行引擎( 问题 055, FG-14)
  7. 安全——SVG无人信任(R7)
  8. 字体被注入, 永不捆绑( R8)
  9. 注册重排文档的字体( 问题 022)
  10. 套装大小
  11. 导出时的表格行高( T) noAdjust (中文(简体) )

@ auto- hwp/ 发动机

自动 hwp 文档引擎编译为 Web Assembly - 打开 .hwp编号 :.hwpx 在浏览器中, 渲染 每页到 SVG,通过 Intent JSON 编辑,并导出 HTML / PDF / HWPX客户端 没有 LLM,没有文件系统,也没有捆绑的字体.

  • 编辑行道 =: hwp-mcp (意为 JSON schema v0): applyIntent 编号 : undo 编号 : redo, (中文(简体) ), toHwpx。 。 。 .
  • 渲染/ 几何/ 导出道 =: hwp-session数字 : renderPageSvg, (中文(简体) ), hitTest, (中文(简体) ), tableAt, (中文(简体) ), exportHtml, (中文(简体) ), exportPdf。 。 。 .
  • 人工智能留在主机上 服务器 (R6):运行您的模式服务器侧并应用由此产生的意图 杰森在这里。 此软件包从未看到 API 密钥 .

在SDK( 层图) 中的位置

这个原子弹引擎是 L1 级 ——无头引擎(平板/放电/放电/对地测量/intent/undo/export). 这个 只知道文档;它没有UI,也没有选择状态. 见 docs/SDK-LAYERS.md。 。 。 .

L4 host app (apps/hwp-lab, Tauri, your app) — supplies the LLM proxy (its key) + assembles a UI
L3 @auto-hwp/react        — optional React binding (useHwpEditor + components); all replaceable
L2 @auto-hwp/editor-core  — headless editor (DocSession/SelectionModel/EditController) over an EngineAdapter
L2' @auto-hwp/ai-protocol — vendor-neutral LLM protocol (prompt/context/validate); no fetch, no keys
L1 @auto-hwp/engine (this) / hwp-mcp — headless engine; state is the document only

A 类 WasmAdapter (单位:千美元) @auto-hwp/react) 包裹此软件包以满足 L2 的 EngineAdapter 契约,所以 同一编辑器核心驱动网页( wasm) 和一个桌面应用程序( Tauri) .

安装快速启动( S)

import { initEngine, HwpDoc } from '@auto-hwp/engine';

await initEngine();                      // instantiate the wasm module once (see "Where the wasm comes from")
const bytes = new Uint8Array(await file.arrayBuffer());
const doc = HwpDoc.open(bytes, file.name); // .hwp or .hwpx (auto-detected)

const pages = doc.pageCount();
for (let p = 0; p < pages; p++) {
  container.insertAdjacentHTML('beforeend', doc.renderPageSvgSanitized(p)); // sanitized SVG — see R7
}

// edit: fill a table cell (Intent schema v0)
doc.applyIntent({ intent: 'SetTableCell', section: 0, index: 1, row: 0, col: 0, text: '셀 값' });
doc.undo();

const html = doc.exportHtml();
const hwpx = doc.toHwpx();                // Uint8Array — hand to a download

doc.free();                              // free the wasm allocation on swap (R13)

原出处(0.0.3+)

initEngine() 与 无参数 从 jsDelivr 取出二进制, 绑入 这个包是自己的 版本 这样啊 npm i 是整个设置 :

https://cdn.jsdelivr.net/npm/@auto-hwp/engine@<this version>/pkg/hwp_wasm_bg.wasm

从不 @latest: 原生胶水和二进制胶水是一起编译的,并且是一个 不匹配的对无法链接(或链接,然后拒绝更新的intents). ENGINE_VERSION, (中文(简体) ), defaultWasmUrl() 财务报告和审定财务报表 defaultWorkerUrl() 从 @auto-hwp/engine (和 @auto-hwp/engine/cdn) 如果你想检查或重新检查它们.

自我接待是 覆盖,而非要求 ——通过 URL(或字节 / 编译) WebAssembly.Module:

await initEngine('/hwp/hwp_wasm_bg.wasm');
// or let your bundler emit it (Vite):
import wasmUrl from '@auto-hwp/engine/pkg/hwp_wasm_bg.wasm?url';

下载进度( 二进制为~7.7 MB,~3.0 MB在线上):

await initEngine(undefined, { onProgress: ({ ratio, loaded, estimated }) => … });

ratio 实值 null 当无分母的时候 estimated: true 意味着转移是 内容编码 - Content-Length 然后计数 压缩 体积下降时的字节数 已解压 因此,公布的大小被用作分母,比例从未提前达到一分. 过 expectedBytes 当自我接待一个定制建筑.

API 密码

方法回返页:1
initEngine(input?, options?)Promise证一相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相 没有 input = CDN 默认值; options.onProgress 报告下载勾选.
HwpDoc.open(bytes, name?)HwpDoc.hwp (需要默认 rhwp 构建) 或 .hwpx。 。 。 .
pageCount()number自发投降吧.
renderPageSvg(n)string已销毁 见安全部.
renderPageSvgSanitized(n)stringsanitizeSvg 应用.
hitTest(page, x, y)BlockHit | null自定义 ưμ㼯a or.
tableAt(page, x, y)TableBox | null自定义 ưμ㼯a coords (标记).
applyIntent(intent)Outcome对象或 JSON 字符串; 有意计划 v0.
undo() 编号 : redo()boolean空地时优雅地无所取.
registerFont(family, bytes)void驱动参数 财务报告和审定财务报表 PDF; (中文(简体) ); 复线 (重压) pageCount) (中文(简体) ).
exportPdf()Uint8Array掷出 {code:"font_missing"} 如果没有.
exportHtml()string自定义 HTML.
toHwpx(options?)Uint8Array圆通安全HWPX. options.hwpRowHeights数字 : "exact" (默认) "auto" - 见下文.
free()void二元;放出被子柄.

坐标: hitTest编号 :tableAt 为: 自定义 px (=HWPUNIT/75) (中文(简体) ). 编辑意向地址 模式在 结构指数 (节/块/行/col),从来像素.

=======================================================================================================================================================================

鲁斯的恐慌 wasm32 是一个 陷阱它毒害了整个案例. catch_unwind- 典型的警卫做的 所以一个恶意/恶作剧的文件 让解剖师惊慌失措地杀死了被谋杀者 不是你的页面。这个包裹包含:

  • 每个电话都是 try/catch编: A WebAssembly.RuntimeError 丢出一个 Error 与 code === "wasm_trap" 标记 全部 现场直播 HwpDoc 处理死亡.
  • 回收协议 : 编号 wasm_trap电话 resetEngine() 以重新验证模块,然后 再来open() 你的证件 未保存的文档状态已丢失——在"重开此文件" UX上汇合.
try {
  doc.applyIntent(intent);
} catch (e) {
  if (e.code === 'wasm_trap') {
    await resetEngine();       // fresh instance
    doc = HwpDoc.open(bytes, name); // re-open; previous handles are dead
  } else {
    throw e;                   // ordinary {code, message} engine error
  }
}

A 类 FinalizationRegistry 自由处理主机忘记 free()不过 明确 free() 关于文档 交换就是合同 (undo快照 + 原始字节按文档保存) — R13.

用 Web Worker 运行引擎( 问题 055, FG-14)

解析/ 重播 / toHwpx 在多MB文档中,它们会阻挡它们运行的线程。 这个包 船舶a 模块-工人条目 (单位:千美元)worker.js)+主线程 RPC 客户端 (单位:千美元)@auto-hwp/engine/worker-client)这样整个发动机就可以从主线上活下来——不 共享ArrayBuffer,没有COOP/COEP头,没有捆绑魔法.

import { EngineWorkerClient } from '@auto-hwp/engine/worker-client';

const client = new EngineWorkerClient();     // 0.0.3+: this version's worker.js from the CDN
await client.init();                          // instantiate wasm IN the worker (CDN default)
const { pages } = await client.open(bytes, file.name);               // parse off-thread
const svg = await client.call('renderPageSvg', [0]);                 // every HwpDoc method, awaited

无法将跨源工人脚本交给 new Worker(),所以CDN默认通过 同一来源 布罗布・希姆 那个 import开始worker-src blob: 在严格的CSP之下。 自我接待是 覆盖: 部署 worker.js, (中文(简体) ), index.js, (中文(简体) ), cdn.js 财务报告和审定财务报表 pkg/hwp_wasm.js 作为静态资产 保留 它们的相对路径 (工人进口) ./index.js输入 ./cdn.js 财务报告和审定财务报表 ./pkg/hwp_wasm.js ——省略 cdn.js 使用模块载重404杀死工人,并传递URL:

const client = new EngineWorkerClient({ url: '/hwp/worker.js' });
await client.init('/hwp/hwp_wasm_bg.wasm');

跨边界出错代码 : wasm_trap (毒死工人内部) client.reset() 然后重来..open, (中文(简体) ), worker_dead (工人自己死了) 下一个 init()编号 :reset() 即复发者, worker_terminated (主持人叫: terminate() ——故意取消,不是坠机. 普通类 引擎出错( e)no_document, (中文(简体) ), font_missing,.)通过不变. @auto-hwp/react是因为 WasmAdapter 所有这一切(包括052快照-第一次恢复) 后面 new WasmAdapter(wasmUrl, { worker: { url: workerUrl } })。 。 。 .

安全——SVG无人信任(R7)

renderPageSvg 返回文档导出字符串. 从不 innerHTML 它生动。 使用 renderPageSvgSanitized(n) 或者说 sanitizeSvg(svg) (划线) <script>, (中文(简体) ), on*, (中文(简体) ), <foreignObject>, (中文(简体) ), javascript: URLs) (中文(简体) ). 这是最低限度的后卫;完全硬化+CSP是宿主的担心(issue 016).

字体被注入, 永不捆绑( R8)

这个包裹船 无字体 (不允许将 Hancom / QQ 的相貌重新分类;见 docs/LICENSE-POLICY.md) (中文(简体) ). PDF 导出时, 您必须先插入一张相 :

const font = new Uint8Array(await (await fetch('/fonts/NotoSansKR-Regular.ttf')).arrayBuffer());
doc.registerFont('Noto Sans KR', font);   // OFL — safe to serve yourself
const pdf = doc.exportPdf();              // real, subsetted Korean glyphs embedded

exportPdf() 掷出 {code:"font_missing"} 如果没有注册字体( 从未默默地发出空) g.

字体字节必须是单面 TTF/OTF - TTC(TrueType收藏)是 没有 已接受:已接受 掷出 {code:"ttc_unsupported"} (克里拉语) simple-text 后端无法子集收藏, 而 形状器只取面额索引 0 。 注入的字节线程一直贯穿到krilla (issue 018): 第一个可解析的注册相成为PDF正文相,所以输出的PDF嵌入a 真实 您的朝鲜格言的子集。 。 。 .

注册重排文档的字体( 问题 022)

registerFont 现在把被注入的面孔喂入 版式测量 以及嵌入的PDF—— 相同的字节形状屏幕 SVG, pagination 财务报告和审定财务报表 PDF,所以三个都同意. 在您注册字体之前, 制成/放出使用定型上标 缩写 倒置( 不需要字体文件) 。 因为真实 度量衡与Aprox不同, 注册( 或替换) 字体可以更改页面数和行 间断,因此:

doc.registerFont('Nanum Gothic', font); // → re-layouts; internal SVG cache invalidated
const pages = doc.pageCount();           // re-query — may differ from before
for (let i = 0; i < pages; i++) render(doc.renderPageSvgSanitized(i)); // re-render every page

v1 地图 每个 文档字体名称到此被注入的相片( 您想要的相片注册相片) 文件一级的每个家庭的绘图是后续行动.

套装大小

pkg/hwp_wasm_bg.wasm 是~11 MiB 生 /~3.5 MiB gzipped(无字体) 。 大部分是HWP5型机车(.hwp(中文(简体) ) 二进制解析器 (rhwp) + krilla PDF 堆栈. 仅使用 HWPX 构建( 丢弃箱子的默认值) hwp5 特性)为~4.6 MiB生 /~1.4 MiB gzipped. 运行 wasm-opt -Oz (binaryen)在文物上缩小 此外,在建筑环境中也找不到.

导出时的表格行高( T)noAdjust(中文(简体) )

HWPX 标记表格 <hp:tbl noAdjust="1"> 当其行不能随内容而增长时(汉科姆剪辑) 以你们所享受的, 当引擎写到:

表格来源noAdjust 写入
HWPX 输入文件本身的值, 不变( 未触碰的表格和单元格编辑保留原始字节)
二进制 .hwp 输入, toHwpx() 编号 : hwpRowHeights: "exact" (0.0.6+) (中文(简体) )1 a 包括: .hwp已保存的行高是 Hancom 的真实布局, 因此页面数到来
二进制 .hwp 输入, hwpRowHeights: "auto"0 ——以汉口语填充内容(事前为0.0.6行为)而成行增长
通过编辑插入表格0

填补a .hwp 带有较长文本的窗体 ? 导出为 doc.toHwpx({ hwpRowHeights: "auto" }) 所以汉口 长出行来而不是剪接.

版本与发布记录

@auto-hwp/engine 共发布 22 个版本,首次发布于 2026/07/22;过去 12 个月发布了 22 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.0.22latest2026/11/052 天前
0.0.212026/10/2810 天前
0.0.202026/10/2711 天前
0.0.192026/10/2612 天前
0.0.182026/10/2415 天前
0.0.172026/10/1424 天前

关于 @auto-hwp/engine 的常见问题

@auto-hwp/engine 是什么?

自动hwp引擎作为WebAssembly:在浏览器中打开.hwp/.hwpx,向SVG渲染页面,通过Intent JSON编辑,导出HTML/PDF/HWPX. 没有LLM,没有文件系统,没有捆绑的字体.

如何安装 @auto-hwp/engine?

在项目目录运行 npm install @auto-hwp/engine,或使用 pnpm add / yarn add / bun add。

@auto-hwp/engine 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@auto-hwp/engine 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@auto-hwp/engine 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@auto-hwp/engine 可以商用吗?

@auto-hwp/engine 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@auto-hwp/engine 的下载量有多少?

根据 npm 官方下载统计,@auto-hwp/engine 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,357 次,日均约 79 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@auto-hwp/engine 还在维护吗?

最新版本 0.0.22 发布于 2026/11/05(2 天前);至今共发布 22 个版本,其中过去 12 个月发布了 22 个;首次发布于 2026/07/22。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。