@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.
- package/.env.example +109 -0
- package/.github/workflows/ci.yml +31 -0
- package/LICENSE +21 -0
- package/README.md +892 -0
- package/architecture.md +652 -0
- package/bun.lock +70 -0
- package/dist/cli/index.js +3233 -0
- package/dist/index.js +9014 -0
- package/package.json +77 -0
- package/src/cache/index.ts +795 -0
- package/src/cli/ARCHITECTURE.md +837 -0
- package/src/cli/bin.ts +10 -0
- package/src/cli/commands/build.ts +425 -0
- package/src/cli/commands/dev.ts +248 -0
- package/src/cli/commands/generate.ts +541 -0
- package/src/cli/commands/help.ts +55 -0
- package/src/cli/commands/index.ts +112 -0
- package/src/cli/commands/migration.ts +355 -0
- package/src/cli/commands/new.ts +804 -0
- package/src/cli/commands/start.ts +208 -0
- package/src/cli/core/args.ts +283 -0
- package/src/cli/core/console.ts +349 -0
- package/src/cli/core/index.ts +60 -0
- package/src/cli/core/prompt.ts +424 -0
- package/src/cli/core/spinner.ts +265 -0
- package/src/cli/index.ts +135 -0
- package/src/cli/templates/deploy.ts +295 -0
- package/src/cli/templates/docker.ts +307 -0
- package/src/cli/templates/index.ts +24 -0
- package/src/cli/utils/fs.ts +428 -0
- package/src/cli/utils/index.ts +8 -0
- package/src/cli/utils/strings.ts +197 -0
- package/src/config/env.ts +408 -0
- package/src/config/index.ts +506 -0
- package/src/config/loader.ts +329 -0
- package/src/config/merge.ts +285 -0
- package/src/config/types.ts +320 -0
- package/src/config/validation.ts +441 -0
- package/src/container/forward-ref.ts +143 -0
- package/src/container/index.ts +386 -0
- package/src/context/index.ts +360 -0
- package/src/database/index.ts +1142 -0
- package/src/database/migrations/index.ts +371 -0
- package/src/database/schema/index.ts +619 -0
- package/src/frontend/api-routes.ts +640 -0
- package/src/frontend/bundler.ts +643 -0
- package/src/frontend/console-client.ts +419 -0
- package/src/frontend/console-stream.ts +587 -0
- package/src/frontend/dev-server.ts +846 -0
- package/src/frontend/file-router.ts +611 -0
- package/src/frontend/frameworks/index.ts +106 -0
- package/src/frontend/frameworks/react.ts +85 -0
- package/src/frontend/frameworks/solid.ts +104 -0
- package/src/frontend/frameworks/svelte.ts +110 -0
- package/src/frontend/frameworks/vue.ts +92 -0
- package/src/frontend/hmr-client.ts +663 -0
- package/src/frontend/hmr.ts +728 -0
- package/src/frontend/index.ts +342 -0
- package/src/frontend/islands.ts +552 -0
- package/src/frontend/isr.ts +555 -0
- package/src/frontend/layout.ts +475 -0
- package/src/frontend/ssr/react.ts +446 -0
- package/src/frontend/ssr/solid.ts +523 -0
- package/src/frontend/ssr/svelte.ts +546 -0
- package/src/frontend/ssr/vue.ts +504 -0
- package/src/frontend/ssr.ts +699 -0
- package/src/frontend/types.ts +2274 -0
- package/src/health/index.ts +604 -0
- package/src/index.ts +410 -0
- package/src/lock/index.ts +587 -0
- package/src/logger/index.ts +444 -0
- package/src/logger/transports/index.ts +969 -0
- package/src/metrics/index.ts +494 -0
- package/src/middleware/built-in.ts +360 -0
- package/src/middleware/index.ts +94 -0
- package/src/modules/filters.ts +458 -0
- package/src/modules/guards.ts +405 -0
- package/src/modules/index.ts +1256 -0
- package/src/modules/interceptors.ts +574 -0
- package/src/modules/lazy.ts +418 -0
- package/src/modules/lifecycle.ts +478 -0
- package/src/modules/metadata.ts +90 -0
- package/src/modules/pipes.ts +626 -0
- package/src/router/index.ts +339 -0
- package/src/router/linear.ts +371 -0
- package/src/router/regex.ts +292 -0
- package/src/router/tree.ts +562 -0
- package/src/rpc/index.ts +1263 -0
- package/src/security/index.ts +436 -0
- package/src/ssg/index.ts +631 -0
- package/src/storage/index.ts +456 -0
- package/src/telemetry/index.ts +1097 -0
- package/src/testing/index.ts +1586 -0
- package/src/types/index.ts +236 -0
- package/src/types/optional-deps.d.ts +219 -0
- package/src/validation/index.ts +276 -0
- package/src/websocket/index.ts +1004 -0
- package/tests/integration/cli.test.ts +1016 -0
- package/tests/integration/fullstack.test.ts +234 -0
- package/tests/unit/cache.test.ts +174 -0
- package/tests/unit/cli-commands.test.ts +892 -0
- package/tests/unit/cli.test.ts +1258 -0
- package/tests/unit/container.test.ts +279 -0
- package/tests/unit/context.test.ts +221 -0
- package/tests/unit/database.test.ts +183 -0
- package/tests/unit/linear-router.test.ts +280 -0
- package/tests/unit/lock.test.ts +336 -0
- package/tests/unit/middleware.test.ts +184 -0
- package/tests/unit/modules.test.ts +142 -0
- package/tests/unit/pubsub.test.ts +257 -0
- package/tests/unit/regex-router.test.ts +265 -0
- package/tests/unit/router.test.ts +373 -0
- package/tests/unit/rpc.test.ts +1248 -0
- package/tests/unit/security.test.ts +174 -0
- package/tests/unit/telemetry.test.ts +371 -0
- package/tests/unit/test-cache.test.ts +110 -0
- package/tests/unit/test-database.test.ts +282 -0
- package/tests/unit/tree-router.test.ts +325 -0
- package/tests/unit/validation.test.ts +794 -0
- 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>;
|