@canmi/seam-react 0.3.7 → 0.4.4
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canmi/seam-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist",
|
|
6
6
|
"scripts"
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
"test": "vitest run"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@canmi/seam-client": "
|
|
21
|
-
"@canmi/seam-i18n": "workspace:*",
|
|
20
|
+
"@canmi/seam-client": "0.4.4",
|
|
22
21
|
"esbuild": "^0.25.0"
|
|
23
22
|
},
|
|
24
23
|
"devDependencies": {
|
|
25
|
-
"@canmi/seam-engine": "
|
|
24
|
+
"@canmi/seam-engine": "0.4.4",
|
|
25
|
+
"@canmi/seam-i18n": "0.4.4",
|
|
26
26
|
"@types/react": "^19.0.0",
|
|
27
27
|
"@types/react-dom": "^19.0.0",
|
|
28
28
|
"jsdom": "^28.1.0",
|
|
@@ -126,8 +126,8 @@ async function main() {
|
|
|
126
126
|
stats: { hits: 0, misses: 0 },
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
-
const layouts = processLayoutsWithCache(layoutMap, ctx);
|
|
130
|
-
const renderedRoutes = processRoutesWithCache(flat, ctx);
|
|
129
|
+
const layouts = await processLayoutsWithCache(layoutMap, ctx);
|
|
130
|
+
const renderedRoutes = await processRoutesWithCache(flat, ctx);
|
|
131
131
|
|
|
132
132
|
const output = {
|
|
133
133
|
layouts,
|
|
@@ -4,7 +4,6 @@ import { build } from "esbuild";
|
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { join } from "node:path";
|
|
7
|
-
import { createI18n } from "@canmi/seam-i18n";
|
|
8
7
|
|
|
9
8
|
/** Parse import statements to map local names to specifiers */
|
|
10
9
|
function parseComponentImports(source) {
|
|
@@ -106,11 +105,16 @@ function computeCacheKey(componentHash, manifestContent, config, scriptHash, loc
|
|
|
106
105
|
return h.digest("hex").slice(0, 16);
|
|
107
106
|
}
|
|
108
107
|
|
|
109
|
-
|
|
108
|
+
let _createI18n = null;
|
|
109
|
+
async function buildI18nValue(locale, messages, defaultLocale) {
|
|
110
|
+
if (!_createI18n) {
|
|
111
|
+
const mod = await import("@canmi/seam-i18n");
|
|
112
|
+
_createI18n = mod.createI18n;
|
|
113
|
+
}
|
|
110
114
|
const localeMessages = messages?.[locale] || {};
|
|
111
115
|
const fallback =
|
|
112
116
|
defaultLocale && locale !== defaultLocale ? messages?.[defaultLocale] || {} : undefined;
|
|
113
|
-
const instance =
|
|
117
|
+
const instance = _createI18n(locale, localeMessages, fallback);
|
|
114
118
|
const usedKeys = new Set();
|
|
115
119
|
const origT = instance.t;
|
|
116
120
|
return {
|
|
@@ -4,181 +4,185 @@ import { buildI18nValue, computeCacheKey, pathToSlug, readCache, writeCache } fr
|
|
|
4
4
|
import { renderLayout } from "./layout.mjs";
|
|
5
5
|
import { renderRoute } from "./schema.mjs";
|
|
6
6
|
|
|
7
|
-
function processLayoutsWithCache(layoutMap, ctx) {
|
|
8
|
-
return
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
7
|
+
async function processLayoutsWithCache(layoutMap, ctx) {
|
|
8
|
+
return Promise.all(
|
|
9
|
+
[...layoutMap.entries()].map(async ([id, entry]) => {
|
|
10
|
+
// i18n: render once per locale, return localeHtml map
|
|
11
|
+
if (ctx.i18n) {
|
|
12
|
+
const localeHtml = {};
|
|
13
|
+
let collectedKeys = null;
|
|
14
|
+
for (const locale of ctx.i18n.locales) {
|
|
15
|
+
const i18nValue = await buildI18nValue(locale, ctx.i18n.messages, ctx.i18n.default);
|
|
16
|
+
const messagesJson = JSON.stringify(ctx.i18n.messages?.[locale] || {});
|
|
17
|
+
const compHash = ctx.componentHashes.get(entry.component?.name);
|
|
18
|
+
if (compHash) {
|
|
19
|
+
const config = { id, loaders: entry.loaders, mock: entry.mock };
|
|
20
|
+
const key = computeCacheKey(
|
|
21
|
+
compHash,
|
|
22
|
+
ctx.manifestContent,
|
|
23
|
+
config,
|
|
24
|
+
ctx.scriptHash,
|
|
25
|
+
locale,
|
|
26
|
+
messagesJson,
|
|
27
|
+
);
|
|
28
|
+
const slug = `layout_${id}_${locale}`;
|
|
29
|
+
const cached = readCache(ctx.cacheDir, slug);
|
|
30
|
+
if (cached && cached.key === key) {
|
|
31
|
+
ctx.stats.hits++;
|
|
32
|
+
localeHtml[locale] = cached.data.html;
|
|
33
|
+
if (!collectedKeys) collectedKeys = cached.data.i18nKeys;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const html = renderLayout(
|
|
37
|
+
entry.component,
|
|
38
|
+
id,
|
|
39
|
+
entry,
|
|
40
|
+
ctx.manifest,
|
|
41
|
+
i18nValue,
|
|
42
|
+
ctx.warnCtx,
|
|
43
|
+
);
|
|
44
|
+
const i18nKeys = [...i18nValue._usedKeys].sort();
|
|
45
|
+
writeCache(ctx.cacheDir, slug, key, { html, i18nKeys });
|
|
46
|
+
ctx.stats.misses++;
|
|
47
|
+
localeHtml[locale] = html;
|
|
48
|
+
if (!collectedKeys) collectedKeys = i18nKeys;
|
|
49
|
+
} else {
|
|
50
|
+
ctx.stats.misses++;
|
|
51
|
+
const html = renderLayout(
|
|
52
|
+
entry.component,
|
|
53
|
+
id,
|
|
54
|
+
entry,
|
|
55
|
+
ctx.manifest,
|
|
56
|
+
i18nValue,
|
|
57
|
+
ctx.warnCtx,
|
|
58
|
+
);
|
|
59
|
+
const i18nKeys = [...i18nValue._usedKeys].sort();
|
|
60
|
+
localeHtml[locale] = html;
|
|
61
|
+
if (!collectedKeys) collectedKeys = i18nKeys;
|
|
34
62
|
}
|
|
35
|
-
const html = renderLayout(
|
|
36
|
-
entry.component,
|
|
37
|
-
id,
|
|
38
|
-
entry,
|
|
39
|
-
ctx.manifest,
|
|
40
|
-
i18nValue,
|
|
41
|
-
ctx.warnCtx,
|
|
42
|
-
);
|
|
43
|
-
const i18nKeys = [...i18nValue._usedKeys].sort();
|
|
44
|
-
writeCache(ctx.cacheDir, slug, key, { html, i18nKeys });
|
|
45
|
-
ctx.stats.misses++;
|
|
46
|
-
localeHtml[locale] = html;
|
|
47
|
-
if (!collectedKeys) collectedKeys = i18nKeys;
|
|
48
|
-
} else {
|
|
49
|
-
ctx.stats.misses++;
|
|
50
|
-
const html = renderLayout(
|
|
51
|
-
entry.component,
|
|
52
|
-
id,
|
|
53
|
-
entry,
|
|
54
|
-
ctx.manifest,
|
|
55
|
-
i18nValue,
|
|
56
|
-
ctx.warnCtx,
|
|
57
|
-
);
|
|
58
|
-
const i18nKeys = [...i18nValue._usedKeys].sort();
|
|
59
|
-
localeHtml[locale] = html;
|
|
60
|
-
if (!collectedKeys) collectedKeys = i18nKeys;
|
|
61
63
|
}
|
|
64
|
+
return {
|
|
65
|
+
id,
|
|
66
|
+
localeHtml,
|
|
67
|
+
loaders: entry.loaders,
|
|
68
|
+
parent: entry.parentId,
|
|
69
|
+
i18nKeys: collectedKeys || [],
|
|
70
|
+
};
|
|
62
71
|
}
|
|
63
|
-
return {
|
|
64
|
-
id,
|
|
65
|
-
localeHtml,
|
|
66
|
-
loaders: entry.loaders,
|
|
67
|
-
parent: entry.parentId,
|
|
68
|
-
i18nKeys: collectedKeys || [],
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
// No i18n: original behavior
|
|
74
|
+
const compHash = ctx.componentHashes.get(entry.component?.name);
|
|
75
|
+
if (compHash) {
|
|
76
|
+
const config = { id, loaders: entry.loaders, mock: entry.mock };
|
|
77
|
+
const key = computeCacheKey(compHash, ctx.manifestContent, config, ctx.scriptHash);
|
|
78
|
+
const slug = `layout_${id}`;
|
|
79
|
+
const cached = readCache(ctx.cacheDir, slug);
|
|
80
|
+
if (cached && cached.key === key) {
|
|
81
|
+
ctx.stats.hits++;
|
|
82
|
+
return cached.data;
|
|
83
|
+
}
|
|
84
|
+
const data = {
|
|
85
|
+
id,
|
|
86
|
+
html: renderLayout(entry.component, id, entry, ctx.manifest, undefined, ctx.warnCtx),
|
|
87
|
+
loaders: entry.loaders,
|
|
88
|
+
parent: entry.parentId,
|
|
89
|
+
};
|
|
90
|
+
writeCache(ctx.cacheDir, slug, key, data);
|
|
91
|
+
ctx.stats.misses++;
|
|
92
|
+
return data;
|
|
82
93
|
}
|
|
83
|
-
|
|
94
|
+
ctx.stats.misses++;
|
|
95
|
+
return {
|
|
84
96
|
id,
|
|
85
97
|
html: renderLayout(entry.component, id, entry, ctx.manifest, undefined, ctx.warnCtx),
|
|
86
98
|
loaders: entry.loaders,
|
|
87
99
|
parent: entry.parentId,
|
|
88
100
|
};
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return data;
|
|
92
|
-
}
|
|
93
|
-
ctx.stats.misses++;
|
|
94
|
-
return {
|
|
95
|
-
id,
|
|
96
|
-
html: renderLayout(entry.component, id, entry, ctx.manifest, undefined, ctx.warnCtx),
|
|
97
|
-
loaders: entry.loaders,
|
|
98
|
-
parent: entry.parentId,
|
|
99
|
-
};
|
|
100
|
-
});
|
|
101
|
+
}),
|
|
102
|
+
);
|
|
101
103
|
}
|
|
102
104
|
|
|
103
|
-
function processRoutesWithCache(flat, ctx) {
|
|
104
|
-
return
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
105
|
+
async function processRoutesWithCache(flat, ctx) {
|
|
106
|
+
return Promise.all(
|
|
107
|
+
flat.map(async (r) => {
|
|
108
|
+
// i18n: render once per locale, return localeVariants map
|
|
109
|
+
if (ctx.i18n) {
|
|
110
|
+
const localeVariants = {};
|
|
111
|
+
let collectedKeys = null;
|
|
112
|
+
for (const locale of ctx.i18n.locales) {
|
|
113
|
+
const i18nValue = await buildI18nValue(locale, ctx.i18n.messages, ctx.i18n.default);
|
|
114
|
+
const messagesJson = JSON.stringify(ctx.i18n.messages?.[locale] || {});
|
|
115
|
+
const compHash = ctx.componentHashes.get(r.component?.name);
|
|
116
|
+
if (compHash) {
|
|
117
|
+
const config = { path: r.path, loaders: r.loaders, mock: r.mock, nullable: r.nullable };
|
|
118
|
+
const key = computeCacheKey(
|
|
119
|
+
compHash,
|
|
120
|
+
ctx.manifestContent,
|
|
121
|
+
config,
|
|
122
|
+
ctx.scriptHash,
|
|
123
|
+
locale,
|
|
124
|
+
messagesJson,
|
|
125
|
+
);
|
|
126
|
+
const slug = `route_${pathToSlug(r.path)}_${locale}`;
|
|
127
|
+
const cached = readCache(ctx.cacheDir, slug);
|
|
128
|
+
if (cached && cached.key === key) {
|
|
129
|
+
ctx.stats.hits++;
|
|
130
|
+
localeVariants[locale] = cached.data;
|
|
131
|
+
if (!collectedKeys) collectedKeys = cached.data.i18nKeys;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const data = renderRoute(r, ctx.manifest, i18nValue, ctx.warnCtx);
|
|
135
|
+
data.i18nKeys = [...i18nValue._usedKeys].sort();
|
|
136
|
+
writeCache(ctx.cacheDir, slug, key, data);
|
|
137
|
+
ctx.stats.misses++;
|
|
138
|
+
localeVariants[locale] = data;
|
|
139
|
+
if (!collectedKeys) collectedKeys = data.i18nKeys;
|
|
140
|
+
} else {
|
|
141
|
+
ctx.stats.misses++;
|
|
142
|
+
const data = renderRoute(r, ctx.manifest, i18nValue, ctx.warnCtx);
|
|
143
|
+
data.i18nKeys = [...i18nValue._usedKeys].sort();
|
|
144
|
+
localeVariants[locale] = data;
|
|
145
|
+
if (!collectedKeys) collectedKeys = data.i18nKeys;
|
|
130
146
|
}
|
|
131
|
-
const data = renderRoute(r, ctx.manifest, i18nValue, ctx.warnCtx);
|
|
132
|
-
data.i18nKeys = [...i18nValue._usedKeys].sort();
|
|
133
|
-
writeCache(ctx.cacheDir, slug, key, data);
|
|
134
|
-
ctx.stats.misses++;
|
|
135
|
-
localeVariants[locale] = data;
|
|
136
|
-
if (!collectedKeys) collectedKeys = data.i18nKeys;
|
|
137
|
-
} else {
|
|
138
|
-
ctx.stats.misses++;
|
|
139
|
-
const data = renderRoute(r, ctx.manifest, i18nValue, ctx.warnCtx);
|
|
140
|
-
data.i18nKeys = [...i18nValue._usedKeys].sort();
|
|
141
|
-
localeVariants[locale] = data;
|
|
142
|
-
if (!collectedKeys) collectedKeys = data.i18nKeys;
|
|
143
147
|
}
|
|
148
|
+
// Combine per-locale data into the expected output format
|
|
149
|
+
const first = localeVariants[ctx.i18n.locales[0]];
|
|
150
|
+
return {
|
|
151
|
+
path: r.path,
|
|
152
|
+
loaders: first.loaders,
|
|
153
|
+
layout: first.layout,
|
|
154
|
+
mock: first.mock,
|
|
155
|
+
pageSchema: first.pageSchema,
|
|
156
|
+
i18nKeys: collectedKeys || [],
|
|
157
|
+
localeVariants: Object.fromEntries(
|
|
158
|
+
Object.entries(localeVariants).map(([loc, data]) => [
|
|
159
|
+
loc,
|
|
160
|
+
{ axes: data.axes, variants: data.variants, mockHtml: data.mockHtml },
|
|
161
|
+
]),
|
|
162
|
+
),
|
|
163
|
+
};
|
|
144
164
|
}
|
|
145
|
-
// Combine per-locale data into the expected output format
|
|
146
|
-
const first = localeVariants[ctx.i18n.locales[0]];
|
|
147
|
-
return {
|
|
148
|
-
path: r.path,
|
|
149
|
-
loaders: first.loaders,
|
|
150
|
-
layout: first.layout,
|
|
151
|
-
mock: first.mock,
|
|
152
|
-
pageSchema: first.pageSchema,
|
|
153
|
-
i18nKeys: collectedKeys || [],
|
|
154
|
-
localeVariants: Object.fromEntries(
|
|
155
|
-
Object.entries(localeVariants).map(([loc, data]) => [
|
|
156
|
-
loc,
|
|
157
|
-
{ axes: data.axes, variants: data.variants, mockHtml: data.mockHtml },
|
|
158
|
-
]),
|
|
159
|
-
),
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
165
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
166
|
+
// No i18n: original behavior
|
|
167
|
+
const compHash = ctx.componentHashes.get(r.component?.name);
|
|
168
|
+
if (compHash) {
|
|
169
|
+
const config = { path: r.path, loaders: r.loaders, mock: r.mock, nullable: r.nullable };
|
|
170
|
+
const key = computeCacheKey(compHash, ctx.manifestContent, config, ctx.scriptHash);
|
|
171
|
+
const slug = `route_${pathToSlug(r.path)}`;
|
|
172
|
+
const cached = readCache(ctx.cacheDir, slug);
|
|
173
|
+
if (cached && cached.key === key) {
|
|
174
|
+
ctx.stats.hits++;
|
|
175
|
+
return cached.data;
|
|
176
|
+
}
|
|
177
|
+
const data = renderRoute(r, ctx.manifest, undefined, ctx.warnCtx);
|
|
178
|
+
writeCache(ctx.cacheDir, slug, key, data);
|
|
179
|
+
ctx.stats.misses++;
|
|
180
|
+
return data;
|
|
173
181
|
}
|
|
174
|
-
const data = renderRoute(r, ctx.manifest, undefined, ctx.warnCtx);
|
|
175
|
-
writeCache(ctx.cacheDir, slug, key, data);
|
|
176
182
|
ctx.stats.misses++;
|
|
177
|
-
return
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return renderRoute(r, ctx.manifest, undefined, ctx.warnCtx);
|
|
181
|
-
});
|
|
183
|
+
return renderRoute(r, ctx.manifest, undefined, ctx.warnCtx);
|
|
184
|
+
}),
|
|
185
|
+
);
|
|
182
186
|
}
|
|
183
187
|
|
|
184
188
|
export { processLayoutsWithCache, processRoutesWithCache };
|