/** * @rhwp/editor — HWP 에디터 웹 컴포넌트 */ export interface EditorOptions { /** rhwp-studio HTTP(S) URL. file:, data:, browser extension 등 opaque origin은 지원하지 않음 */ studioUrl?: string; /** 문서 단위 renderer 요청. 기본값은 canvas2d이며 auto/CanvasKit 명시 선택도 지원함 */ renderer?: 'auto' | 'canvas2d' | 'canvaskit'; /** iframe 너비 (기본: '100%') */ width?: string; /** iframe 높이 (기본: '100%') */ height?: string; /** 모든 method 요청 제한 시간 override(ms, 기본: 일반 10000, load/export 60000) */ requestTimeoutMs?: number; /** v1 협상 제한 시간(ms, 기본: 1000) */ handshakeTimeoutMs?: number; } export interface LoadResult { pageCount: number; } export interface HwpVerifyResult { /** 직렬화된 HWP 바이트 수 */ bytesLen: number; /** 직렬화 직전 페이지 수 */ pageCountBefore: number; /** 자기 재로드 후 페이지 수 (recovered === true 일 때 의미 있음) */ pageCountAfter: number; /** 자기 재로드 성공 여부 */ recovered: boolean; } export interface HmlSaveBlocker { code: string; xmlPath: string; message: string; preserved: false; } export interface HmlSaveState { sourceFormat: string; hmlSavable: boolean; blockers: HmlSaveBlocker[]; } export interface CanvasKitRendererDiagnostics { mode: 'default' | 'compat'; surfacePreference: 'auto' | 'webgpu' | 'webgl' | 'software'; surfaceBackend: 'default' | 'software' | null; surfaceFallbackReason: string | null; lastRenderCompleted: boolean; lastUnsupportedOps: string[]; lastExpectedUnsupportedOps: string[]; lastUnexpectedUnsupportedOps: string[]; lastRenderError: string | null; passesRuntimeReadinessGate: boolean; readinessBlockers: Array<'renderNotCompleted' | 'renderError' | 'unexpectedUnsupportedOps' | 'localFontsPending'>; hiddenCanvas2dOverlayUsed: false; lastRenderDurationMs: number | null; renderCount: number; imageCacheEntries: number; imageCacheLimit: number; imageCachePixels: number; imageCachePixelLimit: number; imageCacheHits: number; imageCacheMisses: number; imageCacheEvictions: number; localTypefaceCount: number; localTypefaceLoadFailureCount: number; localTypefacePendingCount: number; bundledTypefaceCount: number; bundledTypefaceLoadFailureCount: number; } export interface CanvasKitDocumentPreflightV1 { schemaVersion: 1; mode: 'default' | 'compat'; profile: 'fastPreview' | 'screen' | 'print' | 'highQuality'; status: 'eligible' | 'ineligible' | 'incomplete'; eligible: boolean; complete: boolean; pageCount: number; scannedPages: number; scannedWorkUnits: number; limits: { maxPages: number; maxWorkUnits: number; maxBlockers: number; maxRequiredFontFamilies: number; }; summary: { totalItems: number; directItems: number; directRequiredItems: number; compatOverlayItems: number; textFallbackItems: number; unsupportedItems: number; hiddenOverlayViolations: number; }; blockers: Array<{ pageIndex: number; code: string; opType?: string; detail?: string }>; requiredFontFamilies: string[]; capabilityDigest: string; } export interface RendererSelectionV1 { schemaVersion: 1; request: { backend: 'auto' | 'canvas2d' | 'canvaskit'; source: 'default' | 'url'; requested?: string; unsupportedReason?: string }; requestedBackend: 'auto' | 'canvas2d' | 'canvaskit'; effectiveBackend: 'canvas2d' | 'canvaskit'; selectionReason: string; fallbackReason: string | null; documentRevision: number; resourceGeneration: number; renderProfile: 'fastPreview' | 'screen' | 'print' | 'highQuality'; documentDigest: string | null; decisionKey: string; preflight: CanvasKitDocumentPreflightV1 | null; initializationError: string | null; selectionError: string | null; } export interface RendererDiagnosticsV1 { schemaVersion: 1; request: { /** Legacy v1 request snapshot. Automatic intent is exposed additively through selection. */ backend: { backend: 'canvas2d' | 'canvaskit'; source: 'default' | 'url'; requested?: string; unsupportedReason?: string }; canvaskitMode: { mode: 'default' | 'compat'; source: 'default' | 'storage' | 'url'; requested?: string; unsupportedReason?: string }; canvaskitSurface: { preference: 'auto' | 'webgpu' | 'webgl' | 'software'; requested: string; unsupportedReason?: string }; renderProfile: 'fastPreview' | 'screen' | 'print' | 'highQuality'; } | null; initialized: boolean; initializationError: string | null; effectiveBackend: 'canvas2d' | 'canvaskit' | null; backendFallbackReason: string | null; /** Added additively to renderer-diagnostics-v1; older Studio builds may omit it. */ selection?: RendererSelectionV1 | null; page: { index: number; canvaskit: CanvasKitRendererDiagnostics | null }; } export interface LoadFileOptions { /** 미저장 변경 확인 없이 문서 교체 */ skipUnsavedGuard?: boolean; /** * 로드 후 안내창(HWPX 검증, 로컬 글꼴 감지) 없이 열기. * 임베드 환경에서 안내창의 사용자 선택을 기다리느라 loadFile 응답이 * 지연/교착되는 것을 방지한다. 기본값은 true이며, 안내창을 표시하려면 * false를 명시한다. */ suppressDialogs?: boolean; } export declare class RhwpEditor { private constructor(); /** HWP 파일을 로드합니다 */ loadFile(data: ArrayBuffer | Uint8Array, fileName?: string, options?: LoadFileOptions): Promise; /** 현재 문서의 페이지 수를 반환합니다 */ pageCount(): Promise; /** 특정 페이지를 SVG 문자열로 렌더링합니다 */ getPageSvg(page?: number): Promise; /** 선택된 renderer와 페이지별 readiness 진단을 반환합니다 */ getRendererDiagnostics(page?: number): Promise; /** 현재 문서를 HWP 바이너리로 내보냅니다 */ exportHwp(): Promise; /** 현재 문서를 HWPX(ZIP+XML) 바이너리로 내보냅니다 */ exportHwpx(): Promise; /** 현재 문서를 HML(XML) 바이너리로 내보냅니다 */ exportHml(): Promise; /** 현재 문서의 HML 저장 가능 여부와 blocker를 반환합니다 */ getHmlSaveState(): Promise; /** HWP 직렬화 + 자기 재로드 검증 메타데이터 (#178) */ exportHwpVerify(): Promise; /** * 내보내기 바이트의 영속화(업로드/핸드오프) 완료를 스튜디오에 통지합니다 (#2660). * dirty 해제 + 자동복구 draft 삭제 완료 후 resolve — resolve 이후 창을 닫아도 안전. * 업로드 실패 시에는 호출하지 마세요(백업 draft 보존). * 스튜디오가 notify-saved-v1 capability를 광고하지 않으면 요청 없이 실패합니다. */ notifySaved(fileName?: string): Promise<{ ok: true; wasDirty: boolean }>; /** iframe 엘리먼트를 반환합니다 */ readonly element: HTMLIFrameElement; /** 에디터를 제거합니다 */ destroy(): void; } /** * HWP 에디터를 생성하여 지정된 컨테이너에 마운트합니다. * * @example * ```javascript * import { createEditor } from '@rhwp/editor'; * * const editor = await createEditor('#container'); * const resp = await fetch('document.hwp'); * await editor.loadFile(await resp.arrayBuffer()); * ``` */ export declare function createEditor( container: string | HTMLElement, options?: EditorOptions, ): Promise;