@stati/core 1.20.0 → 1.20.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.
@@ -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;AA2B7D,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;AAiXD,wBAAsB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,CAAC,CAudxF"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/core/dev.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAe,MAAM,EAAE,MAAM,mBAAmB,CAAC;AA4B7D,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;AAuXD,wBAAsB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,CAAC,CAudxF"}
package/dist/core/dev.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createServer } from 'node:http';
2
- import { join, extname, posix } from 'node:path';
2
+ import { join, extname } from 'node:path';
3
3
  import { readFile } from 'node:fs/promises';
4
4
  import { WebSocketServer } from 'ws';
5
5
  import chokidar from 'chokidar';
@@ -9,7 +9,7 @@ import { loadConfig } from '../config/loader.js';
9
9
  import { loadCacheManifest, saveCacheManifest, computeNavigationHash } from './isg/index.js';
10
10
  import { loadContent } from './content.js';
11
11
  import { buildNavigation } from './navigation.js';
12
- import { resolveDevPaths, resolveCacheDir, resolvePrettyUrl, createErrorOverlay, parseErrorDetails, TemplateError, createFallbackLogger, mergeServerOptions, createTypeScriptWatcher, } from './utils/index.js';
12
+ import { resolveDevPaths, resolveCacheDir, resolvePrettyUrl, createErrorOverlay, parseErrorDetails, TemplateError, createFallbackLogger, mergeServerOptions, createTypeScriptWatcher, normalizePathForComparison, } from './utils/index.js';
13
13
  import { setEnv, getEnv } from '../env.js';
14
14
  import { DEFAULT_DEV_PORT, DEFAULT_DEV_HOST, TEMPLATE_EXTENSION, DEFAULT_OUT_DIR, } from '../constants.js';
15
15
  /**
@@ -180,7 +180,9 @@ async function performIncrementalRebuild(changedPath, eventType, configPath, sta
180
180
  }
181
181
  }
182
182
  /**
183
- * Handles template/partial file changes by invalidating affected pages
183
+ * Handles template/partial file changes by invalidating affected pages.
184
+ * Uses proper path normalization to ensure reliable matching between
185
+ * file watcher paths and cached dependency paths.
184
186
  */
185
187
  async function handleTemplateChange(templatePath, configPath, logger) {
186
188
  const cacheDir = resolveCacheDir();
@@ -197,16 +199,21 @@ async function handleTemplateChange(templatePath, configPath, logger) {
197
199
  });
198
200
  return;
199
201
  }
202
+ // Normalize the changed template path to absolute POSIX format for reliable comparison
203
+ // This handles cases where the watcher provides relative paths, Windows paths, or different
204
+ // path representations than what's stored in the cache manifest
205
+ const normalizedTemplatePath = normalizePathForComparison(templatePath);
200
206
  // Find pages that depend on this template
201
207
  let affectedPagesCount = 0;
202
- const normalizedTemplatePath = posix.normalize(templatePath.replace(/\\/g, '/'));
203
208
  for (const [pagePath, entry] of Object.entries(cacheManifest.entries)) {
204
- if (entry.deps.some((dep) => {
205
- const normalizedDep = posix.normalize(dep.replace(/\\/g, '/'));
206
- // Use endsWith for more precise matching to avoid false positives
207
- return (normalizedDep === normalizedTemplatePath ||
208
- normalizedDep.endsWith('/' + normalizedTemplatePath));
209
- })) {
209
+ // Check if any of the page's dependencies match the changed template
210
+ const hasMatchingDep = entry.deps.some((dep) => {
211
+ // Normalize the cached dependency path to the same format
212
+ const normalizedDep = normalizePathForComparison(dep);
213
+ // Direct path comparison - both paths are now in consistent format
214
+ return normalizedDep === normalizedTemplatePath;
215
+ });
216
+ if (hasMatchingDep) {
210
217
  affectedPagesCount++;
211
218
  // Remove from cache to force rebuild
212
219
  delete cacheManifest.entries[pagePath];
@@ -3,7 +3,7 @@
3
3
  * @module core/utils
4
4
  */
5
5
  export { readFile, writeFile, pathExists, ensureDir, remove, copyFile, readdir, stat, } from './fs.utils.js';
6
- export { resolveSrcDir, resolveOutDir, resolveStaticDir, resolveCacheDir, resolveDevPaths, normalizeTemplatePath, resolveSrcPath, resolveOutPath, resolveStaticPath, } from './paths.utils.js';
6
+ export { resolveSrcDir, resolveOutDir, resolveStaticDir, resolveCacheDir, resolveDevPaths, normalizeTemplatePath, resolveSrcPath, resolveOutPath, resolveStaticPath, normalizePathForComparison, } from './paths.utils.js';
7
7
  export { discoverLayout, isCollectionIndexPage, getCollectionPathForPage, } from './template-discovery.utils.js';
8
8
  export { propValue } from './template.utils.js';
9
9
  export { slugify } from './slugify.utils.js';
@@ -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,GAClB,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,GAClB,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,GAC3B,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,GAClB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG1E,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -5,7 +5,7 @@
5
5
  // File system utilities
6
6
  export { readFile, writeFile, pathExists, ensureDir, remove, copyFile, readdir, stat, } from './fs.utils.js';
7
7
  // Path resolution utilities
8
- export { resolveSrcDir, resolveOutDir, resolveStaticDir, resolveCacheDir, resolveDevPaths, normalizeTemplatePath, resolveSrcPath, resolveOutPath, resolveStaticPath, } from './paths.utils.js';
8
+ export { resolveSrcDir, resolveOutDir, resolveStaticDir, resolveCacheDir, resolveDevPaths, normalizeTemplatePath, resolveSrcPath, resolveOutPath, resolveStaticPath, normalizePathForComparison, } from './paths.utils.js';
9
9
  // Template discovery utilities
10
10
  export { discoverLayout, isCollectionIndexPage, getCollectionPathForPage, } from './template-discovery.utils.js';
11
11
  // Template utilities
@@ -64,4 +64,31 @@ export declare function resolveOutPath(config: StatiConfig, relativePath: string
64
64
  * @returns Absolute path
65
65
  */
66
66
  export declare function resolveStaticPath(config: StatiConfig, relativePath: string): string;
67
+ /**
68
+ * Normalizes a file path to absolute POSIX format for consistent comparisons.
69
+ * Handles Windows paths, relative paths, and already-normalized paths.
70
+ *
71
+ * This utility ensures that paths from different sources (file watchers, cache manifest,
72
+ * glob results) can be reliably compared even when they use different representations.
73
+ *
74
+ * @param filePath - Path to normalize (can be relative or absolute, Windows or POSIX)
75
+ * @param basePath - Optional base path to resolve relative paths against (defaults to cwd)
76
+ * @returns Normalized absolute path with forward slashes and no trailing slashes
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * // Windows absolute path
81
+ * normalizePathForComparison('C:\\project\\site\\layout.eta')
82
+ * // Returns: 'C:/project/site/layout.eta'
83
+ *
84
+ * // Relative path
85
+ * normalizePathForComparison('site/layout.eta', '/project')
86
+ * // Returns: '/project/site/layout.eta'
87
+ *
88
+ * // Already POSIX path
89
+ * normalizePathForComparison('/project/site/layout.eta')
90
+ * // Returns: '/project/site/layout.eta'
91
+ * ```
92
+ */
93
+ export declare function normalizePathForComparison(filePath: string, basePath?: string): string;
67
94
  //# sourceMappingURL=paths.utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.utils.d.ts","sourceRoot":"","sources":["../../../src/core/utils/paths.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAQxD;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAE5D;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW;;;;EAMlD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEnF"}
1
+ {"version":3,"file":"paths.utils.d.ts","sourceRoot":"","sources":["../../../src/core/utils/paths.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAQxD;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAE5D;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW;;;;EAMlD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAuBtF"}
@@ -83,3 +83,48 @@ export function resolveOutPath(config, relativePath) {
83
83
  export function resolveStaticPath(config, relativePath) {
84
84
  return join(resolveStaticDir(config), relativePath);
85
85
  }
86
+ /**
87
+ * Normalizes a file path to absolute POSIX format for consistent comparisons.
88
+ * Handles Windows paths, relative paths, and already-normalized paths.
89
+ *
90
+ * This utility ensures that paths from different sources (file watchers, cache manifest,
91
+ * glob results) can be reliably compared even when they use different representations.
92
+ *
93
+ * @param filePath - Path to normalize (can be relative or absolute, Windows or POSIX)
94
+ * @param basePath - Optional base path to resolve relative paths against (defaults to cwd)
95
+ * @returns Normalized absolute path with forward slashes and no trailing slashes
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * // Windows absolute path
100
+ * normalizePathForComparison('C:\\project\\site\\layout.eta')
101
+ * // Returns: 'C:/project/site/layout.eta'
102
+ *
103
+ * // Relative path
104
+ * normalizePathForComparison('site/layout.eta', '/project')
105
+ * // Returns: '/project/site/layout.eta'
106
+ *
107
+ * // Already POSIX path
108
+ * normalizePathForComparison('/project/site/layout.eta')
109
+ * // Returns: '/project/site/layout.eta'
110
+ * ```
111
+ */
112
+ export function normalizePathForComparison(filePath, basePath) {
113
+ // Convert backslashes to forward slashes for Windows compatibility
114
+ let normalized = filePath.replace(/\\/g, '/');
115
+ // Resolve to absolute path if relative
116
+ // Check if path is already absolute (starts with / or drive letter)
117
+ const isAbsolute = normalized.startsWith('/') || /^[a-zA-Z]:/.test(normalized);
118
+ if (!isAbsolute) {
119
+ const base = basePath || process.cwd();
120
+ // Use the already-normalized path to avoid reintroducing backslashes
121
+ normalized = join(base, normalized).replace(/\\/g, '/');
122
+ }
123
+ // Use posix.normalize to clean up any '..' or '.' segments and remove redundant separators
124
+ normalized = posix.normalize(normalized);
125
+ // Remove trailing slash (except for root path)
126
+ if (normalized.length > 1 && normalized.endsWith('/')) {
127
+ normalized = normalized.slice(0, -1);
128
+ }
129
+ return normalized;
130
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stati/core",
3
- "version": "1.20.0",
3
+ "version": "1.20.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",