@stati/core 1.23.3 → 1.24.0
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/dist/core/dev.d.ts.map +1 -1
- package/dist/core/dev.js +50 -26
- package/dist/core/templates.d.ts +5 -0
- package/dist/core/templates.d.ts.map +1 -1
- package/dist/core/templates.js +31 -2
- package/dist/core/utils/dev-css-watcher.utils.d.ts +26 -0
- package/dist/core/utils/dev-css-watcher.utils.d.ts.map +1 -0
- package/dist/core/utils/dev-css-watcher.utils.js +70 -0
- package/dist/core/utils/env.utils.d.ts +5 -0
- package/dist/core/utils/env.utils.d.ts.map +1 -0
- package/dist/core/utils/env.utils.js +8 -0
- package/dist/core/utils/index.d.ts +3 -0
- package/dist/core/utils/index.d.ts.map +1 -1
- package/dist/core/utils/index.js +4 -0
- package/package.json +1 -1
package/dist/core/dev.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/core/dev.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAe,MAAM,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/core/dev.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAe,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAsC7D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;CACb;AAscD,wBAAsB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,CAAC,CA+gBxF"}
|
package/dist/core/dev.js
CHANGED
|
@@ -6,10 +6,12 @@ import chokidar from 'chokidar';
|
|
|
6
6
|
import { build } from './build.js';
|
|
7
7
|
import { invalidate } from './invalidate.js';
|
|
8
8
|
import { loadConfig } from '../config/loader.js';
|
|
9
|
+
import { clearTemplateEngineCache } from './templates.js';
|
|
10
|
+
import { clearMarkdownProcessorCache } from './markdown.js';
|
|
9
11
|
import { loadCacheManifest, saveCacheManifest, computeNavigationHash, DevServerLockManager, } from './isg/index.js';
|
|
10
12
|
import { loadContent } from './content.js';
|
|
11
13
|
import { buildNavigation } from './navigation.js';
|
|
12
|
-
import { resolveDevPaths, resolveCacheDir, resolvePrettyUrl, createErrorOverlay, parseErrorDetails, TemplateError, createFallbackLogger, mergeServerOptions, createTypeScriptWatcher, normalizePathForComparison, isPathWithinDirectory, } from './utils/index.js';
|
|
14
|
+
import { resolveDevPaths, resolveCacheDir, resolvePrettyUrl, createErrorOverlay, parseErrorDetails, TemplateError, createFallbackLogger, mergeServerOptions, createTypeScriptWatcher, isEnabledEnvFlag, refreshCssOutputWatcher, normalizePathForComparison, isPathWithinDirectory, } from './utils/index.js';
|
|
13
15
|
import { setEnv, getEnv } from '../env.js';
|
|
14
16
|
import { DEFAULT_DEV_PORT, DEFAULT_DEV_HOST, TEMPLATE_EXTENSION, DEFAULT_OUT_DIR, } from '../constants.js';
|
|
15
17
|
/**
|
|
@@ -75,9 +77,10 @@ async function performInitialBuild(configPath, logger, onError) {
|
|
|
75
77
|
* active build. The `changes` Map stores file paths as keys and their event types as values,
|
|
76
78
|
* ensuring each file is only processed once with its most recent event type.
|
|
77
79
|
* @param onError - Optional callback invoked when build errors occur
|
|
80
|
+
* @param onBuildEnd - Optional callback invoked after each build attempt finishes (success or failure)
|
|
78
81
|
* @param batchedChanges - Array of changes to process in a single batch (used for pending queue processing)
|
|
79
82
|
*/
|
|
80
|
-
async function performIncrementalRebuild(changedPath, eventType, configPath, staticDir, logger, wsServer, isBuildingRef, pendingChangesRef, onError, batchedChanges = []) {
|
|
83
|
+
async function performIncrementalRebuild(changedPath, eventType, configPath, staticDir, logger, wsServer, isBuildingRef, pendingChangesRef, onError, onBuildEnd, batchedChanges = []) {
|
|
81
84
|
// If a build is in progress, queue this change for processing after the current build
|
|
82
85
|
if (isBuildingRef.value) {
|
|
83
86
|
pendingChangesRef.changes.set(changedPath, eventType);
|
|
@@ -193,6 +196,14 @@ async function performIncrementalRebuild(changedPath, eventType, configPath, sta
|
|
|
193
196
|
}
|
|
194
197
|
finally {
|
|
195
198
|
isBuildingRef.value = false;
|
|
199
|
+
if (onBuildEnd) {
|
|
200
|
+
try {
|
|
201
|
+
await onBuildEnd();
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
logger.error?.(`Failed post-build hook after rebuild: ${error instanceof Error ? error.message : String(error)}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
196
207
|
// Check if there are pending changes that occurred during this build
|
|
197
208
|
if (pendingChangesRef.changes.size > 0) {
|
|
198
209
|
// Get all pending changes - the build will process all of them at once
|
|
@@ -202,7 +213,7 @@ async function performIncrementalRebuild(changedPath, eventType, configPath, sta
|
|
|
202
213
|
// The build() call will copy all static assets and rebuild all affected pages
|
|
203
214
|
const [first, ...remaining] = pendingChanges;
|
|
204
215
|
if (first) {
|
|
205
|
-
void performIncrementalRebuild(first.path, first.eventType, configPath, staticDir, logger, wsServer, isBuildingRef, pendingChangesRef, onError, remaining);
|
|
216
|
+
void performIncrementalRebuild(first.path, first.eventType, configPath, staticDir, logger, wsServer, isBuildingRef, pendingChangesRef, onError, onBuildEnd, remaining);
|
|
206
217
|
}
|
|
207
218
|
}
|
|
208
219
|
}
|
|
@@ -217,6 +228,10 @@ async function performIncrementalRebuild(changedPath, eventType, configPath, sta
|
|
|
217
228
|
async function handleTemplateChange(templatePath, configPath, logger) {
|
|
218
229
|
const cacheDir = resolveCacheDir();
|
|
219
230
|
try {
|
|
231
|
+
// Drop the cached Eta engine so the changed template (and any compiled partials)
|
|
232
|
+
// are recompiled on the next build. This keeps rebuilds correct while still
|
|
233
|
+
// reusing the engine across the common markdown-only edit path.
|
|
234
|
+
clearTemplateEngineCache();
|
|
220
235
|
// Load existing cache manifest
|
|
221
236
|
const cacheManifest = await loadCacheManifest(cacheDir);
|
|
222
237
|
if (!cacheManifest) {
|
|
@@ -399,6 +414,10 @@ export async function createDevServer(options = {}) {
|
|
|
399
414
|
const isBuildingRef = { value: false };
|
|
400
415
|
const pendingChangesRef = { changes: new Map() };
|
|
401
416
|
let isStopping = false;
|
|
417
|
+
const watchedCssFiles = new Set();
|
|
418
|
+
// Diagnostics toggles used for investigating dev-server rebuild slowdown.
|
|
419
|
+
const disableCssWatcher = isEnabledEnvFlag(process.env.STATI_DEV_DISABLE_CSS_WATCHER);
|
|
420
|
+
const disableWsReload = isEnabledEnvFlag(process.env.STATI_DEV_DISABLE_WS_RELOAD);
|
|
402
421
|
/**
|
|
403
422
|
* Gets MIME type for a file based on its extension
|
|
404
423
|
*/
|
|
@@ -667,7 +686,7 @@ export async function createDevServer(options = {}) {
|
|
|
667
686
|
onRebuild: (_results, compileTimeMs) => {
|
|
668
687
|
logger.info?.(`▸ TypeScript recompiled in ${compileTimeMs}ms`);
|
|
669
688
|
// Broadcast reload to WebSocket clients
|
|
670
|
-
if (wsServer) {
|
|
689
|
+
if (wsServer && !disableWsReload) {
|
|
671
690
|
wsServer.clients.forEach((client) => {
|
|
672
691
|
const ws = client;
|
|
673
692
|
if (ws.readyState === 1) {
|
|
@@ -699,40 +718,42 @@ export async function createDevServer(options = {}) {
|
|
|
699
718
|
persistent: true,
|
|
700
719
|
ignoreInitial: true,
|
|
701
720
|
});
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
if (ws.readyState === 1) {
|
|
717
|
-
ws.send(JSON.stringify({ type: 'reload' }));
|
|
718
|
-
}
|
|
719
|
-
});
|
|
721
|
+
const refreshCssWatcher = async () => {
|
|
722
|
+
cssWatcher = await refreshCssOutputWatcher({
|
|
723
|
+
outDir,
|
|
724
|
+
logger,
|
|
725
|
+
wsServer,
|
|
726
|
+
disableWsReload,
|
|
727
|
+
cssWatcher,
|
|
728
|
+
watchedCssFiles,
|
|
729
|
+
});
|
|
730
|
+
};
|
|
731
|
+
if (!disableCssWatcher) {
|
|
732
|
+
await refreshCssWatcher();
|
|
733
|
+
if (!cssWatcher) {
|
|
734
|
+
logger.info?.(' • [dev] No CSS files found in output; CSS watcher not started');
|
|
720
735
|
}
|
|
721
|
-
}
|
|
736
|
+
}
|
|
722
737
|
watcher.on('change', (path) => {
|
|
723
|
-
void performIncrementalRebuild(path, 'change', configPath, staticDir, logger, wsServer, isBuildingRef, pendingChangesRef, setLastBuildError);
|
|
738
|
+
void performIncrementalRebuild(path, 'change', configPath, staticDir, logger, disableWsReload ? null : wsServer, isBuildingRef, pendingChangesRef, setLastBuildError, disableCssWatcher ? undefined : refreshCssWatcher);
|
|
724
739
|
});
|
|
725
740
|
watcher.on('add', (path) => {
|
|
726
|
-
void performIncrementalRebuild(path, 'add', configPath, staticDir, logger, wsServer, isBuildingRef, pendingChangesRef, setLastBuildError);
|
|
741
|
+
void performIncrementalRebuild(path, 'add', configPath, staticDir, logger, disableWsReload ? null : wsServer, isBuildingRef, pendingChangesRef, setLastBuildError, disableCssWatcher ? undefined : refreshCssWatcher);
|
|
727
742
|
});
|
|
728
743
|
watcher.on('unlink', (path) => {
|
|
729
|
-
void performIncrementalRebuild(path, 'unlink', configPath, staticDir, logger, wsServer, isBuildingRef, pendingChangesRef, setLastBuildError);
|
|
744
|
+
void performIncrementalRebuild(path, 'unlink', configPath, staticDir, logger, disableWsReload ? null : wsServer, isBuildingRef, pendingChangesRef, setLastBuildError, disableCssWatcher ? undefined : refreshCssWatcher);
|
|
730
745
|
});
|
|
731
746
|
logger.success?.(`Dev server running at ${url}`);
|
|
732
747
|
logger.info?.(`\nServing:`);
|
|
733
748
|
logger.info?.(` • ${outDir}`);
|
|
734
749
|
logger.info?.('Watching:');
|
|
735
750
|
watchPaths.forEach((path) => logger.info?.(` • ${path}`));
|
|
751
|
+
if (disableCssWatcher) {
|
|
752
|
+
logger.info?.(' • [diagnostic] CSS output watcher disabled');
|
|
753
|
+
}
|
|
754
|
+
if (disableWsReload) {
|
|
755
|
+
logger.info?.(' • [diagnostic] WebSocket reload broadcast disabled');
|
|
756
|
+
}
|
|
736
757
|
logger.info?.('');
|
|
737
758
|
// Open browser if requested
|
|
738
759
|
if (open) {
|
|
@@ -782,6 +803,9 @@ export async function createDevServer(options = {}) {
|
|
|
782
803
|
});
|
|
783
804
|
httpServer = null;
|
|
784
805
|
}
|
|
806
|
+
// Release cached dev-session engines so they can be garbage collected
|
|
807
|
+
clearTemplateEngineCache();
|
|
808
|
+
clearMarkdownProcessorCache();
|
|
785
809
|
logger.info?.('Dev server stopped');
|
|
786
810
|
},
|
|
787
811
|
};
|
package/dist/core/templates.d.ts
CHANGED
|
@@ -9,6 +9,11 @@ export interface RenderResult {
|
|
|
9
9
|
/** Number of templates loaded (layout + partials) */
|
|
10
10
|
templatesLoaded: number;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Clear the cached template engine. Call this when templates change in dev mode
|
|
14
|
+
* so the next build recompiles them, or when shutting down a dev session.
|
|
15
|
+
*/
|
|
16
|
+
export declare function clearTemplateEngineCache(): void;
|
|
12
17
|
export declare function createTemplateEngine(config: StatiConfig): Eta;
|
|
13
18
|
export declare function renderPage(page: PageModel, body: string, config: StatiConfig, eta: Eta, navigation?: NavNode[], allPages?: PageModel[], assets?: import('../types/index.js').StatiAssets, toc?: TocEntry[], logger?: Logger): Promise<RenderResult>;
|
|
14
19
|
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/core/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAG1B,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,OAAO,EAEP,QAAQ,EACR,MAAM,EACP,MAAM,mBAAmB,CAAC;AAkB3B;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,eAAe,EAAE,MAAM,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/core/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAG1B,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,OAAO,EAEP,QAAQ,EACR,MAAM,EACP,MAAM,mBAAmB,CAAC;AAkB3B;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,eAAe,EAAE,MAAM,CAAC;CACzB;AAgND;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,GAAG,CAwB7D;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,GAAG,EACR,UAAU,CAAC,EAAE,OAAO,EAAE,EACtB,QAAQ,CAAC,EAAE,SAAS,EAAE,EACtB,MAAM,CAAC,EAAE,OAAO,mBAAmB,EAAE,WAAW,EAChD,GAAG,CAAC,EAAE,QAAQ,EAAE,EAChB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CAuMvB"}
|
package/dist/core/templates.js
CHANGED
|
@@ -173,14 +173,43 @@ async function discoverPartials(pagePath, config) {
|
|
|
173
173
|
}
|
|
174
174
|
return partials;
|
|
175
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Cached template engine for dev mode to avoid re-creating on each rebuild.
|
|
178
|
+
*
|
|
179
|
+
* Recreating the Eta instance and recompiling every template on each dev rebuild
|
|
180
|
+
* generates large transient native allocations that the V8 allocator does not
|
|
181
|
+
* return to the OS, causing monotonic RSS growth and increasing rebuild times
|
|
182
|
+
* over a long dev session. Reusing a single instance (with template caching on)
|
|
183
|
+
* keeps rebuild cost flat. The cache is keyed by template directory so a config
|
|
184
|
+
* change pointing to a different srcDir still produces a fresh engine.
|
|
185
|
+
*/
|
|
186
|
+
let cachedTemplateEngine = null;
|
|
187
|
+
/**
|
|
188
|
+
* Clear the cached template engine. Call this when templates change in dev mode
|
|
189
|
+
* so the next build recompiles them, or when shutting down a dev session.
|
|
190
|
+
*/
|
|
191
|
+
export function clearTemplateEngineCache() {
|
|
192
|
+
cachedTemplateEngine = null;
|
|
193
|
+
}
|
|
176
194
|
export function createTemplateEngine(config) {
|
|
177
195
|
const templateDir = resolveSrcDir(config);
|
|
196
|
+
// In dev mode, reuse a single cached engine across rebuilds to avoid
|
|
197
|
+
// per-rebuild compile churn and the associated native-memory growth.
|
|
198
|
+
if (isDevelopment() && cachedTemplateEngine && cachedTemplateEngine.templateDir === templateDir) {
|
|
199
|
+
return cachedTemplateEngine.eta;
|
|
200
|
+
}
|
|
201
|
+
// Enable the template cache in dev too so partials/layouts compile once and are
|
|
202
|
+
// reused across rebuilds; template edits clear this cache via clearTemplateEngineCache().
|
|
203
|
+
const useCache = isDevelopment() || isProduction();
|
|
178
204
|
const eta = new Eta({
|
|
179
205
|
views: templateDir,
|
|
180
|
-
cache:
|
|
181
|
-
cacheFilepaths:
|
|
206
|
+
cache: useCache,
|
|
207
|
+
cacheFilepaths: useCache,
|
|
182
208
|
varName: 'stati',
|
|
183
209
|
});
|
|
210
|
+
if (isDevelopment()) {
|
|
211
|
+
cachedTemplateEngine = { templateDir, eta };
|
|
212
|
+
}
|
|
184
213
|
return eta;
|
|
185
214
|
}
|
|
186
215
|
export async function renderPage(page, body, config, eta, navigation, allPages, assets, toc, logger) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { FSWatcher } from 'chokidar';
|
|
2
|
+
import type { WebSocketServer } from 'ws';
|
|
3
|
+
import type { Logger } from '../../types/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Returns concrete CSS files currently present in outDir.
|
|
6
|
+
*
|
|
7
|
+
* Watching explicit files avoids a broad recursive outDir glob watcher,
|
|
8
|
+
* which can add significant overhead on large docs sites.
|
|
9
|
+
*/
|
|
10
|
+
export declare function discoverOutputCssFiles(outDir: string): Promise<string[]>;
|
|
11
|
+
export interface RefreshCssOutputWatcherParams {
|
|
12
|
+
outDir: string;
|
|
13
|
+
logger: Logger;
|
|
14
|
+
wsServer: WebSocketServer | null;
|
|
15
|
+
disableWsReload: boolean;
|
|
16
|
+
cssWatcher: FSWatcher | null;
|
|
17
|
+
watchedCssFiles: Set<string>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Reconciles the CSS watcher with the current output CSS file membership.
|
|
21
|
+
*
|
|
22
|
+
* If the file set changed, this closes the previous watcher and creates a new one
|
|
23
|
+
* bound to the latest concrete files.
|
|
24
|
+
*/
|
|
25
|
+
export declare function refreshCssOutputWatcher(params: RefreshCssOutputWatcherParams): Promise<FSWatcher | null>;
|
|
26
|
+
//# sourceMappingURL=dev-css-watcher.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-css-watcher.utils.d.ts","sourceRoot":"","sources":["../../../src/core/utils/dev-css-watcher.utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAGnD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAa9E;AA0BD,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAgC3B"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import chokidar from 'chokidar';
|
|
2
|
+
import fg from 'fast-glob';
|
|
3
|
+
import { pathExists } from './fs.utils.js';
|
|
4
|
+
/**
|
|
5
|
+
* Returns concrete CSS files currently present in outDir.
|
|
6
|
+
*
|
|
7
|
+
* Watching explicit files avoids a broad recursive outDir glob watcher,
|
|
8
|
+
* which can add significant overhead on large docs sites.
|
|
9
|
+
*/
|
|
10
|
+
export async function discoverOutputCssFiles(outDir) {
|
|
11
|
+
if (!(await pathExists(outDir))) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
const cssFiles = await fg('**/*.css', {
|
|
15
|
+
cwd: outDir,
|
|
16
|
+
absolute: true,
|
|
17
|
+
onlyFiles: true,
|
|
18
|
+
dot: false,
|
|
19
|
+
});
|
|
20
|
+
return cssFiles;
|
|
21
|
+
}
|
|
22
|
+
function hasSameMembership(nextFiles, watchedCssFiles) {
|
|
23
|
+
if (nextFiles.length !== watchedCssFiles.size) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return nextFiles.every((file) => watchedCssFiles.has(file));
|
|
27
|
+
}
|
|
28
|
+
function broadcastReload(wsServer, disableWsReload, payload) {
|
|
29
|
+
if (!wsServer || disableWsReload) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
wsServer.clients.forEach((client) => {
|
|
33
|
+
const ws = client;
|
|
34
|
+
if (ws.readyState === 1) {
|
|
35
|
+
ws.send(payload);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Reconciles the CSS watcher with the current output CSS file membership.
|
|
41
|
+
*
|
|
42
|
+
* If the file set changed, this closes the previous watcher and creates a new one
|
|
43
|
+
* bound to the latest concrete files.
|
|
44
|
+
*/
|
|
45
|
+
export async function refreshCssOutputWatcher(params) {
|
|
46
|
+
const { outDir, logger, wsServer, disableWsReload, cssWatcher, watchedCssFiles } = params;
|
|
47
|
+
const cssFiles = await discoverOutputCssFiles(outDir);
|
|
48
|
+
if (hasSameMembership(cssFiles, watchedCssFiles)) {
|
|
49
|
+
return cssWatcher;
|
|
50
|
+
}
|
|
51
|
+
if (cssWatcher) {
|
|
52
|
+
await cssWatcher.close();
|
|
53
|
+
}
|
|
54
|
+
watchedCssFiles.clear();
|
|
55
|
+
cssFiles.forEach((file) => watchedCssFiles.add(file));
|
|
56
|
+
if (cssFiles.length === 0) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const nextCssWatcher = chokidar.watch(cssFiles, {
|
|
60
|
+
ignored: /(^|[/\\])\../,
|
|
61
|
+
persistent: true,
|
|
62
|
+
ignoreInitial: true,
|
|
63
|
+
});
|
|
64
|
+
nextCssWatcher.on('change', (path) => {
|
|
65
|
+
const relativePath = path.replace(process.cwd(), '').replace(/\\/g, '/').replace(/^\//, '');
|
|
66
|
+
logger.info?.(`▸ ${relativePath} updated`);
|
|
67
|
+
broadcastReload(wsServer, disableWsReload, JSON.stringify({ type: 'reload' }));
|
|
68
|
+
});
|
|
69
|
+
return nextCssWatcher;
|
|
70
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.utils.d.ts","sourceRoot":"","sources":["../../../src/core/utils/env.utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGnE"}
|
|
@@ -25,4 +25,7 @@ export { createFallbackLogger } from './logger.utils.js';
|
|
|
25
25
|
export { compileTypeScript, createTypeScriptWatcher, compileStatiConfig, cleanupCompiledConfig, autoInjectBundles, formatBytes, detectExistingBundles, } from './typescript.utils.js';
|
|
26
26
|
export type { CompileOptions, WatchOptions } from './typescript.utils.js';
|
|
27
27
|
export { findHeadClosePosition, injectBeforeHeadClose } from './html.utils.js';
|
|
28
|
+
export { isEnabledEnvFlag } from './env.utils.js';
|
|
29
|
+
export { discoverOutputCssFiles, refreshCssOutputWatcher } from './dev-css-watcher.utils.js';
|
|
30
|
+
export type { RefreshCssOutputWatcherParams } from './dev-css-watcher.utils.js';
|
|
28
31
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,QAAQ,EACR,SAAS,EACT,UAAU,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,OAAO,EACP,IAAI,GACL,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,2BAA2B,EAC3B,cAAc,EACd,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAG9E,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC3F,YAAY,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAG/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAGxE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzE,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACjF,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGpE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGzD,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,EACX,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG1E,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,QAAQ,EACR,SAAS,EACT,UAAU,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,OAAO,EACP,IAAI,GACL,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,2BAA2B,EAC3B,cAAc,EACd,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAG9E,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC3F,YAAY,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAG/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAGxE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzE,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACjF,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGpE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGzD,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,EACX,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG1E,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGlD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAC7F,YAAY,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/core/utils/index.js
CHANGED
|
@@ -38,3 +38,7 @@ export { createFallbackLogger } from './logger.utils.js';
|
|
|
38
38
|
export { compileTypeScript, createTypeScriptWatcher, compileStatiConfig, cleanupCompiledConfig, autoInjectBundles, formatBytes, detectExistingBundles, } from './typescript.utils.js';
|
|
39
39
|
// HTML manipulation utilities
|
|
40
40
|
export { findHeadClosePosition, injectBeforeHeadClose } from './html.utils.js';
|
|
41
|
+
// Environment utilities
|
|
42
|
+
export { isEnabledEnvFlag } from './env.utils.js';
|
|
43
|
+
// Dev-server CSS watcher utilities
|
|
44
|
+
export { discoverOutputCssFiles, refreshCssOutputWatcher } from './dev-css-watcher.utils.js';
|