@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.7",
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": "workspace:*",
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": "workspace:*",
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
- function buildI18nValue(locale, messages, defaultLocale) {
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 = createI18n(locale, localeMessages, fallback);
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 [...layoutMap.entries()].map(([id, entry]) => {
9
- // i18n: render once per locale, return localeHtml map
10
- if (ctx.i18n) {
11
- const localeHtml = {};
12
- let collectedKeys = null;
13
- for (const locale of ctx.i18n.locales) {
14
- const i18nValue = buildI18nValue(locale, ctx.i18n.messages, ctx.i18n.default);
15
- const messagesJson = JSON.stringify(ctx.i18n.messages?.[locale] || {});
16
- const compHash = ctx.componentHashes.get(entry.component?.name);
17
- if (compHash) {
18
- const config = { id, loaders: entry.loaders, mock: entry.mock };
19
- const key = computeCacheKey(
20
- compHash,
21
- ctx.manifestContent,
22
- config,
23
- ctx.scriptHash,
24
- locale,
25
- messagesJson,
26
- );
27
- const slug = `layout_${id}_${locale}`;
28
- const cached = readCache(ctx.cacheDir, slug);
29
- if (cached && cached.key === key) {
30
- ctx.stats.hits++;
31
- localeHtml[locale] = cached.data.html;
32
- if (!collectedKeys) collectedKeys = cached.data.i18nKeys;
33
- continue;
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
- // No i18n: original behavior
73
- const compHash = ctx.componentHashes.get(entry.component?.name);
74
- if (compHash) {
75
- const config = { id, loaders: entry.loaders, mock: entry.mock };
76
- const key = computeCacheKey(compHash, ctx.manifestContent, config, ctx.scriptHash);
77
- const slug = `layout_${id}`;
78
- const cached = readCache(ctx.cacheDir, slug);
79
- if (cached && cached.key === key) {
80
- ctx.stats.hits++;
81
- return cached.data;
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
- const data = {
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
- writeCache(ctx.cacheDir, slug, key, data);
90
- ctx.stats.misses++;
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 flat.map((r) => {
105
- // i18n: render once per locale, return localeVariants map
106
- if (ctx.i18n) {
107
- const localeVariants = {};
108
- let collectedKeys = null;
109
- for (const locale of ctx.i18n.locales) {
110
- const i18nValue = buildI18nValue(locale, ctx.i18n.messages, ctx.i18n.default);
111
- const messagesJson = JSON.stringify(ctx.i18n.messages?.[locale] || {});
112
- const compHash = ctx.componentHashes.get(r.component?.name);
113
- if (compHash) {
114
- const config = { path: r.path, loaders: r.loaders, mock: r.mock, nullable: r.nullable };
115
- const key = computeCacheKey(
116
- compHash,
117
- ctx.manifestContent,
118
- config,
119
- ctx.scriptHash,
120
- locale,
121
- messagesJson,
122
- );
123
- const slug = `route_${pathToSlug(r.path)}_${locale}`;
124
- const cached = readCache(ctx.cacheDir, slug);
125
- if (cached && cached.key === key) {
126
- ctx.stats.hits++;
127
- localeVariants[locale] = cached.data;
128
- if (!collectedKeys) collectedKeys = cached.data.i18nKeys;
129
- continue;
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
- // No i18n: original behavior
164
- const compHash = ctx.componentHashes.get(r.component?.name);
165
- if (compHash) {
166
- const config = { path: r.path, loaders: r.loaders, mock: r.mock, nullable: r.nullable };
167
- const key = computeCacheKey(compHash, ctx.manifestContent, config, ctx.scriptHash);
168
- const slug = `route_${pathToSlug(r.path)}`;
169
- const cached = readCache(ctx.cacheDir, slug);
170
- if (cached && cached.key === key) {
171
- ctx.stats.hits++;
172
- return cached.data;
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 data;
178
- }
179
- ctx.stats.misses++;
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 };