akanjs 2.2.3-rc.0 → 2.2.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.
package/common/types.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export interface FetchPolicy<Returns = unknown> {
2
2
  cache?: boolean | number;
3
3
  crystalize?: boolean;
4
- url?: string;
4
+ origin?: string;
5
5
  onError?: (error: string) => void;
6
6
  token?: string;
7
7
  partial?: string[];
@@ -142,7 +142,7 @@ export class FetchClient {
142
142
  const argMap = new Map(serializerMap.entries().map(([key, serializer], idx) => [key, serializer(args[idx])]));
143
143
  const url = FetchClient.makeHttpUrl(key, endpoint, prefix, argMap);
144
144
  const headers = this.#makeAuthHeaders(option);
145
- const baseUrl = option?.url;
145
+ const baseUrl = option?.origin;
146
146
 
147
147
  const requestQuery = () => this.http.get(url, { headers, baseUrl });
148
148
  const response = baseUrl
@@ -162,7 +162,7 @@ export class FetchClient {
162
162
  const body = HttpClient.makeBody(bodyArgs, uploadArgs, argMap);
163
163
  const response = await this.http.post(url, body, {
164
164
  headers: this.#makeAuthHeaders(option),
165
- baseUrl: option?.url,
165
+ baseUrl: option?.origin,
166
166
  });
167
167
  const parsedReturn = parseReturn(response, { crystalize: option?.crystalize ?? true });
168
168
  return parsedReturn;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akanjs",
3
- "version": "2.2.3-rc.0",
3
+ "version": "2.2.3",
4
4
  "sourceType": "module",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -1,7 +1,7 @@
1
1
  export interface FetchPolicy<Returns = unknown> {
2
2
  cache?: boolean | number;
3
3
  crystalize?: boolean;
4
- url?: string;
4
+ origin?: string;
5
5
  onError?: (error: string) => void;
6
6
  token?: string;
7
7
  partial?: string[];
@@ -30,6 +30,12 @@ export interface ProviderProps {
30
30
  reconnect?: boolean;
31
31
  /** Active-locale dictionary injected by the server (SSR only) to seed the client Translator. */
32
32
  dictionary?: Record<string, Record<string, unknown>>;
33
+ /**
34
+ * Full lang-keyed dictionary snapshot (SSR server-only). The provider seeds every locale into
35
+ * the RSC-worker Translator (free on the server, never shipped to the browser) and serializes only
36
+ * the request's active locale to the client, so translations resolve regardless of locale routing.
37
+ */
38
+ allDictionary?: Record<string, Record<string, Record<string, unknown>>>;
33
39
  /** Root route component used by CSR page loading. */
34
40
  of: (props: unknown) => ReactNode | null;
35
41
  }
@@ -3,13 +3,13 @@ import { type ReactNode } from "react";
3
3
  import { type ProviderProps } from "./Common.d.ts";
4
4
  export declare const SSR: {
5
5
  (): import("react/jsx-runtime").JSX.Element;
6
- Provider: ({ className, appName, params, head, manifest, env, gaTrackingId, children, theme, prefix, fonts, layoutStyle, reconnect, dictionary, of, }: SSRProviderProps) => import("react/jsx-runtime").JSX.Element;
6
+ Provider: ({ className, appName, params, head, manifest, env, gaTrackingId, children, theme, prefix, fonts, layoutStyle, reconnect, dictionary, allDictionary, of, }: SSRProviderProps) => import("react/jsx-runtime").JSX.Element;
7
7
  Wrapper: ({ children, head, manifest, fonts, className, prefix, layoutStyle, }: SSRWrapperProps) => import("react/jsx-runtime").JSX.Element;
8
8
  };
9
9
  export type SSRProviderProps = ProviderProps & {
10
10
  fonts?: ReactFont[];
11
11
  };
12
- declare const SSRProvider: ({ className, appName, params, head, manifest, env, gaTrackingId, children, theme, prefix, fonts, layoutStyle, reconnect, dictionary, of, }: SSRProviderProps) => import("react/jsx-runtime").JSX.Element;
12
+ declare const SSRProvider: ({ className, appName, params, head, manifest, env, gaTrackingId, children, theme, prefix, fonts, layoutStyle, reconnect, dictionary, allDictionary, of, }: SSRProviderProps) => import("react/jsx-runtime").JSX.Element;
13
13
  interface SSRWrapperProps {
14
14
  className?: string;
15
15
  appName: string;
@@ -32,6 +32,12 @@ export interface ProviderProps {
32
32
  reconnect?: boolean;
33
33
  /** Active-locale dictionary injected by the server (SSR only) to seed the client Translator. */
34
34
  dictionary?: Record<string, Record<string, unknown>>;
35
+ /**
36
+ * Full lang-keyed dictionary snapshot (SSR server-only). The provider seeds every locale into
37
+ * the RSC-worker Translator (free on the server, never shipped to the browser) and serializes only
38
+ * the request's active locale to the client, so translations resolve regardless of locale routing.
39
+ */
40
+ allDictionary?: Record<string, Record<string, Record<string, unknown>>>;
35
41
  /** Root route component used by CSR page loading. */
36
42
  of: (props: unknown) => ReactNode | null;
37
43
  }
@@ -57,10 +63,7 @@ export function toManifestJson(value: unknown): unknown {
57
63
  return Object.fromEntries(
58
64
  Object.entries(value)
59
65
  .filter(([, entryValue]) => entryValue !== undefined)
60
- .map(([key, entryValue]) => [
61
- camelToSnake(key),
62
- toManifestJson(entryValue),
63
- ]),
66
+ .map(([key, entryValue]) => [camelToSnake(key), toManifestJson(entryValue)]),
64
67
  );
65
68
  }
66
69
 
package/ui/System/SSR.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import { getEnv } from "akanjs/base";
2
- import { clsx, type ReactFont, router, Translator, type WebAppManifest } from "akanjs/client";
2
+ import { clsx, type ReactFont, router, Translator, usePage, type WebAppManifest } from "akanjs/client";
3
3
  import { setRequestTheme } from "akanjs/fetch";
4
4
  import { Children, Fragment, type ReactNode, Suspense } from "react";
5
5
  import { FontCss } from "../fontCss";
@@ -30,17 +30,23 @@ const SSRProvider = ({
30
30
  layoutStyle = "web",
31
31
  reconnect = getEnv().operationMode === "local",
32
32
  dictionary,
33
+ allDictionary,
33
34
  of,
34
35
  }: SSRProviderProps) => {
35
36
  setRequestTheme(theme);
36
- if (dictionary && params.lang) Translator.seed(params.lang, dictionary);
37
+
38
+ const { lang: activeLocale } = usePage();
39
+
40
+ if (allDictionary) for (const [lng, dict] of Object.entries(allDictionary)) Translator.seed(lng, dict);
41
+
42
+ const activeDictionary = allDictionary?.[activeLocale] ?? dictionary;
43
+
37
44
  return (
38
45
  <Load.Page
39
46
  of={of}
40
47
  loader={async () => {
41
- const { lang } = params;
42
- if (!router.isInitialized) router.init({ type: "ssr", side: "server", lang, prefix });
43
- return { lang } as const;
48
+ if (!router.isInitialized) router.init({ type: "ssr", side: "server", lang: activeLocale, prefix });
49
+ return { lang: activeLocale } as const;
44
50
  }}
45
51
  render={({ lang }) => (
46
52
  <SSRWrapper
@@ -53,7 +59,7 @@ const SSRProvider = ({
53
59
  prefix={prefix}
54
60
  layoutStyle={layoutStyle}
55
61
  >
56
- <ClientWrapper theme={theme} lang={lang} reconnect={reconnect} dictionary={dictionary}>
62
+ <ClientWrapper theme={theme} lang={lang} reconnect={reconnect} dictionary={activeDictionary}>
57
63
  <Fragment key="children">{Children.toArray(children)}</Fragment>
58
64
  <Suspense key="client-inner" fallback={null}>
59
65
  <ClientInner />