ロクヨウ's avatar
ロクヨウ
_@lokuyow.github.io
npub1a3pv...sgh3
ほぼ雑談 たまにビットコインとLN 作ったやつ おいくらサッツ https://osats.money/ 今日からビットコ https://lokuyow.github.io/btc-dca-simulator/ nostr-zap-view https://lokuyow.github.io/nostr-zap-view/ eHagaki https://lokuyow.github.io/ehagaki/
ロクヨウ's avatar
ロクヨウ 4 days ago
なんかね接続テストできるアップローダーとできないのがある
ロクヨウ's avatar
ロクヨウ 4 days ago
きってんの色も変わるようにしようかな SVGだから出来るかな
ロクヨウ's avatar
ロクヨウ 4 days ago
#eHagaki v1.27.0 ・Web Component対応 ・アクセントカラー / ベースカラーのカスタマイズ ・投稿送信中の誤操作防止 ・NIP-46でeHagakiのクライアント情報を送信 ・その他UI、不具合、安定性を改善 Web Componentでは <ehagaki-composer> を使って、eHagakiの投稿画面をWebサイトへ直接埋め込めます。 投稿内容・返信・引用の指定や各種API、イベントに対応し、アクセントカラーやベースカラーなどのCSS Custom Propertiesで埋め込み先に合わせた見た目の調整もできます。 Web Componentの認証はNIP-07 / NIP-46に対応しています。ホストページと同じ実行環境で動作するため、ローカルnsecの入力・保存には対応していません。
ロクヨウ's avatar
ロクヨウ 4 days ago
結論から言うとやで、**LumiLumiのような既に完成したNostrクライアントへ本格導入するなら、最終形は「Host-owned / 軽量Composer Web Component版」が一番きれい**だと思います。 一方で、現在のWeb Component版は「導入コストと統合感のバランス」がかなり良く、iframe版は「隔離と導入の独立性」が最大の強みです。 重要なのは、この3つは単なる表示方式の違いではないことです。 ```text iframe版 LumiLumi ⇅ postMessage [eHagakiという別アプリ] Editor + Auth + Nostr + Relay + Publish + Storage 現在のWeb Component版 LumiLumi ⇅ method / CustomEvent <ehagaki-composer> Editor + Auth + Nostr + Relay + Publish + Storage ↑ 同じWindow / window.nostr Host-owned 軽量Composer LumiLumi Auth + Sign + Relay + Publish + Storage + Nostr context ⇅ <ehagaki-composer> Editor + Preview + Media編集 + Nostr向け本文生成 ``` つまり、**3番目だけ責務の境界そのものが違います。** ## まず全体比較 | 項目 | iframe版 | 現Web Component版 | Host-owned 軽量WC | | -------------------- | ------- | --------------- | --------------- | | 導入の簡単さ | ◎ | ○ | △ | | eHagaki側の独立性 | ◎ | ◎ | △ | | ホストとのUI一体感 | △ | ◎ | ◎ | | CSS隔離 | ◎ | ◎ ShadowRoot | ◎ ShadowRoot | | JS実行環境の隔離 | ◎ | × | × | | 秘密情報の隔離 | ◎ | △ | ○〜◎ | | `postMessage` | 必要 | 不要 | 不要 | | ホストのNostr処理との重複 | 多い | 多い | **ほぼなし** | | Relay管理の一元化 | △ | △ | **◎** | | Signer管理の一元化 | ○ | △ | **◎** | | 投稿処理の一元化 | △ | △ | **◎** | | ホスト独自tag処理 | やや面倒 | やや面倒 | **容易** | | ホストの投稿状態との同期 | 面倒 | 比較的容易 | **自然** | | モバイルfocus/keyboard統合 | △ | ◎ | ◎ | | eHagaki単体で完結 | **◎** | **◎** | × | | 汎用埋め込み配布 | **◎** | ◎ | ○ | | LumiLumiとの相性 | ○ | ◎ | **◎◎** | --- # 1. iframe版 これは一番「**eHagakiを別アプリとしてそのまま貸す**」方式です。 現在のiframe版は、単に画面を埋め込むだけではなく、親から設定・reply/quote/channel/contentを与えたり、親側signerへ認証を委譲したり、storageを親へ委譲したりできます。かなり高度な統合まですでに可能です。 ### メリット 最大のメリットは**隔離**です。 eHagakiは別document・別Window realmで動くので、LumiLumi側のCSSやJSとかなり明確に分離できます。eHagakiを `lokuyow.github.io` から配信したまま使うこともでき、eHagakiだけ更新することも容易です。 さらに、秘密情報についてもorigin境界を作れます。これは現在のWeb Component版にはない大きな特徴です。eHagaki自身のWeb Componentガイドでも、ホストJavaScriptから秘密情報を隔離したい場合はiframe版を使うよう明示しています。 したがって、 > 「自分のアプリに、第三者製のeHagakiをなるべく信用境界を保ったまま入れたい」 という一般公開の埋め込み方式としては、iframeはかなり良いです。 ### デメリット 問題は、**LumiLumiの中にもう一つNostrアプリがいる感じになる**ことです。 LumiLumiとeHagakiの間で、 * 現在のユーザー * signer * reply/quote context * relay * 設定 * storage * 投稿結果 などをbridgeしなければなりません。 さらにiframeなので、focus、IME、スマホキーボード、高さ、scroll、dialog、clipboard、drag & dropなども「別document」という境界が付いて回ります。 ローカルrelayについてもiframeではLocal Network Accessの許可が絡むケースがあり、現在の公開ガイドにも専用の `allow` 設定があります。 **LumiLumiの投稿欄を完全に置き換える用途では、ちょっと大げさです。** --- # 2. 現在のWeb Component版 これはiframeのかなりの問題を消した、 > **「eHagakiという完成したComposerアプリを、同じページ内へ直接置く」** 方式です。 現在のeHagaki Web Componentは同じWindow realmで動作し、`postMessage` ではなく普通のメソッドとCustomEventでホストと連携します。UI自体はShadowRootで隔離されています。 ### メリット LumiLumiへの組み込みはiframeより圧倒的に自然です。 `<ehagaki-composer>` を置いて、 * `whenReady()` * `setContext()` * `setSettings()` * CustomEvent などで操作できます。 現在のAPIもiframe側のComposer Context型を再利用しており、reply/quote/content等の概念を共通化しています。 CSSについてもShadowRootなので、LumiLumiがTailwindを使っていてもeHagaki内部へ直接侵入しません。テーマについてはCSS Custom Propertiesを公開する方式なので、iframeよりはるかにLumiLumiらしい見た目にできます。 モバイルでも同一documentなので、 > LumiLumiのモーダルの中にeHagakiを置く といった構成はiframeより自然です。 ### ただし大きな問題 **Nostrクライアントとしての責務は、まだeHagaki側にかなり残っています。** 現在のWeb Componentにはhost signer callback APIはありません。NIP-07ならホストと同じ `window.nostr` をeHagakiが直接利用し、NIP-46ならeHagaki自身のUI・処理を使います。さらにeHagaki自身が専用localStorage namespaceや`eHagakiDB`を持ちます。 つまりLumiLumi内では、 ```text LumiLumi ├─ アカウント ├─ relay ├─ 投稿処理 ├─ NIP-07 ├─ メディアアップロード ├─ 設定 └─ storage eHagaki ├─ アカウント ├─ relay ├─ 投稿処理 ├─ NIP-07 / NIP-46 ├─ メディアアップロード ├─ 設定 └─ storage ``` という**二重構造**になりやすい。 もちろん同じNIP-07を見れば同じアカウントにはできます。しかし、 > 「同じユーザーで署名できる」 ことと、 > 「一つのNostrクライアントとして状態が統合されている」 ことは別です。 ここが現在版の一番大きな限界だと思います。 --- # 3. Host-owned / 軽量Composer Web Component版 これは、 > **eHagakiから「Nostrクライアント」の責務を外し、「高機能Nostr投稿エディター」にする** 方式です。 LumiLumiの場合、かなり理にかなっています。 実際、現在のLumiLumiはすでに投稿Composerを持っていて、`CreatePost.svelte` が本文・tags・カスタム絵文字・メディアupload等を処理し、最終的に `onSendEvent()` へ `text` と `tags` を渡す構造になっています。 さらにその上位の`OpenPostWindow.svelte`では、 * NIP-07ユーザー取得 * `nip07Signer()` による署名 * protected event tag * client tag * 投稿 * relayへのpublish * 投稿失敗処理 をLumiLumi自身が行っています。 つまりLumiLumiには、**eHagakiに任せる必要がないNostrクライアント機能がすでに揃っています。** 依存関係にも `rx-nostr`、`nostr-tools`、`@konemono/nostr-login` 等があり、Svelte 5ベースの完全なNostrアプリです。 なので理想形は、 ```text LumiLumi │ │ context ▼ ┌─────────────────────┐ │ eHagaki Composer │ │ │ │ WYSIWYG editor │ │ emoji │ │ media UI │ │ quote/reply preview │ │ content → Nostr表現 │ └──────────┬──────────┘ │ │ composition ▼ LumiLumi ↓ event構築 ↓ sign ↓ relay publish ``` です。 ## この方式の最大のメリット **「投稿する」という責務が1か所になります。** 例えばLumiLumiが、 ```text kind content tags ``` を受け取れば、その後は全部LumiLumi。 eHagakiは秘密鍵もsignerも知る必要がない。 relay一覧も知らなくてよい。 「投稿成功」と判定するrelay数も知らなくてよい。 NIP-07/NIP-46も知らなくてよい。 client tagもLumiLumiが付ける。 LumiLumi独自のprotected event処理もLumiLumi側。 これはかなり綺麗です。 --- # セキュリティ面でも3番が面白い iframeには**実行環境そのものの隔離**があります。これは最強です。 Host-owned Web Componentにはそれはありません。eHagaki JavaScriptはLumiLumiと同じrealmで動きます。 しかし、**eHagakiへ与える権限をかなり減らせます。** 現在版ならeHagaki自身が、 ```text window.nostr relay storage NIP-46 session ``` などを扱います。 Host-ownedなら、 ```text LumiLumi → eHagaki 「この投稿を編集して」 eHagaki → LumiLumi 「contentとtagsはこれ」 ``` だけに近づけられる。 つまり、 **iframe = 強い技術的隔離** に対して、 **Host-owned = 最小権限化** という別方向の安全性があります。 --- # MediaもHost-ownedの方がLumiLumiには合いそう ここは少し特殊です。 eHagakiの魅力には画像・動画を直接編集できることも含まれるので、upload機能そのものを全部ホストへ追い出してしまうとeHagakiの価値を削ってしまいます。 一方、LumiLumiにはすでにUploader選択と`filesUpload()`があります。 なので軽量版では、 ```text eHagaki ↓ host.upload(file) ↓ LumiLumiの既存Uploader ↓ URL / metadata ↓ eHagakiがエディターへ挿入 ``` という**Upload AdapterだけHost-owned**にするのがかなり良さそうです。 これなら、 * eHagakiが画像編集UIを所有 * LumiLumiがアップロード先設定を所有 * 同じファイルをLumiLumiとeHagakiで別々に設定しなくていい となります。 --- # Custom Emojiも似ています LumiLumiはすでにCustom Emojiを扱っています。現在のComposerにもemoji storeやemoji tag生成処理があります。 eHagakiにもCustom Emoji管理があります。 ここを何も考えず統合すると、 ```text LumiLumiの絵文字一覧 eHagakiの絵文字一覧 ``` ができてしまいます。 Host-owned版なら例えば、 ```text composer.setCustomEmojis(...) ``` のように**ホストの絵文字データをComposerへ渡す**設計にできます。 ユーザーからすると「LumiLumiで設定した絵文字が、そのままeHagakiの絵文字ピッカーに出る」。 こっちの方が自然です。 --- # 一方、Host-owned版にもかなり明確なデメリットがあります 最大の欠点は、 **API設計が難しいこと**です。 現在版は簡単です。 > eHagakiに「投稿して」と言えばeHagakiが投稿する。 Host-ownedにすると、 > 「eHagakiはどこまでeventを作るのか?」 を決めなければなりません。 例えば、 ```text content emoji tags imeta e tags p tags q tags reply markers kind subject content-warning ``` このうち誰が何を作るか。 全部ホストに任せると、eHagakiがただのTiptap UIになってしまいます。 逆に全部eHagakiが作れば、今度はHost-ownedの意味が薄れます。 ここはおそらく、 ### eHagakiが所有 * WYSIWYG編集状態 * content serialization * editor内の画像・動画 * emoji * editorから必然的に生まれるtags * quote/reply表示 * 投稿Preview ### Hostが所有 * 現在のアカウント * signer * relay * publish * アプリ固有tag * Nostrセッション * 投稿成功/失敗 * draft保存方針 * uploaderの実体 * アプリ設定 という線がよさそうです。 そしてreply/quote tagsの最終生成をどちらに置くかは、もう少し慎重に設計した方がいい領域です。 --- # LumiLumiならどうするか 私なら優先順位はこうします。 | 順位 | 方式 | 用途 | | ----- | ------------------- | ------------------- | | **1** | **Host-owned 軽量WC** | LumiLumiへ正式統合 | | **2** | 現在のWeb Component | とりあえずeHagakiを導入、PoC | | **3** | iframe | 外部サービスとして疎結合に導入 | LumiLumiの場合、現在の投稿処理を見る限り、特にHost-ownedとの相性がいいです。 今のLumiLumiはすでに、 ```text CreatePost ↓ {text, tags, ...} ↓ OpenPostWindow ↓ contentCheck ↓ LumiLumi固有tags ↓ signEvent ↓ promisePublishSignedEvent ``` という境界があります。 だから極端に言えば、 ```text CreatePost.svelte ``` の役割を ```text <ehagaki-composer> ``` へ置き換え、**その後ろのLumiLumi処理を残す**方向が自然です。 これはかなり良い適用例です。 --- ## ただし、現在版Web Componentを捨てる必要はない むしろ私は**2種類残した方がいい**と思います。 ```text <ehagaki-composer> Full Composer <ehagaki-composer-lite> Host-owned Composer ``` のように別Custom Elementにする必要があるかどうかはまだ検討余地がありますが、概念としては、 **Full Composer** > 「eHagakiをあなたのサイトで使ってください」 **Host-owned Composer** > 「あなたのNostrクライアントの投稿エディターとしてeHagakiを使ってください」 という二つの製品用途があります。 そしてiframeは、 > 「実行環境まで分離したい人向け」 として残す。 すると3方式は競合せず、 ```text 簡単・隔離 iframe ↓ 深いUI統合 Full WC ↓ 深いNostr統合 Host-owned WC ``` という綺麗な段階になります。 **LumiLumiは一番下まで行く価値があるタイプのホスト**です。 逆に、ブログや一般Webアプリへ「Nostr投稿機能だけ付けたい」ならFull Web Component、eHagaki側の更新を完全に独立させたい・強く隔離したいならiframeの方が合理的です。 なのでHost-owned版は「現在版の上位互換」ではなく、**Nostrクライアントへ組み込むための別の責務境界**として考えるのが一番よいと思いますやで。
ロクヨウ's avatar
ロクヨウ 4 days ago
AIに聞いたら最終的には次やる予定のHost-owned軽量Web Componentを入れた方いいけど、私次第だからどうかな?って言われた
ロクヨウ's avatar
ロクヨウ 4 days ago
GitHubのaboutのtopicsにnostrを入れたらいい気がする
ロクヨウ's avatar
ロクヨウ 4 days ago
信じてくれ 殺し以外はやったことない
ロクヨウ's avatar
ロクヨウ 4 days ago
いやまぁ別にiframe版でもいい気がする
ロクヨウ's avatar
ロクヨウ 4 days ago
来週またここに来てください 本物のeHagakiをご覧に入れますよ
ロクヨウ's avatar
ロクヨウ 4 days ago
今eHagakiからアカウントと署名機能を取り除いた版のWebコンポーネントを作ろうとしてる
ロクヨウ's avatar
ロクヨウ 4 days ago
でもiframe版はiOSで埋め込まれeHagakiのデータを保存できないからだるい
ロクヨウ's avatar
ロクヨウ 4 days ago
でもなんかWebコンポーネントってコンポーネントを信頼しないと入れちゃだめらしい eHagakiに悪意があれば親側の色々を色々できちゃうらしい