内部リンク
- [[技術の探求 xLog 1 可行性の探求]]
- [[技術の探求 xLog 2 xlog の認証の理解]]
- [[技術の探求 xLog 3 obsidian プラグインの実装]]
- [[技術の探求 xLog 4 unStorage での xLogDriver のカプセル化]]
- [[速通 - xLog の背後にある CrossBell SDK]]
- [[公式 XLOG Obsidian プラグインから学べること]]
- [[Obsidian Sync To Xlog プラグインの開発 - obsidian の画像の処理]]
- [[速通 - CrossBell のオープンソースプロジェクト]]
- [[速通 Obsidian Docs - プラグイン開発に重点を置く]]
関連
- [[unjs_unstorage]]
背景#
前の 3 つの記事に続いて、私たちは xlog の野心が現在のウェブ版ブログに満足していないと考え、より優れたヘッドレス CMS であるべきだと考えました。記事をよりスムーズに投稿するために、sync-to-xlog
プラグインを開発し、同期プロセスをより簡単にしました。
さらに展望すると、xlog の表示シナリオを拡張するために、nuxt を使用して独自のブログを作成することはできるでしょうか?このアイデアに沿って、現在の xlog の取得方法をよりシンプルにすることができると気づきました。それに加えて、自分自身に少し難易度を追加して、unjs/unstorage
を試してみることにしました。
unstorageを簡単に紹介します。これは、異なるドライバーアダプターを使用して、詳細の違いを埋めるための統一されたインターフェースを提供する汎用プラグインです。
実際の使用方法は非常に簡単で、すぐにわかります。localstorage と同じように使います。
import { createStorage } from "unstorage";
const storage = createStorage(/* opts */);
await storage.getItem("foo:bar");
await storage.hasItem()
// getItem getItems
// getItemRaw
// setItem setItems setItemRaw
// getMeta setMeta removeMeta
// getKeys
技術設計#
見た目は複雑ではありません。
まず、xLogDriver
をカスタマイズします。
対応する API を実装します。
- getItem ('site') を定義します。
- getKeys () を定義します - リストを返します。
- getItem ('slugOrID') を定義します。
const storage = createStorage({
driver: xLogStorageDriver({
token: "", // オプション
charactorID: "", // 必須
}),
});
// console.log("list", list);
const list = await storage.getKesy();
console.log("list", list);
コードの実装#
それほど難しくないようです。後で実装します。進展があれば、ここで更新します。
今回は RESTful API リクエストを使用せず、すべての操作をcrossbell.js
SDK で完了します。
実際に書いてみたけど、気持ち悪い、特にgetKeys
の戻り値がstring[]
しか受け付けないことに気づいて、やめました。数バージョン後に戻って見ることにします。
getItems
だけを実装すればいいのかもしれません?
しばらく迷った後、それでも実装しました。ソースコードはこちらに公開されています:https://github.com/Otto-J/unstorage-xlog-driver
次のように使用できます。
/* eslint-disable unicorn/prefer-top-level-await */
import { createStorage } from "unstorage";
import { xLogStorageDriver } from "unstorage-xlog-driver";
const OTTO_ID = 53_709;
async function main() {
const storage = createStorage({
driver: xLogStorageDriver({
characterId: OTTO_ID,
ttl: 60 * 60,
}),
});
// const keys = await storage.getKeys();
// console.log(keys);
const info = await storage.getItem("72.md");
// const info = await storage.getMeta("72.md");
console.log(info);
}
main();
踏み込んだ経験#
すべての API を実装する必要はありません#
最初はunstorage
を正しく理解していなかったので、すべての機能を実装する必要があると思っていましたが、後でいくつかの主要なメソッドだけを実装すればよいことに気づきました。
どのような戻り値を返すか#
getKeys
はstring[]
を返さなければなりません。実践的には、${noteID}.md
を返すことが最適だとわかりました。なぜなら、nuxt-content モジュールで次のように設定できるからです。仮想ファイルを生成し、md とローカルファイルに似たものを追加するため、より一貫性があります。
export default defineNuxtConfig({
content: {
sources: {
driver: path.resolve(
__dirname,
"node_modules/unstorage-xlog-driver/dist/index.mjs",
),
characterId: 53709,
prefix: "/blogs",
}
}
})
この神秘的な sources の設定があれば、リモートデータをローカルに取り込んで、.nuxt/content-cache/parsed/xLog/blogs
でこれらの理論上の仮想ファイルを確認できます。
ここで素晴らしいスクリーンショットがありますが、考えてみたら掲載しない方が良いです。文字化けして見栄えが悪いです。
getItem の設計はどうすればよいですか#
getItem('72.md')
は純粋なテキストのマークダウンのみを返します。これにより、スラッグや更新日時などの情報が失われます。
私は自分に合った解決策を考えました。テキストをインターセプトして、埋めたい情報を最初に frontmatter に入れることです。
理解する方法は、こちらのコードをご覧ください:https://github.com/Otto-J/unstorage-xlog-driver/blob/main/src/index.ts#L124
まず、front-matter を解析し、元のマークダウンとマージしてから返します。リモートデータは変更せず、自分で処理するだけです。
必要なキャッシュを追加する#
最初はログを出力して、何度もリクエストが発生していることに驚きました。非常に奇妙でしたが、github-driver の実装を見て、自分でキャッシュを追加できることを知りました。キャッシュを保持するためのオブジェクトマッピングテーブルを自分で管理し、有効な場合はキャッシュを読み取ることで、一定時間内にリモートデータを再リクエストする必要がありません。
何度もトリガーされて、攻撃のように思えましたが、頭を抱えて泣き笑いしました。
unjs の unbuild テンプレートを使用する#
最初はパイプラインを作成するために tsup を使用しようとしましたが、unjs には unbuild プロジェクトがあり、vitest/jiti などが付属しているテンプレートが提供されていることに気づきました。使いやすかったです。
テンプレートのリンク:https://github.com/unjs/template
vitest の単体テストも書きました。
もう一度やり直せるなら#
もう一度やり直せるなら、迷わずに書くでしょう。2 週間迷った後に書くかどうか迷いました。最初に書いて、後でやめることにしましたが、コードを削除しました。あまり多くのものはありませんが、削除するとなくなってしまいます。再度書くしかありませんので、自分のコードを尊重することにしました。本当に残したくないので、コードをブログに載せることもできます。
展望#
これで、unstorage の xLogDriver を実装しました。将来的には、どのようなレンダリング環境を使用しても、このメソッドを使用できます。