jinrai 1.1.3 → 1.1.5

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 (64) hide show
  1. package/front.config.json +2 -1
  2. package/index.ts +2 -1
  3. package/lib/bin/bin.js +115 -52
  4. package/lib/index.d.ts +2 -1
  5. package/lib/index.js +2 -1
  6. package/lib/src/bin/agent/agent.d.ts +1 -0
  7. package/lib/src/bin/agent/agent.js +2 -1
  8. package/lib/src/bin/config/userConfig.d.ts +1 -0
  9. package/lib/src/bin/playwright/pageCollector.d.ts +2 -0
  10. package/lib/src/bin/playwright/pageTestCollector.d.ts +6 -0
  11. package/lib/src/bin/playwright/templates.d.ts +6 -1
  12. package/lib/src/bin/routes/Parser.d.ts +19 -1
  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.js +3 -0
  17. package/lib/src/front/server-state/SSR.d.ts +1 -0
  18. package/lib/src/front/server-state/SSR.js +3 -1
  19. package/lib/src/front/server-state/orig.d.ts +2 -0
  20. package/lib/src/front/server-state/{real.js → orig.js} +3 -2
  21. package/lib/src/front/server-state/serverStates.d.ts +1 -0
  22. package/lib/src/front/server-state/serverStates.js +6 -2
  23. package/lib/src/front/server-state/testState.d.ts +3 -0
  24. package/lib/src/front/server-state/testState.js +14 -0
  25. package/lib/src/front/server-state/useServerState.js +5 -9
  26. package/lib/src/front/translate/TranslateConfig.d.ts +21 -0
  27. package/lib/src/front/translate/TranslateConfig.js +108 -0
  28. package/lib/src/front/url/JinraiContext.d.ts +1 -0
  29. package/lib/src/front/url/JinraiContext.js +1 -0
  30. package/lib/src/front/url/adapter/def.js +1 -1
  31. package/lib/src/front/url/adapter/rrd6.js +2 -2
  32. package/lib/src/front/url/adapter/rrd7.js +2 -2
  33. package/lib/src/front/url/search/useSearch.js +3 -4
  34. package/lib/src/front/wrapper/Custom.js +5 -1
  35. package/lib/vite/plugin.js +20 -14
  36. package/package.json +6 -2
  37. package/rollup.config.mjs +2 -1
  38. package/src/bin/agent/agent.ts +1 -0
  39. package/src/bin/build/build.ts +23 -10
  40. package/src/bin/config/define.ts +1 -3
  41. package/src/bin/config/userConfig.ts +1 -0
  42. package/src/bin/playwright/pageCollector.ts +8 -4
  43. package/src/bin/playwright/pageTestCollector.ts +15 -0
  44. package/src/bin/playwright/templates.ts +14 -4
  45. package/src/bin/routes/Parser.ts +88 -27
  46. package/src/bin/routes/getRoutes.ts +5 -1
  47. package/src/front/server/useIsServer.ts +5 -0
  48. package/src/front/server-state/DataProxy.ts +4 -0
  49. package/src/front/server-state/SSR.ts +5 -1
  50. package/src/front/server-state/{real.ts → orig.ts} +3 -1
  51. package/src/front/server-state/serverStates.ts +8 -2
  52. package/src/front/server-state/testState.ts +15 -0
  53. package/src/front/server-state/useServerState.ts +6 -11
  54. package/src/front/translate/TranslateConfig.tsx +153 -0
  55. package/src/front/url/JinraiContext.tsx +2 -0
  56. package/src/front/url/adapter/def.tsx +1 -1
  57. package/src/front/url/adapter/rrd6.tsx +2 -3
  58. package/src/front/url/adapter/rrd7.tsx +2 -2
  59. package/src/front/url/search/useSearch.ts +3 -4
  60. package/src/front/wrapper/Custom.tsx +9 -1
  61. package/tests/parse/custom.test.ts +2 -1
  62. package/tsconfig.types.json +1 -0
  63. package/vite/plugin.ts +32 -20
  64. package/lib/src/front/server-state/real.d.ts +0 -1
@@ -13,7 +13,7 @@ interface ParserOptions {
13
13
  normalize?: boolean
14
14
  }
15
15
 
16
- export type Element = ArrayElement | HtmlElement | ValueElement | CustomElement
16
+ export type Element = ArrayElement | HtmlElement | ValueElement | CustomElement | TranslateText | TValueElement
17
17
 
18
18
  interface ArrayElement {
19
19
  type: "array"
@@ -30,6 +30,15 @@ interface ValueElement {
30
30
  type: "value"
31
31
  key: string
32
32
  }
33
+ interface TValueElement {
34
+ type: "tvalue"
35
+ value: string
36
+ }
37
+
38
+ interface TranslateText {
39
+ type: "t"
40
+ text: string
41
+ }
33
42
 
34
43
  interface CustomElement {
35
44
  type: "custom"
@@ -37,17 +46,27 @@ interface CustomElement {
37
46
  props: object
38
47
  }
39
48
 
49
+ export interface CustomExample {
50
+ name: string
51
+ html: string
52
+ props: any
53
+ }
54
+
40
55
  export class Parser {
41
56
  options?: ParserOptions
42
57
 
43
58
  openVar = "{{"
44
59
  createVar = "}}"
60
+ openTVar = "{!"
61
+ createTVar = "!}"
62
+
45
63
  createArray = "</loopwrapper"
46
64
  createCustom = "</custom"
47
65
  deepUp = "<loopwrapper"
48
66
  deepUp2 = "<custom"
49
67
 
50
68
  templates: Record<string, string> = {}
69
+ custom: CustomExample[] = []
51
70
 
52
71
  constructor(options?: ParserOptions) {
53
72
  this.options = options
@@ -63,9 +82,10 @@ export class Parser {
63
82
  let match
64
83
  let deep = 0
65
84
  let lastIndex = 0
85
+ let translate = false
66
86
 
67
87
  const tagPattern = new RegExp(
68
- `(<loopwrapper(\\s+[^>]*)?>|</loopwrapper>|\{\{|\}\}|<custom(\\s+[^>]*)?>|</custom>)`,
88
+ `(<loopwrapper(\\s+[^>]*)?>|</loopwrapper>|\{\{|\}\}|\{\!|\!\}|<custom(\\s+[^>]*)?>|</custom>)`,
69
89
  "gi",
70
90
  )
71
91
 
@@ -73,28 +93,42 @@ export class Parser {
73
93
  const currentTag = match[0]
74
94
  const value = content.substring(lastIndex, match.index)
75
95
 
76
- if (currentTag.startsWith(this.createArray)) {
77
- deep--
78
- if (deep > 0) continue
79
- this.createElement(tree, value)
80
- } else if (currentTag.startsWith(this.deepUp)) {
81
- deep++
82
- if (deep > 1) continue
83
- this.createElement(tree, value)
84
- } else if (currentTag.startsWith(this.createCustom)) {
85
- deep--
86
- if (deep != 0) continue
87
- this.createCustomElement(tree, value)
88
- } else if (currentTag.startsWith(this.deepUp2)) {
89
- deep++
90
- if (deep > 1) continue
91
- this.createElement(tree, value)
92
- } else if (currentTag == this.createVar) {
93
- if (deep != 0) continue
94
- this.createElement(tree, value, true)
96
+ if (translate) {
97
+ if (currentTag.startsWith(this.createTVar)) {
98
+ translate = false
99
+ this.createTranslate(tree, value)
100
+ } else {
101
+ continue
102
+ }
95
103
  } else {
96
- if (deep != 0) continue
97
- this.createElement(tree, value)
104
+ if (currentTag.startsWith(this.createArray)) {
105
+ deep--
106
+ if (deep > 0) continue
107
+ this.createElement(tree, value)
108
+ } else if (currentTag.startsWith(this.deepUp)) {
109
+ deep++
110
+ if (deep > 1) continue
111
+ this.createElement(tree, value)
112
+ } else if (currentTag.startsWith(this.createCustom)) {
113
+ deep--
114
+ if (deep != 0) continue
115
+ this.createCustomElement(tree, value)
116
+ } else if (currentTag.startsWith(this.deepUp2)) {
117
+ deep++
118
+ if (deep > 1) continue
119
+ this.createElement(tree, value)
120
+ } else if (currentTag.startsWith(this.openTVar)) {
121
+ ////////////// >>>>
122
+ if (deep != 0) continue
123
+ translate = true
124
+ this.createElement(tree, value)
125
+ } else if (currentTag == this.createVar) {
126
+ if (deep != 0) continue
127
+ this.createElement(tree, value, true)
128
+ } else {
129
+ if (deep != 0) continue
130
+ this.createElement(tree, value)
131
+ }
98
132
  }
99
133
 
100
134
  lastIndex = match.index + currentTag.length
@@ -110,6 +144,14 @@ export class Parser {
110
144
  const [customProps, exampleProps, children] = value.split(SPLIT)
111
145
  const custom = JSON.parse(customProps) as CustomElement
112
146
 
147
+ if (this.custom.find(itm => itm.name == custom.name) == undefined) {
148
+ this.custom.push({
149
+ name: custom.name,
150
+ html: children,
151
+ props: exampleProps,
152
+ })
153
+ }
154
+
113
155
  parent.push({
114
156
  type: "custom",
115
157
  name: custom.name,
@@ -117,12 +159,31 @@ export class Parser {
117
159
  })
118
160
  }
119
161
 
120
- createElement(parent: Element[], value: string, isVarible?: boolean) {
121
- if (isVarible)
162
+ createVarible(parent: Element[], value: string) {
163
+ return parent.push({
164
+ type: "value",
165
+ key: value,
166
+ })
167
+ }
168
+
169
+ createTranslate(parent: Element[], value: string) {
170
+ if (value.startsWith("{{") && value.endsWith("}}")) {
122
171
  return parent.push({
123
- type: "value",
124
- key: value,
172
+ type: "tvalue",
173
+ value: value.slice(2, -2),
125
174
  })
175
+ }
176
+
177
+ return parent.push({
178
+ type: "t",
179
+ text: value,
180
+ })
181
+ }
182
+
183
+ createElement(parent: Element[], value: string, isVarible?: boolean) {
184
+ if (isVarible) {
185
+ return this.createVarible(parent, value)
186
+ }
126
187
 
127
188
  if (value.trimStart().startsWith("ArrayDataKey=")) {
128
189
  const [key, ...val] = value.trimStart().substring(13).split("|")
@@ -16,7 +16,10 @@ export const getRoutesAndTemplates = (pages: PageData[], normalize: boolean = tr
16
16
  for (const [id, template] of pages.entries()) {
17
17
  const content = parser.parse(template.root)
18
18
 
19
- const mask = template.mask.replaceAll("/", "\\/").replace(/{(.*?)}/, ".+?")
19
+ const mask = template.mask
20
+ .replaceAll("/", "\\/")
21
+ .replace(/{(.*?)}/, ".+?")
22
+ .replace("\/*", "\/?.*")
20
23
 
21
24
  routes.push({
22
25
  id,
@@ -29,5 +32,6 @@ export const getRoutesAndTemplates = (pages: PageData[], normalize: boolean = tr
29
32
  return {
30
33
  routes,
31
34
  templates: parser.templates,
35
+ customComponents: parser.custom,
32
36
  }
33
37
  }
@@ -0,0 +1,5 @@
1
+ import { ssr } from "../server-state/SSR"
2
+
3
+ export const useIsServer = () : boolean => {
4
+ return ssr.current
5
+ }
@@ -161,6 +161,10 @@ function createDataProxy<T>(data: T, path: string = ""): WithDataProxy<T> {
161
161
  // ---------------------------
162
162
  // 8. Nested object
163
163
  // ---------------------------
164
+ if (data === null) {
165
+ return undefined
166
+ }
167
+
164
168
  const value = (data as any)[prop]
165
169
  if (!ssr.exportParams) {
166
170
  return value
@@ -1,7 +1,10 @@
1
- import { JinraiAgent } from "../../bin/agent/agent"
1
+ import { JinraiAgent, ViteAgent } from "../../bin/agent/agent"
2
2
 
3
3
  export const ssr = {
4
4
  current: navigator.userAgent == JinraiAgent,
5
+ // current: true,
6
+
7
+ test: navigator.userAgent == ViteAgent,
5
8
  exportParams: true,
6
9
  exportToJV: false,
7
10
  }
@@ -13,6 +16,7 @@ if (window != undefined) {
13
16
 
14
17
  export const stringifyInput = (input: any) => {
15
18
  ssr.exportParams = false
19
+
16
20
  const result = JSON.stringify(input)
17
21
  ssr.exportParams = true
18
22
 
@@ -2,7 +2,7 @@ import { ssr } from "./SSR"
2
2
  import { sources } from "./DataProxy"
3
3
  import { getJinraiValue, JinraiValue } from "../url/search/useSearchValue"
4
4
 
5
- export function real<T>(value: T): T {
5
+ export function orig<T>(value: T): T {
6
6
  if (!ssr.current) return value
7
7
 
8
8
  switch (typeof value) {
@@ -31,6 +31,8 @@ export function real<T>(value: T): T {
31
31
  }
32
32
  }
33
33
 
34
+ export const original = orig
35
+
34
36
  const wrapSource = <T>(value: T, source: JinraiValue): T => {
35
37
  if (typeof value == "string") {
36
38
  return value.bindSource(source) as T
@@ -40,7 +40,7 @@ if (window != undefined) {
40
40
  window.$exportServerStates = serverStates
41
41
  }
42
42
 
43
- const getIdent = (key: ServerKey): string => {
43
+ export const getIdent = (key: ServerKey): string => {
44
44
  return Array.isArray(key) ? key.join("-") : key
45
45
  }
46
46
 
@@ -51,13 +51,19 @@ export const getServerValue = (key?: ServerKey, def?: ServerValue["value"], opti
51
51
  const ident = getIdent(key)
52
52
  serverStates.set(ident, { options, value: !options?.source ? def : undefined, key })
53
53
 
54
+ console.log("CHECK", ident)
55
+
54
56
  if (ident in initialState) {
55
57
  const result = initialState[ident]
56
58
  // delete initialState[ident]
57
59
 
58
60
  console.log("HAS", ident, result)
59
61
 
60
- return ["data" in result ? result.data : result, true]
62
+ if (result != null && typeof result == 'object' && "data" in result) {
63
+ return [result.data, true]
64
+ }
65
+
66
+ return [result, true]
61
67
  }
62
68
 
63
69
  return [def, false]
@@ -0,0 +1,15 @@
1
+ import { getIdent, ServerValue } from "./serverStates";
2
+ import { ssr } from "./SSR";
3
+ import { ServerKey } from "./useServerState";
4
+
5
+ const test_states = new Map<string, any>()
6
+
7
+ if (window != undefined && ssr.test) {
8
+ // @ts-ignore
9
+ window.$testStates = test_states
10
+ }
11
+
12
+ export const setTestState = (key: ServerKey, value: ServerValue["value"], options?: ServerValue["options"]) => {
13
+ const ident = getIdent(key)
14
+ test_states.set(ident, value)
15
+ }
@@ -1,6 +1,7 @@
1
- import { Dispatch, SetStateAction, useRef, useState } from "react"
1
+ import { Dispatch, SetStateAction, useState } from "react"
2
2
  import { ssr } from "./SSR"
3
3
  import { getServerValue, ServerValue, setServerValue } from "./serverStates"
4
+ import { setTestState } from "./testState"
4
5
 
5
6
  export type ServerStateMap = Record<string, ServerValue>
6
7
  export type ServerKey = string | string[]
@@ -12,7 +13,6 @@ export const useServerState = <T extends ServerValue["value"]>(
12
13
  ) => {
13
14
  const [serverValue, isInitOnServer] = getServerValue(serverKey, initialValue, options)
14
15
  const [value, setStateValue] = useState(serverValue)
15
- const isInit = useRef(isInitOnServer)
16
16
 
17
17
  const setValue: Dispatch<SetStateAction<T>> = (value: T | ((prevState: T) => T)) => {
18
18
  setStateValue((prev: T) => {
@@ -22,18 +22,13 @@ export const useServerState = <T extends ServerValue["value"]>(
22
22
  return setServerValue(serverKey, result, options)
23
23
  }
24
24
 
25
+ if (serverKey != undefined && ssr.test) {
26
+ setTestState(serverKey, result, options)
27
+ }
28
+
25
29
  return result
26
30
  })
27
31
  }
28
32
 
29
- // const initOnServer = () => {
30
- // if (isInit.current) {
31
- // isInit.current = false
32
- // return true
33
- // }
34
-
35
- // return false
36
- // }
37
-
38
33
  return [value, setValue, isInitOnServer] as [T, Dispatch<SetStateAction<T>>, boolean]
39
34
  }
@@ -0,0 +1,153 @@
1
+ import { createContext, useContext, useEffect, useState, type ReactNode } from "react"
2
+ import { ssr } from "../server-state/SSR"
3
+
4
+ export type DefaultLangType = {
5
+ defaultLang: string
6
+ langBaseUrl: string
7
+ source: TranslateSource
8
+ }
9
+
10
+ // let DefaultConfig: DefaultLangType | undefined = undefined
11
+
12
+ // if (window != undefined) {
13
+ // // @ts-ignore
14
+ // window.$langDefaultConfig = DefaultConfig
15
+ // }
16
+
17
+ interface TranslateContextProps {
18
+ translate: (text: string, context?: string) => string
19
+ changeLang: (lang: string) => void
20
+ lang: string
21
+ }
22
+
23
+ const TranslateContext = createContext<TranslateContextProps | null>(null)
24
+
25
+ export const useTranslate = () => {
26
+ const context = useContext(TranslateContext)
27
+ if (!context) throw new Error("not in context (<TranslateConfig>)")
28
+ return context
29
+ }
30
+
31
+ interface TranslateSource {
32
+ from: "cookie" | "url"
33
+ key: string
34
+ }
35
+
36
+ type TranslateConfigProps = DefaultLangType & {
37
+ children: ReactNode
38
+ }
39
+
40
+ type LangMap = Record<string, string>
41
+
42
+ const ONE_DAY = 1000 * 60 * 60 * 24
43
+
44
+ const getCookie = (key: string): string | null => {
45
+ const match = document.cookie.match(new RegExp(`(?:^|; )${key.replace(/([$?*|{}()[\]\\/+^])/g, "\\$1")}=([^;]*)`))
46
+ return match ? decodeURIComponent(match[1]) : null
47
+ }
48
+
49
+ const setCookie = (key: string, value: string, days = 365) => {
50
+ const expires = new Date(Date.now() + days * 864e5).toUTCString()
51
+ document.cookie = `${key}=${encodeURIComponent(value)}; expires=${expires}; path=/`
52
+ }
53
+
54
+ const getStorageKey = (lang: string) => `lang:${lang}`
55
+
56
+ const loadFromStorage = (lang: string): LangMap | null => {
57
+ try {
58
+ const raw = localStorage.getItem(getStorageKey(lang))
59
+ if (!raw) return null
60
+
61
+ const parsed = JSON.parse(raw) as { data: LangMap; expires: number }
62
+ if (Date.now() > parsed.expires) {
63
+ localStorage.removeItem(getStorageKey(lang))
64
+ return null
65
+ }
66
+
67
+ return parsed.data
68
+ } catch {
69
+ return null
70
+ }
71
+ }
72
+
73
+ const saveToStorage = (lang: string, data: LangMap) => {
74
+ localStorage.setItem(
75
+ getStorageKey(lang),
76
+ JSON.stringify({
77
+ data,
78
+ expires: Date.now() + ONE_DAY,
79
+ }),
80
+ )
81
+ }
82
+
83
+ export const TranslateConfig = ({ children, defaultLang, langBaseUrl, source }: TranslateConfigProps) => {
84
+ const [lang, setLang] = useState(defaultLang)
85
+ const [langMap, setLangMap] = useState<LangMap | null>(null)
86
+
87
+ useEffect(() => {
88
+ // @ts-ignore
89
+ window.$langDefaultConfig = {
90
+ defaultLang,
91
+ langBaseUrl,
92
+ source,
93
+ }
94
+ }, [])
95
+
96
+ // initial lang from cookie
97
+ useEffect(() => {
98
+ if (source.from === "cookie") {
99
+ const fromCookie = getCookie(source.key)
100
+ if (fromCookie) setLang(fromCookie)
101
+ }
102
+ }, [source.from, source.key])
103
+
104
+ // load translations on lang change
105
+ useEffect(() => {
106
+ if (lang === defaultLang) {
107
+ setLangMap(null)
108
+ return
109
+ }
110
+
111
+ const cached = loadFromStorage(lang)
112
+ if (cached) {
113
+ setLangMap(cached)
114
+ return
115
+ }
116
+
117
+ fetch(langBaseUrl.replace("*", lang))
118
+ .then(res => {
119
+ if (!res.ok) throw new Error("Failed to load lang map")
120
+ return res.json()
121
+ })
122
+ .then((data: LangMap) => {
123
+ saveToStorage(lang, data)
124
+ setLangMap(data)
125
+ })
126
+ .catch(() => {
127
+ setLangMap(null)
128
+ })
129
+ }, [lang, defaultLang, langBaseUrl])
130
+
131
+ const translate = (text: string, context?: string): string => {
132
+ const key = context ? `${text}(context:${context})` : text
133
+
134
+ if (ssr.current) {
135
+ return `{!${key}!}`
136
+ }
137
+
138
+ if (!langMap) return text
139
+ return langMap[key] ?? langMap[text] ?? text
140
+ }
141
+
142
+ const changeLang = (nextLang: string) => {
143
+ if (nextLang === lang) return
144
+
145
+ if (source.from === "cookie") {
146
+ setCookie(source.key, nextLang)
147
+ }
148
+
149
+ setLang(nextLang)
150
+ }
151
+
152
+ return <TranslateContext.Provider value={{ translate, changeLang, lang }}>{children}</TranslateContext.Provider>
153
+ }
@@ -3,8 +3,10 @@ import { createContext, DependencyList, ReactNode } from "react"
3
3
  export interface JinraiProps {
4
4
  deps?: DependencyList
5
5
  children?: ReactNode
6
+ search: string
6
7
  }
7
8
  export const JinraiContext = createContext<JinraiProps>({
8
9
  deps: [],
9
10
  children: undefined,
11
+ search: ""
10
12
  })
@@ -4,7 +4,7 @@ import { NuqsAdapter } from "nuqs/adapters/react"
4
4
  export const Adapter = (props: JinraiProps) => {
5
5
  return (
6
6
  <NuqsAdapter>
7
- <JinraiContext.Provider value={{ deps: props.deps ?? [] }} {...props} />
7
+ <JinraiContext.Provider value={{ deps: props.deps ?? [], search: "" }} {...props} />
8
8
  </NuqsAdapter>
9
9
  )
10
10
  }
@@ -1,4 +1,3 @@
1
- import React from "react"
2
1
  import { NuqsAdapter } from "nuqs/adapters/react-router/v6"
3
2
 
4
3
  // @ts-ignore
@@ -9,11 +8,11 @@ export const Adapter = (props: JinraiProps) => {
9
8
  // useLocation требует, чтобы компонент был внутри RouterProvider
10
9
  // NuqsAdapter должен быть установлен на верхнем уровне, но может работать внутри роутера
11
10
  // для React Router v6 адаптера
12
- const { pathname } = useLocation()
11
+ const { pathname, search } = useLocation()
13
12
 
14
13
  return (
15
14
  <NuqsAdapter>
16
- <JinraiContext.Provider value={{ deps: [...(props.deps ?? []), pathname] }} {...props} />
15
+ <JinraiContext.Provider value={{ deps: [...(props.deps ?? []), pathname], search: search.substring(1) }} {...props} />
17
16
  </NuqsAdapter>
18
17
  )
19
18
  }
@@ -8,11 +8,11 @@ export const Adapter = (props: JinraiProps) => {
8
8
  // useLocation требует, чтобы компонент был внутри RouterProvider
9
9
  // NuqsAdapter должен быть установлен на верхнем уровне, но может работать внутри роутера
10
10
  // для React Router v7 адаптера
11
- const { pathname } = useLocation()
11
+ const { pathname, search } = useLocation()
12
12
 
13
13
  return (
14
14
  <NuqsAdapter>
15
- <JinraiContext.Provider value={{ deps: [...(props.deps ?? []), pathname] }} {...props} />
15
+ <JinraiContext.Provider value={{ deps: [...(props.deps ?? []), pathname], search}} {...props} />
16
16
  </NuqsAdapter>
17
17
  )
18
18
  }
@@ -4,12 +4,11 @@ import { ssr } from "../../server-state/SSR"
4
4
  import { getJinraiValue } from "./useSearchValue"
5
5
 
6
6
  export const useSearch = (): string => {
7
- const { deps } = useContext(JinraiContext)
8
- const value = useMemo(() => location.search.substring(1), deps ? deps : [])
7
+ const { search } = useContext(JinraiContext)
9
8
 
10
9
  const stableValue = useMemo(() => {
11
- return ssr.current ? value.bindSource(getJinraiValue("", "searchFull", "", "")) : value
12
- }, [value])
10
+ return ssr.current ? search.bindSource(getJinraiValue("", "searchFull", "", "")) : search
11
+ }, [search])
13
12
 
14
13
  return stableValue
15
14
  }
@@ -1,6 +1,8 @@
1
1
  import { Fragment, type ReactElement, type ReactNode } from "react"
2
2
  import { ssr } from "../server-state/SSR"
3
3
  import { SPLIT } from "../../bin/routes/Parser"
4
+ import { orig } from "../server-state/orig"
5
+
4
6
 
5
7
  interface CustomProps {
6
8
  name: string
@@ -11,7 +13,13 @@ interface CustomProps {
11
13
  export const Custom = ({ name, props, children }: CustomProps) => {
12
14
  if (!ssr.current) return <Fragment>{children as ReactElement}</Fragment>
13
15
 
14
- const exampleProps = JSON.stringify({ name, props: props() })
16
+ if (typeof props != "function") {
17
+ throw new Error(`Custom props is not function (${name})`);
18
+
19
+ }
20
+
21
+ const exampleProps = JSON.stringify({ name, props: orig(props()) })
22
+
15
23
  ssr.exportToJV = true
16
24
  const customProps = JSON.stringify({ name, props: props() })
17
25
  ssr.exportToJV = false
@@ -9,7 +9,8 @@ describe("test custom component", async () => {
9
9
 
10
10
  it("parse custom.html", async () => {
11
11
  const html = await readFile("./tests/parse/content/custom.html", "utf-8")
12
- // expect(JSON.stringify(parsr.parse(html))).toEqual("")
12
+ const result = parsr.parse(html)
13
+ // expect(JSON.stringify(result)).toEqual("")
13
14
 
14
15
  expect(parsr.parse(html)).toEqual(custom)
15
16
  })
@@ -30,3 +30,4 @@
30
30
  ]
31
31
  }
32
32
 
33
+