loly 0.1.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/README.md +374 -0
- package/bin/loly.js +3015 -0
- package/dist/bootstrap-DgWagZ79.d.ts +16 -0
- package/dist/client.d.ts +101 -0
- package/dist/client.js +727 -0
- package/dist/client.js.map +1 -0
- package/dist/components.d.ts +39 -0
- package/dist/components.js +147 -0
- package/dist/components.js.map +1 -0
- package/dist/index.d.ts +458 -0
- package/dist/index.js +3826 -0
- package/dist/index.js.map +1 -0
- package/package.json +108 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
import { Express } from 'express';
|
|
2
|
+
export { B as BootstrapOptions, C as ClientRouteLoaded, b as bootstrapClient } from './bootstrap-DgWagZ79.js';
|
|
3
|
+
export { Image, ImageProps } from './components.js';
|
|
4
|
+
import 'loly-jsx';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Route segment types
|
|
8
|
+
*/
|
|
9
|
+
interface RouteSegment {
|
|
10
|
+
segment: string;
|
|
11
|
+
isDynamic: boolean;
|
|
12
|
+
isCatchAll: boolean;
|
|
13
|
+
isOptional: boolean;
|
|
14
|
+
paramName?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Route file information
|
|
18
|
+
*/
|
|
19
|
+
interface RouteFile {
|
|
20
|
+
filePath: string;
|
|
21
|
+
segments: RouteSegment[];
|
|
22
|
+
type: "page" | "layout" | "route";
|
|
23
|
+
isRootLayout: boolean;
|
|
24
|
+
urlPath: string;
|
|
25
|
+
isApiRoute?: boolean;
|
|
26
|
+
httpMethods?: string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Route configuration
|
|
30
|
+
*/
|
|
31
|
+
interface RouteConfig {
|
|
32
|
+
routes: RouteFile[];
|
|
33
|
+
rootLayout: RouteFile | undefined;
|
|
34
|
+
routeMap: Map<string, RouteFile>;
|
|
35
|
+
apiRouteMap?: Map<string, RouteFile>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Page component props
|
|
39
|
+
*/
|
|
40
|
+
interface PageProps {
|
|
41
|
+
params: Record<string, string>;
|
|
42
|
+
searchParams: Record<string, string>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Layout component props
|
|
46
|
+
*/
|
|
47
|
+
interface LayoutProps {
|
|
48
|
+
children: any;
|
|
49
|
+
params: Record<string, string>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Scan src/app/ directory and generate route configuration
|
|
54
|
+
*/
|
|
55
|
+
declare function scanRoutes(appDir: string): Promise<RouteConfig>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Match a URL pathname to a route
|
|
59
|
+
*/
|
|
60
|
+
declare function matchRoute(pathname: string, config: RouteConfig, loadComponent: (route: RouteFile) => Promise<any>): {
|
|
61
|
+
route: RouteFile;
|
|
62
|
+
params: Record<string, string>;
|
|
63
|
+
} | null;
|
|
64
|
+
/**
|
|
65
|
+
* Extract params from pathname for a matched route
|
|
66
|
+
*/
|
|
67
|
+
declare function extractParams(pathname: string, route: RouteFile): Record<string, string>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Manifest route entry with compiled paths and chunks
|
|
71
|
+
*/
|
|
72
|
+
interface ManifestRouteEntry {
|
|
73
|
+
path: string;
|
|
74
|
+
sourcePath: string;
|
|
75
|
+
serverPath?: string;
|
|
76
|
+
segments: RouteFile["segments"];
|
|
77
|
+
type: RouteFile["type"];
|
|
78
|
+
isRootLayout: boolean;
|
|
79
|
+
urlPath: string;
|
|
80
|
+
isApiRoute?: boolean;
|
|
81
|
+
httpMethods?: string[];
|
|
82
|
+
clientChunks?: {
|
|
83
|
+
js: string[];
|
|
84
|
+
css: string[];
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Root layout manifest entry
|
|
89
|
+
*/
|
|
90
|
+
interface RootLayoutManifest {
|
|
91
|
+
sourcePath: string;
|
|
92
|
+
serverPath?: string;
|
|
93
|
+
segments: RouteFile["segments"];
|
|
94
|
+
type: "layout";
|
|
95
|
+
isRootLayout: boolean;
|
|
96
|
+
urlPath: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Route configuration with manifest data
|
|
100
|
+
*/
|
|
101
|
+
interface RouteConfigWithManifest {
|
|
102
|
+
routeMapManifest?: Map<string, ManifestRouteEntry>;
|
|
103
|
+
rootLayoutManifest?: RootLayoutManifest;
|
|
104
|
+
routesManifest?: ManifestRouteEntry[];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface SSRContext {
|
|
108
|
+
pathname: string;
|
|
109
|
+
searchParams: Record<string, string>;
|
|
110
|
+
params: Record<string, string>;
|
|
111
|
+
}
|
|
112
|
+
interface SSRResult {
|
|
113
|
+
html: ReadableStream<Uint8Array>;
|
|
114
|
+
status: number;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Render page content (without full HTML wrapper) - used for RSC endpoint
|
|
118
|
+
*/
|
|
119
|
+
declare function renderPageContent(context: SSRContext, config: RouteConfig, appDir: string): Promise<{
|
|
120
|
+
html: string;
|
|
121
|
+
scripts: string;
|
|
122
|
+
styles: string;
|
|
123
|
+
preloads: string;
|
|
124
|
+
islandData: Record<string, any>;
|
|
125
|
+
}>;
|
|
126
|
+
/**
|
|
127
|
+
* Render a page using streaming
|
|
128
|
+
*/
|
|
129
|
+
declare function renderPageStream(context: SSRContext, config: RouteConfig, appDir: string): Promise<SSRResult>;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Handler for RSC endpoint
|
|
133
|
+
*/
|
|
134
|
+
type RSCHandler = (pathname: string, searchParams: Record<string, string>) => Promise<{
|
|
135
|
+
html: string;
|
|
136
|
+
scripts: string;
|
|
137
|
+
styles: string;
|
|
138
|
+
preloads: string;
|
|
139
|
+
islandData?: Record<string, any>;
|
|
140
|
+
params: Record<string, string>;
|
|
141
|
+
}>;
|
|
142
|
+
/**
|
|
143
|
+
* Handler for SSR endpoint
|
|
144
|
+
*/
|
|
145
|
+
type SSRHandler = (pathname: string, searchParams: Record<string, string>) => Promise<SSRResult>;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Abstract base server class using Template Method pattern
|
|
149
|
+
* Defines the skeleton of server setup algorithm
|
|
150
|
+
*/
|
|
151
|
+
declare abstract class BaseServer {
|
|
152
|
+
protected app: Express;
|
|
153
|
+
protected port: number;
|
|
154
|
+
constructor(port?: number);
|
|
155
|
+
/**
|
|
156
|
+
* Template method - defines the algorithm structure
|
|
157
|
+
*/
|
|
158
|
+
setup(): Promise<void>;
|
|
159
|
+
/**
|
|
160
|
+
* Setup Express middleware
|
|
161
|
+
*/
|
|
162
|
+
protected setupMiddleware(): void;
|
|
163
|
+
/**
|
|
164
|
+
* Setup static file serving
|
|
165
|
+
*/
|
|
166
|
+
protected setupStaticFiles(): void;
|
|
167
|
+
/**
|
|
168
|
+
* Setup image optimization endpoint
|
|
169
|
+
*/
|
|
170
|
+
protected setupImageEndpoint(): void;
|
|
171
|
+
/**
|
|
172
|
+
* Setup async component endpoint
|
|
173
|
+
*/
|
|
174
|
+
protected setupAsyncEndpoint(): void;
|
|
175
|
+
/**
|
|
176
|
+
* Setup API routes
|
|
177
|
+
*/
|
|
178
|
+
protected setupApiRoutes(): void;
|
|
179
|
+
/**
|
|
180
|
+
* Setup RSC endpoint
|
|
181
|
+
*/
|
|
182
|
+
protected setupRSCEndpoint(): void;
|
|
183
|
+
/**
|
|
184
|
+
* Setup SSR endpoint
|
|
185
|
+
*/
|
|
186
|
+
protected setupSSREndpoint(): void;
|
|
187
|
+
/**
|
|
188
|
+
* Create RSC handler - to be implemented by subclasses
|
|
189
|
+
*/
|
|
190
|
+
protected abstract createRSCHandler(): RSCHandler;
|
|
191
|
+
/**
|
|
192
|
+
* Create SSR handler - to be implemented by subclasses
|
|
193
|
+
*/
|
|
194
|
+
protected abstract createSSRHandler(): SSRHandler;
|
|
195
|
+
/**
|
|
196
|
+
* Load route configuration - to be implemented by subclasses
|
|
197
|
+
*/
|
|
198
|
+
protected abstract loadRouteConfig(): Promise<RouteConfig>;
|
|
199
|
+
/**
|
|
200
|
+
* Start the server
|
|
201
|
+
*/
|
|
202
|
+
start(): Promise<void>;
|
|
203
|
+
/**
|
|
204
|
+
* Get the Express app instance
|
|
205
|
+
*/
|
|
206
|
+
getApp(): Express;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
interface DevServerOptions {
|
|
210
|
+
projectDir: string;
|
|
211
|
+
port?: number;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Development server class
|
|
215
|
+
* Extends BaseServer with hot reload capabilities
|
|
216
|
+
*/
|
|
217
|
+
declare class DevServer extends BaseServer {
|
|
218
|
+
private projectDir;
|
|
219
|
+
private watcher;
|
|
220
|
+
constructor(options: DevServerOptions);
|
|
221
|
+
/**
|
|
222
|
+
* Initialize server context and load routes
|
|
223
|
+
*/
|
|
224
|
+
initialize(): Promise<void>;
|
|
225
|
+
/**
|
|
226
|
+
* Create RSC handler
|
|
227
|
+
*/
|
|
228
|
+
protected createRSCHandler(): RSCHandler;
|
|
229
|
+
/**
|
|
230
|
+
* Create SSR handler
|
|
231
|
+
*/
|
|
232
|
+
protected createSSRHandler(): SSRHandler;
|
|
233
|
+
/**
|
|
234
|
+
* Load route configuration
|
|
235
|
+
*/
|
|
236
|
+
protected loadRouteConfig(): Promise<RouteConfig>;
|
|
237
|
+
/**
|
|
238
|
+
* Setup hot reload watcher
|
|
239
|
+
*/
|
|
240
|
+
private setupHotReload;
|
|
241
|
+
/**
|
|
242
|
+
* Start the development server with hot reload
|
|
243
|
+
*/
|
|
244
|
+
start(): Promise<void>;
|
|
245
|
+
/**
|
|
246
|
+
* Stop the server and cleanup
|
|
247
|
+
*/
|
|
248
|
+
stop(): Promise<void>;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Convenience function to start development server
|
|
252
|
+
* Maintains backward compatibility
|
|
253
|
+
*/
|
|
254
|
+
declare function startDevServer(options: DevServerOptions): Promise<void>;
|
|
255
|
+
|
|
256
|
+
interface ProdServerOptions {
|
|
257
|
+
projectDir: string;
|
|
258
|
+
port?: number;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Production server class
|
|
262
|
+
* Extends BaseServer with manifest-based route loading
|
|
263
|
+
*/
|
|
264
|
+
declare class ProdServer extends BaseServer {
|
|
265
|
+
private projectDir;
|
|
266
|
+
private config;
|
|
267
|
+
constructor(options: ProdServerOptions);
|
|
268
|
+
/**
|
|
269
|
+
* Initialize server context and load routes from manifest
|
|
270
|
+
*/
|
|
271
|
+
initialize(): Promise<void>;
|
|
272
|
+
/**
|
|
273
|
+
* Create RSC handler
|
|
274
|
+
*/
|
|
275
|
+
protected createRSCHandler(): RSCHandler;
|
|
276
|
+
/**
|
|
277
|
+
* Create SSR handler
|
|
278
|
+
*/
|
|
279
|
+
protected createSSRHandler(): SSRHandler;
|
|
280
|
+
/**
|
|
281
|
+
* Load route configuration from manifest
|
|
282
|
+
*/
|
|
283
|
+
protected loadRouteConfig(): Promise<RouteConfig>;
|
|
284
|
+
/**
|
|
285
|
+
* Start the production server
|
|
286
|
+
*/
|
|
287
|
+
start(): Promise<void>;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Convenience function to start production server
|
|
291
|
+
* Maintains backward compatibility
|
|
292
|
+
*/
|
|
293
|
+
declare function startProdServer(options: ProdServerOptions): Promise<void>;
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Factory for loading route and layout components
|
|
297
|
+
* Centralizes component loading logic with caching support
|
|
298
|
+
*/
|
|
299
|
+
declare class RouteComponentFactory {
|
|
300
|
+
private componentCache;
|
|
301
|
+
private layoutCache;
|
|
302
|
+
/**
|
|
303
|
+
* Load a route component
|
|
304
|
+
* @param route - Route file information
|
|
305
|
+
* @param compiledPath - Optional compiled path for production
|
|
306
|
+
* @returns The loaded component module
|
|
307
|
+
*/
|
|
308
|
+
loadRouteComponent(route: RouteFile, compiledPath?: string): Promise<any>;
|
|
309
|
+
/**
|
|
310
|
+
* Load a layout component
|
|
311
|
+
* @param layout - Layout route file information
|
|
312
|
+
* @param compiledPath - Optional compiled path for production
|
|
313
|
+
* @returns The loaded layout component module
|
|
314
|
+
*/
|
|
315
|
+
loadLayoutComponent(layout: RouteFile, compiledPath?: string): Promise<any>;
|
|
316
|
+
/**
|
|
317
|
+
* Load all layouts from root to route
|
|
318
|
+
* @param route - Target route file
|
|
319
|
+
* @param config - Route configuration
|
|
320
|
+
* @param appDir - Application directory
|
|
321
|
+
* @param manifestRoute - Optional manifest route data
|
|
322
|
+
* @returns Array of layout components in order (root to route)
|
|
323
|
+
*/
|
|
324
|
+
loadLayouts(route: RouteFile, config: RouteConfig, appDir: string, manifestRoute?: ManifestRouteEntry): Promise<Array<(props: {
|
|
325
|
+
children: any;
|
|
326
|
+
params: Record<string, string>;
|
|
327
|
+
}) => any>>;
|
|
328
|
+
/**
|
|
329
|
+
* Clear component cache
|
|
330
|
+
*/
|
|
331
|
+
clearCache(): void;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Rendering strategy interface for SSR
|
|
336
|
+
* Defines the contract for different rendering approaches
|
|
337
|
+
*/
|
|
338
|
+
interface RenderingStrategy {
|
|
339
|
+
/**
|
|
340
|
+
* Render content based on the strategy
|
|
341
|
+
* @param context - SSR context with pathname, searchParams, etc.
|
|
342
|
+
* @param config - Route configuration
|
|
343
|
+
* @returns Rendering result with HTML and status
|
|
344
|
+
*/
|
|
345
|
+
render(context: SSRContext, config: RouteConfig): Promise<SSRResult>;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* RSC rendering result
|
|
349
|
+
*/
|
|
350
|
+
interface RSCRenderingResult {
|
|
351
|
+
html: string;
|
|
352
|
+
scripts: string;
|
|
353
|
+
styles: string;
|
|
354
|
+
preloads: string;
|
|
355
|
+
islandData: Record<string, any>;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* RSC (React Server Components) Strategy
|
|
359
|
+
* Renders page content without full HTML wrapper for SPA navigation
|
|
360
|
+
*/
|
|
361
|
+
declare class RSCStrategy {
|
|
362
|
+
private routeFactory;
|
|
363
|
+
constructor(routeFactory: RouteComponentFactory);
|
|
364
|
+
render(context: SSRContext, config: RouteConfig): Promise<RSCRenderingResult>;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* SSR (Server-Side Rendering) Strategy
|
|
368
|
+
* Renders full HTML document with head, body, scripts, and styles
|
|
369
|
+
*/
|
|
370
|
+
declare class SSRStrategy implements RenderingStrategy {
|
|
371
|
+
private routeFactory;
|
|
372
|
+
constructor(routeFactory: RouteComponentFactory);
|
|
373
|
+
render(context: SSRContext, config: RouteConfig): Promise<SSRResult>;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Factory for creating rendering strategies
|
|
377
|
+
*/
|
|
378
|
+
declare class RenderingStrategyFactory {
|
|
379
|
+
private routeFactory;
|
|
380
|
+
constructor(routeFactory: RouteComponentFactory);
|
|
381
|
+
/**
|
|
382
|
+
* Get SSR rendering strategy
|
|
383
|
+
* @returns SSR rendering strategy
|
|
384
|
+
*/
|
|
385
|
+
getSSRStrategy(): SSRStrategy;
|
|
386
|
+
/**
|
|
387
|
+
* Get RSC rendering strategy
|
|
388
|
+
* @returns RSC rendering strategy
|
|
389
|
+
*/
|
|
390
|
+
getRSCStrategy(): RSCStrategy;
|
|
391
|
+
/**
|
|
392
|
+
* Get rendering strategy based on type
|
|
393
|
+
* @param type - Strategy type: 'ssr' or 'rsc'
|
|
394
|
+
* @returns Appropriate rendering strategy (SSR only, RSC must be accessed via getRSCStrategy)
|
|
395
|
+
*/
|
|
396
|
+
getStrategy(type: "ssr"): RenderingStrategy;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
interface BuildOptions {
|
|
400
|
+
projectDir: string;
|
|
401
|
+
outDir?: string;
|
|
402
|
+
mode?: "development" | "production";
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Execute the build
|
|
406
|
+
*/
|
|
407
|
+
declare function buildProject(options: BuildOptions): Promise<void>;
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Generate routes manifest for client
|
|
411
|
+
*/
|
|
412
|
+
declare function generateRoutesManifest(config: RouteConfig, projectDir: string, appDir: string): void;
|
|
413
|
+
/**
|
|
414
|
+
* Generate bootstrap.ts file for client
|
|
415
|
+
*/
|
|
416
|
+
declare function generateBootstrap(projectDir: string, routes: any[]): void;
|
|
417
|
+
/**
|
|
418
|
+
* Read Rspack manifest
|
|
419
|
+
*/
|
|
420
|
+
interface ChunkManifest {
|
|
421
|
+
[key: string]: {
|
|
422
|
+
file: string;
|
|
423
|
+
isEntry?: boolean;
|
|
424
|
+
imports?: string[];
|
|
425
|
+
css?: string[];
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
declare function readRspackManifest(manifestPath: string): ChunkManifest;
|
|
429
|
+
/**
|
|
430
|
+
* Write manifest
|
|
431
|
+
*/
|
|
432
|
+
declare function writeManifest(manifestPath: string, manifest: ChunkManifest): void;
|
|
433
|
+
/**
|
|
434
|
+
* Generate asset tags from manifest
|
|
435
|
+
*/
|
|
436
|
+
declare function generateAssetTags(manifest: ChunkManifest, entryName: string, publicPath: string): {
|
|
437
|
+
scripts: string;
|
|
438
|
+
styles: string;
|
|
439
|
+
preloads: string;
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Extract public environment variables (LOLY_PUBLIC_*)
|
|
444
|
+
* These variables will be available in the client
|
|
445
|
+
*/
|
|
446
|
+
declare function getPublicEnv(): Record<string, string>;
|
|
447
|
+
/**
|
|
448
|
+
* Generate script tag to inject public env variables into client
|
|
449
|
+
*/
|
|
450
|
+
declare function generatePublicEnvScript(): string;
|
|
451
|
+
/**
|
|
452
|
+
* Get public environment variable (works in both server and client)
|
|
453
|
+
* In server: reads from process.env (with or without LOLY_PUBLIC_ prefix)
|
|
454
|
+
* In client: reads from window.__LOLY_ENV__
|
|
455
|
+
*/
|
|
456
|
+
declare function getEnv(key: string): string | undefined;
|
|
457
|
+
|
|
458
|
+
export { BaseServer, type ChunkManifest, DevServer, type LayoutProps, type ManifestRouteEntry, type PageProps, ProdServer, type RSCRenderingResult, RSCStrategy, type RenderingStrategy, RenderingStrategyFactory, type RootLayoutManifest, RouteComponentFactory, type RouteConfig, type RouteConfigWithManifest, type RouteFile, type RouteSegment, type SSRContext, type SSRResult, SSRStrategy, buildProject, extractParams, generateAssetTags, generateBootstrap, generatePublicEnvScript, generateRoutesManifest, getEnv, getPublicEnv, matchRoute, readRspackManifest, renderPageContent, renderPageStream, scanRoutes, startDevServer, startProdServer, writeManifest };
|