@lolyjs/core 0.1.0-alpha.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 (53) hide show
  1. package/README.md +607 -0
  2. package/bin/loly.cjs +6 -0
  3. package/dist/bootstrap-BiCQmSkx.d.mts +50 -0
  4. package/dist/bootstrap-BiCQmSkx.d.ts +50 -0
  5. package/dist/cli.cjs +5186 -0
  6. package/dist/cli.cjs.map +1 -0
  7. package/dist/cli.d.mts +2 -0
  8. package/dist/cli.d.ts +2 -0
  9. package/dist/cli.js +5181 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/index.cjs +5774 -0
  12. package/dist/index.cjs.map +1 -0
  13. package/dist/index.d.mts +445 -0
  14. package/dist/index.d.ts +445 -0
  15. package/dist/index.js +5731 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/react/cache.cjs +251 -0
  18. package/dist/react/cache.cjs.map +1 -0
  19. package/dist/react/cache.d.mts +59 -0
  20. package/dist/react/cache.d.ts +59 -0
  21. package/dist/react/cache.js +220 -0
  22. package/dist/react/cache.js.map +1 -0
  23. package/dist/react/components.cjs +218 -0
  24. package/dist/react/components.cjs.map +1 -0
  25. package/dist/react/components.d.mts +26 -0
  26. package/dist/react/components.d.ts +26 -0
  27. package/dist/react/components.js +190 -0
  28. package/dist/react/components.js.map +1 -0
  29. package/dist/react/hooks.cjs +86 -0
  30. package/dist/react/hooks.cjs.map +1 -0
  31. package/dist/react/hooks.d.mts +19 -0
  32. package/dist/react/hooks.d.ts +19 -0
  33. package/dist/react/hooks.js +58 -0
  34. package/dist/react/hooks.js.map +1 -0
  35. package/dist/react/sockets.cjs +43 -0
  36. package/dist/react/sockets.cjs.map +1 -0
  37. package/dist/react/sockets.d.mts +29 -0
  38. package/dist/react/sockets.d.ts +29 -0
  39. package/dist/react/sockets.js +18 -0
  40. package/dist/react/sockets.js.map +1 -0
  41. package/dist/react/themes.cjs +145 -0
  42. package/dist/react/themes.cjs.map +1 -0
  43. package/dist/react/themes.d.mts +13 -0
  44. package/dist/react/themes.d.ts +13 -0
  45. package/dist/react/themes.js +117 -0
  46. package/dist/react/themes.js.map +1 -0
  47. package/dist/runtime.cjs +626 -0
  48. package/dist/runtime.cjs.map +1 -0
  49. package/dist/runtime.d.mts +11 -0
  50. package/dist/runtime.d.ts +11 -0
  51. package/dist/runtime.js +599 -0
  52. package/dist/runtime.js.map +1 -0
  53. package/package.json +101 -0
package/README.md ADDED
@@ -0,0 +1,607 @@
1
+ # Loly Framework
2
+
3
+ <div align="center">
4
+
5
+ **A modern, production-ready React framework with file-based routing, SSR, SSG, and built-in security**
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@loly/core?style=flat-square)](https://www.npmjs.com/package/@loly/core)
8
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg?style=flat-square)](https://opensource.org/licenses/ISC)
9
+
10
+ *Built with React 19, Express, Rspack, and TypeScript*
11
+
12
+ </div>
13
+
14
+ ---
15
+
16
+ ## Overview
17
+
18
+ Loly is a full-stack React framework that combines the simplicity of file-based routing with powerful server-side rendering, static site generation, and enterprise-grade security features.
19
+
20
+ ### Why Loly?
21
+
22
+ - ⚡ **Fast** - Lightning-fast bundling with Rspack and optimized SSR streaming
23
+ - 🔒 **Secure** - Built-in rate limiting, CORS, CSP, input validation, and sanitization
24
+ - 🎯 **Developer-Friendly** - File-based routing, hot reload, and full TypeScript support
25
+ - 🚀 **Production-Ready** - Structured logging, error handling, and optimized builds
26
+ - 💾 **Smart Caching** - LRU cache with path indexing for optimal performance
27
+
28
+ ---
29
+
30
+ ## Quick Start
31
+
32
+ ### Installation
33
+
34
+ ```bash
35
+ npm install @loly/core react react-dom
36
+ # or
37
+ pnpm add @loly/core react react-dom
38
+ ```
39
+
40
+ ### Create Your First App
41
+
42
+ ```bash
43
+ # Create app directory
44
+ mkdir my-app && cd my-app
45
+
46
+ # Create your first page
47
+ mkdir -p app
48
+ ```
49
+
50
+ ```tsx
51
+ // app/page.tsx
52
+ export default function Home() {
53
+ return <h1>Hello, Loly!</h1>;
54
+ }
55
+ ```
56
+
57
+ ```tsx
58
+ // bootstrap.tsx
59
+ import { bootstrapClient } from "@loly/core/runtime";
60
+ import routes from "@loly/core/runtime";
61
+
62
+ bootstrapClient(routes);
63
+ ```
64
+
65
+ ```json
66
+ // package.json
67
+ {
68
+ "scripts": {
69
+ "dev": "loly dev",
70
+ "build": "loly build",
71
+ "start": "loly start"
72
+ }
73
+ }
74
+ ```
75
+
76
+ ```bash
77
+ npm run dev
78
+ # Server runs on http://localhost:3000
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Core Concepts
84
+
85
+ ### File-Based Routing
86
+
87
+ Routes are automatically created from your file structure:
88
+
89
+ | File Path | Route |
90
+ |-----------|-------|
91
+ | `app/page.tsx` | `/` |
92
+ | `app/about/page.tsx` | `/about` |
93
+ | `app/blog/[slug]/page.tsx` | `/blog/:slug` |
94
+ | `app/post/[...path]/page.tsx` | `/post/*` (catch-all) |
95
+
96
+ ### Server-Side Data Fetching
97
+
98
+ Use `server.hook.ts` to fetch data on the server:
99
+
100
+ ```tsx
101
+ // app/blog/[slug]/server.hook.ts
102
+ import type { ServerLoader } from "@loly/core";
103
+
104
+ export const getServerSideProps: ServerLoader = async (ctx) => {
105
+ const { slug } = ctx.params;
106
+ const post = await fetchPost(slug);
107
+
108
+ return {
109
+ props: { post },
110
+ metadata: {
111
+ title: post.title,
112
+ description: post.excerpt,
113
+ },
114
+ };
115
+ };
116
+ ```
117
+
118
+ ```tsx
119
+ // app/blog/[slug]/page.tsx
120
+ import { usePageProps } from "@loly/core/hooks";
121
+
122
+ export default function BlogPost() {
123
+ const { props } = usePageProps();
124
+ const { post } = props;
125
+
126
+ return (
127
+ <article>
128
+ <h1>{post.title}</h1>
129
+ <div>{post.content}</div>
130
+ </article>
131
+ );
132
+ }
133
+ ```
134
+
135
+ ### Client-Side Navigation
136
+
137
+ Fast page transitions without full reloads:
138
+
139
+ ```tsx
140
+ import { Link } from "@loly/core/components";
141
+
142
+ export default function Navigation() {
143
+ return (
144
+ <nav>
145
+ <Link href="/">Home</Link>
146
+ <Link href="/about">About</Link>
147
+ </nav>
148
+ );
149
+ }
150
+ ```
151
+
152
+ ### Cache Revalidation
153
+
154
+ Invalidate and refresh route data:
155
+
156
+ ```tsx
157
+ import { revalidatePath, revalidate } from "@loly/core/client-cache";
158
+
159
+ // Revalidate a specific route
160
+ revalidatePath('/posts');
161
+
162
+ // Revalidate and refresh current page (similar to Next.js router.refresh())
163
+ await revalidate();
164
+ ```
165
+
166
+ Components using `usePageProps()` automatically update when you call `revalidate()`.
167
+
168
+ ---
169
+
170
+ ## Features
171
+
172
+ ### Core Features
173
+
174
+ - ✅ **File-based Routing** - Automatic route generation
175
+ - ✅ **Server-Side Rendering (SSR)** - React 19 streaming
176
+ - ✅ **Static Site Generation (SSG)** - Pre-render at build time
177
+ - ✅ **API Routes** - RESTful APIs alongside pages
178
+ - ✅ **Nested Layouts** - Shared UI components
179
+ - ✅ **Client-Side Navigation** - Fast page transitions
180
+ - ✅ **Smart Caching** - LRU cache with path indexing
181
+
182
+ ### Security Features
183
+
184
+ - 🔒 **Rate Limiting** - Configurable with strict patterns
185
+ - 🔒 **CORS Protection** - Secure cross-origin sharing
186
+ - 🔒 **Content Security Policy** - XSS protection with nonce
187
+ - 🔒 **Input Validation** - Zod-based validation
188
+ - 🔒 **Input Sanitization** - Automatic XSS protection
189
+
190
+ ---
191
+
192
+ ## API Reference
193
+
194
+ ### Server Loader
195
+
196
+ ```tsx
197
+ import type { ServerLoader } from "@loly/core";
198
+
199
+ export const getServerSideProps: ServerLoader = async (ctx) => {
200
+ const { req, res, params, pathname, locals } = ctx;
201
+
202
+ // Fetch data
203
+ const data = await fetchData();
204
+
205
+ // Redirect
206
+ return {
207
+ redirect: {
208
+ destination: "/new-path",
209
+ permanent: true,
210
+ },
211
+ };
212
+
213
+ // Not found
214
+ return { notFound: true };
215
+
216
+ // Return props
217
+ return {
218
+ props: { data },
219
+ metadata: {
220
+ title: "Page Title",
221
+ description: "Page description",
222
+ },
223
+ };
224
+ };
225
+ ```
226
+
227
+ ### Static Site Generation
228
+
229
+ ```tsx
230
+ import type { ServerLoader, GenerateStaticParams } from "@loly/core";
231
+
232
+ export const dynamic = "force-static" as const;
233
+
234
+ export const generateStaticParams: GenerateStaticParams = async () => {
235
+ const posts = await fetchAllPosts();
236
+ return posts.map((post) => ({ slug: post.slug }));
237
+ };
238
+
239
+ export const getServerSideProps: ServerLoader = async (ctx) => {
240
+ const { slug } = ctx.params;
241
+ const post = await fetchPost(slug);
242
+ return { props: { post } };
243
+ };
244
+ ```
245
+
246
+ ### API Routes
247
+
248
+ ```tsx
249
+ import type { ApiContext } from "@loly/core";
250
+ import { validate } from "@loly/core";
251
+ import { z } from "zod";
252
+
253
+ const schema = z.object({
254
+ title: z.string().min(1),
255
+ content: z.string().min(1),
256
+ });
257
+
258
+ export async function GET(ctx: ApiContext) {
259
+ const posts = await fetchPosts();
260
+ return ctx.Response({ posts });
261
+ }
262
+
263
+ export async function POST(ctx: ApiContext) {
264
+ const body = validate(schema, ctx.req.body);
265
+ const post = await createPost(body);
266
+ return ctx.Response(post, 201);
267
+ }
268
+ ```
269
+
270
+ ### Middleware
271
+
272
+ ```tsx
273
+ import type { RouteMiddleware } from "@loly/core";
274
+
275
+ export const requireAuth: RouteMiddleware = async (ctx, next) => {
276
+ const user = await getUser(ctx.req);
277
+ if (!user) {
278
+ ctx.res.redirect("/login");
279
+ return;
280
+ }
281
+ ctx.locals.user = user;
282
+ await next();
283
+ };
284
+ ```
285
+
286
+ ```tsx
287
+ // app/dashboard/server.hook.ts
288
+ import { requireAuth } from "../middleware/auth";
289
+
290
+ export const middlewares = [requireAuth];
291
+
292
+ export const getServerSideProps: ServerLoader = async (ctx) => {
293
+ const user = ctx.locals.user; // Available from middleware
294
+ return { props: { user } };
295
+ };
296
+ ```
297
+
298
+ ### Cache Management
299
+
300
+ ```tsx
301
+ import { revalidatePath, revalidate } from "@loly/core/client-cache";
302
+
303
+ // Revalidate a specific route (removes from cache)
304
+ revalidatePath('/posts');
305
+
306
+ // Revalidate with query params
307
+ revalidatePath('/posts?page=2');
308
+
309
+ // Revalidate current page and refresh components
310
+ await revalidate();
311
+ ```
312
+
313
+ ### Client Hooks
314
+
315
+ ```tsx
316
+ import { usePageProps } from "@loly/core/hooks";
317
+
318
+ export default function Page() {
319
+ const { params, props } = usePageProps();
320
+ // Automatically updates when revalidate() is called
321
+ return <div>{/* Your UI */}</div>;
322
+ }
323
+ ```
324
+
325
+ ---
326
+
327
+ ## Configuration
328
+
329
+ Create `loly.config.ts` in your project root:
330
+
331
+ ```tsx
332
+ export const config = (env: string) => {
333
+ return {
334
+ // Server
335
+ server: {
336
+ port: 3000,
337
+ host: env === "production" ? "0.0.0.0" : "localhost",
338
+ },
339
+
340
+ // Security
341
+ security: {
342
+ contentSecurityPolicy: {
343
+ directives: {
344
+ defaultSrc: ["'self'"],
345
+ scriptSrc: ["'self'"],
346
+ styleSrc: ["'self'", "'unsafe-inline'"],
347
+ },
348
+ },
349
+ },
350
+
351
+ // Rate limiting
352
+ rateLimit: {
353
+ windowMs: 15 * 60 * 1000,
354
+ max: 100,
355
+ strictMax: 5,
356
+ strictPatterns: ["/api/auth/**"],
357
+ },
358
+
359
+ // CORS
360
+ corsOrigin: env === "production"
361
+ ? ["https://yourdomain.com"]
362
+ : true,
363
+ };
364
+ };
365
+ ```
366
+
367
+ ---
368
+
369
+ ## Project Structure
370
+
371
+ ```
372
+ your-app/
373
+ ├── app/
374
+ │ ├── layout.tsx # Root layout
375
+ │ ├── page.tsx # Home page (/)
376
+ │ ├── _not-found.tsx # Custom 404 (optional)
377
+ │ ├── _error.tsx # Custom error (optional)
378
+ │ ├── about/
379
+ │ │ └── page.tsx # /about
380
+ │ ├── blog/
381
+ │ │ ├── layout.tsx # Blog layout
382
+ │ │ └── [slug]/
383
+ │ │ ├── page.tsx # /blog/:slug
384
+ │ │ └── server.hook.ts # Server-side data
385
+ │ └── api/
386
+ │ └── posts/
387
+ │ └── route.ts # /api/posts
388
+ ├── bootstrap.tsx # Client entry
389
+ ├── init.server.ts # Server init (optional)
390
+ ├── loly.config.ts # Config (optional)
391
+ └── package.json
392
+ ```
393
+
394
+ ---
395
+
396
+ ## Advanced
397
+
398
+ ### Layouts
399
+
400
+ ```tsx
401
+ // app/layout.tsx (Root)
402
+ export default function RootLayout({ children }) {
403
+ return (
404
+ <div className="app">
405
+ <nav>Navigation</nav>
406
+ <main>{children}</main>
407
+ <footer>Footer</footer>
408
+ </div>
409
+ );
410
+ }
411
+ ```
412
+
413
+ ```tsx
414
+ // app/blog/layout.tsx (Nested)
415
+ export default function BlogLayout({ children }) {
416
+ return (
417
+ <div className="blog">
418
+ <aside>Sidebar</aside>
419
+ <main>{children}</main>
420
+ </div>
421
+ );
422
+ }
423
+ ```
424
+
425
+ ### Themes
426
+
427
+ ```tsx
428
+ import { ThemeProvider } from "@loly/core/themes";
429
+
430
+ export default function RootLayout({ children, theme }) {
431
+ return (
432
+ <ThemeProvider initialTheme={theme}>
433
+ {children}
434
+ </ThemeProvider>
435
+ );
436
+ }
437
+ ```
438
+
439
+ ### Validation & Sanitization
440
+
441
+ ```tsx
442
+ import { validate, safeValidate, sanitizeString } from "@loly/core";
443
+ import { z } from "zod";
444
+
445
+ const schema = z.object({
446
+ name: z.string().min(1).max(100),
447
+ email: z.string().email(),
448
+ });
449
+
450
+ // Throw on error
451
+ const data = validate(schema, req.body);
452
+
453
+ // Return result object
454
+ const result = safeValidate(schema, req.body);
455
+ if (!result.success) {
456
+ return Response({ errors: result.error }, 400);
457
+ }
458
+
459
+ // Sanitize strings
460
+ const clean = sanitizeString(userInput);
461
+ ```
462
+
463
+ ### Logging
464
+
465
+ ```tsx
466
+ import { getRequestLogger, createModuleLogger } from "@loly/core";
467
+
468
+ // In server hooks or API routes
469
+ export const getServerSideProps: ServerLoader = async (ctx) => {
470
+ const logger = getRequestLogger(ctx.req);
471
+ logger.info("Processing request", { userId: ctx.locals.user?.id });
472
+ return { props: {} };
473
+ };
474
+
475
+ // Module logger
476
+ const logger = createModuleLogger("my-module");
477
+ logger.debug("Debug message");
478
+ logger.error("Error", error);
479
+ ```
480
+
481
+ ---
482
+
483
+ ## TypeScript Support
484
+
485
+ Loly is built with TypeScript and provides full type safety:
486
+
487
+ ```tsx
488
+ import type {
489
+ ServerContext,
490
+ ServerLoader,
491
+ ApiContext,
492
+ RouteMiddleware,
493
+ ApiMiddleware,
494
+ } from "@loly/core";
495
+
496
+ // Fully typed server loader
497
+ export const getServerSideProps: ServerLoader = async (ctx) => {
498
+ // ctx is fully typed
499
+ const { params, req, res, locals } = ctx;
500
+ // ...
501
+ };
502
+ ```
503
+
504
+ ---
505
+
506
+ ## Production
507
+
508
+ ### Build
509
+
510
+ ```bash
511
+ npm run build
512
+ ```
513
+
514
+ This generates:
515
+ - Client bundle (`.loly/client`)
516
+ - Static pages if using SSG (`.loly/ssg`)
517
+ - Server code
518
+
519
+ ### Start
520
+
521
+ ```bash
522
+ npm run start
523
+ ```
524
+
525
+ ### Environment Variables
526
+
527
+ ```bash
528
+ PORT=3000
529
+ HOST=0.0.0.0
530
+ LOG_LEVEL=info
531
+ LOG_REQUESTS=false
532
+ ```
533
+
534
+ ---
535
+
536
+ ## CLI Commands
537
+
538
+ ```bash
539
+ # Development
540
+ loly dev [--port 3000] [--appDir app]
541
+
542
+ # Build
543
+ loly build [--appDir app]
544
+
545
+ # Start production server
546
+ loly start [--port 3000] [--appDir app]
547
+ ```
548
+
549
+ ---
550
+
551
+ ## All Exports
552
+
553
+ ```tsx
554
+ // Server
555
+ import { startDevServer, startProdServer, buildApp } from "@loly/core";
556
+
557
+ // Types
558
+ import type {
559
+ ServerContext,
560
+ ServerLoader,
561
+ ApiContext,
562
+ RouteMiddleware,
563
+ ApiMiddleware,
564
+ GenerateStaticParams,
565
+ } from "@loly/core";
566
+
567
+ // Validation
568
+ import { validate, safeValidate, ValidationError } from "@loly/core";
569
+
570
+ // Security
571
+ import { sanitizeString, sanitizeObject } from "@loly/core";
572
+ import { strictRateLimiter, lenientRateLimiter } from "@loly/core";
573
+
574
+ // Logging
575
+ import { logger, createModuleLogger, getRequestLogger } from "@loly/core";
576
+
577
+ // Client
578
+ import { Link } from "@loly/core/components";
579
+ import { usePageProps } from "@loly/core/hooks";
580
+ import { ThemeProvider } from "@loly/core/themes";
581
+ import { revalidatePath, revalidate } from "@loly/core/client-cache";
582
+ ```
583
+
584
+ ---
585
+
586
+ ## License
587
+
588
+ ISC
589
+
590
+ ---
591
+
592
+ ## Built With
593
+
594
+ - [React](https://react.dev/) - UI library
595
+ - [Express](https://expressjs.com/) - Web framework
596
+ - [Rspack](https://rspack.dev/) - Fast bundler
597
+ - [Pino](https://getpino.io/) - Fast logger
598
+ - [Zod](https://zod.dev/) - Schema validation
599
+ - [Helmet](https://helmetjs.github.io/) - Security headers
600
+
601
+ ---
602
+
603
+ <div align="center">
604
+
605
+ **Made with ❤️ by the Loly team**
606
+
607
+ </div>
package/bin/loly.cjs ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Small bootstrap that delegates to the compiled CLI entrypoint.
4
+ // This file is what npm exposes as the "loly" executable.
5
+
6
+ require("../dist/cli.cjs");
@@ -0,0 +1,50 @@
1
+ declare const WINDOW_DATA_KEY = "__FW_DATA__";
2
+
3
+ type InitialData = {
4
+ pathname: string;
5
+ params: Record<string, string>;
6
+ props: Record<string, any>;
7
+ metadata?: {
8
+ title?: string;
9
+ description?: string;
10
+ } | null;
11
+ notFound?: boolean;
12
+ error?: boolean;
13
+ theme?: string;
14
+ };
15
+ declare global {
16
+ interface Window {
17
+ [WINDOW_DATA_KEY]?: InitialData;
18
+ }
19
+ }
20
+ type ClientLoadedComponents = {
21
+ Page: React.ComponentType<any>;
22
+ layouts: React.ComponentType<any>[];
23
+ };
24
+ type ClientRouteLoaded = {
25
+ pattern: string;
26
+ paramNames: string[];
27
+ load: () => Promise<ClientLoadedComponents>;
28
+ };
29
+ type ClientRouteMatch = {
30
+ route: ClientRouteLoaded;
31
+ params: Record<string, string>;
32
+ };
33
+ type RouteViewState = {
34
+ url: string;
35
+ route: ClientRouteLoaded | null;
36
+ params: Record<string, string>;
37
+ components: ClientLoadedComponents | null;
38
+ props: Record<string, any>;
39
+ };
40
+
41
+ /**
42
+ * Bootstraps the client-side application.
43
+ *
44
+ * @param routes - Array of client routes
45
+ * @param notFoundRoute - Not-found route definition
46
+ * @param errorRoute - Error route definition
47
+ */
48
+ declare function bootstrapClient(routes: ClientRouteLoaded[], notFoundRoute: ClientRouteLoaded | null, errorRoute?: ClientRouteLoaded | null): void;
49
+
50
+ export { type ClientRouteLoaded as C, type InitialData as I, type RouteViewState as R, type ClientLoadedComponents as a, type ClientRouteMatch as b, bootstrapClient as c };
@@ -0,0 +1,50 @@
1
+ declare const WINDOW_DATA_KEY = "__FW_DATA__";
2
+
3
+ type InitialData = {
4
+ pathname: string;
5
+ params: Record<string, string>;
6
+ props: Record<string, any>;
7
+ metadata?: {
8
+ title?: string;
9
+ description?: string;
10
+ } | null;
11
+ notFound?: boolean;
12
+ error?: boolean;
13
+ theme?: string;
14
+ };
15
+ declare global {
16
+ interface Window {
17
+ [WINDOW_DATA_KEY]?: InitialData;
18
+ }
19
+ }
20
+ type ClientLoadedComponents = {
21
+ Page: React.ComponentType<any>;
22
+ layouts: React.ComponentType<any>[];
23
+ };
24
+ type ClientRouteLoaded = {
25
+ pattern: string;
26
+ paramNames: string[];
27
+ load: () => Promise<ClientLoadedComponents>;
28
+ };
29
+ type ClientRouteMatch = {
30
+ route: ClientRouteLoaded;
31
+ params: Record<string, string>;
32
+ };
33
+ type RouteViewState = {
34
+ url: string;
35
+ route: ClientRouteLoaded | null;
36
+ params: Record<string, string>;
37
+ components: ClientLoadedComponents | null;
38
+ props: Record<string, any>;
39
+ };
40
+
41
+ /**
42
+ * Bootstraps the client-side application.
43
+ *
44
+ * @param routes - Array of client routes
45
+ * @param notFoundRoute - Not-found route definition
46
+ * @param errorRoute - Error route definition
47
+ */
48
+ declare function bootstrapClient(routes: ClientRouteLoaded[], notFoundRoute: ClientRouteLoaded | null, errorRoute?: ClientRouteLoaded | null): void;
49
+
50
+ export { type ClientRouteLoaded as C, type InitialData as I, type RouteViewState as R, type ClientLoadedComponents as a, type ClientRouteMatch as b, bootstrapClient as c };