@buenojs/bueno 0.8.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 (120) hide show
  1. package/.env.example +109 -0
  2. package/.github/workflows/ci.yml +31 -0
  3. package/LICENSE +21 -0
  4. package/README.md +892 -0
  5. package/architecture.md +652 -0
  6. package/bun.lock +70 -0
  7. package/dist/cli/index.js +3233 -0
  8. package/dist/index.js +9014 -0
  9. package/package.json +77 -0
  10. package/src/cache/index.ts +795 -0
  11. package/src/cli/ARCHITECTURE.md +837 -0
  12. package/src/cli/bin.ts +10 -0
  13. package/src/cli/commands/build.ts +425 -0
  14. package/src/cli/commands/dev.ts +248 -0
  15. package/src/cli/commands/generate.ts +541 -0
  16. package/src/cli/commands/help.ts +55 -0
  17. package/src/cli/commands/index.ts +112 -0
  18. package/src/cli/commands/migration.ts +355 -0
  19. package/src/cli/commands/new.ts +804 -0
  20. package/src/cli/commands/start.ts +208 -0
  21. package/src/cli/core/args.ts +283 -0
  22. package/src/cli/core/console.ts +349 -0
  23. package/src/cli/core/index.ts +60 -0
  24. package/src/cli/core/prompt.ts +424 -0
  25. package/src/cli/core/spinner.ts +265 -0
  26. package/src/cli/index.ts +135 -0
  27. package/src/cli/templates/deploy.ts +295 -0
  28. package/src/cli/templates/docker.ts +307 -0
  29. package/src/cli/templates/index.ts +24 -0
  30. package/src/cli/utils/fs.ts +428 -0
  31. package/src/cli/utils/index.ts +8 -0
  32. package/src/cli/utils/strings.ts +197 -0
  33. package/src/config/env.ts +408 -0
  34. package/src/config/index.ts +506 -0
  35. package/src/config/loader.ts +329 -0
  36. package/src/config/merge.ts +285 -0
  37. package/src/config/types.ts +320 -0
  38. package/src/config/validation.ts +441 -0
  39. package/src/container/forward-ref.ts +143 -0
  40. package/src/container/index.ts +386 -0
  41. package/src/context/index.ts +360 -0
  42. package/src/database/index.ts +1142 -0
  43. package/src/database/migrations/index.ts +371 -0
  44. package/src/database/schema/index.ts +619 -0
  45. package/src/frontend/api-routes.ts +640 -0
  46. package/src/frontend/bundler.ts +643 -0
  47. package/src/frontend/console-client.ts +419 -0
  48. package/src/frontend/console-stream.ts +587 -0
  49. package/src/frontend/dev-server.ts +846 -0
  50. package/src/frontend/file-router.ts +611 -0
  51. package/src/frontend/frameworks/index.ts +106 -0
  52. package/src/frontend/frameworks/react.ts +85 -0
  53. package/src/frontend/frameworks/solid.ts +104 -0
  54. package/src/frontend/frameworks/svelte.ts +110 -0
  55. package/src/frontend/frameworks/vue.ts +92 -0
  56. package/src/frontend/hmr-client.ts +663 -0
  57. package/src/frontend/hmr.ts +728 -0
  58. package/src/frontend/index.ts +342 -0
  59. package/src/frontend/islands.ts +552 -0
  60. package/src/frontend/isr.ts +555 -0
  61. package/src/frontend/layout.ts +475 -0
  62. package/src/frontend/ssr/react.ts +446 -0
  63. package/src/frontend/ssr/solid.ts +523 -0
  64. package/src/frontend/ssr/svelte.ts +546 -0
  65. package/src/frontend/ssr/vue.ts +504 -0
  66. package/src/frontend/ssr.ts +699 -0
  67. package/src/frontend/types.ts +2274 -0
  68. package/src/health/index.ts +604 -0
  69. package/src/index.ts +410 -0
  70. package/src/lock/index.ts +587 -0
  71. package/src/logger/index.ts +444 -0
  72. package/src/logger/transports/index.ts +969 -0
  73. package/src/metrics/index.ts +494 -0
  74. package/src/middleware/built-in.ts +360 -0
  75. package/src/middleware/index.ts +94 -0
  76. package/src/modules/filters.ts +458 -0
  77. package/src/modules/guards.ts +405 -0
  78. package/src/modules/index.ts +1256 -0
  79. package/src/modules/interceptors.ts +574 -0
  80. package/src/modules/lazy.ts +418 -0
  81. package/src/modules/lifecycle.ts +478 -0
  82. package/src/modules/metadata.ts +90 -0
  83. package/src/modules/pipes.ts +626 -0
  84. package/src/router/index.ts +339 -0
  85. package/src/router/linear.ts +371 -0
  86. package/src/router/regex.ts +292 -0
  87. package/src/router/tree.ts +562 -0
  88. package/src/rpc/index.ts +1263 -0
  89. package/src/security/index.ts +436 -0
  90. package/src/ssg/index.ts +631 -0
  91. package/src/storage/index.ts +456 -0
  92. package/src/telemetry/index.ts +1097 -0
  93. package/src/testing/index.ts +1586 -0
  94. package/src/types/index.ts +236 -0
  95. package/src/types/optional-deps.d.ts +219 -0
  96. package/src/validation/index.ts +276 -0
  97. package/src/websocket/index.ts +1004 -0
  98. package/tests/integration/cli.test.ts +1016 -0
  99. package/tests/integration/fullstack.test.ts +234 -0
  100. package/tests/unit/cache.test.ts +174 -0
  101. package/tests/unit/cli-commands.test.ts +892 -0
  102. package/tests/unit/cli.test.ts +1258 -0
  103. package/tests/unit/container.test.ts +279 -0
  104. package/tests/unit/context.test.ts +221 -0
  105. package/tests/unit/database.test.ts +183 -0
  106. package/tests/unit/linear-router.test.ts +280 -0
  107. package/tests/unit/lock.test.ts +336 -0
  108. package/tests/unit/middleware.test.ts +184 -0
  109. package/tests/unit/modules.test.ts +142 -0
  110. package/tests/unit/pubsub.test.ts +257 -0
  111. package/tests/unit/regex-router.test.ts +265 -0
  112. package/tests/unit/router.test.ts +373 -0
  113. package/tests/unit/rpc.test.ts +1248 -0
  114. package/tests/unit/security.test.ts +174 -0
  115. package/tests/unit/telemetry.test.ts +371 -0
  116. package/tests/unit/test-cache.test.ts +110 -0
  117. package/tests/unit/test-database.test.ts +282 -0
  118. package/tests/unit/tree-router.test.ts +325 -0
  119. package/tests/unit/validation.test.ts +794 -0
  120. package/tsconfig.json +27 -0
@@ -0,0 +1,2274 @@
1
+ /**
2
+ * TypeScript interfaces for the Frontend Integration Layer
3
+ *
4
+ * Provides type definitions for the development server,
5
+ * framework detection, and frontend-related configurations.
6
+ */
7
+
8
+ // ============= Framework Types =============
9
+
10
+ /**
11
+ * Supported frontend frameworks
12
+ */
13
+ export type FrontendFramework = 'react' | 'vue' | 'svelte' | 'solid';
14
+
15
+ /**
16
+ * Framework detection mode
17
+ */
18
+ export type FrameworkDetectionMode = FrontendFramework | 'auto';
19
+
20
+ // ============= Dev Server Configuration =============
21
+
22
+ /**
23
+ * Development server configuration options
24
+ */
25
+ export interface DevServerConfig {
26
+ /**
27
+ * Port number for the dev server
28
+ * @default 3000
29
+ */
30
+ port: number;
31
+
32
+ /**
33
+ * Hostname for the dev server
34
+ * @default 'localhost'
35
+ */
36
+ hostname: string;
37
+
38
+ /**
39
+ * Project root directory
40
+ */
41
+ rootDir: string;
42
+
43
+ /**
44
+ * Static files directory (relative to rootDir)
45
+ * @default 'public'
46
+ */
47
+ publicDir: string;
48
+
49
+ /**
50
+ * Pages directory (relative to rootDir)
51
+ * @default 'pages'
52
+ */
53
+ pagesDir: string;
54
+
55
+ /**
56
+ * Enable Hot Module Replacement
57
+ * @default true
58
+ */
59
+ hmr: boolean;
60
+
61
+ /**
62
+ * Frontend framework to use
63
+ * 'auto' will detect from package.json dependencies
64
+ * @default 'auto'
65
+ */
66
+ framework: FrameworkDetectionMode;
67
+
68
+ /**
69
+ * Console streaming configuration
70
+ * Browser console output will be streamed to terminal
71
+ */
72
+ consoleStream?: PartialConsoleStreamConfig;
73
+ }
74
+
75
+ /**
76
+ * Partial configuration for creating a dev server
77
+ */
78
+ export type PartialDevServerConfig = Partial<DevServerConfig> & Pick<DevServerConfig, 'rootDir'>;
79
+
80
+ // ============= Server State Types =============
81
+
82
+ /**
83
+ * Runtime state of the development server
84
+ */
85
+ export interface DevServerState {
86
+ /**
87
+ * Whether the server is currently running
88
+ */
89
+ running: boolean;
90
+
91
+ /**
92
+ * Port the server is listening on
93
+ */
94
+ port: number;
95
+
96
+ /**
97
+ * Hostname the server is bound to
98
+ */
99
+ hostname: string;
100
+
101
+ /**
102
+ * Detected or configured framework
103
+ */
104
+ framework: FrontendFramework;
105
+
106
+ /**
107
+ * Server start time
108
+ */
109
+ startTime: Date | null;
110
+
111
+ /**
112
+ * Number of active connections
113
+ */
114
+ activeConnections: number;
115
+ }
116
+
117
+ // ============= Request Handling Types =============
118
+
119
+ /**
120
+ * Information about an incoming request
121
+ */
122
+ export interface RequestInfo {
123
+ /**
124
+ * HTTP method
125
+ */
126
+ method: string;
127
+
128
+ /**
129
+ * Request URL
130
+ */
131
+ url: URL;
132
+
133
+ /**
134
+ * Request path
135
+ */
136
+ path: string;
137
+
138
+ /**
139
+ * Request headers
140
+ */
141
+ headers: Headers;
142
+
143
+ /**
144
+ * Query parameters
145
+ */
146
+ query: URLSearchParams;
147
+ }
148
+
149
+ /**
150
+ * Result of file resolution for a request
151
+ */
152
+ export interface FileResolution {
153
+ /**
154
+ * Whether a file was found
155
+ */
156
+ found: boolean;
157
+
158
+ /**
159
+ * Absolute path to the file
160
+ */
161
+ filePath?: string;
162
+
163
+ /**
164
+ * Content type of the file
165
+ */
166
+ contentType?: string;
167
+
168
+ /**
169
+ * Whether this is an index.html fallback
170
+ */
171
+ isFallback?: boolean;
172
+ }
173
+
174
+ // ============= Framework Detection Types =============
175
+
176
+ /**
177
+ * Package.json dependency information for framework detection
178
+ */
179
+ export interface PackageDependencies {
180
+ [key: string]: string;
181
+ }
182
+
183
+ /**
184
+ * Result of framework detection
185
+ */
186
+ export interface FrameworkDetectionResult {
187
+ /**
188
+ * Detected framework
189
+ */
190
+ framework: FrontendFramework;
191
+
192
+ /**
193
+ * Whether detection was successful
194
+ */
195
+ detected: boolean;
196
+
197
+ /**
198
+ * Source of detection ('package.json' or 'config')
199
+ */
200
+ source: 'package.json' | 'config';
201
+ }
202
+
203
+ // ============= Build/Transform Types =============
204
+
205
+ /**
206
+ * Result of transforming a file
207
+ */
208
+ export interface TransformResult {
209
+ /**
210
+ * Transformed content
211
+ */
212
+ content: string;
213
+
214
+ /**
215
+ * Content type
216
+ */
217
+ contentType: string;
218
+
219
+ /**
220
+ * Source map (if applicable)
221
+ */
222
+ sourceMap?: string;
223
+ }
224
+
225
+ /**
226
+ * Options for file transformation
227
+ */
228
+ export interface TransformOptions {
229
+ /**
230
+ * File path being transformed
231
+ */
232
+ filePath: string;
233
+
234
+ /**
235
+ * Original content
236
+ */
237
+ content: string;
238
+
239
+ /**
240
+ * Target framework
241
+ */
242
+ framework: FrontendFramework;
243
+
244
+ /**
245
+ * Whether to generate source maps
246
+ */
247
+ sourceMap?: boolean;
248
+ }
249
+
250
+ // ============= Middleware Types =============
251
+
252
+ /**
253
+ * Dev server middleware function
254
+ */
255
+ export type DevServerMiddleware = (
256
+ request: Request,
257
+ next: () => Promise<Response>
258
+ ) => Response | Promise<Response>;
259
+
260
+ // ============= Event Types =============
261
+
262
+ /**
263
+ * Dev server event types
264
+ */
265
+ export type DevServerEvent =
266
+ | { type: 'start'; port: number; hostname: string }
267
+ | { type: 'stop'; reason?: string }
268
+ | { type: 'request'; method: string; path: string; duration: number }
269
+ | { type: 'error'; error: Error }
270
+ | { type: 'file-change'; path: string }
271
+ | { type: 'framework-detected'; framework: FrontendFramework };
272
+
273
+ /**
274
+ * Dev server event listener
275
+ */
276
+ export type DevServerEventListener = (event: DevServerEvent) => void;
277
+
278
+ // ============= Response Types =============
279
+
280
+ /**
281
+ * Standard error response
282
+ */
283
+ export interface ErrorResponse {
284
+ /**
285
+ * Error message
286
+ */
287
+ error: string;
288
+
289
+ /**
290
+ * HTTP status code
291
+ */
292
+ statusCode: number;
293
+
294
+ /**
295
+ * Optional stack trace (development only)
296
+ */
297
+ stack?: string;
298
+ }
299
+
300
+ // ============= HMR Types =============
301
+
302
+ /**
303
+ * HMR client connection information
304
+ */
305
+ export interface HMRClient {
306
+ /**
307
+ * Unique client identifier
308
+ */
309
+ id: string;
310
+
311
+ /**
312
+ * WebSocket connection
313
+ */
314
+ ws: WebSocket;
315
+
316
+ /**
317
+ * Set of file paths the client is subscribed to
318
+ */
319
+ subscribedFiles: Set<string>;
320
+ }
321
+
322
+ /**
323
+ * HMR update error information
324
+ */
325
+ export interface HMRUpdateError {
326
+ /**
327
+ * Error message
328
+ */
329
+ message: string;
330
+
331
+ /**
332
+ * Stack trace
333
+ */
334
+ stack?: string;
335
+
336
+ /**
337
+ * File where error occurred
338
+ */
339
+ file?: string;
340
+
341
+ /**
342
+ * Line number of error
343
+ */
344
+ line?: number;
345
+
346
+ /**
347
+ * Column number of error
348
+ */
349
+ column?: number;
350
+ }
351
+
352
+ /**
353
+ * HMR update message sent to clients
354
+ */
355
+ export interface HMRUpdate {
356
+ /**
357
+ * Type of update
358
+ */
359
+ type: 'update' | 'reload' | 'error';
360
+
361
+ /**
362
+ * Unique identifier for this update
363
+ */
364
+ fileId: string;
365
+
366
+ /**
367
+ * Timestamp of the update
368
+ */
369
+ timestamp: number;
370
+
371
+ /**
372
+ * List of changed file paths
373
+ */
374
+ changes: string[];
375
+
376
+ /**
377
+ * Error information if type is 'error'
378
+ */
379
+ error?: HMRUpdateError;
380
+ }
381
+
382
+ /**
383
+ * HMR configuration options
384
+ */
385
+ export interface HMRConfig {
386
+ /**
387
+ * Enable or disable HMR
388
+ * @default true
389
+ */
390
+ enabled: boolean;
391
+
392
+ /**
393
+ * WebSocket port for HMR
394
+ * Defaults to dev server port + 1
395
+ */
396
+ port?: number;
397
+
398
+ /**
399
+ * Debounce time for file changes in milliseconds
400
+ * @default 100
401
+ */
402
+ debounceMs: number;
403
+
404
+ /**
405
+ * File patterns to ignore for file watching
406
+ * @default ['node_modules', '.git', 'dist', 'build']
407
+ */
408
+ ignorePatterns: string[];
409
+ }
410
+
411
+ /**
412
+ * Partial HMR configuration for creating HMR manager
413
+ */
414
+ export type PartialHMRConfig = Partial<HMRConfig>;
415
+
416
+ /**
417
+ * HMR dependency graph entry
418
+ */
419
+ export interface HMRDependencyNode {
420
+ /**
421
+ * File path
422
+ */
423
+ filePath: string;
424
+
425
+ /**
426
+ * Files that this file imports
427
+ */
428
+ imports: Set<string>;
429
+
430
+ /**
431
+ * Files that import this file
432
+ */
433
+ importedBy: Set<string>;
434
+
435
+ /**
436
+ * Last modification timestamp
437
+ */
438
+ lastModified: number;
439
+ }
440
+
441
+ /**
442
+ * HMR module update result
443
+ */
444
+ export interface HMRModuleUpdate {
445
+ /**
446
+ * Module ID (file path)
447
+ */
448
+ moduleId: string;
449
+
450
+ /**
451
+ * Updated module code
452
+ */
453
+ code: string;
454
+
455
+ /**
456
+ * Whether the module accepts hot updates
457
+ */
458
+ accepted: boolean;
459
+
460
+ /**
461
+ * Dependencies that need to be updated
462
+ */
463
+ dependencies: string[];
464
+ }
465
+
466
+ /**
467
+ * HMR client message types
468
+ */
469
+ export type HMRClientMessage =
470
+ | { type: 'subscribe'; fileId: string }
471
+ | { type: 'unsubscribe'; fileId: string }
472
+ | { type: 'ping' }
473
+ | { type: 'module-accepted'; moduleId: string; dependencies: string[] };
474
+
475
+ /**
476
+ * HMR server message types
477
+ */
478
+ export type HMRServerMessage =
479
+ | HMRUpdate
480
+ | { type: 'pong' }
481
+ | { type: 'connected'; clientId: string };
482
+
483
+ /**
484
+ * File change event information
485
+ */
486
+ export interface FileChangeEvent {
487
+ /**
488
+ * Path to the changed file
489
+ */
490
+ path: string;
491
+
492
+ /**
493
+ * Type of change
494
+ */
495
+ event: 'create' | 'update' | 'delete';
496
+
497
+ /**
498
+ * Timestamp of the change
499
+ */
500
+ timestamp: number;
501
+ }
502
+
503
+ // ============= Console Stream Types =============
504
+
505
+ /**
506
+ * Console message types that can be captured
507
+ */
508
+ export type ConsoleMessageType = 'log' | 'info' | 'warn' | 'error' | 'debug' | 'trace' | 'table';
509
+
510
+ /**
511
+ * Console message captured from the browser
512
+ */
513
+ export interface ConsoleMessage {
514
+ /**
515
+ * Type of console method called
516
+ */
517
+ type: ConsoleMessageType;
518
+
519
+ /**
520
+ * Serialized arguments passed to console method
521
+ */
522
+ args: unknown[];
523
+
524
+ /**
525
+ * Timestamp when the message was created
526
+ */
527
+ timestamp: number;
528
+
529
+ /**
530
+ * Source file where console was called
531
+ */
532
+ file?: string;
533
+
534
+ /**
535
+ * Line number in source file
536
+ */
537
+ line?: number;
538
+
539
+ /**
540
+ * Column number in source file
541
+ */
542
+ column?: number;
543
+
544
+ /**
545
+ * Stack trace for errors
546
+ */
547
+ stack?: string;
548
+
549
+ /**
550
+ * Page URL where console was called
551
+ */
552
+ url?: string;
553
+ }
554
+
555
+ /**
556
+ * Configuration for console streaming
557
+ */
558
+ export interface ConsoleStreamConfig {
559
+ /**
560
+ * Enable or disable console streaming
561
+ * @default true
562
+ */
563
+ enabled: boolean;
564
+
565
+ /**
566
+ * Show timestamps in output
567
+ * @default true
568
+ */
569
+ showTimestamps: boolean;
570
+
571
+ /**
572
+ * Show file:line information
573
+ * @default true
574
+ */
575
+ showFile: boolean;
576
+
577
+ /**
578
+ * Colorize terminal output
579
+ * @default true
580
+ */
581
+ colorize: boolean;
582
+
583
+ /**
584
+ * Filter which console types to show
585
+ * Default: show all types
586
+ */
587
+ filter: ConsoleMessageType[];
588
+ }
589
+
590
+ /**
591
+ * Partial console stream configuration
592
+ */
593
+ export type PartialConsoleStreamConfig = Partial<ConsoleStreamConfig>;
594
+
595
+ /**
596
+ * Console stream client connection
597
+ */
598
+ export interface ConsoleStreamClient {
599
+ /**
600
+ * Unique client identifier
601
+ */
602
+ id: string;
603
+
604
+ /**
605
+ * WebSocket connection
606
+ */
607
+ ws: WebSocket;
608
+
609
+ /**
610
+ * Page URL of the client
611
+ */
612
+ url?: string;
613
+ }
614
+
615
+ /**
616
+ * Console message from client
617
+ */
618
+ export interface ConsoleClientMessage {
619
+ /**
620
+ * Message type identifier
621
+ */
622
+ type: 'console';
623
+
624
+ /**
625
+ * Console method called (log, warn, error, etc.)
626
+ */
627
+ consoleType: ConsoleMessageType;
628
+
629
+ /**
630
+ * Serialized arguments passed to console method
631
+ */
632
+ args: unknown[];
633
+
634
+ /**
635
+ * Timestamp when the message was created
636
+ */
637
+ timestamp: number;
638
+
639
+ /**
640
+ * Source file where console was called
641
+ */
642
+ file?: string;
643
+
644
+ /**
645
+ * Line number in source file
646
+ */
647
+ line?: number;
648
+
649
+ /**
650
+ * Column number in source file
651
+ */
652
+ column?: number;
653
+
654
+ /**
655
+ * Stack trace for errors
656
+ */
657
+ stack?: string;
658
+
659
+ /**
660
+ * Page URL where console was called
661
+ */
662
+ url?: string;
663
+ }
664
+
665
+ /**
666
+ * Server message for console stream
667
+ */
668
+ export type ConsoleServerMessage =
669
+ | { type: 'connected'; clientId: string }
670
+ | { type: 'pong' };
671
+
672
+ // ============= Bundler Types =============
673
+
674
+ /**
675
+ * Build plugin interface for framework-specific plugins
676
+ */
677
+ export interface BuildPlugin {
678
+ /**
679
+ * Plugin name
680
+ */
681
+ name: string;
682
+
683
+ /**
684
+ * Setup function called during build
685
+ */
686
+ setup?: (build: unknown) => void | Promise<void>;
687
+
688
+ /**
689
+ * Plugin namespace for module resolution
690
+ */
691
+ namespace?: string;
692
+ }
693
+
694
+ /**
695
+ * Source map generation options
696
+ */
697
+ export type SourcemapOption = 'linked' | 'external' | 'none';
698
+
699
+ /**
700
+ * Build target environment
701
+ */
702
+ export type BuildTarget = 'browser' | 'node' | 'bun';
703
+
704
+ /**
705
+ * Output module format
706
+ */
707
+ export type OutputFormat = 'esm' | 'cjs' | 'iife';
708
+
709
+ /**
710
+ * Bundler configuration options
711
+ */
712
+ export interface BundlerConfig {
713
+ /**
714
+ * Entry file(s) for the build
715
+ * Can be a single file or array of files
716
+ */
717
+ entryPoints: string | string[];
718
+
719
+ /**
720
+ * Output directory for built files
721
+ * @default 'dist'
722
+ */
723
+ outDir: string;
724
+
725
+ /**
726
+ * Frontend framework to use
727
+ * 'auto' will detect from package.json
728
+ * @default 'auto'
729
+ */
730
+ framework: FrontendFramework | 'auto';
731
+
732
+ /**
733
+ * Minify output
734
+ * @default true
735
+ */
736
+ minify: boolean;
737
+
738
+ /**
739
+ * Source map generation
740
+ * @default 'linked'
741
+ */
742
+ sourcemap: SourcemapOption;
743
+
744
+ /**
745
+ * Enable code splitting
746
+ * @default true
747
+ */
748
+ splitting: boolean;
749
+
750
+ /**
751
+ * Enable tree shaking
752
+ * @default true
753
+ */
754
+ treeshaking: boolean;
755
+
756
+ /**
757
+ * Environment variable prefix to include in build
758
+ * @default 'PUBLIC_'
759
+ */
760
+ envPrefix: string;
761
+
762
+ /**
763
+ * Global constants to define
764
+ */
765
+ define: Record<string, string>;
766
+
767
+ /**
768
+ * External dependencies to exclude from bundle
769
+ */
770
+ external: string[];
771
+
772
+ /**
773
+ * Build target environment
774
+ * @default 'browser'
775
+ */
776
+ target: BuildTarget;
777
+
778
+ /**
779
+ * Output module format
780
+ * @default 'esm'
781
+ */
782
+ format: OutputFormat;
783
+
784
+ /**
785
+ * Project root directory
786
+ * @default process.cwd()
787
+ */
788
+ rootDir?: string;
789
+
790
+ /**
791
+ * Public path for assets
792
+ */
793
+ publicPath?: string;
794
+
795
+ /**
796
+ * Generate build manifest
797
+ * @default true
798
+ */
799
+ manifest: boolean;
800
+
801
+ /**
802
+ * Environment mode
803
+ */
804
+ mode?: 'development' | 'production';
805
+ }
806
+
807
+ /**
808
+ * Partial bundler configuration
809
+ */
810
+ export type PartialBundlerConfig = Partial<BundlerConfig> & Pick<BundlerConfig, 'entryPoints'>;
811
+
812
+ /**
813
+ * Build output file information
814
+ */
815
+ export interface BuildOutput {
816
+ /**
817
+ * Output file path (relative to outDir)
818
+ */
819
+ path: string;
820
+
821
+ /**
822
+ * Type of output file
823
+ */
824
+ type: 'js' | 'css' | 'asset';
825
+
826
+ /**
827
+ * File size in bytes
828
+ */
829
+ size: number;
830
+
831
+ /**
832
+ * Content hash for cache busting
833
+ */
834
+ hash?: string;
835
+
836
+ /**
837
+ * Entry point this file belongs to
838
+ */
839
+ entryPoint?: string;
840
+
841
+ /**
842
+ * For JS files, list of imported modules
843
+ */
844
+ imports?: string[];
845
+
846
+ /**
847
+ * For JS files, list of dynamically imported modules
848
+ */
849
+ dynamicImports?: string[];
850
+
851
+ /**
852
+ * For CSS files, list of referenced assets
853
+ */
854
+ references?: string[];
855
+ }
856
+
857
+ /**
858
+ * Build error information
859
+ */
860
+ export interface BuildError {
861
+ /**
862
+ * Error message
863
+ */
864
+ message: string;
865
+
866
+ /**
867
+ * File where error occurred
868
+ */
869
+ file?: string;
870
+
871
+ /**
872
+ * Line number
873
+ */
874
+ line?: number;
875
+
876
+ /**
877
+ * Column number
878
+ */
879
+ column?: number;
880
+
881
+ /**
882
+ * Stack trace
883
+ */
884
+ stack?: string;
885
+ }
886
+
887
+ /**
888
+ * Build warning information
889
+ */
890
+ export interface BuildWarning {
891
+ /**
892
+ * Warning message
893
+ */
894
+ message: string;
895
+
896
+ /**
897
+ * File where warning occurred
898
+ */
899
+ file?: string;
900
+
901
+ /**
902
+ * Line number
903
+ */
904
+ line?: number;
905
+
906
+ /**
907
+ * Column number
908
+ */
909
+ column?: number;
910
+ }
911
+
912
+ /**
913
+ * Result of a production build
914
+ */
915
+ export interface BuildResult {
916
+ /**
917
+ * Whether the build succeeded
918
+ */
919
+ success: boolean;
920
+
921
+ /**
922
+ * Output files generated
923
+ */
924
+ outputs: BuildOutput[];
925
+
926
+ /**
927
+ * Build errors
928
+ */
929
+ errors: BuildError[];
930
+
931
+ /**
932
+ * Build warnings
933
+ */
934
+ warnings: BuildWarning[];
935
+
936
+ /**
937
+ * Build duration in milliseconds
938
+ */
939
+ duration: number;
940
+
941
+ /**
942
+ * Build manifest (if generated)
943
+ */
944
+ manifest?: BuildManifest;
945
+
946
+ /**
947
+ * Total output size in bytes
948
+ */
949
+ totalSize: number;
950
+ }
951
+
952
+ /**
953
+ * Framework-specific build configuration
954
+ */
955
+ export interface FrameworkBuildConfig {
956
+ /**
957
+ * JSX runtime to use
958
+ */
959
+ jsxRuntime: 'automatic' | 'classic';
960
+
961
+ /**
962
+ * JSX import source for automatic runtime
963
+ */
964
+ jsxImportSource?: string;
965
+
966
+ /**
967
+ * JSX fragment import source
968
+ */
969
+ jsxFragment?: string;
970
+
971
+ /**
972
+ * Framework-specific build plugins
973
+ */
974
+ plugins: BuildPlugin[];
975
+
976
+ /**
977
+ * Global constants for the framework
978
+ */
979
+ define: Record<string, string>;
980
+
981
+ /**
982
+ * External dependencies
983
+ */
984
+ external: string[];
985
+
986
+ /**
987
+ * File extensions to handle
988
+ */
989
+ extensions: string[];
990
+
991
+ /**
992
+ * Additional loader configurations
993
+ */
994
+ loaders?: Record<string, 'js' | 'jsx' | 'ts' | 'tsx' | 'css' | 'file' | 'dataurl' | 'text'>;
995
+ }
996
+
997
+ /**
998
+ * Build manifest for SSR integration
999
+ */
1000
+ export interface BuildManifest {
1001
+ /**
1002
+ * Entry points and their files
1003
+ */
1004
+ entryPoints: Record<string, string[]>;
1005
+
1006
+ /**
1007
+ * All output files
1008
+ */
1009
+ files: Record<string, {
1010
+ type: 'js' | 'css' | 'asset';
1011
+ size: number;
1012
+ hash?: string;
1013
+ imports?: string[];
1014
+ dynamicImports?: string[];
1015
+ }>;
1016
+
1017
+ /**
1018
+ * CSS files for each entry point
1019
+ */
1020
+ css: Record<string, string[]>;
1021
+
1022
+ /**
1023
+ * Build timestamp
1024
+ */
1025
+ timestamp: number;
1026
+
1027
+ /**
1028
+ * Build duration in ms
1029
+ */
1030
+ duration: number;
1031
+ }
1032
+
1033
+ /**
1034
+ * Bundle analysis result
1035
+ */
1036
+ export interface BundleAnalysis {
1037
+ /**
1038
+ * Total bundle size in bytes
1039
+ */
1040
+ totalSize: number;
1041
+
1042
+ /**
1043
+ * Size breakdown by module
1044
+ */
1045
+ modules: {
1046
+ path: string;
1047
+ size: number;
1048
+ percentage: number;
1049
+ }[];
1050
+
1051
+ /**
1052
+ * Duplicate code detection
1053
+ */
1054
+ duplicates: {
1055
+ module: string;
1056
+ occurrences: number;
1057
+ wastedBytes: number;
1058
+ }[];
1059
+
1060
+ /**
1061
+ * Large modules (>50KB)
1062
+ */
1063
+ largeModules: {
1064
+ path: string;
1065
+ size: number;
1066
+ }[];
1067
+
1068
+ /**
1069
+ * Dependency tree
1070
+ */
1071
+ dependencyTree: Record<string, string[]>;
1072
+ }
1073
+
1074
+ /**
1075
+ * Watch mode callback
1076
+ */
1077
+ export type BuildWatchCallback = (result: BuildResult) => void;
1078
+
1079
+ /**
1080
+ * Bundler state
1081
+ */
1082
+ export interface BundlerState {
1083
+ /**
1084
+ * Whether a build is in progress
1085
+ */
1086
+ building: boolean;
1087
+
1088
+ /**
1089
+ * Last build result
1090
+ */
1091
+ lastResult: BuildResult | null;
1092
+
1093
+ /**
1094
+ * Whether watch mode is active
1095
+ */
1096
+ watching: boolean;
1097
+
1098
+ /**
1099
+ * Detected framework
1100
+ */
1101
+ framework: FrontendFramework | null;
1102
+ }
1103
+
1104
+ // ============= SSR Types =============
1105
+
1106
+ /**
1107
+ * SSR element representation for head/body elements
1108
+ */
1109
+ export interface SSRElement {
1110
+ /**
1111
+ * HTML tag name
1112
+ */
1113
+ tag: string;
1114
+
1115
+ /**
1116
+ * HTML attributes
1117
+ */
1118
+ attrs: Record<string, string>;
1119
+
1120
+ /**
1121
+ * Child elements
1122
+ */
1123
+ children?: SSRElement[];
1124
+
1125
+ /**
1126
+ * Inner HTML content
1127
+ */
1128
+ innerHTML?: string;
1129
+ }
1130
+
1131
+ /**
1132
+ * SSR context passed to page components
1133
+ */
1134
+ export interface SSRContext {
1135
+ /**
1136
+ * Request URL
1137
+ */
1138
+ url: string;
1139
+
1140
+ /**
1141
+ * Original request object
1142
+ */
1143
+ request: Request;
1144
+
1145
+ /**
1146
+ * Response headers
1147
+ */
1148
+ headers: Headers;
1149
+
1150
+ /**
1151
+ * HTTP response status
1152
+ */
1153
+ status: number;
1154
+
1155
+ /**
1156
+ * Head elements to inject
1157
+ */
1158
+ head: SSRElement[];
1159
+
1160
+ /**
1161
+ * Body elements to inject
1162
+ */
1163
+ body: SSRElement[];
1164
+
1165
+ /**
1166
+ * Serialized data for client hydration
1167
+ */
1168
+ data: Record<string, unknown>;
1169
+
1170
+ /**
1171
+ * Loaded modules for preload
1172
+ */
1173
+ modules: Set<string>;
1174
+
1175
+ /**
1176
+ * URL pathname
1177
+ */
1178
+ pathname: string;
1179
+
1180
+ /**
1181
+ * Query parameters
1182
+ */
1183
+ query: URLSearchParams;
1184
+
1185
+ /**
1186
+ * Route parameters
1187
+ */
1188
+ params: Record<string, string>;
1189
+ }
1190
+
1191
+ /**
1192
+ * Result of rendering a page
1193
+ */
1194
+ export interface RenderResult {
1195
+ /**
1196
+ * Rendered HTML or stream
1197
+ */
1198
+ html: string | ReadableStream<Uint8Array>;
1199
+
1200
+ /**
1201
+ * Head content string
1202
+ */
1203
+ head: string;
1204
+
1205
+ /**
1206
+ * Body content string
1207
+ */
1208
+ body: string;
1209
+
1210
+ /**
1211
+ * Data for client hydration
1212
+ */
1213
+ data: Record<string, unknown>;
1214
+
1215
+ /**
1216
+ * Loaded modules
1217
+ */
1218
+ modules: string[];
1219
+
1220
+ /**
1221
+ * HTTP status code
1222
+ */
1223
+ status: number;
1224
+ }
1225
+
1226
+ /**
1227
+ * SSR page component interface
1228
+ */
1229
+ export interface SSRPage {
1230
+ /**
1231
+ * Render the page to HTML
1232
+ */
1233
+ render(ctx: SSRContext): Promise<RenderResult> | RenderResult;
1234
+
1235
+ /**
1236
+ * Server-side data fetching
1237
+ */
1238
+ getServerSideProps?(ctx: SSRContext): Promise<Record<string, unknown>>;
1239
+
1240
+ /**
1241
+ * Static paths for dynamic routes
1242
+ */
1243
+ getStaticPaths?(): Promise<{ paths: string[]; fallback: boolean }>;
1244
+ }
1245
+
1246
+ /**
1247
+ * SSR configuration options
1248
+ */
1249
+ export interface SSRConfig {
1250
+ /**
1251
+ * Server entry point file
1252
+ */
1253
+ entry: string;
1254
+
1255
+ /**
1256
+ * Client entry point for hydration
1257
+ */
1258
+ clientEntry: string;
1259
+
1260
+ /**
1261
+ * Build manifest from bundler
1262
+ */
1263
+ clientManifest: BuildManifest;
1264
+
1265
+ /**
1266
+ * Enable streaming SSR
1267
+ * @default true
1268
+ */
1269
+ streaming: boolean;
1270
+
1271
+ /**
1272
+ * Maximum await timeout in milliseconds
1273
+ * @default 5000
1274
+ */
1275
+ maxTimeout: number;
1276
+
1277
+ /**
1278
+ * Buffer initial stream for faster TTFB
1279
+ * @default true
1280
+ */
1281
+ bufferInitialStream: boolean;
1282
+
1283
+ /**
1284
+ * Framework to use for SSR
1285
+ */
1286
+ framework: FrontendFramework;
1287
+
1288
+ /**
1289
+ * Project root directory
1290
+ */
1291
+ rootDir?: string;
1292
+
1293
+ /**
1294
+ * Base HTML template
1295
+ */
1296
+ template?: string;
1297
+
1298
+ /**
1299
+ * Custom HTML template function
1300
+ */
1301
+ templateFn?: (ctx: SSRContext, content: string, head: string, body: string) => string;
1302
+ }
1303
+
1304
+ /**
1305
+ * Partial SSR configuration
1306
+ */
1307
+ export type PartialSSRConfig = Partial<SSRConfig> & Pick<SSRConfig, 'entry' | 'clientEntry' | 'clientManifest' | 'framework'>;
1308
+
1309
+ /**
1310
+ * Framework-specific SSR renderer
1311
+ */
1312
+ export interface FrameworkSSRRenderer {
1313
+ /**
1314
+ * Render a component to HTML string
1315
+ */
1316
+ renderToString(component: unknown, context: SSRContext): Promise<string>;
1317
+
1318
+ /**
1319
+ * Render a component to a stream
1320
+ */
1321
+ renderToStream(component: unknown, context: SSRContext): ReadableStream<Uint8Array>;
1322
+
1323
+ /**
1324
+ * Get head elements from component
1325
+ */
1326
+ getHeadElements(context: SSRContext): SSRElement[];
1327
+
1328
+ /**
1329
+ * Create the framework-specific component
1330
+ */
1331
+ createComponent(page: SSRPage, context: SSRContext): unknown;
1332
+ }
1333
+
1334
+ /**
1335
+ * SSR hydration data structure
1336
+ */
1337
+ export interface SSRHydrationData {
1338
+ /**
1339
+ * Page props
1340
+ */
1341
+ props: Record<string, unknown>;
1342
+
1343
+ /**
1344
+ * Current URL
1345
+ */
1346
+ url: string;
1347
+
1348
+ /**
1349
+ * Route parameters
1350
+ */
1351
+ params: Record<string, string>;
1352
+
1353
+ /**
1354
+ * Query parameters
1355
+ */
1356
+ query: Record<string, string>;
1357
+
1358
+ /**
1359
+ * Framework identifier
1360
+ */
1361
+ framework: FrontendFramework;
1362
+ }
1363
+
1364
+ /**
1365
+ * SSR error information
1366
+ */
1367
+ export interface SSRError {
1368
+ /**
1369
+ * Error message
1370
+ */
1371
+ message: string;
1372
+
1373
+ /**
1374
+ * Stack trace
1375
+ */
1376
+ stack?: string;
1377
+
1378
+ /**
1379
+ * Component where error occurred
1380
+ */
1381
+ component?: string;
1382
+
1383
+ /**
1384
+ * Error timestamp
1385
+ */
1386
+ timestamp: number;
1387
+ }
1388
+
1389
+ /**
1390
+ * SSR render options
1391
+ */
1392
+ export interface SSRRenderOptions {
1393
+ /**
1394
+ * Request URL
1395
+ */
1396
+ url: string;
1397
+
1398
+ /**
1399
+ * Original request
1400
+ */
1401
+ request: Request;
1402
+
1403
+ /**
1404
+ * Route parameters
1405
+ */
1406
+ params?: Record<string, string>;
1407
+
1408
+ /**
1409
+ * Additional props to pass to page
1410
+ */
1411
+ props?: Record<string, unknown>;
1412
+
1413
+ /**
1414
+ * Skip streaming and return string
1415
+ */
1416
+ skipStreaming?: boolean;
1417
+ }
1418
+
1419
+ /**
1420
+ * Preload link information
1421
+ */
1422
+ export interface PreloadLink {
1423
+ /**
1424
+ * Module path
1425
+ */
1426
+ href: string;
1427
+
1428
+ /**
1429
+ * Link rel type
1430
+ */
1431
+ rel: 'preload' | 'prefetch' | 'modulepreload';
1432
+
1433
+ /**
1434
+ * As attribute
1435
+ */
1436
+ as?: 'script' | 'style' | 'font' | 'image' | 'fetch';
1437
+
1438
+ /**
1439
+ * Additional attributes
1440
+ */
1441
+ attrs?: Record<string, string>;
1442
+ }
1443
+ // ============= ISR Types =============
1444
+
1445
+ /**
1446
+ * ISR cache entry
1447
+ */
1448
+ export interface ISRCacheEntry {
1449
+ /**
1450
+ * Rendered result
1451
+ */
1452
+ result: RenderResult;
1453
+
1454
+ /**
1455
+ * Timestamp when cached
1456
+ */
1457
+ timestamp: number;
1458
+
1459
+ /**
1460
+ * Revalidation time in seconds
1461
+ */
1462
+ revalidate: number;
1463
+
1464
+ /**
1465
+ * Tags for tag-based revalidation
1466
+ */
1467
+ tags: string[];
1468
+ }
1469
+
1470
+ /**
1471
+ * ISR page configuration
1472
+ */
1473
+ export interface ISRPageConfig {
1474
+ /**
1475
+ * Revalidation time in seconds
1476
+ */
1477
+ revalidate?: number;
1478
+
1479
+ /**
1480
+ * Tags for tag-based revalidation
1481
+ */
1482
+ tags?: string[];
1483
+
1484
+ /**
1485
+ * Enable stale-while-revalidate
1486
+ */
1487
+ staleWhileRevalidate?: number;
1488
+ }
1489
+
1490
+ /**
1491
+ * ISR configuration options
1492
+ */
1493
+ export interface ISRConfig {
1494
+ /**
1495
+ * Cache directory for ISR pages
1496
+ * @default '.isr-cache'
1497
+ */
1498
+ cacheDir: string;
1499
+
1500
+ /**
1501
+ * Default revalidation time in seconds
1502
+ * @default 3600 (1 hour)
1503
+ */
1504
+ defaultRevalidate: number;
1505
+
1506
+ /**
1507
+ * Stale-while-revalidate time in seconds
1508
+ * @default 60
1509
+ */
1510
+ staleWhileRevalidate: number;
1511
+
1512
+ /**
1513
+ * Maximum number of pages in cache
1514
+ */
1515
+ maxCacheSize: number;
1516
+
1517
+ /**
1518
+ * Redis client for distributed cache
1519
+ */
1520
+ redis?: {
1521
+ get(key: string): Promise<string | null>;
1522
+ set(key: string, value: string, options?: { EX?: number }): Promise<void>;
1523
+ del(...keys: string[]): Promise<void>;
1524
+ keys(pattern: string): Promise<string[]>;
1525
+ };
1526
+
1527
+ /**
1528
+ * Redis key prefix
1529
+ * @default 'bueno:isr:'
1530
+ */
1531
+ redisKeyPrefix: string;
1532
+
1533
+ /**
1534
+ * Enable ISR
1535
+ * @default true
1536
+ */
1537
+ enabled: boolean;
1538
+ }
1539
+
1540
+ /**
1541
+ * Partial ISR configuration
1542
+ */
1543
+ export type PartialISRConfig = Partial<ISRConfig>;
1544
+
1545
+ /**
1546
+ * ISR revalidation result
1547
+ */
1548
+ export interface ISRRevalidationResult {
1549
+ /**
1550
+ * Whether revalidation succeeded
1551
+ */
1552
+ success: boolean;
1553
+
1554
+ /**
1555
+ * URL that was revalidated
1556
+ */
1557
+ url: string;
1558
+
1559
+ /**
1560
+ * Duration in milliseconds
1561
+ */
1562
+ duration: number;
1563
+
1564
+ /**
1565
+ * Timestamp of revalidation
1566
+ */
1567
+ timestamp: number;
1568
+
1569
+ /**
1570
+ * Error message if failed
1571
+ */
1572
+ error?: string;
1573
+ }
1574
+
1575
+ /**
1576
+ * ISR statistics
1577
+ */
1578
+ export interface ISRStats {
1579
+ /**
1580
+ * Number of cache hits
1581
+ */
1582
+ hits: number;
1583
+
1584
+ /**
1585
+ * Number of cache misses
1586
+ */
1587
+ misses: number;
1588
+
1589
+ /**
1590
+ * Number of revalidations
1591
+ */
1592
+ revalidations: number;
1593
+
1594
+ /**
1595
+ * Number of stale hits (served stale while revalidating)
1596
+ */
1597
+ staleHits: number;
1598
+
1599
+ /**
1600
+ * Current cache size
1601
+ */
1602
+ cacheSize: number;
1603
+
1604
+ /**
1605
+ * Number of pending revalidations
1606
+ */
1607
+ pendingRevalidations: number;
1608
+
1609
+ /**
1610
+ * Cache hit rate (0-1)
1611
+ */
1612
+ hitRate: number;
1613
+ }
1614
+ // ============= Island Architecture Types =============
1615
+
1616
+ /**
1617
+ * Island hydration strategy
1618
+ */
1619
+ export type IslandHydrationStrategy = 'eager' | 'lazy' | 'visible' | 'idle';
1620
+
1621
+ /**
1622
+ * Island configuration options
1623
+ */
1624
+ export interface IslandConfig {
1625
+ /**
1626
+ * Unique island identifier
1627
+ */
1628
+ id: string;
1629
+
1630
+ /**
1631
+ * Hydration strategy
1632
+ * - eager: Hydrate immediately on page load
1633
+ * - lazy: Hydrate on user interaction (click, focus, etc.)
1634
+ * - visible: Hydrate when element enters viewport
1635
+ * - idle: Hydrate when browser is idle
1636
+ */
1637
+ strategy: IslandHydrationStrategy;
1638
+
1639
+ /**
1640
+ * Placeholder content before hydration
1641
+ */
1642
+ placeholder?: string;
1643
+ }
1644
+
1645
+ /**
1646
+ * Island definition for registration
1647
+ */
1648
+ export interface IslandDefinition {
1649
+ /**
1650
+ * Unique island identifier
1651
+ */
1652
+ id: string;
1653
+
1654
+ /**
1655
+ * Component name
1656
+ */
1657
+ component: string;
1658
+
1659
+ /**
1660
+ * Entry point for the island component
1661
+ */
1662
+ entry: string;
1663
+
1664
+ /**
1665
+ * Hydration strategy
1666
+ */
1667
+ strategy: IslandHydrationStrategy;
1668
+
1669
+ /**
1670
+ * CSS selector for the island
1671
+ */
1672
+ selector?: string;
1673
+
1674
+ /**
1675
+ * Additional props
1676
+ */
1677
+ props?: Record<string, unknown>;
1678
+ }
1679
+
1680
+ /**
1681
+ * Island registry type
1682
+ */
1683
+ export type IslandRegistry = Map<string, IslandDefinition>;
1684
+
1685
+ /**
1686
+ * Island render result
1687
+ */
1688
+ export interface IslandRenderResult {
1689
+ /**
1690
+ * Rendered HTML string
1691
+ */
1692
+ html: string;
1693
+
1694
+ /**
1695
+ * Island ID
1696
+ */
1697
+ id: string;
1698
+
1699
+ /**
1700
+ * Component name
1701
+ */
1702
+ component: string;
1703
+
1704
+ /**
1705
+ * Whether the island is hydrated
1706
+ */
1707
+ hydrated: boolean;
1708
+
1709
+ /**
1710
+ * Props passed to the island
1711
+ */
1712
+ props?: Record<string, unknown>;
1713
+
1714
+ /**
1715
+ * Hydration strategy used
1716
+ */
1717
+ strategy?: IslandHydrationStrategy;
1718
+
1719
+ /**
1720
+ * SSR content (if any)
1721
+ */
1722
+ ssrContent?: string;
1723
+ }
1724
+
1725
+ /**
1726
+ * Island state for client-side tracking
1727
+ */
1728
+ export interface IslandState {
1729
+ /**
1730
+ * Island ID
1731
+ */
1732
+ id: string;
1733
+
1734
+ /**
1735
+ * Component name
1736
+ */
1737
+ component: string;
1738
+
1739
+ /**
1740
+ * Props for the island
1741
+ */
1742
+ props: Record<string, unknown>;
1743
+
1744
+ /**
1745
+ * Hydration strategy
1746
+ */
1747
+ strategy: IslandHydrationStrategy;
1748
+
1749
+ /**
1750
+ * Whether the island is hydrated
1751
+ */
1752
+ hydrated: boolean;
1753
+ }
1754
+
1755
+ /**
1756
+ * Island hydration script info
1757
+ */
1758
+ export interface IslandHydrationScript {
1759
+ /**
1760
+ * Script content
1761
+ */
1762
+ script: string;
1763
+
1764
+ /**
1765
+ * Whether to inline the script
1766
+ */
1767
+ inline: boolean;
1768
+
1769
+ /**
1770
+ * Script type
1771
+ */
1772
+ type: 'module' | 'text/javascript';
1773
+ }
1774
+ // ============= File-based Routing Types =============
1775
+
1776
+ /**
1777
+ * Route type
1778
+ */
1779
+ export type RouteType = 'page' | 'api' | 'layout';
1780
+
1781
+ /**
1782
+ * Route definition from file
1783
+ */
1784
+ export interface RouteDefinition {
1785
+ /**
1786
+ * Unique route identifier
1787
+ */
1788
+ id: string;
1789
+
1790
+ /**
1791
+ * Route path (e.g., /users/:id)
1792
+ */
1793
+ path: string;
1794
+
1795
+ /**
1796
+ * Route pattern for matching
1797
+ */
1798
+ pattern: string;
1799
+
1800
+ /**
1801
+ * File path to the route module
1802
+ */
1803
+ filePath: string;
1804
+
1805
+ /**
1806
+ * Type of route
1807
+ */
1808
+ type: RouteType;
1809
+
1810
+ /**
1811
+ * Parameter names extracted from path
1812
+ */
1813
+ params: string[];
1814
+
1815
+ /**
1816
+ * Compiled regex for matching
1817
+ */
1818
+ regex: RegExp;
1819
+ }
1820
+
1821
+ /**
1822
+ * Dynamic route with parameter names
1823
+ */
1824
+ export interface DynamicRoute extends RouteDefinition {
1825
+ /**
1826
+ * Names of dynamic parameters
1827
+ */
1828
+ paramNames: string[];
1829
+ }
1830
+
1831
+ /**
1832
+ * Route match result
1833
+ */
1834
+ export interface RouteMatch {
1835
+ /**
1836
+ * Matched route definition
1837
+ */
1838
+ route: RouteDefinition;
1839
+
1840
+ /**
1841
+ * Extracted parameters
1842
+ */
1843
+ params: Record<string, string>;
1844
+ }
1845
+
1846
+ /**
1847
+ * Route handler function
1848
+ */
1849
+ export type RouteHandler = (request: Request) => Response | Promise<Response>;
1850
+
1851
+ /**
1852
+ * Route middleware function
1853
+ */
1854
+ export type RouteMiddleware = (
1855
+ request: Request,
1856
+ next: () => Promise<Response>
1857
+ ) => Response | Promise<Response>;
1858
+
1859
+ /**
1860
+ * File router configuration
1861
+ */
1862
+ export interface FileRouterConfig {
1863
+ /**
1864
+ * Pages directory path
1865
+ * @default 'pages'
1866
+ */
1867
+ pagesDir: string;
1868
+
1869
+ /**
1870
+ * API routes directory (relative to pagesDir)
1871
+ * @default 'api'
1872
+ */
1873
+ apiDir: string;
1874
+
1875
+ /**
1876
+ * Root directory for file scanning
1877
+ */
1878
+ rootDir: string;
1879
+
1880
+ /**
1881
+ * Supported file extensions
1882
+ * @default ['.tsx', '.ts', '.jsx', '.js']
1883
+ */
1884
+ extensions: string[];
1885
+
1886
+ /**
1887
+ * Enable file watching for hot reload
1888
+ * @default false
1889
+ */
1890
+ watch: boolean;
1891
+
1892
+ /**
1893
+ * Patterns to ignore during scanning
1894
+ */
1895
+ ignore: string[];
1896
+ }
1897
+
1898
+ /**
1899
+ * Partial file router configuration
1900
+ */
1901
+ export type PartialFileRouterConfig = Partial<FileRouterConfig>;
1902
+
1903
+ /**
1904
+ * File route options
1905
+ */
1906
+ export interface FileRouteOptions {
1907
+ /**
1908
+ * Route middleware
1909
+ */
1910
+ middleware?: RouteMiddleware[];
1911
+
1912
+ /**
1913
+ * Route metadata
1914
+ */
1915
+ meta?: Record<string, unknown>;
1916
+ }
1917
+ // ============= Layout Nesting Types =============
1918
+
1919
+ /**
1920
+ * Layout definition from file
1921
+ */
1922
+ export interface LayoutDefinition {
1923
+ /**
1924
+ * Unique layout identifier
1925
+ */
1926
+ id: string;
1927
+
1928
+ /**
1929
+ * File path to the layout module
1930
+ */
1931
+ filePath: string;
1932
+
1933
+ /**
1934
+ * Layout segment (e.g., "/", "/users")
1935
+ */
1936
+ segment: string;
1937
+
1938
+ /**
1939
+ * Depth in the layout tree
1940
+ */
1941
+ depth: number;
1942
+ }
1943
+
1944
+ /**
1945
+ * Layout tree node
1946
+ */
1947
+ export interface LayoutNode {
1948
+ /**
1949
+ * Layout definition
1950
+ */
1951
+ layout: LayoutDefinition;
1952
+
1953
+ /**
1954
+ * Parent node
1955
+ */
1956
+ parent: LayoutNode | null;
1957
+
1958
+ /**
1959
+ * Child nodes
1960
+ */
1961
+ children: LayoutNode[];
1962
+ }
1963
+
1964
+ /**
1965
+ * Layout tree structure
1966
+ */
1967
+ export type LayoutTree = LayoutNode;
1968
+
1969
+ /**
1970
+ * Layout props passed to layout components
1971
+ */
1972
+ export interface LayoutProps {
1973
+ /**
1974
+ * Child content (nested layouts or page)
1975
+ */
1976
+ children: string;
1977
+
1978
+ /**
1979
+ * Route parameters
1980
+ */
1981
+ params: Record<string, string>;
1982
+
1983
+ /**
1984
+ * Query parameters
1985
+ */
1986
+ query: URLSearchParams;
1987
+
1988
+ /**
1989
+ * Current pathname
1990
+ */
1991
+ pathname: string;
1992
+ }
1993
+
1994
+ /**
1995
+ * Layout renderer function
1996
+ */
1997
+ export type LayoutRenderer = (
1998
+ props: LayoutProps,
1999
+ context: SSRContext
2000
+ ) => Promise<string | LayoutRenderResult> | string | LayoutRenderResult;
2001
+
2002
+ /**
2003
+ * Layout middleware function
2004
+ */
2005
+ export type LayoutMiddleware = (
2006
+ props: LayoutProps,
2007
+ context: SSRContext,
2008
+ next: () => Promise<string>
2009
+ ) => Promise<string> | string;
2010
+
2011
+ /**
2012
+ * Layout configuration
2013
+ */
2014
+ export interface LayoutConfig {
2015
+ /**
2016
+ * Pages directory path
2017
+ * @default 'pages'
2018
+ */
2019
+ pagesDir: string;
2020
+
2021
+ /**
2022
+ * Root directory for file scanning
2023
+ */
2024
+ rootDir: string;
2025
+
2026
+ /**
2027
+ * Supported file extensions
2028
+ * @default ['.tsx', '.ts', '.jsx', '.js']
2029
+ */
2030
+ extensions: string[];
2031
+
2032
+ /**
2033
+ * Preserve layout state on navigation
2034
+ * @default true
2035
+ */
2036
+ preserveState: boolean;
2037
+ }
2038
+
2039
+ /**
2040
+ * Partial layout configuration
2041
+ */
2042
+ export type PartialLayoutConfig = Partial<LayoutConfig>;
2043
+
2044
+ /**
2045
+ * Layout render result
2046
+ */
2047
+ export interface LayoutRenderResult {
2048
+ /**
2049
+ * Rendered HTML
2050
+ */
2051
+ html: string;
2052
+
2053
+ /**
2054
+ * Head elements
2055
+ */
2056
+ head: SSRElement[];
2057
+
2058
+ /**
2059
+ * Body elements
2060
+ */
2061
+ body: SSRElement[];
2062
+
2063
+ /**
2064
+ * Layouts that were rendered
2065
+ */
2066
+ layouts: string[];
2067
+ }
2068
+
2069
+ /**
2070
+ * Layout segment information
2071
+ */
2072
+ export interface LayoutSegment {
2073
+ /**
2074
+ * Segment path
2075
+ */
2076
+ path: string;
2077
+
2078
+ /**
2079
+ * Route parameters
2080
+ */
2081
+ params: Record<string, string>;
2082
+
2083
+ /**
2084
+ * Layout component
2085
+ */
2086
+ component: LayoutRenderer | null;
2087
+ }
2088
+ // ============= API Routes Types =============
2089
+
2090
+ /**
2091
+ * HTTP methods supported by API routes
2092
+ */
2093
+ export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
2094
+
2095
+ /**
2096
+ * API route definition
2097
+ */
2098
+ export interface APIRouteDefinition {
2099
+ /**
2100
+ * Unique route identifier
2101
+ */
2102
+ id: string;
2103
+
2104
+ /**
2105
+ * Route path (e.g., /api/users/:id)
2106
+ */
2107
+ path: string;
2108
+
2109
+ /**
2110
+ * File path to the route module
2111
+ */
2112
+ filePath: string;
2113
+
2114
+ /**
2115
+ * Supported HTTP methods
2116
+ */
2117
+ methods: HTTPMethod[];
2118
+
2119
+ /**
2120
+ * Parameter names extracted from path
2121
+ */
2122
+ params: string[];
2123
+
2124
+ /**
2125
+ * Compiled regex for matching
2126
+ */
2127
+ regex: RegExp;
2128
+ }
2129
+
2130
+ /**
2131
+ * API route handler function
2132
+ */
2133
+ export type APIRouteHandler = (ctx: APIContext) => APIResponse | Promise<APIResponse>;
2134
+
2135
+ /**
2136
+ * API response type
2137
+ */
2138
+ export type APIResponse = Response | string | Record<string, unknown> | null;
2139
+
2140
+ /**
2141
+ * API middleware function
2142
+ */
2143
+ export type APIMiddleware = (
2144
+ ctx: APIContext,
2145
+ next: () => Promise<Response>
2146
+ ) => Response | Promise<Response>;
2147
+
2148
+ /**
2149
+ * API context passed to handlers
2150
+ */
2151
+ export interface APIContext {
2152
+ /**
2153
+ * Original request object
2154
+ */
2155
+ request: Request;
2156
+
2157
+ /**
2158
+ * Request URL
2159
+ */
2160
+ url: string;
2161
+
2162
+ /**
2163
+ * URL pathname
2164
+ */
2165
+ pathname: string;
2166
+
2167
+ /**
2168
+ * Query parameters
2169
+ */
2170
+ query: URLSearchParams;
2171
+
2172
+ /**
2173
+ * Route parameters
2174
+ */
2175
+ params: Record<string, string>;
2176
+
2177
+ /**
2178
+ * Request body (parsed)
2179
+ */
2180
+ body: unknown;
2181
+
2182
+ /**
2183
+ * Request headers
2184
+ */
2185
+ headers: Headers;
2186
+
2187
+ /**
2188
+ * HTTP method
2189
+ */
2190
+ method: HTTPMethod;
2191
+
2192
+ /**
2193
+ * Cookies
2194
+ */
2195
+ cookies: Record<string, string>;
2196
+ }
2197
+
2198
+ /**
2199
+ * API route module interface
2200
+ */
2201
+ export interface APIRouteModule {
2202
+ /**
2203
+ * GET handler
2204
+ */
2205
+ GET?: APIRouteHandler;
2206
+
2207
+ /**
2208
+ * POST handler
2209
+ */
2210
+ POST?: APIRouteHandler;
2211
+
2212
+ /**
2213
+ * PUT handler
2214
+ */
2215
+ PUT?: APIRouteHandler;
2216
+
2217
+ /**
2218
+ * PATCH handler
2219
+ */
2220
+ PATCH?: APIRouteHandler;
2221
+
2222
+ /**
2223
+ * DELETE handler
2224
+ */
2225
+ DELETE?: APIRouteHandler;
2226
+
2227
+ /**
2228
+ * HEAD handler
2229
+ */
2230
+ HEAD?: APIRouteHandler;
2231
+
2232
+ /**
2233
+ * OPTIONS handler
2234
+ */
2235
+ OPTIONS?: APIRouteHandler;
2236
+
2237
+ /**
2238
+ * Default export (config or handler)
2239
+ */
2240
+ default?: APIRouteHandler | { handler: APIRouteHandler; config?: APIRouteConfig };
2241
+ }
2242
+
2243
+ /**
2244
+ * API route configuration
2245
+ */
2246
+ export interface APIRouteConfig {
2247
+ /**
2248
+ * API routes directory
2249
+ * @default 'pages/api'
2250
+ */
2251
+ apiDir: string;
2252
+
2253
+ /**
2254
+ * Root directory for file scanning
2255
+ */
2256
+ rootDir: string;
2257
+
2258
+ /**
2259
+ * Supported file extensions
2260
+ * @default ['.ts', '.js']
2261
+ */
2262
+ extensions: string[];
2263
+
2264
+ /**
2265
+ * Maximum request body size in bytes
2266
+ * @default 1048576 (1MB)
2267
+ */
2268
+ bodyLimit: number;
2269
+ }
2270
+
2271
+ /**
2272
+ * Partial API route configuration
2273
+ */
2274
+ export type PartialAPIRouteConfig = Partial<APIRouteConfig>;