olova 2.0.40 → 2.0.41
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 +305 -12
- package/dist/client.d.ts +9 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +8 -0
- package/dist/client.js.map +1 -0
- package/dist/core/config.d.ts +179 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +33 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/types.d.ts +16 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/data/hooks.d.ts +5 -0
- package/dist/data/hooks.d.ts.map +1 -0
- package/dist/data/hooks.js +19 -0
- package/dist/data/hooks.js.map +1 -0
- package/dist/data/index.d.ts +9 -0
- package/dist/data/index.d.ts.map +1 -0
- package/dist/data/index.js +9 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data/provider.d.ts +10 -0
- package/dist/data/provider.d.ts.map +1 -0
- package/dist/data/provider.js +10 -0
- package/dist/data/provider.js.map +1 -0
- package/dist/data/serialize.d.ts +10 -0
- package/dist/data/serialize.d.ts.map +1 -0
- package/dist/data/serialize.js +16 -0
- package/dist/data/serialize.js.map +1 -0
- package/dist/data/types.d.ts +9 -0
- package/dist/data/types.d.ts.map +1 -0
- package/dist/data/types.js +2 -0
- package/dist/data/types.js.map +1 -0
- package/dist/head/Head.d.ts +8 -0
- package/dist/head/Head.d.ts.map +1 -0
- package/dist/head/Head.js +56 -0
- package/dist/head/Head.js.map +1 -0
- package/dist/head/HeadProvider.d.ts +31 -0
- package/dist/head/HeadProvider.d.ts.map +1 -0
- package/dist/head/HeadProvider.js +17 -0
- package/dist/head/HeadProvider.js.map +1 -0
- package/dist/head/index.d.ts +8 -0
- package/dist/head/index.d.ts.map +1 -0
- package/dist/head/index.js +8 -0
- package/dist/head/index.js.map +1 -0
- package/dist/head/ssr.d.ts +9 -0
- package/dist/head/ssr.d.ts.map +1 -0
- package/dist/head/ssr.js +35 -0
- package/dist/head/ssr.js.map +1 -0
- package/dist/hydration/context.d.ts +14 -0
- package/dist/hydration/context.d.ts.map +1 -0
- package/dist/hydration/context.js +20 -0
- package/dist/hydration/context.js.map +1 -0
- package/dist/hydration/index.d.ts +15 -0
- package/dist/hydration/index.d.ts.map +1 -0
- package/dist/hydration/index.js +25 -0
- package/dist/hydration/index.js.map +1 -0
- package/dist/hydration/payload.d.ts +46 -0
- package/dist/hydration/payload.d.ts.map +1 -0
- package/dist/hydration/payload.js +99 -0
- package/dist/hydration/payload.js.map +1 -0
- package/dist/hydration/scheduler.d.ts +16 -0
- package/dist/hydration/scheduler.d.ts.map +1 -0
- package/dist/hydration/scheduler.js +83 -0
- package/dist/hydration/scheduler.js.map +1 -0
- package/dist/hydration/seo.d.ts +10 -0
- package/dist/hydration/seo.d.ts.map +1 -0
- package/dist/hydration/seo.js +110 -0
- package/dist/hydration/seo.js.map +1 -0
- package/dist/hydration/serialization.d.ts +30 -0
- package/dist/hydration/serialization.d.ts.map +1 -0
- package/dist/hydration/serialization.js +99 -0
- package/dist/hydration/serialization.js.map +1 -0
- package/dist/hydration/types.d.ts +104 -0
- package/dist/hydration/types.d.ts.map +1 -0
- package/dist/hydration/types.js +2 -0
- package/dist/hydration/types.js.map +1 -0
- package/dist/index.d.ts +15 -85
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -1
- package/dist/plugin/cache.d.ts +66 -0
- package/dist/plugin/cache.d.ts.map +1 -0
- package/dist/plugin/cache.js +129 -0
- package/dist/plugin/cache.js.map +1 -0
- package/dist/plugin/index.d.ts +8 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +8 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/plugin.d.ts +25 -0
- package/dist/plugin/plugin.d.ts.map +1 -0
- package/dist/plugin/plugin.js +601 -0
- package/dist/plugin/plugin.js.map +1 -0
- package/dist/router/Link.d.ts +7 -0
- package/dist/router/Link.d.ts.map +1 -0
- package/dist/router/Link.js +53 -0
- package/dist/router/Link.js.map +1 -0
- package/dist/router/Router.d.ts +7 -0
- package/dist/router/Router.d.ts.map +1 -0
- package/dist/router/Router.js +263 -0
- package/dist/router/Router.js.map +1 -0
- package/dist/router/context.d.ts +13 -0
- package/dist/router/context.d.ts.map +1 -0
- package/dist/router/context.js +47 -0
- package/dist/router/context.js.map +1 -0
- package/dist/router/hooks.d.ts +30 -0
- package/dist/router/hooks.d.ts.map +1 -0
- package/dist/router/hooks.js +59 -0
- package/dist/router/hooks.js.map +1 -0
- package/dist/router/index.d.ts +13 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +14 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/matching.d.ts +19 -0
- package/dist/router/matching.d.ts.map +1 -0
- package/dist/router/matching.js +115 -0
- package/dist/router/matching.js.map +1 -0
- package/dist/router/navigation.d.ts +26 -0
- package/dist/router/navigation.d.ts.map +1 -0
- package/dist/router/navigation.js +65 -0
- package/dist/router/navigation.js.map +1 -0
- package/dist/router/types.d.ts +61 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +6 -0
- package/dist/router/types.js.map +1 -0
- package/dist/server.d.ts +10 -16
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +7 -19
- package/dist/server.js.map +1 -1
- package/dist/streaming/html.d.ts +29 -0
- package/dist/streaming/html.d.ts.map +1 -0
- package/dist/streaming/html.js +72 -0
- package/dist/streaming/html.js.map +1 -0
- package/dist/streaming/index.d.ts +7 -0
- package/dist/streaming/index.d.ts.map +1 -0
- package/dist/streaming/index.js +7 -0
- package/dist/streaming/index.js.map +1 -0
- package/dist/streaming/render.d.ts +32 -0
- package/dist/streaming/render.d.ts.map +1 -0
- package/dist/streaming/render.js +83 -0
- package/dist/streaming/render.js.map +1 -0
- package/dist/streaming/utils.d.ts +30 -0
- package/dist/streaming/utils.d.ts.map +1 -0
- package/dist/streaming/utils.js +61 -0
- package/dist/streaming/utils.js.map +1 -0
- package/package.json +43 -35
- package/dist/router.d.ts +0 -3
- package/dist/router.js +0 -234
- package/dist/router.js.map +0 -1
- package/dist/vite.d.ts +0 -98
- package/dist/vite.js +0 -1820
- package/dist/vite.js.map +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { FlightPayload } from '../hydration/types';
|
|
2
|
+
import type { StreamingOptions } from './render';
|
|
3
|
+
export interface StreamingResponseOptions extends StreamingOptions {
|
|
4
|
+
status?: number;
|
|
5
|
+
headers?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Create a Transform stream that injects Flight chunks
|
|
9
|
+
*/
|
|
10
|
+
export declare function createFlightInjector(payload: FlightPayload): {
|
|
11
|
+
addChunk(id: string, html: string, data?: any): void;
|
|
12
|
+
flush(): string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Create a Suspense fallback placeholder
|
|
16
|
+
*/
|
|
17
|
+
export declare function createSuspensePlaceholder(id: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Create resolved Suspense content
|
|
20
|
+
*/
|
|
21
|
+
export declare function createSuspenseResolved(id: string, html: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Check if we're in a streaming context
|
|
24
|
+
*/
|
|
25
|
+
export declare function isStreaming(): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Create headers for streaming response
|
|
28
|
+
*/
|
|
29
|
+
export declare function createStreamingHeaders(options?: StreamingResponseOptions): Record<string, string>;
|
|
30
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/streaming/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,oBAAoB,CAAC;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD,MAAM,WAAW,wBAAyB,SAAQ,gBAAgB;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa;iBAK1C,MAAM,QAAQ,MAAM,SAAS,GAAG,GAAG,IAAI;aAY3C,MAAM;EAOlB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAIrC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,wBAA6B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOrG"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { addFlightChunk, generateChunkScript, getFlightContext } from '../hydration';
|
|
2
|
+
/**
|
|
3
|
+
* Create a Transform stream that injects Flight chunks
|
|
4
|
+
*/
|
|
5
|
+
export function createFlightInjector(payload) {
|
|
6
|
+
const chunks = [];
|
|
7
|
+
let chunkOrder = 0;
|
|
8
|
+
return {
|
|
9
|
+
addChunk(id, html, data) {
|
|
10
|
+
const chunk = {
|
|
11
|
+
id,
|
|
12
|
+
html,
|
|
13
|
+
ready: true,
|
|
14
|
+
data,
|
|
15
|
+
order: chunkOrder++,
|
|
16
|
+
};
|
|
17
|
+
chunks.push(chunk);
|
|
18
|
+
addFlightChunk(payload, id, html, data);
|
|
19
|
+
},
|
|
20
|
+
flush() {
|
|
21
|
+
if (chunks.length === 0)
|
|
22
|
+
return '';
|
|
23
|
+
const scripts = chunks.map(chunk => generateChunkScript(chunk)).join('\n');
|
|
24
|
+
chunks.length = 0;
|
|
25
|
+
return scripts;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a Suspense fallback placeholder
|
|
31
|
+
*/
|
|
32
|
+
export function createSuspensePlaceholder(id) {
|
|
33
|
+
return `<template data-flight-id="${id}" data-suspense="pending"></template>`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create resolved Suspense content
|
|
37
|
+
*/
|
|
38
|
+
export function createSuspenseResolved(id, html) {
|
|
39
|
+
return `<!--$?--><template data-flight-id="${id}" data-suspense="resolved">${html}</template><!--/$-->`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Check if we're in a streaming context
|
|
43
|
+
*/
|
|
44
|
+
export function isStreaming() {
|
|
45
|
+
if (typeof window !== 'undefined')
|
|
46
|
+
return false;
|
|
47
|
+
const context = getFlightContext();
|
|
48
|
+
return context?.isStreaming ?? false;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create headers for streaming response
|
|
52
|
+
*/
|
|
53
|
+
export function createStreamingHeaders(options = {}) {
|
|
54
|
+
return {
|
|
55
|
+
'Content-Type': 'text/html; charset=utf-8',
|
|
56
|
+
'Transfer-Encoding': 'chunked',
|
|
57
|
+
'X-Content-Type-Options': 'nosniff',
|
|
58
|
+
...options.headers,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/streaming/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAQrF;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAsB;IACzD,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,OAAO;QACL,QAAQ,CAAC,EAAU,EAAE,IAAY,EAAE,IAAU;YAC3C,MAAM,KAAK,GAAgB;gBACzB,EAAE;gBACF,IAAI;gBACJ,KAAK,EAAE,IAAI;gBACX,IAAI;gBACJ,KAAK,EAAE,UAAU,EAAE;aACpB,CAAC;YACF,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,cAAc,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,CAAC;QAED,KAAK;YACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3E,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,EAAU;IAClD,OAAO,6BAA6B,EAAE,uCAAuC,CAAC;AAChF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAU,EAAE,IAAY;IAC7D,OAAO,sCAAsC,EAAE,8BAA8B,IAAI,sBAAsB,CAAC;AAC1G,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAChD,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,OAAO,OAAO,EAAE,WAAW,IAAI,KAAK,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAAoC,EAAE;IAC3E,OAAO;QACL,cAAc,EAAE,0BAA0B;QAC1C,mBAAmB,EAAE,SAAS;QAC9B,wBAAwB,EAAE,SAAS;QACnC,GAAG,OAAO,CAAC,OAAO;KACnB,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,55 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "olova",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "framework built
|
|
3
|
+
"version": "2.0.41",
|
|
4
|
+
"description": "A Next.js-style React framework built on Vite with SSG, SSR, streaming, and progressive hydration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
12
|
},
|
|
13
|
-
"./
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
},
|
|
17
|
-
"./router": {
|
|
18
|
-
"import": "./dist/router.js",
|
|
19
|
-
"types": "./dist/router.d.ts"
|
|
13
|
+
"./client": {
|
|
14
|
+
"types": "./dist/client.d.ts",
|
|
15
|
+
"default": "./dist/client.js"
|
|
20
16
|
},
|
|
21
17
|
"./server": {
|
|
22
|
-
"
|
|
23
|
-
"
|
|
18
|
+
"types": "./dist/server.d.ts",
|
|
19
|
+
"default": "./dist/server.js"
|
|
20
|
+
},
|
|
21
|
+
"./plugin": {
|
|
22
|
+
"types": "./dist/plugin.d.ts",
|
|
23
|
+
"default": "./dist/plugin.js"
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
|
-
"dist"
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md"
|
|
28
29
|
],
|
|
29
30
|
"scripts": {
|
|
30
|
-
"build": "
|
|
31
|
-
"
|
|
31
|
+
"build": "tsc",
|
|
32
|
+
"clean": "rimraf dist",
|
|
33
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
32
34
|
},
|
|
33
35
|
"keywords": [
|
|
34
|
-
"vite",
|
|
35
|
-
"static-site-generator",
|
|
36
|
-
"static-site",
|
|
37
|
-
"ssg",
|
|
38
|
-
"documentation",
|
|
39
36
|
"react",
|
|
37
|
+
"vite",
|
|
40
38
|
"framework",
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"front-end",
|
|
48
|
-
"static",
|
|
49
|
-
"seo-friendly",
|
|
50
|
-
"fast",
|
|
51
|
-
"web-framework",
|
|
52
|
-
"meta-tags"
|
|
39
|
+
"ssr",
|
|
40
|
+
"ssg",
|
|
41
|
+
"streaming",
|
|
42
|
+
"hydration",
|
|
43
|
+
"next.js",
|
|
44
|
+
"router"
|
|
53
45
|
],
|
|
54
46
|
"author": "",
|
|
55
47
|
"license": "MIT",
|
|
@@ -58,11 +50,27 @@
|
|
|
58
50
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
59
51
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
60
52
|
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"marked": "^17.0.0",
|
|
55
|
+
"html-minifier-terser": "^7.0.0"
|
|
56
|
+
},
|
|
61
57
|
"devDependencies": {
|
|
62
58
|
"@types/node": "^22.0.0",
|
|
63
59
|
"@types/react": "^19.0.0",
|
|
64
60
|
"@types/react-dom": "^19.0.0",
|
|
65
|
-
"
|
|
61
|
+
"@types/html-minifier-terser": "^7.0.0",
|
|
62
|
+
"react": "^19.0.0",
|
|
63
|
+
"react-dom": "^19.0.0",
|
|
64
|
+
"vite": "^7.0.0",
|
|
65
|
+
"rimraf": "^5.0.0",
|
|
66
66
|
"typescript": "^5.0.0"
|
|
67
|
-
}
|
|
67
|
+
},
|
|
68
|
+
"repository": {
|
|
69
|
+
"type": "git",
|
|
70
|
+
"url": ""
|
|
71
|
+
},
|
|
72
|
+
"bugs": {
|
|
73
|
+
"url": ""
|
|
74
|
+
},
|
|
75
|
+
"homepage": ""
|
|
68
76
|
}
|
package/dist/router.d.ts
DELETED
package/dist/router.js
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
// src/client/router.tsx
|
|
2
|
-
import React, { useState, useEffect, createContext, useContext } from "react";
|
|
3
|
-
import { routes } from "virtual:olova-routes";
|
|
4
|
-
import { jsx } from "react/jsx-runtime";
|
|
5
|
-
var RouterContext = createContext({ params: {}, path: "/" });
|
|
6
|
-
function useParams() {
|
|
7
|
-
return useContext(RouterContext).params;
|
|
8
|
-
}
|
|
9
|
-
function usePathname() {
|
|
10
|
-
const [pathname, setPathname] = useState(() => {
|
|
11
|
-
if (typeof window === "undefined") return "/";
|
|
12
|
-
return window.location.pathname;
|
|
13
|
-
});
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
if (typeof window === "undefined") return;
|
|
16
|
-
const handleNavigation = () => {
|
|
17
|
-
setPathname(window.location.pathname);
|
|
18
|
-
};
|
|
19
|
-
window.addEventListener("popstate", handleNavigation);
|
|
20
|
-
window.addEventListener("pushstate", handleNavigation);
|
|
21
|
-
return () => {
|
|
22
|
-
window.removeEventListener("popstate", handleNavigation);
|
|
23
|
-
window.removeEventListener("pushstate", handleNavigation);
|
|
24
|
-
};
|
|
25
|
-
}, []);
|
|
26
|
-
return pathname;
|
|
27
|
-
}
|
|
28
|
-
function useSearchParams() {
|
|
29
|
-
const [searchParams, setSearchParams] = useState(() => {
|
|
30
|
-
if (typeof window === "undefined") return new URLSearchParams();
|
|
31
|
-
return new URLSearchParams(window.location.search);
|
|
32
|
-
});
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
if (typeof window === "undefined") return;
|
|
35
|
-
const handleNavigation = () => {
|
|
36
|
-
setSearchParams(new URLSearchParams(window.location.search));
|
|
37
|
-
};
|
|
38
|
-
window.addEventListener("popstate", handleNavigation);
|
|
39
|
-
window.addEventListener("pushstate", handleNavigation);
|
|
40
|
-
return () => {
|
|
41
|
-
window.removeEventListener("popstate", handleNavigation);
|
|
42
|
-
window.removeEventListener("pushstate", handleNavigation);
|
|
43
|
-
};
|
|
44
|
-
}, []);
|
|
45
|
-
return {
|
|
46
|
-
get: (name) => searchParams.get(name),
|
|
47
|
-
getAll: (name) => searchParams.getAll(name),
|
|
48
|
-
has: (name) => searchParams.has(name),
|
|
49
|
-
keys: () => searchParams.keys(),
|
|
50
|
-
values: () => searchParams.values(),
|
|
51
|
-
entries: () => searchParams.entries(),
|
|
52
|
-
forEach: (callback) => searchParams.forEach(callback),
|
|
53
|
-
toString: () => searchParams.toString(),
|
|
54
|
-
get size() {
|
|
55
|
-
return Array.from(searchParams.keys()).length;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
var normalizePath = (path) => {
|
|
60
|
-
let p = path.split("?")[0].split("#")[0];
|
|
61
|
-
if (p.length > 1 && p.endsWith("/")) p = p.slice(0, -1);
|
|
62
|
-
return p || "/";
|
|
63
|
-
};
|
|
64
|
-
function matchRoute(path) {
|
|
65
|
-
const normalizedPath = normalizePath(path);
|
|
66
|
-
const routeKeys = Object.keys(routes);
|
|
67
|
-
for (const route of routeKeys) {
|
|
68
|
-
if (route === normalizedPath) {
|
|
69
|
-
return { loader: routes[route], params: {}, pattern: route };
|
|
70
|
-
}
|
|
71
|
-
const regexPath = route.replace(/:[^\/]+/g, "([^/]+)").replace(/\$[^\/]+/g, "([^/]+)");
|
|
72
|
-
const regex = new RegExp(`^${regexPath}$`);
|
|
73
|
-
const match = normalizedPath.match(regex);
|
|
74
|
-
if (match) {
|
|
75
|
-
const params = {};
|
|
76
|
-
const paramNames = (route.match(/[:$][^\/]+/g) || []).map((s) => s.slice(1));
|
|
77
|
-
paramNames.forEach((name, i) => {
|
|
78
|
-
params[name] = match[i + 1];
|
|
79
|
-
});
|
|
80
|
-
return { loader: routes[route], params, pattern: route };
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
function parseMarkdown(md) {
|
|
86
|
-
return md.replace(/^### (.*$)/gim, "<h3>$1</h3>").replace(/^## (.*$)/gim, "<h2>$1</h2>").replace(/^# (.*$)/gim, "<h1>$1</h1>").replace(/\*\*\*(.*?)\*\*\*/g, "<strong><em>$1</em></strong>").replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>").replace(/\*(.*?)\*/g, "<em>$1</em>").replace(/```([\s\S]*?)```/g, "<pre><code>$1</code></pre>").replace(/`(.*?)`/g, "<code>$1</code>").replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>').replace(/\n\n/g, "</p><p>").replace(/\n/g, "<br>").replace(/^(.*)$/, "<p>$1</p>");
|
|
87
|
-
}
|
|
88
|
-
function HtmlContent({ html }) {
|
|
89
|
-
return React.createElement("div", {
|
|
90
|
-
dangerouslySetInnerHTML: { __html: html },
|
|
91
|
-
className: "olova-html-content"
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
function MarkdownContent({ markdown }) {
|
|
95
|
-
const html = parseMarkdown(markdown);
|
|
96
|
-
return React.createElement("article", {
|
|
97
|
-
dangerouslySetInnerHTML: { __html: html },
|
|
98
|
-
className: "olova-markdown-content"
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
async function loadRoute(path) {
|
|
102
|
-
const match = matchRoute(path);
|
|
103
|
-
if (match) {
|
|
104
|
-
console.log(`[Router] Loading route: ${path} (pattern: ${match.pattern})`);
|
|
105
|
-
const module = await match.loader();
|
|
106
|
-
if (module.__isHtml) {
|
|
107
|
-
return {
|
|
108
|
-
module: {
|
|
109
|
-
default: () => HtmlContent({ html: module.__rawHtml })
|
|
110
|
-
},
|
|
111
|
-
params: match.params,
|
|
112
|
-
metadata: void 0
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
if (module.__isMd) {
|
|
116
|
-
return {
|
|
117
|
-
module: {
|
|
118
|
-
default: () => MarkdownContent({ markdown: module.default })
|
|
119
|
-
},
|
|
120
|
-
params: match.params,
|
|
121
|
-
metadata: void 0
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
return {
|
|
125
|
-
module,
|
|
126
|
-
params: match.params,
|
|
127
|
-
metadata: module.metadata
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
console.warn(`[Router] No match for: ${path}`);
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
function Router({ url, initialComponent, initialParams, onRouteChange, children }) {
|
|
134
|
-
const [path, setPath] = useState(() => normalizePath(url || (typeof window !== "undefined" ? window.location.pathname : "/")));
|
|
135
|
-
const [Component, setComponent] = useState(() => initialComponent || null);
|
|
136
|
-
const [params, setParams] = useState(() => initialParams || {});
|
|
137
|
-
const hasHydrated = React.useRef(false);
|
|
138
|
-
const isInitialRender = React.useRef(true);
|
|
139
|
-
const [isLoading, setIsLoading] = useState(!initialComponent);
|
|
140
|
-
useEffect(() => {
|
|
141
|
-
if (typeof window === "undefined") return;
|
|
142
|
-
const handleNavigation = () => {
|
|
143
|
-
const newPath = normalizePath(window.location.pathname);
|
|
144
|
-
console.log(`[Router] Navigation event: ${newPath}`);
|
|
145
|
-
setPath(newPath);
|
|
146
|
-
};
|
|
147
|
-
window.addEventListener("popstate", handleNavigation);
|
|
148
|
-
window.addEventListener("pushstate", handleNavigation);
|
|
149
|
-
return () => {
|
|
150
|
-
window.removeEventListener("popstate", handleNavigation);
|
|
151
|
-
window.removeEventListener("pushstate", handleNavigation);
|
|
152
|
-
};
|
|
153
|
-
}, []);
|
|
154
|
-
useEffect(() => {
|
|
155
|
-
if (!hasHydrated.current && initialComponent && path === normalizePath(url || "")) {
|
|
156
|
-
console.log(`[Router] Hydration skipped for: ${path}`);
|
|
157
|
-
hasHydrated.current = true;
|
|
158
|
-
isInitialRender.current = false;
|
|
159
|
-
setIsLoading(false);
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
let isCancelled = false;
|
|
163
|
-
const load = async () => {
|
|
164
|
-
console.log(`[Router] Loading route: ${path}`);
|
|
165
|
-
const result = await loadRoute(path);
|
|
166
|
-
if (!isCancelled) {
|
|
167
|
-
if (result) {
|
|
168
|
-
setComponent(() => result.module.default);
|
|
169
|
-
setParams(result.params);
|
|
170
|
-
if (onRouteChange) {
|
|
171
|
-
onRouteChange(result.metadata);
|
|
172
|
-
}
|
|
173
|
-
} else {
|
|
174
|
-
const fallbackResult = await loadRoute("/404");
|
|
175
|
-
if (fallbackResult) {
|
|
176
|
-
console.log("[Router] Serving custom 404 page");
|
|
177
|
-
setComponent(() => fallbackResult.module.default);
|
|
178
|
-
setParams(fallbackResult.params);
|
|
179
|
-
if (onRouteChange) {
|
|
180
|
-
onRouteChange(fallbackResult.metadata);
|
|
181
|
-
}
|
|
182
|
-
} else {
|
|
183
|
-
setComponent(() => () => /* @__PURE__ */ jsx("div", { children: "404 Not Found" }));
|
|
184
|
-
setParams({});
|
|
185
|
-
if (onRouteChange) {
|
|
186
|
-
onRouteChange(void 0);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
isInitialRender.current = false;
|
|
191
|
-
setIsLoading(false);
|
|
192
|
-
hasHydrated.current = true;
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
load();
|
|
196
|
-
return () => {
|
|
197
|
-
isCancelled = true;
|
|
198
|
-
};
|
|
199
|
-
}, [path, onRouteChange]);
|
|
200
|
-
if (isLoading && isInitialRender.current) {
|
|
201
|
-
return null;
|
|
202
|
-
}
|
|
203
|
-
if (!Component) {
|
|
204
|
-
if (initialComponent) {
|
|
205
|
-
const InitComp = initialComponent;
|
|
206
|
-
return /* @__PURE__ */ jsx(RouterContext.Provider, { value: { params, path }, children: /* @__PURE__ */ jsx(InitComp, { ...params }) });
|
|
207
|
-
}
|
|
208
|
-
return /* @__PURE__ */ jsx("div", { children: "Loading..." });
|
|
209
|
-
}
|
|
210
|
-
return /* @__PURE__ */ jsx(RouterContext.Provider, { value: { params, path }, children: /* @__PURE__ */ jsx(Component, { ...params }) });
|
|
211
|
-
}
|
|
212
|
-
function Link({ href, children, ...props }) {
|
|
213
|
-
const handleClick = (e) => {
|
|
214
|
-
if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
215
|
-
if (href.startsWith("http") || href.startsWith("//")) return;
|
|
216
|
-
e.preventDefault();
|
|
217
|
-
const currentUrl = window.location.pathname + window.location.search;
|
|
218
|
-
const targetUrl = href.startsWith("/") ? href : "/" + href;
|
|
219
|
-
if (currentUrl === targetUrl) return;
|
|
220
|
-
window.history.pushState({}, "", href);
|
|
221
|
-
window.dispatchEvent(new Event("pushstate"));
|
|
222
|
-
};
|
|
223
|
-
return /* @__PURE__ */ jsx("a", { href, onClick: handleClick, ...props, children });
|
|
224
|
-
}
|
|
225
|
-
export {
|
|
226
|
-
Link,
|
|
227
|
-
Router,
|
|
228
|
-
loadRoute,
|
|
229
|
-
matchRoute,
|
|
230
|
-
useParams,
|
|
231
|
-
usePathname,
|
|
232
|
-
useSearchParams
|
|
233
|
-
};
|
|
234
|
-
//# sourceMappingURL=router.js.map
|
package/dist/router.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/router.tsx"],"sourcesContent":["import React, { useState, useEffect, createContext, useContext, type ReactNode } from 'react';\n\n// @ts-ignore - Virtual module provided by Olova Vite plugin\nimport { routes } from 'virtual:olova-routes';\n\nconst RouterContext = createContext<{ params: Record<string, string>, path: string }>({ params: {}, path: '/' });\n\nexport function useParams() {\n return useContext(RouterContext).params;\n}\n\nexport function usePath() {\n return useContext(RouterContext).path;\n}\n\n/**\n * Returns the current pathname (without query string or hash)\n * Similar to Next.js usePathname hook\n */\nexport function usePathname(): string {\n const [pathname, setPathname] = useState(() => {\n if (typeof window === 'undefined') return '/';\n return window.location.pathname;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleNavigation = () => {\n setPathname(window.location.pathname);\n };\n\n window.addEventListener('popstate', handleNavigation);\n window.addEventListener('pushstate', handleNavigation);\n\n return () => {\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('pushstate', handleNavigation);\n };\n }, []);\n\n return pathname;\n}\n\n/**\n * A read-only interface for URLSearchParams\n * Similar to Next.js useSearchParams hook\n */\ninterface ReadonlyURLSearchParams {\n get(name: string): string | null;\n getAll(name: string): string[];\n has(name: string): boolean;\n keys(): IterableIterator<string>;\n values(): IterableIterator<string>;\n entries(): IterableIterator<[string, string]>;\n forEach(callback: (value: string, key: string, parent: URLSearchParams) => void): void;\n toString(): string;\n size: number;\n}\n\n/**\n * Returns the current URL search parameters\n * Similar to Next.js useSearchParams hook\n * \n * Example usage:\n * const searchParams = useSearchParams();\n * const query = searchParams.get('q'); // ?q=hello -> 'hello'\n * const tags = searchParams.getAll('tag'); // ?tag=a&tag=b -> ['a', 'b']\n */\nexport function useSearchParams(): ReadonlyURLSearchParams {\n const [searchParams, setSearchParams] = useState<URLSearchParams>(() => {\n if (typeof window === 'undefined') return new URLSearchParams();\n return new URLSearchParams(window.location.search);\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleNavigation = () => {\n setSearchParams(new URLSearchParams(window.location.search));\n };\n\n window.addEventListener('popstate', handleNavigation);\n window.addEventListener('pushstate', handleNavigation);\n\n return () => {\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('pushstate', handleNavigation);\n };\n }, []);\n\n // Return a readonly interface that wraps URLSearchParams\n return {\n get: (name: string) => searchParams.get(name),\n getAll: (name: string) => searchParams.getAll(name),\n has: (name: string) => searchParams.has(name),\n keys: () => searchParams.keys(),\n values: () => searchParams.values(),\n entries: () => searchParams.entries(),\n forEach: (callback) => searchParams.forEach(callback),\n toString: () => searchParams.toString(),\n get size() { return Array.from(searchParams.keys()).length; }\n };\n}\n\n// Helper to normalize paths\nconst normalizePath = (path: string) => {\n let p = path.split('?')[0].split('#')[0];\n if (p.length > 1 && p.endsWith('/')) p = p.slice(0, -1);\n return p || '/';\n};\n\n// Route matching with param extraction\nexport function matchRoute(path: string) {\n const normalizedPath = normalizePath(path);\n const routeKeys = Object.keys(routes);\n \n for (const route of routeKeys) {\n // Handle exact match first\n if (route === normalizedPath) {\n return { loader: routes[route], params: {}, pattern: route };\n }\n \n // Convert :param and $param to regex group\n const regexPath = route\n .replace(/:[^\\/]+/g, '([^/]+)')\n .replace(/\\$[^\\/]+/g, '([^/]+)');\n \n const regex = new RegExp(`^${regexPath}$`);\n const match = normalizedPath.match(regex);\n \n if (match) {\n const params: Record<string, string> = {};\n const paramNames = (route.match(/[:$][^\\/]+/g) || []).map(s => s.slice(1));\n paramNames.forEach((name, i) => {\n params[name] = match[i + 1];\n });\n return { loader: routes[route], params, pattern: route };\n }\n }\n return null;\n}\n\n// Metadata type - like Next.js\nexport interface Metadata {\n title?: string;\n description?: string;\n keywords?: string | string[];\n openGraph?: {\n title?: string;\n description?: string;\n url?: string;\n siteName?: string;\n images?: { url: string; width?: number; height?: number; alt?: string }[];\n type?: string;\n };\n twitter?: {\n card?: 'summary' | 'summary_large_image' | 'app' | 'player';\n site?: string;\n creator?: string;\n title?: string;\n description?: string;\n images?: string[];\n };\n robots?: string;\n canonical?: string;\n jsonLd?: object | object[];\n}\n\n// Simple markdown to HTML converter (basic support)\nfunction parseMarkdown(md: string): string {\n return md\n // Headers\n .replace(/^### (.*$)/gim, '<h3>$1</h3>')\n .replace(/^## (.*$)/gim, '<h2>$1</h2>')\n .replace(/^# (.*$)/gim, '<h1>$1</h1>')\n // Bold and italic\n .replace(/\\*\\*\\*(.*?)\\*\\*\\*/g, '<strong><em>$1</em></strong>')\n .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')\n .replace(/\\*(.*?)\\*/g, '<em>$1</em>')\n // Code blocks\n .replace(/```([\\s\\S]*?)```/g, '<pre><code>$1</code></pre>')\n .replace(/`(.*?)`/g, '<code>$1</code>')\n // Links\n .replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\">$1</a>')\n // Line breaks and paragraphs\n .replace(/\\n\\n/g, '</p><p>')\n .replace(/\\n/g, '<br>')\n // Wrap in paragraph\n .replace(/^(.*)$/, '<p>$1</p>');\n}\n\n// React component for rendering HTML content\nfunction HtmlContent({ html }: { html: string }) {\n return React.createElement('div', { \n dangerouslySetInnerHTML: { __html: html },\n className: 'olova-html-content'\n });\n}\n\n// React component for rendering Markdown content\nfunction MarkdownContent({ markdown }: { markdown: string }) {\n const html = parseMarkdown(markdown);\n return React.createElement('article', { \n dangerouslySetInnerHTML: { __html: html },\n className: 'olova-markdown-content'\n });\n}\n\nexport async function loadRoute(path: string) {\n const match = matchRoute(path);\n if (match) {\n console.log(`[Router] Loading route: ${path} (pattern: ${match.pattern})`);\n const module = await match.loader();\n \n // Handle HTML files\n if (module.__isHtml) {\n return { \n module: {\n default: () => HtmlContent({ html: module.__rawHtml }),\n },\n params: match.params,\n metadata: undefined\n };\n }\n \n // Handle Markdown files\n if (module.__isMd) {\n return { \n module: {\n default: () => MarkdownContent({ markdown: module.default }),\n },\n params: match.params,\n metadata: undefined\n };\n }\n \n return { \n module,\n params: match.params,\n metadata: module.metadata as Metadata | undefined\n };\n }\n console.warn(`[Router] No match for: ${path}`);\n return null;\n}\n\ninterface RouterProps {\n url?: string;\n initialComponent?: React.ComponentType;\n initialParams?: Record<string, string>;\n onRouteChange?: (metadata: Metadata | undefined) => void;\n children?: React.ReactNode;\n}\n\nexport function Router({ url, initialComponent, initialParams, onRouteChange, children }: RouterProps) {\n const [path, setPath] = useState(() => normalizePath(url || (typeof window !== 'undefined' ? window.location.pathname : '/')));\n // CRITICAL: Initialize with initialComponent to match SSG output - no Loading state during hydration\n const [Component, setComponent] = useState<React.ComponentType | null>(() => initialComponent || null);\n const [params, setParams] = useState<Record<string, string>>(() => initialParams || {});\n const hasHydrated = React.useRef(false);\n const isInitialRender = React.useRef(true);\n const [isLoading, setIsLoading] = useState(!initialComponent);\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleNavigation = () => {\n const newPath = normalizePath(window.location.pathname);\n console.log(`[Router] Navigation event: ${newPath}`);\n setPath(newPath);\n };\n\n window.addEventListener('popstate', handleNavigation);\n window.addEventListener('pushstate', handleNavigation);\n\n return () => {\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('pushstate', handleNavigation);\n };\n }, []);\n\n useEffect(() => {\n // Skip loading on mount if we already have the initial component for the current path\n if (!hasHydrated.current && initialComponent && path === normalizePath(url || '')) {\n console.log(`[Router] Hydration skipped for: ${path}`);\n hasHydrated.current = true;\n isInitialRender.current = false;\n setIsLoading(false);\n return;\n }\n\n let isCancelled = false;\n const load = async () => {\n console.log(`[Router] Loading route: ${path}`);\n const result = await loadRoute(path);\n if (!isCancelled) {\n if (result) {\n setComponent(() => result.module.default);\n setParams(result.params);\n // Call onRouteChange with new metadata for SEO updates\n if (onRouteChange) {\n onRouteChange(result.metadata);\n }\n } else {\n // Try to load custom 404 page\n const fallbackResult = await loadRoute('/404');\n if (fallbackResult) {\n console.log('[Router] Serving custom 404 page');\n setComponent(() => fallbackResult.module.default);\n setParams(fallbackResult.params);\n if (onRouteChange) {\n onRouteChange(fallbackResult.metadata);\n }\n } else {\n // Default 404 if no custom page exists\n setComponent(() => () => <div>404 Not Found</div>);\n setParams({});\n if (onRouteChange) {\n onRouteChange(undefined);\n }\n }\n }\n isInitialRender.current = false;\n setIsLoading(false);\n hasHydrated.current = true;\n }\n };\n\n load();\n return () => { isCancelled = true; };\n }, [path, onRouteChange]);\n\n // During initial hydration when we don't have a component yet,\n // render null to let React hydrate the existing SSG content\n // Once component loads, React will properly update the DOM\n if (isLoading && isInitialRender.current) {\n // Return null during initial hydration - React will keep existing DOM\n return null;\n }\n\n if (!Component) {\n // If we have initialComponent, use it (shouldn't happen but safety)\n if (initialComponent) {\n const InitComp = initialComponent;\n return (\n <RouterContext.Provider value={{ params, path }}>\n <InitComp {...params} />\n </RouterContext.Provider>\n );\n }\n // Show loading for pure client-side navigation\n return <div>Loading...</div>;\n }\n \n return (\n <RouterContext.Provider value={{ params, path }}>\n <Component {...params} />\n </RouterContext.Provider>\n );\n}\n\n// Link component - always uses SPA navigation (like Next.js)\n// Pre-rendered HTML is only for initial page load and SEO crawlers\nexport function Link({ href, children, ...props }: { href: string, children: ReactNode } & React.AnchorHTMLAttributes<HTMLAnchorElement>): React.ReactElement {\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n // Allow modifier keys for new tab, etc.\n if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;\n // Allow external links\n if (href.startsWith('http') || href.startsWith('//')) return;\n\n e.preventDefault();\n \n // Compare full URLs (including query strings) to allow search param changes\n const currentUrl = window.location.pathname + window.location.search;\n const targetUrl = href.startsWith('/') ? href : '/' + href;\n \n if (currentUrl === targetUrl) return;\n \n // SPA navigation - no page reload\n window.history.pushState({}, '', href);\n window.dispatchEvent(new Event('pushstate'));\n };\n\n return (\n <a href={href} onClick={handleClick} {...props}>\n {children}\n </a>\n );\n}"],"mappings":"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","names":[]}
|
package/dist/vite.d.ts
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
declare function olovaPlugins(): any[];
|
|
2
|
-
|
|
3
|
-
declare function minifyHtml(html: string): string;
|
|
4
|
-
declare function generateBuildId(): string;
|
|
5
|
-
declare function generateResourceHints(): string;
|
|
6
|
-
declare function generateCriticalCSS(): string;
|
|
7
|
-
declare function generateServiceWorkerScript(): string;
|
|
8
|
-
declare function generateServiceWorkerContent(buildId: string, assets: string[]): string;
|
|
9
|
-
declare function generatePerformanceMeta(): string;
|
|
10
|
-
|
|
11
|
-
interface OlovaHydrationData {
|
|
12
|
-
route: string;
|
|
13
|
-
metadata?: Record<string, unknown>;
|
|
14
|
-
params?: Record<string, string>;
|
|
15
|
-
chunks?: string[];
|
|
16
|
-
isStatic?: boolean;
|
|
17
|
-
}
|
|
18
|
-
declare function generateOlovaHydration(data: OlovaHydrationData, buildId: string): string;
|
|
19
|
-
/**
|
|
20
|
-
* Generate JSON-LD structured data script for SEO
|
|
21
|
-
* This is injected into <head> for search engine crawlers
|
|
22
|
-
*/
|
|
23
|
-
declare function generateJsonLd(data: OlovaHydrationData): string;
|
|
24
|
-
/**
|
|
25
|
-
* Parse flight data from the page (client-side utility)
|
|
26
|
-
* Use this to access hydration data in your components
|
|
27
|
-
*/
|
|
28
|
-
declare function parseFlightData(): Record<string, unknown> | null;
|
|
29
|
-
|
|
30
|
-
declare const colors: {
|
|
31
|
-
reset: string;
|
|
32
|
-
bold: string;
|
|
33
|
-
dim: string;
|
|
34
|
-
italic: string;
|
|
35
|
-
underline: string;
|
|
36
|
-
black: string;
|
|
37
|
-
red: string;
|
|
38
|
-
green: string;
|
|
39
|
-
yellow: string;
|
|
40
|
-
blue: string;
|
|
41
|
-
magenta: string;
|
|
42
|
-
cyan: string;
|
|
43
|
-
white: string;
|
|
44
|
-
gray: string;
|
|
45
|
-
bgBlack: string;
|
|
46
|
-
bgRed: string;
|
|
47
|
-
bgGreen: string;
|
|
48
|
-
bgYellow: string;
|
|
49
|
-
bgBlue: string;
|
|
50
|
-
bgMagenta: string;
|
|
51
|
-
bgCyan: string;
|
|
52
|
-
bgWhite: string;
|
|
53
|
-
};
|
|
54
|
-
declare const symbols: {
|
|
55
|
-
success: string;
|
|
56
|
-
error: string;
|
|
57
|
-
warning: string;
|
|
58
|
-
info: string;
|
|
59
|
-
arrow: string;
|
|
60
|
-
arrowRight: string;
|
|
61
|
-
bullet: string;
|
|
62
|
-
filled: string;
|
|
63
|
-
lambda: string;
|
|
64
|
-
triangle: string;
|
|
65
|
-
square: string;
|
|
66
|
-
diamond: string;
|
|
67
|
-
star: string;
|
|
68
|
-
check: string;
|
|
69
|
-
cross: string;
|
|
70
|
-
pointer: string;
|
|
71
|
-
};
|
|
72
|
-
declare function formatTime(ms: number): string;
|
|
73
|
-
declare function formatBytes(bytes: number): string;
|
|
74
|
-
declare const logger: {
|
|
75
|
-
banner: (name: string, version?: string) => void;
|
|
76
|
-
header: (text: string) => void;
|
|
77
|
-
info: (text: string) => void;
|
|
78
|
-
success: (text: string, time?: number) => void;
|
|
79
|
-
error: (text: string) => void;
|
|
80
|
-
warn: (text: string) => void;
|
|
81
|
-
step: (text: string, time?: number) => void;
|
|
82
|
-
route: (route: string, type: "static" | "ssr" | "isr", size?: number, time?: number) => void;
|
|
83
|
-
indent: (text: string, level?: number) => void;
|
|
84
|
-
newline: () => void;
|
|
85
|
-
dim: (text: string) => string;
|
|
86
|
-
bold: (text: string) => string;
|
|
87
|
-
cyan: (text: string) => string;
|
|
88
|
-
green: (text: string) => string;
|
|
89
|
-
yellow: (text: string) => string;
|
|
90
|
-
red: (text: string) => string;
|
|
91
|
-
magenta: (text: string) => string;
|
|
92
|
-
};
|
|
93
|
-
declare function createTimer(): {
|
|
94
|
-
elapsed: () => number;
|
|
95
|
-
format: () => string;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export { type OlovaHydrationData, colors, createTimer, formatBytes, formatTime, generateBuildId, generateCriticalCSS, generateJsonLd, generateOlovaHydration, generatePerformanceMeta, generateResourceHints, generateServiceWorkerContent, generateServiceWorkerScript, logger, minifyHtml, olovaPlugins, parseFlightData, symbols };
|