olova 2.0.61 → 2.0.63

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 (80) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +42 -61
  3. package/dist/compiler.d.ts +44 -0
  4. package/dist/compiler.js +2139 -0
  5. package/dist/compiler.js.map +1 -0
  6. package/dist/core.d.ts +4 -0
  7. package/dist/core.js +859 -0
  8. package/dist/core.js.map +1 -0
  9. package/dist/global.d.ts +15 -0
  10. package/dist/global.js +226 -0
  11. package/dist/global.js.map +1 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.js +2302 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/runtime.d.ts +89 -0
  16. package/dist/runtime.js +633 -0
  17. package/dist/runtime.js.map +1 -0
  18. package/dist/signals-core-BdfWh1Yt.d.ts +43 -0
  19. package/dist/vite.d.ts +5 -0
  20. package/dist/vite.js +2302 -0
  21. package/dist/vite.js.map +1 -0
  22. package/package.json +83 -65
  23. package/dist/chunk-D7SIC5TC.js +0 -367
  24. package/dist/chunk-D7SIC5TC.js.map +0 -1
  25. package/dist/entry-server.cjs +0 -120
  26. package/dist/entry-server.cjs.map +0 -1
  27. package/dist/entry-server.js +0 -115
  28. package/dist/entry-server.js.map +0 -1
  29. package/dist/entry-worker.cjs +0 -133
  30. package/dist/entry-worker.cjs.map +0 -1
  31. package/dist/entry-worker.js +0 -127
  32. package/dist/entry-worker.js.map +0 -1
  33. package/dist/main.cjs +0 -18
  34. package/dist/main.cjs.map +0 -1
  35. package/dist/main.js +0 -16
  36. package/dist/main.js.map +0 -1
  37. package/dist/olova.cjs +0 -1680
  38. package/dist/olova.cjs.map +0 -1
  39. package/dist/olova.d.cts +0 -72
  40. package/dist/olova.d.ts +0 -72
  41. package/dist/olova.js +0 -1321
  42. package/dist/olova.js.map +0 -1
  43. package/dist/performance.cjs +0 -386
  44. package/dist/performance.cjs.map +0 -1
  45. package/dist/performance.js +0 -3
  46. package/dist/performance.js.map +0 -1
  47. package/dist/router.cjs +0 -646
  48. package/dist/router.cjs.map +0 -1
  49. package/dist/router.d.cts +0 -113
  50. package/dist/router.d.ts +0 -113
  51. package/dist/router.js +0 -632
  52. package/dist/router.js.map +0 -1
  53. package/main.tsx +0 -76
  54. package/olova.ts +0 -619
  55. package/src/entry-server.tsx +0 -165
  56. package/src/entry-worker.tsx +0 -201
  57. package/src/generator/index.ts +0 -409
  58. package/src/hydration/flight.ts +0 -320
  59. package/src/hydration/index.ts +0 -12
  60. package/src/hydration/types.ts +0 -225
  61. package/src/logger.ts +0 -182
  62. package/src/main.tsx +0 -24
  63. package/src/performance.ts +0 -488
  64. package/src/plugin/index.ts +0 -204
  65. package/src/router/ErrorBoundary.tsx +0 -145
  66. package/src/router/Link.tsx +0 -117
  67. package/src/router/OlovaRouter.tsx +0 -354
  68. package/src/router/Outlet.tsx +0 -8
  69. package/src/router/context.ts +0 -117
  70. package/src/router/index.ts +0 -29
  71. package/src/router/matching.ts +0 -63
  72. package/src/router/router.tsx +0 -23
  73. package/src/router/search-params.ts +0 -29
  74. package/src/scanner/index.ts +0 -114
  75. package/src/types/index.ts +0 -190
  76. package/src/utils/export.ts +0 -85
  77. package/src/utils/index.ts +0 -4
  78. package/src/utils/naming.ts +0 -54
  79. package/src/utils/path.ts +0 -45
  80. package/tsup.config.ts +0 -35
@@ -1,320 +0,0 @@
1
- /**
2
- * Olova Flight Format Hydration System
3
- * Implements "Flight" format for efficient client hydration (Next.js style)
4
- */
5
-
6
- import type {
7
- AssetsChunkData,
8
- HintsChunkData,
9
- MetadataChunkData,
10
- OlovaGlobal,
11
- OlovaHydrationData,
12
- ParsedFlightData,
13
- RouteChunkData,
14
- StateChunkData,
15
- TreeChunkData,
16
- } from './types.js';
17
-
18
- /**
19
- * Safely stringify JSON for embedding in script tags
20
- * Escapes <, >, /, \u2028, and \u2029 to prevent XSS and syntax errors
21
- */
22
- function safeStringify(data: unknown): string {
23
- return JSON.stringify(data).replace(/[<>\/\u2028\u2029]/g, (char) => {
24
- switch (char) {
25
- case '<': return '\\u003c';
26
- case '>': return '\\u003e';
27
- case '/': return '\\u002f';
28
- case '\u2028': return '\\u2028';
29
- case '\u2029': return '\\u2029';
30
- default: return char;
31
- }
32
- });
33
- }
34
-
35
- /**
36
- * Generate a page name from route path
37
- */
38
- function generatePageName(route: string): string {
39
- if (route === '/') return 'HomePage';
40
- return route
41
- .slice(1)
42
- .split('/')
43
- .filter(Boolean)
44
- .map(s => s.charAt(0).toUpperCase() + s.slice(1).replace(/[^a-zA-Z0-9]/g, ''))
45
- .join('') + 'Page';
46
- }
47
-
48
- /**
49
- * Generate route pattern from path
50
- */
51
- function generatePattern(route: string): string {
52
- if (route === '/') return '/';
53
- return route
54
- .replace(/\[\.\.\.([^\]]+)\]/g, '*')
55
- .replace(/\[([^\]]+)\]/g, ':$1');
56
- }
57
-
58
- /**
59
- * Generate the Flight runtime script (Next.js style)
60
- * This script processes the flight data array and hydrates the app
61
- */
62
- function generateFlightRuntime(): string {
63
- return `<script>
64
- (function(){
65
- var f=self.__olova_f||[];
66
- var p={R:'$route',M:'$meta',T:'$tree',D:'$schema',A:'$assets',H:'$hints',S:'$state',L:'$loader',Q:'$query'};
67
- var g=self.$OLOVA={};
68
- function h(c){var t=c[1],d=c[2];if(t==='E')return;var k=p[t];if(k){if(t==='L'||t==='Q'){g[k]={data:d,timestamp:c[3]||Date.now()}}else{g[k]=d}}}
69
- for(var i=0;i<f.length;i++)h(f[i]);
70
- self.__olova_f={push:h,length:0};
71
- })();
72
- </script>`;
73
- }
74
-
75
- /**
76
- * Generate Olova hydration scripts using the Flight format
77
- * Creates chunked data that streams into the __olova_f array (Next.js style)
78
- */
79
- export function generateOlovaHydration(data: OlovaHydrationData, buildId: string): string {
80
- const meta = (data.metadata || {}) as Record<string, unknown>;
81
- const chunks: string[] = [];
82
-
83
- // ==========================================================================
84
- // CHUNK 0: Route Information
85
- // ==========================================================================
86
- const routeData: RouteChunkData = {
87
- path: data.route,
88
- params: data.params || {},
89
- pattern: generatePattern(data.route),
90
- isStatic: data.isStatic ?? true,
91
- buildId: buildId
92
- };
93
- chunks.push(`<script>(self.__olova_f=self.__olova_f||[]).push([0,"R",${safeStringify(routeData)}])</script>`);
94
-
95
- // ==========================================================================
96
- // CHUNK 1: Metadata
97
- // ==========================================================================
98
- const metadataData: MetadataChunkData = {
99
- title: (meta.title as string) || 'Olova App',
100
- description: (meta.description as string) || '',
101
- keywords: Array.isArray(meta.keywords) ? meta.keywords : [],
102
- robots: (meta.robots as string) || 'index, follow',
103
- canonical: (meta.canonical as string) || null,
104
- og: {
105
- type: 'website',
106
- locale: 'en_US',
107
- ...((meta.openGraph as object) || {})
108
- },
109
- twitter: {
110
- card: 'summary_large_image',
111
- ...((meta.twitter as object) || {})
112
- }
113
- };
114
- chunks.push(`<script>(self.__olova_f).push([1,"M",${safeStringify(metadataData)}])</script>`);
115
-
116
- // ==========================================================================
117
- // CHUNK 2: Component Tree
118
- // ==========================================================================
119
- const treeData: TreeChunkData = {
120
- layout: 'RootLayout',
121
- page: generatePageName(data.route),
122
- template: null,
123
- loading: null,
124
- error: null,
125
- notFound: null
126
- };
127
- chunks.push(`<script>(self.__olova_f).push([2,"T",${safeStringify(treeData)}])</script>`);
128
-
129
- // ==========================================================================
130
- // CHUNK 3: Assets
131
- // ==========================================================================
132
- const assetsData: AssetsChunkData = {
133
- chunks: data.chunks || [],
134
- styles: [],
135
- prefetch: (data.chunks || []).slice(0, 5)
136
- };
137
- chunks.push(`<script>(self.__olova_f).push([3,"A",${safeStringify(assetsData)}])</script>`);
138
-
139
- // ==========================================================================
140
- // CHUNK 4: Resource Hints
141
- // ==========================================================================
142
- const hintsData: HintsChunkData = {
143
- dnsPrefetch: ['fonts.googleapis.com', 'fonts.gstatic.com'],
144
- preconnect: ['https://fonts.googleapis.com', 'https://fonts.gstatic.com'],
145
- modulePreload: (data.chunks || []).slice(0, 3)
146
- };
147
- chunks.push(`<script>(self.__olova_f).push([4,"H",${safeStringify(hintsData)}])</script>`);
148
-
149
- // ==========================================================================
150
- // CHUNK 5: Hydration State
151
- // ==========================================================================
152
- const stateData: StateChunkData = {
153
- hydrated: false,
154
- streaming: false,
155
- ready: true,
156
- timestamp: Date.now(),
157
- version: '1.0.0',
158
- buildId: buildId
159
- };
160
- chunks.push(`<script>(self.__olova_f).push([5,"S",${safeStringify(stateData)}])</script>`);
161
-
162
- // ==========================================================================
163
- // CHUNK 6: Loader Data (if present)
164
- // ==========================================================================
165
- if (data.loaderData) {
166
- chunks.push(`<script>(self.__olova_f).push([6,"L",${safeStringify(data.loaderData)},${Date.now()}])</script>`);
167
- }
168
-
169
- // ==========================================================================
170
- // CHUNK 7: Query State (if present)
171
- // ==========================================================================
172
- if (data.queryState) {
173
- chunks.push(`<script>(self.__olova_f).push([7,"Q",${safeStringify(data.queryState)},${Date.now()}])</script>`);
174
- }
175
-
176
- // ==========================================================================
177
- // CHUNK 8: END MARKER
178
- // ==========================================================================
179
- chunks.push(`<script>(self.__olova_f).push([8,"E",null])</script>`);
180
-
181
- // ==========================================================================
182
- // FLIGHT RUNTIME: Process all chunks into $OLOVA global (Next.js style)
183
- // ==========================================================================
184
- chunks.push(generateFlightRuntime());
185
-
186
- return chunks.join('');
187
- }
188
-
189
- /**
190
- * Generate JSON-LD structured data script for SEO
191
- * This is injected into <head> for search engine crawlers
192
- */
193
- export function generateJsonLd(data: OlovaHydrationData): string {
194
- const meta = (data.metadata || {}) as Record<string, unknown>;
195
-
196
- const jsonLd = {
197
- '@context': 'https://schema.org',
198
- '@graph': [
199
- {
200
- '@type': 'WebPage',
201
- '@id': data.route,
202
- name: (meta.title as string) || 'Olova App',
203
- description: (meta.description as string) || '',
204
- url: data.route,
205
- isPartOf: {
206
- '@type': 'WebSite',
207
- name: 'Olova App'
208
- }
209
- },
210
- {
211
- '@type': 'BreadcrumbList',
212
- itemListElement: data.route.split('/').filter(Boolean).map((segment, index, arr) => ({
213
- '@type': 'ListItem',
214
- position: index + 1,
215
- name: segment.charAt(0).toUpperCase() + segment.slice(1),
216
- item: '/' + arr.slice(0, index + 1).join('/')
217
- }))
218
- }
219
- ]
220
- };
221
-
222
- // Add custom schemas from page metadata
223
- if (meta.schema) {
224
- const graph = jsonLd['@graph'] as unknown[];
225
- if (Array.isArray(meta.schema)) {
226
- graph.push(...meta.schema);
227
- } else {
228
- graph.push(meta.schema);
229
- }
230
- }
231
-
232
- return `<script type="application/ld+json">${JSON.stringify(jsonLd)}</script>`;
233
- }
234
-
235
- /**
236
- * Generate resource hint link tags for the head
237
- */
238
- export function generateResourceHints(data: OlovaHydrationData): string {
239
- const hints: string[] = [];
240
-
241
- // DNS Prefetch for common external resources
242
- hints.push(`<link rel="dns-prefetch" href="//fonts.googleapis.com">`);
243
- hints.push(`<link rel="dns-prefetch" href="//fonts.gstatic.com">`);
244
-
245
- // Preconnect to critical origins
246
- hints.push(`<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>`);
247
- hints.push(`<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>`);
248
-
249
- // Module preload for chunks
250
- if (data.chunks) {
251
- for (const chunk of data.chunks.slice(0, 3)) {
252
- hints.push(`<link rel="modulepreload" href="/${chunk}">`);
253
- }
254
- }
255
-
256
- return hints.join('');
257
- }
258
-
259
- /**
260
- * Parse flight data from the page (client-side utility)
261
- * Use this to access hydration data in your components
262
- */
263
- export function parseFlightData(): ParsedFlightData | null {
264
- // Check if we're in a browser environment
265
- if (typeof globalThis === 'undefined' || typeof (globalThis as Record<string, unknown>).document === 'undefined') {
266
- return null;
267
- }
268
-
269
- const flightArray = ((globalThis as Record<string, unknown>).__olova_f) as unknown[] | undefined;
270
- if (!flightArray) return null;
271
-
272
- const result: ParsedFlightData = {};
273
- const typeMap: Record<string, keyof ParsedFlightData | '$end'> = {
274
- 'M': '$meta',
275
- 'T': '$tree',
276
- 'R': '$route',
277
- 'A': '$assets',
278
- 'S': '$state',
279
- 'D': '$schema',
280
- 'H': '$hints',
281
- 'L': '$loader',
282
- 'Q': '$query',
283
- 'E': '$end'
284
- };
285
-
286
- for (const chunk of flightArray) {
287
- if (Array.isArray(chunk) && chunk.length >= 3) {
288
- const [_index, type, data] = chunk;
289
- const key = typeMap[String(type)];
290
- if (key && key !== '$end') {
291
- (result as Record<string, unknown>)[key] = data;
292
- }
293
- }
294
- }
295
-
296
- return result;
297
- }
298
-
299
- /**
300
- * Get the global $OLOVA object (client-side)
301
- */
302
- export function getOlovaGlobal(): OlovaGlobal | null {
303
- if (typeof globalThis === 'undefined') return null;
304
- return ((globalThis as Record<string, unknown>).$OLOVA as OlovaGlobal) || null;
305
- }
306
-
307
- /**
308
- * Generate a unique build ID
309
- */
310
- export function generateBuildId(): string {
311
- const timestamp = Date.now().toString(36);
312
- const random = Math.random().toString(36).substring(2, 8);
313
- return `${timestamp}-${random}`;
314
- }
315
-
316
- // Re-export types for convenience
317
- export type {
318
- FlightChunk, FlightDataType, OlovaGlobal, OlovaHydrationData, PageMetadata, ParsedFlightData
319
- } from './types.js';
320
-
@@ -1,12 +0,0 @@
1
- /**
2
- * Olova Flight Hydration - Public API
3
- */
4
-
5
- export {
6
- generateBuildId, generateJsonLd, generateOlovaHydration, generateResourceHints, getOlovaGlobal, parseFlightData
7
- } from './flight.js';
8
-
9
- export type {
10
- AssetsChunkData, BuildInfo, DehydratedState, FlightChunk, FlightDataType, HintsChunkData, LoaderChunkData, LoaderData, MetadataChunkData, OlovaGlobal, OlovaHydrationData, PageMetadata, ParsedFlightData, QueryChunkData, RouteChunkData, StateChunkData, TreeChunkData
11
- } from './types.js';
12
-
@@ -1,225 +0,0 @@
1
- /**
2
- * Olova Flight Format Hydration Types
3
- * Type definitions for the Flight hydration system
4
- */
5
-
6
- /**
7
- * Flight data type identifiers
8
- * Each chunk type has a specific purpose in the hydration flow
9
- */
10
- export type FlightDataType =
11
- | 'R' // Route - navigation and routing info
12
- | 'M' // Metadata - SEO and page metadata
13
- | 'T' // Tree - component tree structure
14
- | 'D' // Data - JSON-LD structured data
15
- | 'A' // Assets - chunks for prefetching
16
- | 'H' // Hints - resource hints (dns-prefetch, preconnect)
17
- | 'S' // State - hydration state
18
- | 'L' // Loader - server-side data (TanStack Query compatible)
19
- | 'Q' // Query - TanStack Query dehydrated state
20
- | 'E'; // End - marks completion
21
-
22
- /**
23
- * Loader data type - can be any JSON-serializable data
24
- */
25
- export type LoaderData = Record<string, unknown>;
26
-
27
- /**
28
- * TanStack Query dehydrated state
29
- */
30
- export interface DehydratedState {
31
- queries?: Array<{
32
- queryKey: unknown[];
33
- queryData: unknown;
34
- state?: {
35
- status: string;
36
- dataUpdatedAt?: number;
37
- };
38
- }>;
39
- mutations?: unknown[];
40
- }
41
-
42
- /**
43
- * Input data for hydration generation
44
- */
45
- export interface OlovaHydrationData {
46
- route: string;
47
- params?: Record<string, string>;
48
- metadata?: PageMetadata;
49
- chunks?: string[];
50
- isStatic?: boolean;
51
- /** Data from route loaders (TanStack Query compatible) */
52
- loaderData?: LoaderData;
53
- /** TanStack Query dehydrated state */
54
- queryState?: DehydratedState;
55
- }
56
-
57
- /**
58
- * Page metadata structure (SEO)
59
- */
60
- export interface PageMetadata {
61
- title?: string;
62
- description?: string;
63
- keywords?: string[];
64
- robots?: string;
65
- canonical?: string;
66
- openGraph?: OpenGraphData;
67
- twitter?: TwitterCardData;
68
- schema?: unknown | unknown[];
69
- }
70
-
71
- /**
72
- * OpenGraph metadata
73
- */
74
- export interface OpenGraphData {
75
- type?: string;
76
- locale?: string;
77
- title?: string;
78
- description?: string;
79
- image?: string;
80
- url?: string;
81
- siteName?: string;
82
- }
83
-
84
- /**
85
- * Twitter Card metadata
86
- */
87
- export interface TwitterCardData {
88
- card?: 'summary' | 'summary_large_image' | 'app' | 'player';
89
- site?: string;
90
- creator?: string;
91
- title?: string;
92
- description?: string;
93
- image?: string;
94
- }
95
-
96
- /**
97
- * Individual Flight chunk structure
98
- */
99
- export interface FlightChunk {
100
- type: FlightDataType;
101
- data: unknown;
102
- }
103
-
104
- /**
105
- * Route chunk data (Chunk 0)
106
- */
107
- export interface RouteChunkData {
108
- path: string;
109
- params: Record<string, string>;
110
- pattern: string;
111
- isStatic: boolean;
112
- buildId: string;
113
- }
114
-
115
- /**
116
- * Metadata chunk data (Chunk 1)
117
- */
118
- export interface MetadataChunkData {
119
- title: string;
120
- description: string;
121
- keywords: string[];
122
- robots: string;
123
- canonical: string | null;
124
- og: OpenGraphData;
125
- twitter: TwitterCardData;
126
- }
127
-
128
- /**
129
- * Component tree chunk data (Chunk 2)
130
- */
131
- export interface TreeChunkData {
132
- layout: string;
133
- page: string;
134
- template: string | null;
135
- loading: string | null;
136
- error: string | null;
137
- notFound: string | null;
138
- }
139
-
140
- /**
141
- * Assets chunk data (Chunk 4)
142
- */
143
- export interface AssetsChunkData {
144
- chunks: string[];
145
- styles: string[];
146
- prefetch: string[];
147
- }
148
-
149
- /**
150
- * Resource hints chunk data (Chunk 5)
151
- */
152
- export interface HintsChunkData {
153
- dnsPrefetch: string[];
154
- preconnect: string[];
155
- modulePreload: string[];
156
- }
157
-
158
- /**
159
- * Hydration state chunk data (Chunk 6)
160
- */
161
- export interface StateChunkData {
162
- hydrated: boolean;
163
- streaming: boolean;
164
- ready: boolean;
165
- timestamp: number;
166
- version: string;
167
- buildId: string;
168
- }
169
-
170
- /**
171
- * Loader data chunk (Chunk 7) - for data-only SSR
172
- */
173
- export interface LoaderChunkData {
174
- data: LoaderData;
175
- timestamp: number;
176
- }
177
-
178
- /**
179
- * Query state chunk (Chunk 8) - TanStack Query hydration
180
- */
181
- export interface QueryChunkData {
182
- state: DehydratedState;
183
- timestamp: number;
184
- }
185
-
186
- /**
187
- * Build info structure
188
- */
189
- export interface BuildInfo {
190
- id: string;
191
- version: string;
192
- timestamp: number;
193
- env: 'development' | 'production';
194
- }
195
-
196
- /**
197
- * Global $OLOVA object structure
198
- */
199
- export interface OlovaGlobal {
200
- $route: RouteChunkData;
201
- $meta: MetadataChunkData;
202
- $tree: TreeChunkData;
203
- $schema: unknown[];
204
- $assets: AssetsChunkData;
205
- $hints: HintsChunkData;
206
- $state: StateChunkData;
207
- $loader?: LoaderChunkData;
208
- $query?: QueryChunkData;
209
- $build: BuildInfo;
210
- }
211
-
212
- /**
213
- * Parsed flight data result
214
- */
215
- export interface ParsedFlightData {
216
- $route?: RouteChunkData;
217
- $meta?: MetadataChunkData;
218
- $tree?: TreeChunkData;
219
- $schema?: unknown[];
220
- $assets?: AssetsChunkData;
221
- $hints?: HintsChunkData;
222
- $state?: StateChunkData;
223
- $loader?: LoaderChunkData;
224
- $query?: QueryChunkData;
225
- }