From dccb5f716c80a422d7dc581cf4be4fdfb1a10b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20=E2=80=9CAd=C3=A6dra=E2=80=9D=20Hamel?= Date: Wed, 26 Jun 2024 05:30:43 +0200 Subject: [PATCH] `then` pattern --- lib/rx-utils.ts | 54 +++++++++++++++++++------------------------ lib/tasks/articles.ts | 10 ++++---- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/lib/rx-utils.ts b/lib/rx-utils.ts index cf96dea..d079244 100644 --- a/lib/rx-utils.ts +++ b/lib/rx-utils.ts @@ -1,62 +1,56 @@ -import { Observable, from, map, mergeAll } from "rxjs"; +import { Observable, from, map } 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"; +import { existsSync } from "node:fs"; +import { writeFile, mkdir } from "node:fs/promises"; -export function src(glob: string | string[]): Observable { +export function src(glob: string | string[]): Observable> { return from(new Glob(glob, {})).pipe( map(async (path) => new File({ path, contents: await readFile(path) })), - map(from), - mergeAll(), ); } -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); +export function then(f: (v: T) => Promise) { + return (observable: Observable>): Observable> => + observable.pipe(map((v) => v.then(f))); +} - subscriber.next(value); - }, - complete() { - subscriber.complete(); - }, - }), - ); +export function dest(prefix: string) { + return async (file: File) => { + const actualPath = join(prefix, file.path); + if (!existsSync(dirname(actualPath))) { + await mkdir(dirname(actualPath), { recursive: true }); + } + await writeFile(actualPath, file.contents as Buffer); + console.log("[-] Written", actualPath); + + return file; + }; } export function synchronise() { return (observable: Observable>): Observable => new Observable((subscriber) => { - const promiseArray = []; + const runningPromises = new Set>(); let done = false; observable.subscribe({ next(value) { const promise = value.then((v) => { - const i = promiseArray.findIndex((i) => i == promise); - promiseArray.splice(i, 1); + runningPromises.delete(promise); subscriber.next(v); - if (promiseArray.length === 0 && done) { + if (runningPromises.size === 0 && done) { subscriber.complete(); } }); - promiseArray.push(promise); + runningPromises.add(promise); }, complete() { done = true; - if (promiseArray.length === 0) { - console.log("[synchronise] complete (from complete)"); + if (runningPromises.size === 0) { subscriber.complete(); } }, diff --git a/lib/tasks/articles.ts b/lib/tasks/articles.ts index 834cbfc..4e528e2 100644 --- a/lib/tasks/articles.ts +++ b/lib/tasks/articles.ts @@ -18,8 +18,8 @@ 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, lastValueFrom } from "rxjs"; -import { src, synchronise, dist } from "../rx-utils.js"; +import { lastValueFrom } from "rxjs"; +import { src, synchronise, dest, then } from "../rx-utils.js"; const Asciidoctor = asciidoctor(); const EXTENSION_REGISTRY = Asciidoctor.Extensions.create(); @@ -75,7 +75,7 @@ export async function articles(): Promise { await lastValueFrom( src("articles/**/*.asciidoc").pipe( - map(async (file) => { + then(async (file) => { const slug = basename(file.path, ".asciidoc"); const document = Asciidoctor.load(file.contents.toString(), { extension_registry: EXTENSION_REGISTRY, @@ -119,8 +119,8 @@ export async function articles(): Promise { return file; }), + then(dest("dist")), synchronise(), - dist("dist"), ), ); images.forEach(_output); @@ -133,7 +133,7 @@ export async function articles(): Promise { "og:type": "website", "og:url": `https://adaedra.eu`, }, - Content: () => renderIndex({ articles: articles }), + Content: () => renderIndex({ articles }), }); _output(