← back to Dw Marketing Reels
scripts/sync-reels.mjs
51 lines
#!/usr/bin/env node
/**
* sync-reels.mjs — single-source-of-truth guard for the flip-book pipeline.
*
* WHY: the studio serves the public video from `reels/<slug>-flipbook.mp4`, but
* `build-page.mjs` only COPIES the render into `reels/` once, at page-build time.
* Any RE-RENDER after that writes to `flipbooks/<slug>/renders/<slug>-flipbook.mp4`
* and silently leaves `reels/` (the served file) stale — so the live page shows an
* old cut while "deploy OK" reports success. (Hit live on Majilite Metallics,
* 2026-08-10, TK-10413.)
*
* FIX: run this as the project's PREDEPLOY_HOOK. Before every deploy it copies each
* render into `reels/` whenever the render is newer or differs in size, so the
* served file can never lag the freshest render again. It only SYNCS (never gates);
* it exits non-zero only on a real IO failure.
*/
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const PROJ = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const flipbooks = path.join(PROJ, 'flipbooks');
const reelsDir = path.join(PROJ, 'reels');
fs.mkdirSync(reelsDir, { recursive: true });
let synced = 0, checked = 0;
try {
const slugs = fs.existsSync(flipbooks)
? fs.readdirSync(flipbooks, { withFileTypes: true }).filter(d => d.isDirectory()).map(d => d.name)
: [];
for (const slug of slugs) {
const render = path.join(flipbooks, slug, 'renders', `${slug}-flipbook.mp4`);
if (!fs.existsSync(render)) continue; // no render for this slug — skip
checked++;
const served = path.join(reelsDir, `${slug}-flipbook.mp4`);
const src = fs.statSync(render);
const cur = fs.existsSync(served) ? fs.statSync(served) : null;
const stale = !cur || cur.size !== src.size || cur.mtimeMs < src.mtimeMs;
if (stale) {
fs.copyFileSync(render, served);
console.log(` sync-reels: ${slug} → reels/ (${(src.size / 1e6).toFixed(1)} MB, render was newer)`);
synced++;
}
}
console.log(` sync-reels: ${checked} render(s) checked, ${synced} refreshed, ${checked - synced} already current`);
process.exit(0);
} catch (e) {
console.error(` sync-reels: IO error — ${e.message}`);
process.exit(1); // real failure aborts deploy (safer than shipping unknown state)
}