Skip to content

iframe 임베드 시 loadFile race condition — 'ready' ping 응답 후 wasm 미초기화 상태에서 호출되어 __wbindgen_malloc undefined 또는 timeout 발생 #522

@svrforum

Description

@svrforum

환경

  • rhwp-studio v0.7.9 (npm @rhwp/editor 0.7.9 wrapper 또는 직접 iframe 임베드)
  • 부모 페이지: 외부 React/Vite 앱
  • 브라우저: Chromium 기반

증상

부모 페이지에서 @rhwp/editorcreateEditor()editor.loadFile(buffer, fileName) 호출 시 두 가지 패턴으로 실패:

  1. 즉시 실패: Cannot read properties of undefined (reading '__wbindgen_malloc')
  2. 타임아웃: Request timeout: loadFile (10초 후 — @rhwp/editor 내부 default)

이 두 패턴은 iframe 페이지의 wasm-bindgen 초기화 완료 시점에 따라 무작위로 발생합니다.

분석

rhwp-studio/src/main.ts 코드 흐름:

async function initialize(): Promise<void> {
  msg.textContent = '웹폰트 로딩 중...'
  await loadWebFonts([])
  msg.textContent = 'WASM 로딩 중...'
  await wasm.initialize()             // ← 시간 소요 (5-15초)
  msg.textContent = 'HWP 파일을 선택해주세요.'
  // ... 후속 setup
}
initialize()                           // 비동기 시작

// 파일 끝에서 message 핸들러 즉시 등록 (initialize 완료 대기 X)
window.addEventListener('message', async (e) => {
  ...
  case 'ready':
    reply(true)                        // ← wasm 상태 무관, 항상 true
  case 'loadFile':
    const docInfo = wasm.loadDocument(bytes, ...)  // ← wasm 미초기화 시 throw
})

문제:

  • message 핸들러는 initialize() 완료 전에 등록됨 (script tail at module top-level)
  • 'ready' 응답은 단순히 reply(true) 라 wasm 상태와 무관하게 즉시 반환
  • 따라서 _waitReady() (@rhwp/editor wrapper) 가 통과한 후 곧바로 loadFile 을 보내면, 그 시점에 wasm-bindgen exports 가 아직 바인딩 안 되어 있어 wasm.loadDocument()__wbindgen_malloc undefined 로 throw
  • wasm.initialize() 가 throw 하지 않고 hang 하면 이후 loadFile 메시지가 처리 큐에서 대기하다 우리 측 timeout (10초) 으로 reject

재현

import { createEditor } from '@rhwp/editor';
const editor = await createEditor('#container', { studioUrl: 'https://edwardkim.github.io/rhwp/' });
const buffer = await fetch('/sample.hwp').then(r => r.arrayBuffer());
await editor.loadFile(buffer, 'sample.hwp');
// → throws "Cannot read properties of undefined (reading '__wbindgen_malloc')"
//   or "Request timeout: loadFile"

@rhwp/editor wrapper 의 _waitReady() 가 wasm 미준비 상태에서 통과하기 때문에 외부에서 retry 만으로는 해결이 어렵습니다 (timeout 이 길어도 wasm 초기화 완료 시점을 알 수 없음).

제안

'ready' 응답을 wasm 초기화 완료 후로 지연:

// main.ts
const wasmReadyPromise = (async () => {
  await loadWebFonts([])
  await wasm.initialize()
})()

window.addEventListener('message', async (e) => {
  ...
  case 'ready':
    await wasmReadyPromise            // ← wasm 준비 대기 후 응답
    reply(true)
})

또는 별도 메서드 추가:

  • 'isWasmReady' — wasm.initialize() 완료 시 true 응답
  • @rhwp/editor wrapper 의 _waitReady() 가 이 메서드를 polling

참고

좋은 라이브러리 개발 감사드리며, 이슈 검토 부탁드립니다.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions