jinrai 1.1.1 → 1.1.3

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 (58) hide show
  1. package/index.ts +4 -0
  2. package/lib/bin/bin.js +13 -9
  3. package/lib/index.d.ts +2 -0
  4. package/lib/index.js +1 -0
  5. package/lib/src/bin/agent/agent.d.ts +1 -0
  6. package/lib/src/bin/agent/agent.js +3 -0
  7. package/lib/src/bin/playwright/pageCollector.d.ts +2 -1
  8. package/lib/src/bin/playwright/templates.d.ts +2 -6
  9. package/lib/src/bin/routes/Parser.d.ts +6 -1
  10. package/lib/src/bin/routes/Parser.js +5 -0
  11. package/lib/src/bin/routes/getRoutes.d.ts +3 -2
  12. package/lib/src/front/server-state/DataProxy.d.ts +2 -1
  13. package/lib/src/front/server-state/DataProxy.js +119 -60
  14. package/lib/src/front/server-state/SSR.d.ts +2 -0
  15. package/lib/src/front/server-state/SSR.js +16 -3
  16. package/lib/src/front/server-state/real.js +12 -1
  17. package/lib/src/front/server-state/serverStates.d.ts +19 -5
  18. package/lib/src/front/server-state/serverStates.js +29 -15
  19. package/lib/src/front/server-state/useServerState.d.ts +3 -12
  20. package/lib/src/front/server-state/useServerState.js +12 -12
  21. package/lib/src/front/url/search/useSearch.js +1 -1
  22. package/lib/src/front/url/search/useSearchValue.d.ts +11 -5
  23. package/lib/src/front/url/search/useSearchValue.js +15 -7
  24. package/lib/src/front/wrapper/Custom.d.ts +3 -3
  25. package/lib/src/front/wrapper/Custom.js +11 -2
  26. package/lib/vite/plugin.js +18 -149
  27. package/package.json +7 -1
  28. package/src/bin/agent/agent.ts +1 -0
  29. package/src/bin/playwright/pageCollector.ts +6 -3
  30. package/src/bin/playwright/templates.ts +5 -9
  31. package/src/bin/routes/Parser.ts +12 -5
  32. package/src/bin/routes/getRoutes.ts +4 -3
  33. package/src/front/server-state/DataProxy.ts +136 -61
  34. package/src/front/server-state/SSR.ts +18 -2
  35. package/src/front/server-state/real.ts +16 -1
  36. package/src/front/server-state/serverStates.ts +54 -20
  37. package/src/front/server-state/useServerState.ts +17 -26
  38. package/src/front/url/search/useSearch.ts +1 -1
  39. package/src/front/url/search/useSearchValue.ts +29 -13
  40. package/src/front/wrapper/Custom.tsx +20 -4
  41. package/tests/data-proxy/create-dataproxy.test.ts +116 -0
  42. package/tests/{custom.test.ts → parse/custom.test.ts} +2 -2
  43. package/tests/{parse.test.ts → parse/parse.test.ts} +7 -7
  44. package/vite/plugin.ts +21 -15
  45. /package/tests/{content → parse/content}/1.html +0 -0
  46. /package/tests/{content → parse/content}/1_result.json +0 -0
  47. /package/tests/{content → parse/content}/2.html +0 -0
  48. /package/tests/{content → parse/content}/2_result.json +0 -0
  49. /package/tests/{content → parse/content}/3.html +0 -0
  50. /package/tests/{content → parse/content}/3_result.json +0 -0
  51. /package/tests/{content → parse/content}/4.html +0 -0
  52. /package/tests/{content → parse/content}/4_result.json +0 -0
  53. /package/tests/{content → parse/content}/custom.html +0 -0
  54. /package/tests/{content → parse/content}/custom.json +0 -0
  55. /package/tests/{content → parse/content}/index.html +0 -0
  56. /package/tests/{content → parse/content}/index.json +0 -0
  57. /package/tests/{content → parse/content}/index_with_templates.json +0 -0
  58. /package/tests/{content → parse/content}/templates.json +0 -0
@@ -0,0 +1,116 @@
1
+ import { describe, it, expect } from "vitest"
2
+ import createDataProxy, { DataProxy } from "../../src/front/server-state/DataProxy"
3
+ import { ssr, stringifyInput } from "../../src/front/server-state/SSR"
4
+
5
+ const getValue = <T>(p: T & DataProxy) => p.getValue()
6
+
7
+ describe("createDataProxy", () => {
8
+ it("should return getValue() = original data", () => {
9
+ const proxy = createDataProxy({ a: 1 })
10
+ expect(proxy.getValue()).toEqual({ a: 1 })
11
+ })
12
+
13
+ it("should generate template for primitive children", () => {
14
+ const proxy = createDataProxy({ name: "John" })
15
+
16
+ // name → {{/name}}
17
+ expect((proxy as any).name).toBe("{{/name}}")
18
+ })
19
+
20
+ it("should create nested proxies for objects", () => {
21
+ const proxy = createDataProxy({ user: { age: 20 } })
22
+
23
+ // user is proxy
24
+ const sub = (proxy as any).user
25
+ expect(typeof sub.getValue).toBe("function")
26
+
27
+ // nested fallback
28
+ expect(sub.age).toBe("{{/user/age}}")
29
+ })
30
+
31
+ it("should work with arrays in map()", () => {
32
+ const data = { items: [1, 2, 3] }
33
+ const proxy = createDataProxy(data)
34
+
35
+ const res = (proxy as any).items.map((itm: any) => itm)
36
+ // вернул React.createElement(...) → проверим массив аргументов
37
+ const [, arr] = res.props.children
38
+
39
+ expect(arr.length).toBe(1) // slice(0,1)
40
+ const mapped = arr[0]
41
+ expect(getValue(mapped)).toBe(1)
42
+ })
43
+
44
+ it("should handle Symbol.toPrimitive", () => {
45
+ const proxy = createDataProxy(123 as any)
46
+
47
+ const str = `${proxy}` // вызывает toPrimitive
48
+
49
+ expect(str).toBe("{{}}") // путь "" → {{}}
50
+ })
51
+
52
+ it("should return correct path in nested map()", () => {
53
+ const proxy = createDataProxy({
54
+ list: [{ value: 10 }],
55
+ })
56
+
57
+ const result = (proxy as any).list.map((itm: any) => itm)
58
+
59
+ const [, arr] = result.props.children
60
+ const mappedProxy = arr[0]
61
+
62
+ expect(mappedProxy.value).toBe("{{/list/[ITEM=0]/value}}")
63
+ })
64
+
65
+ it("should allow calling $ accessors", () => {
66
+ const proxy = createDataProxy({})
67
+
68
+ const expr = (proxy as any).$some("id")
69
+
70
+ expect(expr).toBe("{{/id\\$some}}")
71
+ })
72
+
73
+ it("toJSON should return template when ssr.exportParams = true", () => {
74
+ const proxy = createDataProxy({ a: 1 }, "/root")
75
+
76
+ expect(stringifyInput(proxy)).toBe('"{{/root}}"')
77
+ })
78
+
79
+ it("should ignore then / Promise-like traps", () => {
80
+ const proxy = createDataProxy({ then: "abc" } as any)
81
+
82
+ // then должен быть undefined → чтобы Proxy не выглядел как Promise
83
+ expect((proxy as any).then).toBe(undefined)
84
+ })
85
+
86
+ it("should preserve Symbol.iterator for iterable data", () => {
87
+ const original = [1, 2, 3]
88
+ const proxy = createDataProxy(original)
89
+
90
+ const iter = (proxy as any)[Symbol.iterator]
91
+ expect(typeof iter).toBe("function")
92
+
93
+ const collected = [...proxy]
94
+ expect(collected).toEqual(["{{/0}}", "{{/1}}", "{{/2}}"])
95
+ })
96
+
97
+ it("should not define Symbol.iterator on non-iterables", () => {
98
+ const proxy = createDataProxy({})
99
+
100
+ const iter = (proxy as any)[Symbol.iterator]
101
+ expect(iter).toBe(undefined)
102
+ })
103
+
104
+ it("should produce fallback template for unknown prop", () => {
105
+ const proxy = createDataProxy({})
106
+
107
+ expect((proxy as any).abc).toBe("{{/abc}}")
108
+ })
109
+
110
+ it("should produce path-based fallback for nested unknown prop", () => {
111
+ const proxy = createDataProxy({ user: {} })
112
+
113
+ const sub = (proxy as any).user
114
+ expect(sub.unknown).toBe("{{/user/unknown}}")
115
+ })
116
+ })
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest"
2
- import { Parser } from "../src/bin/routes/Parser"
2
+ import { Parser } from "../../src/bin/routes/Parser"
3
3
  import { readFile } from "fs/promises"
4
4
 
5
5
  import custom from "./content/custom.json"
@@ -8,7 +8,7 @@ describe("test custom component", async () => {
8
8
  const parsr = new Parser({ normalize: true })
9
9
 
10
10
  it("parse custom.html", async () => {
11
- const html = await readFile("./tests/content/custom.html", "utf-8")
11
+ const html = await readFile("./tests/parse/content/custom.html", "utf-8")
12
12
  // expect(JSON.stringify(parsr.parse(html))).toEqual("")
13
13
 
14
14
  expect(parsr.parse(html)).toEqual(custom)
@@ -1,6 +1,6 @@
1
1
  import { readFile } from "node:fs/promises"
2
2
  import { describe, expect, it } from "vitest"
3
- import { Parser } from "../src/bin/routes/Parser"
3
+ import { Parser } from "../../src/bin/routes/Parser"
4
4
 
5
5
  import result_1 from "./content/1_result.json"
6
6
  import result_2 from "./content/2_result.json"
@@ -14,27 +14,27 @@ describe("test Parser class", async () => {
14
14
  const parsr = new Parser({ normalize: true })
15
15
 
16
16
  it("parse 1.html", async () => {
17
- const html = await readFile("./tests/content/1.html", "utf-8")
17
+ const html = await readFile("./tests/parse/content/1.html", "utf-8")
18
18
  expect(parsr.parse(html)).toEqual(result_1)
19
19
  })
20
20
 
21
21
  it("parse 2.html", async () => {
22
- const html = await readFile("./tests/content/2.html", "utf-8")
22
+ const html = await readFile("./tests/parse/content/2.html", "utf-8")
23
23
  expect(parsr.parse(html)).toEqual(result_2)
24
24
  })
25
25
 
26
26
  it("parse 3.html", async () => {
27
- const html = await readFile("./tests/content/3.html", "utf-8")
27
+ const html = await readFile("./tests/parse/content/3.html", "utf-8")
28
28
  expect(parsr.parse(html)).toEqual(result_3)
29
29
  })
30
30
 
31
31
  it("parse 4.html", async () => {
32
- const html = await readFile("./tests/content/4.html", "utf-8")
32
+ const html = await readFile("./tests/parse/content/4.html", "utf-8")
33
33
  expect(parsr.parse(html)).toEqual(result_4)
34
34
  })
35
35
 
36
36
  it("parse index.html", async () => {
37
- const html = await readFile("./tests/content/index.html", "utf-8")
37
+ const html = await readFile("./tests/parse/content/index.html", "utf-8")
38
38
  expect(parsr.parse(html)).toEqual(index)
39
39
  })
40
40
  })
@@ -43,7 +43,7 @@ describe("test Parser templates", async () => {
43
43
  const parsr = new Parser({ normalize: true, templates: true })
44
44
 
45
45
  it("parse index.html", async () => {
46
- const html = await readFile("./tests/content/index.html", "utf-8")
46
+ const html = await readFile("./tests/parse/content/index.html", "utf-8")
47
47
  // expect(JSON.stringify(parsr.templates)).toEqual("")
48
48
 
49
49
  expect(parsr.parse(html)).toEqual(index_tempates)
package/vite/plugin.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import { createServer, type Plugin, type ViteDevServer } from "vite"
2
2
 
3
3
  import { AsyncLocalStorage } from "async_hooks"
4
- import { type BrowserContext, chromium } from "playwright"
4
+ import { type BrowserContext, chromium, Page } from "playwright"
5
5
  import { pageCollector } from "../src/bin/playwright/pageCollector"
6
- import { getRoutesAndTemplates } from "../src/bin/routes/getRoutes"
6
+ // import { getRoutesAndTemplates } from "../src/bin/routes/getRoutes"
7
7
 
8
- import { writeFile } from "fs/promises"
8
+ // import { writeFile } from "fs/promises"
9
+ import { JinraiAgent } from "../src/bin/agent/agent"
9
10
 
10
11
  const urlStorage = new AsyncLocalStorage<string>()
11
12
 
@@ -18,6 +19,7 @@ export function hydration(): Plugin {
18
19
  console.log("create mirror")
19
20
  let mirrorServer: ViteDevServer | undefined = undefined
20
21
  let context: BrowserContext | undefined = undefined
22
+ let page: Page | undefined = undefined
21
23
 
22
24
  let debugUrl: string | undefined = undefined
23
25
 
@@ -31,12 +33,14 @@ export function hydration(): Plugin {
31
33
 
32
34
  debugUrl = mirrorServer.resolvedUrls?.local[0].slice(0, -1)
33
35
 
34
- chromium.launch({ headless: true, devtools: false }).then(async browser => {
36
+ chromium.launch({ headless: false, devtools: false, channel: "chrome" }).then(async browser => {
35
37
  console.log("create context")
36
38
  context = await browser.newContext({
37
- userAgent: "____fast-ssr-tool___",
39
+ // userAgent: JinraiAgent,
38
40
  locale: "ru-RU",
39
41
  })
42
+
43
+ page = await context.newPage()
40
44
  })
41
45
  })
42
46
 
@@ -56,28 +60,30 @@ export function hydration(): Plugin {
56
60
 
57
61
  async transformIndexHtml(html: string) {
58
62
  const currentUrl = urlStorage.getStore()
59
- if (currentUrl && context) {
60
- const page = await context.newPage()
63
+ if (currentUrl && page) {
61
64
  await page.goto(debugUrl + currentUrl)
62
65
  await page.waitForLoadState("networkidle")
63
66
 
64
- const { root } = await pageCollector(page)
65
- const { routes } = getRoutesAndTemplates([{ id: 1, input: [], mask: currentUrl, root }], true, false)
67
+ const { state } = await pageCollector(page)
68
+ // const { routes } = getRoutesAndTemplates([{ id: 1, state: {}, mask: currentUrl, root }], true, false)
66
69
 
67
- console.log({ routes })
68
- writeFile("./routs.json", JSON.stringify(routes, null, 2))
70
+ // console.log({ routes })
71
+ // writeFile("./routs.json", JSON.stringify(routes, null, 2))
69
72
 
70
- const result = html.replace("<!--app-html-->", root)
73
+ // html = html.replace("<!--app-html-->", root)
74
+ html = html.replace("<!--app-head-->", JSON.stringify(state, null, 2))
71
75
 
72
- page.close()
73
- return result
76
+ return html
74
77
  }
75
78
  return html
76
79
  },
77
80
 
78
81
  closeWatcher() {
79
82
  console.log("Stop server")
80
- // mirrorServer?.close()
83
+
84
+ page?.close()
85
+ mirrorServer?.close()
86
+ context?.close()
81
87
  },
82
88
  }
83
89
  }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes