@bouygues-telecom/staticjs 0.1.11 → 1.0.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.
Files changed (66) hide show
  1. package/_build/helpers/cachePages.d.ts +15 -0
  2. package/_build/helpers/cachePages.js +162 -0
  3. package/_build/helpers/createPage.d.ts +18 -0
  4. package/_build/helpers/createPage.js +41 -0
  5. package/_build/helpers/layoutDiscovery.d.ts +9 -0
  6. package/_build/helpers/layoutDiscovery.js +39 -0
  7. package/_build/helpers/readPages.d.ts +3 -0
  8. package/_build/helpers/readPages.js +24 -0
  9. package/_build/helpers/renderPageRuntime.d.ts +13 -0
  10. package/_build/helpers/renderPageRuntime.js +222 -0
  11. package/_build/scripts/build-html.d.ts +1 -0
  12. package/_build/scripts/build-html.js +138 -0
  13. package/_build/scripts/cli.d.ts +6 -0
  14. package/_build/scripts/cli.js +119 -0
  15. package/_build/scripts/create-static-app.d.ts +2 -0
  16. package/{dist/scripts/cli.js → _build/scripts/create-static-app.js} +2 -2
  17. package/_build/scripts/generate-test-multiapps.d.ts +6 -0
  18. package/_build/scripts/generate-test-multiapps.js +79 -0
  19. package/_build/server/config/index.d.ts +20 -0
  20. package/_build/server/config/index.js +25 -0
  21. package/_build/server/config/vite.config.d.ts +2 -0
  22. package/_build/server/config/vite.config.js +31 -0
  23. package/_build/server/config/vite.plugin.d.ts +11 -0
  24. package/_build/server/config/vite.plugin.js +75 -0
  25. package/_build/server/index.d.ts +22 -0
  26. package/_build/server/index.js +124 -0
  27. package/_build/server/middleware/errorHandling.d.ts +22 -0
  28. package/_build/server/middleware/errorHandling.js +48 -0
  29. package/_build/server/middleware/hotReload.d.ts +31 -0
  30. package/_build/server/middleware/hotReload.js +152 -0
  31. package/_build/server/middleware/logging.d.ts +13 -0
  32. package/_build/server/middleware/logging.js +23 -0
  33. package/_build/server/middleware/parsing.d.ts +9 -0
  34. package/_build/server/middleware/parsing.js +21 -0
  35. package/_build/server/middleware/performance.d.ts +13 -0
  36. package/_build/server/middleware/performance.js +26 -0
  37. package/_build/server/middleware/rateLimiting.d.ts +17 -0
  38. package/_build/server/middleware/rateLimiting.js +38 -0
  39. package/_build/server/middleware/runtime.d.ts +23 -0
  40. package/_build/server/middleware/runtime.js +186 -0
  41. package/_build/server/middleware/security.d.ts +24 -0
  42. package/_build/server/middleware/security.js +39 -0
  43. package/_build/server/middleware/static.d.ts +9 -0
  44. package/_build/server/middleware/static.js +63 -0
  45. package/_build/server/routes/api.d.ts +23 -0
  46. package/_build/server/routes/api.js +124 -0
  47. package/_build/server/scripts/revalidate.d.ts +2 -0
  48. package/{dist → _build/server}/scripts/revalidate.js +3 -3
  49. package/_build/server/utils/fileWatcher.d.ts +27 -0
  50. package/_build/server/utils/fileWatcher.js +194 -0
  51. package/_build/server/utils/startup.d.ts +18 -0
  52. package/_build/server/utils/startup.js +93 -0
  53. package/_build/server/utils/vite.d.ts +18 -0
  54. package/_build/server/utils/vite.js +61 -0
  55. package/_build/server/utils/websocket.d.ts +26 -0
  56. package/_build/server/utils/websocket.js +140 -0
  57. package/package.json +28 -16
  58. package/LICENSE +0 -190
  59. package/README.md +0 -158
  60. package/dist/config/vite.plugin.js +0 -80
  61. package/dist/helpers/cachePages.js +0 -26
  62. package/dist/helpers/createPage.js +0 -23
  63. package/dist/helpers/readPages.js +0 -19
  64. package/dist/scripts/build-html.js +0 -82
  65. package/dist/scripts/create-static-app.js +0 -36
  66. package/dist/scripts/generate-test-multiapps.js +0 -51
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Runtime rendering middleware configuration
3
+ * Handles development mode runtime page rendering and JavaScript serving
4
+ */
5
+ import { renderPageRuntime } from "../../helpers/renderPageRuntime.js";
6
+ import { isDevelopment } from "../index.js";
7
+ import { CONFIG } from "../config/index.js";
8
+ import fs from "fs";
9
+ // Cache for rendered pages and module cache invalidation
10
+ let pageCache = new Map();
11
+ let lastCacheInvalidation = Date.now();
12
+ /**
13
+ * Clear all caches when files change
14
+ */
15
+ export const invalidateRuntimeCache = async () => {
16
+ try {
17
+ // Cache invalidation (silent)
18
+ pageCache.clear();
19
+ lastCacheInvalidation = Date.now();
20
+ // Import Vite server using ES modules
21
+ const { getViteServer } = await import('../utils/vite.js');
22
+ const viteServer = getViteServer();
23
+ if (viteServer) {
24
+ // Check if Vite has module graph and invalidate caches
25
+ if (viteServer.moduleGraph) {
26
+ viteServer.moduleGraph.invalidateAll();
27
+ // Clear Vite's transform cache if it exists
28
+ if (viteServer.transformCache && typeof viteServer.transformCache.clear === 'function') {
29
+ viteServer.transformCache.clear();
30
+ }
31
+ // Clear Vite's internal caches if they exist
32
+ if (viteServer.ssrTransform && typeof viteServer.ssrTransform.clear === 'function') {
33
+ viteServer.ssrTransform.clear();
34
+ }
35
+ }
36
+ }
37
+ // Force garbage collection to clear any remaining cached modules
38
+ if (global.gc) {
39
+ global.gc();
40
+ }
41
+ // Cache invalidation completed
42
+ }
43
+ catch (error) {
44
+ console.error('[Runtime] Error during cache invalidation:', error);
45
+ }
46
+ };
47
+ /**
48
+ * Runtime page rendering middleware for development mode
49
+ * Uses renderPageRuntime which handles all page resolution and dynamic routing
50
+ */
51
+ export const runtimeRenderingMiddleware = async (req, res, next) => {
52
+ // Only handle GET requests for pages, but skip static assets and JS files
53
+ if (req.method === 'GET' && !req.path.match(/\.(js|css|ico|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/)) {
54
+ /**
55
+ * Handle runtime rendering for development mode
56
+ * Leverages renderPageRuntime's built-in page resolution and parameter handling
57
+ */
58
+ try {
59
+ const cacheKey = req.path;
60
+ let htmlContent = null;
61
+ // Check if we have cached content and it's still valid
62
+ if (pageCache.has(cacheKey)) {
63
+ const cached = pageCache.get(cacheKey);
64
+ if (cached.timestamp > lastCacheInvalidation) {
65
+ htmlContent = cached.content;
66
+ // Serving cached content
67
+ }
68
+ }
69
+ // If no valid cached content, render fresh
70
+ if (!htmlContent) {
71
+ // Rendering fresh content
72
+ htmlContent = await renderPageRuntime(req.path);
73
+ if (htmlContent) {
74
+ // Cache the rendered content
75
+ pageCache.set(cacheKey, {
76
+ content: htmlContent,
77
+ timestamp: Date.now()
78
+ });
79
+ }
80
+ }
81
+ if (htmlContent) {
82
+ res.setHeader('Content-Type', 'text/html');
83
+ res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
84
+ res.setHeader('Pragma', 'no-cache');
85
+ res.setHeader('Expires', '0');
86
+ res.send(htmlContent);
87
+ return;
88
+ }
89
+ else {
90
+ // Continue to next middleware (static files or 404)
91
+ return next();
92
+ }
93
+ }
94
+ catch (error) {
95
+ console.error('[Runtime] Error rendering page:', error);
96
+ // Continue to next middleware on error
97
+ return next();
98
+ }
99
+ }
100
+ else {
101
+ next();
102
+ }
103
+ };
104
+ /**
105
+ * Register JavaScript serving middleware for each page
106
+ */
107
+ export const registerJavaScriptMiddleware = (app, viteServer) => {
108
+ // Register specific routes for each page's JavaScript file
109
+ const pagesCache = JSON.parse(fs.readFileSync(`./${CONFIG.BUILD_DIR}/cache/pagesCache.json`, 'utf8'));
110
+ const excludedFiles = JSON.parse(fs.readFileSync(`./${CONFIG.BUILD_DIR}/cache/excludedFiles.json`, 'utf8'));
111
+ // Register a route for each page's JS file (skip dynamic routes)
112
+ Object.keys(pagesCache).forEach(pageName => {
113
+ if (!excludedFiles.includes(pageName) && !pageName.includes('[') && !pageName.includes(']')) {
114
+ const jsRoute = `/${pageName}.js`;
115
+ // Registering JS route for page
116
+ app.get(jsRoute, async (req, res) => {
117
+ try {
118
+ // Check if the page file has "no scripts" directive
119
+ const pageContent = fs.readFileSync(pagesCache[pageName], 'utf8');
120
+ const firstLine = pageContent.split('\n')[0];
121
+ if (firstLine.includes('no scripts')) {
122
+ return res.status(404).json({
123
+ success: false,
124
+ error: 'Not Found',
125
+ message: `JavaScript disabled for ${pageName}`,
126
+ });
127
+ }
128
+ // Check file modification time and invalidate cache if needed
129
+ const stats = fs.statSync(pagesCache[pageName]);
130
+ const fileModTime = stats.mtime.getTime();
131
+ if (fileModTime > lastCacheInvalidation && viteServer.moduleGraph) {
132
+ const moduleId = pagesCache[pageName];
133
+ const module = viteServer.moduleGraph.getModuleById(moduleId);
134
+ if (module) {
135
+ viteServer.moduleGraph.invalidateModule(module);
136
+ }
137
+ }
138
+ // Transform the page file using Vite
139
+ const transformStartTime = Date.now();
140
+ const result = await viteServer.transformRequest(`${pagesCache[pageName]}?t=${transformStartTime}`, {
141
+ ssr: false
142
+ });
143
+ if (result && result.code) {
144
+ // Create a hash of the code for cache busting
145
+ const crypto = await import('crypto');
146
+ const codeHash = crypto.createHash('md5').update(result.code).digest('hex').slice(0, 8);
147
+ res.setHeader('Content-Type', 'application/javascript');
148
+ res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
149
+ res.setHeader('Pragma', 'no-cache');
150
+ res.setHeader('Expires', '0');
151
+ res.setHeader('X-Timestamp', Date.now().toString());
152
+ res.setHeader('X-Code-Hash', codeHash);
153
+ res.setHeader('X-File-Modified', fileModTime.toString());
154
+ return res.send(result.code);
155
+ }
156
+ else {
157
+ return res.status(404).json({
158
+ success: false,
159
+ error: 'Not Found',
160
+ message: `No JavaScript generated for ${pageName}`,
161
+ });
162
+ }
163
+ }
164
+ catch (error) {
165
+ console.error(`Error compiling JavaScript for ${pageName}:`, error);
166
+ return res.status(500).json({
167
+ success: false,
168
+ error: 'Internal Server Error',
169
+ message: `Failed to compile JavaScript for ${pageName}`,
170
+ });
171
+ }
172
+ });
173
+ }
174
+ else if (pageName.includes('[') || pageName.includes(']')) {
175
+ // Dynamic routes are handled differently - could add logging here if needed
176
+ }
177
+ });
178
+ };
179
+ /**
180
+ * Apply runtime middleware to Express app (development mode only)
181
+ */
182
+ export const applyRuntime = (app) => {
183
+ if (isDevelopment) {
184
+ app.use(runtimeRenderingMiddleware);
185
+ }
186
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Security middleware configuration
3
+ * Handles helmet, CORS, and other security-related middleware
4
+ */
5
+ import cors from "cors";
6
+ import { Express } from "express";
7
+ /**
8
+ * Security headers middleware using helmet
9
+ * Configures appropriate security headers for the application
10
+ */
11
+ export declare const securityMiddleware: (req: import("http").IncomingMessage, res: import("http").ServerResponse, next: (err?: unknown) => void) => void;
12
+ /**
13
+ * CORS configuration for development
14
+ * Allows cross-origin requests in development mode
15
+ */
16
+ export declare const corsMiddleware: (req: cors.CorsRequest, res: {
17
+ statusCode?: number | undefined;
18
+ setHeader(key: string, value: string): any;
19
+ end(): any;
20
+ }, next: (err?: any) => any) => void;
21
+ /**
22
+ * Apply security middleware to Express app
23
+ */
24
+ export declare const applySecurity: (app: Express) => void;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Security middleware configuration
3
+ * Handles helmet, CORS, and other security-related middleware
4
+ */
5
+ import helmet from "helmet";
6
+ import cors from "cors";
7
+ import { isDevelopment } from "../index.js";
8
+ /**
9
+ * Security headers middleware using helmet
10
+ * Configures appropriate security headers for the application
11
+ */
12
+ export const securityMiddleware = helmet({
13
+ contentSecurityPolicy: {
14
+ directives: {
15
+ defaultSrc: ["'self'"],
16
+ styleSrc: ["'self'", "'unsafe-inline'"],
17
+ scriptSrc: ["'self'"],
18
+ imgSrc: ["'self'", "data:", "https:"],
19
+ },
20
+ },
21
+ crossOriginEmbedderPolicy: false, // Allow embedding for development
22
+ });
23
+ /**
24
+ * CORS configuration for development
25
+ * Allows cross-origin requests in development mode
26
+ */
27
+ export const corsMiddleware = cors({
28
+ origin: true,
29
+ credentials: true,
30
+ });
31
+ /**
32
+ * Apply security middleware to Express app
33
+ */
34
+ export const applySecurity = (app) => {
35
+ app.use(securityMiddleware);
36
+ if (isDevelopment) {
37
+ app.use(corsMiddleware);
38
+ }
39
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Static file serving middleware configuration
3
+ * Handles static file serving with proper cache headers
4
+ */
5
+ import { Express } from "express";
6
+ /**
7
+ * Apply static file serving middleware to Express app
8
+ */
9
+ export declare const applyStatic: (app: Express) => void;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Static file serving middleware configuration
3
+ * Handles static file serving with proper cache headers
4
+ */
5
+ import express from "express";
6
+ import { extname } from "path";
7
+ import { CONFIG, isDevelopment } from "../config/index.js";
8
+ /**
9
+ * Apply static file serving middleware to Express app
10
+ */
11
+ export const applyStatic = (app) => {
12
+ /**
13
+ * Enhanced static file serving with proper cache headers
14
+ * In development mode, exclude JavaScript files so they can be handled by Vite
15
+ */
16
+ app.use((req, res, next) => {
17
+ // In development mode, skip JavaScript files - let Vite handle them
18
+ if (isDevelopment && req.path.endsWith('.js')) {
19
+ console.log(`[DIAGNOSTIC] Skipping static middleware for JS file in development: ${req.path}`);
20
+ return next();
21
+ }
22
+ // Use express.static for non-JS files or in production
23
+ express.static(CONFIG.BUILD_DIR, {
24
+ maxAge: CONFIG.CACHE_MAX_AGE * 1000, // Convert to milliseconds
25
+ etag: true,
26
+ lastModified: true,
27
+ setHeaders: (res, path) => {
28
+ // Set cache headers based on file type
29
+ const ext = extname(path).toLowerCase();
30
+ // DIAGNOSTIC: Log static file serving
31
+ if (ext === '.js') {
32
+ console.log(`[DIAGNOSTIC] Static middleware serving JS file: ${path}`);
33
+ console.log(`[DIAGNOSTIC] Cache max age: ${CONFIG.CACHE_MAX_AGE}`);
34
+ console.log(`[DIAGNOSTIC] Is development: ${isDevelopment}`);
35
+ }
36
+ if (['.js', '.css', '.woff', '.woff2', '.ttf', '.eot'].includes(ext)) {
37
+ if (ext === '.js' && isDevelopment) {
38
+ // Don't cache JavaScript files in development to prevent stale code
39
+ const cacheControl = 'no-cache, no-store, must-revalidate';
40
+ res.setHeader('Cache-Control', cacheControl);
41
+ res.setHeader('Pragma', 'no-cache');
42
+ res.setHeader('Expires', '0');
43
+ console.log(`[DIAGNOSTIC] Setting no-cache for JS in development: ${cacheControl}`);
44
+ }
45
+ else {
46
+ // Cache static assets for longer in production
47
+ const cacheControl = `public, max-age=${CONFIG.CACHE_MAX_AGE}`;
48
+ res.setHeader('Cache-Control', cacheControl);
49
+ if (ext === '.js') {
50
+ console.log(`[DIAGNOSTIC] Setting Cache-Control for JS: ${cacheControl}`);
51
+ }
52
+ }
53
+ }
54
+ else if (['.html', '.htm'].includes(ext)) {
55
+ // Don't cache HTML files in development
56
+ res.setHeader('Cache-Control', isDevelopment ? 'no-cache' : `public, max-age=${CONFIG.CACHE_MAX_AGE / 24}`);
57
+ }
58
+ // Security headers for static files
59
+ res.setHeader('X-Content-Type-Options', 'nosniff');
60
+ },
61
+ })(req, res, next);
62
+ });
63
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * API route handlers
3
+ * Handles health check, pages listing, and revalidate endpoints
4
+ */
5
+ import { Request, Response, Express } from "express";
6
+ /**
7
+ * Health check endpoint
8
+ * Returns server status and basic information
9
+ */
10
+ export declare const healthCheck: (req: Request, res: Response) => void;
11
+ /**
12
+ * API endpoint to list available pages
13
+ * In development mode, uses readPages helper; in production, scans static directory
14
+ */
15
+ export declare const listPages: (req: Request, res: Response) => Promise<void>;
16
+ /**
17
+ * Revalidate endpoint with enhanced error handling and rate limiting
18
+ */
19
+ export declare const revalidateEndpoint: (req: Request, res: Response) => Promise<void>;
20
+ /**
21
+ * Register API routes with Express app
22
+ */
23
+ export declare const registerApiRoutes: (app: Express) => void;
@@ -0,0 +1,124 @@
1
+ /**
2
+ * API route handlers
3
+ * Handles health check, pages listing, and revalidate endpoints
4
+ */
5
+ import { revalidate } from "../scripts/revalidate.js";
6
+ import { getAvailablePagesRuntime } from "../../helpers/renderPageRuntime.js";
7
+ import { readdir } from "fs/promises";
8
+ import { extname, join } from "path";
9
+ import { CONFIG, isDevelopment } from "../config/index.js";
10
+ import { revalidateLimiter } from "../middleware/rateLimiting.js";
11
+ /**
12
+ * Health check endpoint
13
+ * Returns server status and basic information
14
+ */
15
+ export const healthCheck = (req, res) => {
16
+ const healthInfo = {
17
+ status: 'healthy',
18
+ timestamp: new Date().toISOString(),
19
+ uptime: process.uptime(),
20
+ environment: CONFIG.NODE_ENV,
21
+ version: process.version,
22
+ memory: process.memoryUsage(),
23
+ };
24
+ res.status(200).json(healthInfo);
25
+ };
26
+ /**
27
+ * API endpoint to list available pages
28
+ * In development mode, uses readPages helper; in production, scans static directory
29
+ */
30
+ export const listPages = async (req, res) => {
31
+ try {
32
+ let pages;
33
+ if (isDevelopment) {
34
+ // Use runtime pages discovery in development
35
+ const runtimePages = getAvailablePagesRuntime();
36
+ pages = Object.keys(runtimePages).map(pageName => {
37
+ const filePath = runtimePages[pageName];
38
+ const isIndexFile = filePath.endsWith('/index.tsx');
39
+ return {
40
+ name: isIndexFile ? `${pageName}/index.tsx` : `${pageName}.tsx`,
41
+ path: pageName === 'index' ? '/' : `/${pageName}`,
42
+ file: filePath,
43
+ };
44
+ });
45
+ }
46
+ else {
47
+ // Use static file scanning in production
48
+ pages = await getAvailablePages();
49
+ }
50
+ const response = {
51
+ success: true,
52
+ pages,
53
+ count: pages.length,
54
+ mode: isDevelopment ? 'development (runtime)' : 'production (static)',
55
+ };
56
+ res.status(200).json(response);
57
+ }
58
+ catch (error) {
59
+ console.error('Error listing pages:', error);
60
+ const errorResponse = {
61
+ success: false,
62
+ error: 'Failed to list available pages',
63
+ message: isDevelopment ? error.message : 'Internal server error',
64
+ };
65
+ res.status(500).json(errorResponse);
66
+ }
67
+ };
68
+ /**
69
+ * Revalidate endpoint with enhanced error handling and rate limiting
70
+ */
71
+ export const revalidateEndpoint = async (req, res) => {
72
+ try {
73
+ await revalidate(req, res);
74
+ }
75
+ catch (error) {
76
+ console.error('Revalidate error:', error);
77
+ const errorResponse = {
78
+ success: false,
79
+ error: 'Revalidation failed',
80
+ message: isDevelopment ? error.message : 'Internal server error',
81
+ };
82
+ res.status(500).json(errorResponse);
83
+ }
84
+ };
85
+ /**
86
+ * Scans the static directory for available HTML pages
87
+ * @returns {Promise<Array>} Array of available page paths
88
+ */
89
+ async function getAvailablePages() {
90
+ const pages = [];
91
+ try {
92
+ const scanDirectory = async (dir, basePath = '') => {
93
+ const items = await readdir(join(CONFIG.BUILD_DIR, dir), { withFileTypes: true });
94
+ for (const item of items) {
95
+ const itemPath = join(dir, item.name);
96
+ const urlPath = join(basePath, item.name);
97
+ if (item.isDirectory()) {
98
+ await scanDirectory(itemPath, urlPath);
99
+ }
100
+ else if (item.isFile() && extname(item.name).toLowerCase() === '.html') {
101
+ const pagePath = urlPath.replace(/\.html$/, '').replace(/\\/g, '/');
102
+ pages.push({
103
+ name: item.name,
104
+ path: pagePath === 'index' ? '/' : `/${pagePath}`,
105
+ file: itemPath.replace(/\\/g, '/'),
106
+ });
107
+ }
108
+ }
109
+ };
110
+ await scanDirectory('');
111
+ }
112
+ catch (error) {
113
+ console.warn('Could not scan pages directory:', error.message);
114
+ }
115
+ return pages.sort((a, b) => a.path.localeCompare(b.path));
116
+ }
117
+ /**
118
+ * Register API routes with Express app
119
+ */
120
+ export const registerApiRoutes = (app) => {
121
+ app.get('/health', healthCheck);
122
+ app.get('/api/pages', listPages);
123
+ app.post('/revalidate', revalidateLimiter, revalidateEndpoint);
124
+ };
@@ -0,0 +1,2 @@
1
+ import { Request, Response } from "express";
2
+ export declare const revalidate: (req: Request, res: Response) => void;
@@ -7,8 +7,8 @@ export const revalidate = (req, res) => {
7
7
  try {
8
8
  const paths = req?.body?.paths || [];
9
9
  const pathsArg = paths.length > 0 ? paths.join(" ") : "";
10
- const cachePages = path.resolve(__dirname, "../helpers/cachePages.js");
11
- const buildHtmlConfig = path.resolve(__dirname, "./build-html.js");
10
+ const cachePages = path.resolve(__dirname, "../../../helpers/cachePages.js");
11
+ const buildHtmlConfig = path.resolve(__dirname, "../../../scripts/build-html.js");
12
12
  const buildCommand = `NODE_TLS_REJECT_UNAUTHORIZED=0 node ${cachePages} ${pathsArg && `${pathsArg}`} && npx tsx ${buildHtmlConfig}`;
13
13
  exec(buildCommand, (error, stdout, stderr) => {
14
14
  if (error) {
@@ -20,7 +20,7 @@ export const revalidate = (req, res) => {
20
20
  console.error(`stderr: ${stderr}`);
21
21
  }
22
22
  });
23
- return res
23
+ res
24
24
  .status(200)
25
25
  .send(`Revalidation triggered, paths: ${paths.length > 0 ? paths.join(", ") : "all pages"} built!`);
26
26
  }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * File watcher system for hot reloading
3
+ * Watches source files and triggers WebSocket broadcasts on changes
4
+ */
5
+ import { FSWatcher } from 'chokidar';
6
+ type ReloadType = 'style' | 'page' | 'full' | 'asset';
7
+ /**
8
+ * Initialize file watcher
9
+ */
10
+ export declare const initializeFileWatcher: () => FSWatcher | null;
11
+ /**
12
+ * Get current file watcher instance
13
+ */
14
+ export declare const getFileWatcher: () => FSWatcher | null;
15
+ /**
16
+ * Get watched files count
17
+ */
18
+ export declare const getWatchedFilesCount: () => number;
19
+ /**
20
+ * Close file watcher and cleanup
21
+ */
22
+ export declare const closeFileWatcher: () => Promise<void>;
23
+ /**
24
+ * Manually trigger a reload (useful for testing)
25
+ */
26
+ export declare const triggerReload: (type?: ReloadType, data?: Record<string, any>) => void;
27
+ export {};