From e7ed23bb395d419fd9c31b9fe421a15f02013a9a Mon Sep 17 00:00:00 2001 From: haetae Date: Fri, 15 Aug 2025 01:23:18 -0400 Subject: [PATCH] fix classes and make fic loader more responsive in dev --- bun.lock | 28 +++-- guestbook.db | 0 package.json | 10 +- src/components/Figure.astro | 6 +- src/content/config.ts | 27 ++--- src/content/fics/test/_index.toml | 9 ++ src/content/fics/test/_index.yaml | 5 - src/content/fics/test/test.md | 2 +- src/content/fics/test/two.md | 4 +- src/content/fics/weight of living/_index.yaml | 2 +- src/layouts/About.astro | 3 +- src/layouts/Chapter.astro | 3 +- src/pages/fics/[ficId]/[chapterId].astro | 21 ++-- src/pages/fics/[ficId]/index.astro | 34 +++--- src/pages/fics/[ficId]/rss.xml.ts | 21 ++-- src/pages/fics/index.astro | 30 ++--- src/pages/index.astro | 4 +- src/pages/test.astro | 14 --- src/utils/loader.ts | 109 ++++++++++-------- 19 files changed, 167 insertions(+), 165 deletions(-) create mode 100644 guestbook.db create mode 100644 src/content/fics/test/_index.toml delete mode 100644 src/content/fics/test/_index.yaml delete mode 100644 src/pages/test.astro diff --git a/bun.lock b/bun.lock index 04b3c2a..d7038be 100644 --- a/bun.lock +++ b/bun.lock @@ -4,15 +4,17 @@ "": { "name": "astro", "dependencies": { - "@astrojs/db": "^0.16.1", + "@astrojs/db": "0.17.1", "@astrojs/mdx": "^4.3.3", - "@astrojs/node": "^9.4.0", + "@astrojs/node": "9.4.1", "@astrojs/rss": "4.0.12", - "@fujocoded/astro-dev-only": "0.0.3", - "astro": "5.12.3", + "@fujocoded/astro-dev-only": "0.0.4", + "astro": "5.13.0", "astro-breadcrumbs": "^3.3.1", "dayjs": "^1.11.13", + "dompurify": "^3.2.6", "markdown-it": "^14.1.0", + "marked": "^16.1.2", "node-html-parser": "^7.0.1", "sanitize-html": "^2.17.0", }, @@ -26,7 +28,7 @@ "packages": { "@astrojs/compiler": ["@astrojs/compiler@2.12.2", "", {}, "sha512-w2zfvhjNCkNMmMMOn5b0J8+OmUaBL1o40ipMvqcG6NRpdC+lKxmTi48DT8Xw0SzJ3AfmeFLB45zXZXtmbsjcgw=="], - "@astrojs/db": ["@astrojs/db@0.16.1", "", { "dependencies": { "@libsql/client": "^0.15.2", "deep-diff": "^1.0.2", "drizzle-orm": "^0.42.0", "kleur": "^4.1.5", "nanoid": "^5.1.5", "prompts": "^2.4.2", "yargs-parser": "^21.1.1", "zod": "^3.24.4" } }, "sha512-pBX19Rh1Ds7riQReDH6gZ5gCf1Txk03WWqMhHIkZIW7lNPnyEx5cuYtl/V9fUnXnqMrBxL9bOHkW4e937DFtWg=="], + "@astrojs/db": ["@astrojs/db@0.17.1", "", { "dependencies": { "@libsql/client": "^0.15.2", "deep-diff": "^1.0.2", "drizzle-orm": "^0.42.0", "kleur": "^4.1.5", "nanoid": "^5.1.5", "prompts": "^2.4.2", "yargs-parser": "^21.1.1", "zod": "^3.24.4" } }, "sha512-QL09xZf5Om8AshIlt+YhLDYf6M1QSzv+kfuljsPrhEXJ8U/tuKnbWs2M3wimFaLG3/fU0prFix8lWt7zU8ytfA=="], "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.7.1", "", {}, "sha512-7dwEVigz9vUWDw3nRwLQ/yH/xYovlUA0ZD86xoeKEBmkz9O6iELG1yri67PgAPW6VLL/xInA4t7H0CK6VmtkKQ=="], @@ -34,7 +36,7 @@ "@astrojs/mdx": ["@astrojs/mdx@4.3.3", "", { "dependencies": { "@astrojs/markdown-remark": "6.3.5", "@mdx-js/mdx": "^3.1.0", "acorn": "^8.14.1", "es-module-lexer": "^1.6.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "kleur": "^4.1.5", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.4", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-+9+xGP2TBXxcm84cpiq4S9JbuHOHM1fcvREfqW7VHxlUyfUQPByoJ9YYliqHkLS6BMzG+O/+o7n8nguVhuEv4w=="], - "@astrojs/node": ["@astrojs/node@9.4.0", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.1", "send": "^1.2.0", "server-destroy": "^1.0.1" }, "peerDependencies": { "astro": "^5.3.0" } }, "sha512-Gxs0iVUvOmQmK+H1DBoabcgvdSDg277SwbujRv2cUBlnpcOTJQDFRhRvyJ7G+Zkd06/jhRphsTTmmrBY0PqI4g=="], + "@astrojs/node": ["@astrojs/node@9.4.1", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.1", "send": "^1.2.0", "server-destroy": "^1.0.1" }, "peerDependencies": { "astro": "^5.3.0" } }, "sha512-lpSAQFS4IiCFGQHL/q/1CcX+AmFbma4NOoV5j7Z7Ml2wevyDe/2kAjScKIKk2DA7k/MrXSZ5ZN+IxJgpPbnAOQ=="], "@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="], @@ -106,7 +108,7 @@ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.8", "", { "os": "win32", "cpu": "x64" }, "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw=="], - "@fujocoded/astro-dev-only": ["@fujocoded/astro-dev-only@0.0.3", "", {}, "sha512-BOLYZcivrJVUA60d4R2+yEGwDJZ+3Z/zndLACxk6YpClu5ETl0adghwCCt9yIHsq79KDx/Or8LH2aqS6fVlQbg=="], + "@fujocoded/astro-dev-only": ["@fujocoded/astro-dev-only@0.0.4", "", {}, "sha512-1I/h/M5QguTjl+MxXUqwDiuLs1xUDhzQ3bzWwwhyrrZL8bhqXsHbEcuxw+AUT0RS3WTFclF7L/5wq7vw1YEXdg=="], "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], @@ -268,6 +270,8 @@ "@types/sanitize-html": ["@types/sanitize-html@2.16.0", "", { "dependencies": { "htmlparser2": "^8.0.0" } }, "sha512-l6rX1MUXje5ztPT0cAFtUayXF06DqPhRyfVXareEN5gGCFaP/iwsxIyKODr9XDhfxPpN6vXUFNfo5kZMXCxBtw=="], + "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], @@ -294,7 +298,7 @@ "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], - "astro": ["astro@5.12.3", "", { "dependencies": { "@astrojs/compiler": "^2.12.2", "@astrojs/internal-helpers": "0.6.1", "@astrojs/markdown-remark": "6.3.3", "@astrojs/telemetry": "3.3.0", "@capsizecss/unpack": "^2.4.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.1.4", "acorn": "^8.14.1", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.2.0", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^1.0.2", "cssesc": "^3.0.0", "debug": "^4.4.0", "deterministic-object-hash": "^2.0.2", "devalue": "^5.1.1", "diff": "^5.2.0", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.6.0", "esbuild": "^0.25.0", "estree-walker": "^3.0.3", "flattie": "^1.1.1", "fontace": "~0.3.0", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.1.1", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.17", "magicast": "^0.3.5", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.0", "package-manager-detector": "^1.1.0", "picomatch": "^4.0.2", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.1", "shiki": "^3.2.1", "smol-toml": "^1.3.4", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.12", "tsconfck": "^3.1.5", "ultrahtml": "^1.6.0", "unifont": "~0.5.0", "unist-util-visit": "^5.0.0", "unstorage": "^1.15.0", "vfile": "^6.0.3", "vite": "^6.3.4", "vitefu": "^1.0.6", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.1", "zod": "^3.24.2", "zod-to-json-schema": "^3.24.5", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.33.3" }, "bin": { "astro": "astro.js" } }, "sha512-fU1hNPMkccm+FuonGsY5DFkC2QyuLCju++8L2ubzBtYBDBf6bmfgmVM7A2dK+Hl+ZJCUNgepsClhBpczj+2LRw=="], + "astro": ["astro@5.13.0", "", { "dependencies": { "@astrojs/compiler": "^2.12.2", "@astrojs/internal-helpers": "0.7.1", "@astrojs/markdown-remark": "6.3.5", "@astrojs/telemetry": "3.3.0", "@capsizecss/unpack": "^2.4.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.1.4", "acorn": "^8.14.1", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.2.0", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^1.0.2", "cssesc": "^3.0.0", "debug": "^4.4.0", "deterministic-object-hash": "^2.0.2", "devalue": "^5.1.1", "diff": "^5.2.0", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.6.0", "esbuild": "^0.25.0", "estree-walker": "^3.0.3", "flattie": "^1.1.1", "fontace": "~0.3.0", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.1.1", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.17", "magicast": "^0.3.5", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.0", "package-manager-detector": "^1.1.0", "picomatch": "^4.0.2", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.1", "shiki": "^3.2.1", "smol-toml": "^1.3.4", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.12", "tsconfck": "^3.1.5", "ultrahtml": "^1.6.0", "unifont": "~0.5.0", "unist-util-visit": "^5.0.0", "unstorage": "^1.15.0", "vfile": "^6.0.3", "vite": "^6.3.4", "vitefu": "^1.0.6", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.1", "zod": "^3.24.4", "zod-to-json-schema": "^3.24.5", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.33.3" }, "bin": { "astro": "astro.js" } }, "sha512-kWahyvrrxUtgxFRRWSH5X0DESvgg4ZZ0fk6tU7blVZRgmj4PY79nzfaXFT+N+Ac2vWXX7eYUPYs1kLLk5IjBfQ=="], "astro-breadcrumbs": ["astro-breadcrumbs@3.3.1", "", { "peerDependencies": { "astro": "^2.0.0-beta.0 || ^3.0.0 || ^4.0.0 || ^5.0.0" } }, "sha512-O3wWzlc4HOU//ePefcwk2F4yQn830buVUVn6h7+sGmVq7+xvv9JmHTcmihU18ISte72ELnJlG2U8s58nIuPXfg=="], @@ -408,6 +412,8 @@ "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], + "dompurify": ["dompurify@3.2.6", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ=="], + "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], "drizzle-orm": ["drizzle-orm@0.42.0", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-pS8nNJm2kBNZwrOjTHJfdKkaU+KuUQmV/vk5D57NojDq4FG+0uAYGMulXtYT///HfgsMF0hnFFvu1ezI3OwOkg=="], @@ -570,6 +576,8 @@ "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="], + "marked": ["marked@16.1.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-rNQt5EvRinalby7zJZu/mB+BvaAY2oz3wCuCjt1RDrWNpS1Pdf9xqMOeC9Hm5adBdcV/3XZPJpG58eT+WBc0XQ=="], + "mdast-util-definitions": ["mdast-util-definitions@6.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ=="], "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="], @@ -960,10 +968,6 @@ "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "astro/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="], - - "astro/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.3", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.2.1", "smol-toml": "^1.3.4", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-DDRtD1sPvAuA7ms2btc9A7/7DApKqgLMNrE6kh5tmkfy8utD0Z738gqd3p5aViYYdUtHIyEJ1X4mCMxfCfu15w=="], - "cross-fetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], "hast-util-to-parse5/property-information": ["property-information@6.5.0", "", {}, "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="], diff --git a/guestbook.db b/guestbook.db new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json index 68fe9ad..096c8ca 100644 --- a/package.json +++ b/package.json @@ -9,15 +9,17 @@ "astro": "astro" }, "dependencies": { - "@astrojs/db": "^0.16.1", + "@astrojs/db": "0.17.1", "@astrojs/mdx": "^4.3.3", - "@astrojs/node": "^9.4.0", + "@astrojs/node": "9.4.1", "@astrojs/rss": "4.0.12", - "@fujocoded/astro-dev-only": "0.0.3", - "astro": "5.12.3", + "@fujocoded/astro-dev-only": "0.0.4", + "astro": "5.13.0", "astro-breadcrumbs": "^3.3.1", "dayjs": "^1.11.13", + "dompurify": "^3.2.6", "markdown-it": "^14.1.0", + "marked": "^16.1.2", "node-html-parser": "^7.0.1", "sanitize-html": "^2.17.0" }, diff --git a/src/components/Figure.astro b/src/components/Figure.astro index efd8452..c0239ca 100644 --- a/src/components/Figure.astro +++ b/src/components/Figure.astro @@ -5,15 +5,15 @@ interface Props { imagePath: string; alt: string; caption?: string; - class?: string | string[]; + class?: string; } -const { imagePath, alt, caption, class: className }: Props = Astro.props; +const { imagePath, alt, caption, class: className, ...rest }: Props = Astro.props; const images = import.meta.glob<{ default: ImageMetadata }>("/src/assets/**/*.{jpeg,jpg,png,webp,gif}"); const path = imagePath.startsWith("$") ? imagePath.replace("$", "/src/assets") : imagePath; if (!images[path]) throw new Error(`"${path}" does not exist in glob: "src/assets/**/*.{jpeg,jpg,png,webp,gif}"`); --- -
+
{caption &&
{caption}
}
\ No newline at end of file diff --git a/src/content/config.ts b/src/content/config.ts index 5b5d9d4..46fed3c 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -1,7 +1,8 @@ import { defineCollection, reference, z } from "astro:content"; import { glob } from "astro/loaders"; import { rssSchema } from "@astrojs/rss"; -import MarkdownIt from "markdown-it"; +// import MarkdownIt from "markdown-it"; +import { marked } from "marked"; import moods from "@/utils/moods"; import { ficsLoader } from "@/utils/loader"; @@ -19,10 +20,7 @@ function slugify(input: string) { .replace(/-+$/, ""); } -const parser = new MarkdownIt({ - html: true, - breaks: true, -}); +const parser = marked.use({ gfm: true, breaks: true, }); const blog = defineCollection({ loader: glob({ pattern: "*.{md,mdx}", base: "./src/content/blog" }), @@ -46,14 +44,13 @@ const chapters = defineCollection({ schema: z.object({ title: z.string(), publishedAt: z.coerce.date(), - notes: z.ostring().transform(notes => parser.renderInline(notes ?? "", {})), + notes: z.ostring().transform(async (notes) => await parser.parseInline(notes ?? "")), lastModified: z.coerce.date().optional(), sortOrder: z.number().default(1), - // fic: reference("fics"), }), }); -const fics = defineCollection({ +const test = defineCollection({ loader: glob({ pattern: "**/*.{yml,yaml}", base: source, @@ -66,19 +63,19 @@ const fics = defineCollection({ title: z.string(), series: z.union([z.string(), z.array(z.string())]), publishedAt: z.coerce.date(), - summary: z.string().transform(summary => parser.renderInline(summary, {})), + summary: z.string().transform(async (summary) => await parser.parseInline(summary ?? "")), characters: z.array(z.string()).optional(), ships: z.ostring(), tags: z.array(z.string()).optional(), - notes: z.ostring().transform(notes => parser.renderInline(notes ?? "", {})), + notes: z.ostring().transform(async (notes) => await parser.parseInline(notes ?? "")), lastModified: z.coerce.date().optional(), }), }); -const test = defineCollection({ +const fics = defineCollection({ loader: ficsLoader( glob({ - pattern: "**/*.{yml,yaml}", + pattern: "**/*.{yml,yaml|toml}", base: source, generateId: ({ entry, data }) => { if (data.slug) return data.slug as string; @@ -90,14 +87,14 @@ const test = defineCollection({ title: z.string(), series: z.union([z.string(), z.array(z.string())]), publishedAt: z.coerce.date(), - summary: z.string().transform(summary => parser.renderInline(summary, {})), + summary: z.string().transform(async (summary) => await parser.parseInline(summary ?? "")), characters: z.array(z.string()).optional(), ships: z.ostring(), tags: z.array(z.string()).optional(), - notes: z.ostring().transform(notes => parser.renderInline(notes ?? "", {})), + notes: z.ostring().transform(async (notes) => await parser.parseInline(notes ?? "")), lastModified: z.coerce.date().optional(), chapters: z.array(reference("chapters")).optional(), }), }); -export const collections = { blog, fics, chapters, test }; \ No newline at end of file +export const collections = { blog, fics, chapters }; \ No newline at end of file diff --git a/src/content/fics/test/_index.toml b/src/content/fics/test/_index.toml new file mode 100644 index 0000000..1faaed8 --- /dev/null +++ b/src/content/fics/test/_index.toml @@ -0,0 +1,9 @@ +title = "this is a test" +series = [ + "test", + "fandom 2" +] +publishedAt = 2022-12-22 +summary = """ + yeller + """ \ No newline at end of file diff --git a/src/content/fics/test/_index.yaml b/src/content/fics/test/_index.yaml deleted file mode 100644 index f4e60d3..0000000 --- a/src/content/fics/test/_index.yaml +++ /dev/null @@ -1,5 +0,0 @@ -title: this is a test -series: test -publishedAt: 2020-12-20T19:18:00 -summary: - yeller \ No newline at end of file diff --git a/src/content/fics/test/test.md b/src/content/fics/test/test.md index 77dff10..0c46005 100644 --- a/src/content/fics/test/test.md +++ b/src/content/fics/test/test.md @@ -1,6 +1,6 @@ --- title: ch 1 -publishedAt: 2020-12-20T19:18:00 +publishedAt: 2022-11-01 notes: i wrote this in a fugue state while listening to [Waste by Oh Wonder](https://www.youtube.com/watch?v=Ar1grAdGkec) sortOrder: 1 --- diff --git a/src/content/fics/test/two.md b/src/content/fics/test/two.md index 3c336b0..4508008 100644 --- a/src/content/fics/test/two.md +++ b/src/content/fics/test/two.md @@ -1,6 +1,6 @@ --- -title: ch 2 -publishedAt: 2020-12-20T19:18:00 +title: chapter 2 +publishedAt: 2023-12-12 notes: i wrote this in a fugue state while listening to [Waste by Oh Wonder](https://www.youtube.com/watch?v=Ar1grAdGkec) sortOrder: 2 --- diff --git a/src/content/fics/weight of living/_index.yaml b/src/content/fics/weight of living/_index.yaml index 72d6f13..f5a9ac0 100644 --- a/src/content/fics/weight of living/_index.yaml +++ b/src/content/fics/weight of living/_index.yaml @@ -4,6 +4,6 @@ publishedAt: 2020-12-20T19:18:00 summary: Sanemi survives. He learns to bear the weight of living. - -- +
MAJOR ending spoilers for the manga please don't read if you haven't finished the manga!! \ No newline at end of file diff --git a/src/layouts/About.astro b/src/layouts/About.astro index e515f89..68980b7 100644 --- a/src/layouts/About.astro +++ b/src/layouts/About.astro @@ -75,7 +75,7 @@ const { frontmatter } = Astro.props; li::marker { content: " "; } } - :global(.avatar) { + .avatar { width: fit-content; margin: 0 auto 2rem; border-image: var(--borderImage) 5 4 / 10px 8px / 8px repeat; @@ -86,7 +86,6 @@ const { frontmatter } = Astro.props; place-content: center; width: 80px; height: auto; - image-rendering: pixelated; } } \ No newline at end of file diff --git a/src/layouts/Chapter.astro b/src/layouts/Chapter.astro index f6a1927..1c35c50 100644 --- a/src/layouts/Chapter.astro +++ b/src/layouts/Chapter.astro @@ -24,7 +24,8 @@ const { title, ficTitle, date, notes, lastModified }: Props = Astro.props;
-

{title}

+

{ficTitle}

+

{title}

diff --git a/src/pages/fics/[ficId]/[chapterId].astro b/src/pages/fics/[ficId]/[chapterId].astro index 20bc3a8..b7653be 100644 --- a/src/pages/fics/[ficId]/[chapterId].astro +++ b/src/pages/fics/[ficId]/[chapterId].astro @@ -5,7 +5,10 @@ import { getCollection, render } from "astro:content"; import { Breadcrumbs } from "astro-breadcrumbs"; export const getStaticPaths = (async () => { - const chapters = await getCollection("chapters"); + const fics = await getCollection("fics"); + const chapters = await getCollection("chapters", ({ id }) => { + return fics.find(({ data }) => data.chapters?.some(chapter => chapter.id === id)); + }); return chapters.map(chapter => ({ params: { ficId: chapter.id.split("/")[0], @@ -19,12 +22,8 @@ const { ficId, chapterId } = Astro.params; const { chapter } = Astro.props; const { Content, remarkPluginFrontmatter } = await render(chapter); -const chapters = await getCollection("chapters", ({ id }) => { - return id.split("/")[0] === ficId; -}); -const fic = await getCollection("fics", ({ id }) => { - return id === ficId; -}); +const chapters = await getCollection("chapters", ({ id }) => id.split("/")[0] === ficId); +const fic = await getCollection("fics", ({ id }) => id === ficId); chapters.sort((a, b) => a.data.sortOrder - b.data.sortOrder); const current = chapters.findIndex(chapter => chapter.id === `${ficId}/${chapterId}`); const next = current + 1 === chapters.length ? undefined : chapters[current + 1]; @@ -66,12 +65,8 @@ const links = [ ))} - {previous && ( - - )} - {next && ( - - )} + {previous && } + {next && } )} diff --git a/src/pages/fics/[ficId]/index.astro b/src/pages/fics/[ficId]/index.astro index 473a5c4..54eb968 100644 --- a/src/pages/fics/[ficId]/index.astro +++ b/src/pages/fics/[ficId]/index.astro @@ -1,7 +1,9 @@ --- import type { GetStaticPaths } from "astro"; import { Font } from "astro:assets"; -import { getCollection, getEntry, render } from "astro:content"; +import { getCollection, getEntries, render } from "astro:content"; +import { marked } from "marked"; + import Layout from "@/layouts/Layout.astro"; import formatDate from "@/utils/formatDate"; import ChapterContent from "~/ChapterContent.astro"; @@ -15,21 +17,17 @@ export const getStaticPaths = (async () => { }) satisfies GetStaticPaths; const { fic } = Astro.props; -const chapters = await getCollection("chapters", ({ id }) => { - return id.startsWith(fic.id); -}); +const chapters = await getEntries(fic.data.chapters ?? []); chapters.length = Math.min(chapters.length, 5); chapters.sort((a, b) => a.data.sortOrder - b.data.sortOrder); -const oneshot = chapters.length === 1 && await getEntry(chapters[0]); -const { Content } = oneshot && await render(oneshot); +const { Content } = await render(fic); +const notes = fic.rendered && await marked.use({ async: true, gfm: true, breaks: true }).parseInline((fic.rendered.metadata!.frontmatter as any)["notes"]); --- - {oneshot && ( - - )} + {fic.body && }
@@ -39,10 +37,8 @@ const { Content } = oneshot && await render(oneshot);
Fandom
{typeof fic.data.series === "object" - ? (
    - {fic.data.series.map(fandom => (
  • {fandom}
  • ))} -
) - : (
{fic.data.series}
) + ?
    {fic.data.series.map(fandom => (
  • {fandom}
  • ))}
+ :
{fic.data.series}
}
Date
@@ -59,14 +55,12 @@ const { Content } = oneshot && await render(oneshot);
- - {!oneshot && ( + + {fic.data.chapters && (

chapters

    {chapters.map(chapter => ( @@ -76,9 +70,9 @@ const { Content } = oneshot && await render(oneshot); )} - {oneshot && ( + {fic.body && (
    - +
    diff --git a/src/pages/fics/[ficId]/rss.xml.ts b/src/pages/fics/[ficId]/rss.xml.ts index 73ea430..50f113e 100644 --- a/src/pages/fics/[ficId]/rss.xml.ts +++ b/src/pages/fics/[ficId]/rss.xml.ts @@ -1,23 +1,25 @@ import type { APIRoute } from "astro"; -import { getCollection } from "astro:content"; +import { experimental_AstroContainer as AstroContainer } from "astro/container"; +import { getCollection, render } from "astro:content"; import rss, { type RSSFeedItem } from "@astrojs/rss"; -import MarkdownIt from "markdown-it"; + +import { marked } from "marked"; import { parse as htmlParser } from "node-html-parser"; import sanitize from "sanitize-html"; import fixRssImages from "@/utils/fixRssImages"; -const parser = new MarkdownIt(); +const parser = marked.use({ gfm: true, breaks: true }); const fics = await getCollection("fics"); export const GET: APIRoute = async (context) => { - const chapters = await getCollection("chapters", ({ id }) => { - return id.split("/")[0] === context.params.ficId; - }); + const chapters = await getCollection("chapters", ({ id }) => id.split("/")[0] === context.params.ficId); const fic = fics.find(({ id }) => id === context.params.ficId); + const container = await AstroContainer.create(); const feed: RSSFeedItem[] = []; for (const entry of chapters) { - const content = parser.render(entry.body!); + const { Content } = await render(entry); + const content = await container.renderToString(Content); const html = htmlParser.parse(content); const images = html.querySelectorAll("img"); @@ -33,12 +35,11 @@ export const GET: APIRoute = async (context) => { categories: typeof fic?.data.series == "string" ? [fic?.data.series] : [...fic?.data.series!], }); } + const summary = await parser.parseInline(fic?.data.summary ?? ""); return rss({ title: `${fic?.data.title}`, - description: sanitize(parser.render(fic?.data.summary!), { - allowedTags: sanitize.defaults.allowedTags.concat(["br"]), - }), + description: sanitize(summary), site: context.site!, items: feed, }); diff --git a/src/pages/fics/index.astro b/src/pages/fics/index.astro index ccb9c60..fbe4a5c 100644 --- a/src/pages/fics/index.astro +++ b/src/pages/fics/index.astro @@ -1,14 +1,13 @@ --- -import Layout from "@/layouts/Layout.astro"; import { getCollection } from "astro:content"; -import dayjs from "dayjs"; -import utc from "dayjs/plugin/utc"; +import Layout from "@/layouts/Layout.astro"; +import formatDate from "@/utils/formatDate"; const fics = await getCollection("fics"); const chapters = await getCollection("chapters"); +fics.sort((a, b) => b.data.publishedAt.valueOf() - a.data.publishedAt.valueOf()); chapters.length = Math.min(chapters.length, 5); -chapters.sort((a, b) => a.data.publishedAt.valueOf() - b.data.publishedAt.valueOf()); -dayjs.extend(utc); +chapters.sort((a, b) => b.data.publishedAt.valueOf() - a.data.publishedAt.valueOf()); ---

    fanfics

    @@ -17,15 +16,20 @@ dayjs.extend(utc); diff --git a/src/pages/index.astro b/src/pages/index.astro index ca45331..f68dabb 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -7,7 +7,7 @@ import bulletin from "$/acnl-bulletin.png";
    -
    +

    welcome!

    @@ -16,7 +16,7 @@ import bulletin from "$/acnl-bulletin.png";
    -
    +

    update title

    diff --git a/src/pages/test.astro b/src/pages/test.astro deleted file mode 100644 index 49aefa5..0000000 --- a/src/pages/test.astro +++ /dev/null @@ -1,14 +0,0 @@ ---- -import Layout from "@/layouts/Layout.astro"; -import { getCollection } from "astro:content"; - -const fics = await getCollection("test"); ---- - - {fics.map(fic => ( -
    -

    {fic.data.title}

    -
    - ))} - -
    \ No newline at end of file diff --git a/src/utils/loader.ts b/src/utils/loader.ts index c770326..f1cbda6 100644 --- a/src/utils/loader.ts +++ b/src/utils/loader.ts @@ -14,55 +14,70 @@ async function getAllChapters(metaPath: string) { export function ficsLoader(loader: Loader) { const oldLoad = loader.load; loader.load = async (context: LoaderContext) => { - await oldLoad({ - ...context, - parseData: async (data) => data.data, + context.watcher?.on("all", async (_event, path) => { + if (path.includes("fics")) { + await resolveFics(oldLoad, context); + } }); - await Promise.all( - context.store.values().map(async (value) => { - const loadedPromise = Promise.withResolvers(); - getAllChapters(value.filePath as string).then( - async (chapters) => { - const { digest, ...valueWithoutDigest } = value; - const newData = await context.parseData({ - id: value.id, - data: { - ...valueWithoutDigest.data, - ...chapters.length > 1 && { chapters: chapters }, - }, - }); - if (chapters.length === 1) { - // i've committed unspeakable atrocities here - const search = import.meta.glob>(`../content/fics/**/*.md`, { eager: true }); - const body = Object.values(search).filter(path => path.file?.includes(chapters[0]))[0]; - context.store.set({ - ...valueWithoutDigest, - data: newData, - body: body.rawContent(), - rendered: { - html: await body.compiledContent(), - metadata: { - headings: body.getHeadings(), - frontmatter: body.frontmatter, - }, - }, - digest: context.generateDigest(newData), - }); - } else { - context.store.set({ - ...valueWithoutDigest, - data: newData, - digest: context.generateDigest(newData), - }); - } - loadedPromise.resolve(chapters); - } - ); - - return loadedPromise.promise; - }) - ); + await resolveFics(oldLoad, context); }; return loader; +} + +// please don't ask me why i did this. idk either. +async function resolveFics(loader: (oldContext: LoaderContext) => Promise, context: LoaderContext) { + await loader({ + ...context, + parseData: async (data) => data.data, + }); + await Promise.all( + context.store.values().map(async (value) => { + const loadedPromise = Promise.withResolvers(); + getAllChapters(value.filePath as string).then( + async (chapters) => { + const { digest, ...valueWithoutDigest } = value; + const newData = await context.parseData({ + id: value.id, + data: { + ...valueWithoutDigest.data, + ...chapters.length > 1 && { chapters: chapters }, + }, + }); + if (chapters.length === 1) { + // i've committed unspeakable atrocities here + const search = import.meta.glob>(`../content/fics/**/*.md`); + // const body = Object.values(search).filter(path => path.file?.includes(chapters[0]))[0]; + for (const path in search) { + if (path.includes(chapters[0])) { + const body = await search[path](); + const html = await body.compiledContent(); + context.store.set({ + ...valueWithoutDigest, + data: newData, + body: body.rawContent(), + rendered: { + html, + metadata: { + headings: body.getHeadings(), + frontmatter: body.frontmatter, + }, + }, + digest: context.generateDigest(newData), + }); + } + } + } else { + context.store.set({ + ...valueWithoutDigest, + data: newData, + digest: context.generateDigest(newData), + }); + } + loadedPromise.resolve(chapters); + } + ); + return loadedPromise.promise; + }) + ); } \ No newline at end of file