ホストがページ読込み後にグローバルAPIを遅延注入する可能性には、ポーリング+イベント両構えを冗長化ガード付きで対処する
ブラウザ拡張機能や埋め込みWebView(例: チャットアプリ内蔵ブラウザ)がページに独自API(例: エージェントツール公開用のグローバルオブジェクト)を注入する設計では、その注入タイミングがページの読込み完了と必ずしも一致しない(ページ読込み後に非同期に注入されるホストが存在する)。ページ側のコードがモジュール評価時に一度だけif (!hostAPI) returnで判定していると、そのホストでは永久にno-opになる。
適用条件: 「ページ自体が能力を公開する側であり、ホストの注入タイミングを制御できない」ケースに限られる。自前で提供するグローバルAPIなら不要。
対処方法: 初回判定が失敗したら、(1) 短隔ポーリング(例: 250ms間隔・上限椖20秒)と (2) DOMContentLoaded/loadイベントリスナーの両方で再試行する。どちらか一方だけでは、ポーリング間隔と注入タイミングがたまたまタイミング良く一致しなければ検知が遅れるリスクが残るため、両構えにする。複数のトリガー(ポーリングtickとイベント)が竞合しても実際の登録処理は1回だけ実行されるよう、「登録済みフラグ」を先に立ててから実体登録を行う冗長化ガードを入れる。一定時間(上限)を超えてもAPIが現れなければ「未対応確定」の状態に確定させる。
確認方法: 自動テストでは、ページ読込み時にホストAPIを一切注入せずに通常読込みし、存在しないことを確認した上で数秒後にスクリプト実行で後付け注入し、その後ポーリング/イベントリスナーが検知して実際に登録が完了することを確認すれば、後付け注入をブラウザのaddInitScript相当の事前注入では再現できないことに注意(事前注入は常にページスクリプトより前に実行されるため、遅延注入の再現には使えない)。
教訓: 「ホストのAPIはページ読込み時点ですでに存在するはず」という仮定は、自分が実装を控制できない外部ホスト(ブラウザ拡張、アプリ内蔵WebView)では成り立たない。feature detectionの一回判定だけでなく、登録の冗長化を伴う継続監視が必要になる。