From a7c834a8921fc0da85fa91c2a611437fa7a631fa Mon Sep 17 00:00:00 2001 From: Otto Date: Sun, 29 Oct 2023 22:59:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8=E7=8B=AC=E7=AB=8B?= =?UTF-8?q?=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- driver/xLog.mjs | 149 ----------------------------------------- driver/xLog.ts | 175 ------------------------------------------------ nuxt.config.ts | 6 +- package.json | 5 +- pnpm-lock.yaml | 34 ++++++++-- 5 files changed, 35 insertions(+), 334 deletions(-) delete mode 100644 driver/xLog.mjs delete mode 100644 driver/xLog.ts diff --git a/driver/xLog.mjs b/driver/xLog.mjs deleted file mode 100644 index ac90d5a..0000000 --- a/driver/xLog.mjs +++ /dev/null @@ -1,149 +0,0 @@ -import { createStorage, defineDriver } from "unstorage"; -import { createIndexer } from "crossbell"; -import matter from "gray-matter"; - -const indexer = createIndexer(); - -const DRIVER_NAME = "xLog-driver"; -const LIMIT = 100; -const TAGS = "post"; -const IPFS_GATEWAY = "https://ipfs.4everland.xyz/ipfs/"; - -async function fetchFiles(options) { - const files = {}; - try { - const characterId = Number(options.characterId); - const rawRes = await indexer.note.getMany({ - characterId, - includeNestedNotes: false, - limit: LIMIT, - tags: TAGS, - }); - - const lists = rawRes.list ?? []; - // console.log(JSON.stringify(lists[0].metadata, null, 2)); - - // const res = lists.map((i) => String(i.noteId) + ".md"); - - for (let i of lists) { - files[i.noteId + ".md"] = { - meta: { - uri: i.uri ?? "", - create_time: i?.createdAt ?? "", - update_time: i?.updatedAt ?? "", - // publishedAt: i?.publishedAt ?? "", - publish_time: i.metadata?.content?.date_published ?? "", - title: i.metadata?.content?.title ?? "", - tags: i.metadata?.content?.tags ?? [], - slug: - (i.metadata?.content?.attributes ?? []).find( - (item) => item.trait_type === "xlog_slug", - )?.value ?? "", - }, - body: i.metadata?.content?.content ?? "", - }; - } - return files; - } catch (error) { - throw Error(DRIVER_NAME + " Error: Failed to fetch git tree"); - } -} - -export const xLogStorageDriver = defineDriver((opt) => { - const options = { - ...{ - ttl: 60 * 60, // cache 1h - }, - ...opt, - }; - - // 这是要实现缓存 - let files = {}; - let lastCheck = 0; - let syncPromise; - - // 这里缓存数据,多次读取不会重复请求 - const syncFiles = async () => { - if (!options.characterId) { - throw Error(DRIVER_NAME + " Error: Not set characterId"); - } - - if (lastCheck + options.ttl * 1000 > Date.now()) { - // console.log("cache"); - return; - } - - if (!syncPromise) { - syncPromise = fetchFiles(options); - } - - files = await syncPromise; - lastCheck = Date.now(); - syncPromise = undefined; - }; - - return { - name: DRIVER_NAME, - options, - async hasItem(key, _opts) { - await syncFiles(); - return key in files; - }, - async getItem(key, _opts) { - await syncFiles(); - // 可以考虑在这里转换 IPFS 为网关地址 - // 可以考虑把 meta 信息塞入 frontmatter 里 - // 解析 frontmatter - const body = files[key]?.body ?? ""; - const { data, content } = matter(body); - - // 替换 content 中的 ipfs 地址,转换为网关地址 - const processedContent = content.replace( - /ipfs:\/\/([^ \n]+)/g, - IPFS_GATEWAY + "$1", - ); - - // 将处理后的结果写入文件 - const processedFrontmatter = { - ...data, - ...files[key]?.meta, - }; - const processedMarkdown = matter.stringify( - processedContent, - processedFrontmatter, - ); - - return processedMarkdown; - }, - // async setItem(key, value, _opts) {}, - // async removeItem(key, _opts) {}, - async getKeys(base, _opts) { - await syncFiles(); - return Object.keys(files); - }, - async getMeta(key, _opts) { - await syncFiles(); - const item = files[key]; - return item ? item.meta : null; - }, - }; -}); -export default xLogStorageDriver; - -async function main() { - const storage = createStorage({ - driver: xLogStorageDriver({ - characterId: 53709, - 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(); diff --git a/driver/xLog.ts b/driver/xLog.ts deleted file mode 100644 index 0e060bf..0000000 --- a/driver/xLog.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { createStorage, defineDriver } from "unstorage"; -import { createIndexer } from "crossbell"; -import matter from "gray-matter"; - -const indexer = createIndexer(); - -const IPFS_GATEWAY = "https://ipfs.4everland.xyz/ipfs/"; - -export interface XLogStorageDriverOptions { - characterId: number; - ttl: number; -} - -interface xLogFile { - body: string; - meta: { - title: string; - slug: string; - tags: string[]; - uri: string; - create_time: string; - update_time: string; - publish_time: string; - // showPublishtime: string; // 可浏览时间,这里是给用户看的 - }; -} -interface XLogFileInfo { - [prop: string]: xLogFile; -} - -const DRIVER_NAME = "xLog-driver"; -const LIMIT = 100; -const TAGS = "post"; - -async function fetchFiles( - options: XLogStorageDriverOptions, -): Promise { - const files: XLogFileInfo = {}; - try { - const characterId = Number(options.characterId); - const rawRes = await indexer.note.getMany({ - characterId, - includeNestedNotes: false, - limit: LIMIT, - tags: TAGS, - }); - - const lists = rawRes.list ?? []; - // console.log(JSON.stringify(lists[0].metadata, null, 2)); - - // const res = lists.map((i) => String(i.noteId) + ".md"); - - for (let i of lists) { - files[i.noteId + ".md"] = { - meta: { - uri: i.uri ?? "", - create_time: i?.createdAt ?? "", - update_time: i?.updatedAt ?? "", - // publishedAt: i?.publishedAt ?? "", - publish_time: i.metadata?.content?.date_published ?? "", - title: i.metadata?.content?.title ?? "", - tags: i.metadata?.content?.tags ?? [], - slug: - ((i.metadata?.content?.attributes ?? []).find( - (item) => item.trait_type === "xlog_slug", - )?.value as string) ?? "", - }, - body: i.metadata?.content?.content ?? "", - }; - } - return files; - } catch (error) { - throw Error(DRIVER_NAME + " Error: Failed to fetch git tree"); - } -} - -export const xLogStorageDriver = defineDriver( - (opt: XLogStorageDriverOptions) => { - const options: XLogStorageDriverOptions = { - ...{ - ttl: 60 * 60, // cache 1h - }, - ...opt, - }; - - // 这是要实现缓存 - let files: XLogFileInfo = {}; - let lastCheck = 0; - let syncPromise: undefined | Promise; - - // 这里缓存数据,多次读取不会重复请求 - const syncFiles = async () => { - if (!options.characterId) { - throw Error(DRIVER_NAME + " Error: Not set characterId"); - } - - if (lastCheck + options.ttl! * 1000 > Date.now()) { - return; - } - - if (!syncPromise) { - syncPromise = fetchFiles(options); - } - - files = await syncPromise; - lastCheck = Date.now(); - syncPromise = undefined; - }; - - return { - name: DRIVER_NAME, - options, - async hasItem(key, _opts) { - await syncFiles(); - return key in files; - }, - async getItem(key: string, _opts) { - await syncFiles(); - // 可以考虑在这里转换 IPFS 为网关地址 - // 可以考虑把 meta 信息塞入 frontmatter 里 - // 解析 frontmatter - const body = files[key]?.body ?? ""; - const { data, content } = matter(body); - - // 替换 content 中的 ipfs 地址,转换为网关地址 - const processedContent = content.replace( - /ipfs:\/\/([^ \n]+)/g, - IPFS_GATEWAY + "$1", - ); - - // 将处理后的结果写入文件 - const processedFrontmatter = { - ...data, - ...files[key]?.meta, - }; - const processedMarkdown = matter.stringify( - processedContent, - processedFrontmatter, - ); - - return processedMarkdown; - }, - // async setItem(key, value, _opts) {}, - // async removeItem(key, _opts) {}, - async getKeys(base, _opts) { - await syncFiles(); - return Object.keys(files); - }, - async getMeta(key, _opts) { - await syncFiles(); - const item = files[key as keyof typeof files]; - return item ? item.meta : null; - }, - }; - }, -); -export default xLogStorageDriver; - -async function main() { - const storage = createStorage({ - driver: xLogStorageDriver({ - characterId: 53709, - 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(); diff --git a/nuxt.config.ts b/nuxt.config.ts index 1efb96d..e424804 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -3,6 +3,7 @@ import components from "unplugin-vue-components/vite"; import autoImport from "unplugin-auto-import/vite"; import { VarletUIResolver } from "unplugin-vue-components/resolvers"; import path from "path"; +// import x from 'unstorage-xlog-driver' export default defineNuxtConfig({ devtools: { enabled: true }, @@ -45,7 +46,10 @@ export default defineNuxtConfig({ }, sources: { xLog: { - driver: path.resolve(__dirname, "./driver/xLog.mjs"), + driver: path.resolve( + __dirname, + "node_modules/unstorage-xlog-driver/dist/index.mjs", + ), characterId: 53709, prefix: "/blogs", }, diff --git a/package.json b/package.json index c4b0313..cd986c6 100644 --- a/package.json +++ b/package.json @@ -30,15 +30,14 @@ "@vueuse/core": "^10.5.0", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", - "crossbell": "^1.9.0", "dayjs": "^1.11.10", - "gray-matter": "^4.0.3", "html-to-image": "^1.11.11", "lucide-vue-next": "^0.286.0", "radix-vue": "^0.4.1", "sitemap": "^7.1.1", "tailwind-merge": "^1.14.0", "tailwindcss-animate": "^1.0.7", - "trianglify": "^4.1.1" + "trianglify": "^4.1.1", + "unstorage-xlog-driver": "^0.0.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4f7fd08..458c88f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,15 +23,9 @@ dependencies: clsx: specifier: ^2.0.0 version: 2.0.0 - crossbell: - specifier: ^1.9.0 - version: 1.9.0 dayjs: specifier: ^1.11.10 version: 1.11.10 - gray-matter: - specifier: ^4.0.3 - version: 4.0.3 html-to-image: specifier: ^1.11.11 version: 1.11.11 @@ -53,6 +47,9 @@ dependencies: trianglify: specifier: ^4.1.1 version: 4.1.1 + unstorage-xlog-driver: + specifier: ^0.0.1 + version: 0.0.1 devDependencies: '@nuxt/content': @@ -9051,6 +9048,31 @@ packages: webpack-sources: 3.2.3 webpack-virtual-modules: 0.5.0 + /unstorage-xlog-driver@0.0.1: + resolution: {integrity: sha512-IbvRNYGZQ8bcrJtFD5FxYrwuki+4obWnmbz9lKNehpCgvPPbipuxKTofIP2qf2OEF+rW2oLEerWD6jE2QGR1zg==} + dependencies: + crossbell: 1.9.0 + gray-matter: 4.0.3 + unstorage: 1.9.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - idb-keyval + - supports-color + - typescript + - utf-8-validate + - zod + dev: false + /unstorage@1.9.0: resolution: {integrity: sha512-VpD8ZEYc/le8DZCrny3bnqKE4ZjioQxBRnWE+j5sGNvziPjeDlaS1NaFFHzl/kkXaO3r7UaF8MGQrs14+1B4pQ==} peerDependencies: