caracms 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.ts +43 -3
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
import type { AstroIntegration } from 'astro';
|
|
50
50
|
import { fontProviders } from 'astro/config';
|
|
51
51
|
import { execFileSync } from 'node:child_process';
|
|
52
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
52
|
+
import { existsSync, readFileSync, watch, writeFileSync, type FSWatcher } from 'node:fs';
|
|
53
53
|
import { createRequire } from 'node:module';
|
|
54
|
-
import { isAbsolute, join, sep } from 'node:path';
|
|
54
|
+
import { basename, dirname, isAbsolute, join, sep } from 'node:path';
|
|
55
55
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
56
56
|
import { resolveSite, SITE_SETTINGS_FILE, type ResolvedSite, type SiteConfig } from './config.ts';
|
|
57
57
|
import { lockupCss } from './lockup-css.ts';
|
|
@@ -219,6 +219,39 @@ export function contentWatchIgnores(site: Pick<ResolvedSite, 'collections' | 'ro
|
|
|
219
219
|
];
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
/**
|
|
223
|
+
* The content contentWatchIgnores takes out of Vite's watch, watched apart, so the dev server
|
|
224
|
+
* learns a page was added, moved, hidden or removed. Astro's dev server caches each route's
|
|
225
|
+
* `getStaticPaths` and clears it only on its own content changes, so without this the public
|
|
226
|
+
* site kept its old list of pages until a restart (an old address even answered 500 rather
|
|
227
|
+
* than its redirect). Every collection folder that exists at start, recursively, and the
|
|
228
|
+
* Site Settings file; `onChange` once per burst of changes. Returns the stop.
|
|
229
|
+
*/
|
|
230
|
+
export function watchContent(site: Pick<ResolvedSite, 'collections' | 'root'>, onChange: () => void, wait = 100): () => void {
|
|
231
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
232
|
+
const changed = () => {
|
|
233
|
+
clearTimeout(timer);
|
|
234
|
+
timer = setTimeout(onChange, wait);
|
|
235
|
+
};
|
|
236
|
+
const watchers: FSWatcher[] = [];
|
|
237
|
+
const add = (path: string, recursive: boolean, only?: string) => {
|
|
238
|
+
if (!existsSync(path)) return;
|
|
239
|
+
const watcher = watch(path, { recursive, persistent: false }, (_event, name) => {
|
|
240
|
+
if (!only || name === only) changed();
|
|
241
|
+
});
|
|
242
|
+
// A watched folder that's removed mustn't take the dev server down with it.
|
|
243
|
+
watcher.on('error', () => watcher.close());
|
|
244
|
+
watchers.push(watcher);
|
|
245
|
+
};
|
|
246
|
+
for (const c of Object.values(site.collections)) if (c.kind !== 'settings') add(c.dir, true);
|
|
247
|
+
const settings = join(site.root, SITE_SETTINGS_FILE);
|
|
248
|
+
add(dirname(settings), false, basename(settings));
|
|
249
|
+
return () => {
|
|
250
|
+
clearTimeout(timer);
|
|
251
|
+
for (const watcher of watchers) watcher.close();
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
222
255
|
/**
|
|
223
256
|
* The hosts Astro may take a request's address from (`security.allowedDomains`).
|
|
224
257
|
* Without them, Astro ignores the Host header and every request reads as
|
|
@@ -461,13 +494,20 @@ export default function caracms(config: SiteConfig): AstroIntegration {
|
|
|
461
494
|
},
|
|
462
495
|
// M8 Decision 14: a dev server (at start, and on the restart a config change makes) regenerates
|
|
463
496
|
// schemas/ from the config. Never content files: a dev run only changes what your code change derives.
|
|
464
|
-
'astro:server:setup': ({ logger }) => {
|
|
497
|
+
'astro:server:setup': ({ server, logger }) => {
|
|
465
498
|
try {
|
|
466
499
|
const changed = writeSchemaFiles(site);
|
|
467
500
|
if (changed.length) logger.info(`updated ${changed.map((c) => c.file).join(', ')}`);
|
|
468
501
|
} catch (error) {
|
|
469
502
|
logger.warn(`couldn't write schemas/: ${(error as Error).message}`);
|
|
470
503
|
}
|
|
504
|
+
// A content change re-runs every route's getStaticPaths, as Astro does for its own content
|
|
505
|
+
// collections (the same event, to the same server environments). Never a browser reload:
|
|
506
|
+
// the editor writes these files.
|
|
507
|
+
const stop = watchContent(site, () => {
|
|
508
|
+
for (const name of ['ssr', 'prerender']) server.environments[name]?.hot.send('astro:content-changed', {});
|
|
509
|
+
});
|
|
510
|
+
server.httpServer?.once('close', stop);
|
|
471
511
|
},
|
|
472
512
|
// Posts and tags, Decision 15: a production build reads each document once (read.ts). Never in dev.
|
|
473
513
|
'astro:build:start': () => shareBuildReads(true),
|