#!/usr/bin/env node /** * make run : sync + build tous les decks, puis VitePress dev + watch slides/ * → rebuild ciblé + sync pour refléter les sources. */ import path from 'node:path' import { fileURLToPath } from 'node:url' import { spawn, execFileSync } from 'node:child_process' import chokidar from 'chokidar' import { listPresentationSlugs } from './list-slugs.mjs' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const root = path.resolve(__dirname, '..') const slidesDir = path.join(root, 'slides') /** Aligne sync, decks et VitePress sur base=/ (ignore SITE_BASE du .env). Voir tools/site-base.mjs */ const runEnv = process.env.SKIP_PORTAL_DEV === '1' ? process.env : { ...process.env, TALKS_PORTAL_DEV: '1' } function sync() { execFileSync(process.execPath, [path.join(root, 'tools', 'sync-portal.mjs')], { stdio: 'inherit', cwd: root, env: runEnv, }) } function buildDeck(slug) { execFileSync(process.execPath, [path.join(root, 'tools', 'build-deck.mjs'), slug], { stdio: 'inherit', cwd: root, env: runEnv, }) } function buildAllDecks() { const slugs = listPresentationSlugs(root) for (const slug of slugs) buildDeck(slug) } sync() buildAllDecks() const pending = new Set() let flushTimer = null function flush() { flushTimer = null sync() for (const slug of pending) { try { buildDeck(slug) } catch { /* build-deck a déjà loggé */ } } pending.clear() } chokidar .watch(slidesDir, { ignoreInitial: true, ignored: (p) => path.basename(p).startsWith('.') || p.includes(`${path.sep}wip_`), }) .on('all', (_evt, fp) => { const rel = path.relative(slidesDir, fp) const slug = rel.split(path.sep)[0] if (!slug || slug.startsWith('wip_')) return pending.add(slug) clearTimeout(flushTimer) flushTimer = setTimeout(flush, 450) }) const vitepressBin = path.join(root, 'node_modules', '.bin', 'vitepress') const child = spawn(vitepressBin, ['dev', 'portal'], { cwd: root, stdio: 'inherit', env: runEnv, shell: process.platform === 'win32', }) function die() { try { child.kill('SIGTERM') } catch { /* ignore */ } process.exit(0) } process.on('SIGINT', die) process.on('SIGTERM', die) child.on('exit', (code) => process.exit(code ?? 0))