olova 2.0.55 → 2.0.57

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 (82) hide show
  1. package/README.md +28 -288
  2. package/dist/chunk-D7SIC5TC.js +367 -0
  3. package/dist/chunk-D7SIC5TC.js.map +1 -0
  4. package/dist/entry-server.cjs +120 -0
  5. package/dist/entry-server.cjs.map +1 -0
  6. package/dist/entry-server.js +115 -0
  7. package/dist/entry-server.js.map +1 -0
  8. package/dist/entry-worker.cjs +133 -0
  9. package/dist/entry-worker.cjs.map +1 -0
  10. package/dist/entry-worker.js +127 -0
  11. package/dist/entry-worker.js.map +1 -0
  12. package/dist/main.cjs +18 -0
  13. package/dist/main.cjs.map +1 -0
  14. package/dist/main.js +16 -0
  15. package/dist/main.js.map +1 -0
  16. package/dist/olova.cjs +1684 -0
  17. package/dist/olova.cjs.map +1 -0
  18. package/dist/olova.d.cts +72 -0
  19. package/dist/olova.d.ts +72 -0
  20. package/dist/olova.js +1325 -0
  21. package/dist/olova.js.map +1 -0
  22. package/dist/performance.cjs +386 -0
  23. package/dist/performance.cjs.map +1 -0
  24. package/dist/performance.js +3 -0
  25. package/dist/performance.js.map +1 -0
  26. package/dist/router.cjs +646 -0
  27. package/dist/router.cjs.map +1 -0
  28. package/dist/router.d.cts +113 -0
  29. package/dist/router.d.ts +113 -0
  30. package/dist/router.js +632 -0
  31. package/dist/router.js.map +1 -0
  32. package/main.tsx +76 -0
  33. package/olova.ts +619 -0
  34. package/package.json +44 -61
  35. package/src/entry-server.tsx +165 -0
  36. package/src/entry-worker.tsx +201 -0
  37. package/src/generator/index.ts +409 -0
  38. package/src/hydration/flight.ts +320 -0
  39. package/src/hydration/index.ts +12 -0
  40. package/src/hydration/types.ts +225 -0
  41. package/src/logger.ts +182 -0
  42. package/src/main.tsx +24 -0
  43. package/src/performance.ts +488 -0
  44. package/src/plugin/index.ts +204 -0
  45. package/src/router/ErrorBoundary.tsx +145 -0
  46. package/src/router/Link.tsx +117 -0
  47. package/src/router/OlovaRouter.tsx +354 -0
  48. package/src/router/Outlet.tsx +8 -0
  49. package/src/router/context.ts +117 -0
  50. package/src/router/index.ts +29 -0
  51. package/src/router/matching.ts +63 -0
  52. package/src/router/router.tsx +23 -0
  53. package/src/router/search-params.ts +29 -0
  54. package/src/scanner/index.ts +116 -0
  55. package/src/types/index.ts +191 -0
  56. package/src/utils/export.ts +85 -0
  57. package/src/utils/index.ts +4 -0
  58. package/src/utils/naming.ts +54 -0
  59. package/src/utils/path.ts +45 -0
  60. package/tsup.config.ts +35 -0
  61. package/CHANGELOG.md +0 -31
  62. package/LICENSE +0 -21
  63. package/dist/index.cjs +0 -883
  64. package/dist/index.cjs.map +0 -1
  65. package/dist/index.d.cts +0 -138
  66. package/dist/index.d.ts +0 -138
  67. package/dist/index.js +0 -832
  68. package/dist/index.js.map +0 -1
  69. package/dist/plugin.cjs +0 -927
  70. package/dist/plugin.cjs.map +0 -1
  71. package/dist/plugin.d.cts +0 -18
  72. package/dist/plugin.d.ts +0 -18
  73. package/dist/plugin.js +0 -894
  74. package/dist/plugin.js.map +0 -1
  75. package/dist/ssg.cjs +0 -637
  76. package/dist/ssg.cjs.map +0 -1
  77. package/dist/ssg.d.cts +0 -191
  78. package/dist/ssg.d.ts +0 -191
  79. package/dist/ssg.js +0 -585
  80. package/dist/ssg.js.map +0 -1
  81. package/dist/types-BT6YsBGO.d.cts +0 -143
  82. package/dist/types-BT6YsBGO.d.ts +0 -143
@@ -0,0 +1,115 @@
1
+ import { StrictMode, Suspense } from 'react';
2
+ import { renderToString } from 'react-dom/server';
3
+ import { QueryClient, dehydrate, QueryClientProvider, HydrationBoundary } from '@tanstack/react-query';
4
+ import { layouts, Outlet, OlovaRouter, notFoundPages, routes } from 'virtual:olova-app';
5
+ export { routes } from 'virtual:olova-app';
6
+ import { jsx } from 'react/jsx-runtime';
7
+
8
+ // src/entry-server.tsx
9
+ var wrappedLayouts = layouts.map((item) => ({
10
+ ...item,
11
+ layout: (props) => /* @__PURE__ */ jsx(item.layout, { ...props, children: /* @__PURE__ */ jsx(Outlet, {}) })
12
+ }));
13
+ function matchRoute(url) {
14
+ const pathname = url.split("?")[0];
15
+ for (const route of routes) {
16
+ if (route.path === pathname) {
17
+ return { route, params: {} };
18
+ }
19
+ if (route.path.includes(":") || route.path.includes("*")) {
20
+ const pattern = route.path.replace(/\*/g, "(.*)").replace(/:[^/]+/g, "([^/]+)");
21
+ const regex = new RegExp(`^${pattern}$`);
22
+ const match = pathname.match(regex);
23
+ if (match) {
24
+ const params = {};
25
+ const paramNames = route.path.match(/:[^/]+|\*/g) || [];
26
+ paramNames.forEach((name, i) => {
27
+ if (name === "*") {
28
+ params["*"] = match[i + 1];
29
+ } else {
30
+ params[name.slice(1)] = match[i + 1];
31
+ }
32
+ });
33
+ return { route, params };
34
+ }
35
+ }
36
+ }
37
+ return null;
38
+ }
39
+ async function runLoader(url) {
40
+ const match = matchRoute(url);
41
+ if (!match || !match.route.loader) {
42
+ return null;
43
+ }
44
+ try {
45
+ const baseUrl = "http://localhost";
46
+ const result = await match.route.loader({
47
+ request: new Request(new URL(url, baseUrl)),
48
+ params: match.params
49
+ });
50
+ if (result instanceof Response) {
51
+ return null;
52
+ }
53
+ return result;
54
+ } catch (error) {
55
+ console.error(`[SSR] Loader error for ${url}:`, error);
56
+ return null;
57
+ }
58
+ }
59
+ async function render(url) {
60
+ const globalAny = globalThis;
61
+ globalAny.window = {
62
+ location: { pathname: url, search: "", hash: "" },
63
+ addEventListener: () => {
64
+ },
65
+ removeEventListener: () => {
66
+ },
67
+ history: {
68
+ pushState: () => {
69
+ },
70
+ replaceState: () => {
71
+ },
72
+ location: { pathname: url, search: "", hash: "" }
73
+ }
74
+ };
75
+ globalAny.location = globalAny.window.location;
76
+ globalAny.document = {
77
+ createElement: () => ({}),
78
+ getElementsByTagName: () => [],
79
+ getElementById: () => null,
80
+ querySelector: () => null,
81
+ title: "",
82
+ location: globalAny.window.location
83
+ };
84
+ const loaderData = await runLoader(url);
85
+ if (loaderData) {
86
+ globalAny.window.__LOADER_DATA__ = loaderData;
87
+ }
88
+ const queryClient = new QueryClient({
89
+ defaultOptions: {
90
+ queries: {
91
+ staleTime: Infinity,
92
+ // Data is fresh during SSR
93
+ gcTime: Infinity
94
+ }
95
+ }
96
+ });
97
+ if (loaderData) {
98
+ Object.entries(loaderData).forEach(([key, value]) => {
99
+ queryClient.setQueryData([key], value);
100
+ });
101
+ }
102
+ const dehydratedState = dehydrate(queryClient);
103
+ const html = renderToString(
104
+ /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(HydrationBoundary, { state: dehydratedState, children: /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(OlovaRouter, { routes, layouts: wrappedLayouts, notFoundPages }) }) }) }) })
105
+ );
106
+ return {
107
+ html,
108
+ loaderData,
109
+ queryState: dehydratedState
110
+ };
111
+ }
112
+
113
+ export { render };
114
+ //# sourceMappingURL=entry-server.js.map
115
+ //# sourceMappingURL=entry-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/entry-server.tsx"],"names":[],"mappings":";;;;;;;;AAOA,IAAM,cAAA,GAAiB,OAAA,CAAQ,GAAA,CAAI,CAAC,IAAA,MAAe;AAAA,EACjD,GAAG,IAAA;AAAA,EACH,MAAA,EAAQ,CAAC,KAAA,qBACP,GAAA,CAAC,IAAA,CAAK,MAAA,EAAL,EAAa,GAAG,KAAA,EACf,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,CAAA,EACV;AAEJ,CAAA,CAAE,CAAA;AAKF,SAAS,WAAW,GAAA,EAAoE;AACtF,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAEjC,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAE1B,IAAA,IAAI,KAAA,CAAM,SAAS,QAAA,EAAU;AAC3B,MAAA,OAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,EAAC,EAAE;AAAA,IAC7B;AAGA,IAAA,IAAI,KAAA,CAAM,KAAK,QAAA,CAAS,GAAG,KAAK,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AACxD,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CACnB,OAAA,CAAQ,OAAO,MAAM,CAAA,CACrB,OAAA,CAAQ,SAAA,EAAW,SAAS,CAAA;AAC/B,MAAA,MAAM,KAAA,GAAQ,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,CAAG,CAAA;AACvC,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA;AAElC,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,MAAM,SAAiC,EAAC;AACxC,QAAA,MAAM,aAAa,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,YAAY,KAAK,EAAC;AAEtD,QAAA,UAAA,CAAW,OAAA,CAAQ,CAAC,IAAA,EAAc,CAAA,KAAc;AAC9C,UAAA,IAAI,SAAS,GAAA,EAAK;AAChB,YAAA,MAAA,CAAO,GAAG,CAAA,GAAI,KAAA,CAAM,CAAA,GAAI,CAAC,CAAA;AAAA,UAC3B,CAAA,MAAO;AACL,YAAA,MAAA,CAAO,KAAK,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI,KAAA,CAAM,IAAI,CAAC,CAAA;AAAA,UACrC;AAAA,QACF,CAAC,CAAA;AAED,QAAA,OAAO,EAAE,OAAO,MAAA,EAAO;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAMA,eAAe,UAAU,GAAA,EAAsD;AAC7E,EAAA,MAAM,KAAA,GAAQ,WAAW,GAAG,CAAA;AAE5B,EAAA,IAAI,CAAC,KAAA,IAAS,CAAC,KAAA,CAAM,MAAM,MAAA,EAAQ;AACjC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI;AAGF,IAAA,MAAM,OAAA,GAAU,kBAAA;AAChB,IAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAAM,KAAA,CAAM,MAAA,CAAO;AAAA,MACtC,SAAS,IAAI,OAAA,CAAQ,IAAI,GAAA,CAAI,GAAA,EAAK,OAAO,CAAC,CAAA;AAAA,MAC1C,QAAQ,KAAA,CAAM;AAAA,KACf,CAAA;AAGD,IAAA,IAAI,kBAAkB,QAAA,EAAU;AAC9B,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,uBAAA,EAA0B,GAAG,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AACrD,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,eAAsB,OAAO,GAAA,EAAa;AAExC,EAAA,MAAM,SAAA,GAAY,UAAA;AAClB,EAAA,SAAA,CAAU,MAAA,GAAS;AAAA,IACjB,UAAU,EAAE,QAAA,EAAU,KAAK,MAAA,EAAQ,EAAA,EAAI,MAAM,EAAA,EAAG;AAAA,IAChD,kBAAkB,MAAM;AAAA,IAAC,CAAA;AAAA,IACzB,qBAAqB,MAAM;AAAA,IAAC,CAAA;AAAA,IAC5B,OAAA,EAAS;AAAA,MACP,WAAW,MAAM;AAAA,MAAC,CAAA;AAAA,MAClB,cAAc,MAAM;AAAA,MAAC,CAAA;AAAA,MACrB,UAAU,EAAE,QAAA,EAAU,KAAK,MAAA,EAAQ,EAAA,EAAI,MAAM,EAAA;AAAG;AAClD,GACF;AACA,EAAA,SAAA,CAAU,QAAA,GAAW,UAAU,MAAA,CAAO,QAAA;AACtC,EAAA,SAAA,CAAU,QAAA,GAAW;AAAA,IACnB,aAAA,EAAe,OAAO,EAAC,CAAA;AAAA,IACvB,oBAAA,EAAsB,MAAM,EAAC;AAAA,IAC7B,gBAAgB,MAAM,IAAA;AAAA,IACtB,eAAe,MAAM,IAAA;AAAA,IACrB,KAAA,EAAO,EAAA;AAAA,IACP,QAAA,EAAU,UAAU,MAAA,CAAO;AAAA,GAC7B;AAGA,EAAA,MAAM,UAAA,GAAa,MAAM,SAAA,CAAU,GAAG,CAAA;AAGtC,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,SAAA,CAAU,OAAO,eAAA,GAAkB,UAAA;AAAA,EACrC;AAGA,EAAA,MAAM,WAAA,GAAc,IAAI,WAAA,CAAY;AAAA,IAClC,cAAA,EAAgB;AAAA,MACd,OAAA,EAAS;AAAA,QACP,SAAA,EAAW,QAAA;AAAA;AAAA,QACX,MAAA,EAAQ;AAAA;AACV;AACF,GACD,CAAA;AAGD,EAAA,IAAI,UAAA,EAAY;AAGd,IAAA,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AACnD,MAAA,WAAA,CAAY,YAAA,CAAa,CAAC,GAAG,CAAA,EAAG,KAAK,CAAA;AAAA,IACvC,CAAC,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,eAAA,GAAkB,UAAU,WAAW,CAAA;AAG7C,EAAA,MAAM,IAAA,GAAO,cAAA;AAAA,oBACX,GAAA,CAAC,cACC,QAAA,kBAAA,GAAA,CAAC,mBAAA,EAAA,EAAoB,QAAQ,WAAA,EAC3B,QAAA,kBAAA,GAAA,CAAC,iBAAA,EAAA,EAAkB,KAAA,EAAO,eAAA,EACxB,QAAA,kBAAA,GAAA,CAAC,YAAS,QAAA,EAAU,IAAA,EAClB,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,MAAA,EAAgB,OAAA,EAAS,gBAAgB,aAAA,EAA8B,CAAA,EACtF,CAAA,EACF,CAAA,EACF,CAAA,EACF;AAAA,GACF;AAGA,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,UAAA;AAAA,IACA,UAAA,EAAY;AAAA,GACd;AACF","file":"entry-server.js","sourcesContent":["import { StrictMode, Suspense } from 'react';\r\nimport { renderToString } from 'react-dom/server';\r\nimport { QueryClient, QueryClientProvider, dehydrate, HydrationBoundary } from '@tanstack/react-query';\r\n// @ts-expect-error - Virtual module resolved by vite-plugin-olova\r\nimport { layouts, notFoundPages, OlovaRouter, Outlet, routes } from 'virtual:olova-app';\r\n\r\n// Wrapper to support \"children\" prop style layouts\r\nconst wrappedLayouts = layouts.map((item: any) => ({\r\n ...item,\r\n layout: (props: any) => (\r\n <item.layout {...props}>\r\n <Outlet />\r\n </item.layout>\r\n )\r\n}));\r\n\r\n/**\r\n * Find matching route and extract params\r\n */\r\nfunction matchRoute(url: string): { route: any; params: Record<string, string> } | null {\r\n const pathname = url.split('?')[0];\r\n \r\n for (const route of routes) {\r\n // Exact match\r\n if (route.path === pathname) {\r\n return { route, params: {} };\r\n }\r\n \r\n // Dynamic segments\r\n if (route.path.includes(':') || route.path.includes('*')) {\r\n const pattern = route.path\r\n .replace(/\\*/g, '(.*)')\r\n .replace(/:[^/]+/g, '([^/]+)');\r\n const regex = new RegExp(`^${pattern}$`);\r\n const match = pathname.match(regex);\r\n \r\n if (match) {\r\n const params: Record<string, string> = {};\r\n const paramNames = route.path.match(/:[^/]+|\\*/g) || [];\r\n \r\n paramNames.forEach((name: string, i: number) => {\r\n if (name === '*') {\r\n params['*'] = match[i + 1];\r\n } else {\r\n params[name.slice(1)] = match[i + 1];\r\n }\r\n });\r\n \r\n return { route, params };\r\n }\r\n }\r\n }\r\n \r\n return null;\r\n}\r\n\r\n/**\r\n * Run loader for SSG builds\r\n * Simplified: loader just returns data directly\r\n */\r\nasync function runLoader(url: string): Promise<Record<string, unknown> | null> {\r\n const match = matchRoute(url);\r\n \r\n if (!match || !match.route.loader) {\r\n return null;\r\n }\r\n \r\n try {\r\n // Simple call - loader returns data directly\r\n // Use a valid URL for Request (requires absolute URL)\r\n const baseUrl = 'http://localhost';\r\n const result = await match.route.loader({\r\n request: new Request(new URL(url, baseUrl)),\r\n params: match.params\r\n });\r\n \r\n // If it's a Response, skip\r\n if (result instanceof Response) {\r\n return null;\r\n }\r\n \r\n // Direct data return (simplified syntax)\r\n return result as Record<string, unknown>;\r\n } catch (error) {\r\n console.error(`[SSR] Loader error for ${url}:`, error);\r\n return null;\r\n }\r\n}\r\n\r\nexport async function render(url: string) {\r\n // Always recreate the window mock to ensure clean state for every SSG path\r\n const globalAny = globalThis as any;\r\n globalAny.window = {\r\n location: { pathname: url, search: '', hash: '' },\r\n addEventListener: () => {},\r\n removeEventListener: () => {},\r\n history: { \r\n pushState: () => {}, \r\n replaceState: () => {}, \r\n location: { pathname: url, search: '', hash: '' } \r\n }\r\n };\r\n globalAny.location = globalAny.window.location;\r\n globalAny.document = {\r\n createElement: () => ({}),\r\n getElementsByTagName: () => [],\r\n getElementById: () => null,\r\n querySelector: () => null,\r\n title: '',\r\n location: globalAny.window.location\r\n };\r\n\r\n // Run loader for data-only SSR\r\n const loaderData = await runLoader(url);\r\n \r\n // Inject loader data into window for components to access\r\n if (loaderData) {\r\n globalAny.window.__LOADER_DATA__ = loaderData;\r\n }\r\n\r\n // Create QueryClient for SSR with pre-loaded data\r\n const queryClient = new QueryClient({\r\n defaultOptions: {\r\n queries: {\r\n staleTime: Infinity, // Data is fresh during SSR\r\n gcTime: Infinity,\r\n },\r\n },\r\n });\r\n\r\n // Pre-populate query client with loader data\r\n if (loaderData) {\r\n // Convert loader data to query state format\r\n // If loader returns { user: {...} }, we hydrate it\r\n Object.entries(loaderData).forEach(([key, value]) => {\r\n queryClient.setQueryData([key], value);\r\n });\r\n }\r\n\r\n // Get dehydrated state for client hydration\r\n const dehydratedState = dehydrate(queryClient);\r\n\r\n // Wrap in Suspense to handle lazy-loaded components\r\n const html = renderToString(\r\n <StrictMode>\r\n <QueryClientProvider client={queryClient}>\r\n <HydrationBoundary state={dehydratedState}>\r\n <Suspense fallback={null}>\r\n <OlovaRouter routes={routes} layouts={wrappedLayouts} notFoundPages={notFoundPages} />\r\n </Suspense>\r\n </HydrationBoundary>\r\n </QueryClientProvider>\r\n </StrictMode>\r\n );\r\n\r\n // Return both html and dehydrated state for flight serialization\r\n return { \r\n html, \r\n loaderData,\r\n queryState: dehydratedState \r\n };\r\n}\r\n\r\nexport { routes };\r\n\r\n"]}
@@ -0,0 +1,133 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var server = require('react-dom/server');
6
+ var react = require('react');
7
+ var reactQuery = require('@tanstack/react-query');
8
+ var virtual_olovaApp = require('virtual:olova-app');
9
+ var jsxRuntime = require('react/jsx-runtime');
10
+
11
+ // src/entry-worker.tsx
12
+ function matchRoute(pathname) {
13
+ for (const route of virtual_olovaApp.routes) {
14
+ if (route.path === pathname) {
15
+ return { route, params: {} };
16
+ }
17
+ if (route.path.includes(":") || route.path.includes("*")) {
18
+ const pattern = route.path.replace(/\*/g, "(.*)").replace(/:[^/]+/g, "([^/]+)");
19
+ const regex = new RegExp(`^${pattern}$`);
20
+ const match = pathname.match(regex);
21
+ if (match) {
22
+ const params = {};
23
+ const paramNames = route.path.match(/:[^/]+|\*/g) || [];
24
+ paramNames.forEach((name, i) => {
25
+ const key = name === "*" ? "*" : name.slice(1);
26
+ params[key] = match[i + 1];
27
+ });
28
+ return { route, params };
29
+ }
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+ var wrappedLayouts = virtual_olovaApp.layouts.map((item) => ({
35
+ ...item,
36
+ layout: (props) => /* @__PURE__ */ jsxRuntime.jsx(item.layout, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx(virtual_olovaApp.Outlet, {}) })
37
+ }));
38
+ async function render(pathname, loaderData) {
39
+ const g = globalThis;
40
+ g.window = {
41
+ location: { pathname, search: "", hash: "" },
42
+ addEventListener: () => {
43
+ },
44
+ removeEventListener: () => {
45
+ },
46
+ history: { pushState: () => {
47
+ }, replaceState: () => {
48
+ } },
49
+ __LOADER_DATA__: loaderData
50
+ };
51
+ g.__LOADER_DATA__ = loaderData;
52
+ const queryClient = new reactQuery.QueryClient({
53
+ defaultOptions: {
54
+ queries: {
55
+ staleTime: Infinity,
56
+ gcTime: Infinity
57
+ }
58
+ }
59
+ });
60
+ if (loaderData) {
61
+ Object.entries(loaderData).forEach(([key, value]) => {
62
+ queryClient.setQueryData([key], value);
63
+ });
64
+ }
65
+ const queryState = reactQuery.dehydrate(queryClient);
66
+ const html = server.renderToString(
67
+ /* @__PURE__ */ jsxRuntime.jsx(react.StrictMode, { children: /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsxRuntime.jsx(reactQuery.HydrationBoundary, { state: queryState, children: /* @__PURE__ */ jsxRuntime.jsx(react.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
68
+ virtual_olovaApp.OlovaRouter,
69
+ {
70
+ routes: virtual_olovaApp.routes,
71
+ layouts: wrappedLayouts,
72
+ notFoundPages: virtual_olovaApp.notFoundPages
73
+ }
74
+ ) }) }) }) })
75
+ );
76
+ return { html, queryState };
77
+ }
78
+ var entry_worker_default = {
79
+ async fetch(request, env) {
80
+ const url = new URL(request.url);
81
+ const pathname = url.pathname;
82
+ if (!request.headers.get("accept")?.includes("text/html")) {
83
+ return env.ASSETS.fetch(request);
84
+ }
85
+ const match = matchRoute(pathname);
86
+ const needsSSR = match?.route?.loader;
87
+ if (!needsSSR) {
88
+ const staticPath = pathname === "/" ? "/index.html" : `${pathname}/index.html`;
89
+ try {
90
+ const staticResponse = await env.ASSETS.fetch(new URL(staticPath, url));
91
+ if (staticResponse.ok) {
92
+ return new Response(staticResponse.body, {
93
+ status: 200,
94
+ headers: { "Content-Type": "text/html; charset=utf-8" }
95
+ });
96
+ }
97
+ } catch {
98
+ }
99
+ try {
100
+ const notFoundResponse = await env.ASSETS.fetch(new URL("/404.html", url));
101
+ return new Response(notFoundResponse.body, {
102
+ status: 404,
103
+ headers: { "Content-Type": "text/html; charset=utf-8" }
104
+ });
105
+ } catch {
106
+ }
107
+ return new Response("Not Found", { status: 404 });
108
+ }
109
+ let loaderData;
110
+ try {
111
+ const result = await match.route.loader({
112
+ request,
113
+ params: match.params
114
+ });
115
+ if (!(result instanceof Response)) {
116
+ loaderData = result;
117
+ }
118
+ } catch (error) {
119
+ console.error("[Olova] Loader error:", error);
120
+ }
121
+ const { html: appHtml, queryState } = await render(pathname, loaderData);
122
+ const html = `<!DOCTYPE html>${appHtml}<script>window.__QUERY_STATE__=${JSON.stringify(queryState)}</script><script type="module" src="/assets/_olova/main.js"></script>`;
123
+ return new Response(html, {
124
+ headers: { "Content-Type": "text/html; charset=utf-8" }
125
+ });
126
+ }
127
+ };
128
+
129
+ exports.default = entry_worker_default;
130
+ exports.matchRoute = matchRoute;
131
+ exports.render = render;
132
+ //# sourceMappingURL=entry-worker.cjs.map
133
+ //# sourceMappingURL=entry-worker.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/entry-worker.tsx"],"names":["routes","layouts","jsx","Outlet","QueryClient","dehydrate","renderToString","StrictMode","QueryClientProvider","HydrationBoundary","Suspense","OlovaRouter","notFoundPages"],"mappings":"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","file":"entry-worker.cjs","sourcesContent":["/**\n * Olova Cloudflare Workers Entry\n * Auto-generated by plugin - handles SSR for routes with loaders only\n */\n\nimport { renderToString } from 'react-dom/server';\nimport { StrictMode, Suspense } from 'react';\nimport { QueryClient, QueryClientProvider, dehydrate, HydrationBoundary } from '@tanstack/react-query';\n// @ts-expect-error - Virtual module resolved by vite-plugin-olova\nimport { layouts, notFoundPages, OlovaRouter, Outlet, routes } from 'virtual:olova-app';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface RouteMatch {\n route: any;\n params: Record<string, string>;\n}\n\n// =============================================================================\n// ROUTE MATCHING\n// =============================================================================\n\nfunction matchRoute(pathname: string): RouteMatch | null {\n for (const route of routes) {\n // Exact match\n if (route.path === pathname) {\n return { route, params: {} };\n }\n\n // Dynamic segments\n if (route.path.includes(':') || route.path.includes('*')) {\n const pattern = route.path\n .replace(/\\*/g, '(.*)')\n .replace(/:[^/]+/g, '([^/]+)');\n const regex = new RegExp(`^${pattern}$`);\n const match = pathname.match(regex);\n\n if (match) {\n const params: Record<string, string> = {};\n const paramNames = route.path.match(/:[^/]+|\\*/g) || [];\n\n paramNames.forEach((name: string, i: number) => {\n const key = name === '*' ? '*' : name.slice(1);\n params[key] = match[i + 1];\n });\n\n return { route, params };\n }\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// SSR RENDERING\n// =============================================================================\n\n// Wrapper to support \"children\" prop style layouts\nconst wrappedLayouts = layouts.map((item: any) => ({\n ...item,\n layout: (props: any) => (\n <item.layout {...props}>\n <Outlet />\n </item.layout>\n )\n}));\n\nasync function render(\n pathname: string,\n loaderData?: Record<string, unknown>\n): Promise<{ html: string; queryState: unknown }> {\n // Mock browser globals\n const g = globalThis as any;\n g.window = {\n location: { pathname, search: '', hash: '' },\n addEventListener: () => {},\n removeEventListener: () => {},\n history: { pushState: () => {}, replaceState: () => {} },\n __LOADER_DATA__: loaderData\n };\n g.__LOADER_DATA__ = loaderData;\n\n // Create QueryClient with pre-loaded data\n const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: Infinity,\n gcTime: Infinity,\n },\n },\n });\n\n // Pre-populate query client with loader data\n if (loaderData) {\n Object.entries(loaderData).forEach(([key, value]) => {\n queryClient.setQueryData([key], value);\n });\n }\n\n // Get dehydrated state for client hydration\n const queryState = dehydrate(queryClient);\n\n const html = renderToString(\n <StrictMode>\n <QueryClientProvider client={queryClient}>\n <HydrationBoundary state={queryState}>\n <Suspense fallback={null}>\n <OlovaRouter\n routes={routes}\n layouts={wrappedLayouts}\n notFoundPages={notFoundPages}\n />\n </Suspense>\n </HydrationBoundary>\n </QueryClientProvider>\n </StrictMode>\n );\n\n return { html, queryState };\n}\n\n// =============================================================================\n// WORKER EXPORT\n// =============================================================================\n\nexport interface WorkerEnv {\n ASSETS: { fetch: (request: Request | URL) => Promise<Response> };\n}\n\nexport default {\n async fetch(request: Request, env: WorkerEnv): Promise<Response> {\n const url = new URL(request.url);\n const pathname = url.pathname;\n\n // 1. Non-HTML requests → serve static assets directly\n if (!request.headers.get('accept')?.includes('text/html')) {\n return env.ASSETS.fetch(request);\n }\n\n // 2. Check if route has loader (needs SSR)\n const match = matchRoute(pathname);\n const needsSSR = match?.route?.loader;\n\n // 3. No SSR needed → serve pre-built static HTML\n if (!needsSSR) {\n const staticPath = pathname === '/' ? '/index.html' : `${pathname}/index.html`;\n try {\n const staticResponse = await env.ASSETS.fetch(new URL(staticPath, url));\n if (staticResponse.ok) {\n return new Response(staticResponse.body, {\n status: 200,\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\n });\n }\n } catch {}\n \n // Fallback to 404.html\n try {\n const notFoundResponse = await env.ASSETS.fetch(new URL('/404.html', url));\n return new Response(notFoundResponse.body, { \n status: 404, \n headers: { 'Content-Type': 'text/html; charset=utf-8' } \n });\n } catch {}\n \n return new Response('Not Found', { status: 404 });\n }\n\n // 4. Route has loader → run SSR\n let loaderData: Record<string, unknown> | undefined;\n\n try {\n const result = await match.route.loader({\n request,\n params: match.params\n });\n\n if (!(result instanceof Response)) {\n loaderData = result;\n }\n } catch (error) {\n console.error('[Olova] Loader error:', error);\n }\n\n // 5. Render with loader data\n const { html: appHtml, queryState } = await render(pathname, loaderData);\n\n // Build full HTML document\n const html = `<!DOCTYPE html>${appHtml}<script>window.__QUERY_STATE__=${JSON.stringify(queryState)}</script><script type=\"module\" src=\"/assets/_olova/main.js\"></script>`;\n\n return new Response(html, {\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\n });\n }\n};\n\n// Export for SSG builds\nexport { render, matchRoute };\n"]}
@@ -0,0 +1,127 @@
1
+ import { renderToString } from 'react-dom/server';
2
+ import { StrictMode, Suspense } from 'react';
3
+ import { QueryClient, dehydrate, QueryClientProvider, HydrationBoundary } from '@tanstack/react-query';
4
+ import { layouts, Outlet, routes, OlovaRouter, notFoundPages } from 'virtual:olova-app';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ // src/entry-worker.tsx
8
+ function matchRoute(pathname) {
9
+ for (const route of routes) {
10
+ if (route.path === pathname) {
11
+ return { route, params: {} };
12
+ }
13
+ if (route.path.includes(":") || route.path.includes("*")) {
14
+ const pattern = route.path.replace(/\*/g, "(.*)").replace(/:[^/]+/g, "([^/]+)");
15
+ const regex = new RegExp(`^${pattern}$`);
16
+ const match = pathname.match(regex);
17
+ if (match) {
18
+ const params = {};
19
+ const paramNames = route.path.match(/:[^/]+|\*/g) || [];
20
+ paramNames.forEach((name, i) => {
21
+ const key = name === "*" ? "*" : name.slice(1);
22
+ params[key] = match[i + 1];
23
+ });
24
+ return { route, params };
25
+ }
26
+ }
27
+ }
28
+ return null;
29
+ }
30
+ var wrappedLayouts = layouts.map((item) => ({
31
+ ...item,
32
+ layout: (props) => /* @__PURE__ */ jsx(item.layout, { ...props, children: /* @__PURE__ */ jsx(Outlet, {}) })
33
+ }));
34
+ async function render(pathname, loaderData) {
35
+ const g = globalThis;
36
+ g.window = {
37
+ location: { pathname, search: "", hash: "" },
38
+ addEventListener: () => {
39
+ },
40
+ removeEventListener: () => {
41
+ },
42
+ history: { pushState: () => {
43
+ }, replaceState: () => {
44
+ } },
45
+ __LOADER_DATA__: loaderData
46
+ };
47
+ g.__LOADER_DATA__ = loaderData;
48
+ const queryClient = new QueryClient({
49
+ defaultOptions: {
50
+ queries: {
51
+ staleTime: Infinity,
52
+ gcTime: Infinity
53
+ }
54
+ }
55
+ });
56
+ if (loaderData) {
57
+ Object.entries(loaderData).forEach(([key, value]) => {
58
+ queryClient.setQueryData([key], value);
59
+ });
60
+ }
61
+ const queryState = dehydrate(queryClient);
62
+ const html = renderToString(
63
+ /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(HydrationBoundary, { state: queryState, children: /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
64
+ OlovaRouter,
65
+ {
66
+ routes,
67
+ layouts: wrappedLayouts,
68
+ notFoundPages
69
+ }
70
+ ) }) }) }) })
71
+ );
72
+ return { html, queryState };
73
+ }
74
+ var entry_worker_default = {
75
+ async fetch(request, env) {
76
+ const url = new URL(request.url);
77
+ const pathname = url.pathname;
78
+ if (!request.headers.get("accept")?.includes("text/html")) {
79
+ return env.ASSETS.fetch(request);
80
+ }
81
+ const match = matchRoute(pathname);
82
+ const needsSSR = match?.route?.loader;
83
+ if (!needsSSR) {
84
+ const staticPath = pathname === "/" ? "/index.html" : `${pathname}/index.html`;
85
+ try {
86
+ const staticResponse = await env.ASSETS.fetch(new URL(staticPath, url));
87
+ if (staticResponse.ok) {
88
+ return new Response(staticResponse.body, {
89
+ status: 200,
90
+ headers: { "Content-Type": "text/html; charset=utf-8" }
91
+ });
92
+ }
93
+ } catch {
94
+ }
95
+ try {
96
+ const notFoundResponse = await env.ASSETS.fetch(new URL("/404.html", url));
97
+ return new Response(notFoundResponse.body, {
98
+ status: 404,
99
+ headers: { "Content-Type": "text/html; charset=utf-8" }
100
+ });
101
+ } catch {
102
+ }
103
+ return new Response("Not Found", { status: 404 });
104
+ }
105
+ let loaderData;
106
+ try {
107
+ const result = await match.route.loader({
108
+ request,
109
+ params: match.params
110
+ });
111
+ if (!(result instanceof Response)) {
112
+ loaderData = result;
113
+ }
114
+ } catch (error) {
115
+ console.error("[Olova] Loader error:", error);
116
+ }
117
+ const { html: appHtml, queryState } = await render(pathname, loaderData);
118
+ const html = `<!DOCTYPE html>${appHtml}<script>window.__QUERY_STATE__=${JSON.stringify(queryState)}</script><script type="module" src="/assets/_olova/main.js"></script>`;
119
+ return new Response(html, {
120
+ headers: { "Content-Type": "text/html; charset=utf-8" }
121
+ });
122
+ }
123
+ };
124
+
125
+ export { entry_worker_default as default, matchRoute, render };
126
+ //# sourceMappingURL=entry-worker.js.map
127
+ //# sourceMappingURL=entry-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/entry-worker.tsx"],"names":[],"mappings":"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","file":"entry-worker.js","sourcesContent":["/**\n * Olova Cloudflare Workers Entry\n * Auto-generated by plugin - handles SSR for routes with loaders only\n */\n\nimport { renderToString } from 'react-dom/server';\nimport { StrictMode, Suspense } from 'react';\nimport { QueryClient, QueryClientProvider, dehydrate, HydrationBoundary } from '@tanstack/react-query';\n// @ts-expect-error - Virtual module resolved by vite-plugin-olova\nimport { layouts, notFoundPages, OlovaRouter, Outlet, routes } from 'virtual:olova-app';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface RouteMatch {\n route: any;\n params: Record<string, string>;\n}\n\n// =============================================================================\n// ROUTE MATCHING\n// =============================================================================\n\nfunction matchRoute(pathname: string): RouteMatch | null {\n for (const route of routes) {\n // Exact match\n if (route.path === pathname) {\n return { route, params: {} };\n }\n\n // Dynamic segments\n if (route.path.includes(':') || route.path.includes('*')) {\n const pattern = route.path\n .replace(/\\*/g, '(.*)')\n .replace(/:[^/]+/g, '([^/]+)');\n const regex = new RegExp(`^${pattern}$`);\n const match = pathname.match(regex);\n\n if (match) {\n const params: Record<string, string> = {};\n const paramNames = route.path.match(/:[^/]+|\\*/g) || [];\n\n paramNames.forEach((name: string, i: number) => {\n const key = name === '*' ? '*' : name.slice(1);\n params[key] = match[i + 1];\n });\n\n return { route, params };\n }\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// SSR RENDERING\n// =============================================================================\n\n// Wrapper to support \"children\" prop style layouts\nconst wrappedLayouts = layouts.map((item: any) => ({\n ...item,\n layout: (props: any) => (\n <item.layout {...props}>\n <Outlet />\n </item.layout>\n )\n}));\n\nasync function render(\n pathname: string,\n loaderData?: Record<string, unknown>\n): Promise<{ html: string; queryState: unknown }> {\n // Mock browser globals\n const g = globalThis as any;\n g.window = {\n location: { pathname, search: '', hash: '' },\n addEventListener: () => {},\n removeEventListener: () => {},\n history: { pushState: () => {}, replaceState: () => {} },\n __LOADER_DATA__: loaderData\n };\n g.__LOADER_DATA__ = loaderData;\n\n // Create QueryClient with pre-loaded data\n const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: Infinity,\n gcTime: Infinity,\n },\n },\n });\n\n // Pre-populate query client with loader data\n if (loaderData) {\n Object.entries(loaderData).forEach(([key, value]) => {\n queryClient.setQueryData([key], value);\n });\n }\n\n // Get dehydrated state for client hydration\n const queryState = dehydrate(queryClient);\n\n const html = renderToString(\n <StrictMode>\n <QueryClientProvider client={queryClient}>\n <HydrationBoundary state={queryState}>\n <Suspense fallback={null}>\n <OlovaRouter\n routes={routes}\n layouts={wrappedLayouts}\n notFoundPages={notFoundPages}\n />\n </Suspense>\n </HydrationBoundary>\n </QueryClientProvider>\n </StrictMode>\n );\n\n return { html, queryState };\n}\n\n// =============================================================================\n// WORKER EXPORT\n// =============================================================================\n\nexport interface WorkerEnv {\n ASSETS: { fetch: (request: Request | URL) => Promise<Response> };\n}\n\nexport default {\n async fetch(request: Request, env: WorkerEnv): Promise<Response> {\n const url = new URL(request.url);\n const pathname = url.pathname;\n\n // 1. Non-HTML requests → serve static assets directly\n if (!request.headers.get('accept')?.includes('text/html')) {\n return env.ASSETS.fetch(request);\n }\n\n // 2. Check if route has loader (needs SSR)\n const match = matchRoute(pathname);\n const needsSSR = match?.route?.loader;\n\n // 3. No SSR needed → serve pre-built static HTML\n if (!needsSSR) {\n const staticPath = pathname === '/' ? '/index.html' : `${pathname}/index.html`;\n try {\n const staticResponse = await env.ASSETS.fetch(new URL(staticPath, url));\n if (staticResponse.ok) {\n return new Response(staticResponse.body, {\n status: 200,\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\n });\n }\n } catch {}\n \n // Fallback to 404.html\n try {\n const notFoundResponse = await env.ASSETS.fetch(new URL('/404.html', url));\n return new Response(notFoundResponse.body, { \n status: 404, \n headers: { 'Content-Type': 'text/html; charset=utf-8' } \n });\n } catch {}\n \n return new Response('Not Found', { status: 404 });\n }\n\n // 4. Route has loader → run SSR\n let loaderData: Record<string, unknown> | undefined;\n\n try {\n const result = await match.route.loader({\n request,\n params: match.params\n });\n\n if (!(result instanceof Response)) {\n loaderData = result;\n }\n } catch (error) {\n console.error('[Olova] Loader error:', error);\n }\n\n // 5. Render with loader data\n const { html: appHtml, queryState } = await render(pathname, loaderData);\n\n // Build full HTML document\n const html = `<!DOCTYPE html>${appHtml}<script>window.__QUERY_STATE__=${JSON.stringify(queryState)}</script><script type=\"module\" src=\"/assets/_olova/main.js\"></script>`;\n\n return new Response(html, {\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\n });\n }\n};\n\n// Export for SSG builds\nexport { render, matchRoute };\n"]}
package/dist/main.cjs ADDED
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var client = require('react-dom/client');
5
+ var virtual_olovaApp = require('virtual:olova-app');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ // src/main.tsx
9
+ var wrappedLayouts = virtual_olovaApp.layouts.map((item) => ({
10
+ ...item,
11
+ layout: (props) => /* @__PURE__ */ jsxRuntime.jsx(item.layout, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx(virtual_olovaApp.Outlet, {}) })
12
+ }));
13
+ var isBrowser = typeof window !== "undefined" && !undefined.SSR;
14
+ if (isBrowser) {
15
+ client.hydrateRoot(document, /* @__PURE__ */ jsxRuntime.jsx(react.StrictMode, { children: /* @__PURE__ */ jsxRuntime.jsx(virtual_olovaApp.OlovaRouter, { routes: virtual_olovaApp.routes, layouts: wrappedLayouts, notFoundPages: virtual_olovaApp.notFoundPages }) }));
16
+ }
17
+ //# sourceMappingURL=main.cjs.map
18
+ //# sourceMappingURL=main.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/main.tsx"],"names":["layouts","jsx","Outlet","hydrateRoot","StrictMode","OlovaRouter","routes","notFoundPages"],"mappings":";;;;;;;;AAMA,IAAM,cAAA,GAAiBA,wBAAA,CAAQ,GAAA,CAAI,CAAC,IAAA,MAAe;AAAA,EACjD,GAAG,IAAA;AAAA,EACH,MAAA,EAAQ,CAAC,KAAA,qBACPC,cAAA,CAAC,IAAA,CAAK,MAAA,EAAL,EAAa,GAAG,KAAA,EACf,QAAA,kBAAAA,cAAA,CAACC,uBAAA,EAAA,EAAO,CAAA,EACV;AAEJ,CAAA,CAAE,CAAA;AAEF,IAAM,YAAY,OAAO,MAAA,KAAW,WAAA,IAAe,CAAE,SAAoB,CAAI,GAAA;AAE7E,IAAI,SAAA,EAAW;AACb,EAAAC,kBAAA,CAAY,QAAA,kBACVF,cAAA,CAACG,gBAAA,EAAA,EACC,QAAA,kBAAAH,cAAA,CAACI,4BAAA,EAAA,UAAYC,yBAAgB,OAAA,EAAS,cAAA,iBAAgBC,8BAAA,EAA8B,CAAA,EACtF,CACD,CAAA;AACH","file":"main.cjs","sourcesContent":["import { StrictMode } from 'react';\r\nimport { hydrateRoot } from 'react-dom/client';\r\n// @ts-expect-error - Virtual module resolved by vite-plugin-olova\r\nimport { layouts, notFoundPages, OlovaRouter, Outlet, routes } from 'virtual:olova-app';\r\n\r\n// Wrapper to support \"children\" prop style layouts (Next.js style)\r\nconst wrappedLayouts = layouts.map((item: any) => ({\r\n ...item,\r\n layout: (props: any) => (\r\n <item.layout {...props}>\r\n <Outlet />\r\n </item.layout>\r\n )\r\n}));\r\n\r\nconst isBrowser = typeof window !== 'undefined' && !(import.meta as any).env.SSR;\r\n\r\nif (isBrowser) {\r\n hydrateRoot(document, (\r\n <StrictMode>\r\n <OlovaRouter routes={routes} layouts={wrappedLayouts} notFoundPages={notFoundPages} />\r\n </StrictMode>\r\n ));\r\n}\r\n"]}
package/dist/main.js ADDED
@@ -0,0 +1,16 @@
1
+ import { StrictMode } from 'react';
2
+ import { hydrateRoot } from 'react-dom/client';
3
+ import { layouts, Outlet, OlovaRouter, notFoundPages, routes } from 'virtual:olova-app';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ // src/main.tsx
7
+ var wrappedLayouts = layouts.map((item) => ({
8
+ ...item,
9
+ layout: (props) => /* @__PURE__ */ jsx(item.layout, { ...props, children: /* @__PURE__ */ jsx(Outlet, {}) })
10
+ }));
11
+ var isBrowser = typeof window !== "undefined" && !import.meta.env.SSR;
12
+ if (isBrowser) {
13
+ hydrateRoot(document, /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(OlovaRouter, { routes, layouts: wrappedLayouts, notFoundPages }) }));
14
+ }
15
+ //# sourceMappingURL=main.js.map
16
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/main.tsx"],"names":[],"mappings":";;;;;;AAMA,IAAM,cAAA,GAAiB,OAAA,CAAQ,GAAA,CAAI,CAAC,IAAA,MAAe;AAAA,EACjD,GAAG,IAAA;AAAA,EACH,MAAA,EAAQ,CAAC,KAAA,qBACP,GAAA,CAAC,IAAA,CAAK,MAAA,EAAL,EAAa,GAAG,KAAA,EACf,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,CAAA,EACV;AAEJ,CAAA,CAAE,CAAA;AAEF,IAAM,YAAY,OAAO,MAAA,KAAW,WAAA,IAAe,CAAE,YAAoB,GAAA,CAAI,GAAA;AAE7E,IAAI,SAAA,EAAW;AACb,EAAA,WAAA,CAAY,QAAA,kBACV,GAAA,CAAC,UAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,QAAgB,OAAA,EAAS,cAAA,EAAgB,aAAA,EAA8B,CAAA,EACtF,CACD,CAAA;AACH","file":"main.js","sourcesContent":["import { StrictMode } from 'react';\r\nimport { hydrateRoot } from 'react-dom/client';\r\n// @ts-expect-error - Virtual module resolved by vite-plugin-olova\r\nimport { layouts, notFoundPages, OlovaRouter, Outlet, routes } from 'virtual:olova-app';\r\n\r\n// Wrapper to support \"children\" prop style layouts (Next.js style)\r\nconst wrappedLayouts = layouts.map((item: any) => ({\r\n ...item,\r\n layout: (props: any) => (\r\n <item.layout {...props}>\r\n <Outlet />\r\n </item.layout>\r\n )\r\n}));\r\n\r\nconst isBrowser = typeof window !== 'undefined' && !(import.meta as any).env.SSR;\r\n\r\nif (isBrowser) {\r\n hydrateRoot(document, (\r\n <StrictMode>\r\n <OlovaRouter routes={routes} layouts={wrappedLayouts} notFoundPages={notFoundPages} />\r\n </StrictMode>\r\n ));\r\n}\r\n"]}