opticore-webapp 1.0.70 → 1.0.72

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/index.d.cts CHANGED
@@ -6,17 +6,98 @@ import { express } from 'opticore-express';
6
6
  import { LoggerCore } from 'opticore-logger';
7
7
  import { CorsOptions } from 'cors';
8
8
 
9
+ interface HotReloadConfig {
10
+ /**
11
+ * Entry point file to run.
12
+ * Reserved for future standalone mode — not used in integrated mode.
13
+ */
14
+ entry?: string;
15
+ /**
16
+ * Runtime to use for spawning the child process.
17
+ * - 'node' : compiled JS only, supports IPC hot reload for .env
18
+ * - 'tsx' : runs TypeScript directly via tsx
19
+ * - 'ts-node' : runs TypeScript directly via ts-node
20
+ * @default 'node'
21
+ */
22
+ runtime?: 'node' | 'tsx' | 'ts-node';
23
+ /**
24
+ * Extra arguments passed to the runtime before the entry file.
25
+ * Example: ['--experimental-specifier-resolution=node']
26
+ */
27
+ runtimeArgs?: string[];
28
+ /**
29
+ * Root directory to watch for file changes.
30
+ * @default process.cwd()
31
+ */
32
+ rootDir?: string;
33
+ /**
34
+ * Additional directories or glob patterns to watch.
35
+ * Merged with the default watched extensions (.ts, .js, .env, .json).
36
+ * Example: ['config', 'locales']
37
+ */
38
+ watchDirs?: string[];
39
+ /**
40
+ * File extensions to watch.
41
+ * @default ['.ts', '.js', '.mjs', '.cjs', '.json', '.env']
42
+ */
43
+ watchExtensions?: string[];
44
+ /**
45
+ * Patterns / file names to ignore in addition to the built-in ignores.
46
+ * Built-in ignores: node_modules, dist, .git, package.json, package-lock.json
47
+ * Example: ['coverage', 'tmp', 'myIgnored.json']
48
+ */
49
+ ignore?: string[];
50
+ /**
51
+ * Path to the .env file that should be hot-reloaded without restarting.
52
+ * @default '.env'
53
+ */
54
+ envFile?: string;
55
+ /**
56
+ * File extensions that support in-process hot reload (no server restart).
57
+ * All other watched extensions trigger a full server restart.
58
+ * @default ['.env', '.json']
59
+ */
60
+ hotReloadExtensions?: string[];
61
+ /**
62
+ * Milliseconds to wait after the last change before acting (debounce).
63
+ * Prevents rapid successive restarts when many files change at once.
64
+ * @default 300
65
+ */
66
+ debounceMs?: number;
67
+ /**
68
+ * Automatically restart the child process if it exits unexpectedly.
69
+ * @default true
70
+ */
71
+ restartOnCrash?: boolean;
72
+ /**
73
+ * Maximum number of automatic restarts on crash before giving up.
74
+ * @default 5
75
+ */
76
+ maxCrashRestarts?: number;
77
+ }
78
+
9
79
  interface WebServerConstructorInterface {
10
80
  app: express.Application;
11
81
  loggerConfig: LoggerCore;
12
82
  localLanguage: string;
13
83
  environmentPath: any;
14
84
  corsOriginOptions?: Partial<CorsOptions> | null;
85
+ /**
86
+ * Enable hot reload in development mode.
87
+ * - true → use all defaults
88
+ * - HotReloadConfig → custom configuration
89
+ * The watcher starts automatically when onStartServer() is called.
90
+ * On code changes the HTTP server is closed gracefully and the process
91
+ * exits (code 0) so your external runner restarts it:
92
+ * tsx --watch src/index.ts | nodemon | node --watch dist/index.js
93
+ */
94
+ hotReload?: boolean | HotReloadConfig;
15
95
  }
16
96
 
17
97
  declare class WebServerCore {
18
98
  private serverUtility;
19
99
  private expressApp;
100
+ private container;
20
101
  private readonly localLanguage;
21
102
  private readonly loggerConfig;
22
103
  private readonly routerExpressApp;
@@ -24,16 +105,61 @@ declare class WebServerCore {
24
105
  private readonly environmentPath;
25
106
  private serverListenEvent;
26
107
  private dependenciesRegistered;
108
+ private readonly hotReloadCfg;
27
109
  constructor(paramsConstructor: WebServerConstructorInterface);
110
+ /**
111
+ *
112
+ * @param dependencies
113
+ */
28
114
  registerDependencies(dependencies: TDependency[]): void;
115
+ /**
116
+ *
117
+ * @param routers
118
+ * @param databaseCallback
119
+ * @param dependenciesProvider
120
+ */
29
121
  onStartServer(routers: TFeatureRoutes[], databaseCallback: (env: any) => void, dependenciesProvider?: TDependency[]): Server<typeof http.IncomingMessage, typeof http.ServerResponse> | undefined;
122
+ /**
123
+ *
124
+ * @param serverWeb
125
+ */
30
126
  onListeningOnServerEvent(serverWeb: Server): void;
127
+ /**
128
+ *
129
+ * @param serverWeb
130
+ */
31
131
  onRequestOnServerEvent(serverWeb: Server): void;
32
132
  /**
33
133
  *
34
134
  * @private
35
135
  */
36
136
  private loadTranslationFiles;
137
+ /**
138
+ * Resolve the final HotReloadConfig by merging constructor config with
139
+ * HMR environment variables.
140
+ *
141
+ * Priority (highest → lowest):
142
+ * 1. Constructor hotReload properties (explicit code-level config)
143
+ * 2. HMR_* env variables (runtime / per-environment config)
144
+ * 3. HotReloadWatcher internal defaults (built-in fallbacks)
145
+ *
146
+ * The watcher starts when:
147
+ * - constructor passed hotReload: true | HotReloadConfig
148
+ * - OR HMR_ENABLED=true in the .env file
149
+ */
150
+ private resolveHotReloadConfig;
151
+ /**
152
+ * Extract file extensions from glob patterns such as "src/** /*.ts".
153
+ * "src/** /*.ts"
154
+ * ".env" skipped, handled natively by the watcher
155
+ */
156
+ private hmrExtractExtensions;
157
+ /**
158
+ * Extract ignore names from glob patterns such as "node_modules/**".
159
+ * "node_modules/**" → "node_modules"
160
+ * "dist/**" → "dist"
161
+ */
162
+ private hmrExtractIgnore;
37
163
  /**
38
164
  *
39
165
  * @param allFeatureRoutes
@@ -54,6 +180,54 @@ declare class WebServerCore {
54
180
 
55
181
  declare const envPath: string;
56
182
 
183
+ declare class HotReloadWatcher {
184
+ private readonly cfg;
185
+ private server;
186
+ private watchers;
187
+ private debounceTimer;
188
+ private restarting;
189
+ constructor(config?: HotReloadConfig);
190
+ attach(server: Server): Promise<void>;
191
+ private setupWatchers;
192
+ private watchRecursive;
193
+ private onFileChange;
194
+ private doHotReload;
195
+ private scheduleRestart;
196
+ /**
197
+ * Gracefully close the HTTP server so in-flight requests can finish,
198
+ * then exit with code 0 — the external runner restarts the process.
199
+ */
200
+ private closeAndExit;
201
+ private shouldIgnoreDir;
202
+ private shouldIgnoreFile;
203
+ private isWatched;
204
+ private isHotReloadable;
205
+ private isEnvFile;
206
+ private strip;
207
+ private ts;
208
+ /**
209
+ * Startup banner — same bgGreen box style as CoreService.infoServer().
210
+ *
211
+ * OPTICORE HOT RELOAD ← gradient
212
+ * ████████████████████████████████ ← bgGreen border
213
+ * root ./src
214
+ * watching .ts .js .json .env
215
+ * debounce 300ms
216
+ * ████████████████████████████████ ← bgGreen border
217
+ * watching for changes...
218
+ */
219
+ private printBanner;
220
+ /**
221
+ * ✔ [ HOT ] 14:23:45 | .env → env variables reloaded
222
+ */
223
+ private printHot;
224
+ /**
225
+ * ⚡ [ RELOAD ] 14:24:03 | src/routes/user.ts → restarting server...
226
+ */
227
+ private printReloading;
228
+ private setupProcessSignals;
229
+ }
230
+
57
231
  type KernelModuleType = [any[], () => void];
58
232
 
59
- export { type KernelModuleType, WebServerCore as WebServer, envPath };
233
+ export { type HotReloadConfig, HotReloadWatcher, type KernelModuleType, WebServerCore as WebServer, envPath };
package/dist/index.d.ts CHANGED
@@ -6,17 +6,98 @@ import { express } from 'opticore-express';
6
6
  import { LoggerCore } from 'opticore-logger';
7
7
  import { CorsOptions } from 'cors';
8
8
 
9
+ interface HotReloadConfig {
10
+ /**
11
+ * Entry point file to run.
12
+ * Reserved for future standalone mode — not used in integrated mode.
13
+ */
14
+ entry?: string;
15
+ /**
16
+ * Runtime to use for spawning the child process.
17
+ * - 'node' : compiled JS only, supports IPC hot reload for .env
18
+ * - 'tsx' : runs TypeScript directly via tsx
19
+ * - 'ts-node' : runs TypeScript directly via ts-node
20
+ * @default 'node'
21
+ */
22
+ runtime?: 'node' | 'tsx' | 'ts-node';
23
+ /**
24
+ * Extra arguments passed to the runtime before the entry file.
25
+ * Example: ['--experimental-specifier-resolution=node']
26
+ */
27
+ runtimeArgs?: string[];
28
+ /**
29
+ * Root directory to watch for file changes.
30
+ * @default process.cwd()
31
+ */
32
+ rootDir?: string;
33
+ /**
34
+ * Additional directories or glob patterns to watch.
35
+ * Merged with the default watched extensions (.ts, .js, .env, .json).
36
+ * Example: ['config', 'locales']
37
+ */
38
+ watchDirs?: string[];
39
+ /**
40
+ * File extensions to watch.
41
+ * @default ['.ts', '.js', '.mjs', '.cjs', '.json', '.env']
42
+ */
43
+ watchExtensions?: string[];
44
+ /**
45
+ * Patterns / file names to ignore in addition to the built-in ignores.
46
+ * Built-in ignores: node_modules, dist, .git, package.json, package-lock.json
47
+ * Example: ['coverage', 'tmp', 'myIgnored.json']
48
+ */
49
+ ignore?: string[];
50
+ /**
51
+ * Path to the .env file that should be hot-reloaded without restarting.
52
+ * @default '.env'
53
+ */
54
+ envFile?: string;
55
+ /**
56
+ * File extensions that support in-process hot reload (no server restart).
57
+ * All other watched extensions trigger a full server restart.
58
+ * @default ['.env', '.json']
59
+ */
60
+ hotReloadExtensions?: string[];
61
+ /**
62
+ * Milliseconds to wait after the last change before acting (debounce).
63
+ * Prevents rapid successive restarts when many files change at once.
64
+ * @default 300
65
+ */
66
+ debounceMs?: number;
67
+ /**
68
+ * Automatically restart the child process if it exits unexpectedly.
69
+ * @default true
70
+ */
71
+ restartOnCrash?: boolean;
72
+ /**
73
+ * Maximum number of automatic restarts on crash before giving up.
74
+ * @default 5
75
+ */
76
+ maxCrashRestarts?: number;
77
+ }
78
+
9
79
  interface WebServerConstructorInterface {
10
80
  app: express.Application;
11
81
  loggerConfig: LoggerCore;
12
82
  localLanguage: string;
13
83
  environmentPath: any;
14
84
  corsOriginOptions?: Partial<CorsOptions> | null;
85
+ /**
86
+ * Enable hot reload in development mode.
87
+ * - true → use all defaults
88
+ * - HotReloadConfig → custom configuration
89
+ * The watcher starts automatically when onStartServer() is called.
90
+ * On code changes the HTTP server is closed gracefully and the process
91
+ * exits (code 0) so your external runner restarts it:
92
+ * tsx --watch src/index.ts | nodemon | node --watch dist/index.js
93
+ */
94
+ hotReload?: boolean | HotReloadConfig;
15
95
  }
16
96
 
17
97
  declare class WebServerCore {
18
98
  private serverUtility;
19
99
  private expressApp;
100
+ private container;
20
101
  private readonly localLanguage;
21
102
  private readonly loggerConfig;
22
103
  private readonly routerExpressApp;
@@ -24,16 +105,61 @@ declare class WebServerCore {
24
105
  private readonly environmentPath;
25
106
  private serverListenEvent;
26
107
  private dependenciesRegistered;
108
+ private readonly hotReloadCfg;
27
109
  constructor(paramsConstructor: WebServerConstructorInterface);
110
+ /**
111
+ *
112
+ * @param dependencies
113
+ */
28
114
  registerDependencies(dependencies: TDependency[]): void;
115
+ /**
116
+ *
117
+ * @param routers
118
+ * @param databaseCallback
119
+ * @param dependenciesProvider
120
+ */
29
121
  onStartServer(routers: TFeatureRoutes[], databaseCallback: (env: any) => void, dependenciesProvider?: TDependency[]): Server<typeof http.IncomingMessage, typeof http.ServerResponse> | undefined;
122
+ /**
123
+ *
124
+ * @param serverWeb
125
+ */
30
126
  onListeningOnServerEvent(serverWeb: Server): void;
127
+ /**
128
+ *
129
+ * @param serverWeb
130
+ */
31
131
  onRequestOnServerEvent(serverWeb: Server): void;
32
132
  /**
33
133
  *
34
134
  * @private
35
135
  */
36
136
  private loadTranslationFiles;
137
+ /**
138
+ * Resolve the final HotReloadConfig by merging constructor config with
139
+ * HMR environment variables.
140
+ *
141
+ * Priority (highest → lowest):
142
+ * 1. Constructor hotReload properties (explicit code-level config)
143
+ * 2. HMR_* env variables (runtime / per-environment config)
144
+ * 3. HotReloadWatcher internal defaults (built-in fallbacks)
145
+ *
146
+ * The watcher starts when:
147
+ * - constructor passed hotReload: true | HotReloadConfig
148
+ * - OR HMR_ENABLED=true in the .env file
149
+ */
150
+ private resolveHotReloadConfig;
151
+ /**
152
+ * Extract file extensions from glob patterns such as "src/** /*.ts".
153
+ * "src/** /*.ts"
154
+ * ".env" skipped, handled natively by the watcher
155
+ */
156
+ private hmrExtractExtensions;
157
+ /**
158
+ * Extract ignore names from glob patterns such as "node_modules/**".
159
+ * "node_modules/**" → "node_modules"
160
+ * "dist/**" → "dist"
161
+ */
162
+ private hmrExtractIgnore;
37
163
  /**
38
164
  *
39
165
  * @param allFeatureRoutes
@@ -54,6 +180,54 @@ declare class WebServerCore {
54
180
 
55
181
  declare const envPath: string;
56
182
 
183
+ declare class HotReloadWatcher {
184
+ private readonly cfg;
185
+ private server;
186
+ private watchers;
187
+ private debounceTimer;
188
+ private restarting;
189
+ constructor(config?: HotReloadConfig);
190
+ attach(server: Server): Promise<void>;
191
+ private setupWatchers;
192
+ private watchRecursive;
193
+ private onFileChange;
194
+ private doHotReload;
195
+ private scheduleRestart;
196
+ /**
197
+ * Gracefully close the HTTP server so in-flight requests can finish,
198
+ * then exit with code 0 — the external runner restarts the process.
199
+ */
200
+ private closeAndExit;
201
+ private shouldIgnoreDir;
202
+ private shouldIgnoreFile;
203
+ private isWatched;
204
+ private isHotReloadable;
205
+ private isEnvFile;
206
+ private strip;
207
+ private ts;
208
+ /**
209
+ * Startup banner — same bgGreen box style as CoreService.infoServer().
210
+ *
211
+ * OPTICORE HOT RELOAD ← gradient
212
+ * ████████████████████████████████ ← bgGreen border
213
+ * root ./src
214
+ * watching .ts .js .json .env
215
+ * debounce 300ms
216
+ * ████████████████████████████████ ← bgGreen border
217
+ * watching for changes...
218
+ */
219
+ private printBanner;
220
+ /**
221
+ * ✔ [ HOT ] 14:23:45 | .env → env variables reloaded
222
+ */
223
+ private printHot;
224
+ /**
225
+ * ⚡ [ RELOAD ] 14:24:03 | src/routes/user.ts → restarting server...
226
+ */
227
+ private printReloading;
228
+ private setupProcessSignals;
229
+ }
230
+
57
231
  type KernelModuleType = [any[], () => void];
58
232
 
59
- export { type KernelModuleType, WebServerCore as WebServer, envPath };
233
+ export { type HotReloadConfig, HotReloadWatcher, type KernelModuleType, WebServerCore as WebServer, envPath };