@akanjs/devkit 2.2.0-rc.4 → 2.2.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.
|
@@ -73,9 +73,15 @@ describe("resolveSsrPageEntries", () => {
|
|
|
73
73
|
const generatedSource = await Bun.file(groupedRoot?.moduleAbsPath ?? "").text();
|
|
74
74
|
expect(generatedSource).toContain("<System.Provider");
|
|
75
75
|
expect(generatedSource).toContain("theme={userLayout.theme ?? inheritedLayout.theme}");
|
|
76
|
-
expect(generatedSource).toContain(
|
|
77
|
-
expect(generatedSource).toContain(
|
|
78
|
-
expect(generatedSource).toContain("
|
|
76
|
+
expect(generatedSource).toContain('import { allDictionary } from "../dict/useDict.ts";');
|
|
77
|
+
expect(generatedSource).toContain("dictionary={allDictionary[params.lang]}");
|
|
78
|
+
expect(generatedSource).not.toContain("getAllDictionary");
|
|
79
79
|
expect(generatedSource).not.toContain("// export default function GeneratedLayout");
|
|
80
|
+
|
|
81
|
+
const generatedDictMacro = await Bun.file(path.join(appRoot, ".akan", "generated", "dict", "useDict.ts")).text();
|
|
82
|
+
expect(generatedDictMacro).toContain(
|
|
83
|
+
'import { getAllDictionary } from "@apps/demo/lib/dict" with { type: "macro" };',
|
|
84
|
+
);
|
|
85
|
+
expect(generatedDictMacro).toContain("export const allDictionary = getAllDictionary();");
|
|
80
86
|
});
|
|
81
87
|
});
|
|
@@ -15,6 +15,7 @@ async function appHasStModule(appCwdPath: string): Promise<boolean> {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const IMPLICIT_LAYOUT_DIR = path.join(".akan", "generated", "root-layouts");
|
|
18
|
+
const IMPLICIT_DICT_DIR = path.join(".akan", "generated", "dict");
|
|
18
19
|
|
|
19
20
|
interface RootBoundary {
|
|
20
21
|
sourceKey: string | null;
|
|
@@ -39,6 +40,10 @@ function implicitRootLayoutAbsPath(appCwdPath: string, segments: string[]): stri
|
|
|
39
40
|
return path.join(path.resolve(appCwdPath), IMPLICIT_LAYOUT_DIR, filename);
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
function implicitDictionaryMacroAbsPath(appCwdPath: string): string {
|
|
44
|
+
return path.join(path.resolve(appCwdPath), IMPLICIT_DICT_DIR, "useDict.ts");
|
|
45
|
+
}
|
|
46
|
+
|
|
42
47
|
function isRootBoundarySegments(segments: string[], basePaths: Iterable<string>): boolean {
|
|
43
48
|
const firstVisibleIndex = segments.findIndex((segment) => !/^\(.+\)$/.test(segment));
|
|
44
49
|
if (firstVisibleIndex === -1) return segments.length <= 1;
|
|
@@ -99,6 +104,19 @@ async function assertEnvClientConvention(appCwdPath: string, appName: string) {
|
|
|
99
104
|
}
|
|
100
105
|
}
|
|
101
106
|
|
|
107
|
+
async function writeGeneratedDictionaryMacroFile(appCwdPath: string, appName: string): Promise<string> {
|
|
108
|
+
const absPath = implicitDictionaryMacroAbsPath(appCwdPath);
|
|
109
|
+
await mkdir(path.dirname(absPath), { recursive: true });
|
|
110
|
+
await Bun.write(
|
|
111
|
+
absPath,
|
|
112
|
+
`import { getAllDictionary } from "@apps/${appName}/lib/dict" with { type: "macro" };
|
|
113
|
+
|
|
114
|
+
export const allDictionary = getAllDictionary();
|
|
115
|
+
`,
|
|
116
|
+
);
|
|
117
|
+
return absPath;
|
|
118
|
+
}
|
|
119
|
+
|
|
102
120
|
async function writeGeneratedRootLayoutFile(opts: {
|
|
103
121
|
appCwdPath: string;
|
|
104
122
|
appName: string;
|
|
@@ -108,8 +126,15 @@ async function writeGeneratedRootLayoutFile(opts: {
|
|
|
108
126
|
includeSystemProvider: boolean;
|
|
109
127
|
}): Promise<string> {
|
|
110
128
|
await assertEnvClientConvention(opts.appCwdPath, opts.appName);
|
|
129
|
+
const dictMacroAbsPath = opts.includeSystemProvider
|
|
130
|
+
? await writeGeneratedDictionaryMacroFile(opts.appCwdPath, opts.appName)
|
|
131
|
+
: null;
|
|
111
132
|
const absPath = implicitRootLayoutAbsPath(opts.appCwdPath, opts.boundary.segments);
|
|
112
133
|
await mkdir(path.dirname(absPath), { recursive: true });
|
|
134
|
+
const dictMacroRel = dictMacroAbsPath
|
|
135
|
+
? path.relative(path.dirname(absPath), dictMacroAbsPath).split(path.sep).join("/")
|
|
136
|
+
: null;
|
|
137
|
+
const dictMacroSpecifier = dictMacroRel ? (dictMacroRel.startsWith(".") ? dictMacroRel : `./${dictMacroRel}`) : null;
|
|
113
138
|
const sourceRel = opts.boundary.sourceAbsPath
|
|
114
139
|
? path.relative(path.dirname(absPath), opts.boundary.sourceAbsPath).split(path.sep).join("/")
|
|
115
140
|
: null;
|
|
@@ -139,12 +164,8 @@ async function writeGeneratedRootLayoutFile(opts: {
|
|
|
139
164
|
import { loadFonts } from "akanjs/client";
|
|
140
165
|
import { System } from "akanjs/ui";
|
|
141
166
|
import { env } from "@apps/${opts.appName}/env/env.client";
|
|
167
|
+
import { allDictionary } from ${JSON.stringify(dictMacroSpecifier)};
|
|
142
168
|
${clientImport}${inheritedImport}${userImport}
|
|
143
|
-
// SSR builds (target=bun) load the full dictionary server-side and pass only the active locale to the client.
|
|
144
|
-
// CSR builds (target=browser) fold this branch to undefined, so the macro-seeded dictionary is used and the
|
|
145
|
-
// server-only dict module (which pulls @libs/*/server) is dead-code-eliminated out of the browser bundle.
|
|
146
|
-
const getActiveLocaleDictionary =
|
|
147
|
-
process.env.AKAN_PUBLIC_RENDER_ENV === "ssr" ? (await import("@apps/${opts.appName}/lib/dict")).getDictionary : undefined;
|
|
148
169
|
const userFonts = userLayout.fonts ?? inheritedLayout.fonts ?? [];
|
|
149
170
|
const defaultFonts = userFonts.filter((font) => font.default);
|
|
150
171
|
if (defaultFonts.length > 1) throw new Error("[route-convention] only one default font is allowed per root layout");
|
|
@@ -175,7 +196,7 @@ export default function GeneratedLayout({ children, params, searchParams }: Layo
|
|
|
175
196
|
gaTrackingId={userLayout.gaTrackingId ?? inheritedLayout.gaTrackingId}
|
|
176
197
|
layoutStyle={userLayout.layoutStyle ?? inheritedLayout.layoutStyle}
|
|
177
198
|
reconnect={userLayout.reconnect ?? inheritedLayout.reconnect ?? false}
|
|
178
|
-
dictionary={
|
|
199
|
+
dictionary={allDictionary[params.lang]}
|
|
179
200
|
>
|
|
180
201
|
<UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>
|
|
181
202
|
</System.Provider>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/devkit",
|
|
3
|
-
"version": "2.2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@langchain/openai": "^1.4.6",
|
|
33
33
|
"@tailwindcss/node": "^4.3.0",
|
|
34
34
|
"@trapezedev/project": "^7.1.4",
|
|
35
|
-
"akanjs": "2.2.0
|
|
35
|
+
"akanjs": "2.2.0",
|
|
36
36
|
"chalk": "^5.6.2",
|
|
37
37
|
"commander": "^14.0.3",
|
|
38
38
|
"daisyui": "^5.5.20",
|