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.
Files changed (85) hide show
  1. package/front.config.json +2 -1
  2. package/index.ts +4 -1
  3. package/lib/bin/bin.js +123 -59
  4. package/lib/index.d.ts +3 -1
  5. package/lib/index.js +3 -1
  6. package/lib/src/bin/agent/agent.d.ts +2 -0
  7. package/lib/src/bin/agent/agent.js +4 -0
  8. package/lib/src/bin/playwright/pageCollector.d.ts +2 -0
  9. package/lib/src/bin/playwright/pageTestCollector.d.ts +6 -0
  10. package/lib/src/bin/playwright/templates.d.ts +6 -1
  11. package/lib/src/bin/routes/Parser.d.ts +25 -2
  12. package/lib/src/bin/routes/Parser.js +5 -0
  13. package/lib/src/bin/routes/getRoutes.d.ts +1 -0
  14. package/lib/src/front/server/useIsServer.d.ts +1 -0
  15. package/lib/src/front/server/useIsServer.js +7 -0
  16. package/lib/src/front/server-state/DataProxy.d.ts +2 -1
  17. package/lib/src/front/server-state/DataProxy.js +122 -60
  18. package/lib/src/front/server-state/SSR.d.ts +3 -0
  19. package/lib/src/front/server-state/SSR.js +18 -3
  20. package/lib/src/front/server-state/orig.d.ts +2 -0
  21. package/lib/src/front/server-state/{real.js → orig.js} +18 -3
  22. package/lib/src/front/server-state/serverStates.d.ts +3 -1
  23. package/lib/src/front/server-state/serverStates.js +24 -17
  24. package/lib/src/front/server-state/testState.d.ts +3 -0
  25. package/lib/src/front/server-state/testState.js +14 -0
  26. package/lib/src/front/server-state/useServerState.d.ts +1 -1
  27. package/lib/src/front/server-state/useServerState.js +5 -9
  28. package/lib/src/front/translate/TranslateConfig.d.ts +21 -0
  29. package/lib/src/front/translate/TranslateConfig.js +108 -0
  30. package/lib/src/front/url/JinraiContext.d.ts +1 -0
  31. package/lib/src/front/url/JinraiContext.js +1 -0
  32. package/lib/src/front/url/adapter/def.js +1 -1
  33. package/lib/src/front/url/adapter/rrd6.js +2 -2
  34. package/lib/src/front/url/adapter/rrd7.js +2 -2
  35. package/lib/src/front/url/params/useParamsIndex.js +2 -1
  36. package/lib/src/front/url/search/useSearch.js +4 -4
  37. package/lib/src/front/url/search/useSearchValue.d.ts +11 -5
  38. package/lib/src/front/url/search/useSearchValue.js +13 -8
  39. package/lib/src/front/wrapper/Custom.d.ts +3 -3
  40. package/lib/src/front/wrapper/Custom.js +18 -1
  41. package/lib/vite/plugin.js +26 -154
  42. package/package.json +9 -1
  43. package/rollup.config.mjs +2 -1
  44. package/src/bin/agent/agent.ts +2 -0
  45. package/src/bin/build/build.ts +23 -10
  46. package/src/bin/playwright/pageCollector.ts +8 -6
  47. package/src/bin/playwright/pageTestCollector.ts +15 -0
  48. package/src/bin/playwright/templates.ts +16 -5
  49. package/src/bin/routes/Parser.ts +100 -32
  50. package/src/bin/routes/getRoutes.ts +5 -1
  51. package/src/front/server/useIsServer.ts +5 -0
  52. package/src/front/server-state/DataProxy.ts +140 -61
  53. package/src/front/server-state/SSR.ts +22 -2
  54. package/src/front/server-state/{real.ts → orig.ts} +19 -2
  55. package/src/front/server-state/serverStates.ts +33 -18
  56. package/src/front/server-state/testState.ts +15 -0
  57. package/src/front/server-state/useServerState.ts +6 -11
  58. package/src/front/translate/TranslateConfig.tsx +153 -0
  59. package/src/front/url/JinraiContext.tsx +2 -0
  60. package/src/front/url/adapter/def.tsx +1 -1
  61. package/src/front/url/adapter/rrd6.tsx +2 -3
  62. package/src/front/url/adapter/rrd7.tsx +2 -2
  63. package/src/front/url/search/useSearch.ts +3 -4
  64. package/src/front/url/search/useSearchValue.ts +25 -13
  65. package/src/front/wrapper/Custom.tsx +28 -4
  66. package/tests/data-proxy/create-dataproxy.test.ts +116 -0
  67. package/tests/{custom.test.ts → parse/custom.test.ts} +2 -2
  68. package/tests/{parse.test.ts → parse/parse.test.ts} +7 -7
  69. package/tsconfig.types.json +1 -0
  70. package/vite/plugin.ts +40 -22
  71. package/lib/src/front/server-state/real.d.ts +0 -1
  72. /package/tests/{content → parse/content}/1.html +0 -0
  73. /package/tests/{content → parse/content}/1_result.json +0 -0
  74. /package/tests/{content → parse/content}/2.html +0 -0
  75. /package/tests/{content → parse/content}/2_result.json +0 -0
  76. /package/tests/{content → parse/content}/3.html +0 -0
  77. /package/tests/{content → parse/content}/3_result.json +0 -0
  78. /package/tests/{content → parse/content}/4.html +0 -0
  79. /package/tests/{content → parse/content}/4_result.json +0 -0
  80. /package/tests/{content → parse/content}/custom.html +0 -0
  81. /package/tests/{content → parse/content}/custom.json +0 -0
  82. /package/tests/{content → parse/content}/index.html +0 -0
  83. /package/tests/{content → parse/content}/index.json +0 -0
  84. /package/tests/{content → parse/content}/index_with_templates.json +0 -0
  85. /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
- source?: string;
10
+ $JV?: JinraiValue;
5
11
  toJSON: () => string;
6
- bindSource: (source: string) => string;
12
+ bindSource: (source: JinraiValue) => string;
7
13
  }
8
14
  interface Array<T> {
9
- source?: string;
15
+ $JV?: JinraiValue;
10
16
  toJSON(): any;
11
- bindSource(source: string): T[];
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: string, separator: string, def: any) => string;
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 source = this.source;
8
+ const $JV = this.$JV;
9
9
  // @ts-ignore
10
- return source ? source : this;
10
+ return $JV ? { $JV } : this;
11
11
  }
12
12
  // @ts-ignore
13
13
  return this;
14
14
  }
15
15
  {
16
- String.prototype.source = undefined;
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.source = source;
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.source = source;
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 `@JV[[${JSON.stringify({ key, type, separator, def })}]]`;
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 type { ReactElement, ReactNode } from "react";
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) => string | ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
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
- return `<custom>${JSON.stringify({ name, props })}<custom>`;
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 };
@@ -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 pageCollector = async (page) => {
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.$exportServerStates);
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: "____fast-ssr-tool___",
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 && context) {
192
- const page = await context.newPage();
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
- const { root } = await pageCollector(page);
196
- const { routes } = getRoutesAndTemplates([{ id: 1, state: {}, mask: currentUrl, root }], true, false);
197
- console.log({ routes });
198
- writeFile("./routs.json", JSON.stringify(routes, null, 2));
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
- console.log("Stop server");
207
- // mirrorServer?.close()
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.2",
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"),
@@ -0,0 +1,2 @@
1
+ export const JinraiAgent = "____JINRAI_AGENT____"
2
+ export const ViteAgent = "____JINRAI_VITE_AGENT____"
@@ -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 (config.test) {
58
- task.next(`Tests`)
59
- for await (const page of pages) {
60
- if (!page.test) {
61
- continue
62
- }
59
+ if (customComponents.length) {
60
+ task.next(`Custom`)
61
+
62
+ await mkdir(path.join(outputcashe, "custom"), { recursive: true })
63
63
 
64
- await writeFile(path.join(outputcashe, `test_${page.id}.html`), normalizeHtmlWhitespace(page.test))
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 (page: Page): Promise<{ state: ServerStateMap; root: string }> => {
5
- const state = await page.evaluate(() => {
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
- console.log("BROWSER", state)
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<PageData[]> => {
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: "____JINRAI_CLIENT____",
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
  }