jinrai 1.1.2 → 1.1.4
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/front.config.json +2 -1
- package/index.ts +4 -1
- package/lib/bin/bin.js +123 -59
- package/lib/index.d.ts +3 -1
- package/lib/index.js +3 -1
- package/lib/src/bin/agent/agent.d.ts +2 -0
- package/lib/src/bin/agent/agent.js +4 -0
- package/lib/src/bin/playwright/pageCollector.d.ts +2 -0
- package/lib/src/bin/playwright/pageTestCollector.d.ts +6 -0
- package/lib/src/bin/playwright/templates.d.ts +6 -1
- package/lib/src/bin/routes/Parser.d.ts +25 -2
- package/lib/src/bin/routes/Parser.js +5 -0
- package/lib/src/bin/routes/getRoutes.d.ts +1 -0
- package/lib/src/front/server/useIsServer.d.ts +1 -0
- package/lib/src/front/server/useIsServer.js +7 -0
- package/lib/src/front/server-state/DataProxy.d.ts +2 -1
- package/lib/src/front/server-state/DataProxy.js +122 -60
- package/lib/src/front/server-state/SSR.d.ts +3 -0
- package/lib/src/front/server-state/SSR.js +18 -3
- package/lib/src/front/server-state/orig.d.ts +2 -0
- package/lib/src/front/server-state/{real.js → orig.js} +18 -3
- package/lib/src/front/server-state/serverStates.d.ts +3 -1
- package/lib/src/front/server-state/serverStates.js +24 -17
- package/lib/src/front/server-state/testState.d.ts +3 -0
- package/lib/src/front/server-state/testState.js +14 -0
- package/lib/src/front/server-state/useServerState.d.ts +1 -1
- package/lib/src/front/server-state/useServerState.js +5 -9
- package/lib/src/front/translate/TranslateConfig.d.ts +21 -0
- package/lib/src/front/translate/TranslateConfig.js +108 -0
- package/lib/src/front/url/JinraiContext.d.ts +1 -0
- package/lib/src/front/url/JinraiContext.js +1 -0
- package/lib/src/front/url/adapter/def.js +1 -1
- package/lib/src/front/url/adapter/rrd6.js +2 -2
- package/lib/src/front/url/adapter/rrd7.js +2 -2
- package/lib/src/front/url/params/useParamsIndex.js +2 -1
- package/lib/src/front/url/search/useSearch.js +4 -4
- package/lib/src/front/url/search/useSearchValue.d.ts +11 -5
- package/lib/src/front/url/search/useSearchValue.js +13 -8
- package/lib/src/front/wrapper/Custom.d.ts +3 -3
- package/lib/src/front/wrapper/Custom.js +18 -1
- package/lib/vite/plugin.js +26 -154
- package/package.json +9 -1
- package/rollup.config.mjs +2 -1
- package/src/bin/agent/agent.ts +2 -0
- package/src/bin/build/build.ts +23 -10
- package/src/bin/playwright/pageCollector.ts +8 -6
- package/src/bin/playwright/pageTestCollector.ts +15 -0
- package/src/bin/playwright/templates.ts +16 -5
- package/src/bin/routes/Parser.ts +100 -32
- package/src/bin/routes/getRoutes.ts +5 -1
- package/src/front/server/useIsServer.ts +5 -0
- package/src/front/server-state/DataProxy.ts +140 -61
- package/src/front/server-state/SSR.ts +22 -2
- package/src/front/server-state/{real.ts → orig.ts} +19 -2
- package/src/front/server-state/serverStates.ts +33 -18
- package/src/front/server-state/testState.ts +15 -0
- package/src/front/server-state/useServerState.ts +6 -11
- package/src/front/translate/TranslateConfig.tsx +153 -0
- package/src/front/url/JinraiContext.tsx +2 -0
- package/src/front/url/adapter/def.tsx +1 -1
- package/src/front/url/adapter/rrd6.tsx +2 -3
- package/src/front/url/adapter/rrd7.tsx +2 -2
- package/src/front/url/search/useSearch.ts +3 -4
- package/src/front/url/search/useSearchValue.ts +25 -13
- package/src/front/wrapper/Custom.tsx +28 -4
- package/tests/data-proxy/create-dataproxy.test.ts +116 -0
- package/tests/{custom.test.ts → parse/custom.test.ts} +2 -2
- package/tests/{parse.test.ts → parse/parse.test.ts} +7 -7
- package/tsconfig.types.json +1 -0
- package/vite/plugin.ts +40 -22
- package/lib/src/front/server-state/real.d.ts +0 -1
- /package/tests/{content → parse/content}/1.html +0 -0
- /package/tests/{content → parse/content}/1_result.json +0 -0
- /package/tests/{content → parse/content}/2.html +0 -0
- /package/tests/{content → parse/content}/2_result.json +0 -0
- /package/tests/{content → parse/content}/3.html +0 -0
- /package/tests/{content → parse/content}/3_result.json +0 -0
- /package/tests/{content → parse/content}/4.html +0 -0
- /package/tests/{content → parse/content}/4_result.json +0 -0
- /package/tests/{content → parse/content}/custom.html +0 -0
- /package/tests/{content → parse/content}/custom.json +0 -0
- /package/tests/{content → parse/content}/index.html +0 -0
- /package/tests/{content → parse/content}/index.json +0 -0
- /package/tests/{content → parse/content}/index_with_templates.json +0 -0
- /package/tests/{content → parse/content}/templates.json +0 -0
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import { UseQueryStateReturn } from "nuqs";
|
|
2
|
+
export interface JinraiValue {
|
|
3
|
+
key: string;
|
|
4
|
+
type: "searchArray" | "searchString" | "proxy" | "searchFull" | "paramsIndex";
|
|
5
|
+
separator: string;
|
|
6
|
+
def: any;
|
|
7
|
+
}
|
|
2
8
|
declare global {
|
|
3
9
|
interface String {
|
|
4
|
-
|
|
10
|
+
$JV?: JinraiValue;
|
|
5
11
|
toJSON: () => string;
|
|
6
|
-
bindSource: (source:
|
|
12
|
+
bindSource: (source: JinraiValue) => string;
|
|
7
13
|
}
|
|
8
14
|
interface Array<T> {
|
|
9
|
-
|
|
15
|
+
$JV?: JinraiValue;
|
|
10
16
|
toJSON(): any;
|
|
11
|
-
bindSource(source:
|
|
17
|
+
bindSource(source: JinraiValue): T[];
|
|
12
18
|
}
|
|
13
19
|
}
|
|
14
20
|
export declare const useSearchValue: (key: string, defaultValue: string) => UseQueryStateReturn<string, string>;
|
|
15
21
|
export declare const useSearchArray: (key: string, defaultValue?: string[], separator?: string) => UseQueryStateReturn<string[], string[]>;
|
|
16
|
-
export declare const getJinraiValue: (key: string, type:
|
|
22
|
+
export declare const getJinraiValue: (key: string, type: JinraiValue["type"], separator: string, def: any) => JinraiValue;
|
|
@@ -5,19 +5,19 @@ import { ssr } from '../../server-state/SSR.js';
|
|
|
5
5
|
function toJSON() {
|
|
6
6
|
if (ssr.exportParams) {
|
|
7
7
|
// @ts-ignore
|
|
8
|
-
const
|
|
8
|
+
const $JV = this.$JV;
|
|
9
9
|
// @ts-ignore
|
|
10
|
-
return
|
|
10
|
+
return $JV ? { $JV } : this;
|
|
11
11
|
}
|
|
12
12
|
// @ts-ignore
|
|
13
13
|
return this;
|
|
14
14
|
}
|
|
15
15
|
{
|
|
16
|
-
String.prototype
|
|
16
|
+
String.prototype.$JV = undefined;
|
|
17
17
|
String.prototype.toJSON = toJSON;
|
|
18
18
|
String.prototype.bindSource = function (source) {
|
|
19
19
|
const result = new String(this);
|
|
20
|
-
result
|
|
20
|
+
result.$JV = source;
|
|
21
21
|
return result;
|
|
22
22
|
};
|
|
23
23
|
if (!Array.prototype.toJSON) {
|
|
@@ -25,7 +25,7 @@ function toJSON() {
|
|
|
25
25
|
}
|
|
26
26
|
if (!Array.prototype.bindSource) {
|
|
27
27
|
Array.prototype.bindSource = function (source) {
|
|
28
|
-
this
|
|
28
|
+
this.$JV = source;
|
|
29
29
|
return this;
|
|
30
30
|
};
|
|
31
31
|
}
|
|
@@ -33,7 +33,7 @@ function toJSON() {
|
|
|
33
33
|
const useSearchValue = (key, defaultValue) => {
|
|
34
34
|
const [value, setValue] = useQueryState(key, { defaultValue });
|
|
35
35
|
const stableValue = useMemo(() => {
|
|
36
|
-
return value.bindSource(getJinraiValue(key, "searchString", "", defaultValue)) ;
|
|
36
|
+
return ssr.current ? value.bindSource(getJinraiValue(key, "searchString", "", defaultValue)) : value;
|
|
37
37
|
}, [key, value]);
|
|
38
38
|
return [stableValue, setValue];
|
|
39
39
|
};
|
|
@@ -41,12 +41,17 @@ const useSearchArray = (key, defaultValue = [], separator = ",") => {
|
|
|
41
41
|
const stableDefault = useMemo(() => defaultValue, []);
|
|
42
42
|
const [value, setValue] = useQueryState(key, parseAsArrayOf(parseAsString, separator).withDefault(stableDefault));
|
|
43
43
|
const stableValue = useMemo(() => {
|
|
44
|
-
return value.bindSource(getJinraiValue(key, "searchArray", separator, defaultValue)) ;
|
|
44
|
+
return ssr.current ? value.bindSource(getJinraiValue(key, "searchArray", separator, defaultValue)) : value;
|
|
45
45
|
}, [key, value]);
|
|
46
46
|
return [stableValue, setValue];
|
|
47
47
|
};
|
|
48
48
|
const getJinraiValue = (key, type, separator, def) => {
|
|
49
|
-
return
|
|
49
|
+
return {
|
|
50
|
+
key,
|
|
51
|
+
type,
|
|
52
|
+
separator,
|
|
53
|
+
def,
|
|
54
|
+
};
|
|
50
55
|
};
|
|
51
56
|
|
|
52
57
|
export { getJinraiValue, useSearchArray, useSearchValue };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
2
|
interface CustomProps {
|
|
3
3
|
name: string;
|
|
4
|
-
props: object;
|
|
4
|
+
props: () => object;
|
|
5
5
|
children: ReactNode;
|
|
6
6
|
}
|
|
7
|
-
export declare const Custom: ({ name, props, children }: CustomProps) =>
|
|
7
|
+
export declare const Custom: ({ name, props, children }: CustomProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
8
|
export {};
|
|
@@ -1,5 +1,22 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { Fragment } from 'react';
|
|
3
|
+
import { ssr } from '../server-state/SSR.js';
|
|
4
|
+
import { SPLIT } from '../../bin/routes/Parser.js';
|
|
5
|
+
import { orig } from '../server-state/orig.js';
|
|
6
|
+
|
|
1
7
|
const Custom = ({ name, props, children }) => {
|
|
2
|
-
|
|
8
|
+
if (!ssr.current)
|
|
9
|
+
return jsx(Fragment, { children: children });
|
|
10
|
+
if (typeof props != "function") {
|
|
11
|
+
throw new Error(`Custom props is not function (${name})`);
|
|
12
|
+
}
|
|
13
|
+
const exampleProps = JSON.stringify({ name, props: orig(props()) });
|
|
14
|
+
ssr.exportToJV = true;
|
|
15
|
+
const customProps = JSON.stringify({ name, props: props() });
|
|
16
|
+
ssr.exportToJV = false;
|
|
17
|
+
return (
|
|
18
|
+
//@ts-ignore
|
|
19
|
+
jsxs("custom", { children: [customProps, SPLIT, exampleProps, SPLIT, children] }));
|
|
3
20
|
};
|
|
4
21
|
|
|
5
22
|
export { Custom };
|
package/lib/vite/plugin.js
CHANGED
|
@@ -1,162 +1,28 @@
|
|
|
1
1
|
import { createServer } from 'vite';
|
|
2
2
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
3
3
|
import { chromium } from 'playwright';
|
|
4
|
-
import { createHash } from 'node:crypto';
|
|
5
|
-
import { writeFile } from 'fs/promises';
|
|
6
4
|
|
|
7
|
-
const
|
|
5
|
+
const ViteAgent = "____JINRAI_VITE_AGENT____";
|
|
6
|
+
|
|
7
|
+
const pageTestCollector = async (page) => {
|
|
8
8
|
const state = await page.evaluate(() => {
|
|
9
|
-
const state = Object.fromEntries(window.$
|
|
10
|
-
console.log("BROWSER", state);
|
|
9
|
+
const state = Object.fromEntries(window.$testStates);
|
|
11
10
|
return state;
|
|
12
11
|
});
|
|
13
|
-
console.log("CLIENT", state);
|
|
14
12
|
const root = await page.locator("#root").innerHTML();
|
|
15
13
|
return { root, state };
|
|
16
14
|
};
|
|
17
15
|
|
|
18
|
-
const normalizeHtmlWhitespace = (html) => {
|
|
19
|
-
return html
|
|
20
|
-
.replace(/\r?\n|\r/g, " ")
|
|
21
|
-
.replace(/\s+/g, " ")
|
|
22
|
-
.replace(/>\s+</g, "><")
|
|
23
|
-
.trim();
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
class Parser {
|
|
27
|
-
options;
|
|
28
|
-
openVar = "{{";
|
|
29
|
-
createVar = "}}";
|
|
30
|
-
createArray = "</loopwrapper";
|
|
31
|
-
createCustom = "</custom";
|
|
32
|
-
deepUp = "<loopwrapper";
|
|
33
|
-
deepUp2 = "<custom";
|
|
34
|
-
templates = {};
|
|
35
|
-
constructor(options) {
|
|
36
|
-
this.options = options;
|
|
37
|
-
}
|
|
38
|
-
parse(content) {
|
|
39
|
-
const tree = [];
|
|
40
|
-
this.handle(this.options?.normalize ? normalizeHtmlWhitespace(content) : content, tree);
|
|
41
|
-
return tree;
|
|
42
|
-
}
|
|
43
|
-
handle(content, tree) {
|
|
44
|
-
let match;
|
|
45
|
-
let deep = 0;
|
|
46
|
-
let lastIndex = 0;
|
|
47
|
-
const tagPattern = new RegExp(`(<loopwrapper(\\s+[^>]*)?>|</loopwrapper>|\{\{|\}\}|<custom(\\s+[^>]*)?>|</custom>)`, "gi");
|
|
48
|
-
while ((match = tagPattern.exec(content)) !== null) {
|
|
49
|
-
const currentTag = match[0];
|
|
50
|
-
const value = content.substring(lastIndex, match.index);
|
|
51
|
-
if (currentTag.startsWith(this.createArray)) {
|
|
52
|
-
deep--;
|
|
53
|
-
if (deep > 0)
|
|
54
|
-
continue;
|
|
55
|
-
this.createElement(tree, value);
|
|
56
|
-
}
|
|
57
|
-
else if (currentTag.startsWith(this.deepUp)) {
|
|
58
|
-
deep++;
|
|
59
|
-
if (deep > 1)
|
|
60
|
-
continue;
|
|
61
|
-
this.createElement(tree, value);
|
|
62
|
-
}
|
|
63
|
-
else if (currentTag.startsWith(this.createCustom)) {
|
|
64
|
-
deep--;
|
|
65
|
-
if (deep != 0)
|
|
66
|
-
continue;
|
|
67
|
-
this.createCustomElement(tree, value);
|
|
68
|
-
}
|
|
69
|
-
else if (currentTag.startsWith(this.deepUp2)) {
|
|
70
|
-
deep++;
|
|
71
|
-
if (deep > 1)
|
|
72
|
-
continue;
|
|
73
|
-
this.createElement(tree, value);
|
|
74
|
-
}
|
|
75
|
-
else if (currentTag == this.createVar) {
|
|
76
|
-
if (deep != 0)
|
|
77
|
-
continue;
|
|
78
|
-
this.createElement(tree, value, true);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
if (deep != 0)
|
|
82
|
-
continue;
|
|
83
|
-
this.createElement(tree, value);
|
|
84
|
-
}
|
|
85
|
-
lastIndex = match.index + currentTag.length;
|
|
86
|
-
}
|
|
87
|
-
if (lastIndex < content.length) {
|
|
88
|
-
const value = content.substring(lastIndex);
|
|
89
|
-
this.createElement(tree, value);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
createCustomElement(parent, value) {
|
|
93
|
-
const [name, ...props] = value.trimStart().split("|");
|
|
94
|
-
value = props.join("|");
|
|
95
|
-
parent.push({
|
|
96
|
-
type: "custom",
|
|
97
|
-
name,
|
|
98
|
-
props: value,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
createElement(parent, value, isVarible) {
|
|
102
|
-
if (isVarible)
|
|
103
|
-
return parent.push({
|
|
104
|
-
type: "value",
|
|
105
|
-
key: value,
|
|
106
|
-
});
|
|
107
|
-
if (value.trimStart().startsWith("ArrayDataKey=")) {
|
|
108
|
-
const [key, ...val] = value.trimStart().substring(13).split("|");
|
|
109
|
-
value = val.join("|");
|
|
110
|
-
const children = [];
|
|
111
|
-
this.handle(value, children);
|
|
112
|
-
return parent.push({
|
|
113
|
-
type: "array",
|
|
114
|
-
data: children,
|
|
115
|
-
key,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
if (value)
|
|
119
|
-
parent.push({
|
|
120
|
-
type: "html",
|
|
121
|
-
content: this.options?.templates ? this.createTemplate(value) : value,
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
createTemplate(html) {
|
|
125
|
-
if (!(html in this.templates)) {
|
|
126
|
-
this.templates[html] = createHash("md5").update(Object.keys(this.templates).length.toString()).digest("hex");
|
|
127
|
-
}
|
|
128
|
-
return this.templates[html];
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const getRoutesAndTemplates = (pages, normalize = true, templates = true) => {
|
|
133
|
-
const routes = [];
|
|
134
|
-
const parser = new Parser({ normalize, templates });
|
|
135
|
-
for (const [id, template] of pages.entries()) {
|
|
136
|
-
const content = parser.parse(template.root);
|
|
137
|
-
const mask = template.mask.replaceAll("/", "\\/").replace(/{(.*?)}/, ".+?");
|
|
138
|
-
routes.push({
|
|
139
|
-
id,
|
|
140
|
-
content,
|
|
141
|
-
mask,
|
|
142
|
-
state: template.state,
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
return {
|
|
146
|
-
routes,
|
|
147
|
-
templates: parser.templates,
|
|
148
|
-
};
|
|
149
|
-
};
|
|
150
|
-
|
|
151
16
|
const urlStorage = new AsyncLocalStorage();
|
|
17
|
+
const cashe = new Map();
|
|
152
18
|
function hydration() {
|
|
153
19
|
if (process.env.CHILD_JINRAI_DEV_SERVER) {
|
|
154
20
|
return { name: "vite-jinrai-dummy" };
|
|
155
21
|
}
|
|
156
22
|
process.env.CHILD_JINRAI_DEV_SERVER = "true";
|
|
157
|
-
console.log("create mirror");
|
|
158
23
|
let mirrorServer = undefined;
|
|
159
24
|
let context = undefined;
|
|
25
|
+
let page = undefined;
|
|
160
26
|
let debugUrl = undefined;
|
|
161
27
|
createServer({
|
|
162
28
|
server: {
|
|
@@ -166,12 +32,12 @@ function hydration() {
|
|
|
166
32
|
mirrorServer = server;
|
|
167
33
|
await mirrorServer.listen();
|
|
168
34
|
debugUrl = mirrorServer.resolvedUrls?.local[0].slice(0, -1);
|
|
169
|
-
chromium.launch({ headless: true, devtools: false }).then(async (browser) => {
|
|
170
|
-
console.log("create context");
|
|
35
|
+
chromium.launch({ headless: true, devtools: false, channel: "chrome" }).then(async (browser) => {
|
|
171
36
|
context = await browser.newContext({
|
|
172
|
-
userAgent:
|
|
37
|
+
userAgent: ViteAgent,
|
|
173
38
|
locale: "ru-RU",
|
|
174
39
|
});
|
|
40
|
+
page = await context.newPage();
|
|
175
41
|
});
|
|
176
42
|
});
|
|
177
43
|
return {
|
|
@@ -188,25 +54,31 @@ function hydration() {
|
|
|
188
54
|
},
|
|
189
55
|
async transformIndexHtml(html) {
|
|
190
56
|
const currentUrl = urlStorage.getStore();
|
|
191
|
-
if (currentUrl &&
|
|
192
|
-
const
|
|
57
|
+
if (currentUrl && page) {
|
|
58
|
+
const data = cashe.get(currentUrl);
|
|
59
|
+
if (data) {
|
|
60
|
+
return print(html, data.root, data.state);
|
|
61
|
+
}
|
|
193
62
|
await page.goto(debugUrl + currentUrl);
|
|
194
63
|
await page.waitForLoadState("networkidle");
|
|
195
|
-
|
|
196
|
-
const {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const result = html.replace("<!--app-html-->", root);
|
|
200
|
-
page.close();
|
|
201
|
-
return result;
|
|
64
|
+
await page.waitForTimeout(2000);
|
|
65
|
+
const { root, state } = await pageTestCollector(page);
|
|
66
|
+
cashe.set(currentUrl, { root, state });
|
|
67
|
+
return print(html, root, state);
|
|
202
68
|
}
|
|
203
69
|
return html;
|
|
204
70
|
},
|
|
205
71
|
closeWatcher() {
|
|
206
|
-
|
|
207
|
-
|
|
72
|
+
page?.close();
|
|
73
|
+
mirrorServer?.close();
|
|
74
|
+
context?.close();
|
|
208
75
|
},
|
|
209
76
|
};
|
|
210
77
|
}
|
|
78
|
+
const print = (html, root, state) => {
|
|
79
|
+
html = html.replace("<!--app-html-->", root);
|
|
80
|
+
html = html.replace("<!--app-head-->", `<script>window.__appc__ = ${JSON.stringify({ state })}</script>`);
|
|
81
|
+
return html;
|
|
82
|
+
};
|
|
211
83
|
|
|
212
84
|
export { hydration };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jinrai",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "A powerful library that analyzes your modern web application and automatically generates a perfectly rendered, static snapshot of its pages. Experience unparalleled loading speed and SEO clarity without the complexity of traditional SSR setups. Simply point Jinrai at your SPA and witness divine speed.",
|
|
5
5
|
"main": "lib/index.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -66,6 +66,14 @@
|
|
|
66
66
|
"./config": {
|
|
67
67
|
"types": "./lib/config/config.d.ts",
|
|
68
68
|
"import": "./lib/config/config.js"
|
|
69
|
+
},
|
|
70
|
+
"./vite": {
|
|
71
|
+
"types": "./lib/vite/plugin.d.ts",
|
|
72
|
+
"import": "./lib/vite/plugin.js"
|
|
73
|
+
},
|
|
74
|
+
"./translate": {
|
|
75
|
+
"types": "./lib/src/front/translate/TranslateConfig.d.ts",
|
|
76
|
+
"import": "./lib/src/front/translate/TranslateConfig.js"
|
|
69
77
|
}
|
|
70
78
|
}
|
|
71
79
|
}
|
package/rollup.config.mjs
CHANGED
|
@@ -68,7 +68,8 @@ export default defineConfig([
|
|
|
68
68
|
index: path.resolve(__dirname, "index.ts"),
|
|
69
69
|
"src/front/url/adapter/rrd6": path.resolve(__dirname, "src/front/url/adapter/rrd6.tsx"),
|
|
70
70
|
"src/front/url/adapter/rrd7": path.resolve(__dirname, "src/front/url/adapter/rrd7.tsx"),
|
|
71
|
-
"src/front/url/adapter/def": path.resolve(__dirname, "src/front/url/adapter/def.tsx")
|
|
71
|
+
"src/front/url/adapter/def": path.resolve(__dirname, "src/front/url/adapter/def.tsx"),
|
|
72
|
+
"src/front/translate/TranslateConfig": path.resolve(__dirname, "src/front/translate/TranslateConfig.tsx"),
|
|
72
73
|
},
|
|
73
74
|
output: {
|
|
74
75
|
dir: path.resolve(__dirname, "lib"),
|
package/src/bin/build/build.ts
CHANGED
|
@@ -28,21 +28,23 @@ export const runBuild = async (options: buildArgs) => {
|
|
|
28
28
|
|
|
29
29
|
const [serverUrl, close] = await vitePreview()
|
|
30
30
|
|
|
31
|
-
const pages = await getRawPageData(serverUrl, config.pages, config.test, options.debug)
|
|
31
|
+
const { pages, lang } = await getRawPageData(serverUrl, config.pages, config.test, options.debug)
|
|
32
|
+
|
|
33
|
+
console.log({ lang })
|
|
32
34
|
|
|
33
35
|
close()
|
|
34
36
|
|
|
35
37
|
const outputcashe = path.join(config.dist ?? "dist", ".cached")
|
|
36
38
|
|
|
37
39
|
task.do("Format")
|
|
38
|
-
const { routes, templates } = getRoutesAndTemplates(pages)
|
|
40
|
+
const { routes, templates, customComponents } = getRoutesAndTemplates(pages)
|
|
39
41
|
|
|
40
42
|
task.next(`Export: (${templates.length})`)
|
|
41
43
|
await mkdir(outputcashe, { recursive: true })
|
|
42
44
|
|
|
43
45
|
console.log("dev")
|
|
44
46
|
|
|
45
|
-
const exportConfig = { routes, proxy: config.proxy, meta: config.meta }
|
|
47
|
+
const exportConfig = { routes, proxy: config.proxy, meta: config.meta, lang }
|
|
46
48
|
|
|
47
49
|
await writeFile(path.join(outputcashe, "config.json"), JSON.stringify(exportConfig, null, 2))
|
|
48
50
|
// await writeFile(
|
|
@@ -54,16 +56,27 @@ export const runBuild = async (options: buildArgs) => {
|
|
|
54
56
|
await writeFile(path.join(outputcashe, `${name}.html`), template)
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
if (
|
|
58
|
-
task.next(`
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
continue
|
|
62
|
-
}
|
|
59
|
+
if (customComponents.length) {
|
|
60
|
+
task.next(`Custom`)
|
|
61
|
+
|
|
62
|
+
await mkdir(path.join(outputcashe, "custom"), { recursive: true })
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
for await (const component of customComponents) {
|
|
65
|
+
await writeFile(path.join(outputcashe, "custom", `${component.name}.html`), component.html)
|
|
66
|
+
await writeFile(path.join(outputcashe, "custom", `${component.name}.json`), component.props)
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
69
|
|
|
70
|
+
// if (config.test) {
|
|
71
|
+
// task.next(`Tests`)
|
|
72
|
+
// for await (const page of pages) {
|
|
73
|
+
// if (!page.test) {
|
|
74
|
+
// continue
|
|
75
|
+
// }
|
|
76
|
+
|
|
77
|
+
// await writeFile(path.join(outputcashe, `test_${page.id}.html`), normalizeHtmlWhitespace(page.test))
|
|
78
|
+
// }
|
|
79
|
+
// }
|
|
80
|
+
|
|
68
81
|
task.success()
|
|
69
82
|
}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { Page } from "playwright"
|
|
2
2
|
import { ServerStateMap } from "../../front/server-state/useServerState"
|
|
3
|
+
import { DefaultLangType } from "../../front/translate/TranslateConfig"
|
|
3
4
|
|
|
4
|
-
export const pageCollector = async (
|
|
5
|
-
|
|
5
|
+
export const pageCollector = async (
|
|
6
|
+
page: Page,
|
|
7
|
+
): Promise<{ state: ServerStateMap; root: string; lang: DefaultLangType }> => {
|
|
8
|
+
const [state, lang] = await page.evaluate(() => {
|
|
6
9
|
const state = Object.fromEntries((window as any).$exportServerStates)
|
|
7
|
-
|
|
10
|
+
const lang = (window as any).$langDefaultConfig
|
|
8
11
|
|
|
9
|
-
return state
|
|
12
|
+
return [state, lang]
|
|
10
13
|
})
|
|
11
14
|
|
|
12
|
-
console.log("CLIENT", state)
|
|
13
15
|
const root = await page.locator("#root").innerHTML()
|
|
14
16
|
|
|
15
|
-
return { root, state }
|
|
17
|
+
return { root, state, lang }
|
|
16
18
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Page } from "playwright";
|
|
2
|
+
import { ServerStateMap } from "../../front/server-state/useServerState";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export const pageTestCollector = async (page: Page): Promise<{ state: ServerStateMap; root: string }> => {
|
|
6
|
+
const state = await page.evaluate(() => {
|
|
7
|
+
const state = Object.fromEntries((window as any).$testStates)
|
|
8
|
+
|
|
9
|
+
return state
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
const root = await page.locator("#root").innerHTML()
|
|
13
|
+
|
|
14
|
+
return { root, state }
|
|
15
|
+
}
|
|
@@ -3,6 +3,8 @@ import Task from "../ui/task"
|
|
|
3
3
|
import { spinners } from "ora"
|
|
4
4
|
import { pageCollector } from "./pageCollector"
|
|
5
5
|
import { ServerValue } from "../../front/server-state/serverStates"
|
|
6
|
+
import { JinraiAgent } from "../agent/agent"
|
|
7
|
+
import { DefaultLangType } from "../../front/translate/TranslateConfig"
|
|
6
8
|
|
|
7
9
|
export interface PageData {
|
|
8
10
|
id: number
|
|
@@ -12,22 +14,28 @@ export interface PageData {
|
|
|
12
14
|
test?: string
|
|
13
15
|
}
|
|
14
16
|
|
|
17
|
+
export interface Pages {
|
|
18
|
+
pages: PageData[]
|
|
19
|
+
lang?: DefaultLangType
|
|
20
|
+
}
|
|
21
|
+
|
|
15
22
|
export const getRawPageData = async (
|
|
16
23
|
url: string,
|
|
17
24
|
pages: string[],
|
|
18
25
|
test: boolean = false,
|
|
19
26
|
debug: boolean = false,
|
|
20
|
-
): Promise<
|
|
27
|
+
): Promise<Pages> => {
|
|
21
28
|
const task = new Task()
|
|
22
29
|
task.next("Router analysis", "yellow", spinners.dotsCircle)
|
|
23
30
|
|
|
24
31
|
const result: PageData[] = []
|
|
32
|
+
let defaultLang: DefaultLangType | undefined = undefined
|
|
25
33
|
|
|
26
34
|
const browser = await chromium.launch({ headless: !debug, devtools: true, channel: "chrome" })
|
|
27
35
|
// const test_browser = await chromium.launch({ headless: true, channel: "chrome" })
|
|
28
36
|
|
|
29
37
|
const context = await browser.newContext({
|
|
30
|
-
userAgent:
|
|
38
|
+
userAgent: JinraiAgent,
|
|
31
39
|
locale: "ru-RU",
|
|
32
40
|
})
|
|
33
41
|
|
|
@@ -35,7 +43,7 @@ export const getRawPageData = async (
|
|
|
35
43
|
task.next(mask, "yellow", spinners.dotsCircle, 1)
|
|
36
44
|
|
|
37
45
|
const page = await context.newPage()
|
|
38
|
-
const path = mask.replaceAll("{", "").replaceAll("}", "")
|
|
46
|
+
const path = mask.replaceAll("{", "").replaceAll("}", "").replace("\/*", "")
|
|
39
47
|
|
|
40
48
|
await page.goto(url + path)
|
|
41
49
|
|
|
@@ -43,7 +51,10 @@ export const getRawPageData = async (
|
|
|
43
51
|
|
|
44
52
|
await page.waitForTimeout(1000)
|
|
45
53
|
|
|
46
|
-
const { state, root } = await pageCollector(page)
|
|
54
|
+
const { state, root, lang } = await pageCollector(page)
|
|
55
|
+
if (defaultLang == undefined) {
|
|
56
|
+
defaultLang = lang
|
|
57
|
+
}
|
|
47
58
|
|
|
48
59
|
// if (debug) console.log({ input })
|
|
49
60
|
|
|
@@ -76,5 +87,5 @@ export const getRawPageData = async (
|
|
|
76
87
|
// await test_browser.close()
|
|
77
88
|
|
|
78
89
|
task.success()
|
|
79
|
-
return result
|
|
90
|
+
return { pages: result, lang: defaultLang }
|
|
80
91
|
}
|