akanjs 2.2.1 → 2.2.2-rc.0

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.
@@ -11,9 +11,9 @@ export interface AllDictionary {
11
11
 
12
12
  export class Translator {
13
13
  static #langDictionaryMap = new Map<string, Dictionary>();
14
- constructor(
15
- dictionary: Record<string, Record<string, Record<string, unknown>>>,
16
- ) {
14
+
15
+ static #seededDicts = new WeakSet<object>();
16
+ constructor(dictionary: Record<string, Record<string, Record<string, unknown>>>) {
17
17
  Object.entries(dictionary).forEach(([lang, dictionary]) => {
18
18
  this.#setDictionary(lang, dictionary);
19
19
  });
@@ -24,10 +24,12 @@ export class Translator {
24
24
 
25
25
  static seed(lang: string, dict: Dictionary | undefined) {
26
26
  if (!dict) return;
27
+
28
+ if (Translator.#seededDicts.has(dict)) return;
29
+ Translator.#seededDicts.add(dict);
27
30
  const existingDictionary = Translator.#langDictionaryMap.get(lang) ?? {};
28
31
  Object.entries(dict).forEach(([key, modelDict]) => {
29
- if (existingDictionary[key])
30
- Object.assign(existingDictionary[key], modelDict);
32
+ if (existingDictionary[key]) Object.assign(existingDictionary[key], modelDict);
31
33
  else existingDictionary[key] = modelDict as Dictionary[string];
32
34
  });
33
35
  Translator.#langDictionaryMap.set(lang, existingDictionary);
@@ -36,22 +38,15 @@ export class Translator {
36
38
  Translator.seed(lang, dict);
37
39
  return Translator.#langDictionaryMap.get(lang) as Dictionary;
38
40
  }
39
- translate(
40
- lang: string,
41
- key: string,
42
- param?: Record<string, string | number>,
43
- ): string {
41
+ translate(lang: string, key: string, param?: Record<string, string | number>): string {
44
42
  const dictionary = Translator.#langDictionaryMap.get(lang);
45
43
  if (!dictionary) return key;
46
44
  const msg = (pathGet(key, dictionary, ".", { t: key }) as { t: string }).t;
47
- return param
48
- ? msg.replace(/{([^}]+)}/g, (_, key: string) => param[key] as string)
49
- : msg;
45
+ return param ? msg.replace(/{([^}]+)}/g, (_, key: string) => param[key] as string) : msg;
50
46
  }
51
47
  async getDictionary(lang: string) {
52
48
  const dictionary = Translator.#langDictionaryMap.get(lang);
53
- if (!dictionary)
54
- throw new Error(`Dictionary for language ${lang} not found`);
49
+ if (!dictionary) throw new Error(`Dictionary for language ${lang} not found`);
55
50
  return dictionary;
56
51
  }
57
52
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akanjs",
3
- "version": "2.2.1",
3
+ "version": "2.2.2-rc.0",
4
4
  "sourceType": "module",
5
5
  "type": "module",
6
6
  "publishConfig": {
package/ui/System/SSR.tsx CHANGED
@@ -1,21 +1,10 @@
1
1
  import { getEnv } from "akanjs/base";
2
- import {
3
- clsx,
4
- type ReactFont,
5
- router,
6
- type WebAppManifest,
7
- } from "akanjs/client";
2
+ import { clsx, type ReactFont, router, Translator, type WebAppManifest } from "akanjs/client";
8
3
  import { setRequestTheme } from "akanjs/fetch";
9
4
  import { Children, Fragment, type ReactNode, Suspense } from "react";
10
5
  import { FontCss } from "../fontCss";
11
6
  import { Load } from "../Load";
12
- import {
13
- ClientBridge,
14
- ClientInner,
15
- ClientPathWrapper,
16
- ClientSsrBridge,
17
- ClientWrapper,
18
- } from "./Client";
7
+ import { ClientBridge, ClientInner, ClientPathWrapper, ClientSsrBridge, ClientWrapper } from "./Client";
19
8
  import { ManifestLink, type ProviderProps } from "./Common";
20
9
 
21
10
  export const SSR = () => {
@@ -44,14 +33,13 @@ const SSRProvider = ({
44
33
  of,
45
34
  }: SSRProviderProps) => {
46
35
  setRequestTheme(theme);
47
-
36
+ if (dictionary && params.lang) Translator.seed(params.lang, dictionary);
48
37
  return (
49
38
  <Load.Page
50
39
  of={of}
51
40
  loader={async () => {
52
41
  const { lang } = params;
53
- if (!router.isInitialized)
54
- router.init({ type: "ssr", side: "server", lang, prefix });
42
+ if (!router.isInitialized) router.init({ type: "ssr", side: "server", lang, prefix });
55
43
  return { lang } as const;
56
44
  }}
57
45
  render={({ lang }) => (
@@ -65,24 +53,13 @@ const SSRProvider = ({
65
53
  prefix={prefix}
66
54
  layoutStyle={layoutStyle}
67
55
  >
68
- <ClientWrapper
69
- theme={theme}
70
- lang={lang}
71
- reconnect={reconnect}
72
- dictionary={dictionary}
73
- >
56
+ <ClientWrapper theme={theme} lang={lang} reconnect={reconnect} dictionary={dictionary}>
74
57
  <Fragment key="children">{Children.toArray(children)}</Fragment>
75
58
  <Suspense key="client-inner" fallback={null}>
76
59
  <ClientInner />
77
60
  </Suspense>
78
61
  <Suspense key="client-bridge" fallback={null}>
79
- <ClientBridge
80
- key="bridge"
81
- env={env}
82
- theme={theme}
83
- prefix={prefix}
84
- gaTrackingId={gaTrackingId}
85
- />
62
+ <ClientBridge key="bridge" env={env} theme={theme} prefix={prefix} gaTrackingId={gaTrackingId} />
86
63
  <ClientSsrBridge key="ssr-bridge" lang={lang} prefix={prefix} />
87
64
  </Suspense>
88
65
  </ClientWrapper>
@@ -101,14 +78,7 @@ const ServerFontFace = ({ fonts }: { fonts: ReactFont[] }) => {
101
78
  return (
102
79
  <>
103
80
  {preloads.map((preload) => (
104
- <link
105
- key={preload.href}
106
- rel="preload"
107
- href={preload.href}
108
- as="font"
109
- type={preload.type}
110
- crossOrigin=""
111
- />
81
+ <link key={preload.href} rel="preload" href={preload.href} as="font" type={preload.type} crossOrigin="" />
112
82
  ))}
113
83
  {css ? (
114
84
 
@@ -145,23 +115,14 @@ const SSRWrapper = ({
145
115
  {head ? <Fragment key="head">{head}</Fragment> : null}
146
116
  <div key="frame-root" id="frameRoot" className={className}>
147
117
  <ClientPathWrapper layoutStyle={layoutStyle} prefix={prefix}>
148
- <div
149
- key="top-safe-area"
150
- id="topSafeArea"
151
- className={clsx("fixed inset-x-0 top-0 bg-base-100")}
152
- />
153
- <div
154
- key="page-containers"
155
- id="pageContainers"
156
- className={clsx("isolate")}
157
- >
118
+ <div key="top-safe-area" id="topSafeArea" className={clsx("fixed inset-x-0 top-0 bg-base-100")} />
119
+ <div key="page-containers" id="pageContainers" className={clsx("isolate")}>
158
120
  <div id="pageContainer">
159
121
  <div
160
122
  id="pageContent"
161
123
  className={clsx("relative isolate", {
162
124
  "w-full": layoutStyle === "web",
163
- "left-1/2 h-screen w-[600px] -translate-x-1/2":
164
- layoutStyle === "mobile",
125
+ "left-1/2 h-screen w-[600px] -translate-x-1/2": layoutStyle === "mobile",
165
126
  })}
166
127
  >
167
128
  {Children.toArray(children)}
@@ -176,10 +137,7 @@ const SSRWrapper = ({
176
137
  "w-full": layoutStyle === "web",
177
138
  })}
178
139
  >
179
- <div
180
- id="topInsetContent"
181
- className={clsx("relative isolate size-full")}
182
- />
140
+ <div id="topInsetContent" className={clsx("relative isolate size-full")} />
183
141
  </div>
184
142
  <div
185
143
  key="top-left-action"
@@ -196,11 +154,7 @@ const SSRWrapper = ({
196
154
  >
197
155
  <div id="bottomInsetContent" className="isolate size-full" />
198
156
  </div>
199
- <div
200
- key="bottom-safe-area"
201
- id="bottomSafeArea"
202
- className="fixed inset-x-0 bg-base-100"
203
- />
157
+ <div key="bottom-safe-area" id="bottomSafeArea" className="fixed inset-x-0 bg-base-100" />
204
158
  </ClientPathWrapper>
205
159
  </div>
206
160
  </>