fix(tiptap): expose EditorOptions as runtime class for wasm-bindgen
EditorOptions was a TS interface (erased at runtime), but the Rust wasm-bindgen extern uses #[wasm_bindgen(constructor)] which generates 'new EditorOptions()' — requiring a global constructor. Vite 5/Rollup accidentally leaked the name into IIFE global scope, masking this. Vite 8/Rolldown strictly erases interfaces, exposing it as 'EditorOptions is not defined'. Fix: make EditorOptions a class (retains runtime constructor) and mount it on window, since the IIFE bundle name is taken by TiptapEditor.
This commit is contained in:
parent
368a651fa6
commit
fb31ecb5ae
@ -9,7 +9,16 @@ import { UploadCoordinator, UPLOAD_COORDINATOR_STORAGE_KEY, type UploadEvent } f
|
||||
import { UploadImage } from './upload-image'
|
||||
import './style.css'
|
||||
|
||||
export interface EditorOptions {
|
||||
/**
|
||||
* 编辑器选项。用 class 而非 interface,使其编译后保留运行时构造函数——
|
||||
* Rust 侧 wasm-bindgen 的 `#[wasm_bindgen(constructor)]` 会生成 `new EditorOptions()`,
|
||||
* 需要一个全局可访问的构造函数(interface 会被 TS 擦除)。
|
||||
* 字段全部可选,Rust 通过 setter(set_placeholder/set_on_update/...)逐个赋值。
|
||||
*
|
||||
* 不用 export(避免 IIFE 的 named export 与 default 冲突),而是挂到 globalThis,
|
||||
* 让 wasm-bindgen glue 里的裸标识符 `EditorOptions` 能解析到。
|
||||
*/
|
||||
class EditorOptions {
|
||||
content?: string
|
||||
placeholder?: string
|
||||
onUpdate?: (markdown: string) => void
|
||||
@ -24,17 +33,21 @@ export interface EditorOptions {
|
||||
onUploadEvent?: (event: UploadEvent) => void
|
||||
}
|
||||
|
||||
// wasm-bindgen 生成的 glue 用裸标识符 `new EditorOptions()` 从全局解析,
|
||||
// IIFE 的 name 只能挂一个全局(TiptapEditor),这里手动把 EditorOptions 也挂到 window 上。
|
||||
;(window as unknown as Record<string, unknown>).EditorOptions = EditorOptions
|
||||
|
||||
class TiptapEditorInstance {
|
||||
private editor: Editor | null = null
|
||||
private container: HTMLElement
|
||||
private options: EditorOptions
|
||||
// 源码模式相关状态
|
||||
|
||||
private isSourceMode = false
|
||||
private sourceTextarea: HTMLTextAreaElement | null = null
|
||||
private toggleButton: HTMLButtonElement | null = null
|
||||
private coordinator: UploadCoordinator | null = null
|
||||
|
||||
constructor(container: HTMLElement, options: EditorOptions = {}) {
|
||||
constructor(container: HTMLElement, options: EditorOptions = new EditorOptions()) {
|
||||
this.container = container
|
||||
this.options = options
|
||||
this.init()
|
||||
@ -257,7 +270,7 @@ class TiptapEditorInstance {
|
||||
const TiptapEditor = {
|
||||
_instances: new Map<string, TiptapEditorInstance>(),
|
||||
|
||||
create(containerId: string, options: EditorOptions = {}): TiptapEditorInstance | null {
|
||||
create(containerId: string, options: EditorOptions = new EditorOptions()): TiptapEditorInstance | null {
|
||||
const container = document.getElementById(containerId)
|
||||
if (!container) {
|
||||
console.error(`[TiptapEditor] Container not found: #${containerId}`)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user