Core API
@imposia/core が提供する、フレームワーク非依存のページ文書と Publication のコントローラーです。
@imposia/core はページ文書の本体となるランタイムです。ページ分割、ライフサイクル、リゾルバー境界、拡張機能、印刷、書き出しを React なしで提供します。ここにあるものは、すべてブラウザー内でのみ動作します。
Core のページ文書
mountPageDocument
mountPageDocument(
container: HTMLElement,
source: PageSource,
options?: PageDocumentOptions,
): PageDocumentController;この関数はただちに canonical iframe を 1 つ追加し、ステージング世代を開始して、同期的に返ります。最初の文書を読む前に ready を待ってください。
const controller = mountPageDocument(host, { html: "<article><h1>こんにちは</h1></article>" });
const pageDocument = await controller.ready;PageSource は { html: string; baseUrl?: string } または { lightDom: Element | DocumentFragment; baseUrl?: string } です。
PageDocumentOptions のフィールド | 型と役割 |
|---|---|
css | readonly string[]。追加のソース CSS です。 |
assetResolver | フォント、画像、メディア、スタイルシート要求のための非同期リゾルバーです。 |
page | { size?, orientation?, margin? }。size は A3、A4、A5、B4、B5、Letter、Legal、Ledger、または任意の幅・高さを受け取ります。 |
limits | 入力、ノード、アセット、期限、ページ、レイアウトパス、生成出力の上限です(任意)。 |
headerTemplate、footerTemplate | 装飾マークアップです。 |
decorateBlankPages | 空白ページにも装飾を適用するかどうかです。 |
experimental | { footnotes?: boolean; pageFloats?: boolean }。どちらも実験的機能で、制限の外では FOOTNOTE_DEFERRED または PAGE_FLOAT_FALLBACK 警告とともにフォールバックします。 |
extensions | 順序付きの PageExtension または PublicationExtension 値です。 |
compose | { yieldBudgetMs?: number; scheduler?: () => Promise<void> }。メインスレッド上の協調的なページ分割で、既定の実行予算は 8 ms です。Infinity でスケジューラーへの移譲を無効にします。 |
signal | 初回の世代を中止します。 |
onProgress | ステージングがページを割り当てるたび、パス内の { completedPages, pass, provisional: true } を受け取ります。後続の収束パスでカウントはリセットされます。 |
スケジューラー、フォント、画像の待機は、実時間で測る limits.resourceDeadlineMs に計上されます。進捗は暫定的なステージング作業を表します。最新の確定済み世代は controller.current からだけ読み取ってください。
AssetResolver は { url, kind, baseUrl, signal } を受け取り、{ status: "resolved", bytes, mimeType, resolvedUrl? } または { status: "blocked", reason? } に解決されます。実装方法は画像とフォントを読み込むで説明しています。
拡張機能
PageExtension と PublicationExtension は、同期メソッド finalizePage(page, context) も実装できます。このフックは、Core が装飾と margin box を解決した後、確定の前に、受理された各ページに対して 1 回実行されます。このとき page.element は計測可能な実体のあるページ要素です。page.tableFragments には、分割されて続くテーブル片が、元のテーブルと 1 から始まる継続インデックスとともに入ります。加えた変更は確定後の iframe に残ります。フックは decorateBlankPages の設定にかかわらず、意図的に挿入された空白ページを含むすべての割り当て済みページで実行されます。
finalizePage は undefined を返さなければなりません
finalizePage が undefined 以外の値を返すと、その世代全体が reject されます。このフックは実体のあるページ要素を書き換えることで結果を伝えます。置き換えを返す仕組みではありません。
分割されたテーブルの継続片に、計測済みのピクセル列幅を固定したい場合は、明示的に有効化する拡張機能として createTableColgroupExtension() を使ってください。Core はソースの <colgroup> 要素を常に引き継ぎますが、既定で列幅を合成することはありません。
PageDocumentController
| メンバー | 戻り値 | 準備状態とエラー |
|---|---|---|
ready | Promise<PageDocument> | 最初の確定です。確定できない場合は reject されます。 |
current | PageDocument | undefined | 更新の失敗中・失敗後も前回の確定が残ります。破棄でクリアされます。 |
update(source, options?) | Promise<PageDocument> | 世代を開始します。より新しい update は進行中の世代を中止します。options.signal を指定できます。 |
print() | Promise<void> | 最新の処理を待ってから、隔離されたトップレベル文書スナップショットで直近の確定を印刷します。確定がない場合と破棄後は reject されます。 |
destroy() | Promise<void> | 世代と書き出しの処理を中止し、iframe を取り除き、リソースを解放し、追跡中の処理を待ちます。何度でも呼べます。 |
PageDocument
| メンバー | 型・戻り値 | 意味 |
|---|---|---|
iframe | HTMLIFrameElement | Core が所有する canonical フレームです。 |
generation、pageCount | number | 確定番号とページ数です。 |
pages | readonly PageMetadata[] | ページ番号、左右、名前、空白かどうか、ジオメトリ、寸法、本文テキストです。 |
warnings | readonly PageWarning[] | 現在の世代の診断です。 |
timings | { totalMs; resourceMs; paginationMs } | 世代のミリ秒単位の所要時間です。 |
exportEpub(options) | Promise<Blob> | 進行中の最新処理を待ち、最後に確定した意味構造を保つソースをリフロー型 EPUB 3.3 Blob として書き出します。 |
EPUB のオプションは metadata: { title, language, identifier, modified? } が必須で、任意で signal と { maxEntries?, maxBytes? } の上限を指定できます。書き出しは意味構造ベースです。ページのラッパー、余白の装飾、生成されたカウンター、ページ限定の実験的な出力は含まれません。
警告
確定されたすべての PageWarning は、code、message、そして generation、entryId、page(それぞれ不明なら undefined)を持つ凍結された location を運びます。拡張機能の診断は名前空間付きの EXTENSION_${string} コードを使い、extension に拡張機能名を示します。
Core ユーティリティ
prepareDocument(html: string, options?: PrepareDocumentOptions): PreparedDocument;
pageWarningTargetBounds(document: PageDocument, warning: PageWarning): PageWarningTargetBounds | undefined;
hasPageDocumentFrameSandbox(iframe: HTMLIFrameElement): boolean;
committedFrameGeneration(frameDocument: Document): number | undefined;
selectBlankMarkers(markers: PageSideConstraint[], pages: Map<number, number>): number[];prepareDocumentは HTML を同期的に正規化・サニタイズし、{ html, headerTemplate?, footerTemplate?, warnings }を返します。オプションはheaderTemplate、footerTemplate、allowRemoteResourcesです。API の装飾オプションは、埋め込みテンプレートより優先されます。ブラウザーのネイティブ HTML パーサーで解析するため、他のすべての Core API と同じくブラウザー専用で、警告はエラー回復後の文書順に並びます。pageWarningTargetBoundsは、iframe ビューポート座標での実測の{ left, top, width, height }を返します。別の世代の警告や、位置を特定できない警告にはundefinedを返します。hasPageDocumentFrameSandboxは、sandbox トークンが公開されたトークンの集合(allow-same-originとallow-modals)と正確に一致する場合だけtrueです。committedFrameGenerationは、Core がコミット時に canonical frame へ刻んだ世代を返します。スタンプされた世代をまだコミットしていないフレームではundefinedです。まだ配達されていない新しいコミットと、実際の破損とを区別するために使います。ページマーカーの読み取りや検証は行いません。selectBlankMarkersは、左右のページの偶奇を満たすために空白ページが必要なマーカー ID を、先行する選択も踏まえて返します。ページ対応のないマーカーには例外をスローします。
Core の Publication
mountPublication
mountPublication(
container: HTMLElement,
snapshot: PublicationSnapshot,
options?: PublicationOptions,
): PublicationController;順序付きのエントリーを 1 つのページ列に構成し、同期的に返ります。不正なスナップショットや Publication 拡張は、マウント中に例外をスローすることがあります。
const controller = mountPublication(host, {
metadata: { title: "ハンドブック", language: "ja" },
entries: [
{ id: "cover", title: "表紙", html: "<h1>ハンドブック</h1>" },
{ id: "start", title: "はじめに", html: "<h1>はじめに</h1><p>最初の一歩。</p>" },
],
});
const publication = await controller.ready;PublicationSnapshot は metadata: { title, language?, identifier? } と、順序付きのエントリーを持ちます。各エントリーには、空白と制御文字を含まない一意の id、title、任意の baseUrl、そして html または lightDom のどちらか一方だけが必要です。PublicationOptions は PageDocumentOptions と同じですが、extensions だけは PublicationExtension[] のみを受け取り、pageNumbering が加わります。pageNumbering: "entry" を指定すると、各エントリーは新しいページから始まり、counter(page)、counter(pages)、pageNumber/totalPages テンプレートトークンはエントリーの中で数えます。請求書をまとめて印刷しても、各請求書に「Page 1 of 2」のように入ります。ページメタデータ、移動、検索、エントリーのページ範囲、拡張の decoratePage 入力、target 参照は全体の番号のままです。既定値の "publication" は Publication 全体に番号を振ります。
PublicationController
| メンバー | 戻り値 | 準備状態とエラー |
|---|---|---|
ready | Promise<PublicationDocument> | 最初に確定した Publication です。 |
current | PublicationDocument | undefined | 現在の確定です。 |
resolveDestination(id) | PublicationDestination | undefined | 現在の世代で、アウトラインまたは検索の ID を解決します。 |
search(query) | readonly PublicationSearchResult[] | 確定前は空です。それ以降は現在の索引を検索します。 |
navigate(destination) | void | 完全な移動先が現在の世代と一致し、そこに存在する場合以外は例外をスローします。 |
update(snapshot, options?) | Promise<PublicationDocument> | 完全なスナップショットを検証してステージングします。options.signal を指定できます。 |
print() | Promise<void> | ページコントローラーと同じ、直近の確定を印刷する動作です。 |
destroy() | Promise<void> | 下層のページと Publication のリソースを破棄します。 |
PublicationDocument は PageDocument を拡張し、確定済みの metadata、entries、入れ子の outline を持ちます。各エントリーは閉区間のグローバル pageRange を持ちます。PublicationDestination は { id, entryId, page, generation } で、世代に束縛されます。古い値を渡すと、navigate は型付きの ImposiaError(STALE_PUBLICATION_DESTINATION)をスローします。検索結果は { entry, page, excerpt, destination } です。