next-intlayer 9.3.3 → 9.4.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.
- package/README.md +4 -1
- package/dist/cjs/client/IntlayerClientProvider.cjs +18 -14
- package/dist/cjs/client/IntlayerClientProvider.cjs.map +1 -1
- package/dist/cjs/index.cjs +18 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/rsc/index.cjs +96 -0
- package/dist/cjs/server/IntlayerProvider.cjs +54 -0
- package/dist/cjs/server/IntlayerProvider.cjs.map +1 -0
- package/dist/cjs/server/IntlayerServerProvider.cjs +29 -0
- package/dist/cjs/server/IntlayerServerProvider.cjs.map +1 -0
- package/dist/cjs/server/ambientLocale.cjs +64 -0
- package/dist/cjs/server/ambientLocale.cjs.map +1 -0
- package/dist/cjs/server/format/index.cjs +17 -7
- package/dist/cjs/server/format/useCompact.cjs +26 -0
- package/dist/cjs/server/format/useCompact.cjs.map +1 -0
- package/dist/cjs/server/format/useCurrency.cjs +26 -0
- package/dist/cjs/server/format/useCurrency.cjs.map +1 -0
- package/dist/cjs/server/format/useDate.cjs +33 -0
- package/dist/cjs/server/format/useDate.cjs.map +1 -0
- package/dist/cjs/server/format/useList.cjs +26 -0
- package/dist/cjs/server/format/useList.cjs.map +1 -0
- package/dist/cjs/server/format/useNumber.cjs +26 -0
- package/dist/cjs/server/format/useNumber.cjs.map +1 -0
- package/dist/cjs/server/format/usePercentage.cjs +26 -0
- package/dist/cjs/server/format/usePercentage.cjs.map +1 -0
- package/dist/cjs/server/format/useRelativeTime.cjs +26 -0
- package/dist/cjs/server/format/useRelativeTime.cjs.map +1 -0
- package/dist/cjs/server/format/useUnit.cjs +26 -0
- package/dist/cjs/server/format/useUnit.cjs.map +1 -0
- package/dist/cjs/server/index.cjs +27 -43
- package/dist/cjs/server/prepareSwcOptimization.cjs +1 -1
- package/dist/cjs/server/prepareSwcOptimization.cjs.map +1 -1
- package/dist/cjs/server/suspendingReader.cjs +45 -0
- package/dist/cjs/server/suspendingReader.cjs.map +1 -0
- package/dist/cjs/server/t.cjs +16 -0
- package/dist/cjs/server/t.cjs.map +1 -0
- package/dist/cjs/server/useDictionary.cjs +5 -4
- package/dist/cjs/server/useDictionary.cjs.map +1 -1
- package/dist/cjs/server/useDictionaryAsync.cjs +5 -7
- package/dist/cjs/server/useDictionaryAsync.cjs.map +1 -1
- package/dist/cjs/server/useDictionaryDynamic.cjs +5 -4
- package/dist/cjs/server/useDictionaryDynamic.cjs.map +1 -1
- package/dist/cjs/server/useI18n.cjs +17 -0
- package/dist/cjs/server/useI18n.cjs.map +1 -0
- package/dist/cjs/server/useIntl.cjs +16 -0
- package/dist/cjs/server/useIntl.cjs.map +1 -0
- package/dist/cjs/server/useIntlayer.cjs +5 -20
- package/dist/cjs/server/useIntlayer.cjs.map +1 -1
- package/dist/cjs/server/useLocale.cjs +26 -0
- package/dist/cjs/server/useLocale.cjs.map +1 -0
- package/dist/cjs/server/withIntlayer.cjs +2 -3
- package/dist/cjs/server/withIntlayer.cjs.map +1 -1
- package/dist/esm/client/IntlayerClientProvider.mjs +18 -15
- package/dist/esm/client/IntlayerClientProvider.mjs.map +1 -1
- package/dist/esm/index.mjs +2 -2
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/rsc/index.mjs +18 -0
- package/dist/esm/server/IntlayerProvider.mjs +53 -0
- package/dist/esm/server/IntlayerProvider.mjs.map +1 -0
- package/dist/esm/server/IntlayerServerProvider.mjs +28 -0
- package/dist/esm/server/IntlayerServerProvider.mjs.map +1 -0
- package/dist/esm/server/ambientLocale.mjs +61 -0
- package/dist/esm/server/ambientLocale.mjs.map +1 -0
- package/dist/esm/server/format/index.mjs +10 -1
- package/dist/esm/server/format/useCompact.mjs +25 -0
- package/dist/esm/server/format/useCompact.mjs.map +1 -0
- package/dist/esm/server/format/useCurrency.mjs +25 -0
- package/dist/esm/server/format/useCurrency.mjs.map +1 -0
- package/dist/esm/server/format/useDate.mjs +32 -0
- package/dist/esm/server/format/useDate.mjs.map +1 -0
- package/dist/esm/server/format/useList.mjs +25 -0
- package/dist/esm/server/format/useList.mjs.map +1 -0
- package/dist/esm/server/format/useNumber.mjs +25 -0
- package/dist/esm/server/format/useNumber.mjs.map +1 -0
- package/dist/esm/server/format/usePercentage.mjs +25 -0
- package/dist/esm/server/format/usePercentage.mjs.map +1 -0
- package/dist/esm/server/format/useRelativeTime.mjs +25 -0
- package/dist/esm/server/format/useRelativeTime.mjs.map +1 -0
- package/dist/esm/server/format/useUnit.mjs +25 -0
- package/dist/esm/server/format/useUnit.mjs.map +1 -0
- package/dist/esm/server/index.mjs +12 -2
- package/dist/esm/server/prepareSwcOptimization.mjs +1 -1
- package/dist/esm/server/prepareSwcOptimization.mjs.map +1 -1
- package/dist/esm/server/suspendingReader.mjs +42 -0
- package/dist/esm/server/suspendingReader.mjs.map +1 -0
- package/dist/esm/server/t.mjs +15 -0
- package/dist/esm/server/t.mjs.map +1 -0
- package/dist/esm/server/useDictionary.mjs +5 -4
- package/dist/esm/server/useDictionary.mjs.map +1 -1
- package/dist/esm/server/useDictionaryAsync.mjs +5 -7
- package/dist/esm/server/useDictionaryAsync.mjs.map +1 -1
- package/dist/esm/server/useDictionaryDynamic.mjs +5 -4
- package/dist/esm/server/useDictionaryDynamic.mjs.map +1 -1
- package/dist/esm/server/useI18n.mjs +16 -0
- package/dist/esm/server/useI18n.mjs.map +1 -0
- package/dist/esm/server/useIntl.mjs +15 -0
- package/dist/esm/server/useIntl.mjs.map +1 -0
- package/dist/esm/server/useIntlayer.mjs +6 -18
- package/dist/esm/server/useIntlayer.mjs.map +1 -1
- package/dist/esm/server/useLocale.mjs +25 -0
- package/dist/esm/server/useLocale.mjs.map +1 -0
- package/dist/esm/server/withIntlayer.mjs +2 -3
- package/dist/esm/server/withIntlayer.mjs.map +1 -1
- package/dist/types/@intlayer/babel/dist/types/babel-plugin-intlayer-purge.d.ts +2 -2
- package/dist/types/@intlayer/babel/dist/types/babel-plugin-intlayer-usage-analyzer.d.ts +2 -2
- package/dist/types/@intlayer/babel/dist/types/extractContent/contentWriter.d.ts +2 -2
- package/dist/types/@intlayer/babel/dist/types/getOptimizePluginOptions.d.ts +2 -2
- package/dist/types/@intlayer/babel/dist/types/getPurgePluginOptions.d.ts +2 -2
- package/dist/types/client/IntlayerClientProvider.d.ts +20 -14
- package/dist/types/client/IntlayerClientProvider.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/rsc/index.d.ts +19 -0
- package/dist/types/server/IntlayerProvider.d.ts +43 -0
- package/dist/types/server/IntlayerProvider.d.ts.map +1 -0
- package/dist/types/server/IntlayerServerProvider.d.ts +30 -0
- package/dist/types/server/IntlayerServerProvider.d.ts.map +1 -0
- package/dist/types/server/ambientLocale.d.ts +34 -0
- package/dist/types/server/ambientLocale.d.ts.map +1 -0
- package/dist/types/server/format/index.d.ts +9 -1
- package/dist/types/server/format/useCompact.d.ts +16 -0
- package/dist/types/server/format/useCompact.d.ts.map +1 -0
- package/dist/types/server/format/useCurrency.d.ts +16 -0
- package/dist/types/server/format/useCurrency.d.ts.map +1 -0
- package/dist/types/server/format/useDate.d.ts +20 -0
- package/dist/types/server/format/useDate.d.ts.map +1 -0
- package/dist/types/server/format/useList.d.ts +16 -0
- package/dist/types/server/format/useList.d.ts.map +1 -0
- package/dist/types/server/format/useNumber.d.ts +16 -0
- package/dist/types/server/format/useNumber.d.ts.map +1 -0
- package/dist/types/server/format/usePercentage.d.ts +16 -0
- package/dist/types/server/format/usePercentage.d.ts.map +1 -0
- package/dist/types/server/format/useRelativeTime.d.ts +16 -0
- package/dist/types/server/format/useRelativeTime.d.ts.map +1 -0
- package/dist/types/server/format/useUnit.d.ts +16 -0
- package/dist/types/server/format/useUnit.d.ts.map +1 -0
- package/dist/types/server/index.d.ts +12 -2
- package/dist/types/server/prepareSwcOptimization.d.ts +1 -1
- package/dist/types/server/prepareSwcOptimization.d.ts.map +1 -1
- package/dist/types/server/suspendingReader.d.ts +22 -0
- package/dist/types/server/suspendingReader.d.ts.map +1 -0
- package/dist/types/server/t.d.ts +13 -0
- package/dist/types/server/t.d.ts.map +1 -0
- package/dist/types/server/useDictionary.d.ts +2 -1
- package/dist/types/server/useDictionary.d.ts.map +1 -1
- package/dist/types/server/useDictionaryAsync.d.ts +5 -4
- package/dist/types/server/useDictionaryAsync.d.ts.map +1 -1
- package/dist/types/server/useDictionaryDynamic.d.ts +3 -2
- package/dist/types/server/useDictionaryDynamic.d.ts.map +1 -1
- package/dist/types/server/useI18n.d.ts +14 -0
- package/dist/types/server/useI18n.d.ts.map +1 -0
- package/dist/types/server/useIntl.d.ts +13 -0
- package/dist/types/server/useIntl.d.ts.map +1 -0
- package/dist/types/server/useIntlayer.d.ts +4 -5
- package/dist/types/server/useIntlayer.d.ts.map +1 -1
- package/dist/types/server/useLocale.d.ts +20 -0
- package/dist/types/server/useLocale.d.ts.map +1 -0
- package/package.json +14 -9
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { resolveAmbientLocale } from "../ambientLocale.mjs";
|
|
2
|
+
import { list } from "@intlayer/core/formatters";
|
|
3
|
+
|
|
4
|
+
//#region src/server/format/useList.ts
|
|
5
|
+
/**
|
|
6
|
+
* On the server side, hook returning a `list` formatter bound to the ambient
|
|
7
|
+
* locale: the server context, falling back to the locale carried by the
|
|
8
|
+
* request. A per-call `locale` option still wins.
|
|
9
|
+
*
|
|
10
|
+
* Reimplemented rather than re-exported from `react-intlayer/server/format`:
|
|
11
|
+
* that one takes no locale argument, so there is no way to hand it the ambient
|
|
12
|
+
* locale — it would read the server context alone and format with the default
|
|
13
|
+
* locale on any render the provider did not reach.
|
|
14
|
+
*/
|
|
15
|
+
const useList = () => {
|
|
16
|
+
const locale = resolveAmbientLocale();
|
|
17
|
+
return (...args) => list(args[0], {
|
|
18
|
+
...args[1],
|
|
19
|
+
locale: args[1]?.locale ?? locale
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { useList };
|
|
25
|
+
//# sourceMappingURL=useList.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useList.mjs","names":[],"sources":["../../../../src/server/format/useList.ts"],"sourcesContent":["import { list } from '@intlayer/core/formatters';\nimport { resolveAmbientLocale } from '../ambientLocale';\n\n/**\n * On the server side, hook returning a `list` formatter bound to the ambient\n * locale: the server context, falling back to the locale carried by the\n * request. A per-call `locale` option still wins.\n *\n * Reimplemented rather than re-exported from `react-intlayer/server/format`:\n * that one takes no locale argument, so there is no way to hand it the ambient\n * locale — it would read the server context alone and format with the default\n * locale on any render the provider did not reach.\n */\nexport const useList = () => {\n const locale = resolveAmbientLocale();\n\n return (...args: Parameters<typeof list>) =>\n list(args[0], {\n ...args[1],\n locale: args[1]?.locale ?? locale,\n });\n};\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAa,gBAAgB;CAC3B,MAAM,SAAS,qBAAqB;CAEpC,QAAQ,GAAG,SACT,KAAK,KAAK,IAAI;EACZ,GAAG,KAAK;EACR,QAAQ,KAAK,EAAE,EAAE,UAAU;CAC7B,CAAC;AACL"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { resolveAmbientLocale } from "../ambientLocale.mjs";
|
|
2
|
+
import { number } from "@intlayer/core/formatters";
|
|
3
|
+
|
|
4
|
+
//#region src/server/format/useNumber.ts
|
|
5
|
+
/**
|
|
6
|
+
* On the server side, hook returning a `number` formatter bound to the ambient
|
|
7
|
+
* locale: the server context, falling back to the locale carried by the
|
|
8
|
+
* request. A per-call `locale` option still wins.
|
|
9
|
+
*
|
|
10
|
+
* Reimplemented rather than re-exported from `react-intlayer/server/format`:
|
|
11
|
+
* that one takes no locale argument, so there is no way to hand it the ambient
|
|
12
|
+
* locale — it would read the server context alone and format with the default
|
|
13
|
+
* locale on any render the provider did not reach.
|
|
14
|
+
*/
|
|
15
|
+
const useNumber = () => {
|
|
16
|
+
const locale = resolveAmbientLocale();
|
|
17
|
+
return (...args) => number(args[0], {
|
|
18
|
+
...args[1],
|
|
19
|
+
locale: args[1]?.locale ?? locale
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { useNumber };
|
|
25
|
+
//# sourceMappingURL=useNumber.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useNumber.mjs","names":[],"sources":["../../../../src/server/format/useNumber.ts"],"sourcesContent":["import { number } from '@intlayer/core/formatters';\nimport { resolveAmbientLocale } from '../ambientLocale';\n\n/**\n * On the server side, hook returning a `number` formatter bound to the ambient\n * locale: the server context, falling back to the locale carried by the\n * request. A per-call `locale` option still wins.\n *\n * Reimplemented rather than re-exported from `react-intlayer/server/format`:\n * that one takes no locale argument, so there is no way to hand it the ambient\n * locale — it would read the server context alone and format with the default\n * locale on any render the provider did not reach.\n */\nexport const useNumber = () => {\n const locale = resolveAmbientLocale();\n\n return (...args: Parameters<typeof number>) =>\n number(args[0], {\n ...args[1],\n locale: args[1]?.locale ?? locale,\n });\n};\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAa,kBAAkB;CAC7B,MAAM,SAAS,qBAAqB;CAEpC,QAAQ,GAAG,SACT,OAAO,KAAK,IAAI;EACd,GAAG,KAAK;EACR,QAAQ,KAAK,EAAE,EAAE,UAAU;CAC7B,CAAC;AACL"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { resolveAmbientLocale } from "../ambientLocale.mjs";
|
|
2
|
+
import { percentage } from "@intlayer/core/formatters";
|
|
3
|
+
|
|
4
|
+
//#region src/server/format/usePercentage.ts
|
|
5
|
+
/**
|
|
6
|
+
* On the server side, hook returning a `percentage` formatter bound to the ambient
|
|
7
|
+
* locale: the server context, falling back to the locale carried by the
|
|
8
|
+
* request. A per-call `locale` option still wins.
|
|
9
|
+
*
|
|
10
|
+
* Reimplemented rather than re-exported from `react-intlayer/server/format`:
|
|
11
|
+
* that one takes no locale argument, so there is no way to hand it the ambient
|
|
12
|
+
* locale — it would read the server context alone and format with the default
|
|
13
|
+
* locale on any render the provider did not reach.
|
|
14
|
+
*/
|
|
15
|
+
const usePercentage = () => {
|
|
16
|
+
const locale = resolveAmbientLocale();
|
|
17
|
+
return (...args) => percentage(args[0], {
|
|
18
|
+
...args[1],
|
|
19
|
+
locale: args[1]?.locale ?? locale
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { usePercentage };
|
|
25
|
+
//# sourceMappingURL=usePercentage.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePercentage.mjs","names":[],"sources":["../../../../src/server/format/usePercentage.ts"],"sourcesContent":["import { percentage } from '@intlayer/core/formatters';\nimport { resolveAmbientLocale } from '../ambientLocale';\n\n/**\n * On the server side, hook returning a `percentage` formatter bound to the ambient\n * locale: the server context, falling back to the locale carried by the\n * request. A per-call `locale` option still wins.\n *\n * Reimplemented rather than re-exported from `react-intlayer/server/format`:\n * that one takes no locale argument, so there is no way to hand it the ambient\n * locale — it would read the server context alone and format with the default\n * locale on any render the provider did not reach.\n */\nexport const usePercentage = () => {\n const locale = resolveAmbientLocale();\n\n return (...args: Parameters<typeof percentage>) =>\n percentage(args[0], {\n ...args[1],\n locale: args[1]?.locale ?? locale,\n });\n};\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAa,sBAAsB;CACjC,MAAM,SAAS,qBAAqB;CAEpC,QAAQ,GAAG,SACT,WAAW,KAAK,IAAI;EAClB,GAAG,KAAK;EACR,QAAQ,KAAK,EAAE,EAAE,UAAU;CAC7B,CAAC;AACL"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { resolveAmbientLocale } from "../ambientLocale.mjs";
|
|
2
|
+
import { relativeTime } from "@intlayer/core/formatters";
|
|
3
|
+
|
|
4
|
+
//#region src/server/format/useRelativeTime.ts
|
|
5
|
+
/**
|
|
6
|
+
* On the server side, hook returning a `relativeTime` formatter bound to the ambient
|
|
7
|
+
* locale: the server context, falling back to the locale carried by the
|
|
8
|
+
* request. A per-call `locale` option still wins.
|
|
9
|
+
*
|
|
10
|
+
* Reimplemented rather than re-exported from `react-intlayer/server/format`:
|
|
11
|
+
* that one takes no locale argument, so there is no way to hand it the ambient
|
|
12
|
+
* locale — it would read the server context alone and format with the default
|
|
13
|
+
* locale on any render the provider did not reach.
|
|
14
|
+
*/
|
|
15
|
+
const useRelativeTime = () => {
|
|
16
|
+
const locale = resolveAmbientLocale();
|
|
17
|
+
return (...args) => relativeTime(args[0], args[1] ?? /* @__PURE__ */ new Date(), {
|
|
18
|
+
...args[2],
|
|
19
|
+
locale: args[2]?.locale ?? locale
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { useRelativeTime };
|
|
25
|
+
//# sourceMappingURL=useRelativeTime.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRelativeTime.mjs","names":[],"sources":["../../../../src/server/format/useRelativeTime.ts"],"sourcesContent":["import { relativeTime } from '@intlayer/core/formatters';\nimport { resolveAmbientLocale } from '../ambientLocale';\n\n/**\n * On the server side, hook returning a `relativeTime` formatter bound to the ambient\n * locale: the server context, falling back to the locale carried by the\n * request. A per-call `locale` option still wins.\n *\n * Reimplemented rather than re-exported from `react-intlayer/server/format`:\n * that one takes no locale argument, so there is no way to hand it the ambient\n * locale — it would read the server context alone and format with the default\n * locale on any render the provider did not reach.\n */\nexport const useRelativeTime = () => {\n const locale = resolveAmbientLocale();\n\n return (...args: Parameters<typeof relativeTime>) =>\n relativeTime(args[0], args[1] ?? new Date(), {\n ...args[2],\n locale: args[2]?.locale ?? locale,\n });\n};\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAa,wBAAwB;CACnC,MAAM,SAAS,qBAAqB;CAEpC,QAAQ,GAAG,SACT,aAAa,KAAK,IAAI,KAAK,sBAAM,IAAI,KAAK,GAAG;EAC3C,GAAG,KAAK;EACR,QAAQ,KAAK,EAAE,EAAE,UAAU;CAC7B,CAAC;AACL"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { resolveAmbientLocale } from "../ambientLocale.mjs";
|
|
2
|
+
import { units } from "@intlayer/core/formatters";
|
|
3
|
+
|
|
4
|
+
//#region src/server/format/useUnit.ts
|
|
5
|
+
/**
|
|
6
|
+
* On the server side, hook returning a `units` formatter bound to the ambient
|
|
7
|
+
* locale: the server context, falling back to the locale carried by the
|
|
8
|
+
* request. A per-call `locale` option still wins.
|
|
9
|
+
*
|
|
10
|
+
* Reimplemented rather than re-exported from `react-intlayer/server/format`:
|
|
11
|
+
* that one takes no locale argument, so there is no way to hand it the ambient
|
|
12
|
+
* locale — it would read the server context alone and format with the default
|
|
13
|
+
* locale on any render the provider did not reach.
|
|
14
|
+
*/
|
|
15
|
+
const useUnit = () => {
|
|
16
|
+
const locale = resolveAmbientLocale();
|
|
17
|
+
return (...args) => units(args[0], {
|
|
18
|
+
...args[1],
|
|
19
|
+
locale: args[1]?.locale ?? locale
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { useUnit };
|
|
25
|
+
//# sourceMappingURL=useUnit.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useUnit.mjs","names":[],"sources":["../../../../src/server/format/useUnit.ts"],"sourcesContent":["import { units } from '@intlayer/core/formatters';\nimport { resolveAmbientLocale } from '../ambientLocale';\n\n/**\n * On the server side, hook returning a `units` formatter bound to the ambient\n * locale: the server context, falling back to the locale carried by the\n * request. A per-call `locale` option still wins.\n *\n * Reimplemented rather than re-exported from `react-intlayer/server/format`:\n * that one takes no locale argument, so there is no way to hand it the ambient\n * locale — it would read the server context alone and format with the default\n * locale on any render the provider did not reach.\n */\nexport const useUnit = () => {\n const locale = resolveAmbientLocale();\n\n return (...args: Parameters<typeof units>) =>\n units(args[0], {\n ...args[1],\n locale: args[1]?.locale ?? locale,\n });\n};\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAa,gBAAgB;CAC3B,MAAM,SAAS,qBAAqB;CAEpC,QAAQ,GAAG,SACT,MAAM,KAAK,IAAI;EACb,GAAG,KAAK;EACR,QAAQ,KAAK,EAAE,EAAE,UAAU;CAC7B,CAAC;AACL"}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
import { IntlayerProvider } from "./IntlayerProvider.mjs";
|
|
1
2
|
import { getLocale } from "./getLocale.mjs";
|
|
3
|
+
import { t } from "./t.mjs";
|
|
4
|
+
import { useDictionary } from "./useDictionary.mjs";
|
|
5
|
+
import { useDictionaryAsync } from "./useDictionaryAsync.mjs";
|
|
6
|
+
import { useDictionaryDynamic } from "./useDictionaryDynamic.mjs";
|
|
7
|
+
import { useI18n } from "./useI18n.mjs";
|
|
8
|
+
import { useIntl } from "./useIntl.mjs";
|
|
9
|
+
import { useIntlayer } from "./useIntlayer.mjs";
|
|
10
|
+
import { useLocale } from "./useLocale.mjs";
|
|
2
11
|
import { withIntlayer, withIntlayerSync } from "./withIntlayer.mjs";
|
|
3
|
-
import { IntlayerServerProvider
|
|
12
|
+
import { IntlayerServerProvider } from "./IntlayerServerProvider.mjs";
|
|
13
|
+
import { getServerContext, locale, setLocale, setVariant, useLoadDynamic } from "react-intlayer/server";
|
|
4
14
|
|
|
5
|
-
export { IntlayerServerProvider, getLocale, locale, t, useDictionary, useDictionaryAsync, useDictionaryDynamic, useI18n, useIntl, useIntlayer, useLoadDynamic, useLocale, withIntlayer, withIntlayerSync };
|
|
15
|
+
export { IntlayerProvider, IntlayerServerProvider, getLocale, getServerContext, locale, setLocale, setVariant, t, useDictionary, useDictionaryAsync, useDictionaryDynamic, useI18n, useIntl, useIntlayer, useLoadDynamic, useLocale, withIntlayer, withIntlayerSync };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { colorize, getAppLogger } from "@intlayer/config/logger";
|
|
2
1
|
import { dirname, join } from "node:path";
|
|
3
2
|
import * as ANSIColors from "@intlayer/config/colors";
|
|
3
|
+
import { colorize, getAppLogger } from "@intlayer/config/logger";
|
|
4
4
|
import { getProjectRequire } from "@intlayer/config/utils";
|
|
5
5
|
import { runOnce } from "@intlayer/engine/utils";
|
|
6
6
|
import { readFileSync, rmSync } from "node:fs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepareSwcOptimization.mjs","names":[],"sources":["../../../src/server/prepareSwcOptimization.ts"],"sourcesContent":["import { readFileSync, rmSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport type {\n getPurgePluginOptions as GetPurgePluginOptions,\n runIntlayerPurgePipeline as RunIntlayerPurgePipeline,\n SerializedFieldRenameMap,\n serializeFieldRenameMap as SerializeFieldRenameMap,\n} from '@intlayer/babel';\nimport type { SwcExtraCallerConfig } from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport type { GetConfigurationOptions } from '@intlayer/config/node';\nimport { getProjectRequire } from '@intlayer/config/utils';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\n\n/**\n * Field-rename tables keyed by dictionary key, forwarded to the\n * `@intlayer/swc` plugin's `fieldRenameMap` option.\n */\nexport type FieldRenameMapByDictionaryKey = Record<\n string,\n SerializedFieldRenameMap\n>;\n\n/** Verbosity forwarded to the `@intlayer/swc` plugin's `logLevel` option. */\nexport type SwcLogLevel = 'off' | 'info' | 'debug';\n\n/**\n * Subset of `@intlayer/babel` this module needs. The package is only an\n * optional runtime dependency, so it is required lazily and never imported at\n * module scope.\n */\ntype IntlayerBabelModule = {\n getPurgePluginOptions: typeof GetPurgePluginOptions;\n runIntlayerPurgePipeline: typeof RunIntlayerPurgePipeline;\n serializeFieldRenameMap: typeof SerializeFieldRenameMap;\n};\n\n/**\n * Opt-in to the SWC plugin's per-file tracing.\n *\n * The plugin transforms one file at a time with no cross-file state, so all it\n * can report is a line per file — hundreds of them on a real project, and with\n * no counterpart in the Vite build output. The purge and minify summaries that\n * `log.mode` does control are emitted by the pipeline itself, in Node; this\n * variable is purely a debugging aid on top.\n */\nconst SWC_LOG_LEVEL_ENV_VAR = 'INTLAYER_SWC_LOG_LEVEL';\n\n/** Sentinel coordinating the pipeline across the processes of one build. */\nconst PURGE_SENTINEL_FILE_NAME = 'intlayer-swc-purge.lock';\n\n/** Where the serialised field-rename tables are cached between processes. */\nconst FIELD_RENAME_MAP_FILE_NAME = 'swc-field-rename-map.json';\n\n/**\n * Next.js evaluates `next.config.*` in the main build process and again in each\n * Turbopack/webpack worker. The dictionary rewrite must happen exactly once —\n * a second run would derive the short aliases from the already-renamed JSON —\n * so the sentinel window has to cover a whole build startup.\n */\nconst PURGE_CACHE_TIMEOUT_MS = 30 * 1000;\n\n/** Absolute path of a file in the intlayer cache directory. */\nconst getCacheFilePath = (\n intlayerConfig: IntlayerConfig,\n fileName: string\n): string =>\n join(intlayerConfig.system.baseDir, '.intlayer', 'cache', fileName);\n\n/**\n * Resolves the verbosity the `@intlayer/swc` plugin should report at.\n *\n * Off unless {@link SWC_LOG_LEVEL_ENV_VAR} asks for tracing: `log.mode` governs\n * the purge and minify reporting, which the pipeline emits in Node so the\n * Next.js build reads the same as the Vite one.\n */\nexport const resolveSwcLogLevel = (\n intlayerConfig: IntlayerConfig\n): SwcLogLevel => {\n if (intlayerConfig.log.mode === 'disabled') return 'off';\n\n const requestedLogLevel = process.env[SWC_LOG_LEVEL_ENV_VAR];\n\n return requestedLogLevel === 'info' || requestedLogLevel === 'debug'\n ? requestedLogLevel\n : 'off';\n};\n\n/**\n * Whether the purge / minify pipeline should run for this build.\n *\n * Compat-adapter callers disable it: their descriptors reach `withIntlayer`\n * only in the SWC plugin's lossy wire format, so the usage analyser would not\n * recognise `useTranslation(...)` & co. and would purge fields those call sites\n * still read.\n */\nconst getIsPurgePipelineEnabled = (\n intlayerConfig: IntlayerConfig,\n swcExtraCallers: SwcExtraCallerConfig[] | undefined,\n isSwcPluginUsable: boolean\n): boolean => {\n const { purge, minify, optimize } = intlayerConfig.build;\n\n if (optimize === false) return false;\n if (!purge && !minify) return false;\n\n // The pipeline rewrites the compiled dictionaries in place — dropping unused\n // fields and renaming the rest to short aliases. Only the SWC plugin rewrites\n // the matching source accesses, so running this without it would ship\n // dictionaries whose keys no longer match the code reading them.\n if (!isSwcPluginUsable) return false;\n\n // `editor.enabled` is deliberately not checked here: the pipeline stands down\n // on its own and explains why, the same way the Vite build does.\n\n if (swcExtraCallers && swcExtraCallers.length > 0) {\n getAppLogger(intlayerConfig)(\n [\n 'Dictionary purge and minification are',\n colorize('disabled', ANSIColors.GREY_DARK),\n 'because compat-adapter callers are configured — their call sites are',\n 'not visible to the usage analyser.',\n ],\n { level: 'warn' }\n );\n return false;\n }\n\n return true;\n};\n\n/**\n * Exports this module needs from `@intlayer/babel`. Checked one by one so a\n * version predating the purge pipeline is rejected like a missing package,\n * instead of failing later with `runIntlayerPurgePipeline is not a function`.\n */\nconst REQUIRED_BABEL_EXPORTS = [\n 'getPurgePluginOptions',\n 'runIntlayerPurgePipeline',\n 'serializeFieldRenameMap',\n] as const satisfies readonly (keyof IntlayerBabelModule)[];\n\n/**\n * Lazily loads `@intlayer/babel`, or `null` when it is not installed or too old\n * to expose the purge pipeline.\n */\nconst loadIntlayerBabel = (\n intlayerConfig: IntlayerConfig\n): IntlayerBabelModule | null => {\n try {\n const requireFunction =\n intlayerConfig.build?.require ?? getProjectRequire();\n\n const intlayerBabel = requireFunction(\n '@intlayer/babel'\n ) as Partial<IntlayerBabelModule>;\n\n const hasEveryRequiredExport = REQUIRED_BABEL_EXPORTS.every(\n (exportName) => typeof intlayerBabel?.[exportName] === 'function'\n );\n\n if (!hasEveryRequiredExport) return null;\n\n return intlayerBabel as IntlayerBabelModule;\n } catch {\n return null;\n }\n};\n\n/**\n * Whether the purge / minify pipeline can run at all, i.e. whether a usable\n * `@intlayer/babel` is resolvable from the project.\n *\n * Used by `withIntlayer` to keep the build report honest: announcing\n * `Dictionary minification enabled` while the pipeline cannot load would describe a\n * pass that never happens.\n */\nexport const getIsPurgePipelineAvailable = (\n intlayerConfig: IntlayerConfig\n): boolean => loadIntlayerBabel(intlayerConfig) !== null;\n\n/**\n * Runs the purge / minify pipeline and writes the resulting field-rename\n * tables to the cache file so every process of the build reads the same ones.\n */\nconst runPurgePipelineOnce = async (\n intlayerConfig: IntlayerConfig,\n configOptions: GetConfigurationOptions | undefined,\n dictionaries: Dictionary[] | undefined,\n fieldRenameMapFilePath: string\n): Promise<void> => {\n const appLogger = getAppLogger(intlayerConfig);\n\n const intlayerBabel = loadIntlayerBabel(intlayerConfig);\n\n if (!intlayerBabel) {\n // Not verbose: the build asked for purge / minify and is silently getting\n // neither, which is exactly the kind of thing a default build must report.\n appLogger(\n [\n 'Dictionary purge and minification are',\n colorize('disabled', ANSIColors.GREY_DARK),\n 'because',\n colorize('@intlayer/babel', ANSIColors.GREY_LIGHT),\n 'is missing or too old to expose the purge pipeline — install it in',\n 'this project to enable them.',\n ],\n { level: 'warn' }\n );\n return;\n }\n\n const {\n getPurgePluginOptions,\n runIntlayerPurgePipeline,\n serializeFieldRenameMap,\n } = intlayerBabel;\n\n // `runOnce` discards whatever this callback throws, so a pipeline failure\n // would otherwise leave the build with no dictionaries rewritten and no\n // explanation of why.\n let fieldRenameMap: FieldRenameMapByDictionaryKey;\n\n try {\n // The pipeline reports what it purged and minified through the intlayer\n // logger, matching the Vite build output.\n const pruneContext = runIntlayerPurgePipeline(\n getPurgePluginOptions({ configOptions, dictionaries })\n );\n\n fieldRenameMap = serializeFieldRenameMap(pruneContext);\n } catch (pipelineError) {\n appLogger(\n [\n 'Dictionary purge and minification',\n colorize('failed', ANSIColors.RED),\n '— the compiled dictionaries are left untouched.',\n pipelineError instanceof Error\n ? `(${pipelineError.message})`\n : String(pipelineError),\n ],\n { level: 'error' }\n );\n return;\n }\n\n await mkdir(dirname(fieldRenameMapFilePath), { recursive: true });\n await writeFile(\n fieldRenameMapFilePath,\n JSON.stringify(fieldRenameMap),\n 'utf-8'\n );\n};\n\n/** Reads the cached field-rename tables, or `{}` when none were written. */\nconst readFieldRenameMapFile = (\n fieldRenameMapFilePath: string\n): FieldRenameMapByDictionaryKey => {\n try {\n return JSON.parse(\n readFileSync(fieldRenameMapFilePath, 'utf-8')\n ) as FieldRenameMapByDictionaryKey;\n } catch {\n return {};\n }\n};\n\n/** Removes the cached field-rename tables, ignoring a missing file. */\nconst removeFieldRenameMapFile = (fieldRenameMapFilePath: string): void => {\n try {\n rmSync(fieldRenameMapFilePath, { force: true });\n } catch {\n // Nothing to clean up.\n }\n};\n\ntype PrepareSwcOptimizationParams = {\n /** Options forwarded to the intlayer configuration loader. */\n configOptions?: GetConfigurationOptions;\n /** Pre-loaded dictionaries, to avoid a second `getDictionaries` call. */\n dictionaries?: Dictionary[];\n /** Compat-adapter callers declared by the consuming plugin, if any. */\n swcExtraCallers?: SwcExtraCallerConfig[];\n /**\n * Whether the `@intlayer/swc` plugin is installed *and* the resolved Next.js\n * version can load it. False leaves the compiled dictionaries untouched.\n */\n isSwcPluginUsable: boolean;\n};\n\n/**\n * Prepares the parts of the build optimisation the `@intlayer/swc` plugin\n * cannot do itself, and returns the field-rename tables it needs.\n *\n * Removing unused content fields (`build.purge`) and assigning short field\n * aliases (`build.minify`) require reading every component source file and\n * rewriting the compiled dictionary JSON — file I/O and cross-file state that a\n * per-file Wasm transform has no access to. That analysis therefore runs here,\n * in Node, through `@intlayer/babel`; the plugin only receives the resulting\n * tables and rewrites the matching source accesses\n * (`content.title` → `content.a`).\n *\n * The work is coordinated by a sentinel file: Next.js loads `next.config.*` in\n * several processes per build, and running the minify pass twice would derive\n * the aliases from the already-renamed dictionaries. Processes that lose the\n * race read the tables the winner cached.\n *\n * @returns The field-rename tables, keyed by dictionary key. Empty when the\n * pipeline is disabled, unavailable, or renamed nothing.\n */\nexport const prepareSwcOptimization = async (\n intlayerConfig: IntlayerConfig,\n params: PrepareSwcOptimizationParams\n): Promise<FieldRenameMapByDictionaryKey> => {\n const { configOptions, dictionaries, swcExtraCallers, isSwcPluginUsable } =\n params;\n\n const fieldRenameMapFilePath = getCacheFilePath(\n intlayerConfig,\n FIELD_RENAME_MAP_FILE_NAME\n );\n\n // A stale file from an earlier build would rename source accesses that the\n // dictionaries no longer match.\n if (\n !getIsPurgePipelineEnabled(\n intlayerConfig,\n swcExtraCallers,\n isSwcPluginUsable\n )\n ) {\n removeFieldRenameMapFile(fieldRenameMapFilePath);\n return {};\n }\n\n await runOnce(\n getCacheFilePath(intlayerConfig, PURGE_SENTINEL_FILE_NAME),\n () =>\n runPurgePipelineOnce(\n intlayerConfig,\n configOptions,\n dictionaries,\n fieldRenameMapFilePath\n ),\n { cacheTimeoutMs: PURGE_CACHE_TIMEOUT_MS }\n );\n\n return readFieldRenameMapFile(fieldRenameMapFilePath);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"prepareSwcOptimization.mjs","names":[],"sources":["../../../src/server/prepareSwcOptimization.ts"],"sourcesContent":["import { readFileSync, rmSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport type {\n getPurgePluginOptions as GetPurgePluginOptions,\n runIntlayerPurgePipeline as RunIntlayerPurgePipeline,\n SerializedFieldRenameMap,\n serializeFieldRenameMap as SerializeFieldRenameMap,\n} from '@intlayer/babel';\nimport type { SwcExtraCallerConfig } from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport type { GetConfigurationOptions } from '@intlayer/config/node';\nimport { getProjectRequire } from '@intlayer/config/utils';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\n\n/**\n * Field-rename tables keyed by dictionary key, forwarded to the\n * `@intlayer/swc` plugin's `fieldRenameMap` option.\n */\nexport type FieldRenameMapByDictionaryKey = Record<\n string,\n SerializedFieldRenameMap\n>;\n\n/** Verbosity forwarded to the `@intlayer/swc` plugin's `logLevel` option. */\nexport type SwcLogLevel = 'off' | 'info' | 'debug';\n\n/**\n * Subset of `@intlayer/babel` this module needs. The package is only an\n * optional runtime dependency, so it is required lazily and never imported at\n * module scope.\n */\ntype IntlayerBabelModule = {\n getPurgePluginOptions: typeof GetPurgePluginOptions;\n runIntlayerPurgePipeline: typeof RunIntlayerPurgePipeline;\n serializeFieldRenameMap: typeof SerializeFieldRenameMap;\n};\n\n/**\n * Opt-in to the SWC plugin's per-file tracing.\n *\n * The plugin transforms one file at a time with no cross-file state, so all it\n * can report is a line per file — hundreds of them on a real project, and with\n * no counterpart in the Vite build output. The purge and minify summaries that\n * `log.mode` does control are emitted by the pipeline itself, in Node; this\n * variable is purely a debugging aid on top.\n */\nconst SWC_LOG_LEVEL_ENV_VAR = 'INTLAYER_SWC_LOG_LEVEL';\n\n/** Sentinel coordinating the pipeline across the processes of one build. */\nconst PURGE_SENTINEL_FILE_NAME = 'intlayer-swc-purge.lock';\n\n/** Where the serialised field-rename tables are cached between processes. */\nconst FIELD_RENAME_MAP_FILE_NAME = 'swc-field-rename-map.json';\n\n/**\n * Next.js evaluates `next.config.*` in the main build process and again in each\n * Turbopack/webpack worker. The dictionary rewrite must happen exactly once —\n * a second run would derive the short aliases from the already-renamed JSON —\n * so the sentinel window has to cover a whole build startup.\n */\nconst PURGE_CACHE_TIMEOUT_MS = 30 * 1000;\n\n/** Absolute path of a file in the intlayer cache directory. */\nconst getCacheFilePath = (\n intlayerConfig: IntlayerConfig,\n fileName: string\n): string =>\n join(intlayerConfig.system.baseDir, '.intlayer', 'cache', fileName);\n\n/**\n * Resolves the verbosity the `@intlayer/swc` plugin should report at.\n *\n * Off unless {@link SWC_LOG_LEVEL_ENV_VAR} asks for tracing: `log.mode` governs\n * the purge and minify reporting, which the pipeline emits in Node so the\n * Next.js build reads the same as the Vite one.\n */\nexport const resolveSwcLogLevel = (\n intlayerConfig: IntlayerConfig\n): SwcLogLevel => {\n if (intlayerConfig.log.mode === 'disabled') return 'off';\n\n const requestedLogLevel = process.env[SWC_LOG_LEVEL_ENV_VAR];\n\n return requestedLogLevel === 'info' || requestedLogLevel === 'debug'\n ? requestedLogLevel\n : 'off';\n};\n\n/**\n * Whether the purge / minify pipeline should run for this build.\n *\n * Compat-adapter callers disable it: their descriptors reach `withIntlayer`\n * only in the SWC plugin's lossy wire format, so the usage analyser would not\n * recognise `useTranslation(...)` & co. and would purge fields those call sites\n * still read.\n */\nconst getIsPurgePipelineEnabled = (\n intlayerConfig: IntlayerConfig,\n swcExtraCallers: SwcExtraCallerConfig[] | undefined,\n isSwcPluginUsable: boolean\n): boolean => {\n const { purge, minify, optimize } = intlayerConfig.build;\n\n if (optimize === false) return false;\n if (!purge && !minify) return false;\n\n // The pipeline rewrites the compiled dictionaries in place — dropping unused\n // fields and renaming the rest to short aliases. Only the SWC plugin rewrites\n // the matching source accesses, so running this without it would ship\n // dictionaries whose keys no longer match the code reading them.\n if (!isSwcPluginUsable) return false;\n\n // `editor.enabled` is deliberately not checked here: it only stands the\n // field-rename step down — inside the pipeline, and with its own explanation\n // — the same way the Vite build does. Purging still runs, and the rename map\n // the SWC plugin receives comes back empty, so source and JSON stay in sync.\n\n if (swcExtraCallers && swcExtraCallers.length > 0) {\n getAppLogger(intlayerConfig)(\n [\n 'Dictionary purge and minification are',\n colorize('disabled', ANSIColors.GREY_DARK),\n 'because compat-adapter callers are configured — their call sites are',\n 'not visible to the usage analyser.',\n ],\n { level: 'warn' }\n );\n return false;\n }\n\n return true;\n};\n\n/**\n * Exports this module needs from `@intlayer/babel`. Checked one by one so a\n * version predating the purge pipeline is rejected like a missing package,\n * instead of failing later with `runIntlayerPurgePipeline is not a function`.\n */\nconst REQUIRED_BABEL_EXPORTS = [\n 'getPurgePluginOptions',\n 'runIntlayerPurgePipeline',\n 'serializeFieldRenameMap',\n] as const satisfies readonly (keyof IntlayerBabelModule)[];\n\n/**\n * Lazily loads `@intlayer/babel`, or `null` when it is not installed or too old\n * to expose the purge pipeline.\n */\nconst loadIntlayerBabel = (\n intlayerConfig: IntlayerConfig\n): IntlayerBabelModule | null => {\n try {\n const requireFunction =\n intlayerConfig.build?.require ?? getProjectRequire();\n\n const intlayerBabel = requireFunction(\n '@intlayer/babel'\n ) as Partial<IntlayerBabelModule>;\n\n const hasEveryRequiredExport = REQUIRED_BABEL_EXPORTS.every(\n (exportName) => typeof intlayerBabel?.[exportName] === 'function'\n );\n\n if (!hasEveryRequiredExport) return null;\n\n return intlayerBabel as IntlayerBabelModule;\n } catch {\n return null;\n }\n};\n\n/**\n * Whether the purge / minify pipeline can run at all, i.e. whether a usable\n * `@intlayer/babel` is resolvable from the project.\n *\n * Used by `withIntlayer` to keep the build report honest: announcing\n * `Dictionary minification enabled` while the pipeline cannot load would describe a\n * pass that never happens.\n */\nexport const getIsPurgePipelineAvailable = (\n intlayerConfig: IntlayerConfig\n): boolean => loadIntlayerBabel(intlayerConfig) !== null;\n\n/**\n * Runs the purge / minify pipeline and writes the resulting field-rename\n * tables to the cache file so every process of the build reads the same ones.\n */\nconst runPurgePipelineOnce = async (\n intlayerConfig: IntlayerConfig,\n configOptions: GetConfigurationOptions | undefined,\n dictionaries: Dictionary[] | undefined,\n fieldRenameMapFilePath: string\n): Promise<void> => {\n const appLogger = getAppLogger(intlayerConfig);\n\n const intlayerBabel = loadIntlayerBabel(intlayerConfig);\n\n if (!intlayerBabel) {\n // Not verbose: the build asked for purge / minify and is silently getting\n // neither, which is exactly the kind of thing a default build must report.\n appLogger(\n [\n 'Dictionary purge and minification are',\n colorize('disabled', ANSIColors.GREY_DARK),\n 'because',\n colorize('@intlayer/babel', ANSIColors.GREY_LIGHT),\n 'is missing or too old to expose the purge pipeline — install it in',\n 'this project to enable them.',\n ],\n { level: 'warn' }\n );\n return;\n }\n\n const {\n getPurgePluginOptions,\n runIntlayerPurgePipeline,\n serializeFieldRenameMap,\n } = intlayerBabel;\n\n // `runOnce` discards whatever this callback throws, so a pipeline failure\n // would otherwise leave the build with no dictionaries rewritten and no\n // explanation of why.\n let fieldRenameMap: FieldRenameMapByDictionaryKey;\n\n try {\n // The pipeline reports what it purged and minified through the intlayer\n // logger, matching the Vite build output.\n const pruneContext = runIntlayerPurgePipeline(\n getPurgePluginOptions({ configOptions, dictionaries })\n );\n\n fieldRenameMap = serializeFieldRenameMap(pruneContext);\n } catch (pipelineError) {\n appLogger(\n [\n 'Dictionary purge and minification',\n colorize('failed', ANSIColors.RED),\n '— the compiled dictionaries are left untouched.',\n pipelineError instanceof Error\n ? `(${pipelineError.message})`\n : String(pipelineError),\n ],\n { level: 'error' }\n );\n return;\n }\n\n await mkdir(dirname(fieldRenameMapFilePath), { recursive: true });\n await writeFile(\n fieldRenameMapFilePath,\n JSON.stringify(fieldRenameMap),\n 'utf-8'\n );\n};\n\n/** Reads the cached field-rename tables, or `{}` when none were written. */\nconst readFieldRenameMapFile = (\n fieldRenameMapFilePath: string\n): FieldRenameMapByDictionaryKey => {\n try {\n return JSON.parse(\n readFileSync(fieldRenameMapFilePath, 'utf-8')\n ) as FieldRenameMapByDictionaryKey;\n } catch {\n return {};\n }\n};\n\n/** Removes the cached field-rename tables, ignoring a missing file. */\nconst removeFieldRenameMapFile = (fieldRenameMapFilePath: string): void => {\n try {\n rmSync(fieldRenameMapFilePath, { force: true });\n } catch {\n // Nothing to clean up.\n }\n};\n\ntype PrepareSwcOptimizationParams = {\n /** Options forwarded to the intlayer configuration loader. */\n configOptions?: GetConfigurationOptions;\n /** Pre-loaded dictionaries, to avoid a second `getDictionaries` call. */\n dictionaries?: Dictionary[];\n /** Compat-adapter callers declared by the consuming plugin, if any. */\n swcExtraCallers?: SwcExtraCallerConfig[];\n /**\n * Whether the `@intlayer/swc` plugin is installed *and* the resolved Next.js\n * version can load it. False leaves the compiled dictionaries untouched.\n */\n isSwcPluginUsable: boolean;\n};\n\n/**\n * Prepares the parts of the build optimisation the `@intlayer/swc` plugin\n * cannot do itself, and returns the field-rename tables it needs.\n *\n * Removing unused content fields (`build.purge`) and assigning short field\n * aliases (`build.minify`) require reading every component source file and\n * rewriting the compiled dictionary JSON — file I/O and cross-file state that a\n * per-file Wasm transform has no access to. That analysis therefore runs here,\n * in Node, through `@intlayer/babel`; the plugin only receives the resulting\n * tables and rewrites the matching source accesses\n * (`content.title` → `content.a`).\n *\n * The work is coordinated by a sentinel file: Next.js loads `next.config.*` in\n * several processes per build, and running the minify pass twice would derive\n * the aliases from the already-renamed dictionaries. Processes that lose the\n * race read the tables the winner cached.\n *\n * @returns The field-rename tables, keyed by dictionary key. Empty when the\n * pipeline is disabled, unavailable, or renamed nothing.\n */\nexport const prepareSwcOptimization = async (\n intlayerConfig: IntlayerConfig,\n params: PrepareSwcOptimizationParams\n): Promise<FieldRenameMapByDictionaryKey> => {\n const { configOptions, dictionaries, swcExtraCallers, isSwcPluginUsable } =\n params;\n\n const fieldRenameMapFilePath = getCacheFilePath(\n intlayerConfig,\n FIELD_RENAME_MAP_FILE_NAME\n );\n\n // A stale file from an earlier build would rename source accesses that the\n // dictionaries no longer match.\n if (\n !getIsPurgePipelineEnabled(\n intlayerConfig,\n swcExtraCallers,\n isSwcPluginUsable\n )\n ) {\n removeFieldRenameMapFile(fieldRenameMapFilePath);\n return {};\n }\n\n await runOnce(\n getCacheFilePath(intlayerConfig, PURGE_SENTINEL_FILE_NAME),\n () =>\n runPurgePipelineOnce(\n intlayerConfig,\n configOptions,\n dictionaries,\n fieldRenameMapFilePath\n ),\n { cacheTimeoutMs: PURGE_CACHE_TIMEOUT_MS }\n );\n\n return readFieldRenameMapFile(fieldRenameMapFilePath);\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/server/suspendingReader.ts
|
|
4
|
+
/**
|
|
5
|
+
* Turns an async loader into a synchronous reader that suspends until the
|
|
6
|
+
* value is available, without going through `React.use`.
|
|
7
|
+
*
|
|
8
|
+
* `React.use` matches its per-component state positionally across suspense
|
|
9
|
+
* retries, so a `use()` call whose condition can change between attempts
|
|
10
|
+
* (here: the server context is seeded by the provider concurrently with the
|
|
11
|
+
* page render) shifts the index and hands a later `use()` — such as the
|
|
12
|
+
* dynamic dictionary chunk loader — the wrong promise's value. Throwing the
|
|
13
|
+
* promise ourselves and caching the settlement in a request-scoped store
|
|
14
|
+
* keeps the suspension mechanics without touching React's positional state,
|
|
15
|
+
* which makes the ambient chain safe to run conditionally.
|
|
16
|
+
*
|
|
17
|
+
* Requires `React.cache` for per-request isolation; without it (React < 19)
|
|
18
|
+
* the reader reports `undefined` so callers fall back to the default locale,
|
|
19
|
+
* matching the previous behavior.
|
|
20
|
+
*/
|
|
21
|
+
const createSuspendingReader = (load) => {
|
|
22
|
+
if (typeof React.cache !== "function") return () => void 0;
|
|
23
|
+
const getStore = React.cache(() => ({ status: "pending" }));
|
|
24
|
+
return () => {
|
|
25
|
+
const store = getStore();
|
|
26
|
+
if (getStore() !== store) return void 0;
|
|
27
|
+
if (store.status === "resolved") return store.value;
|
|
28
|
+
if (store.status === "rejected") throw store.error;
|
|
29
|
+
if (!store.promise) store.promise = load().then((value) => {
|
|
30
|
+
store.value = value;
|
|
31
|
+
store.status = "resolved";
|
|
32
|
+
}, (error) => {
|
|
33
|
+
store.error = error;
|
|
34
|
+
store.status = "rejected";
|
|
35
|
+
});
|
|
36
|
+
throw store.promise;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
//#endregion
|
|
41
|
+
export { createSuspendingReader };
|
|
42
|
+
//# sourceMappingURL=suspendingReader.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suspendingReader.mjs","names":[],"sources":["../../../src/server/suspendingReader.ts"],"sourcesContent":["import React from 'react';\n\ntype AsyncRungStore<T> = {\n status: 'pending' | 'resolved' | 'rejected';\n value?: T;\n error?: unknown;\n promise?: Promise<void>;\n};\n\n/**\n * Turns an async loader into a synchronous reader that suspends until the\n * value is available, without going through `React.use`.\n *\n * `React.use` matches its per-component state positionally across suspense\n * retries, so a `use()` call whose condition can change between attempts\n * (here: the server context is seeded by the provider concurrently with the\n * page render) shifts the index and hands a later `use()` — such as the\n * dynamic dictionary chunk loader — the wrong promise's value. Throwing the\n * promise ourselves and caching the settlement in a request-scoped store\n * keeps the suspension mechanics without touching React's positional state,\n * which makes the ambient chain safe to run conditionally.\n *\n * Requires `React.cache` for per-request isolation; without it (React < 19)\n * the reader reports `undefined` so callers fall back to the default locale,\n * matching the previous behavior.\n */\nexport const createSuspendingReader = <T>(\n load: () => Promise<T | undefined>\n): (() => T | undefined) => {\n if (typeof React.cache !== 'function') return () => undefined;\n\n const getStore = React.cache(\n (): AsyncRungStore<T | undefined> => ({ status: 'pending' })\n );\n\n return (): T | undefined => {\n const store = getStore();\n\n // Suspending is only safe when the store survives the retry: React replays\n // the component from the top, so a cache that hands back a fresh store\n // every call would restart the load and throw a new promise forever. That\n // is what `React.cache` degrades to outside a request scope — notably in\n // the SSR pass of client components, where it is a passthrough. Reporting\n // no value there lets the caller fall back instead of hanging the render.\n if (getStore() !== store) return undefined;\n\n if (store.status === 'resolved') return store.value;\n if (store.status === 'rejected') throw store.error;\n\n if (!store.promise) {\n store.promise = load().then(\n (value) => {\n store.value = value;\n store.status = 'resolved';\n },\n (error) => {\n store.error = error;\n store.status = 'rejected';\n }\n );\n }\n\n // Suspend: React retries the component once the promise settles.\n throw store.promise;\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA0BA,MAAa,0BACX,SAC0B;CAC1B,IAAI,OAAO,MAAM,UAAU,YAAY,aAAa;CAEpD,MAAM,WAAW,MAAM,aACiB,EAAE,QAAQ,UAAU,EAC5D;CAEA,aAA4B;EAC1B,MAAM,QAAQ,SAAS;EAQvB,IAAI,SAAS,MAAM,OAAO,OAAO;EAEjC,IAAI,MAAM,WAAW,YAAY,OAAO,MAAM;EAC9C,IAAI,MAAM,WAAW,YAAY,MAAM,MAAM;EAE7C,IAAI,CAAC,MAAM,SACT,MAAM,UAAU,KAAK,CAAC,CAAC,MACpB,UAAU;GACT,MAAM,QAAQ;GACd,MAAM,SAAS;EACjB,IACC,UAAU;GACT,MAAM,QAAQ;GACd,MAAM,SAAS;EACjB,CACF;EAIF,MAAM,MAAM;CACd;AACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { resolveAmbientLocale } from "./ambientLocale.mjs";
|
|
2
|
+
import { t as t$1 } from "react-intlayer/server";
|
|
3
|
+
|
|
4
|
+
//#region src/server/t.ts
|
|
5
|
+
/**
|
|
6
|
+
* On the server side, returns the translation of a multilingual object.
|
|
7
|
+
*
|
|
8
|
+
* If the locale is not provided, it will use the locale from the server
|
|
9
|
+
* context, falling back to the locale carried by the request.
|
|
10
|
+
*/
|
|
11
|
+
const t = (multilangContent, locale) => t$1(multilangContent, resolveAmbientLocale(locale));
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { t };
|
|
15
|
+
//# sourceMappingURL=t.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"t.mjs","names":["tBase"],"sources":["../../../src/server/t.ts"],"sourcesContent":["import type {\n DeclaredLocales,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { t as tBase } from 'react-intlayer/server';\nimport { resolveAmbientLocale } from './ambientLocale';\n\n/**\n * On the server side, returns the translation of a multilingual object.\n *\n * If the locale is not provided, it will use the locale from the server\n * context, falling back to the locale carried by the request.\n */\nexport const t = <Content = string, L extends LocalesValues = DeclaredLocales>(\n multilangContent: StrictModeLocaleMap<Content>,\n locale?: L\n): ReturnType<typeof tBase<Content, L>> =>\n tBase<Content, L>(multilangContent, resolveAmbientLocale(locale) as L);\n"],"mappings":";;;;;;;;;;AAcA,MAAa,KACX,kBACA,WAEAA,IAAkB,kBAAkB,qBAAqB,MAAM,CAAM"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveFallbackLocale } from "./ambientLocale.mjs";
|
|
2
2
|
import { useDictionary as useDictionary$1 } from "react-intlayer/server";
|
|
3
3
|
|
|
4
4
|
//#region src/server/useDictionary.ts
|
|
@@ -6,11 +6,12 @@ import { useDictionary as useDictionary$1 } from "react-intlayer/server";
|
|
|
6
6
|
* On the server side, hook that transforms a dictionary (or qualified
|
|
7
7
|
* dictionary group) and returns the content for the given locale or selector.
|
|
8
8
|
*
|
|
9
|
-
* If the locale is not provided, it will use the locale from the server
|
|
9
|
+
* If the locale is not provided, it will use the locale from the server
|
|
10
|
+
* context, falling back to the locale carried by the request.
|
|
10
11
|
*/
|
|
11
12
|
const useDictionary = (dictionary, localeOrSelector) => {
|
|
12
|
-
const
|
|
13
|
-
return useDictionary$1(dictionary, localeOrSelector,
|
|
13
|
+
const fallbackLocale = resolveFallbackLocale(localeOrSelector);
|
|
14
|
+
return useDictionary$1(dictionary, localeOrSelector, fallbackLocale);
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionary.mjs","names":["useDictionaryBase"],"sources":["../../../src/server/useDictionary.ts"],"sourcesContent":["import type {\n Dictionary,\n
|
|
1
|
+
{"version":3,"file":"useDictionary.mjs","names":["useDictionaryBase"],"sources":["../../../src/server/useDictionary.ts"],"sourcesContent":["import type {\n Dictionary,\n DictionarySelectorForGroup,\n QualifiedDictionaryGroup,\n} from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { useDictionary as useDictionaryBase } from 'react-intlayer/server';\nimport { resolveFallbackLocale } from './ambientLocale';\n\n/**\n * On the server side, hook that transforms a dictionary (or qualified\n * dictionary group) and returns the content for the given locale or selector.\n *\n * If the locale is not provided, it will use the locale from the server\n * context, falling back to the locale carried by the request.\n */\nexport const useDictionary = <\n const T extends Dictionary | QualifiedDictionaryGroup,\n const A extends\n | LocalesValues\n | DictionarySelectorForGroup<T> = DeclaredLocales,\n>(\n dictionary: T,\n localeOrSelector?: A\n): ReturnType<typeof useDictionaryBase<T, A>> => {\n const fallbackLocale = resolveFallbackLocale(localeOrSelector);\n\n return useDictionaryBase<T, A>(dictionary, localeOrSelector, fallbackLocale);\n};\n"],"mappings":";;;;;;;;;;;AAmBA,MAAa,iBAMX,YACA,qBAC+C;CAC/C,MAAM,iBAAiB,sBAAsB,gBAAgB;CAE7D,OAAOA,gBAAwB,YAAY,kBAAkB,cAAc;AAC7E"}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getFallbackLocale } from "./ambientLocale.mjs";
|
|
2
2
|
import { useDictionaryAsync as useDictionaryAsync$1 } from "react-intlayer/server";
|
|
3
3
|
|
|
4
4
|
//#region src/server/useDictionaryAsync.ts
|
|
5
5
|
/**
|
|
6
|
-
* On the server side,
|
|
6
|
+
* On the server side, hook that transforms a dictionary and returns the content
|
|
7
7
|
*
|
|
8
|
-
* If the locale is not provided, it will use the locale from the server
|
|
8
|
+
* If the locale is not provided, it will use the locale from the server
|
|
9
|
+
* context, falling back to the locale carried by the request.
|
|
9
10
|
*/
|
|
10
|
-
const useDictionaryAsync = async (dictionaryPromise, locale) =>
|
|
11
|
-
const storedLocale = await getLocale();
|
|
12
|
-
return useDictionaryAsync$1(dictionaryPromise, locale, storedLocale);
|
|
13
|
-
};
|
|
11
|
+
const useDictionaryAsync = async (dictionaryPromise, locale) => useDictionaryAsync$1(dictionaryPromise, locale, await getFallbackLocale(locale));
|
|
14
12
|
|
|
15
13
|
//#endregion
|
|
16
14
|
export { useDictionaryAsync };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryAsync.mjs","names":["useDictionaryAsyncBase"],"sources":["../../../src/server/useDictionaryAsync.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useDictionaryAsync as useDictionaryAsyncBase } from 'react-intlayer/server';\nimport {
|
|
1
|
+
{"version":3,"file":"useDictionaryAsync.mjs","names":["useDictionaryAsyncBase"],"sources":["../../../src/server/useDictionaryAsync.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useDictionaryAsync as useDictionaryAsyncBase } from 'react-intlayer/server';\nimport { getFallbackLocale } from './ambientLocale';\n\n/**\n * On the server side, hook that transforms a dictionary and returns the content\n *\n * If the locale is not provided, it will use the locale from the server\n * context, falling back to the locale carried by the request.\n */\nexport const useDictionaryAsync = async <\n const T extends Dictionary,\n const L extends LocalesValues = DeclaredLocales,\n>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n locale?: L\n): ReturnType<typeof useDictionaryAsyncBase<T, L>> =>\n useDictionaryAsyncBase<T, L>(\n dictionaryPromise,\n locale,\n (await getFallbackLocale(locale)) as DeclaredLocales | undefined\n );\n"],"mappings":";;;;;;;;;;AAeA,MAAa,qBAAqB,OAIhC,mBACA,WAEAA,qBACE,mBACA,QACC,MAAM,kBAAkB,MAAM,CACjC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveFallbackLocale } from "./ambientLocale.mjs";
|
|
2
2
|
import { useDictionaryDynamic as useDictionaryDynamic$1 } from "react-intlayer/server";
|
|
3
3
|
|
|
4
4
|
//#region src/server/useDictionaryDynamic.ts
|
|
@@ -6,11 +6,12 @@ import { useDictionaryDynamic as useDictionaryDynamic$1 } from "react-intlayer/s
|
|
|
6
6
|
* On the server side, hook that lazily loads a dictionary (plain or qualified)
|
|
7
7
|
* and returns the content for the given locale or selector.
|
|
8
8
|
*
|
|
9
|
-
* If the locale is not provided, it will use the locale from the server
|
|
9
|
+
* If the locale is not provided, it will use the locale from the server
|
|
10
|
+
* context, falling back to the locale carried by the request.
|
|
10
11
|
*/
|
|
11
12
|
const useDictionaryDynamic = (dictionaryPromise, key, localeOrSelector) => {
|
|
12
|
-
const
|
|
13
|
-
return useDictionaryDynamic$1(dictionaryPromise, key, localeOrSelector,
|
|
13
|
+
const fallbackLocale = resolveFallbackLocale(localeOrSelector);
|
|
14
|
+
return useDictionaryDynamic$1(dictionaryPromise, key, localeOrSelector, fallbackLocale);
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryDynamic.mjs","names":["useDictionaryDynamicBase"],"sources":["../../../src/server/useDictionaryDynamic.ts"],"sourcesContent":["import type { QualifiedDynamicLoaderMap } from '@intlayer/core/dictionaryManipulator';\nimport type {\n Dictionary,\n DictionarySelector,\n} from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useDictionaryDynamic as useDictionaryDynamicBase } from 'react-intlayer/server';\nimport {
|
|
1
|
+
{"version":3,"file":"useDictionaryDynamic.mjs","names":["useDictionaryDynamicBase"],"sources":["../../../src/server/useDictionaryDynamic.ts"],"sourcesContent":["import type { QualifiedDynamicLoaderMap } from '@intlayer/core/dictionaryManipulator';\nimport type {\n Dictionary,\n DictionarySelector,\n} from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useDictionaryDynamic as useDictionaryDynamicBase } from 'react-intlayer/server';\nimport { resolveFallbackLocale } from './ambientLocale';\n\n/**\n * On the server side, hook that lazily loads a dictionary (plain or qualified)\n * and returns the content for the given locale or selector.\n *\n * If the locale is not provided, it will use the locale from the server\n * context, falling back to the locale carried by the request.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const A extends LocalesValues | DictionarySelector = DeclaredLocales,\n>(\n dictionaryPromise:\n | StrictModeLocaleMap<() => Promise<T>>\n | QualifiedDynamicLoaderMap,\n key: string,\n localeOrSelector?: A\n): ReturnType<typeof useDictionaryDynamicBase<T, A>> => {\n const fallbackLocale = resolveFallbackLocale(localeOrSelector);\n\n return useDictionaryDynamicBase<T, A>(\n dictionaryPromise,\n key,\n localeOrSelector,\n fallbackLocale\n );\n};\n"],"mappings":";;;;;;;;;;;AAoBA,MAAa,wBAIX,mBAGA,KACA,qBACsD;CACtD,MAAM,iBAAiB,sBAAsB,gBAAgB;CAE7D,OAAOA,uBACL,mBACA,KACA,kBACA,cACF;AACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { resolveAmbientLocale } from "./ambientLocale.mjs";
|
|
2
|
+
import { useI18n as useI18n$1 } from "react-intlayer/server";
|
|
3
|
+
|
|
4
|
+
//#region src/server/useI18n.ts
|
|
5
|
+
/**
|
|
6
|
+
* On the server side, hook returning a `t(path)` function scoped to one
|
|
7
|
+
* dictionary key, in the i18next / next-intl style.
|
|
8
|
+
*
|
|
9
|
+
* If the locale is not provided, it will use the locale from the server
|
|
10
|
+
* context, falling back to the locale carried by the request.
|
|
11
|
+
*/
|
|
12
|
+
const useI18n = (namespace, locale) => useI18n$1(namespace, resolveAmbientLocale(locale));
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
export { useI18n };
|
|
16
|
+
//# sourceMappingURL=useI18n.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useI18n.mjs","names":["useI18nBase"],"sources":["../../../src/server/useI18n.ts"],"sourcesContent":["import type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { useI18n as useI18nBase } from 'react-intlayer/server';\nimport { resolveAmbientLocale } from './ambientLocale';\n\n/**\n * On the server side, hook returning a `t(path)` function scoped to one\n * dictionary key, in the i18next / next-intl style.\n *\n * If the locale is not provided, it will use the locale from the server\n * context, falling back to the locale carried by the request.\n */\nexport const useI18n = <T extends DictionaryKeys>(\n namespace: T,\n locale?: LocalesValues\n): ReturnType<typeof useI18nBase<T>> =>\n useI18nBase<T>(namespace, resolveAmbientLocale(locale));\n"],"mappings":";;;;;;;;;;;AAcA,MAAa,WACX,WACA,WAEAA,UAAe,WAAW,qBAAqB,MAAM,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { resolveAmbientLocale } from "./ambientLocale.mjs";
|
|
2
|
+
import { useIntl as useIntl$1 } from "react-intlayer/server";
|
|
3
|
+
|
|
4
|
+
//#region src/server/useIntl.ts
|
|
5
|
+
/**
|
|
6
|
+
* On the server side, hook providing a locale-bound `Intl` object.
|
|
7
|
+
*
|
|
8
|
+
* If the locale is not provided, it will use the locale from the server
|
|
9
|
+
* context, falling back to the locale carried by the request.
|
|
10
|
+
*/
|
|
11
|
+
const useIntl = (locale) => useIntl$1(resolveAmbientLocale(locale));
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { useIntl };
|
|
15
|
+
//# sourceMappingURL=useIntl.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useIntl.mjs","names":["useIntlBase"],"sources":["../../../src/server/useIntl.ts"],"sourcesContent":["import type { WrappedIntl } from '@intlayer/core/formatters';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { useIntl as useIntlBase } from 'react-intlayer/server';\nimport { resolveAmbientLocale } from './ambientLocale';\n\n/**\n * On the server side, hook providing a locale-bound `Intl` object.\n *\n * If the locale is not provided, it will use the locale from the server\n * context, falling back to the locale carried by the request.\n */\nexport const useIntl = (locale?: LocalesValues): WrappedIntl =>\n useIntlBase(resolveAmbientLocale(locale));\n"],"mappings":";;;;;;;;;;AAWA,MAAa,WAAW,WACtBA,UAAY,qBAAqB,MAAM,CAAC"}
|
|
@@ -1,29 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import React from "react";
|
|
1
|
+
import { resolveFallbackLocale } from "./ambientLocale.mjs";
|
|
3
2
|
import { useIntlayer as useIntlayer$1 } from "react-intlayer/server";
|
|
4
3
|
|
|
5
4
|
//#region src/server/useIntlayer.ts
|
|
6
|
-
const getCachedLocale = typeof React.cache === "function" ? React.cache(getLocale) : getLocale;
|
|
7
|
-
const safeUseLocale = () => {
|
|
8
|
-
const localeData = getCachedLocale();
|
|
9
|
-
if (localeData instanceof Promise) {
|
|
10
|
-
if (typeof React.use === "function") return React.use(localeData);
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
return localeData;
|
|
14
|
-
};
|
|
15
5
|
/**
|
|
16
|
-
* On the server side, hook
|
|
6
|
+
* On the server side, hook picking one dictionary by its key and returning the
|
|
17
7
|
* content for the given locale or selector (`{ item }`, `{ variant }`,
|
|
18
8
|
* optionally combined with `locale`).
|
|
19
9
|
*
|
|
20
|
-
* If the locale is not provided, it will use the locale from the server
|
|
10
|
+
* If the locale is not provided, it will use the locale from the server
|
|
11
|
+
* context, falling back to the locale carried by the request.
|
|
21
12
|
*/
|
|
22
|
-
const useIntlayer = (key, localeOrSelector) =>
|
|
23
|
-
const storedLocale = safeUseLocale();
|
|
24
|
-
return useIntlayer$1(key, localeOrSelector, storedLocale);
|
|
25
|
-
};
|
|
13
|
+
const useIntlayer = (key, localeOrSelector) => useIntlayer$1(key, localeOrSelector, resolveFallbackLocale(localeOrSelector));
|
|
26
14
|
|
|
27
15
|
//#endregion
|
|
28
|
-
export {
|
|
16
|
+
export { useIntlayer };
|
|
29
17
|
//# sourceMappingURL=useIntlayer.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useIntlayer.mjs","names":["useIntlayerBase"],"sources":["../../../src/server/useIntlayer.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"useIntlayer.mjs","names":["useIntlayerBase"],"sources":["../../../src/server/useIntlayer.ts"],"sourcesContent":["import type {\n DeclaredLocales,\n DictionaryKeys,\n DictionarySelectorForKey,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { useIntlayer as useIntlayerBase } from 'react-intlayer/server';\nimport { resolveFallbackLocale } from './ambientLocale';\n\n/**\n * On the server side, hook picking one dictionary by its key and returning the\n * content for the given locale or selector (`{ item }`, `{ variant }`,\n * optionally combined with `locale`).\n *\n * If the locale is not provided, it will use the locale from the server\n * context, falling back to the locale carried by the request.\n */\nexport const useIntlayer = <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<T> = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A\n): ReturnType<typeof useIntlayerBase<T, A>> =>\n useIntlayerBase<T, A>(\n key,\n localeOrSelector,\n resolveFallbackLocale(localeOrSelector) as DeclaredLocales | undefined\n );\n"],"mappings":";;;;;;;;;;;;AAiBA,MAAa,eAIX,KACA,qBAEAA,cACE,KACA,kBACA,sBAAsB,gBAAgB,CACxC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { resolveAmbientLocale } from "./ambientLocale.mjs";
|
|
2
|
+
import { internationalization } from "@intlayer/config/built";
|
|
3
|
+
|
|
4
|
+
//#region src/server/useLocale.ts
|
|
5
|
+
/**
|
|
6
|
+
* On the server side, hook returning the current locale along with the default
|
|
7
|
+
* and available ones.
|
|
8
|
+
*
|
|
9
|
+
* Reimplemented rather than re-exported from `react-intlayer/server`: that one
|
|
10
|
+
* takes no locale argument, so there is no way to hand it the ambient locale —
|
|
11
|
+
* it would read the server context alone and report the default locale on any
|
|
12
|
+
* render the provider did not reach.
|
|
13
|
+
*/
|
|
14
|
+
const useLocale = () => {
|
|
15
|
+
const { defaultLocale, locales: availableLocales } = internationalization ?? {};
|
|
16
|
+
return {
|
|
17
|
+
locale: resolveAmbientLocale() ?? defaultLocale,
|
|
18
|
+
defaultLocale,
|
|
19
|
+
availableLocales
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { useLocale };
|
|
25
|
+
//# sourceMappingURL=useLocale.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLocale.mjs","names":[],"sources":["../../../src/server/useLocale.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { DeclaredLocales } from '@intlayer/types/module_augmentation';\nimport { resolveAmbientLocale } from './ambientLocale';\n\nexport type UseLocaleResult = {\n locale: DeclaredLocales;\n defaultLocale: DeclaredLocales;\n availableLocales: DeclaredLocales[];\n};\n\n/**\n * On the server side, hook returning the current locale along with the default\n * and available ones.\n *\n * Reimplemented rather than re-exported from `react-intlayer/server`: that one\n * takes no locale argument, so there is no way to hand it the ambient locale —\n * it would read the server context alone and report the default locale on any\n * render the provider did not reach.\n */\nexport const useLocale = (): UseLocaleResult => {\n const { defaultLocale, locales: availableLocales } =\n internationalization ?? {};\n\n const locale = (resolveAmbientLocale() ?? defaultLocale) as DeclaredLocales;\n\n return { locale, defaultLocale, availableLocales };\n};\n"],"mappings":";;;;;;;;;;;;;AAmBA,MAAa,kBAAmC;CAC9C,MAAM,EAAE,eAAe,SAAS,qBAC9B,wBAAwB,CAAC;CAI3B,OAAO;EAAE,QAFO,qBAAqB,KAAK;EAEzB;EAAe;CAAiB;AACnD"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { getIsPurgePipelineAvailable, prepareSwcOptimization, resolveSwcLogLevel } from "./prepareSwcOptimization.mjs";
|
|
2
2
|
import { MINIMUM_SWC_PLUGIN_NEXT_VERSION, getIsSwcPluginSupported } from "./swcPluginCompatibility.mjs";
|
|
3
3
|
import { IMPORT_MODE } from "@intlayer/config/defaultValues";
|
|
4
|
-
import { colorize, getAppLogger } from "@intlayer/config/logger";
|
|
5
4
|
import { join, relative, resolve } from "node:path";
|
|
6
5
|
import * as ANSIColors from "@intlayer/config/colors";
|
|
7
6
|
import { formatDictionarySelectorEnvVar, formatNodeTypeToEnvVar, formatOptimizedNestingEnvVar, getConfigEnvVars } from "@intlayer/config/envVars";
|
|
7
|
+
import { colorize, getAppLogger } from "@intlayer/config/logger";
|
|
8
8
|
import { getConfiguration } from "@intlayer/config/node";
|
|
9
9
|
import { compareVersions, getAlias, getHasDictionarySelector, getProjectRequire, getUnusedNodeTypes, normalizePath } from "@intlayer/config/utils";
|
|
10
10
|
import { getNestedDictionaryGraph } from "@intlayer/core/dictionaryManipulator";
|
|
@@ -63,7 +63,6 @@ const resolvePluginPath = (pluginPath, intlayerConfig, isTurbopackEnabled) => {
|
|
|
63
63
|
};
|
|
64
64
|
const getPruneConfig = ({ intlayerConfig, isBuildCommand, isTurbopackEnabled, isDevCommand, isGteNext13, isSwcPluginSupported, nextVersion, swcExtraCallers, fieldRenameMap }) => {
|
|
65
65
|
const { optimize, minify, purge } = intlayerConfig.build;
|
|
66
|
-
const editorEnabled = intlayerConfig.editor.enabled;
|
|
67
66
|
const importMode = intlayerConfig.build.importMode ?? intlayerConfig.dictionary?.importMode;
|
|
68
67
|
const { dictionariesDir, unmergedDictionariesDir, dynamicDictionariesDir, fetchDictionariesDir, mainDir } = intlayerConfig.system;
|
|
69
68
|
const { baseDir } = intlayerConfig.system;
|
|
@@ -88,7 +87,7 @@ const getPruneConfig = ({ intlayerConfig, isBuildCommand, isTurbopackEnabled, is
|
|
|
88
87
|
colorize(importMode ?? IMPORT_MODE, ANSIColors.BLUE),
|
|
89
88
|
colorize(`)`, ANSIColors.GREY_DARK)
|
|
90
89
|
]);
|
|
91
|
-
const isPurgePipelineEnabled = !
|
|
90
|
+
const isPurgePipelineEnabled = !swcExtraCallers?.length && getIsPurgePipelineAvailable(intlayerConfig);
|
|
92
91
|
if (isPurgePipelineEnabled && minify) logger(`Dictionary minification ${colorize("enabled", ANSIColors.GREEN)}`);
|
|
93
92
|
if (isPurgePipelineEnabled && purge) logger(`Dictionary purge unused keys ${colorize("enabled", ANSIColors.GREEN)}`);
|
|
94
93
|
} else logger([
|