diff --git a/components.d.ts b/components.d.ts index e3fbd0e..db3fbee 100644 --- a/components.d.ts +++ b/components.d.ts @@ -9,6 +9,7 @@ declare module 'vue' { export interface GlobalComponents { AboutMe: typeof import('./src/components/presentation/about-me.vue')['default'] AppHeader: typeof import('./src/components/app-header.vue')['default'] + BlogNotes: typeof import('./src/components/notes/blog-notes.vue')['default'] BlogPosts: typeof import('./src/components/posts/blog-posts.vue')['default'] CrcCard: typeof import('./src/components/architecture/crc-card.vue')['default'] CrcProject: typeof import('./src/components/architecture/crc-project.vue')['default'] @@ -19,6 +20,7 @@ declare module 'vue' { MyProjects: typeof import('./src/components/presentation/my-projects.vue')['default'] OrderTag: typeof import('./src/components/core/order-tag.vue')['default'] ProductionFlow: typeof import('./src/components/flow/ProductionFlow.vue')['default'] + PubLayout: typeof import('./src/components/pub-layout.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] ToucanIcon: typeof import('./src/components/core/toucan-icon.vue')['default'] diff --git a/package.json b/package.json index f10661b..4f4a22a 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,9 @@ "vue-tsc": "^3.2.5" }, "dependencies": { + "@atproto/api": "^0.19.0", "chart.xkcd": "^1.1.15", + "marked": "^17.0.3", "nanoid": "^5.1.6", "pinia": "^3.0.4" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8f0a584..6668b0c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,15 @@ importers: .: dependencies: + '@atproto/api': + specifier: ^0.19.0 + version: 0.19.0 chart.xkcd: specifier: ^1.1.15 version: 1.1.15 + marked: + specifier: ^17.0.3 + version: 17.0.3 nanoid: specifier: ^5.1.6 version: 5.1.6 @@ -63,6 +69,27 @@ packages: peerDependencies: ajv: '>=8' + '@atproto/api@0.19.0': + resolution: {integrity: sha512-7u/EGgkIj4bbslGer2RMQPtMWCPvREcpH0mVagaf5om+NcPzUIZeIacWKANVv95BdMJ7jlcHS7xrkEMPmg2dFw==} + + '@atproto/common-web@0.4.17': + resolution: {integrity: sha512-sfxD8NGxyoxhxmM9EUshEFbWcJ3+JHEOZF4Quk6HsCh1UxpHBmLabT/vEsAkDWl+C/8U0ine0+c/gHyE/OZiQQ==} + + '@atproto/lex-data@0.0.12': + resolution: {integrity: sha512-aekJudcK1p6sbTqUv2bJMJBAGZaOJS0mgDclpK3U6VuBREK/au4B6ffunBFWgrDfg0Vwj2JGyEA7E51WZkJcRw==} + + '@atproto/lex-json@0.0.12': + resolution: {integrity: sha512-XlEpnWWZdDJ5BIgG25GyH+6iBfyrFL18BI5JSE6rUfMObbFMrQRaCuRLQfryRXNysVz3L3U+Qb9y8KcXbE8AcA==} + + '@atproto/lexicon@0.6.1': + resolution: {integrity: sha512-/vI1kVlY50Si+5MXpvOucelnYwb0UJ6Qto5mCp+7Q5C+Jtp+SoSykAPVvjVtTnQUH2vrKOFOwpb3C375vSKzXw==} + + '@atproto/syntax@0.4.3': + resolution: {integrity: sha512-YoZUz40YAJr5nPwvCDWgodEOlt5IftZqPJvA0JDWjuZKD8yXddTwSzXSaKQAzGOpuM+/A3uXRtPzJJqlScc+iA==} + + '@atproto/xrpc@0.7.7': + resolution: {integrity: sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA==} + '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} @@ -1394,6 +1421,9 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + await-lock@2.2.2: + resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==} + babel-plugin-polyfill-corejs2@0.4.14: resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} peerDependencies: @@ -2085,6 +2115,9 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + iso-datestring-validator@2.2.2: + resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==} + jake@10.9.4: resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} engines: {node: '>=10'} @@ -2161,6 +2194,11 @@ packages: resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} engines: {node: '>=16'} + marked@17.0.3: + resolution: {integrity: sha512-jt1v2ObpyOKR8p4XaUJVk3YWRJ5n+i4+rjQopxvV32rSndTJXvIzuUdWWIy/1pFQMkQmvTXawzDNqOH/CUmx6A==} + engines: {node: '>= 20'} + hasBin: true + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -2322,6 +2360,9 @@ packages: muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2740,6 +2781,10 @@ packages: resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} + tlds@1.261.0: + resolution: {integrity: sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==} + hasBin: true + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -2753,6 +2798,9 @@ packages: trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + type-detect@4.1.0: resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} engines: {node: '>=4'} @@ -2785,6 +2833,9 @@ packages: ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + uint8arrays@3.0.0: + resolution: {integrity: sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -2811,6 +2862,9 @@ packages: resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} engines: {node: '>=4'} + unicode-segmenter@0.14.5: + resolution: {integrity: sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g==} + unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -3107,6 +3161,9 @@ packages: zhead@2.2.4: resolution: {integrity: sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag==} + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -3125,6 +3182,53 @@ snapshots: jsonpointer: 5.0.1 leven: 3.1.0 + '@atproto/api@0.19.0': + dependencies: + '@atproto/common-web': 0.4.17 + '@atproto/lexicon': 0.6.1 + '@atproto/syntax': 0.4.3 + '@atproto/xrpc': 0.7.7 + await-lock: 2.2.2 + multiformats: 9.9.0 + tlds: 1.261.0 + zod: 3.25.76 + + '@atproto/common-web@0.4.17': + dependencies: + '@atproto/lex-data': 0.0.12 + '@atproto/lex-json': 0.0.12 + '@atproto/syntax': 0.4.3 + zod: 3.25.76 + + '@atproto/lex-data@0.0.12': + dependencies: + multiformats: 9.9.0 + tslib: 2.8.1 + uint8arrays: 3.0.0 + unicode-segmenter: 0.14.5 + + '@atproto/lex-json@0.0.12': + dependencies: + '@atproto/lex-data': 0.0.12 + tslib: 2.8.1 + + '@atproto/lexicon@0.6.1': + dependencies: + '@atproto/common-web': 0.4.17 + '@atproto/syntax': 0.4.3 + iso-datestring-validator: 2.2.2 + multiformats: 9.9.0 + zod: 3.25.76 + + '@atproto/syntax@0.4.3': + dependencies: + tslib: 2.8.1 + + '@atproto/xrpc@0.7.7': + dependencies: + '@atproto/lexicon': 0.6.1 + zod: 3.25.76 + '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -3140,10 +3244,10 @@ snapshots: '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.5 + '@babel/parser': 7.29.0 '@babel/template': 7.27.2 '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3 @@ -3155,15 +3259,15 @@ snapshots: '@babel/generator@7.28.5': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/helper-compilation-targets@7.27.2': dependencies: @@ -3209,14 +3313,14 @@ snapshots: '@babel/helper-member-expression-to-functions@7.28.5': dependencies: '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.27.1': dependencies: '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -3231,7 +3335,7 @@ snapshots: '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/helper-plugin-utils@7.27.1': {} @@ -3256,7 +3360,7 @@ snapshots: '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -3270,14 +3374,14 @@ snapshots: dependencies: '@babel/template': 7.27.2 '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helpers@7.28.4': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/parser@7.28.5': dependencies: @@ -3755,7 +3859,7 @@ snapshots: dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 esutils: 2.0.3 '@babel/runtime@7.28.4': {} @@ -3763,17 +3867,17 @@ snapshots: '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@babel/traverse@7.28.5': dependencies: '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.5 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.5 + '@babel/parser': 7.29.0 '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -4516,6 +4620,8 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + await-lock@2.2.2: {} + babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.5): dependencies: '@babel/compat-data': 7.28.5 @@ -5417,6 +5523,8 @@ snapshots: isexe@2.0.0: {} + iso-datestring-validator@2.2.2: {} + jake@10.9.4: dependencies: async: 3.2.6 @@ -5483,6 +5591,8 @@ snapshots: markdown-extensions@2.0.0: {} + marked@17.0.3: {} + math-intrinsics@1.1.0: {} mdast-util-from-markdown@2.0.2: @@ -5848,6 +5958,8 @@ snapshots: muggle-string@0.4.1: {} + multiformats@9.9.0: {} + nanoid@3.3.11: {} nanoid@5.1.6: {} @@ -6335,6 +6447,8 @@ snapshots: tinyrainbow@3.0.3: {} + tlds@1.261.0: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -6347,6 +6461,8 @@ snapshots: trough@2.2.0: {} + tslib@2.8.1: {} + type-detect@4.1.0: {} type-fest@0.16.0: {} @@ -6388,6 +6504,10 @@ snapshots: ufo@1.6.1: {} + uint8arrays@3.0.0: + dependencies: + multiformats: 9.9.0 + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -6415,6 +6535,8 @@ snapshots: unicode-property-aliases-ecmascript@2.2.0: {} + unicode-segmenter@0.14.5: {} + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -6775,4 +6897,6 @@ snapshots: zhead@2.2.4: {} + zod@3.25.76: {} + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml deleted file mode 100644 index d3a3ea9..0000000 --- a/pnpm-workspace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -onlyBuiltDependencies: - - '@parcel/watcher' - - esbuild - - vue-demi diff --git a/src/api/fetch-notes.ts b/src/api/fetch-notes.ts new file mode 100644 index 0000000..bfcb2fc --- /dev/null +++ b/src/api/fetch-notes.ts @@ -0,0 +1,38 @@ +import { AtpAgent } from "@atproto/api" +import type { Note } from "~/api/note.type" + +let serviceEndpoint: string | null = null +const did = "did:plc:4m3kouplb7s7xozjd3whinvl" + +export const getServiceEndpoint = async () => { + if (serviceEndpoint) { + return serviceEndpoint + } + const response = await fetch(`https://plc.wtf/${did}`) + const { + service: [{ serviceEndpoint: endpoint }], + } = await response.json() + + if (!endpoint) { + return null + } + + serviceEndpoint = endpoint + + return endpoint +} + +export const fetchNotes = async (): Promise => { + const endpoint = await getServiceEndpoint() + const agent = new AtpAgent({ service: endpoint }) + + const { + data: { records }, + } = await agent.com.atproto.repo.listRecords({ + repo: did, + collection: "site.standard.document", + limit: 50, + }) + + return (records || []).map((record) => record.value) +} diff --git a/src/api/note.type.ts b/src/api/note.type.ts new file mode 100644 index 0000000..7234d73 --- /dev/null +++ b/src/api/note.type.ts @@ -0,0 +1,7 @@ +export type Note = { + path: string + title: string + textContent: string + canonicalUrl: string + publishedAt: string +} diff --git a/src/app.ts b/src/app.ts index 86c513b..edd792a 100644 --- a/src/app.ts +++ b/src/app.ts @@ -11,7 +11,7 @@ export default defineApp({ link: [ { rel: "stylesheet", - href: "https://api.fonts.coollabs.io/css2?family=Noto+Serif+Display&family=Meow+Script&family=Oxygen+Mono&display=swap", + href: "https://api.fonts.coollabs.io/css2?family=Cascadia+Mono&family=Meow+Script&family=Oxygen+Mono&display=swap", }, ], } diff --git a/src/assets/base.scss b/src/assets/base.scss index bdfccc5..93db094 100644 --- a/src/assets/base.scss +++ b/src/assets/base.scss @@ -74,9 +74,9 @@ body { color: var(--color-text); background: var(--color-background); transition: color 0.5s, background-color 0.5s; - font-family: 'Noto Serif', serif; + font-family: 'Cascadia Mono', monospace; font-size: 20px; - line-height: 1.6rem; + line-height: 2.2rem; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; diff --git a/src/components/Welcome.vue b/src/components/Welcome.vue index 7383cd5..3edba0b 100644 --- a/src/components/Welcome.vue +++ b/src/components/Welcome.vue @@ -4,6 +4,8 @@
+ + diff --git a/src/components/notes/blog-notes.vue b/src/components/notes/blog-notes.vue new file mode 100644 index 0000000..c7a2b60 --- /dev/null +++ b/src/components/notes/blog-notes.vue @@ -0,0 +1,16 @@ + + + diff --git a/src/components/pub-layout.vue b/src/components/pub-layout.vue new file mode 100644 index 0000000..b398e0c --- /dev/null +++ b/src/components/pub-layout.vue @@ -0,0 +1,51 @@ + + + diff --git a/src/pages/pub/[rkey]/[slug].vue b/src/pages/pub/[rkey]/[slug].vue new file mode 100644 index 0000000..4793147 --- /dev/null +++ b/src/pages/pub/[rkey]/[slug].vue @@ -0,0 +1,51 @@ + + + + + + +