@astroscope/i18n 0.2.0 → 0.2.1
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/README.md +2 -0
- package/dist/{chunk-FAKBSLNW.js → chunk-7MSGHEST.js} +14 -7
- package/dist/{chunk-JJEDOJBR.js → chunk-EO4FUQXR.js} +49 -18
- package/dist/{chunk-QFAAGCP5.js → chunk-RHWEV4L2.js} +58 -1
- package/dist/client/directives/idle.d.ts +4 -1
- package/dist/client/directives/idle.js +13 -6
- package/dist/client/directives/load.d.ts +4 -1
- package/dist/client/directives/load.js +6 -6
- package/dist/client/directives/media.d.ts +4 -1
- package/dist/client/directives/media.js +16 -6
- package/dist/client/directives/only.d.ts +6 -1
- package/dist/client/directives/only.js +6 -6
- package/dist/client/directives/utils.d.ts +6 -5
- package/dist/client/directives/utils.js +3 -3
- package/dist/client/directives/visible.d.ts +4 -1
- package/dist/client/directives/visible.js +23 -6
- package/dist/client/t.d.ts +2 -2
- package/dist/extraction/index.d.ts +3 -3
- package/dist/extraction/index.js +1 -1
- package/dist/{i18n-BGfrSNM8.d.ts → i18n-mTHTcD8K.d.ts} +9 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/internal.d.ts +4 -4
- package/dist/internal.js +1 -1
- package/dist/server/t.d.ts +1 -1
- package/dist/server/t.js +1 -1
- package/dist/{types-B_-RxW4A.d.ts → types-BeDFfFIL.d.ts} +1 -1
- package/dist/{types-Bzp6KxsI.d.ts → types-DNRFj1XA.d.ts} +1 -0
- package/dist/{types-8uKCwFda.d.ts → types-DTUho6gi.d.ts} +7 -1
- package/package.json +2 -2
- package/src/components/I18nScript.astro +2 -23
package/README.md
CHANGED
|
@@ -4,21 +4,28 @@ import {
|
|
|
4
4
|
} from "./chunk-4A5BKHFN.js";
|
|
5
5
|
|
|
6
6
|
// src/client/directives/utils.ts
|
|
7
|
-
|
|
8
|
-
const componentUrl = el.getAttribute("component-url");
|
|
9
|
-
if (!componentUrl) return;
|
|
10
|
-
const chunkName = componentUrlToChunkName(componentUrl);
|
|
11
|
-
const i18n = window.__i18n__;
|
|
7
|
+
function prefetchTranslation(chunkName, i18n) {
|
|
12
8
|
const hash = i18n.hashes[chunkName];
|
|
13
9
|
if (hash) {
|
|
14
10
|
const url = buildI18nChunkUrl(i18n.locale, chunkName, hash);
|
|
15
|
-
|
|
11
|
+
import(
|
|
16
12
|
/* @vite-ignore */
|
|
17
13
|
url
|
|
18
14
|
);
|
|
19
15
|
}
|
|
20
16
|
}
|
|
17
|
+
function warmUpI18nForChunk(el) {
|
|
18
|
+
const componentUrl = el.getAttribute("component-url");
|
|
19
|
+
if (!componentUrl) return;
|
|
20
|
+
const chunkName = componentUrlToChunkName(componentUrl);
|
|
21
|
+
const i18n = window.__i18n__;
|
|
22
|
+
prefetchTranslation(chunkName, i18n);
|
|
23
|
+
const deps = i18n.imports[chunkName] ?? [];
|
|
24
|
+
for (const dep of deps) {
|
|
25
|
+
prefetchTranslation(dep, i18n);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
21
28
|
|
|
22
29
|
export {
|
|
23
|
-
|
|
30
|
+
warmUpI18nForChunk
|
|
24
31
|
};
|
|
@@ -11,6 +11,7 @@ function getGlobalState() {
|
|
|
11
11
|
g[I18N_MANIFEST_GLOBAL_KEY] = {
|
|
12
12
|
extractedKeys: [],
|
|
13
13
|
chunkManifest: {},
|
|
14
|
+
importsManifest: {},
|
|
14
15
|
projectRoot: ""
|
|
15
16
|
};
|
|
16
17
|
}
|
|
@@ -24,7 +25,7 @@ function getManifest() {
|
|
|
24
25
|
// and avoiding leaking absolute paths from dev or ci environments
|
|
25
26
|
file: state.projectRoot ? path.relative(state.projectRoot, key.file) : key.file
|
|
26
27
|
}));
|
|
27
|
-
return { keys, chunks: state.chunkManifest };
|
|
28
|
+
return { keys, chunks: state.chunkManifest, imports: state.importsManifest };
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
// src/extraction/vite-plugin.ts
|
|
@@ -135,6 +136,10 @@ export function getManifest() { return _getManifest(); }
|
|
|
135
136
|
generateBundle(_, bundle) {
|
|
136
137
|
const state = getGlobalState();
|
|
137
138
|
state.chunkManifest = {};
|
|
139
|
+
state.importsManifest = {};
|
|
140
|
+
const chunksWithI18n = /* @__PURE__ */ new Set();
|
|
141
|
+
const chunkNameToFileName = /* @__PURE__ */ new Map();
|
|
142
|
+
const directImports = /* @__PURE__ */ new Map();
|
|
138
143
|
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
139
144
|
if (chunk.type === "chunk" && chunk.moduleIds) {
|
|
140
145
|
const keys = /* @__PURE__ */ new Set();
|
|
@@ -151,24 +156,50 @@ export function getManifest() { return _getManifest(); }
|
|
|
151
156
|
state.chunkManifest[chunkName] = Array.from(keys);
|
|
152
157
|
}
|
|
153
158
|
if (hasI18nModule) {
|
|
154
|
-
|
|
155
|
-
/* @astroscope/i18n loader */
|
|
156
|
-
if (typeof window !== 'undefined' && window.__i18n__) {
|
|
157
|
-
const __i18n__ = window.__i18n__;
|
|
158
|
-
const __i18n_hash__ = __i18n__.hashes[${JSON.stringify(chunkName)}];
|
|
159
|
-
if (__i18n_hash__) {
|
|
160
|
-
await import(\`/_i18n/\${__i18n__.locale}/${chunkName}.\${__i18n_hash__}.js\`);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
/* end @astroscope/i18n loader */
|
|
164
|
-
`;
|
|
165
|
-
const s = new MagicString(chunk.code);
|
|
166
|
-
s.prepend(loaderCode);
|
|
167
|
-
chunk.code = s.toString();
|
|
168
|
-
if (chunk.map) {
|
|
169
|
-
chunk.map = s.generateMap({ hires: true });
|
|
170
|
-
}
|
|
159
|
+
chunksWithI18n.add(chunkName);
|
|
171
160
|
}
|
|
161
|
+
chunkNameToFileName.set(chunkName, fileName);
|
|
162
|
+
const imports = [];
|
|
163
|
+
for (const importedFile of chunk.imports) {
|
|
164
|
+
const baseName = importedFile.replace(/^.*\//, "").replace(/\.js$/, "");
|
|
165
|
+
const importedChunkName = chunkIdToName(baseName);
|
|
166
|
+
imports.push(importedChunkName);
|
|
167
|
+
}
|
|
168
|
+
directImports.set(chunkName, imports);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const flattenImports = (chunkName, visited) => {
|
|
172
|
+
if (visited.has(chunkName)) return [];
|
|
173
|
+
visited.add(chunkName);
|
|
174
|
+
const result = /* @__PURE__ */ new Set();
|
|
175
|
+
const imports = directImports.get(chunkName) ?? [];
|
|
176
|
+
for (const imported of imports) {
|
|
177
|
+
if (state.chunkManifest[imported]) {
|
|
178
|
+
result.add(imported);
|
|
179
|
+
}
|
|
180
|
+
for (const descendant of flattenImports(imported, visited)) {
|
|
181
|
+
result.add(descendant);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
visited.delete(chunkName);
|
|
185
|
+
return Array.from(result);
|
|
186
|
+
};
|
|
187
|
+
for (const chunkName of directImports.keys()) {
|
|
188
|
+
const flattened = flattenImports(chunkName, /* @__PURE__ */ new Set());
|
|
189
|
+
if (flattened.length > 0) {
|
|
190
|
+
state.importsManifest[chunkName] = flattened;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
194
|
+
if (chunk.type !== "chunk") continue;
|
|
195
|
+
const chunkName = chunkIdToName(fileName.replace(/\.js$/, ""));
|
|
196
|
+
if (!chunksWithI18n.has(chunkName)) continue;
|
|
197
|
+
const loaderCode = `if(typeof window!=='undefined'&&window.__i18n__){const _=window.__i18n__,h=_.hashes[${JSON.stringify(chunkName)}];if(h)await import(\`/_i18n/\${_.locale}/${chunkName}.\${h}.js\`);}`;
|
|
198
|
+
const s = new MagicString(chunk.code);
|
|
199
|
+
s.prepend(loaderCode);
|
|
200
|
+
chunk.code = s.toString();
|
|
201
|
+
if (chunk.map) {
|
|
202
|
+
chunk.map = s.generateMap({ hires: true });
|
|
172
203
|
}
|
|
173
204
|
}
|
|
174
205
|
logger.info(`manifest: ${Object.keys(state.chunkManifest).length} chunks, ${extractedKeys.length} keys`);
|
|
@@ -24,6 +24,21 @@ function computeAllChunkHashes(translations, manifest) {
|
|
|
24
24
|
return hashes;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
// src/server/utils.ts
|
|
28
|
+
var LOWERCASE_A = 97;
|
|
29
|
+
function indexToLetter(index) {
|
|
30
|
+
return String.fromCharCode(LOWERCASE_A + index);
|
|
31
|
+
}
|
|
32
|
+
function generateBB26(index) {
|
|
33
|
+
let name = "";
|
|
34
|
+
let remaining = index;
|
|
35
|
+
do {
|
|
36
|
+
name = indexToLetter(remaining % 26) + name;
|
|
37
|
+
remaining = Math.floor(remaining / 26) - 1;
|
|
38
|
+
} while (remaining >= 0);
|
|
39
|
+
return name;
|
|
40
|
+
}
|
|
41
|
+
|
|
27
42
|
// src/server/i18n.ts
|
|
28
43
|
var I18nSingleton = class {
|
|
29
44
|
// normalized user config with defaults applied
|
|
@@ -36,6 +51,8 @@ var I18nSingleton = class {
|
|
|
36
51
|
compiledCache = /* @__PURE__ */ new Map();
|
|
37
52
|
// locale -> chunk name -> content hash (for cache busting)
|
|
38
53
|
hashCache = /* @__PURE__ */ new Map();
|
|
54
|
+
// locale -> inline script for I18nScript component
|
|
55
|
+
scriptCache = /* @__PURE__ */ new Map();
|
|
39
56
|
// manifest getter (set by init module, provides live data in dev mode)
|
|
40
57
|
manifestGetter = null;
|
|
41
58
|
async configure(config) {
|
|
@@ -88,6 +105,7 @@ var I18nSingleton = class {
|
|
|
88
105
|
this.mergedCache.delete(locale);
|
|
89
106
|
this.compiledCache.delete(locale);
|
|
90
107
|
this.hashCache.delete(locale);
|
|
108
|
+
this.scriptCache.delete(locale);
|
|
91
109
|
const { chunks } = this.getManifest();
|
|
92
110
|
if (Object.keys(chunks).length > 0) {
|
|
93
111
|
this.hashCache.set(locale, computeAllChunkHashes(raw, chunks));
|
|
@@ -99,7 +117,7 @@ var I18nSingleton = class {
|
|
|
99
117
|
return cached;
|
|
100
118
|
}
|
|
101
119
|
const raw = this.rawCache.get(locale) ?? {};
|
|
102
|
-
const manifest = this.manifestGetter?.() ?? { keys: [], chunks: {} };
|
|
120
|
+
const manifest = this.manifestGetter?.() ?? { keys: [], chunks: {}, imports: {} };
|
|
103
121
|
if (manifest.keys.length === 0) {
|
|
104
122
|
return raw;
|
|
105
123
|
}
|
|
@@ -135,6 +153,44 @@ var I18nSingleton = class {
|
|
|
135
153
|
getHashes(locale) {
|
|
136
154
|
return this.hashCache.get(locale) ?? {};
|
|
137
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Get the inline script for I18nScript component.
|
|
158
|
+
* Cached per locale, invalidated when translations change.
|
|
159
|
+
*/
|
|
160
|
+
getClientScript(locale) {
|
|
161
|
+
const cached = this.scriptCache.get(locale);
|
|
162
|
+
if (cached) {
|
|
163
|
+
return cached;
|
|
164
|
+
}
|
|
165
|
+
const script = this.createClientScript(locale);
|
|
166
|
+
this.scriptCache.set(locale, script);
|
|
167
|
+
return script;
|
|
168
|
+
}
|
|
169
|
+
createClientScript(locale) {
|
|
170
|
+
const { chunks, imports } = this.getManifest();
|
|
171
|
+
const hasChunks = Object.keys(chunks).length > 0;
|
|
172
|
+
if (!hasChunks) {
|
|
173
|
+
const raw = this.getTranslations(locale);
|
|
174
|
+
return `window.__i18n__=${JSON.stringify({ locale, hashes: {}, imports: {}, translations: raw })};`;
|
|
175
|
+
}
|
|
176
|
+
const hashes = this.getHashes(locale);
|
|
177
|
+
const allChunks = new Set(Object.keys(hashes));
|
|
178
|
+
for (const deps of Object.values(imports)) {
|
|
179
|
+
deps.forEach((d) => allChunks.add(d));
|
|
180
|
+
}
|
|
181
|
+
const chunkToVar = /* @__PURE__ */ new Map();
|
|
182
|
+
let varIndex = 0;
|
|
183
|
+
for (const chunk of allChunks) {
|
|
184
|
+
chunkToVar.set(chunk, generateBB26(varIndex++));
|
|
185
|
+
}
|
|
186
|
+
const varDecls = [...chunkToVar.entries()].map(([chunk, v]) => `${v}=${JSON.stringify(chunk)}`).join(",");
|
|
187
|
+
const hashesObj = Object.entries(hashes).map(([chunk, hash]) => `[${chunkToVar.get(chunk)}]:${JSON.stringify(hash)}`).join(",");
|
|
188
|
+
const importsObj = Object.entries(imports).filter(([chunk]) => chunkToVar.has(chunk)).map(([chunk, deps]) => {
|
|
189
|
+
const validDeps = deps.filter((d) => chunkToVar.has(d));
|
|
190
|
+
return validDeps.length > 0 ? `[${chunkToVar.get(chunk)}]:[${validDeps.map((d) => chunkToVar.get(d)).join(",")}]` : null;
|
|
191
|
+
}).filter(Boolean).join(",");
|
|
192
|
+
return `(()=>{var ${varDecls};window.__i18n__={locale:${JSON.stringify(locale)},hashes:{${hashesObj}},imports:{${importsObj}},translations:{}};})();`;
|
|
193
|
+
}
|
|
138
194
|
/**
|
|
139
195
|
* Clear translations for specified locale(s).
|
|
140
196
|
* @param locales - Locale(s) to clear, or all if not specified
|
|
@@ -146,6 +202,7 @@ var I18nSingleton = class {
|
|
|
146
202
|
this.mergedCache.delete(locale);
|
|
147
203
|
this.compiledCache.delete(locale);
|
|
148
204
|
this.hashCache.delete(locale);
|
|
205
|
+
this.scriptCache.delete(locale);
|
|
149
206
|
}
|
|
150
207
|
}
|
|
151
208
|
resolveLocales(locales) {
|
|
@@ -2,8 +2,11 @@ import { ClientDirective } from 'astro';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* i18n-aware client:idle directive
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
|
+
* Based on Astro's idle directive (MIT License)
|
|
7
|
+
* https://github.com/withastro/astro/blob/main/packages/astro/src/runtime/client/idle.ts
|
|
6
8
|
*/
|
|
9
|
+
|
|
7
10
|
declare const idleDirective: ClientDirective;
|
|
8
11
|
|
|
9
12
|
export { idleDirective as default };
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "../../chunk-
|
|
2
|
+
warmUpI18nForChunk
|
|
3
|
+
} from "../../chunk-7MSGHEST.js";
|
|
4
4
|
import "../../chunk-4A5BKHFN.js";
|
|
5
5
|
|
|
6
6
|
// src/client/directives/idle.ts
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
var idleDirective = (load, _options, el) => {
|
|
8
|
+
const cb = async () => {
|
|
9
|
+
warmUpI18nForChunk(el);
|
|
10
|
+
const hydrate = await load();
|
|
11
|
+
await hydrate();
|
|
12
|
+
};
|
|
13
|
+
if ("requestIdleCallback" in window) {
|
|
14
|
+
window.requestIdleCallback(cb);
|
|
15
|
+
} else {
|
|
16
|
+
setTimeout(cb, 200);
|
|
17
|
+
}
|
|
11
18
|
};
|
|
12
19
|
var idle_default = idleDirective;
|
|
13
20
|
export {
|
|
@@ -2,8 +2,11 @@ import { ClientDirective } from 'astro';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* i18n-aware client:load directive
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
|
+
* Based on Astro's load directive (MIT License)
|
|
7
|
+
* https://github.com/withastro/astro/blob/main/packages/astro/src/runtime/client/load.ts
|
|
6
8
|
*/
|
|
9
|
+
|
|
7
10
|
declare const loadDirective: ClientDirective;
|
|
8
11
|
|
|
9
12
|
export { loadDirective as default };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "../../chunk-
|
|
2
|
+
warmUpI18nForChunk
|
|
3
|
+
} from "../../chunk-7MSGHEST.js";
|
|
4
4
|
import "../../chunk-4A5BKHFN.js";
|
|
5
5
|
|
|
6
6
|
// src/client/directives/load.ts
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
await
|
|
10
|
-
|
|
7
|
+
var loadDirective = async (load, _options, el) => {
|
|
8
|
+
warmUpI18nForChunk(el);
|
|
9
|
+
const hydrate = await load();
|
|
10
|
+
await hydrate();
|
|
11
11
|
};
|
|
12
12
|
var load_default = loadDirective;
|
|
13
13
|
export {
|
|
@@ -2,8 +2,11 @@ import { ClientDirective } from 'astro';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* i18n-aware client:media directive
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
|
+
* Based on Astro's media directive (MIT License)
|
|
7
|
+
* https://github.com/withastro/astro/blob/main/packages/astro/src/runtime/client/media.ts
|
|
6
8
|
*/
|
|
9
|
+
|
|
7
10
|
declare const mediaDirective: ClientDirective;
|
|
8
11
|
|
|
9
12
|
export { mediaDirective as default };
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "../../chunk-
|
|
2
|
+
warmUpI18nForChunk
|
|
3
|
+
} from "../../chunk-7MSGHEST.js";
|
|
4
4
|
import "../../chunk-4A5BKHFN.js";
|
|
5
5
|
|
|
6
6
|
// src/client/directives/media.ts
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
var mediaDirective = (load, options, el) => {
|
|
8
|
+
const cb = async () => {
|
|
9
|
+
warmUpI18nForChunk(el);
|
|
10
|
+
const hydrate = await load();
|
|
11
|
+
await hydrate();
|
|
12
|
+
};
|
|
13
|
+
if (options.value) {
|
|
14
|
+
const mql = matchMedia(options.value);
|
|
15
|
+
if (mql.matches) {
|
|
16
|
+
cb();
|
|
17
|
+
} else {
|
|
18
|
+
mql.addEventListener("change", cb, { once: true });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
11
21
|
};
|
|
12
22
|
var media_default = mediaDirective;
|
|
13
23
|
export {
|
|
@@ -2,8 +2,13 @@ import { ClientDirective } from 'astro';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* i18n-aware client:only directive
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
|
+
* Based on Astro's load directive (MIT License)
|
|
7
|
+
* https://github.com/withastro/astro/blob/main/packages/astro/src/runtime/client/load.ts
|
|
8
|
+
*
|
|
9
|
+
* client:only works the same as client:load - immediate hydration
|
|
6
10
|
*/
|
|
11
|
+
|
|
7
12
|
declare const onlyDirective: ClientDirective;
|
|
8
13
|
|
|
9
14
|
export { onlyDirective as default };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "../../chunk-
|
|
2
|
+
warmUpI18nForChunk
|
|
3
|
+
} from "../../chunk-7MSGHEST.js";
|
|
4
4
|
import "../../chunk-4A5BKHFN.js";
|
|
5
5
|
|
|
6
6
|
// src/client/directives/only.ts
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
await
|
|
10
|
-
|
|
7
|
+
var onlyDirective = async (load, _options, el) => {
|
|
8
|
+
warmUpI18nForChunk(el);
|
|
9
|
+
const hydrate = await load();
|
|
10
|
+
await hydrate();
|
|
11
11
|
};
|
|
12
12
|
var only_default = onlyDirective;
|
|
13
13
|
export {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import '../../types-
|
|
2
|
-
import '../../types-
|
|
1
|
+
import '../../types-BeDFfFIL.js';
|
|
2
|
+
import '../../types-DNRFj1XA.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Warm up translation cache for a chunk and all its descendants (fire and forget)
|
|
6
6
|
* Extracts chunk name from astro-island's component-url attribute
|
|
7
|
+
* Uses flattened imports map from window.__i18n__ to prefetch all nested translations
|
|
7
8
|
*/
|
|
8
|
-
declare function
|
|
9
|
+
declare function warmUpI18nForChunk(el: HTMLElement): void;
|
|
9
10
|
|
|
10
|
-
export {
|
|
11
|
+
export { warmUpI18nForChunk };
|
|
@@ -2,8 +2,11 @@ import { ClientDirective } from 'astro';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* i18n-aware client:visible directive
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
|
+
* Based on Astro's visible directive (MIT License)
|
|
7
|
+
* https://github.com/withastro/astro/blob/main/packages/astro/src/runtime/client/visible.ts
|
|
6
8
|
*/
|
|
9
|
+
|
|
7
10
|
declare const visibleDirective: ClientDirective;
|
|
8
11
|
|
|
9
12
|
export { visibleDirective as default };
|
|
@@ -1,13 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "../../chunk-
|
|
2
|
+
warmUpI18nForChunk
|
|
3
|
+
} from "../../chunk-7MSGHEST.js";
|
|
4
4
|
import "../../chunk-4A5BKHFN.js";
|
|
5
5
|
|
|
6
6
|
// src/client/directives/visible.ts
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
var visibleDirective = (load, options, el) => {
|
|
8
|
+
const cb = async () => {
|
|
9
|
+
warmUpI18nForChunk(el);
|
|
10
|
+
const hydrate = await load();
|
|
11
|
+
await hydrate();
|
|
12
|
+
};
|
|
13
|
+
const rawOptions = typeof options.value === "object" ? options.value : void 0;
|
|
14
|
+
const ioOptions = {
|
|
15
|
+
rootMargin: rawOptions?.rootMargin
|
|
16
|
+
};
|
|
17
|
+
const io = new IntersectionObserver((entries) => {
|
|
18
|
+
for (const entry of entries) {
|
|
19
|
+
if (!entry.isIntersecting) continue;
|
|
20
|
+
io.disconnect();
|
|
21
|
+
cb();
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
}, ioOptions);
|
|
25
|
+
for (const child of el.children) {
|
|
26
|
+
io.observe(child);
|
|
27
|
+
}
|
|
11
28
|
};
|
|
12
29
|
var visible_default = visibleDirective;
|
|
13
30
|
export {
|
package/dist/client/t.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as ExtractionManifest } from '../types-
|
|
2
|
-
export { C as ChunkManifest, E as ExtractedKey } from '../types-
|
|
1
|
+
import { a as ExtractionManifest } from '../types-DTUho6gi.js';
|
|
2
|
+
export { C as ChunkManifest, E as ExtractedKey } from '../types-DTUho6gi.js';
|
|
3
3
|
import { AstroIntegrationLogger } from 'astro';
|
|
4
4
|
import { Plugin } from 'vite';
|
|
5
|
-
import '../types-
|
|
5
|
+
import '../types-DNRFj1XA.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Manifest state management for i18n extraction
|
package/dist/extraction/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as ExtractionManifest } from './types-
|
|
2
|
-
import { T as TranslationMeta, C as CompiledTranslations, R as RawTranslations } from './types-
|
|
1
|
+
import { a as ExtractionManifest } from './types-DTUho6gi.js';
|
|
2
|
+
import { T as TranslationMeta, C as CompiledTranslations, R as RawTranslations } from './types-DNRFj1XA.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Fallback behavior when translation is missing
|
|
@@ -30,6 +30,7 @@ declare class I18nSingleton {
|
|
|
30
30
|
private mergedCache;
|
|
31
31
|
private compiledCache;
|
|
32
32
|
private hashCache;
|
|
33
|
+
private scriptCache;
|
|
33
34
|
private manifestGetter;
|
|
34
35
|
configure(config: I18nConfig): Promise<void>;
|
|
35
36
|
isConfigured(): boolean;
|
|
@@ -44,6 +45,12 @@ declare class I18nSingleton {
|
|
|
44
45
|
*/
|
|
45
46
|
getManifest(): ExtractionManifest;
|
|
46
47
|
getHashes(locale: string): Record<string, string>;
|
|
48
|
+
/**
|
|
49
|
+
* Get the inline script for I18nScript component.
|
|
50
|
+
* Cached per locale, invalidated when translations change.
|
|
51
|
+
*/
|
|
52
|
+
getClientScript(locale: string): string;
|
|
53
|
+
private createClientScript;
|
|
47
54
|
/**
|
|
48
55
|
* Clear translations for specified locale(s).
|
|
49
56
|
* @param locales - Locale(s) to clear, or all if not specified
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { AstroIntegration, MiddlewareHandler, APIContext } from 'astro';
|
|
2
|
-
export { F as FallbackBehavior, I as I18nConfig, i as i18n } from './i18n-
|
|
2
|
+
export { F as FallbackBehavior, I as I18nConfig, i as i18n } from './i18n-mTHTcD8K.js';
|
|
3
3
|
import { ExcludePattern } from '@astroscope/excludes';
|
|
4
|
-
export { R as RawTranslations, T as TranslationMeta } from './types-
|
|
5
|
-
export { E as ExtractedKey, a as ExtractionManifest } from './types-
|
|
4
|
+
export { R as RawTranslations, T as TranslationMeta } from './types-DNRFj1XA.js';
|
|
5
|
+
export { E as ExtractedKey, a as ExtractionManifest } from './types-DTUho6gi.js';
|
|
6
6
|
|
|
7
7
|
interface I18nOptions {
|
|
8
8
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
i18nVitePlugin
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EO4FUQXR.js";
|
|
4
4
|
import {
|
|
5
5
|
i18n,
|
|
6
6
|
runWithContext
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-RHWEV4L2.js";
|
|
8
8
|
import "./chunk-KNDYKTHE.js";
|
|
9
9
|
import "./chunk-4A5BKHFN.js";
|
|
10
10
|
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as I18nContext } from './i18n-
|
|
2
|
-
export { i as i18n } from './i18n-
|
|
3
|
-
export { I as I18nClientState } from './types-
|
|
4
|
-
import './types-
|
|
1
|
+
import { a as I18nContext } from './i18n-mTHTcD8K.js';
|
|
2
|
+
export { i as i18n } from './i18n-mTHTcD8K.js';
|
|
3
|
+
export { I as I18nClientState } from './types-DNRFj1XA.js';
|
|
4
|
+
import './types-DTUho6gi.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Get the current i18n context
|
package/dist/internal.js
CHANGED
package/dist/server/t.d.ts
CHANGED
package/dist/server/t.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as TranslationMeta } from './types-
|
|
1
|
+
import { T as TranslationMeta } from './types-DNRFj1XA.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Extracted metadata for a single translation key
|
|
@@ -13,12 +13,18 @@ type ExtractedKey = {
|
|
|
13
13
|
* Chunk-to-keys mapping produced by Vite plugin
|
|
14
14
|
*/
|
|
15
15
|
type ChunkManifest = Record<string, string[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Chunk imports mapping: chunk name → array of imported chunk names that have i18n
|
|
18
|
+
* All direct and indirect descendants are flattened into a single array
|
|
19
|
+
*/
|
|
20
|
+
type ImportsManifest = Record<string, string[]>;
|
|
16
21
|
/**
|
|
17
22
|
* Full extraction manifest
|
|
18
23
|
*/
|
|
19
24
|
type ExtractionManifest = {
|
|
20
25
|
keys: ExtractedKey[];
|
|
21
26
|
chunks: ChunkManifest;
|
|
27
|
+
imports: ImportsManifest;
|
|
22
28
|
};
|
|
23
29
|
|
|
24
30
|
export type { ChunkManifest as C, ExtractedKey as E, ExtractionManifest as a };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astroscope/i18n",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "i18n for Astro + React islands — automatic tree-shaking, parallel loading, any translation source",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"vite": "^6.4.1"
|
|
101
101
|
},
|
|
102
102
|
"peerDependencies": {
|
|
103
|
-
"@astroscope/excludes": "^0.1.
|
|
103
|
+
"@astroscope/excludes": "^0.1.3",
|
|
104
104
|
"astro": "^5.0.0"
|
|
105
105
|
}
|
|
106
106
|
}
|
|
@@ -1,29 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
2
|
+
import { getContext, i18n } from '@astroscope/i18n/internal';
|
|
3
3
|
|
|
4
4
|
const context = getContext();
|
|
5
|
-
|
|
6
|
-
let script: string | null = null;
|
|
7
|
-
|
|
8
|
-
if (context) {
|
|
9
|
-
const { locale } = context;
|
|
10
|
-
const { chunks } = i18n.getManifest();
|
|
11
|
-
const hasChunks = Object.keys(chunks).length > 0;
|
|
12
|
-
|
|
13
|
-
let state: I18nClientState;
|
|
14
|
-
|
|
15
|
-
if (hasChunks) {
|
|
16
|
-
const hashes = i18n.getHashes(locale) ?? {};
|
|
17
|
-
|
|
18
|
-
state = { locale, hashes, translations: {} };
|
|
19
|
-
} else {
|
|
20
|
-
const raw = i18n.getTranslations(locale) ?? {};
|
|
21
|
-
|
|
22
|
-
state = { locale, hashes: {}, translations: raw };
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
script = `window.__i18n__=${JSON.stringify(state)};`;
|
|
26
|
-
}
|
|
5
|
+
const script = context ? i18n.getClientScript(context.locale) : null;
|
|
27
6
|
---
|
|
28
7
|
|
|
29
8
|
{
|