@bleedingdev/modern-js-i18n-runtime-extensions 3.9.0-ultramodern.10 → 3.9.0-ultramodern.12

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.
Files changed (73) hide show
  1. package/dist/cjs/index.js +10 -10
  2. package/dist/cjs/localeRedirectPolicy.js +6 -6
  3. package/dist/cjs/paths.js +3 -3
  4. package/dist/cjs/router-navigation/adapter.js +24 -166
  5. package/dist/esm/index.mjs +1 -1
  6. package/dist/esm/localeRedirectPolicy.mjs +1 -1
  7. package/dist/esm/paths.mjs +1 -1
  8. package/dist/esm/router-navigation/adapter.mjs +26 -168
  9. package/dist/esm-node/index.mjs +1 -1
  10. package/dist/esm-node/localeRedirectPolicy.mjs +1 -1
  11. package/dist/esm-node/paths.mjs +1 -1
  12. package/dist/esm-node/router-navigation/adapter.mjs +26 -168
  13. package/dist/types/index.d.ts +1 -1
  14. package/dist/types/localeRedirectPolicy.d.ts +1 -1
  15. package/dist/types/paths.d.ts +1 -1
  16. package/dist/types/router-navigation/adapter.d.ts +7 -55
  17. package/package.json +5 -5
  18. package/src/index.ts +1 -1
  19. package/src/localeRedirectPolicy.ts +2 -2
  20. package/src/paths.ts +2 -2
  21. package/src/router-navigation/adapter.tsx +62 -478
  22. package/tests/routerNavigation.test.tsx +80 -0
  23. package/dist/cjs/localisedUrls/config.js +0 -49
  24. package/dist/cjs/localisedUrls/index.js +0 -98
  25. package/dist/cjs/localisedUrls/normalise.js +0 -87
  26. package/dist/cjs/localisedUrls/pathname.js +0 -68
  27. package/dist/cjs/localisedUrls/patterns.js +0 -214
  28. package/dist/cjs/localisedUrls/redirect.js +0 -100
  29. package/dist/cjs/localisedUrls/resolve.js +0 -78
  30. package/dist/cjs/localisedUrls/routeIdentity.js +0 -118
  31. package/dist/cjs/localisedUrls/routes.js +0 -210
  32. package/dist/cjs/localisedUrls/types.js +0 -18
  33. package/dist/esm/localisedUrls/config.mjs +0 -11
  34. package/dist/esm/localisedUrls/index.mjs +0 -8
  35. package/dist/esm/localisedUrls/normalise.mjs +0 -37
  36. package/dist/esm/localisedUrls/pathname.mjs +0 -24
  37. package/dist/esm/localisedUrls/patterns.mjs +0 -152
  38. package/dist/esm/localisedUrls/redirect.mjs +0 -53
  39. package/dist/esm/localisedUrls/resolve.mjs +0 -37
  40. package/dist/esm/localisedUrls/routeIdentity.mjs +0 -77
  41. package/dist/esm/localisedUrls/routes.mjs +0 -169
  42. package/dist/esm/localisedUrls/types.mjs +0 -0
  43. package/dist/esm-node/localisedUrls/config.mjs +0 -12
  44. package/dist/esm-node/localisedUrls/index.mjs +0 -9
  45. package/dist/esm-node/localisedUrls/normalise.mjs +0 -38
  46. package/dist/esm-node/localisedUrls/pathname.mjs +0 -25
  47. package/dist/esm-node/localisedUrls/patterns.mjs +0 -153
  48. package/dist/esm-node/localisedUrls/redirect.mjs +0 -54
  49. package/dist/esm-node/localisedUrls/resolve.mjs +0 -38
  50. package/dist/esm-node/localisedUrls/routeIdentity.mjs +0 -78
  51. package/dist/esm-node/localisedUrls/routes.mjs +0 -170
  52. package/dist/esm-node/localisedUrls/types.mjs +0 -1
  53. package/dist/types/localisedUrls/config.d.ts +0 -9
  54. package/dist/types/localisedUrls/index.d.ts +0 -10
  55. package/dist/types/localisedUrls/normalise.d.ts +0 -10
  56. package/dist/types/localisedUrls/pathname.d.ts +0 -4
  57. package/dist/types/localisedUrls/patterns.d.ts +0 -11
  58. package/dist/types/localisedUrls/redirect.d.ts +0 -19
  59. package/dist/types/localisedUrls/resolve.d.ts +0 -7
  60. package/dist/types/localisedUrls/routeIdentity.d.ts +0 -24
  61. package/dist/types/localisedUrls/routes.d.ts +0 -3
  62. package/dist/types/localisedUrls/types.d.ts +0 -14
  63. package/src/localisedUrls/config.ts +0 -18
  64. package/src/localisedUrls/index.ts +0 -28
  65. package/src/localisedUrls/normalise.ts +0 -62
  66. package/src/localisedUrls/pathname.ts +0 -60
  67. package/src/localisedUrls/patterns.ts +0 -283
  68. package/src/localisedUrls/redirect.ts +0 -107
  69. package/src/localisedUrls/resolve.ts +0 -106
  70. package/src/localisedUrls/routeIdentity.ts +0 -107
  71. package/src/localisedUrls/routes.ts +0 -432
  72. package/src/localisedUrls/types.ts +0 -18
  73. package/tests/localisedUrls.test.ts +0 -532
package/dist/cjs/index.js CHANGED
@@ -9,8 +9,8 @@ var __webpack_modules__ = {
9
9
  "./localeRedirectPolicy" (module) {
10
10
  module.exports = require("./localeRedirectPolicy.js");
11
11
  },
12
- "./localisedUrls/index" (module) {
13
- module.exports = require("./localisedUrls/index.js");
12
+ "@modern-js/runtime-extensions/localised-urls" (module) {
13
+ module.exports = require("@modern-js/runtime-extensions/localised-urls");
14
14
  }
15
15
  };
16
16
  var __webpack_module_cache__ = {};
@@ -60,21 +60,21 @@ function __webpack_require__(moduleId) {
60
60
  var __webpack_exports__ = {};
61
61
  (()=>{
62
62
  __webpack_require__.r(__webpack_exports__);
63
- var _language_sync_controller__rspack_import_0 = __webpack_require__("./language-sync/controller");
63
+ var _modern_js_runtime_extensions_localised_urls__rspack_import_0 = __webpack_require__("@modern-js/runtime-extensions/localised-urls");
64
64
  var __rspack_reexport = {};
65
- for(const __rspack_import_key in _language_sync_controller__rspack_import_0)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_language_sync_controller__rspack_import_0[__rspack_import_key];
65
+ for(const __rspack_import_key in _modern_js_runtime_extensions_localised_urls__rspack_import_0)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_modern_js_runtime_extensions_localised_urls__rspack_import_0[__rspack_import_key];
66
66
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
67
- var _language_sync_react__rspack_import_1 = __webpack_require__("./language-sync/react");
67
+ var _language_sync_controller__rspack_import_1 = __webpack_require__("./language-sync/controller");
68
68
  var __rspack_reexport = {};
69
- for(const __rspack_import_key in _language_sync_react__rspack_import_1)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_language_sync_react__rspack_import_1[__rspack_import_key];
69
+ for(const __rspack_import_key in _language_sync_controller__rspack_import_1)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_language_sync_controller__rspack_import_1[__rspack_import_key];
70
70
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
71
- var _localeRedirectPolicy__rspack_import_2 = __webpack_require__("./localeRedirectPolicy");
71
+ var _language_sync_react__rspack_import_2 = __webpack_require__("./language-sync/react");
72
72
  var __rspack_reexport = {};
73
- for(const __rspack_import_key in _localeRedirectPolicy__rspack_import_2)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_localeRedirectPolicy__rspack_import_2[__rspack_import_key];
73
+ for(const __rspack_import_key in _language_sync_react__rspack_import_2)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_language_sync_react__rspack_import_2[__rspack_import_key];
74
74
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
75
- var _localisedUrls_index__rspack_import_3 = __webpack_require__("./localisedUrls/index");
75
+ var _localeRedirectPolicy__rspack_import_3 = __webpack_require__("./localeRedirectPolicy");
76
76
  var __rspack_reexport = {};
77
- for(const __rspack_import_key in _localisedUrls_index__rspack_import_3)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_localisedUrls_index__rspack_import_3[__rspack_import_key];
77
+ for(const __rspack_import_key in _localeRedirectPolicy__rspack_import_3)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_localeRedirectPolicy__rspack_import_3[__rspack_import_key];
78
78
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
79
79
  })();
80
80
  for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
@@ -34,7 +34,7 @@ __webpack_require__.d(__webpack_exports__, {
34
34
  isStaticResourceRequest: ()=>isStaticResourceRequest,
35
35
  shouldIgnoreRedirect: ()=>shouldIgnoreRedirect
36
36
  });
37
- const index_js_namespaceObject = require("./localisedUrls/index.js");
37
+ const localised_urls_namespaceObject = require("@modern-js/runtime-extensions/localised-urls");
38
38
  const stripUrlPathPrefix = (pathname, urlPath)=>{
39
39
  const basePath = urlPath.replace('/*', '');
40
40
  if (!basePath || '/' === basePath) return pathname;
@@ -43,13 +43,13 @@ const stripUrlPathPrefix = (pathname, urlPath)=>{
43
43
  };
44
44
  const shouldIgnoreRedirect = (pathname, urlPath, ignoreRedirectRoutes)=>{
45
45
  const remainingPath = stripUrlPathPrefix(pathname, urlPath);
46
- return (0, index_js_namespaceObject.shouldSkipLocaleRedirect)(remainingPath, [], ignoreRedirectRoutes);
46
+ return (0, localised_urls_namespaceObject.shouldSkipLocaleRedirect)(remainingPath, [], ignoreRedirectRoutes);
47
47
  };
48
48
  const isStaticResourceRequest = (pathname, staticRoutePrefixes, languages = [])=>{
49
- if ((0, index_js_namespaceObject.isDefaultLocaleRedirectSkipPath)(pathname, languages)) return true;
50
- const matchesStaticRoutePrefix = (targetPathname)=>staticRoutePrefixes.some((prefix)=>(0, index_js_namespaceObject.matchesPathPrefix)(targetPathname, prefix));
49
+ if ((0, localised_urls_namespaceObject.isDefaultLocaleRedirectSkipPath)(pathname, languages)) return true;
50
+ const matchesStaticRoutePrefix = (targetPathname)=>staticRoutePrefixes.some((prefix)=>(0, localised_urls_namespaceObject.matchesPathPrefix)(targetPathname, prefix));
51
51
  if (matchesStaticRoutePrefix(pathname)) return true;
52
- const pathWithoutLanguage = (0, index_js_namespaceObject.stripLanguagePrefix)(pathname, languages);
52
+ const pathWithoutLanguage = (0, localised_urls_namespaceObject.stripLanguagePrefix)(pathname, languages);
53
53
  return pathWithoutLanguage !== pathname && matchesStaticRoutePrefix(pathWithoutLanguage);
54
54
  };
55
55
  const getLanguageFromPath = (req, urlPath, languages)=>{
@@ -66,7 +66,7 @@ const buildLocalizedUrl = (req, urlPath, language, languages, localisedUrls)=>{
66
66
  const pathname = url.pathname;
67
67
  const basePath = urlPath.replace('/*', '');
68
68
  const remainingPath = stripUrlPathPrefix(pathname, urlPath);
69
- const newPathname = (0, index_js_namespaceObject.localiseTargetPathname)(remainingPath, language, languages, localisedUrls);
69
+ const newPathname = (0, localised_urls_namespaceObject.localiseTargetPathname)(remainingPath, language, languages, localisedUrls);
70
70
  const suffix = `${url.search}${url.hash}`;
71
71
  const localizedUrl = '/' === basePath ? newPathname + suffix : basePath + newPathname + suffix;
72
72
  return localizedUrl;
package/dist/cjs/paths.js CHANGED
@@ -32,16 +32,16 @@ __webpack_require__.d(__webpack_exports__, {
32
32
  canonicalPath: ()=>canonicalPath,
33
33
  localizePath: ()=>localizePath
34
34
  });
35
+ const localised_urls_namespaceObject = require("@modern-js/runtime-extensions/localised-urls");
35
36
  const url_namespaceObject = require("@modern-js/runtime-utils/url");
36
- const index_js_namespaceObject = require("./localisedUrls/index.js");
37
37
  const buildLocalizedUrl = (target, language, languages, localisedUrls)=>{
38
38
  const { pathname, search, hash } = (0, url_namespaceObject.splitUrlTarget)(target);
39
- return `${(0, index_js_namespaceObject.localiseTargetPathname)(pathname, language, languages, localisedUrls)}${search}${hash}`;
39
+ return `${(0, localised_urls_namespaceObject.localiseTargetPathname)(pathname, language, languages, localisedUrls)}${search}${hash}`;
40
40
  };
41
41
  const localizePath = (target, language, config)=>buildLocalizedUrl(target, language, config.languages, config.localisedUrls);
42
42
  const canonicalPath = (target, config)=>{
43
43
  const { pathname, search, hash } = (0, url_namespaceObject.splitUrlTarget)(target);
44
- return `${(0, index_js_namespaceObject.canonicalTargetPathname)(pathname, config.languages, config.localisedUrls)}${search}${hash}`;
44
+ return `${(0, localised_urls_namespaceObject.canonicalTargetPathname)(pathname, config.languages, config.localisedUrls)}${search}${hash}`;
45
45
  };
46
46
  exports.buildLocalizedUrl = __webpack_exports__.buildLocalizedUrl;
47
47
  exports.canonicalPath = __webpack_exports__.canonicalPath;
@@ -35,189 +35,47 @@ const runtime_namespaceObject = require("@modern-js/runtime");
35
35
  const context_namespaceObject = require("@modern-js/runtime/context");
36
36
  const router_state_namespaceObject = require("@modern-js/runtime-extensions/router-state");
37
37
  const external_react_namespaceObject = require("react");
38
- const normalizeUrlPart = (value, prefix)=>{
39
- if ('string' != typeof value || !value) return '';
40
- return value.startsWith(prefix) ? value : `${prefix}${value}`;
41
- };
42
- const normalizeLocation = (location)=>{
43
- if (!location || 'object' != typeof location) return null;
44
- const locationValue = location;
45
- if ('string' != typeof locationValue.pathname) return null;
46
- return {
47
- pathname: locationValue.pathname,
48
- search: normalizeUrlPart('string' == typeof locationValue.search ? locationValue.search : locationValue.searchStr, '?'),
49
- hash: normalizeUrlPart(locationValue.hash, '#')
50
- };
51
- };
52
- const getWindowLocation = ()=>{
53
- if (!(0, runtime_namespaceObject.isBrowser)()) return null;
54
- return {
55
- pathname: window.location.pathname,
56
- search: window.location.search,
57
- hash: window.location.hash
58
- };
59
- };
60
- const getRouterFramework = (runtimeContext, internalContext, inReactRouter)=>{
61
- const framework = (0, router_state_namespaceObject.getRouterRuntimeState)(internalContext)?.framework || (0, router_state_namespaceObject.getRouterRuntimeState)(runtimeContext)?.framework;
62
- if (framework) return framework;
63
- if (internalContext.router?.useRouter || runtimeContext.router?.useRouter) return 'tanstack';
64
- if (internalContext.router?.useLocation || internalContext.router?.useHref || runtimeContext.router?.useLocation || runtimeContext.router?.useHref) return 'react-router';
65
- if (inReactRouter) return 'react-router';
66
- };
67
- const getRouterInstance = (internalContext, contextRouter)=>{
68
- if (contextRouter) return contextRouter;
69
- const router = (0, router_state_namespaceObject.getRouterRuntimeState)(internalContext)?.instance;
70
- if (!router || 'object' != typeof router) return null;
71
- return router;
72
- };
73
- const getRouterStateLocation = (internalContext, contextRouter)=>{
74
- const router = getRouterInstance(internalContext, contextRouter);
75
- return normalizeLocation(router?.stores?.location?.get?.()) || normalizeLocation(router?.state?.location);
76
- };
77
- const getRouterParams = (internalContext, contextRouter)=>{
78
- const router = getRouterInstance(internalContext, contextRouter);
79
- const matches = router?.stores?.matches?.get?.() || router?.state?.matches;
80
- if (!Array.isArray(matches)) return {};
81
- return matches.reduce((params, match)=>{
82
- if (match?.params) Object.assign(params, match.params);
83
- return params;
84
- }, {});
85
- };
86
- const getRouterSnapshot = (internalContext, contextRouter)=>{
87
- const location = getRouterStateLocation(internalContext, contextRouter);
88
- const params = getRouterParams(internalContext, contextRouter);
89
- return JSON.stringify([
90
- location?.pathname ?? '',
91
- location?.search ?? '',
92
- location?.hash ?? '',
93
- Object.entries(params).sort(([left], [right])=>left.localeCompare(right))
94
- ]);
95
- };
38
+ const subscribeNone = ()=>()=>{};
39
+ const getEmptySnapshot = ()=>null;
96
40
  const createI18nRouterNavigation = ({ I18nNavigationProvider, useNativeI18nRouterAdapter })=>{
41
+ const NavigationProvider = I18nNavigationProvider;
97
42
  const useIntegratedRouterAdapter = ()=>{
98
43
  const runtimeContext = (0, external_react_namespaceObject.useContext)(runtime_namespaceObject.RuntimeContext);
99
44
  const internalContext = (0, external_react_namespaceObject.useContext)(context_namespaceObject.InternalRuntimeContext);
100
- const routerApi = internalContext.router || runtimeContext.router;
101
45
  const native = useNativeI18nRouterAdapter();
102
- const inReactRouter = native.hasRouter;
103
- const reactRouterNavigate = native.navigate;
104
- const reactRouterLocation = inReactRouter ? native.location : null;
105
- const reactRouterParams = native.params;
106
- const framework = getRouterFramework(runtimeContext, internalContext, inReactRouter);
107
- const contextUseRouter = inReactRouter || 'tanstack' !== framework ? void 0 : internalContext.router?.useRouter || runtimeContext.router?.useRouter;
108
- const contextRouter = contextUseRouter ? contextUseRouter({
109
- warn: false
110
- }) : null;
111
- const slotRouter = getRouterInstance(internalContext, contextRouter);
112
- const drivableSlotRouter = ('tanstack' === framework || 'react-router' === framework) && 'function' == typeof slotRouter?.navigate;
113
- const hasRouter = Boolean(reactRouterNavigate) || drivableSlotRouter;
114
- const subscribeToRouter = (0, external_react_namespaceObject.useCallback)((update)=>{
115
- const unsubscribers = [];
116
- const unsubscribeFromSlot = (0, router_state_namespaceObject.subscribeRouterRuntimeState)(internalContext, update);
117
- if ('function' == typeof unsubscribeFromSlot) unsubscribers.push(unsubscribeFromSlot);
118
- const router = getRouterInstance(internalContext, contextRouter);
119
- if (!router) return ()=>{
120
- for (const unsubscribe of unsubscribers)unsubscribe();
121
- };
122
- if ('react-router' === framework && !inReactRouter && 'function' == typeof router.subscribe) {
123
- const subscribe = router.subscribe;
124
- const unsubscribe = subscribe.call(router, update);
125
- if ('function' == typeof unsubscribe) unsubscribers.push(unsubscribe);
126
- }
127
- if ('tanstack' === framework && 'function' == typeof router.stores?.location?.subscribe) {
128
- const unsubscribe = router.stores.location.subscribe(update);
129
- if ('function' == typeof unsubscribe) unsubscribers.push(unsubscribe);
130
- }
131
- if ('tanstack' === framework && 'function' == typeof router.subscribe) {
132
- const subscribe = router.subscribe;
133
- for (const eventType of [
134
- 'onBeforeNavigate',
135
- 'onBeforeLoad'
136
- ]){
137
- const unsubscribe = subscribe.call(router, eventType, update);
138
- if ('function' == typeof unsubscribe) unsubscribers.push(unsubscribe);
139
- }
140
- }
46
+ const getCapability = (0, external_react_namespaceObject.useCallback)(()=>(0, router_state_namespaceObject.getRouterRuntimeState)(internalContext)?.navigation ?? (0, router_state_namespaceObject.getRouterRuntimeState)(runtimeContext)?.navigation, [
47
+ internalContext,
48
+ runtimeContext
49
+ ]);
50
+ const subscribeCapability = (0, external_react_namespaceObject.useCallback)((update)=>{
51
+ const stopInternal = (0, router_state_namespaceObject.subscribeRouterRuntimeState)(internalContext, update);
52
+ const stopPublic = internalContext === runtimeContext ? void 0 : (0, router_state_namespaceObject.subscribeRouterRuntimeState)(runtimeContext, update);
141
53
  return ()=>{
142
- for (const unsubscribe of unsubscribers)unsubscribe();
54
+ stopInternal();
55
+ stopPublic?.();
143
56
  };
144
57
  }, [
145
- contextRouter,
146
- framework,
147
- inReactRouter,
148
- internalContext
149
- ]);
150
- const getSnapshot = (0, external_react_namespaceObject.useCallback)(()=>getRouterSnapshot(internalContext, contextRouter), [
151
- contextRouter,
152
- internalContext
153
- ]);
154
- (0, external_react_namespaceObject.useSyncExternalStore)(subscribeToRouter, getSnapshot, getSnapshot);
155
- const navigate = (0, external_react_namespaceObject.useCallback)((href, options)=>{
156
- const router = getRouterInstance(internalContext, contextRouter);
157
- const activeFramework = getRouterFramework(runtimeContext, internalContext, inReactRouter);
158
- if ('tanstack' === activeFramework) {
159
- if ('function' == typeof router?.navigate) return router.navigate({
160
- to: href,
161
- replace: options?.replace,
162
- ...options?.state === void 0 ? {} : {
163
- state: options.state
164
- }
165
- });
166
- throw new Error('TanStack router instance is not available.');
167
- }
168
- if (reactRouterNavigate) return reactRouterNavigate(href, options);
169
- if ('react-router' === activeFramework) {
170
- if ('function' == typeof router?.navigate) return router.navigate(href, options);
171
- throw new Error('React Router instance is not available.');
172
- }
173
- }, [
174
- contextRouter,
175
58
  internalContext,
176
- inReactRouter,
177
- reactRouterNavigate,
178
59
  runtimeContext
179
60
  ]);
180
- const location = (reactRouterLocation ? normalizeLocation(reactRouterLocation) : getRouterStateLocation(internalContext, contextRouter)) || getWindowLocation();
181
- const params = inReactRouter ? reactRouterParams : getRouterParams(internalContext, contextRouter);
182
- const Link = 'tanstack' === framework ? internalContext.router?.Link || runtimeContext.router?.Link || null : 'react-router' === framework || inReactRouter ? routerApi?.Link ?? null : null;
183
- return {
184
- framework,
185
- hasRouter,
186
- location,
187
- navigate: hasRouter ? navigate : null,
188
- Link,
189
- params,
190
- ...'tanstack' === framework ? {
191
- createLinkProps: createTanstackLinkProps
192
- } : {}
193
- };
194
- };
195
- const createTanstackLinkProps = (target)=>{
196
- const preload = void 0 !== target.preload ? target.preload : 'none' === target.prefetch ? false : target.prefetch;
61
+ const capability = (0, external_react_namespaceObject.useSyncExternalStore)(subscribeCapability, getCapability, getCapability);
62
+ const snapshot = (0, external_react_namespaceObject.useSyncExternalStore)(capability?.subscribe ?? subscribeNone, capability?.getSnapshot ?? getEmptySnapshot, capability?.getSnapshot ?? getEmptySnapshot);
63
+ if (native.hasRouter || !capability || !snapshot) return native;
64
+ const internalState = (0, router_state_namespaceObject.getRouterRuntimeState)(internalContext);
197
65
  return {
198
- to: target.pathname,
199
- ...target.search ? {
200
- search: target.search
201
- } : {},
202
- ...target.hash ? {
203
- hash: target.hash
204
- } : {},
205
- ...void 0 === target.hashScrollIntoView ? {} : {
206
- hashScrollIntoView: target.hashScrollIntoView
207
- },
208
- ...void 0 === preload ? {} : {
209
- preload
210
- }
66
+ framework: internalState?.navigation === capability ? internalState.framework : (0, router_state_namespaceObject.getRouterRuntimeState)(runtimeContext)?.framework,
67
+ hasRouter: true,
68
+ ...snapshot,
69
+ navigate: capability.navigate,
70
+ Link: capability.Link,
71
+ createLinkProps: capability.createLinkProps
211
72
  };
212
73
  };
213
74
  const I18nRouterNavigationProvider = ({ children })=>{
214
75
  const value = useIntegratedRouterAdapter();
215
76
  const native = useNativeI18nRouterAdapter();
216
- if (!value.hasRouter || native.hasRouter) return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(jsx_runtime_namespaceObject.Fragment, {
217
- children: children
218
- });
219
- return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(I18nNavigationProvider, {
220
- value: value,
77
+ return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(NavigationProvider, {
78
+ value: value.hasRouter && !native.hasRouter ? value : null,
221
79
  children: children
222
80
  });
223
81
  };
@@ -1,4 +1,4 @@
1
+ export * from "@modern-js/runtime-extensions/localised-urls";
1
2
  export * from "./language-sync/controller.mjs";
2
3
  export * from "./language-sync/react.mjs";
3
4
  export * from "./localeRedirectPolicy.mjs";
4
- export * from "./localisedUrls/index.mjs";
@@ -1,4 +1,4 @@
1
- import { isDefaultLocaleRedirectSkipPath, localiseTargetPathname, matchesPathPrefix, shouldSkipLocaleRedirect, stripLanguagePrefix } from "./localisedUrls/index.mjs";
1
+ import { isDefaultLocaleRedirectSkipPath, localiseTargetPathname, matchesPathPrefix, shouldSkipLocaleRedirect, stripLanguagePrefix } from "@modern-js/runtime-extensions/localised-urls";
2
2
  const stripUrlPathPrefix = (pathname, urlPath)=>{
3
3
  const basePath = urlPath.replace('/*', '');
4
4
  if (!basePath || '/' === basePath) return pathname;
@@ -1,5 +1,5 @@
1
+ import { canonicalTargetPathname, localiseTargetPathname } from "@modern-js/runtime-extensions/localised-urls";
1
2
  import { splitUrlTarget } from "@modern-js/runtime-utils/url";
2
- import { canonicalTargetPathname, localiseTargetPathname } from "./localisedUrls/index.mjs";
3
3
  const buildLocalizedUrl = (target, language, languages, localisedUrls)=>{
4
4
  const { pathname, search, hash } = splitUrlTarget(target);
5
5
  return `${localiseTargetPathname(pathname, language, languages, localisedUrls)}${search}${hash}`;
@@ -1,191 +1,49 @@
1
- import { Fragment, jsx } from "react/jsx-runtime";
2
- import { RuntimeContext, isBrowser } from "@modern-js/runtime";
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { RuntimeContext } from "@modern-js/runtime";
3
3
  import { InternalRuntimeContext } from "@modern-js/runtime/context";
4
4
  import { getRouterRuntimeState, subscribeRouterRuntimeState } from "@modern-js/runtime-extensions/router-state";
5
5
  import { useCallback, useContext, useSyncExternalStore } from "react";
6
- const normalizeUrlPart = (value, prefix)=>{
7
- if ('string' != typeof value || !value) return '';
8
- return value.startsWith(prefix) ? value : `${prefix}${value}`;
9
- };
10
- const normalizeLocation = (location)=>{
11
- if (!location || 'object' != typeof location) return null;
12
- const locationValue = location;
13
- if ('string' != typeof locationValue.pathname) return null;
14
- return {
15
- pathname: locationValue.pathname,
16
- search: normalizeUrlPart('string' == typeof locationValue.search ? locationValue.search : locationValue.searchStr, '?'),
17
- hash: normalizeUrlPart(locationValue.hash, '#')
18
- };
19
- };
20
- const getWindowLocation = ()=>{
21
- if (!isBrowser()) return null;
22
- return {
23
- pathname: window.location.pathname,
24
- search: window.location.search,
25
- hash: window.location.hash
26
- };
27
- };
28
- const getRouterFramework = (runtimeContext, internalContext, inReactRouter)=>{
29
- const framework = getRouterRuntimeState(internalContext)?.framework || getRouterRuntimeState(runtimeContext)?.framework;
30
- if (framework) return framework;
31
- if (internalContext.router?.useRouter || runtimeContext.router?.useRouter) return 'tanstack';
32
- if (internalContext.router?.useLocation || internalContext.router?.useHref || runtimeContext.router?.useLocation || runtimeContext.router?.useHref) return 'react-router';
33
- if (inReactRouter) return 'react-router';
34
- };
35
- const getRouterInstance = (internalContext, contextRouter)=>{
36
- if (contextRouter) return contextRouter;
37
- const router = getRouterRuntimeState(internalContext)?.instance;
38
- if (!router || 'object' != typeof router) return null;
39
- return router;
40
- };
41
- const getRouterStateLocation = (internalContext, contextRouter)=>{
42
- const router = getRouterInstance(internalContext, contextRouter);
43
- return normalizeLocation(router?.stores?.location?.get?.()) || normalizeLocation(router?.state?.location);
44
- };
45
- const getRouterParams = (internalContext, contextRouter)=>{
46
- const router = getRouterInstance(internalContext, contextRouter);
47
- const matches = router?.stores?.matches?.get?.() || router?.state?.matches;
48
- if (!Array.isArray(matches)) return {};
49
- return matches.reduce((params, match)=>{
50
- if (match?.params) Object.assign(params, match.params);
51
- return params;
52
- }, {});
53
- };
54
- const getRouterSnapshot = (internalContext, contextRouter)=>{
55
- const location = getRouterStateLocation(internalContext, contextRouter);
56
- const params = getRouterParams(internalContext, contextRouter);
57
- return JSON.stringify([
58
- location?.pathname ?? '',
59
- location?.search ?? '',
60
- location?.hash ?? '',
61
- Object.entries(params).sort(([left], [right])=>left.localeCompare(right))
62
- ]);
63
- };
6
+ const subscribeNone = ()=>()=>{};
7
+ const getEmptySnapshot = ()=>null;
64
8
  const createI18nRouterNavigation = ({ I18nNavigationProvider, useNativeI18nRouterAdapter })=>{
9
+ const NavigationProvider = I18nNavigationProvider;
65
10
  const useIntegratedRouterAdapter = ()=>{
66
11
  const runtimeContext = useContext(RuntimeContext);
67
12
  const internalContext = useContext(InternalRuntimeContext);
68
- const routerApi = internalContext.router || runtimeContext.router;
69
13
  const native = useNativeI18nRouterAdapter();
70
- const inReactRouter = native.hasRouter;
71
- const reactRouterNavigate = native.navigate;
72
- const reactRouterLocation = inReactRouter ? native.location : null;
73
- const reactRouterParams = native.params;
74
- const framework = getRouterFramework(runtimeContext, internalContext, inReactRouter);
75
- const contextUseRouter = inReactRouter || 'tanstack' !== framework ? void 0 : internalContext.router?.useRouter || runtimeContext.router?.useRouter;
76
- const contextRouter = contextUseRouter ? contextUseRouter({
77
- warn: false
78
- }) : null;
79
- const slotRouter = getRouterInstance(internalContext, contextRouter);
80
- const drivableSlotRouter = ('tanstack' === framework || 'react-router' === framework) && 'function' == typeof slotRouter?.navigate;
81
- const hasRouter = Boolean(reactRouterNavigate) || drivableSlotRouter;
82
- const subscribeToRouter = useCallback((update)=>{
83
- const unsubscribers = [];
84
- const unsubscribeFromSlot = subscribeRouterRuntimeState(internalContext, update);
85
- if ('function' == typeof unsubscribeFromSlot) unsubscribers.push(unsubscribeFromSlot);
86
- const router = getRouterInstance(internalContext, contextRouter);
87
- if (!router) return ()=>{
88
- for (const unsubscribe of unsubscribers)unsubscribe();
89
- };
90
- if ('react-router' === framework && !inReactRouter && 'function' == typeof router.subscribe) {
91
- const subscribe = router.subscribe;
92
- const unsubscribe = subscribe.call(router, update);
93
- if ('function' == typeof unsubscribe) unsubscribers.push(unsubscribe);
94
- }
95
- if ('tanstack' === framework && 'function' == typeof router.stores?.location?.subscribe) {
96
- const unsubscribe = router.stores.location.subscribe(update);
97
- if ('function' == typeof unsubscribe) unsubscribers.push(unsubscribe);
98
- }
99
- if ('tanstack' === framework && 'function' == typeof router.subscribe) {
100
- const subscribe = router.subscribe;
101
- for (const eventType of [
102
- 'onBeforeNavigate',
103
- 'onBeforeLoad'
104
- ]){
105
- const unsubscribe = subscribe.call(router, eventType, update);
106
- if ('function' == typeof unsubscribe) unsubscribers.push(unsubscribe);
107
- }
108
- }
14
+ const getCapability = useCallback(()=>getRouterRuntimeState(internalContext)?.navigation ?? getRouterRuntimeState(runtimeContext)?.navigation, [
15
+ internalContext,
16
+ runtimeContext
17
+ ]);
18
+ const subscribeCapability = useCallback((update)=>{
19
+ const stopInternal = subscribeRouterRuntimeState(internalContext, update);
20
+ const stopPublic = internalContext === runtimeContext ? void 0 : subscribeRouterRuntimeState(runtimeContext, update);
109
21
  return ()=>{
110
- for (const unsubscribe of unsubscribers)unsubscribe();
22
+ stopInternal();
23
+ stopPublic?.();
111
24
  };
112
25
  }, [
113
- contextRouter,
114
- framework,
115
- inReactRouter,
116
- internalContext
117
- ]);
118
- const getSnapshot = useCallback(()=>getRouterSnapshot(internalContext, contextRouter), [
119
- contextRouter,
120
- internalContext
121
- ]);
122
- useSyncExternalStore(subscribeToRouter, getSnapshot, getSnapshot);
123
- const navigate = useCallback((href, options)=>{
124
- const router = getRouterInstance(internalContext, contextRouter);
125
- const activeFramework = getRouterFramework(runtimeContext, internalContext, inReactRouter);
126
- if ('tanstack' === activeFramework) {
127
- if ('function' == typeof router?.navigate) return router.navigate({
128
- to: href,
129
- replace: options?.replace,
130
- ...options?.state === void 0 ? {} : {
131
- state: options.state
132
- }
133
- });
134
- throw new Error('TanStack router instance is not available.');
135
- }
136
- if (reactRouterNavigate) return reactRouterNavigate(href, options);
137
- if ('react-router' === activeFramework) {
138
- if ('function' == typeof router?.navigate) return router.navigate(href, options);
139
- throw new Error('React Router instance is not available.');
140
- }
141
- }, [
142
- contextRouter,
143
26
  internalContext,
144
- inReactRouter,
145
- reactRouterNavigate,
146
27
  runtimeContext
147
28
  ]);
148
- const location = (reactRouterLocation ? normalizeLocation(reactRouterLocation) : getRouterStateLocation(internalContext, contextRouter)) || getWindowLocation();
149
- const params = inReactRouter ? reactRouterParams : getRouterParams(internalContext, contextRouter);
150
- const Link = 'tanstack' === framework ? internalContext.router?.Link || runtimeContext.router?.Link || null : 'react-router' === framework || inReactRouter ? routerApi?.Link ?? null : null;
151
- return {
152
- framework,
153
- hasRouter,
154
- location,
155
- navigate: hasRouter ? navigate : null,
156
- Link,
157
- params,
158
- ...'tanstack' === framework ? {
159
- createLinkProps: createTanstackLinkProps
160
- } : {}
161
- };
162
- };
163
- const createTanstackLinkProps = (target)=>{
164
- const preload = void 0 !== target.preload ? target.preload : 'none' === target.prefetch ? false : target.prefetch;
29
+ const capability = useSyncExternalStore(subscribeCapability, getCapability, getCapability);
30
+ const snapshot = useSyncExternalStore(capability?.subscribe ?? subscribeNone, capability?.getSnapshot ?? getEmptySnapshot, capability?.getSnapshot ?? getEmptySnapshot);
31
+ if (native.hasRouter || !capability || !snapshot) return native;
32
+ const internalState = getRouterRuntimeState(internalContext);
165
33
  return {
166
- to: target.pathname,
167
- ...target.search ? {
168
- search: target.search
169
- } : {},
170
- ...target.hash ? {
171
- hash: target.hash
172
- } : {},
173
- ...void 0 === target.hashScrollIntoView ? {} : {
174
- hashScrollIntoView: target.hashScrollIntoView
175
- },
176
- ...void 0 === preload ? {} : {
177
- preload
178
- }
34
+ framework: internalState?.navigation === capability ? internalState.framework : getRouterRuntimeState(runtimeContext)?.framework,
35
+ hasRouter: true,
36
+ ...snapshot,
37
+ navigate: capability.navigate,
38
+ Link: capability.Link,
39
+ createLinkProps: capability.createLinkProps
179
40
  };
180
41
  };
181
42
  const I18nRouterNavigationProvider = ({ children })=>{
182
43
  const value = useIntegratedRouterAdapter();
183
44
  const native = useNativeI18nRouterAdapter();
184
- if (!value.hasRouter || native.hasRouter) return /*#__PURE__*/ jsx(Fragment, {
185
- children: children
186
- });
187
- return /*#__PURE__*/ jsx(I18nNavigationProvider, {
188
- value: value,
45
+ return /*#__PURE__*/ jsx(NavigationProvider, {
46
+ value: value.hasRouter && !native.hasRouter ? value : null,
189
47
  children: children
190
48
  });
191
49
  };
@@ -1,5 +1,5 @@
1
1
  import "node:module";
2
+ export * from "@modern-js/runtime-extensions/localised-urls";
2
3
  export * from "./language-sync/controller.mjs";
3
4
  export * from "./language-sync/react.mjs";
4
5
  export * from "./localeRedirectPolicy.mjs";
5
- export * from "./localisedUrls/index.mjs";
@@ -1,5 +1,5 @@
1
1
  import "node:module";
2
- import { isDefaultLocaleRedirectSkipPath, localiseTargetPathname, matchesPathPrefix, shouldSkipLocaleRedirect, stripLanguagePrefix } from "./localisedUrls/index.mjs";
2
+ import { isDefaultLocaleRedirectSkipPath, localiseTargetPathname, matchesPathPrefix, shouldSkipLocaleRedirect, stripLanguagePrefix } from "@modern-js/runtime-extensions/localised-urls";
3
3
  const stripUrlPathPrefix = (pathname, urlPath)=>{
4
4
  const basePath = urlPath.replace('/*', '');
5
5
  if (!basePath || '/' === basePath) return pathname;
@@ -1,6 +1,6 @@
1
1
  import "node:module";
2
+ import { canonicalTargetPathname, localiseTargetPathname } from "@modern-js/runtime-extensions/localised-urls";
2
3
  import { splitUrlTarget } from "@modern-js/runtime-utils/url";
3
- import { canonicalTargetPathname, localiseTargetPathname } from "./localisedUrls/index.mjs";
4
4
  const buildLocalizedUrl = (target, language, languages, localisedUrls)=>{
5
5
  const { pathname, search, hash } = splitUrlTarget(target);
6
6
  return `${localiseTargetPathname(pathname, language, languages, localisedUrls)}${search}${hash}`;