diff --git a/lib/rx-utils.ts b/lib/rx-utils.ts index c75c634..cf96dea 100644 --- a/lib/rx-utils.ts +++ b/lib/rx-utils.ts @@ -2,6 +2,8 @@ import { Observable, from, map, mergeAll } from "rxjs"; import File from "vinyl"; import { Glob } from "glob"; import { readFile } from "node:fs/promises"; +import { join, dirname } from "node:path"; +import { existsSync, mkdirSync, writeFileSync } from "node:fs"; export function src(glob: string | string[]): Observable { return from(new Glob(glob, {})).pipe( @@ -11,6 +13,27 @@ export function src(glob: string | string[]): Observable { ); } +export function dist(prefix: string) { + return (observable: Observable): Observable => + new Observable((subscriber) => + observable.subscribe({ + next(value) { + const actualPath = join(prefix, value.path); + if (!existsSync(dirname(actualPath))) { + mkdirSync(dirname(actualPath), { recursive: true }); + } + writeFileSync(actualPath, value.contents as Buffer); + console.log("[-] Written", actualPath); + + subscriber.next(value); + }, + complete() { + subscriber.complete(); + }, + }), + ); +} + export function synchronise() { return (observable: Observable>): Observable => new Observable((subscriber) => { diff --git a/lib/tasks/articles.ts b/lib/tasks/articles.ts index d224974..834cbfc 100644 --- a/lib/tasks/articles.ts +++ b/lib/tasks/articles.ts @@ -12,14 +12,14 @@ import { PRODUCTION, DEFAULT_DATE } from "../environment.js"; import rehypeExternalLinks from "rehype-external-links"; import visit from "unist-util-visit"; import renderLayout from "../views/layout.js"; -import renderArticleLayout from "../views/article.js"; +import renderArticleLayout, { Article } from "../views/article.js"; import renderIndex from "../views/index.js"; import { renderToStaticMarkup } from "preact-render-to-string"; import { SITE_TITLE, SITE_DESCRIPTION } from "../constants.js"; import { JSX } from "preact/jsx-runtime"; import { reloadAssets } from "../assets.js"; -import { map, toArray, lastValueFrom } from "rxjs"; -import { src, synchronise } from "../rx-utils.js"; +import { map, lastValueFrom } from "rxjs"; +import { src, synchronise, dist } from "../rx-utils.js"; const Asciidoctor = asciidoctor(); const EXTENSION_REGISTRY = Asciidoctor.Extensions.create(); @@ -70,9 +70,10 @@ const output = (prefix: string) => (file: File) => { export async function articles(): Promise { reloadAssets(); const _output = output("dist"); + const articles: Article[] = []; const images: File[] = []; - const articles = await lastValueFrom( + await lastValueFrom( src("articles/**/*.asciidoc").pipe( map(async (file) => { const slug = basename(file.path, ".asciidoc"); @@ -116,15 +117,12 @@ export async function articles(): Promise { file.path = join(slug, "index.html"); file.contents = renderDocument(content); - _output(file); - - return article; + return file; }), synchronise(), - toArray(), + dist("dist"), ), ); - images.forEach(_output); articles.sort(({ date: a }, { date: b }) => b.diff(a).toMillis()); @@ -135,7 +133,7 @@ export async function articles(): Promise { "og:type": "website", "og:url": `https://adaedra.eu`, }, - Content: () => renderIndex({ articles }), + Content: () => renderIndex({ articles: articles }), }); _output(