@veloxts/cli 0.4.12 → 0.4.13

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 (54) hide show
  1. package/dist/cli.js +2 -2
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/dev.d.ts +4 -1
  4. package/dist/commands/dev.d.ts.map +1 -1
  5. package/dist/commands/dev.js +29 -15
  6. package/dist/commands/dev.js.map +1 -1
  7. package/dist/commands/make.d.ts +17 -0
  8. package/dist/commands/make.d.ts.map +1 -0
  9. package/dist/commands/make.js +219 -0
  10. package/dist/commands/make.js.map +1 -0
  11. package/dist/dev/error-parser.d.ts +67 -0
  12. package/dist/dev/error-parser.d.ts.map +1 -0
  13. package/dist/dev/error-parser.js +384 -0
  14. package/dist/dev/error-parser.js.map +1 -0
  15. package/dist/dev/hmr-runner.d.ts +67 -9
  16. package/dist/dev/hmr-runner.d.ts.map +1 -1
  17. package/dist/dev/hmr-runner.js +305 -57
  18. package/dist/dev/hmr-runner.js.map +1 -1
  19. package/dist/dev/index.d.ts +6 -0
  20. package/dist/dev/index.d.ts.map +1 -1
  21. package/dist/dev/index.js +8 -0
  22. package/dist/dev/index.js.map +1 -1
  23. package/dist/dev/reload-reporter.d.ts +197 -0
  24. package/dist/dev/reload-reporter.d.ts.map +1 -0
  25. package/dist/dev/reload-reporter.js +370 -0
  26. package/dist/dev/reload-reporter.js.map +1 -0
  27. package/dist/dev/timing-tracker.d.ts +130 -0
  28. package/dist/dev/timing-tracker.d.ts.map +1 -0
  29. package/dist/dev/timing-tracker.js +175 -0
  30. package/dist/dev/timing-tracker.js.map +1 -0
  31. package/dist/generators/generators/factory.d.ts +5 -5
  32. package/dist/generators/generators/factory.js +8 -8
  33. package/dist/generators/generators/migration.d.ts +7 -7
  34. package/dist/generators/generators/migration.js +12 -12
  35. package/dist/generators/generators/model.d.ts +7 -7
  36. package/dist/generators/generators/model.js +12 -12
  37. package/dist/generators/generators/procedure.d.ts +6 -6
  38. package/dist/generators/generators/procedure.js +12 -12
  39. package/dist/generators/generators/seeder.d.ts +5 -5
  40. package/dist/generators/generators/seeder.js +9 -9
  41. package/dist/generators/generators/seeder.js.map +1 -1
  42. package/dist/generators/types.d.ts +1 -1
  43. package/dist/generators/types.d.ts.map +1 -1
  44. package/dist/migrations/commands/run.js +1 -1
  45. package/dist/migrations/commands/run.js.map +1 -1
  46. package/dist/migrations/commands/status.js +1 -1
  47. package/dist/migrations/commands/status.js.map +1 -1
  48. package/dist/migrations/errors.js +1 -1
  49. package/dist/migrations/errors.js.map +1 -1
  50. package/dist/seeding/commands/seed.js +2 -2
  51. package/dist/seeding/commands/seed.js.map +1 -1
  52. package/dist/seeding/errors.js +1 -1
  53. package/dist/seeding/errors.js.map +1 -1
  54. package/package.json +6 -6
@@ -0,0 +1,384 @@
1
+ /**
2
+ * Error Parser - Analyzes development errors and provides actionable feedback
3
+ *
4
+ * Parses error messages and stack traces to identify error types, extract
5
+ * file locations, and generate helpful suggestions for resolution.
6
+ *
7
+ * Inspired by Vite's error overlay and Next.js's error page patterns.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const parsed = parseDevError(error);
12
+ *
13
+ * console.log(parsed.type); // 'syntax-error'
14
+ * console.log(parsed.filePath); // 'src/procedures/users.ts'
15
+ * console.log(parsed.line); // 42
16
+ * console.log(parsed.suggestion); // 'Check for missing closing bracket...'
17
+ * ```
18
+ */
19
+ // ============================================================================
20
+ // Error Detection Patterns
21
+ // ============================================================================
22
+ /**
23
+ * Patterns to identify error types from messages
24
+ */
25
+ const ERROR_TYPE_PATTERNS = [
26
+ {
27
+ type: 'syntax-error',
28
+ patterns: [
29
+ /SyntaxError/i,
30
+ /Unexpected token/i,
31
+ /Missing semicolon/i,
32
+ /Unexpected end of input/i,
33
+ /Invalid or unexpected token/i,
34
+ /Unterminated string/i,
35
+ /Expression expected/i,
36
+ /Declaration or statement expected/i,
37
+ ],
38
+ },
39
+ {
40
+ type: 'module-not-found',
41
+ patterns: [
42
+ /Cannot find module/i,
43
+ /Module not found/i,
44
+ /ERR_MODULE_NOT_FOUND/i,
45
+ /Cannot resolve module/i,
46
+ /Unable to resolve/i,
47
+ /Could not resolve/i,
48
+ ],
49
+ },
50
+ {
51
+ type: 'type-error',
52
+ patterns: [
53
+ /TypeError/i,
54
+ /Type '.*' is not assignable/i,
55
+ /Property '.*' does not exist/i,
56
+ /Argument of type/i,
57
+ /Cannot read propert/i,
58
+ /is not a function/i,
59
+ /undefined is not/i,
60
+ /null is not/i,
61
+ ],
62
+ },
63
+ {
64
+ type: 'database-error',
65
+ patterns: [
66
+ /PrismaClient/i,
67
+ /P\d{4}:/i, // Prisma error codes like P1001
68
+ /Connection refused/i,
69
+ /ECONNREFUSED.*5432/i, // PostgreSQL
70
+ /ECONNREFUSED.*3306/i, // MySQL
71
+ /database.*does not exist/i,
72
+ /relation.*does not exist/i,
73
+ ],
74
+ },
75
+ {
76
+ type: 'port-in-use',
77
+ patterns: [/EADDRINUSE/i, /address already in use/i, /port.*already.*bound/i],
78
+ },
79
+ {
80
+ type: 'permission-denied',
81
+ patterns: [/EACCES/i, /EPERM/i, /permission denied/i, /access denied/i],
82
+ },
83
+ {
84
+ type: 'hmr-failure',
85
+ patterns: [
86
+ /hot-hook/i,
87
+ /HMR.*failed/i,
88
+ /Hot.*update.*failed/i,
89
+ /Cannot apply update/i,
90
+ /Module.*cannot be hot-updated/i,
91
+ ],
92
+ },
93
+ ];
94
+ /**
95
+ * Patterns to extract file locations from error messages and stacks
96
+ */
97
+ const LOCATION_PATTERNS = [
98
+ // TypeScript/esbuild: path/file.ts:10:5
99
+ { regex: /([^\s(]+\.(?:ts|tsx|js|jsx|mjs|cjs)):(\d+):(\d+)/, fileGroup: 1, lineGroup: 2, columnGroup: 3 },
100
+ // Node.js: at Function (path/file.ts:10:5)
101
+ { regex: /at\s+.*\(([^)]+):(\d+):(\d+)\)/, fileGroup: 1, lineGroup: 2, columnGroup: 3 },
102
+ // Node.js: at path/file.ts:10:5
103
+ { regex: /at\s+([^\s]+):(\d+):(\d+)/, fileGroup: 1, lineGroup: 2, columnGroup: 3 },
104
+ // ESLint/Prettier style: path/file.ts(10,5)
105
+ { regex: /([^\s(]+\.(?:ts|tsx|js|jsx))\((\d+),(\d+)\)/, fileGroup: 1, lineGroup: 2, columnGroup: 3 },
106
+ // Simple: path/file.ts:10
107
+ { regex: /([^\s:]+\.(?:ts|tsx|js|jsx|mjs|cjs)):(\d+)(?:\s|$|:)/, fileGroup: 1, lineGroup: 2 },
108
+ ];
109
+ /**
110
+ * Suggestions mapped to error types
111
+ */
112
+ const ERROR_SUGGESTIONS = {
113
+ 'syntax-error': 'Check for missing brackets, parentheses, or semicolons. Ensure all strings and template literals are properly closed.',
114
+ 'module-not-found': 'Verify the import path is correct. Check if the module is installed (run pnpm install) and the file extension matches your imports.',
115
+ 'type-error': 'Check that all variables are properly typed and initialized. Verify the types match between function arguments and parameters.',
116
+ 'runtime-error': 'Add console.log statements or use a debugger to trace the code path. Check for null/undefined values.',
117
+ 'hmr-failure': 'This file may be outside HMR boundaries. Try editing a file in src/procedures/, src/schemas/, or src/handlers/ instead.',
118
+ 'database-error': 'Ensure your database is running and accessible. Check DATABASE_URL in .env matches your database configuration. Run `velox migrate:status` to check migration status.',
119
+ 'port-in-use': 'Another process is using this port. Stop other servers or use a different port with --port flag.',
120
+ 'permission-denied': 'Check file permissions. You may need to run with elevated privileges or fix ownership of the files.',
121
+ unknown: 'Check the full error message and stack trace for clues. Consider searching for the error message online.',
122
+ };
123
+ /**
124
+ * Help URLs for common error types
125
+ */
126
+ const ERROR_HELP_URLS = {
127
+ 'database-error': 'https://www.prisma.io/docs/reference/api-reference/error-reference',
128
+ 'module-not-found': 'https://nodejs.org/api/esm.html#resolution-algorithm',
129
+ };
130
+ // ============================================================================
131
+ // Core Parser Functions
132
+ // ============================================================================
133
+ /**
134
+ * Parse a development error into structured, actionable information.
135
+ *
136
+ * @param error - The error to parse
137
+ * @returns Parsed error with type, location, and suggestions
138
+ */
139
+ export function parseDevError(error) {
140
+ const errorText = formatErrorText(error);
141
+ const type = detectErrorType(errorText);
142
+ const location = extractLocation(errorText);
143
+ const message = cleanErrorMessage(error.message);
144
+ const suggestion = generateSuggestion(type, errorText);
145
+ const codeFrame = extractCodeFrame(errorText);
146
+ return {
147
+ originalError: error,
148
+ type,
149
+ message,
150
+ filePath: location?.filePath,
151
+ line: location?.line,
152
+ column: location?.column,
153
+ suggestion,
154
+ helpUrl: ERROR_HELP_URLS[type],
155
+ isRecoverable: isErrorRecoverable(type),
156
+ codeFrame,
157
+ };
158
+ }
159
+ /**
160
+ * Combine error message and stack for comprehensive analysis
161
+ */
162
+ function formatErrorText(error) {
163
+ const parts = [error.message];
164
+ if (error.stack) {
165
+ parts.push(error.stack);
166
+ }
167
+ // Include cause if present (Error.cause in ES2022+)
168
+ // Use proper type narrowing instead of type assertion
169
+ if ('cause' in error && error.cause instanceof Error) {
170
+ parts.push(`Caused by: ${error.cause.message}`);
171
+ if (error.cause.stack) {
172
+ parts.push(error.cause.stack);
173
+ }
174
+ }
175
+ return parts.join('\n');
176
+ }
177
+ /**
178
+ * Detect the error type from error text
179
+ */
180
+ function detectErrorType(errorText) {
181
+ for (const { type, patterns } of ERROR_TYPE_PATTERNS) {
182
+ for (const pattern of patterns) {
183
+ if (pattern.test(errorText)) {
184
+ return type;
185
+ }
186
+ }
187
+ }
188
+ return 'unknown';
189
+ }
190
+ /**
191
+ * Extract file location from error text
192
+ */
193
+ function extractLocation(errorText) {
194
+ for (const pattern of LOCATION_PATTERNS) {
195
+ const match = pattern.regex.exec(errorText);
196
+ if (match) {
197
+ const filePath = match[pattern.fileGroup];
198
+ const line = parseInt(match[pattern.lineGroup], 10);
199
+ const column = pattern.columnGroup ? parseInt(match[pattern.columnGroup], 10) : undefined;
200
+ // Skip internal node_modules paths unless they're the only match
201
+ if (!filePath.includes('node_modules/') || !hasUserCodeLocation(errorText)) {
202
+ return { filePath, line, column };
203
+ }
204
+ }
205
+ }
206
+ return null;
207
+ }
208
+ /**
209
+ * Check if error text contains a user code location (not node_modules)
210
+ */
211
+ function hasUserCodeLocation(errorText) {
212
+ for (const pattern of LOCATION_PATTERNS) {
213
+ const regex = new RegExp(pattern.regex.source, 'g');
214
+ let match;
215
+ while ((match = regex.exec(errorText)) !== null) {
216
+ const filePath = match[pattern.fileGroup];
217
+ if (!filePath.includes('node_modules/')) {
218
+ return true;
219
+ }
220
+ }
221
+ }
222
+ return false;
223
+ }
224
+ /**
225
+ * Clean up error message for display
226
+ */
227
+ function cleanErrorMessage(message) {
228
+ // Remove ANSI color codes
229
+ let cleaned = message.replace(/\x1b\[[0-9;]*m/g, '');
230
+ // Remove excessive whitespace
231
+ cleaned = cleaned.replace(/\s+/g, ' ').trim();
232
+ // Truncate very long messages
233
+ const maxLength = 200;
234
+ if (cleaned.length > maxLength) {
235
+ cleaned = `${cleaned.slice(0, maxLength)}...`;
236
+ }
237
+ return cleaned;
238
+ }
239
+ /**
240
+ * Generate contextual suggestion based on error type and content
241
+ */
242
+ function generateSuggestion(type, errorText) {
243
+ // Start with base suggestion for the error type
244
+ let suggestion = ERROR_SUGGESTIONS[type];
245
+ // Add contextual enhancements
246
+ if (type === 'module-not-found') {
247
+ // Extract module name for more specific advice
248
+ const moduleMatch = /Cannot find module ['"]([^'"]+)['"]/i.exec(errorText);
249
+ if (moduleMatch) {
250
+ const moduleName = moduleMatch[1];
251
+ if (moduleName.startsWith('.') || moduleName.startsWith('/')) {
252
+ suggestion = `Check that the file '${moduleName}' exists and the path is correct relative to the importing file.`;
253
+ }
254
+ else if (moduleName.startsWith('@')) {
255
+ suggestion = `Install the package: pnpm add ${moduleName}`;
256
+ }
257
+ else {
258
+ suggestion = `Install the package: pnpm add ${moduleName}`;
259
+ }
260
+ }
261
+ }
262
+ if (type === 'database-error') {
263
+ // Check for specific Prisma errors
264
+ if (/P1001/i.test(errorText)) {
265
+ suggestion = 'Cannot reach database server. Ensure your database is running and DATABASE_URL is correct.';
266
+ }
267
+ else if (/P1002/i.test(errorText)) {
268
+ suggestion = 'Database server timed out. Check if the database is overloaded or the connection is slow.';
269
+ }
270
+ else if (/P1003/i.test(errorText)) {
271
+ suggestion = 'Database does not exist. Run `velox migrate:run` to create and migrate the database.';
272
+ }
273
+ else if (/P2002/i.test(errorText)) {
274
+ suggestion = 'Unique constraint violation. A record with this value already exists.';
275
+ }
276
+ else if (/P2025/i.test(errorText)) {
277
+ suggestion = 'Record not found. The requested record does not exist in the database.';
278
+ }
279
+ }
280
+ if (type === 'syntax-error') {
281
+ // Check for common syntax issues
282
+ if (/Unexpected token.*export/i.test(errorText)) {
283
+ suggestion =
284
+ 'Ensure you\'re using ES modules syntax. Check that "type": "module" is in your package.json.';
285
+ }
286
+ else if (/Unexpected token.*import/i.test(errorText)) {
287
+ suggestion =
288
+ 'Check that your Node.js version supports ES modules (v14+) and "type": "module" is in package.json.';
289
+ }
290
+ }
291
+ return suggestion;
292
+ }
293
+ /**
294
+ * Extract code frame from error text if present
295
+ */
296
+ function extractCodeFrame(errorText) {
297
+ // Look for code frame patterns (common in esbuild, TypeScript, etc.)
298
+ // Pattern: line numbers followed by code, with > marking error line
299
+ const frameMatch = /(?:^|\n)((?:\s*\d+\s*│[^\n]*\n)+)/m.exec(errorText);
300
+ if (frameMatch) {
301
+ return frameMatch[1].trim();
302
+ }
303
+ // Alternative pattern: > marking with pipe separators
304
+ const altFrameMatch = /(?:^|\n)((?:\s*>?\s*\d+\s*\|[^\n]*\n)+)/m.exec(errorText);
305
+ if (altFrameMatch) {
306
+ return altFrameMatch[1].trim();
307
+ }
308
+ return undefined;
309
+ }
310
+ /**
311
+ * Determine if error is recoverable by editing files
312
+ */
313
+ function isErrorRecoverable(type) {
314
+ const recoverableTypes = [
315
+ 'syntax-error',
316
+ 'module-not-found',
317
+ 'type-error',
318
+ 'runtime-error',
319
+ 'hmr-failure',
320
+ ];
321
+ return recoverableTypes.includes(type);
322
+ }
323
+ // ============================================================================
324
+ // Utility Functions
325
+ // ============================================================================
326
+ /**
327
+ * Check if an error is a development-time error vs a fatal/configuration error
328
+ */
329
+ export function isDevelopmentError(error) {
330
+ const parsed = parseDevError(error);
331
+ return parsed.isRecoverable;
332
+ }
333
+ /**
334
+ * Get a short, displayable error type label
335
+ */
336
+ export function getErrorTypeLabel(type) {
337
+ const labels = {
338
+ 'syntax-error': 'Syntax Error',
339
+ 'module-not-found': 'Module Not Found',
340
+ 'type-error': 'Type Error',
341
+ 'runtime-error': 'Runtime Error',
342
+ 'hmr-failure': 'HMR Failed',
343
+ 'database-error': 'Database Error',
344
+ 'port-in-use': 'Port In Use',
345
+ 'permission-denied': 'Permission Denied',
346
+ unknown: 'Error',
347
+ };
348
+ return labels[type];
349
+ }
350
+ /**
351
+ * Format parsed error for console output
352
+ */
353
+ export function formatParsedError(parsed) {
354
+ const parts = [];
355
+ // Error type and message
356
+ parts.push(`${getErrorTypeLabel(parsed.type)}: ${parsed.message}`);
357
+ // Location
358
+ if (parsed.filePath) {
359
+ let location = ` at ${parsed.filePath}`;
360
+ if (parsed.line) {
361
+ location += `:${parsed.line}`;
362
+ if (parsed.column) {
363
+ location += `:${parsed.column}`;
364
+ }
365
+ }
366
+ parts.push(location);
367
+ }
368
+ // Code frame
369
+ if (parsed.codeFrame) {
370
+ parts.push('');
371
+ parts.push(parsed.codeFrame);
372
+ }
373
+ // Suggestion
374
+ if (parsed.suggestion) {
375
+ parts.push('');
376
+ parts.push(` Suggestion: ${parsed.suggestion}`);
377
+ }
378
+ // Help URL
379
+ if (parsed.helpUrl) {
380
+ parts.push(` More info: ${parsed.helpUrl}`);
381
+ }
382
+ return parts.join('\n');
383
+ }
384
+ //# sourceMappingURL=error-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-parser.js","sourceRoot":"","sources":["../../src/dev/error-parser.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  /**
2
- * HMR Runner - Experimental Hot Module Replacement
2
+ * HMR Runner - Hot Module Replacement for Development
3
3
  *
4
- * Uses hot-hook library to enable module replacement without full process restart.
5
- * This is marked as experimental and may not work for all use cases.
4
+ * Manages a Node.js process with hot-hook enabled for fast module replacement.
5
+ * Provides rich feedback with timing information and helpful error messages.
6
6
  *
7
7
  * @see https://github.com/Julien-R44/hot-hook
8
8
  */
@@ -18,32 +18,90 @@ export interface HMRRunnerOptions {
18
18
  readonly host: string;
19
19
  /** Environment variables to pass */
20
20
  readonly env?: Record<string, string>;
21
+ /** Show detailed timing and reload information */
22
+ readonly verbose?: boolean;
23
+ /** Enable debug logging and request tracing */
24
+ readonly debug?: boolean;
25
+ /** Clear console on full restart */
26
+ readonly clearOnRestart?: boolean;
21
27
  }
22
28
  /**
23
29
  * HMR Runner manages a Node.js process with hot-hook enabled
24
- * for experimental hot module replacement.
30
+ * for fast hot module replacement during development.
25
31
  */
26
32
  export declare class HMRRunner {
27
33
  private readonly options;
28
34
  private child;
29
35
  private isShuttingDown;
30
- private restartCount;
36
+ private isStartingUp;
37
+ private startupTimer;
38
+ private readonly timing;
39
+ private readonly reporter;
31
40
  constructor(options: HMRRunnerOptions);
32
41
  /**
33
42
  * Start the HMR-enabled development server
34
43
  */
35
44
  start(): Promise<void>;
36
45
  /**
37
- * Stop the HMR runner
46
+ * Stop the HMR runner gracefully
38
47
  */
39
48
  stop(): Promise<void>;
40
49
  /**
41
- * Restart the process (used when HMR fails)
50
+ * Restart the process (called when HMR fails or non-boundary file changes)
51
+ */
52
+ private restart;
53
+ /**
54
+ * Spawn the Node.js process with hot-hook enabled
42
55
  */
43
- restart(): Promise<void>;
44
- private printHMRBanner;
45
56
  private spawnProcess;
57
+ /**
58
+ * Setup detection for when the server is ready
59
+ */
60
+ private setupStartupDetection;
61
+ /**
62
+ * Report that startup is complete
63
+ */
64
+ private reportStartupComplete;
65
+ /**
66
+ * Handle IPC messages from hot-hook
67
+ */
68
+ private handleIPCMessage;
69
+ /**
70
+ * Handle successful hot module update
71
+ */
72
+ private handleHotUpdate;
73
+ /**
74
+ * Handle request for full process reload
75
+ */
76
+ private handleFullReloadRequest;
77
+ /**
78
+ * Handle HMR-specific error
79
+ */
80
+ private handleHMRError;
81
+ /**
82
+ * Handle process spawn/runtime errors
83
+ */
84
+ private handleProcessError;
85
+ /**
86
+ * Handle process exit
87
+ */
88
+ private handleProcessExit;
89
+ /**
90
+ * Handle restart failure
91
+ */
92
+ private handleRestartError;
93
+ /**
94
+ * Report a fatal error that cannot be recovered
95
+ */
96
+ private reportFatalError;
97
+ /**
98
+ * Setup process signal handlers for graceful shutdown
99
+ */
46
100
  private setupSignalHandlers;
101
+ /**
102
+ * Get basename from file path
103
+ */
104
+ private getBasename;
47
105
  }
48
106
  /**
49
107
  * Run the development server with HMR enabled
@@ -1 +1 @@
1
- {"version":3,"file":"hmr-runner.d.ts","sourceRoot":"","sources":["../../src/dev/hmr-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAED;;;GAGG;AACH,qBAAa,SAAS;IAKR,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAK;gBAEI,OAAO,EAAE,gBAAgB;IAEtD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB3B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAe9B,OAAO,CAAC,cAAc;YAYR,YAAY;IAyD1B,OAAO,CAAC,mBAAmB;CAW5B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E"}
1
+ {"version":3,"file":"hmr-runner.d.ts","sourceRoot":"","sources":["../../src/dev/hmr-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4CH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,kDAAkD;IAClD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,oCAAoC;IACpC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AAsDD;;;GAGG;AACH,qBAAa,SAAS;IAUR,OAAO,CAAC,QAAQ,CAAC,OAAO;IATpC,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAA8C;IAGlE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;gBAEb,OAAO,EAAE,gBAAgB;IAYtD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsC3B;;OAEG;YACW,OAAO;IAqBrB;;OAEG;YACW,YAAY;IA8B1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAkB7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAe7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA8BxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAavB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAU/B;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyB1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA6BzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAK1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAgB3B;;OAEG;IACH,OAAO,CAAC,WAAW;CAIpB;AAMD;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E"}