@alwith/module-editor

中文文档
0.6.1发布于 2026/11/04SEE LICENSE IN LICENSETypeScriptES Module构建来源已验证近 30 天下载 2453

Document state, saving, tabs and extensible previews. The package does not depend on the file-tree package, a session store or Tauri.

原始使用文档
文档目录4 节
  1. Lifecycle and safety
  2. Rendering and extensions
  3. Optional local previews
  4. Native spreadsheet parsing

@alwith/module-editor

Document state, saving, tabs and extensible previews. The package does not depend on the file-tree package, a session store or Tauri.

import { createEditorController, EditorWorkbench, imagePreview } from "@alwith/module-editor"
import "@alwith/module-editor/styles.css"
const editor = createEditorController({ fs, confirmClose, reportError })
await editor.open("/project/readme.md")
<EditorWorkbench controller={editor} previews={[imagePreview]}
  onError={reportError} />

Lifecycle and safety

Stable document IDs survive path changes. One FS instance serializes saves, moves, deletions, closes and reloads. Directory moves rebase descendant paths. Dirty documents veto deletion when confirmation returns cancel. Approved deletions temporarily lock their documents until the native operation finishes or fails. Custom engines must respect readOnly. Failed saves keep dirty state; a disk version mismatch never silently overwrites the disk. Editing while a save/reload is awaiting I/O cannot silently close or replace the newer edit.

Call requestClose(id) to close a tab and prepareShutdown() before leaving the workspace/app. Both can return false. dispose() releases subscriptions only; it does not ask, save or discard on the user's behalf. The host is responsible for crash recovery/draft persistence if required; this release retains drafts in memory while switching projects, not across process crashes.

UTF-8 and BOM-marked UTF-16 LE/BE are decoded strictly. Invalid bytes remain binary/read-only. Saving retains BOM and a document's newline convention. Text is not guessed from malformed bytes. The default file size limit is 16 MiB; pass maxFileBytes for adapters that support a different limit. Clean documents have an LRU limit (default 12); dirty documents are not evicted.

saveAs uses create-only writes. The host obtains a destination and grants access; it must not assume an arbitrary path is writable. onOpenExternal is a host action for formats that need another application.

Rendering and extensions

/core contains no React. Root exports EditorWorkbench, PreviewProvider, TextEditorProps and imagePreview. Previews are ordered: the first provider whose supports(document) returns true renders the document. Text files can switch between edit and preview. SVG/HTML are not executed by the built-in image preview. HTML/PDF/office/media services belong in explicit optional providers with the required sandbox and resource disposal; unsupported binaries are not decoded as editable text.

The default text renderer is a textarea. /monaco exports createMonacoEngine(monaco, controller): Monaco is an optional peer and never loaded by the default entry. The host imports Monaco lazily and configures workers. The engine retains undo/models and view state by document ID, releases closed models and provides dispose. The host supplies light/dark theme. U uses Monaco for code/Markdown editing and injects its shared Markdown renderer for preview.

All toolbar text is configured by EditorLabels; theme colors use semantic CSS variables. Hosts may provide renderTextEditor, requestSaveAs, onOpenExternal, and arbitrary preview providers. Business HTML/Drive/account/session integrations stay in the host.

See examples/files/editor-only.tsx and combined.tsx for independent and composed consumers.

compactToolbar keeps the file path visible and moves editor actions into an overflow menu; actionsLabel localizes its trigger. The default toolbar remains unchanged for other hosts. Tabs accept trackpad and wheel scrolling with hidden scrollbars; activating a document brings its tab into view. Preview scrollbars use thin, low-contrast thumbs based on the host foreground token.

Optional local previews

@alwith/module-editor/previews exports createPreviewProviders(host). Load this entry lazily and import @alwith/module-editor/previews/styles.css alongside the workbench stylesheet. PDF, OOXML Word, spreadsheets, Markdown, HTML, audio/video and TIFF decoders load independently when their provider is selected. These portable viewers are reduced from ALwith Desktop; account, collaboration and native filesystem integrations remain in the host.

Spreadsheet previews require SheetJS CE 0.20.3 or a compatible newer 0.20.x release. The public npm xlsx package remains on the old 0.18.5 distribution; install from the official SheetJS distribution and commit the package-manager lockfile:

bun add xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz

The host supplies pdfWorkerSrc and resolveResource(documentPath, reference), returning { bytes, mimeType, path }. Resolve references against the supplied base path, return a canonical resource path and enforce the host's filesystem permissions. parseSpreadsheet(bytes, signal) can delegate SheetJS decoding to a worker; honor cancellation by terminating or cancelling the worker. labels and imageLabels localize controls. openExternal handles legacy .doc/.dot files and unsupported media codecs.

HTML uses an opaque sandbox with scripts enabled and no parent access, navigation permissions or network requests. Relative stylesheets, CSS assets and literal JavaScript imports are resolved before rendering. Remote HTTPS assets require explicit allowRemoteResources: true; privileged schemes and plain HTTP stay blocked. Computed resource paths and circular local script dependencies cannot be resolved ahead of rendering. Preview-owned object URLs are released on replacement/unmount; resource loading and generated content are bounded.

Markdown uses Desktop's Milkdown CommonMark/GFM presets with an outline and formatting controls. It publishes edits synchronously through the workbench's document context and never writes files directly. Programmatic replacements retain their clean state. Set autoSaveDelay to debounce the host's save action, or leave it unset for manual saving. The host remains authoritative for read-only state, dirty state, save failures and external changes.

Native spreadsheet parsing

The Tauri plugin alwith-editor (crates.io) accepts host-authorized file bytes and forwards parsing to the private native editor library, which ships in this package under native/<os>-<cpu>/. Stage it at build time with stageNativeModule from @alwith/module-desktop-shell/stage, register the plugin with .plugin(alwith_editor::init(Config { development_directory })), grant alwith-editor:default, and call it through @alwith/module-editor/commands. calamine and the parser implementation are built into the native library; no additional process is introduced.

parse_spreadsheet(bytes, extension) returns typed worksheets with absolute cell coordinates, deduplicated styles, merged cells, numeric values and date epoch. Desktop and U use this same parser. XLSX styles include fonts, colors, fills, borders, alignment and number format codes. Other formats use calamine's available metadata; CSV remains text. Input is capped at 16 MiB; preview limits are 2,000 rows and 200 columns and sheets report truncated when exceeded. Their tabs visibly identify a partial preview and its limits.

/spreadsheet exports the shared SpreadsheetView and workbookSheets adapter. Number formats use SheetJS SSF (including the 1904 epoch), not a custom formatter. The canvas renderer supports left/center/right and top/middle/bottom alignment; unsupported alignments report an error instead of silently dropping formatting. Pattern fills, diagonal borders, text rotation, conditional formatting and original row/column dimensions are not reproduced by this renderer. Dashed border subtypes use the renderer's dashed line; this is a read-only preview, not pixel-identical Excel.

版本与发布记录

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

版本发布日期距今
0.6.1latest2026/11/043 天前
0.6.02026/11/034 天前
0.5.42026/11/035 天前
0.5.22026/11/025 天前
0.5.12026/11/025 天前
0.5.02026/10/308 天前

其他发布通道:next → 0.1.0-rc.16。

关于 @alwith/module-editor 的常见问题

@alwith/module-editor 是什么?

Document state, saving, tabs and extensible previews. The package does not depend on the file-tree package, a session store or Tauri.

如何安装 @alwith/module-editor?

在项目目录运行 npm install @alwith/module-editor,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^19.3.1)、react-dom(^19.3.1)、lucide-react(^1.61.0)、@tauri-apps/api(^3.0.0-alpha.3)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@alwith/module-editor 支持 TypeScript 吗?

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

@alwith/module-editor 支持 ESM 还是 CommonJS?

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

@alwith/module-editor 可以商用吗?

@alwith/module-editor 使用 SEE LICENSE IN LICENSE 许可。许可条款写在包内的独立文件中,请阅读该文件确认可否商用。以上为概括,不构成法律意见,请以许可原文为准。

@alwith/module-editor 的下载量有多少?

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

@alwith/module-editor 还在维护吗?

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