react-native-intlayer 9.0.0-canary.5 → 9.0.0-canary.6

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.
@@ -0,0 +1,9 @@
1
+
2
+
3
+ var react_intlayer_format = require("react-intlayer/format");
4
+ Object.keys(react_intlayer_format).forEach(function (k) {
5
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
6
+ enumerable: true,
7
+ get: function () { return react_intlayer_format[k]; }
8
+ });
9
+ });
@@ -32,6 +32,21 @@ const configMetroIntlayerSync = (baseConfig) => {
32
32
  configuration,
33
33
  formatter: node_path.resolve
34
34
  });
35
+ /**
36
+ * Project root, used to force `react-intlayer` to resolve to a single copy.
37
+ *
38
+ * Metro does not deduplicate packages the way web bundlers do. When a
39
+ * dependency (e.g. `react-native-intlayer`) pins a different patch of
40
+ * `react-intlayer` than the app, npm/yarn keep two physical copies. The
41
+ * provider would then create its React context from one copy while
42
+ * `useLocale`/`useIntlayer` read the context from the other — two distinct
43
+ * `IntlayerClientContext` instances. The provider's updates never reach the
44
+ * consumers, so `setLocale()` silently does nothing on native.
45
+ *
46
+ * Resolving every `react-intlayer` request from the project root collapses
47
+ * those copies to a single module instance (and therefore a single context).
48
+ */
49
+ const projectRoot = configuration.system.baseDir;
35
50
  const existingBlockList = baseConfig?.resolver?.blockList;
36
51
  const existingPatterns = existingBlockList instanceof RegExp ? [existingBlockList] : existingBlockList ?? [];
37
52
  const existingResolveRequest = baseConfig?.resolver?.resolveRequest;
@@ -69,6 +84,12 @@ const configMetroIntlayerSync = (baseConfig) => {
69
84
  filePath: require.resolve("@intlayer/core/file/browser"),
70
85
  type: "sourceFile"
71
86
  };
87
+ if (moduleName === "react-intlayer" || moduleName.startsWith("react-intlayer/")) try {
88
+ return {
89
+ filePath: require.resolve(moduleName, { paths: [projectRoot] }),
90
+ type: "sourceFile"
91
+ };
92
+ } catch {}
72
93
  if (moduleName.startsWith("@formatjs/")) {
73
94
  inflightFallbackContexts.add(context);
74
95
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"configMetroIntlayer.cjs","names":["pathResolve"],"sources":["../../src/configMetroIntlayer.ts"],"sourcesContent":["import { resolve as pathResolve } from 'node:path';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { getAlias } from '@intlayer/config/utils';\nimport type { getDefaultConfig } from 'expo/metro-config';\n\n/**\n * Returns the `resolve` function from metro-resolver, preferring the copy\n * bundled inside Metro itself. Loading from Metro's own package directory\n * ensures we use the same resolver instance that Metro uses internally,\n * which prevents the cross-version recursion described in\n * https://github.com/aymericzip/intlayer/issues/457.\n */\ntype AnyResolver = (context: any, moduleName: string, ...args: any[]) => any;\n\nconst getMetroResolve = (): AnyResolver => {\n try {\n const metroPackageDir = pathResolve(\n require.resolve('metro/package.json'),\n '..'\n );\n return (\n require(\n pathResolve(metroPackageDir, 'node_modules', 'metro-resolver')\n ) as typeof import('metro-resolver')\n ).resolve as AnyResolver;\n } catch {\n return (require('metro-resolver') as typeof import('metro-resolver'))\n .resolve as AnyResolver;\n }\n};\n\ntype MetroConfig = ReturnType<typeof getDefaultConfig>;\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayerSync } = require(\"react-native-intlayer/metro\");\n *\n *\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return configMetroIntlayerSync(defaultConfig);\n * ```\n *\n * > Note: `configMetroIntlayerSync` does not build intlayer dictionaries on server start. Use `configMetroIntlayer` for that.\n */\nexport const configMetroIntlayerSync = (\n baseConfig?: MetroConfig\n): MetroConfig => {\n const configuration = getConfiguration();\n\n const alias = getAlias({\n configuration,\n formatter: pathResolve, // get absolute path\n });\n\n const existingBlockList = baseConfig?.resolver?.blockList;\n const existingPatterns: RegExp[] =\n existingBlockList instanceof RegExp\n ? [existingBlockList]\n : (existingBlockList ?? []);\n\n const existingResolveRequest = baseConfig?.resolver?.resolveRequest;\n\n /**\n * Tracks resolution contexts that are currently executing inside the\n * metro-resolver fallback call. When metro-resolver cannot find a module it\n * may call back through `context.resolveRequest` (the outermost resolver in\n * the chain, e.g. Sentry → NativeWind → ours). That callback eventually\n * reaches our resolver again. Without a guard we would recurse indefinitely\n * (see issue #457).\n *\n * On the second entry we break the cycle by stripping `resolveRequest` from\n * the context so metro-resolver finishes with its built-in logic only\n * (alias, extraNodeModules, …) rather than calling back a third time.\n *\n * Metro creates a fresh context object per module resolution, so using a\n * WeakSet keyed on context is safe and causes no cross-resolution\n * interference.\n */\n const inflightFallbackContexts = new WeakSet<object>();\n\n const config = {\n ...baseConfig,\n\n resolver: {\n ...baseConfig?.resolver,\n resolveRequest: (context, moduleName, ...args) => {\n if (Object.keys(alias).includes(moduleName)) {\n return {\n filePath: alias[moduleName as keyof typeof alias],\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/config/client') {\n return {\n filePath: require.resolve('@intlayer/config/client'),\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/core/file') {\n // Force React Native to use the correct transpiled version\n return {\n filePath: require.resolve('@intlayer/core/file/browser'),\n type: 'sourceFile',\n };\n }\n\n // @formatjs packages have invalid exports configuration or missing exports for polyfills\n // By disabling package exports for these modules, we avoid the Metro warnings and let it\n // fall back cleanly to file-based resolution.\n if (moduleName.startsWith('@formatjs/')) {\n inflightFallbackContexts.add(context);\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cleanContext = {\n ...(context as any),\n unstable_enablePackageExports: false,\n };\n return getMetroResolve()(cleanContext, moduleName, ...args);\n } finally {\n inflightFallbackContexts.delete(context);\n }\n }\n\n // Delegate to the user-provided resolver if present\n if (existingResolveRequest) {\n return existingResolveRequest(context, moduleName, ...args);\n }\n\n // Re-entry guard: metro-resolver has already been invoked for this\n // context and is now calling back through context.resolveRequest (the\n // outer chain) which has bubbled back to us. Strip resolveRequest so\n // metro-resolver resolves the module with only its built-in rules\n // (alias, extraNodeModules, etc.) and does not recurse again.\n if (inflightFallbackContexts.has(context)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const { resolveRequest: _r, ...pureContext } = context as any;\n return getMetroResolve()(pureContext, moduleName, ...args);\n }\n\n // First pass: call metro-resolver while preserving context.resolveRequest\n // so outer wrappers (NativeWind, Sentry, …) still get a chance to\n // handle modules that metro-resolver cannot locate on its own (e.g. @/\n // tsconfig path aliases that a wrapper resolves via its own logic).\n inflightFallbackContexts.add(context);\n try {\n return getMetroResolve()(context, moduleName, ...args);\n } finally {\n inflightFallbackContexts.delete(context);\n }\n },\n blockList: [\n ...existingPatterns,\n ...configuration.content.fileExtensions.map(\n (ext) => new RegExp(`.*${ext.replace(/\\./g, '\\\\.')}$`)\n ),\n ],\n },\n } as MetroConfig;\n\n return config;\n};\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayer } = require(\"react-native-intlayer/metro\");\n *\n * module.exports = (async () => {\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return await configMetroIntlayer(defaultConfig);\n * })();\n * ```\n *\n * > Note: `configMetroIntlayer` builds intlayer dictionaries on server start. Use `configMetroIntlayerSync` instead if you want to skip that.\n */\nexport const configMetroIntlayer = async (\n baseConfig?: MetroConfig\n): Promise<MetroConfig> => {\n const configuration = getConfiguration();\n\n await prepareIntlayer(configuration);\n\n return configMetroIntlayerSync(baseConfig);\n};\n"],"mappings":";;;;;;;AAeA,MAAM,wBAAqC;AACzC,KAAI;EACF,MAAM,yCACJ,QAAQ,QAAQ,qBAAqB,EACrC,KACD;AACD,SACE,+BACc,iBAAiB,gBAAgB,iBAAiB,CAC/D,CACD;SACI;AACN,SAAQ,QAAQ,iBAAiB,CAC9B;;;;;;;;;;;;;;;;AAmBP,MAAa,2BACX,eACgB;CAChB,MAAM,6DAAkC;CAExC,MAAM,6CAAiB;EACrB;EACA,WAAWA;EACZ,CAAC;CAEF,MAAM,oBAAoB,YAAY,UAAU;CAChD,MAAM,mBACJ,6BAA6B,SACzB,CAAC,kBAAkB,GAClB,qBAAqB,EAAE;CAE9B,MAAM,yBAAyB,YAAY,UAAU;;;;;;;;;;;;;;;;;CAkBrD,MAAM,2CAA2B,IAAI,SAAiB;AAqFtD,QAAO;EAlFL,GAAG;EAEH,UAAU;GACR,GAAG,YAAY;GACf,iBAAiB,SAAS,YAAY,GAAG,SAAS;AAChD,QAAI,OAAO,KAAK,MAAM,CAAC,SAAS,WAAW,CACzC,QAAO;KACL,UAAU,MAAM;KAChB,MAAM;KACP;AAIH,QAAI,eAAe,0BACjB,QAAO;KACL,UAAU,QAAQ,QAAQ,0BAA0B;KACpD,MAAM;KACP;AAIH,QAAI,eAAe,sBAEjB,QAAO;KACL,UAAU,QAAQ,QAAQ,8BAA8B;KACxD,MAAM;KACP;AAMH,QAAI,WAAW,WAAW,aAAa,EAAE;AACvC,8BAAyB,IAAI,QAAQ;AACrC,SAAI;MAEF,MAAM,eAAe;OACnB,GAAI;OACJ,+BAA+B;OAChC;AACD,aAAO,iBAAiB,CAAC,cAAc,YAAY,GAAG,KAAK;eACnD;AACR,+BAAyB,OAAO,QAAQ;;;AAK5C,QAAI,uBACF,QAAO,uBAAuB,SAAS,YAAY,GAAG,KAAK;AAQ7D,QAAI,yBAAyB,IAAI,QAAQ,EAAE;KAEzC,MAAM,EAAE,gBAAgB,IAAI,GAAG,gBAAgB;AAC/C,YAAO,iBAAiB,CAAC,aAAa,YAAY,GAAG,KAAK;;AAO5D,6BAAyB,IAAI,QAAQ;AACrC,QAAI;AACF,YAAO,iBAAiB,CAAC,SAAS,YAAY,GAAG,KAAK;cAC9C;AACR,8BAAyB,OAAO,QAAQ;;;GAG5C,WAAW,CACT,GAAG,kBACH,GAAG,cAAc,QAAQ,eAAe,KACrC,QAAQ,IAAI,OAAO,KAAK,IAAI,QAAQ,OAAO,MAAM,CAAC,GAAG,CACvD,CACF;GACF;EAGU;;;;;;;;;;;;;;;;AAiBf,MAAa,sBAAsB,OACjC,eACyB;AAGzB,kGAAmC,CAAC;AAEpC,QAAO,wBAAwB,WAAW"}
1
+ {"version":3,"file":"configMetroIntlayer.cjs","names":["pathResolve"],"sources":["../../src/configMetroIntlayer.ts"],"sourcesContent":["import { resolve as pathResolve } from 'node:path';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { getAlias } from '@intlayer/config/utils';\nimport type { getDefaultConfig } from 'expo/metro-config';\n\n/**\n * Returns the `resolve` function from metro-resolver, preferring the copy\n * bundled inside Metro itself. Loading from Metro's own package directory\n * ensures we use the same resolver instance that Metro uses internally,\n * which prevents the cross-version recursion described in\n * https://github.com/aymericzip/intlayer/issues/457.\n */\ntype AnyResolver = (context: any, moduleName: string, ...args: any[]) => any;\n\nconst getMetroResolve = (): AnyResolver => {\n try {\n const metroPackageDir = pathResolve(\n require.resolve('metro/package.json'),\n '..'\n );\n return (\n require(\n pathResolve(metroPackageDir, 'node_modules', 'metro-resolver')\n ) as typeof import('metro-resolver')\n ).resolve as AnyResolver;\n } catch {\n return (require('metro-resolver') as typeof import('metro-resolver'))\n .resolve as AnyResolver;\n }\n};\n\ntype MetroConfig = ReturnType<typeof getDefaultConfig>;\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayerSync } = require(\"react-native-intlayer/metro\");\n *\n *\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return configMetroIntlayerSync(defaultConfig);\n * ```\n *\n * > Note: `configMetroIntlayerSync` does not build intlayer dictionaries on server start. Use `configMetroIntlayer` for that.\n */\nexport const configMetroIntlayerSync = (\n baseConfig?: MetroConfig\n): MetroConfig => {\n const configuration = getConfiguration();\n\n const alias = getAlias({\n configuration,\n formatter: pathResolve, // get absolute path\n });\n\n /**\n * Project root, used to force `react-intlayer` to resolve to a single copy.\n *\n * Metro does not deduplicate packages the way web bundlers do. When a\n * dependency (e.g. `react-native-intlayer`) pins a different patch of\n * `react-intlayer` than the app, npm/yarn keep two physical copies. The\n * provider would then create its React context from one copy while\n * `useLocale`/`useIntlayer` read the context from the other — two distinct\n * `IntlayerClientContext` instances. The provider's updates never reach the\n * consumers, so `setLocale()` silently does nothing on native.\n *\n * Resolving every `react-intlayer` request from the project root collapses\n * those copies to a single module instance (and therefore a single context).\n */\n const projectRoot = configuration.system.baseDir;\n\n const existingBlockList = baseConfig?.resolver?.blockList;\n const existingPatterns: RegExp[] =\n existingBlockList instanceof RegExp\n ? [existingBlockList]\n : (existingBlockList ?? []);\n\n const existingResolveRequest = baseConfig?.resolver?.resolveRequest;\n\n /**\n * Tracks resolution contexts that are currently executing inside the\n * metro-resolver fallback call. When metro-resolver cannot find a module it\n * may call back through `context.resolveRequest` (the outermost resolver in\n * the chain, e.g. Sentry → NativeWind → ours). That callback eventually\n * reaches our resolver again. Without a guard we would recurse indefinitely\n * (see issue #457).\n *\n * On the second entry we break the cycle by stripping `resolveRequest` from\n * the context so metro-resolver finishes with its built-in logic only\n * (alias, extraNodeModules, …) rather than calling back a third time.\n *\n * Metro creates a fresh context object per module resolution, so using a\n * WeakSet keyed on context is safe and causes no cross-resolution\n * interference.\n */\n const inflightFallbackContexts = new WeakSet<object>();\n\n const config = {\n ...baseConfig,\n\n resolver: {\n ...baseConfig?.resolver,\n resolveRequest: (context, moduleName, ...args) => {\n if (Object.keys(alias).includes(moduleName)) {\n return {\n filePath: alias[moduleName as keyof typeof alias],\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/config/client') {\n return {\n filePath: require.resolve('@intlayer/config/client'),\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/core/file') {\n // Force React Native to use the correct transpiled version\n return {\n filePath: require.resolve('@intlayer/core/file/browser'),\n type: 'sourceFile',\n };\n }\n\n // Force a single `react-intlayer` instance regardless of which package\n // imports it (the app or a nested dependency). This prevents the\n // duplicate-context bug that silently breaks locale switching on native\n // when two `react-intlayer` copies are installed (see projectRoot doc).\n if (\n moduleName === 'react-intlayer' ||\n moduleName.startsWith('react-intlayer/')\n ) {\n try {\n return {\n filePath: require.resolve(moduleName, { paths: [projectRoot] }),\n type: 'sourceFile',\n };\n } catch {\n // Fall through to the default resolution below if the project root\n // copy cannot be resolved for some reason.\n }\n }\n\n // @formatjs packages have invalid exports configuration or missing exports for polyfills\n // By disabling package exports for these modules, we avoid the Metro warnings and let it\n // fall back cleanly to file-based resolution.\n if (moduleName.startsWith('@formatjs/')) {\n inflightFallbackContexts.add(context);\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cleanContext = {\n ...(context as any),\n unstable_enablePackageExports: false,\n };\n return getMetroResolve()(cleanContext, moduleName, ...args);\n } finally {\n inflightFallbackContexts.delete(context);\n }\n }\n\n // Delegate to the user-provided resolver if present\n if (existingResolveRequest) {\n return existingResolveRequest(context, moduleName, ...args);\n }\n\n // Re-entry guard: metro-resolver has already been invoked for this\n // context and is now calling back through context.resolveRequest (the\n // outer chain) which has bubbled back to us. Strip resolveRequest so\n // metro-resolver resolves the module with only its built-in rules\n // (alias, extraNodeModules, etc.) and does not recurse again.\n if (inflightFallbackContexts.has(context)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const { resolveRequest: _r, ...pureContext } = context as any;\n return getMetroResolve()(pureContext, moduleName, ...args);\n }\n\n // First pass: call metro-resolver while preserving context.resolveRequest\n // so outer wrappers (NativeWind, Sentry, …) still get a chance to\n // handle modules that metro-resolver cannot locate on its own (e.g. @/\n // tsconfig path aliases that a wrapper resolves via its own logic).\n inflightFallbackContexts.add(context);\n try {\n return getMetroResolve()(context, moduleName, ...args);\n } finally {\n inflightFallbackContexts.delete(context);\n }\n },\n blockList: [\n ...existingPatterns,\n ...configuration.content.fileExtensions.map(\n (ext) => new RegExp(`.*${ext.replace(/\\./g, '\\\\.')}$`)\n ),\n ],\n },\n } as MetroConfig;\n\n return config;\n};\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayer } = require(\"react-native-intlayer/metro\");\n *\n * module.exports = (async () => {\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return await configMetroIntlayer(defaultConfig);\n * })();\n * ```\n *\n * > Note: `configMetroIntlayer` builds intlayer dictionaries on server start. Use `configMetroIntlayerSync` instead if you want to skip that.\n */\nexport const configMetroIntlayer = async (\n baseConfig?: MetroConfig\n): Promise<MetroConfig> => {\n const configuration = getConfiguration();\n\n await prepareIntlayer(configuration);\n\n return configMetroIntlayerSync(baseConfig);\n};\n"],"mappings":";;;;;;;AAeA,MAAM,wBAAqC;AACzC,KAAI;EACF,MAAM,yCACJ,QAAQ,QAAQ,qBAAqB,EACrC,KACD;AACD,SACE,+BACc,iBAAiB,gBAAgB,iBAAiB,CAC/D,CACD;SACI;AACN,SAAQ,QAAQ,iBAAiB,CAC9B;;;;;;;;;;;;;;;;AAmBP,MAAa,2BACX,eACgB;CAChB,MAAM,6DAAkC;CAExC,MAAM,6CAAiB;EACrB;EACA,WAAWA;EACZ,CAAC;;;;;;;;;;;;;;;CAgBF,MAAM,cAAc,cAAc,OAAO;CAEzC,MAAM,oBAAoB,YAAY,UAAU;CAChD,MAAM,mBACJ,6BAA6B,SACzB,CAAC,kBAAkB,GAClB,qBAAqB,EAAE;CAE9B,MAAM,yBAAyB,YAAY,UAAU;;;;;;;;;;;;;;;;;CAkBrD,MAAM,2CAA2B,IAAI,SAAiB;AAwGtD,QAAO;EArGL,GAAG;EAEH,UAAU;GACR,GAAG,YAAY;GACf,iBAAiB,SAAS,YAAY,GAAG,SAAS;AAChD,QAAI,OAAO,KAAK,MAAM,CAAC,SAAS,WAAW,CACzC,QAAO;KACL,UAAU,MAAM;KAChB,MAAM;KACP;AAIH,QAAI,eAAe,0BACjB,QAAO;KACL,UAAU,QAAQ,QAAQ,0BAA0B;KACpD,MAAM;KACP;AAIH,QAAI,eAAe,sBAEjB,QAAO;KACL,UAAU,QAAQ,QAAQ,8BAA8B;KACxD,MAAM;KACP;AAOH,QACE,eAAe,oBACf,WAAW,WAAW,kBAAkB,CAExC,KAAI;AACF,YAAO;MACL,UAAU,QAAQ,QAAQ,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC;MAC/D,MAAM;MACP;YACK;AASV,QAAI,WAAW,WAAW,aAAa,EAAE;AACvC,8BAAyB,IAAI,QAAQ;AACrC,SAAI;MAEF,MAAM,eAAe;OACnB,GAAI;OACJ,+BAA+B;OAChC;AACD,aAAO,iBAAiB,CAAC,cAAc,YAAY,GAAG,KAAK;eACnD;AACR,+BAAyB,OAAO,QAAQ;;;AAK5C,QAAI,uBACF,QAAO,uBAAuB,SAAS,YAAY,GAAG,KAAK;AAQ7D,QAAI,yBAAyB,IAAI,QAAQ,EAAE;KAEzC,MAAM,EAAE,gBAAgB,IAAI,GAAG,gBAAgB;AAC/C,YAAO,iBAAiB,CAAC,aAAa,YAAY,GAAG,KAAK;;AAO5D,6BAAyB,IAAI,QAAQ;AACrC,QAAI;AACF,YAAO,iBAAiB,CAAC,SAAS,YAAY,GAAG,KAAK;cAC9C;AACR,8BAAyB,OAAO,QAAQ;;;GAG5C,WAAW,CACT,GAAG,kBACH,GAAG,cAAc,QAAQ,eAAe,KACrC,QAAQ,IAAI,OAAO,KAAK,IAAI,QAAQ,OAAO,MAAM,CAAC,GAAG,CACvD,CACF;GACF;EAGU;;;;;;;;;;;;;;;;AAiBf,MAAa,sBAAsB,OACjC,eACyB;AAGzB,kGAAmC,CAAC;AAEpC,QAAO,wBAAwB,WAAW"}
@@ -0,0 +1,9 @@
1
+
2
+
3
+ var react_intlayer_html = require("react-intlayer/html");
4
+ Object.keys(react_intlayer_html).forEach(function (k) {
5
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
6
+ enumerable: true,
7
+ get: function () { return react_intlayer_html[k]; }
8
+ });
9
+ });
@@ -1,6 +1,127 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_intlayerPolyfill = require('./intlayerPolyfill.cjs');
3
3
  const require_intlayerProvider = require('./intlayerProvider.cjs');
4
+ let react_intlayer = require("react-intlayer");
4
5
 
6
+ Object.defineProperty(exports, 'IntlayerClientContext', {
7
+ enumerable: true,
8
+ get: function () {
9
+ return react_intlayer.IntlayerClientContext;
10
+ }
11
+ });
5
12
  exports.IntlayerProvider = require_intlayerProvider.IntlayerProvider;
6
- exports.intlayerPolyfill = require_intlayerPolyfill.intlayerPolyfill;
13
+ Object.defineProperty(exports, 'IntlayerProviderContent', {
14
+ enumerable: true,
15
+ get: function () {
16
+ return react_intlayer.IntlayerProviderContent;
17
+ }
18
+ });
19
+ Object.defineProperty(exports, 'getDictionary', {
20
+ enumerable: true,
21
+ get: function () {
22
+ return react_intlayer.getDictionary;
23
+ }
24
+ });
25
+ Object.defineProperty(exports, 'getIntlayer', {
26
+ enumerable: true,
27
+ get: function () {
28
+ return react_intlayer.getIntlayer;
29
+ }
30
+ });
31
+ exports.intlayerPolyfill = require_intlayerPolyfill.intlayerPolyfill;
32
+ Object.defineProperty(exports, 'localeInStorage', {
33
+ enumerable: true,
34
+ get: function () {
35
+ return react_intlayer.localeInStorage;
36
+ }
37
+ });
38
+ Object.defineProperty(exports, 'setLocaleInStorage', {
39
+ enumerable: true,
40
+ get: function () {
41
+ return react_intlayer.setLocaleInStorage;
42
+ }
43
+ });
44
+ Object.defineProperty(exports, 't', {
45
+ enumerable: true,
46
+ get: function () {
47
+ return react_intlayer.t;
48
+ }
49
+ });
50
+ Object.defineProperty(exports, 'useDictionary', {
51
+ enumerable: true,
52
+ get: function () {
53
+ return react_intlayer.useDictionary;
54
+ }
55
+ });
56
+ Object.defineProperty(exports, 'useDictionaryAsync', {
57
+ enumerable: true,
58
+ get: function () {
59
+ return react_intlayer.useDictionaryAsync;
60
+ }
61
+ });
62
+ Object.defineProperty(exports, 'useDictionaryDynamic', {
63
+ enumerable: true,
64
+ get: function () {
65
+ return react_intlayer.useDictionaryDynamic;
66
+ }
67
+ });
68
+ Object.defineProperty(exports, 'useI18n', {
69
+ enumerable: true,
70
+ get: function () {
71
+ return react_intlayer.useI18n;
72
+ }
73
+ });
74
+ Object.defineProperty(exports, 'useIntl', {
75
+ enumerable: true,
76
+ get: function () {
77
+ return react_intlayer.useIntl;
78
+ }
79
+ });
80
+ Object.defineProperty(exports, 'useIntlayer', {
81
+ enumerable: true,
82
+ get: function () {
83
+ return react_intlayer.useIntlayer;
84
+ }
85
+ });
86
+ Object.defineProperty(exports, 'useIntlayerContext', {
87
+ enumerable: true,
88
+ get: function () {
89
+ return react_intlayer.useIntlayerContext;
90
+ }
91
+ });
92
+ Object.defineProperty(exports, 'useLoadDynamic', {
93
+ enumerable: true,
94
+ get: function () {
95
+ return react_intlayer.useLoadDynamic;
96
+ }
97
+ });
98
+ Object.defineProperty(exports, 'useLocale', {
99
+ enumerable: true,
100
+ get: function () {
101
+ return react_intlayer.useLocale;
102
+ }
103
+ });
104
+ Object.defineProperty(exports, 'useLocaleBase', {
105
+ enumerable: true,
106
+ get: function () {
107
+ return react_intlayer.useLocaleBase;
108
+ }
109
+ });
110
+ Object.defineProperty(exports, 'useLocaleCookie', {
111
+ enumerable: true,
112
+ get: function () {
113
+ return react_intlayer.useLocaleCookie;
114
+ }
115
+ });
116
+ Object.defineProperty(exports, 'useLocaleStorage', {
117
+ enumerable: true,
118
+ get: function () {
119
+ return react_intlayer.useLocaleStorage;
120
+ }
121
+ });
122
+ Object.defineProperty(exports, 'useRewriteURL', {
123
+ enumerable: true,
124
+ get: function () {
125
+ return react_intlayer.useRewriteURL;
126
+ }
127
+ });
@@ -4,18 +4,70 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  /**
5
5
  * Applies necessary polyfills for React Native to support Intlayer.
6
6
  *
7
- * This includes polyfilling `structuredClone` if it is missing,
8
- * and providing no-op implementations for standard DOM `window` methods
9
- * (`addEventListener`, `removeEventListener`, `postMessage`)
10
- * to ensure compatibility with libraries that expect a browser-like environment.
7
+ * This includes:
8
+ * - Polyfilling `structuredClone` if it is missing.
9
+ * - Providing no-op implementations for standard DOM `window` methods
10
+ * (`addEventListener`, `removeEventListener`, `postMessage`).
11
+ * - Providing in-memory stubs for `document.cookie`, `localStorage`, and
12
+ * `sessionStorage` so that `@intlayer/core`'s locale-storage helpers work
13
+ * without crashing in a React Native environment.
14
+ *
15
+ * Note: These stubs are in-memory only. The locale selection will survive
16
+ * hot-reloads but not full app restarts. To persist across restarts, pass a
17
+ * custom `setLocale` to `<IntlayerProvider>` backed by AsyncStorage.
11
18
  */
19
+ const createStorage = () => {
20
+ const store = {};
21
+ return {
22
+ getItem: (key) => store[key] ?? null,
23
+ setItem: (key, value) => {
24
+ store[key] = String(value);
25
+ },
26
+ removeItem: (key) => {
27
+ delete store[key];
28
+ },
29
+ clear: () => {
30
+ for (const key in store) delete store[key];
31
+ },
32
+ get length() {
33
+ return Object.keys(store).length;
34
+ },
35
+ key: (index) => Object.keys(store)[index] ?? null
36
+ };
37
+ };
12
38
  const intlayerPolyfill = () => {
13
39
  if (typeof global.structuredClone !== "function") global.structuredClone = (obj) => JSON.parse(JSON.stringify(obj));
14
40
  if (typeof window !== "undefined") {
15
- if (typeof window.addEventListener !== "function") window.addEventListener = () => null;
16
- if (typeof window.removeEventListener !== "function") window.removeEventListener = () => null;
17
- if (typeof window.postMessage !== "function") window.postMessage = () => null;
41
+ const noop = () => null;
42
+ if (typeof window.addEventListener !== "function") window.addEventListener = noop;
43
+ if (typeof window.removeEventListener !== "function") window.removeEventListener = noop;
44
+ if (typeof window.postMessage !== "function") window.postMessage = noop;
45
+ }
46
+ if (typeof document === "undefined") {
47
+ let cookieJar = "";
48
+ Object.defineProperty(global, "document", {
49
+ configurable: true,
50
+ get: () => ({
51
+ get cookie() {
52
+ return cookieJar;
53
+ },
54
+ set cookie(value) {
55
+ const [pair] = value.split(";");
56
+ const [key, val] = pair?.split("=") ?? [];
57
+ const name = key?.trim();
58
+ cookieJar = [...cookieJar.split(";").filter((c) => !c.trim().startsWith(`${name}=`)).filter(Boolean), `${name}=${val ?? ""}`].join("; ");
59
+ }
60
+ })
61
+ });
18
62
  }
63
+ if (typeof localStorage === "undefined") Object.defineProperty(global, "localStorage", {
64
+ configurable: true,
65
+ value: createStorage()
66
+ });
67
+ if (typeof sessionStorage === "undefined") Object.defineProperty(global, "sessionStorage", {
68
+ configurable: true,
69
+ value: createStorage()
70
+ });
19
71
  };
20
72
 
21
73
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"intlayerPolyfill.cjs","names":[],"sources":["../../src/intlayerPolyfill.ts"],"sourcesContent":["/**\n * Applies necessary polyfills for React Native to support Intlayer.\n *\n * This includes polyfilling `structuredClone` if it is missing,\n * and providing no-op implementations for standard DOM `window` methods\n * (`addEventListener`, `removeEventListener`, `postMessage`)\n * to ensure compatibility with libraries that expect a browser-like environment.\n */\nexport const intlayerPolyfill = () => {\n if (typeof global.structuredClone !== 'function') {\n global.structuredClone = (obj) => JSON.parse(JSON.stringify(obj));\n }\n\n if (typeof window !== 'undefined') {\n if (typeof window.addEventListener !== 'function') {\n window.addEventListener = () => null;\n }\n if (typeof window.removeEventListener !== 'function') {\n window.removeEventListener = () => null;\n }\n if (typeof window.postMessage !== 'function') {\n window.postMessage = () => null;\n }\n }\n};\n"],"mappings":";;;;;;;;;;;AAQA,MAAa,yBAAyB;AACpC,KAAI,OAAO,OAAO,oBAAoB,WACpC,QAAO,mBAAmB,QAAQ,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;AAGnE,KAAI,OAAO,WAAW,aAAa;AACjC,MAAI,OAAO,OAAO,qBAAqB,WACrC,QAAO,yBAAyB;AAElC,MAAI,OAAO,OAAO,wBAAwB,WACxC,QAAO,4BAA4B;AAErC,MAAI,OAAO,OAAO,gBAAgB,WAChC,QAAO,oBAAoB"}
1
+ {"version":3,"file":"intlayerPolyfill.cjs","names":[],"sources":["../../src/intlayerPolyfill.ts"],"sourcesContent":["/**\n * Applies necessary polyfills for React Native to support Intlayer.\n *\n * This includes:\n * - Polyfilling `structuredClone` if it is missing.\n * - Providing no-op implementations for standard DOM `window` methods\n * (`addEventListener`, `removeEventListener`, `postMessage`).\n * - Providing in-memory stubs for `document.cookie`, `localStorage`, and\n * `sessionStorage` so that `@intlayer/core`'s locale-storage helpers work\n * without crashing in a React Native environment.\n *\n * Note: These stubs are in-memory only. The locale selection will survive\n * hot-reloads but not full app restarts. To persist across restarts, pass a\n * custom `setLocale` to `<IntlayerProvider>` backed by AsyncStorage.\n */\nconst createStorage = () => {\n const store: Record<string, string> = {};\n return {\n getItem: (key: string) => store[key] ?? null,\n setItem: (key: string, value: string) => {\n store[key] = String(value);\n },\n removeItem: (key: string) => {\n delete store[key];\n },\n clear: () => {\n for (const key in store) {\n delete store[key];\n }\n },\n get length() {\n return Object.keys(store).length;\n },\n key: (index: number) => Object.keys(store)[index] ?? null,\n };\n};\n\nexport const intlayerPolyfill = () => {\n if (typeof global.structuredClone !== 'function') {\n global.structuredClone = (obj) => JSON.parse(JSON.stringify(obj));\n }\n\n if (typeof window !== 'undefined') {\n const noop = () => null;\n if (typeof window.addEventListener !== 'function') {\n window.addEventListener = noop;\n }\n if (typeof window.removeEventListener !== 'function') {\n window.removeEventListener = noop;\n }\n if (typeof window.postMessage !== 'function') {\n window.postMessage = noop;\n }\n }\n\n // `@intlayer/core`'s localeStorageOptions accesses document.cookie directly.\n // In React Native, `document` is undefined — we provide a minimal in-memory\n // cookie jar so reads/writes work without throwing.\n if (typeof document === 'undefined') {\n let cookieJar = '';\n Object.defineProperty(global, 'document', {\n configurable: true,\n get: () => ({\n get cookie() {\n return cookieJar;\n },\n set cookie(value: string) {\n // Simplified cookie setter: just append/overwrite the key\n const [pair] = value.split(';');\n const [key, val] = pair?.split('=') ?? [];\n const name = key?.trim();\n const existing = cookieJar\n .split(';')\n .filter((c) => !c.trim().startsWith(`${name}=`))\n .filter(Boolean);\n cookieJar = [...existing, `${name}=${val ?? ''}`].join('; ');\n },\n }),\n });\n }\n\n if (typeof localStorage === 'undefined') {\n Object.defineProperty(global, 'localStorage', {\n configurable: true,\n value: createStorage(),\n });\n }\n\n if (typeof sessionStorage === 'undefined') {\n Object.defineProperty(global, 'sessionStorage', {\n configurable: true,\n value: createStorage(),\n });\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAeA,MAAM,sBAAsB;CAC1B,MAAM,QAAgC,EAAE;AACxC,QAAO;EACL,UAAU,QAAgB,MAAM,QAAQ;EACxC,UAAU,KAAa,UAAkB;AACvC,SAAM,OAAO,OAAO,MAAM;;EAE5B,aAAa,QAAgB;AAC3B,UAAO,MAAM;;EAEf,aAAa;AACX,QAAK,MAAM,OAAO,MAChB,QAAO,MAAM;;EAGjB,IAAI,SAAS;AACX,UAAO,OAAO,KAAK,MAAM,CAAC;;EAE5B,MAAM,UAAkB,OAAO,KAAK,MAAM,CAAC,UAAU;EACtD;;AAGH,MAAa,yBAAyB;AACpC,KAAI,OAAO,OAAO,oBAAoB,WACpC,QAAO,mBAAmB,QAAQ,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;AAGnE,KAAI,OAAO,WAAW,aAAa;EACjC,MAAM,aAAa;AACnB,MAAI,OAAO,OAAO,qBAAqB,WACrC,QAAO,mBAAmB;AAE5B,MAAI,OAAO,OAAO,wBAAwB,WACxC,QAAO,sBAAsB;AAE/B,MAAI,OAAO,OAAO,gBAAgB,WAChC,QAAO,cAAc;;AAOzB,KAAI,OAAO,aAAa,aAAa;EACnC,IAAI,YAAY;AAChB,SAAO,eAAe,QAAQ,YAAY;GACxC,cAAc;GACd,YAAY;IACV,IAAI,SAAS;AACX,YAAO;;IAET,IAAI,OAAO,OAAe;KAExB,MAAM,CAAC,QAAQ,MAAM,MAAM,IAAI;KAC/B,MAAM,CAAC,KAAK,OAAO,MAAM,MAAM,IAAI,IAAI,EAAE;KACzC,MAAM,OAAO,KAAK,MAAM;AAKxB,iBAAY,CAAC,GAJI,UACd,MAAM,IAAI,CACV,QAAQ,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,GAAG,KAAK,GAAG,CAAC,CAC/C,OAAO,QACc,EAAE,GAAG,KAAK,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK;;IAE/D;GACF,CAAC;;AAGJ,KAAI,OAAO,iBAAiB,YAC1B,QAAO,eAAe,QAAQ,gBAAgB;EAC5C,cAAc;EACd,OAAO,eAAe;EACvB,CAAC;AAGJ,KAAI,OAAO,mBAAmB,YAC5B,QAAO,eAAe,QAAQ,kBAAkB;EAC9C,cAAc;EACd,OAAO,eAAe;EACvB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"intlayerProvider.cjs","names":["intlayerPolyfill","IntlayerProviderContent"],"sources":["../../src/intlayerProvider.tsx"],"sourcesContent":["import {\n IntlayerProviderContent,\n type IntlayerProviderProps as IntlayerProviderPropsBase,\n} from 'react-intlayer';\nimport { intlayerPolyfill } from './intlayerPolyfill';\n\nintlayerPolyfill();\n\ntype IntlayerProviderProps = Omit<\n IntlayerProviderPropsBase,\n 'disableEditor' | 'isCookieEnabled'\n>;\n\n/**\n * Provider component that wraps your application and provides the Intlayer context.\n *\n * This provider also automatically applies necessary polyfills for React Native.\n *\n * @param props - The provider props, excluding editor-specific and cookie-specific options which are not applicable in React Native.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'react-native-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider = ({\n children,\n ...props\n}: IntlayerProviderProps) => (\n <IntlayerProviderContent {...props}>{children}</IntlayerProviderContent>\n);\n"],"mappings":";;;;;;AAMAA,2CAAkB;;;;;;;;;;;;;;;;;;;;AA0BlB,MAAa,oBAAoB,EAC/B,UACA,GAAG,YAEH,2CAACC,wCAAD;CAAyB,GAAI;CAAQ;CAAmC"}
1
+ {"version":3,"file":"intlayerProvider.cjs","names":["intlayerPolyfill","IntlayerProviderContent"],"sources":["../../src/intlayerProvider.tsx"],"sourcesContent":["import {\n IntlayerProviderContent,\n type IntlayerProviderProps as IntlayerProviderPropsBase,\n} from 'react-intlayer';\nimport { intlayerPolyfill } from './intlayerPolyfill';\n\nintlayerPolyfill();\n\n/**\n * Props accepted by the React Native `IntlayerProvider`.\n *\n * Editor-specific (`disableEditor`) and cookie-specific (`isCookieEnabled`)\n * options are omitted because they are not applicable in a React Native\n * environment.\n */\nexport type IntlayerProviderProps = Omit<\n IntlayerProviderPropsBase,\n 'disableEditor' | 'isCookieEnabled'\n>;\n\n/**\n * Provider component that wraps your application and provides the Intlayer context.\n *\n * This provider also automatically applies necessary polyfills for React Native.\n *\n * @param props - The provider props, excluding editor-specific and cookie-specific options which are not applicable in React Native.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'react-native-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider = ({\n children,\n ...props\n}: IntlayerProviderProps) => (\n <IntlayerProviderContent {...props}>{children}</IntlayerProviderContent>\n);\n"],"mappings":";;;;;;AAMAA,2CAAkB;;;;;;;;;;;;;;;;;;;;AAiClB,MAAa,oBAAoB,EAC/B,UACA,GAAG,YAEH,2CAACC,wCAAD;CAAyB,GAAI;CAAQ;CAAmC"}
@@ -0,0 +1,9 @@
1
+
2
+
3
+ var react_intlayer_markdown = require("react-intlayer/markdown");
4
+ Object.keys(react_intlayer_markdown).forEach(function (k) {
5
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
6
+ enumerable: true,
7
+ get: function () { return react_intlayer_markdown[k]; }
8
+ });
9
+ });
@@ -0,0 +1 @@
1
+ export * from "react-intlayer/format"
@@ -32,6 +32,21 @@ const configMetroIntlayerSync = (baseConfig) => {
32
32
  configuration,
33
33
  formatter: resolve
34
34
  });
35
+ /**
36
+ * Project root, used to force `react-intlayer` to resolve to a single copy.
37
+ *
38
+ * Metro does not deduplicate packages the way web bundlers do. When a
39
+ * dependency (e.g. `react-native-intlayer`) pins a different patch of
40
+ * `react-intlayer` than the app, npm/yarn keep two physical copies. The
41
+ * provider would then create its React context from one copy while
42
+ * `useLocale`/`useIntlayer` read the context from the other — two distinct
43
+ * `IntlayerClientContext` instances. The provider's updates never reach the
44
+ * consumers, so `setLocale()` silently does nothing on native.
45
+ *
46
+ * Resolving every `react-intlayer` request from the project root collapses
47
+ * those copies to a single module instance (and therefore a single context).
48
+ */
49
+ const projectRoot = configuration.system.baseDir;
35
50
  const existingBlockList = baseConfig?.resolver?.blockList;
36
51
  const existingPatterns = existingBlockList instanceof RegExp ? [existingBlockList] : existingBlockList ?? [];
37
52
  const existingResolveRequest = baseConfig?.resolver?.resolveRequest;
@@ -69,6 +84,12 @@ const configMetroIntlayerSync = (baseConfig) => {
69
84
  filePath: __require.resolve("@intlayer/core/file/browser"),
70
85
  type: "sourceFile"
71
86
  };
87
+ if (moduleName === "react-intlayer" || moduleName.startsWith("react-intlayer/")) try {
88
+ return {
89
+ filePath: __require.resolve(moduleName, { paths: [projectRoot] }),
90
+ type: "sourceFile"
91
+ };
92
+ } catch {}
72
93
  if (moduleName.startsWith("@formatjs/")) {
73
94
  inflightFallbackContexts.add(context);
74
95
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"configMetroIntlayer.mjs","names":["pathResolve"],"sources":["../../src/configMetroIntlayer.ts"],"sourcesContent":["import { resolve as pathResolve } from 'node:path';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { getAlias } from '@intlayer/config/utils';\nimport type { getDefaultConfig } from 'expo/metro-config';\n\n/**\n * Returns the `resolve` function from metro-resolver, preferring the copy\n * bundled inside Metro itself. Loading from Metro's own package directory\n * ensures we use the same resolver instance that Metro uses internally,\n * which prevents the cross-version recursion described in\n * https://github.com/aymericzip/intlayer/issues/457.\n */\ntype AnyResolver = (context: any, moduleName: string, ...args: any[]) => any;\n\nconst getMetroResolve = (): AnyResolver => {\n try {\n const metroPackageDir = pathResolve(\n require.resolve('metro/package.json'),\n '..'\n );\n return (\n require(\n pathResolve(metroPackageDir, 'node_modules', 'metro-resolver')\n ) as typeof import('metro-resolver')\n ).resolve as AnyResolver;\n } catch {\n return (require('metro-resolver') as typeof import('metro-resolver'))\n .resolve as AnyResolver;\n }\n};\n\ntype MetroConfig = ReturnType<typeof getDefaultConfig>;\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayerSync } = require(\"react-native-intlayer/metro\");\n *\n *\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return configMetroIntlayerSync(defaultConfig);\n * ```\n *\n * > Note: `configMetroIntlayerSync` does not build intlayer dictionaries on server start. Use `configMetroIntlayer` for that.\n */\nexport const configMetroIntlayerSync = (\n baseConfig?: MetroConfig\n): MetroConfig => {\n const configuration = getConfiguration();\n\n const alias = getAlias({\n configuration,\n formatter: pathResolve, // get absolute path\n });\n\n const existingBlockList = baseConfig?.resolver?.blockList;\n const existingPatterns: RegExp[] =\n existingBlockList instanceof RegExp\n ? [existingBlockList]\n : (existingBlockList ?? []);\n\n const existingResolveRequest = baseConfig?.resolver?.resolveRequest;\n\n /**\n * Tracks resolution contexts that are currently executing inside the\n * metro-resolver fallback call. When metro-resolver cannot find a module it\n * may call back through `context.resolveRequest` (the outermost resolver in\n * the chain, e.g. Sentry → NativeWind → ours). That callback eventually\n * reaches our resolver again. Without a guard we would recurse indefinitely\n * (see issue #457).\n *\n * On the second entry we break the cycle by stripping `resolveRequest` from\n * the context so metro-resolver finishes with its built-in logic only\n * (alias, extraNodeModules, …) rather than calling back a third time.\n *\n * Metro creates a fresh context object per module resolution, so using a\n * WeakSet keyed on context is safe and causes no cross-resolution\n * interference.\n */\n const inflightFallbackContexts = new WeakSet<object>();\n\n const config = {\n ...baseConfig,\n\n resolver: {\n ...baseConfig?.resolver,\n resolveRequest: (context, moduleName, ...args) => {\n if (Object.keys(alias).includes(moduleName)) {\n return {\n filePath: alias[moduleName as keyof typeof alias],\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/config/client') {\n return {\n filePath: require.resolve('@intlayer/config/client'),\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/core/file') {\n // Force React Native to use the correct transpiled version\n return {\n filePath: require.resolve('@intlayer/core/file/browser'),\n type: 'sourceFile',\n };\n }\n\n // @formatjs packages have invalid exports configuration or missing exports for polyfills\n // By disabling package exports for these modules, we avoid the Metro warnings and let it\n // fall back cleanly to file-based resolution.\n if (moduleName.startsWith('@formatjs/')) {\n inflightFallbackContexts.add(context);\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cleanContext = {\n ...(context as any),\n unstable_enablePackageExports: false,\n };\n return getMetroResolve()(cleanContext, moduleName, ...args);\n } finally {\n inflightFallbackContexts.delete(context);\n }\n }\n\n // Delegate to the user-provided resolver if present\n if (existingResolveRequest) {\n return existingResolveRequest(context, moduleName, ...args);\n }\n\n // Re-entry guard: metro-resolver has already been invoked for this\n // context and is now calling back through context.resolveRequest (the\n // outer chain) which has bubbled back to us. Strip resolveRequest so\n // metro-resolver resolves the module with only its built-in rules\n // (alias, extraNodeModules, etc.) and does not recurse again.\n if (inflightFallbackContexts.has(context)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const { resolveRequest: _r, ...pureContext } = context as any;\n return getMetroResolve()(pureContext, moduleName, ...args);\n }\n\n // First pass: call metro-resolver while preserving context.resolveRequest\n // so outer wrappers (NativeWind, Sentry, …) still get a chance to\n // handle modules that metro-resolver cannot locate on its own (e.g. @/\n // tsconfig path aliases that a wrapper resolves via its own logic).\n inflightFallbackContexts.add(context);\n try {\n return getMetroResolve()(context, moduleName, ...args);\n } finally {\n inflightFallbackContexts.delete(context);\n }\n },\n blockList: [\n ...existingPatterns,\n ...configuration.content.fileExtensions.map(\n (ext) => new RegExp(`.*${ext.replace(/\\./g, '\\\\.')}$`)\n ),\n ],\n },\n } as MetroConfig;\n\n return config;\n};\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayer } = require(\"react-native-intlayer/metro\");\n *\n * module.exports = (async () => {\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return await configMetroIntlayer(defaultConfig);\n * })();\n * ```\n *\n * > Note: `configMetroIntlayer` builds intlayer dictionaries on server start. Use `configMetroIntlayerSync` instead if you want to skip that.\n */\nexport const configMetroIntlayer = async (\n baseConfig?: MetroConfig\n): Promise<MetroConfig> => {\n const configuration = getConfiguration();\n\n await prepareIntlayer(configuration);\n\n return configMetroIntlayerSync(baseConfig);\n};\n"],"mappings":";;;;;;;AAeA,MAAM,wBAAqC;AACzC,KAAI;EACF,MAAM,kBAAkBA,kBACd,QAAQ,qBAAqB,EACrC,KACD;AACD,mBAEIA,QAAY,iBAAiB,gBAAgB,iBAAiB,CAC/D,CACD;SACI;AACN,mBAAgB,iBAAiB,CAC9B;;;;;;;;;;;;;;;;AAmBP,MAAa,2BACX,eACgB;CAChB,MAAM,gBAAgB,kBAAkB;CAExC,MAAM,QAAQ,SAAS;EACrB;EACA,WAAWA;EACZ,CAAC;CAEF,MAAM,oBAAoB,YAAY,UAAU;CAChD,MAAM,mBACJ,6BAA6B,SACzB,CAAC,kBAAkB,GAClB,qBAAqB,EAAE;CAE9B,MAAM,yBAAyB,YAAY,UAAU;;;;;;;;;;;;;;;;;CAkBrD,MAAM,2CAA2B,IAAI,SAAiB;AAqFtD,QAAO;EAlFL,GAAG;EAEH,UAAU;GACR,GAAG,YAAY;GACf,iBAAiB,SAAS,YAAY,GAAG,SAAS;AAChD,QAAI,OAAO,KAAK,MAAM,CAAC,SAAS,WAAW,CACzC,QAAO;KACL,UAAU,MAAM;KAChB,MAAM;KACP;AAIH,QAAI,eAAe,0BACjB,QAAO;KACL,oBAAkB,QAAQ,0BAA0B;KACpD,MAAM;KACP;AAIH,QAAI,eAAe,sBAEjB,QAAO;KACL,oBAAkB,QAAQ,8BAA8B;KACxD,MAAM;KACP;AAMH,QAAI,WAAW,WAAW,aAAa,EAAE;AACvC,8BAAyB,IAAI,QAAQ;AACrC,SAAI;MAEF,MAAM,eAAe;OACnB,GAAI;OACJ,+BAA+B;OAChC;AACD,aAAO,iBAAiB,CAAC,cAAc,YAAY,GAAG,KAAK;eACnD;AACR,+BAAyB,OAAO,QAAQ;;;AAK5C,QAAI,uBACF,QAAO,uBAAuB,SAAS,YAAY,GAAG,KAAK;AAQ7D,QAAI,yBAAyB,IAAI,QAAQ,EAAE;KAEzC,MAAM,EAAE,gBAAgB,IAAI,GAAG,gBAAgB;AAC/C,YAAO,iBAAiB,CAAC,aAAa,YAAY,GAAG,KAAK;;AAO5D,6BAAyB,IAAI,QAAQ;AACrC,QAAI;AACF,YAAO,iBAAiB,CAAC,SAAS,YAAY,GAAG,KAAK;cAC9C;AACR,8BAAyB,OAAO,QAAQ;;;GAG5C,WAAW,CACT,GAAG,kBACH,GAAG,cAAc,QAAQ,eAAe,KACrC,QAAQ,IAAI,OAAO,KAAK,IAAI,QAAQ,OAAO,MAAM,CAAC,GAAG,CACvD,CACF;GACF;EAGU;;;;;;;;;;;;;;;;AAiBf,MAAa,sBAAsB,OACjC,eACyB;AAGzB,OAAM,gBAFgB,kBAEa,CAAC;AAEpC,QAAO,wBAAwB,WAAW"}
1
+ {"version":3,"file":"configMetroIntlayer.mjs","names":["pathResolve"],"sources":["../../src/configMetroIntlayer.ts"],"sourcesContent":["import { resolve as pathResolve } from 'node:path';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { getAlias } from '@intlayer/config/utils';\nimport type { getDefaultConfig } from 'expo/metro-config';\n\n/**\n * Returns the `resolve` function from metro-resolver, preferring the copy\n * bundled inside Metro itself. Loading from Metro's own package directory\n * ensures we use the same resolver instance that Metro uses internally,\n * which prevents the cross-version recursion described in\n * https://github.com/aymericzip/intlayer/issues/457.\n */\ntype AnyResolver = (context: any, moduleName: string, ...args: any[]) => any;\n\nconst getMetroResolve = (): AnyResolver => {\n try {\n const metroPackageDir = pathResolve(\n require.resolve('metro/package.json'),\n '..'\n );\n return (\n require(\n pathResolve(metroPackageDir, 'node_modules', 'metro-resolver')\n ) as typeof import('metro-resolver')\n ).resolve as AnyResolver;\n } catch {\n return (require('metro-resolver') as typeof import('metro-resolver'))\n .resolve as AnyResolver;\n }\n};\n\ntype MetroConfig = ReturnType<typeof getDefaultConfig>;\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayerSync } = require(\"react-native-intlayer/metro\");\n *\n *\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return configMetroIntlayerSync(defaultConfig);\n * ```\n *\n * > Note: `configMetroIntlayerSync` does not build intlayer dictionaries on server start. Use `configMetroIntlayer` for that.\n */\nexport const configMetroIntlayerSync = (\n baseConfig?: MetroConfig\n): MetroConfig => {\n const configuration = getConfiguration();\n\n const alias = getAlias({\n configuration,\n formatter: pathResolve, // get absolute path\n });\n\n /**\n * Project root, used to force `react-intlayer` to resolve to a single copy.\n *\n * Metro does not deduplicate packages the way web bundlers do. When a\n * dependency (e.g. `react-native-intlayer`) pins a different patch of\n * `react-intlayer` than the app, npm/yarn keep two physical copies. The\n * provider would then create its React context from one copy while\n * `useLocale`/`useIntlayer` read the context from the other — two distinct\n * `IntlayerClientContext` instances. The provider's updates never reach the\n * consumers, so `setLocale()` silently does nothing on native.\n *\n * Resolving every `react-intlayer` request from the project root collapses\n * those copies to a single module instance (and therefore a single context).\n */\n const projectRoot = configuration.system.baseDir;\n\n const existingBlockList = baseConfig?.resolver?.blockList;\n const existingPatterns: RegExp[] =\n existingBlockList instanceof RegExp\n ? [existingBlockList]\n : (existingBlockList ?? []);\n\n const existingResolveRequest = baseConfig?.resolver?.resolveRequest;\n\n /**\n * Tracks resolution contexts that are currently executing inside the\n * metro-resolver fallback call. When metro-resolver cannot find a module it\n * may call back through `context.resolveRequest` (the outermost resolver in\n * the chain, e.g. Sentry → NativeWind → ours). That callback eventually\n * reaches our resolver again. Without a guard we would recurse indefinitely\n * (see issue #457).\n *\n * On the second entry we break the cycle by stripping `resolveRequest` from\n * the context so metro-resolver finishes with its built-in logic only\n * (alias, extraNodeModules, …) rather than calling back a third time.\n *\n * Metro creates a fresh context object per module resolution, so using a\n * WeakSet keyed on context is safe and causes no cross-resolution\n * interference.\n */\n const inflightFallbackContexts = new WeakSet<object>();\n\n const config = {\n ...baseConfig,\n\n resolver: {\n ...baseConfig?.resolver,\n resolveRequest: (context, moduleName, ...args) => {\n if (Object.keys(alias).includes(moduleName)) {\n return {\n filePath: alias[moduleName as keyof typeof alias],\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/config/client') {\n return {\n filePath: require.resolve('@intlayer/config/client'),\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/core/file') {\n // Force React Native to use the correct transpiled version\n return {\n filePath: require.resolve('@intlayer/core/file/browser'),\n type: 'sourceFile',\n };\n }\n\n // Force a single `react-intlayer` instance regardless of which package\n // imports it (the app or a nested dependency). This prevents the\n // duplicate-context bug that silently breaks locale switching on native\n // when two `react-intlayer` copies are installed (see projectRoot doc).\n if (\n moduleName === 'react-intlayer' ||\n moduleName.startsWith('react-intlayer/')\n ) {\n try {\n return {\n filePath: require.resolve(moduleName, { paths: [projectRoot] }),\n type: 'sourceFile',\n };\n } catch {\n // Fall through to the default resolution below if the project root\n // copy cannot be resolved for some reason.\n }\n }\n\n // @formatjs packages have invalid exports configuration or missing exports for polyfills\n // By disabling package exports for these modules, we avoid the Metro warnings and let it\n // fall back cleanly to file-based resolution.\n if (moduleName.startsWith('@formatjs/')) {\n inflightFallbackContexts.add(context);\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cleanContext = {\n ...(context as any),\n unstable_enablePackageExports: false,\n };\n return getMetroResolve()(cleanContext, moduleName, ...args);\n } finally {\n inflightFallbackContexts.delete(context);\n }\n }\n\n // Delegate to the user-provided resolver if present\n if (existingResolveRequest) {\n return existingResolveRequest(context, moduleName, ...args);\n }\n\n // Re-entry guard: metro-resolver has already been invoked for this\n // context and is now calling back through context.resolveRequest (the\n // outer chain) which has bubbled back to us. Strip resolveRequest so\n // metro-resolver resolves the module with only its built-in rules\n // (alias, extraNodeModules, etc.) and does not recurse again.\n if (inflightFallbackContexts.has(context)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const { resolveRequest: _r, ...pureContext } = context as any;\n return getMetroResolve()(pureContext, moduleName, ...args);\n }\n\n // First pass: call metro-resolver while preserving context.resolveRequest\n // so outer wrappers (NativeWind, Sentry, …) still get a chance to\n // handle modules that metro-resolver cannot locate on its own (e.g. @/\n // tsconfig path aliases that a wrapper resolves via its own logic).\n inflightFallbackContexts.add(context);\n try {\n return getMetroResolve()(context, moduleName, ...args);\n } finally {\n inflightFallbackContexts.delete(context);\n }\n },\n blockList: [\n ...existingPatterns,\n ...configuration.content.fileExtensions.map(\n (ext) => new RegExp(`.*${ext.replace(/\\./g, '\\\\.')}$`)\n ),\n ],\n },\n } as MetroConfig;\n\n return config;\n};\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayer } = require(\"react-native-intlayer/metro\");\n *\n * module.exports = (async () => {\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return await configMetroIntlayer(defaultConfig);\n * })();\n * ```\n *\n * > Note: `configMetroIntlayer` builds intlayer dictionaries on server start. Use `configMetroIntlayerSync` instead if you want to skip that.\n */\nexport const configMetroIntlayer = async (\n baseConfig?: MetroConfig\n): Promise<MetroConfig> => {\n const configuration = getConfiguration();\n\n await prepareIntlayer(configuration);\n\n return configMetroIntlayerSync(baseConfig);\n};\n"],"mappings":";;;;;;;AAeA,MAAM,wBAAqC;AACzC,KAAI;EACF,MAAM,kBAAkBA,kBACd,QAAQ,qBAAqB,EACrC,KACD;AACD,mBAEIA,QAAY,iBAAiB,gBAAgB,iBAAiB,CAC/D,CACD;SACI;AACN,mBAAgB,iBAAiB,CAC9B;;;;;;;;;;;;;;;;AAmBP,MAAa,2BACX,eACgB;CAChB,MAAM,gBAAgB,kBAAkB;CAExC,MAAM,QAAQ,SAAS;EACrB;EACA,WAAWA;EACZ,CAAC;;;;;;;;;;;;;;;CAgBF,MAAM,cAAc,cAAc,OAAO;CAEzC,MAAM,oBAAoB,YAAY,UAAU;CAChD,MAAM,mBACJ,6BAA6B,SACzB,CAAC,kBAAkB,GAClB,qBAAqB,EAAE;CAE9B,MAAM,yBAAyB,YAAY,UAAU;;;;;;;;;;;;;;;;;CAkBrD,MAAM,2CAA2B,IAAI,SAAiB;AAwGtD,QAAO;EArGL,GAAG;EAEH,UAAU;GACR,GAAG,YAAY;GACf,iBAAiB,SAAS,YAAY,GAAG,SAAS;AAChD,QAAI,OAAO,KAAK,MAAM,CAAC,SAAS,WAAW,CACzC,QAAO;KACL,UAAU,MAAM;KAChB,MAAM;KACP;AAIH,QAAI,eAAe,0BACjB,QAAO;KACL,oBAAkB,QAAQ,0BAA0B;KACpD,MAAM;KACP;AAIH,QAAI,eAAe,sBAEjB,QAAO;KACL,oBAAkB,QAAQ,8BAA8B;KACxD,MAAM;KACP;AAOH,QACE,eAAe,oBACf,WAAW,WAAW,kBAAkB,CAExC,KAAI;AACF,YAAO;MACL,oBAAkB,QAAQ,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC;MAC/D,MAAM;MACP;YACK;AASV,QAAI,WAAW,WAAW,aAAa,EAAE;AACvC,8BAAyB,IAAI,QAAQ;AACrC,SAAI;MAEF,MAAM,eAAe;OACnB,GAAI;OACJ,+BAA+B;OAChC;AACD,aAAO,iBAAiB,CAAC,cAAc,YAAY,GAAG,KAAK;eACnD;AACR,+BAAyB,OAAO,QAAQ;;;AAK5C,QAAI,uBACF,QAAO,uBAAuB,SAAS,YAAY,GAAG,KAAK;AAQ7D,QAAI,yBAAyB,IAAI,QAAQ,EAAE;KAEzC,MAAM,EAAE,gBAAgB,IAAI,GAAG,gBAAgB;AAC/C,YAAO,iBAAiB,CAAC,aAAa,YAAY,GAAG,KAAK;;AAO5D,6BAAyB,IAAI,QAAQ;AACrC,QAAI;AACF,YAAO,iBAAiB,CAAC,SAAS,YAAY,GAAG,KAAK;cAC9C;AACR,8BAAyB,OAAO,QAAQ;;;GAG5C,WAAW,CACT,GAAG,kBACH,GAAG,cAAc,QAAQ,eAAe,KACrC,QAAQ,IAAI,OAAO,KAAK,IAAI,QAAQ,OAAO,MAAM,CAAC,GAAG,CACvD,CACF;GACF;EAGU;;;;;;;;;;;;;;;;AAiBf,MAAa,sBAAsB,OACjC,eACyB;AAGzB,OAAM,gBAFgB,kBAEa,CAAC;AAEpC,QAAO,wBAAwB,WAAW"}
@@ -0,0 +1 @@
1
+ export * from "react-intlayer/html"
@@ -1,4 +1,5 @@
1
1
  import { intlayerPolyfill } from "./intlayerPolyfill.mjs";
2
2
  import { IntlayerProvider } from "./intlayerProvider.mjs";
3
+ import { IntlayerClientContext, IntlayerProviderContent, getDictionary, getIntlayer, localeInStorage, setLocaleInStorage, t, useDictionary, useDictionaryAsync, useDictionaryDynamic, useI18n, useIntl, useIntlayer, useIntlayerContext, useLoadDynamic, useLocale, useLocaleBase, useLocaleCookie, useLocaleStorage, useRewriteURL } from "react-intlayer";
3
4
 
4
- export { IntlayerProvider, intlayerPolyfill };
5
+ export { IntlayerClientContext, IntlayerProvider, IntlayerProviderContent, getDictionary, getIntlayer, intlayerPolyfill, localeInStorage, setLocaleInStorage, t, useDictionary, useDictionaryAsync, useDictionaryDynamic, useI18n, useIntl, useIntlayer, useIntlayerContext, useLoadDynamic, useLocale, useLocaleBase, useLocaleCookie, useLocaleStorage, useRewriteURL };
@@ -2,18 +2,70 @@
2
2
  /**
3
3
  * Applies necessary polyfills for React Native to support Intlayer.
4
4
  *
5
- * This includes polyfilling `structuredClone` if it is missing,
6
- * and providing no-op implementations for standard DOM `window` methods
7
- * (`addEventListener`, `removeEventListener`, `postMessage`)
8
- * to ensure compatibility with libraries that expect a browser-like environment.
5
+ * This includes:
6
+ * - Polyfilling `structuredClone` if it is missing.
7
+ * - Providing no-op implementations for standard DOM `window` methods
8
+ * (`addEventListener`, `removeEventListener`, `postMessage`).
9
+ * - Providing in-memory stubs for `document.cookie`, `localStorage`, and
10
+ * `sessionStorage` so that `@intlayer/core`'s locale-storage helpers work
11
+ * without crashing in a React Native environment.
12
+ *
13
+ * Note: These stubs are in-memory only. The locale selection will survive
14
+ * hot-reloads but not full app restarts. To persist across restarts, pass a
15
+ * custom `setLocale` to `<IntlayerProvider>` backed by AsyncStorage.
9
16
  */
17
+ const createStorage = () => {
18
+ const store = {};
19
+ return {
20
+ getItem: (key) => store[key] ?? null,
21
+ setItem: (key, value) => {
22
+ store[key] = String(value);
23
+ },
24
+ removeItem: (key) => {
25
+ delete store[key];
26
+ },
27
+ clear: () => {
28
+ for (const key in store) delete store[key];
29
+ },
30
+ get length() {
31
+ return Object.keys(store).length;
32
+ },
33
+ key: (index) => Object.keys(store)[index] ?? null
34
+ };
35
+ };
10
36
  const intlayerPolyfill = () => {
11
37
  if (typeof global.structuredClone !== "function") global.structuredClone = (obj) => JSON.parse(JSON.stringify(obj));
12
38
  if (typeof window !== "undefined") {
13
- if (typeof window.addEventListener !== "function") window.addEventListener = () => null;
14
- if (typeof window.removeEventListener !== "function") window.removeEventListener = () => null;
15
- if (typeof window.postMessage !== "function") window.postMessage = () => null;
39
+ const noop = () => null;
40
+ if (typeof window.addEventListener !== "function") window.addEventListener = noop;
41
+ if (typeof window.removeEventListener !== "function") window.removeEventListener = noop;
42
+ if (typeof window.postMessage !== "function") window.postMessage = noop;
43
+ }
44
+ if (typeof document === "undefined") {
45
+ let cookieJar = "";
46
+ Object.defineProperty(global, "document", {
47
+ configurable: true,
48
+ get: () => ({
49
+ get cookie() {
50
+ return cookieJar;
51
+ },
52
+ set cookie(value) {
53
+ const [pair] = value.split(";");
54
+ const [key, val] = pair?.split("=") ?? [];
55
+ const name = key?.trim();
56
+ cookieJar = [...cookieJar.split(";").filter((c) => !c.trim().startsWith(`${name}=`)).filter(Boolean), `${name}=${val ?? ""}`].join("; ");
57
+ }
58
+ })
59
+ });
16
60
  }
61
+ if (typeof localStorage === "undefined") Object.defineProperty(global, "localStorage", {
62
+ configurable: true,
63
+ value: createStorage()
64
+ });
65
+ if (typeof sessionStorage === "undefined") Object.defineProperty(global, "sessionStorage", {
66
+ configurable: true,
67
+ value: createStorage()
68
+ });
17
69
  };
18
70
 
19
71
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"intlayerPolyfill.mjs","names":[],"sources":["../../src/intlayerPolyfill.ts"],"sourcesContent":["/**\n * Applies necessary polyfills for React Native to support Intlayer.\n *\n * This includes polyfilling `structuredClone` if it is missing,\n * and providing no-op implementations for standard DOM `window` methods\n * (`addEventListener`, `removeEventListener`, `postMessage`)\n * to ensure compatibility with libraries that expect a browser-like environment.\n */\nexport const intlayerPolyfill = () => {\n if (typeof global.structuredClone !== 'function') {\n global.structuredClone = (obj) => JSON.parse(JSON.stringify(obj));\n }\n\n if (typeof window !== 'undefined') {\n if (typeof window.addEventListener !== 'function') {\n window.addEventListener = () => null;\n }\n if (typeof window.removeEventListener !== 'function') {\n window.removeEventListener = () => null;\n }\n if (typeof window.postMessage !== 'function') {\n window.postMessage = () => null;\n }\n }\n};\n"],"mappings":";;;;;;;;;AAQA,MAAa,yBAAyB;AACpC,KAAI,OAAO,OAAO,oBAAoB,WACpC,QAAO,mBAAmB,QAAQ,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;AAGnE,KAAI,OAAO,WAAW,aAAa;AACjC,MAAI,OAAO,OAAO,qBAAqB,WACrC,QAAO,yBAAyB;AAElC,MAAI,OAAO,OAAO,wBAAwB,WACxC,QAAO,4BAA4B;AAErC,MAAI,OAAO,OAAO,gBAAgB,WAChC,QAAO,oBAAoB"}
1
+ {"version":3,"file":"intlayerPolyfill.mjs","names":[],"sources":["../../src/intlayerPolyfill.ts"],"sourcesContent":["/**\n * Applies necessary polyfills for React Native to support Intlayer.\n *\n * This includes:\n * - Polyfilling `structuredClone` if it is missing.\n * - Providing no-op implementations for standard DOM `window` methods\n * (`addEventListener`, `removeEventListener`, `postMessage`).\n * - Providing in-memory stubs for `document.cookie`, `localStorage`, and\n * `sessionStorage` so that `@intlayer/core`'s locale-storage helpers work\n * without crashing in a React Native environment.\n *\n * Note: These stubs are in-memory only. The locale selection will survive\n * hot-reloads but not full app restarts. To persist across restarts, pass a\n * custom `setLocale` to `<IntlayerProvider>` backed by AsyncStorage.\n */\nconst createStorage = () => {\n const store: Record<string, string> = {};\n return {\n getItem: (key: string) => store[key] ?? null,\n setItem: (key: string, value: string) => {\n store[key] = String(value);\n },\n removeItem: (key: string) => {\n delete store[key];\n },\n clear: () => {\n for (const key in store) {\n delete store[key];\n }\n },\n get length() {\n return Object.keys(store).length;\n },\n key: (index: number) => Object.keys(store)[index] ?? null,\n };\n};\n\nexport const intlayerPolyfill = () => {\n if (typeof global.structuredClone !== 'function') {\n global.structuredClone = (obj) => JSON.parse(JSON.stringify(obj));\n }\n\n if (typeof window !== 'undefined') {\n const noop = () => null;\n if (typeof window.addEventListener !== 'function') {\n window.addEventListener = noop;\n }\n if (typeof window.removeEventListener !== 'function') {\n window.removeEventListener = noop;\n }\n if (typeof window.postMessage !== 'function') {\n window.postMessage = noop;\n }\n }\n\n // `@intlayer/core`'s localeStorageOptions accesses document.cookie directly.\n // In React Native, `document` is undefined — we provide a minimal in-memory\n // cookie jar so reads/writes work without throwing.\n if (typeof document === 'undefined') {\n let cookieJar = '';\n Object.defineProperty(global, 'document', {\n configurable: true,\n get: () => ({\n get cookie() {\n return cookieJar;\n },\n set cookie(value: string) {\n // Simplified cookie setter: just append/overwrite the key\n const [pair] = value.split(';');\n const [key, val] = pair?.split('=') ?? [];\n const name = key?.trim();\n const existing = cookieJar\n .split(';')\n .filter((c) => !c.trim().startsWith(`${name}=`))\n .filter(Boolean);\n cookieJar = [...existing, `${name}=${val ?? ''}`].join('; ');\n },\n }),\n });\n }\n\n if (typeof localStorage === 'undefined') {\n Object.defineProperty(global, 'localStorage', {\n configurable: true,\n value: createStorage(),\n });\n }\n\n if (typeof sessionStorage === 'undefined') {\n Object.defineProperty(global, 'sessionStorage', {\n configurable: true,\n value: createStorage(),\n });\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAM,sBAAsB;CAC1B,MAAM,QAAgC,EAAE;AACxC,QAAO;EACL,UAAU,QAAgB,MAAM,QAAQ;EACxC,UAAU,KAAa,UAAkB;AACvC,SAAM,OAAO,OAAO,MAAM;;EAE5B,aAAa,QAAgB;AAC3B,UAAO,MAAM;;EAEf,aAAa;AACX,QAAK,MAAM,OAAO,MAChB,QAAO,MAAM;;EAGjB,IAAI,SAAS;AACX,UAAO,OAAO,KAAK,MAAM,CAAC;;EAE5B,MAAM,UAAkB,OAAO,KAAK,MAAM,CAAC,UAAU;EACtD;;AAGH,MAAa,yBAAyB;AACpC,KAAI,OAAO,OAAO,oBAAoB,WACpC,QAAO,mBAAmB,QAAQ,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;AAGnE,KAAI,OAAO,WAAW,aAAa;EACjC,MAAM,aAAa;AACnB,MAAI,OAAO,OAAO,qBAAqB,WACrC,QAAO,mBAAmB;AAE5B,MAAI,OAAO,OAAO,wBAAwB,WACxC,QAAO,sBAAsB;AAE/B,MAAI,OAAO,OAAO,gBAAgB,WAChC,QAAO,cAAc;;AAOzB,KAAI,OAAO,aAAa,aAAa;EACnC,IAAI,YAAY;AAChB,SAAO,eAAe,QAAQ,YAAY;GACxC,cAAc;GACd,YAAY;IACV,IAAI,SAAS;AACX,YAAO;;IAET,IAAI,OAAO,OAAe;KAExB,MAAM,CAAC,QAAQ,MAAM,MAAM,IAAI;KAC/B,MAAM,CAAC,KAAK,OAAO,MAAM,MAAM,IAAI,IAAI,EAAE;KACzC,MAAM,OAAO,KAAK,MAAM;AAKxB,iBAAY,CAAC,GAJI,UACd,MAAM,IAAI,CACV,QAAQ,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,GAAG,KAAK,GAAG,CAAC,CAC/C,OAAO,QACc,EAAE,GAAG,KAAK,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK;;IAE/D;GACF,CAAC;;AAGJ,KAAI,OAAO,iBAAiB,YAC1B,QAAO,eAAe,QAAQ,gBAAgB;EAC5C,cAAc;EACd,OAAO,eAAe;EACvB,CAAC;AAGJ,KAAI,OAAO,mBAAmB,YAC5B,QAAO,eAAe,QAAQ,kBAAkB;EAC9C,cAAc;EACd,OAAO,eAAe;EACvB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"intlayerProvider.mjs","names":[],"sources":["../../src/intlayerProvider.tsx"],"sourcesContent":["import {\n IntlayerProviderContent,\n type IntlayerProviderProps as IntlayerProviderPropsBase,\n} from 'react-intlayer';\nimport { intlayerPolyfill } from './intlayerPolyfill';\n\nintlayerPolyfill();\n\ntype IntlayerProviderProps = Omit<\n IntlayerProviderPropsBase,\n 'disableEditor' | 'isCookieEnabled'\n>;\n\n/**\n * Provider component that wraps your application and provides the Intlayer context.\n *\n * This provider also automatically applies necessary polyfills for React Native.\n *\n * @param props - The provider props, excluding editor-specific and cookie-specific options which are not applicable in React Native.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'react-native-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider = ({\n children,\n ...props\n}: IntlayerProviderProps) => (\n <IntlayerProviderContent {...props}>{children}</IntlayerProviderContent>\n);\n"],"mappings":";;;;;AAMA,kBAAkB;;;;;;;;;;;;;;;;;;;;AA0BlB,MAAa,oBAAoB,EAC/B,UACA,GAAG,YAEH,oBAAC,yBAAD;CAAyB,GAAI;CAAQ;CAAmC"}
1
+ {"version":3,"file":"intlayerProvider.mjs","names":[],"sources":["../../src/intlayerProvider.tsx"],"sourcesContent":["import {\n IntlayerProviderContent,\n type IntlayerProviderProps as IntlayerProviderPropsBase,\n} from 'react-intlayer';\nimport { intlayerPolyfill } from './intlayerPolyfill';\n\nintlayerPolyfill();\n\n/**\n * Props accepted by the React Native `IntlayerProvider`.\n *\n * Editor-specific (`disableEditor`) and cookie-specific (`isCookieEnabled`)\n * options are omitted because they are not applicable in a React Native\n * environment.\n */\nexport type IntlayerProviderProps = Omit<\n IntlayerProviderPropsBase,\n 'disableEditor' | 'isCookieEnabled'\n>;\n\n/**\n * Provider component that wraps your application and provides the Intlayer context.\n *\n * This provider also automatically applies necessary polyfills for React Native.\n *\n * @param props - The provider props, excluding editor-specific and cookie-specific options which are not applicable in React Native.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'react-native-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider = ({\n children,\n ...props\n}: IntlayerProviderProps) => (\n <IntlayerProviderContent {...props}>{children}</IntlayerProviderContent>\n);\n"],"mappings":";;;;;AAMA,kBAAkB;;;;;;;;;;;;;;;;;;;;AAiClB,MAAa,oBAAoB,EAC/B,UACA,GAAG,YAEH,oBAAC,yBAAD;CAAyB,GAAI;CAAQ;CAAmC"}
@@ -0,0 +1 @@
1
+ export * from "react-intlayer/markdown"
@@ -0,0 +1 @@
1
+ export * from "react-intlayer/format";
@@ -1 +1 @@
1
- {"version":3,"file":"configMetroIntlayer.d.ts","names":[],"sources":["../../src/configMetroIntlayer.ts"],"mappings":";;;KAgCK,WAAA,GAAc,UAAA,QAAkB,gBAAA;;AA5BqB;;;;;AA2C1D;;;;;;;cAAa,uBAAA,GACX,UAAA,GAAa,WAAA,KACZ,WAAA;;AAsIH;;;;;;;;;;;;;cAAa,mBAAA,GACX,UAAA,GAAa,WAAA,KACZ,OAAA,CAAQ,WAAA"}
1
+ {"version":3,"file":"configMetroIntlayer.d.ts","names":[],"sources":["../../src/configMetroIntlayer.ts"],"mappings":";;;KAgCK,WAAA,GAAc,UAAA,QAAkB,gBAAA;;AA5BqB;;;;;AA2C1D;;;;;;;cAAa,uBAAA,GACX,UAAA,GAAa,WAAA,KACZ,WAAA;;AAyKH;;;;;;;;;;;;;cAAa,mBAAA,GACX,UAAA,GAAa,WAAA,KACZ,OAAA,CAAQ,WAAA"}
@@ -0,0 +1 @@
1
+ export * from "react-intlayer/html";
@@ -1,3 +1,4 @@
1
1
  import { intlayerPolyfill } from "./intlayerPolyfill.js";
2
- import { IntlayerProvider } from "./intlayerProvider.js";
3
- export { IntlayerProvider, intlayerPolyfill };
2
+ import { IntlayerProvider, IntlayerProviderProps } from "./intlayerProvider.js";
3
+ import { IntlayerClientContext, IntlayerNode, IntlayerProviderContent, UseLocaleProps, UseLocaleResult, getDictionary, getIntlayer, localeInStorage, setLocaleInStorage, t, useDictionary, useDictionaryAsync, useDictionaryDynamic, useI18n, useIntl, useIntlayer, useIntlayerContext, useLoadDynamic, useLocale, useLocaleBase, useLocaleCookie, useLocaleStorage, useRewriteURL } from "react-intlayer";
4
+ export { IntlayerClientContext, type IntlayerNode, IntlayerProvider, IntlayerProviderContent, IntlayerProviderProps, type UseLocaleProps, type UseLocaleResult, getDictionary, getIntlayer, intlayerPolyfill, localeInStorage, setLocaleInStorage, t, useDictionary, useDictionaryAsync, useDictionaryDynamic, useI18n, useIntl, useIntlayer, useIntlayerContext, useLoadDynamic, useLocale, useLocaleBase, useLocaleCookie, useLocaleStorage, useRewriteURL };
@@ -1,12 +1,4 @@
1
1
  //#region src/intlayerPolyfill.d.ts
2
- /**
3
- * Applies necessary polyfills for React Native to support Intlayer.
4
- *
5
- * This includes polyfilling `structuredClone` if it is missing,
6
- * and providing no-op implementations for standard DOM `window` methods
7
- * (`addEventListener`, `removeEventListener`, `postMessage`)
8
- * to ensure compatibility with libraries that expect a browser-like environment.
9
- */
10
2
  declare const intlayerPolyfill: () => void;
11
3
  //#endregion
12
4
  export { intlayerPolyfill };
@@ -1 +1 @@
1
- {"version":3,"file":"intlayerPolyfill.d.ts","names":[],"sources":["../../src/intlayerPolyfill.ts"],"mappings":";;AAQA;;;;;;;cAAa,gBAAA"}
1
+ {"version":3,"file":"intlayerPolyfill.d.ts","names":[],"sources":["../../src/intlayerPolyfill.ts"],"mappings":";cAqCa,gBAAA"}
@@ -1,8 +1,15 @@
1
+ import { IntlayerProviderProps as IntlayerProviderProps$1 } from "react-intlayer";
1
2
  import * as _$react from "react";
2
- import { IntlayerProviderProps } from "react-intlayer";
3
3
 
4
4
  //#region src/intlayerProvider.d.ts
5
- type IntlayerProviderProps$1 = Omit<IntlayerProviderProps, 'disableEditor' | 'isCookieEnabled'>;
5
+ /**
6
+ * Props accepted by the React Native `IntlayerProvider`.
7
+ *
8
+ * Editor-specific (`disableEditor`) and cookie-specific (`isCookieEnabled`)
9
+ * options are omitted because they are not applicable in a React Native
10
+ * environment.
11
+ */
12
+ type IntlayerProviderProps = Omit<IntlayerProviderProps$1, 'disableEditor' | 'isCookieEnabled'>;
6
13
  /**
7
14
  * Provider component that wraps your application and provides the Intlayer context.
8
15
  *
@@ -25,7 +32,7 @@ type IntlayerProviderProps$1 = Omit<IntlayerProviderProps, 'disableEditor' | 'is
25
32
  declare const IntlayerProvider: ({
26
33
  children,
27
34
  ...props
28
- }: IntlayerProviderProps$1) => _$react.JSX.Element;
35
+ }: IntlayerProviderProps) => _$react.JSX.Element;
29
36
  //#endregion
30
- export { IntlayerProvider };
37
+ export { IntlayerProvider, IntlayerProviderProps };
31
38
  //# sourceMappingURL=intlayerProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"intlayerProvider.d.ts","names":[],"sources":["../../src/intlayerProvider.tsx"],"mappings":";;;;KAQK,uBAAA,GAAwB,IAAA,CAC3B,qBAAA;;;AANsB;;;;;AA6BxB;;;;;;;;;;;;cAAa,gBAAA;EAAoB,QAAA;EAAA,GAAA;AAAA,GAG9B,uBAAA,KAAqB,OAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"intlayerProvider.d.ts","names":[],"sources":["../../src/intlayerProvider.tsx"],"mappings":";;;;;;;AAeA;;;;KAAY,qBAAA,GAAwB,IAAA,CAClC,uBAAA;AAuBF;;;;;;;;;;;;;;;;;;;AAAA,cAAa,gBAAA;EAAoB,QAAA;EAAA,GAAA;AAAA,GAG9B,qBAAA,KAAqB,OAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1 @@
1
+ export * from "react-intlayer/markdown";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-intlayer",
3
- "version": "9.0.0-canary.5",
3
+ "version": "9.0.0-canary.6",
4
4
  "private": false,
5
5
  "description": "A React Native plugin for seamless internationalization (i18n), providing locale detection, redirection, and environment-based configuration",
6
6
  "keywords": [
@@ -41,6 +41,21 @@
41
41
  "require": "./dist/cjs/index.cjs",
42
42
  "import": "./dist/esm/index.mjs"
43
43
  },
44
+ "./format": {
45
+ "types": "./dist/types/client/format/index.d.ts",
46
+ "require": "./dist/cjs/client/format/index.cjs",
47
+ "import": "./dist/esm/client/format/index.mjs"
48
+ },
49
+ "./html": {
50
+ "types": "./dist/types/html/index.d.ts",
51
+ "require": "./dist/cjs/html/index.cjs",
52
+ "import": "./dist/esm/html/index.mjs"
53
+ },
54
+ "./markdown": {
55
+ "types": "./dist/types/markdown/index.d.ts",
56
+ "require": "./dist/cjs/markdown/index.cjs",
57
+ "import": "./dist/esm/markdown/index.mjs"
58
+ },
44
59
  "./metro": {
45
60
  "types": "./dist/types/metro.d.ts",
46
61
  "require": "./dist/cjs/metro.cjs",
@@ -56,6 +71,15 @@
56
71
  ".": [
57
72
  "./dist/types/index.d.ts"
58
73
  ],
74
+ "format": [
75
+ "./dist/types/client/format/index.d.ts"
76
+ ],
77
+ "html": [
78
+ "./dist/types/html/index.d.ts"
79
+ ],
80
+ "markdown": [
81
+ "./dist/types/markdown/index.d.ts"
82
+ ],
59
83
  "metro": [
60
84
  "./dist/types/metro.d.ts"
61
85
  ],
@@ -86,11 +110,11 @@
86
110
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
87
111
  },
88
112
  "dependencies": {
89
- "@intlayer/chokidar": "9.0.0-canary.5",
90
- "@intlayer/config": "9.0.0-canary.5",
91
- "@intlayer/core": "9.0.0-canary.5",
92
- "@intlayer/types": "9.0.0-canary.5",
93
- "react-intlayer": "9.0.0-canary.5"
113
+ "@intlayer/chokidar": "9.0.0-canary.6",
114
+ "@intlayer/config": "9.0.0-canary.6",
115
+ "@intlayer/core": "9.0.0-canary.6",
116
+ "@intlayer/types": "9.0.0-canary.6",
117
+ "react-intlayer": "9.0.0-canary.6"
94
118
  },
95
119
  "devDependencies": {
96
120
  "@types/node": "25.9.4",
@@ -108,8 +132,7 @@
108
132
  },
109
133
  "peerDependencies": {
110
134
  "expo": ">=52",
111
- "react": ">=18.0.0",
112
- "react-intlayer": "9.0.0-canary.5"
135
+ "react": ">=18.0.0"
113
136
  },
114
137
  "engines": {
115
138
  "node": ">=14.18"