@bleedingdev/modern-js-renderer-solid 3.9.3-ultramodern.7 → 3.9.3-ultramodern.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/actions.js +3 -4
- package/dist/esm/application-router.js +7 -2
- package/dist/esm/entry-client.js +1 -0
- package/dist/esm/federation-ssr.js +17 -9
- package/dist/esm/federation.js +8 -4
- package/dist/esm/i18n/LocalizedLink.js +28 -50
- package/dist/esm/i18n/index.js +1 -1
- package/dist/esm/index.js +5 -5
- package/dist/esm/manifest.js +1 -1
- package/dist/esm/route-completion.js +2 -1
- package/dist/esm/router-binding/Asset.js +3 -2
- package/dist/esm/router-binding/Matches.js +19 -12
- package/dist/esm/router-binding/PROVENANCE.json +3 -3
- package/dist/esm/router-binding/RouterProvider.js +2 -1
- package/dist/esm/router-binding/Transitioner.js +10 -4
- package/dist/esm/router-binding/fileRoute.js +1 -1
- package/dist/esm/router-binding/headContentUtils.js +9 -3
- package/dist/esm/router-binding/index.js +1 -1
- package/dist/esm/router-binding/link.js +3 -5
- package/dist/esm/router-binding/registryTransfer.js +16 -3
- package/dist/esm/router-binding/router.js +2 -1
- package/dist/esm/router-binding/routerOptions.js +0 -0
- package/dist/esm/router-binding/useLoaderData.js +1 -2
- package/dist/esm/router-binding/useNavigate.js +8 -2
- package/dist/esm/router-binding/useParams.js +1 -3
- package/dist/esm/router-binding/useSearch.js +1 -3
- package/dist/esm-node/actions.js +2 -2
- package/dist/esm-node/application-router.js +7 -2
- package/dist/esm-node/entry-client.js +1 -0
- package/dist/esm-node/federation-ssr.js +17 -9
- package/dist/esm-node/federation.js +8 -4
- package/dist/esm-node/i18n/LocalizedLink.js +43 -97
- package/dist/esm-node/i18n/index.js +1 -1
- package/dist/esm-node/index.js +5 -5
- package/dist/esm-node/manifest.js +1 -1
- package/dist/esm-node/plugin/index.js +1 -4
- package/dist/esm-node/plugin/profile.js +10 -11
- package/dist/esm-node/route-completion.js +2 -1
- package/dist/esm-node/router-binding/Asset.js +3 -2
- package/dist/esm-node/router-binding/CatchBoundary.js +3 -3
- package/dist/esm-node/router-binding/Matches.js +30 -30
- package/dist/esm-node/router-binding/PROVENANCE.json +3 -3
- package/dist/esm-node/router-binding/RouterProvider.js +2 -1
- package/dist/esm-node/router-binding/Transitioner.js +10 -4
- package/dist/esm-node/router-binding/fileRoute.js +1 -1
- package/dist/esm-node/router-binding/headContentUtils.js +9 -3
- package/dist/esm-node/router-binding/index.js +1 -1
- package/dist/esm-node/router-binding/link.js +2 -2
- package/dist/esm-node/router-binding/registryTransfer.js +16 -3
- package/dist/esm-node/router-binding/router.js +2 -1
- package/dist/esm-node/router-binding/routerOptions.js +1 -0
- package/dist/esm-node/router-binding/useLoaderData.js +1 -2
- package/dist/esm-node/router-binding/useNavigate.js +8 -2
- package/dist/esm-node/router-binding/useParams.js +1 -3
- package/dist/esm-node/router-binding/useSearch.js +1 -3
- package/dist/types/federation-ssr.d.ts +3 -5
- package/dist/types/i18n/LocalizedLink.d.ts +5 -33
- package/dist/types/i18n/index.d.ts +1 -1
- package/dist/types/index.d.ts +5 -5
- package/dist/types/manifest.d.ts +1 -1
- package/dist/types/router-binding/RouterProvider.d.ts +2 -1
- package/dist/types/router-binding/index.d.ts +3 -2
- package/dist/types/router-binding/registryTransfer.d.ts +2 -0
- package/dist/types/router-binding/routerOptions.d.ts +6 -0
- package/dist/types/router.d.ts +3 -3
- package/package.json +29 -22
- package/src/actions.tsx +5 -1
- package/src/application-router.tsx +9 -3
- package/src/entry-client.tsx +1 -0
- package/src/federation-ssr.ts +32 -13
- package/src/federation.tsx +9 -5
- package/src/i18n/LocalizedLink.tsx +44 -83
- package/src/i18n/index.ts +1 -5
- package/src/index.ts +5 -5
- package/src/manifest.ts +1 -1
- package/src/plugin/index.ts +0 -3
- package/src/plugin/preserve-import-loader.cjs +1 -1
- package/src/plugin/profile.ts +10 -10
- package/src/route-completion.tsx +5 -1
- package/src/router-binding/Asset.tsx +10 -9
- package/src/router-binding/Matches.tsx +10 -10
- package/src/router-binding/PROVENANCE.json +3 -3
- package/src/router-binding/RouterProvider.tsx +4 -5
- package/src/router-binding/Transitioner.tsx +6 -1
- package/src/router-binding/fileRoute.ts +1 -1
- package/src/router-binding/headContentUtils.tsx +5 -3
- package/src/router-binding/index.tsx +1 -4
- package/src/router-binding/link.tsx +2 -2
- package/src/router-binding/registryTransfer.ts +23 -6
- package/src/router-binding/route.tsx +1 -1
- package/src/router-binding/router.ts +2 -0
- package/src/router-binding/routerOptions.ts +26 -0
- package/src/router-binding/useLoaderData.tsx +4 -3
- package/src/router-binding/useNavigate.tsx +5 -3
- package/src/router-binding/useParams.tsx +1 -3
- package/src/router-binding/useSearch.tsx +1 -3
- package/src/router.ts +3 -3
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
canonicalPath,
|
|
3
2
|
configuredLanguage,
|
|
4
3
|
localizePath,
|
|
5
4
|
} from '@modern-js/i18n-runtime-extensions/paths';
|
|
6
5
|
import type { JSX } from '@solidjs/web';
|
|
7
6
|
import * as Solid from 'solid-js';
|
|
8
7
|
import {
|
|
8
|
+
type AnyRouter,
|
|
9
9
|
Link,
|
|
10
10
|
type LinkComponentProps,
|
|
11
11
|
useLocation,
|
|
@@ -13,110 +13,71 @@ import {
|
|
|
13
13
|
} from '../router';
|
|
14
14
|
import { I18nContext } from './context';
|
|
15
15
|
|
|
16
|
-
export interface LocalizedLinkProps
|
|
16
|
+
export interface LocalizedLinkProps
|
|
17
|
+
extends Omit<
|
|
18
|
+
LinkComponentProps<'a', AnyRouter, string, string>,
|
|
19
|
+
'to' | 'mask' | 'href' | 'publicHref' | '_fromLocation'
|
|
20
|
+
> {
|
|
17
21
|
/** A canonical, language-agnostic target, e.g. `/products/red-shoe`. */
|
|
18
22
|
to: string;
|
|
19
23
|
/** Localize for a specific language instead of the current one. */
|
|
20
24
|
language?: string;
|
|
21
|
-
children?: LinkComponentProps<'a'>['children'];
|
|
22
|
-
class?: string;
|
|
23
|
-
activeProps?: LinkComponentProps<'a'>['activeProps'];
|
|
24
|
-
inactiveProps?: LinkComponentProps<'a'>['inactiveProps'];
|
|
25
|
-
activeOptions?: LinkComponentProps<'a'>['activeOptions'];
|
|
26
|
-
replace?: boolean;
|
|
27
|
-
preload?: LinkComponentProps<'a'>['preload'];
|
|
28
25
|
[key: `data-${string}`]: unknown;
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* `Link`. It resolves the href itself via the shared pathname helpers, so it
|
|
36
|
-
* works with or without the router's i18n `rewrite`. Every link, including
|
|
37
|
-
* one to another language, is the native `Link`: navigation, preloading and
|
|
38
|
-
* active state stay with the router.
|
|
39
|
-
*
|
|
40
|
-
* Under the i18n `rewrite` the router matches canonical paths and localizes
|
|
41
|
-
* outgoing locations to the current language, so a link to another language
|
|
42
|
-
* routes to the canonical `to` and publishes the target language's URL as a
|
|
43
|
-
* route mask (the rewrite keeps a mask's explicit language). The entry's
|
|
44
|
-
* router language synchronization (`syncWithRouter`) switches the i18next
|
|
45
|
-
* instance from the navigated URL, as it does for history navigation.
|
|
46
|
-
*
|
|
47
|
-
* Props are forwarded explicitly (not via object-rest or a missing
|
|
48
|
-
* `splitProps`/`mergeProps` primitive — Solid 2 only exports `merge`) so
|
|
49
|
-
* each one is read directly from `props` in JSX position and keeps its
|
|
50
|
-
* per-key reactivity.
|
|
29
|
+
* The native router owns navigation, preloading and active state. A route mask
|
|
30
|
+
* publishes the selected language URL while keeping the canonical route;
|
|
31
|
+
* the entry's router subscription synchronizes the i18next instance.
|
|
51
32
|
*/
|
|
52
33
|
export function LocalizedLink(props: LocalizedLinkProps): JSX.Element {
|
|
53
34
|
const context = Solid.useContext(I18nContext);
|
|
54
35
|
const router = useRouter();
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
// An explicit language must be configured: it becomes the locale prefix.
|
|
36
|
+
const location = useLocation();
|
|
37
|
+
const options = Solid.omit(props, 'to', 'language', 'children');
|
|
58
38
|
const targetLanguage = () =>
|
|
59
39
|
props.language === undefined
|
|
60
40
|
? context.language()
|
|
61
41
|
: configuredLanguage(props.language, context.languages);
|
|
62
|
-
const
|
|
63
|
-
|
|
42
|
+
const externalTarget = () =>
|
|
43
|
+
props.to.startsWith('//') || URL.canParse(props.to);
|
|
44
|
+
const canonicalTarget = () => ({
|
|
45
|
+
to: props.to,
|
|
46
|
+
from: props.from,
|
|
47
|
+
params: props.params,
|
|
48
|
+
unsafeRelative: props.unsafeRelative,
|
|
49
|
+
});
|
|
50
|
+
const pathname = Solid.createMemo(() => {
|
|
51
|
+
if (externalTarget()) return props.to;
|
|
52
|
+
const target = router.buildLocation({
|
|
53
|
+
...canonicalTarget(),
|
|
54
|
+
_fromLocation: location(),
|
|
55
|
+
});
|
|
56
|
+
return localizePath(target.pathname, targetLanguage(), {
|
|
64
57
|
languages: [...context.languages],
|
|
65
58
|
localisedUrls: context.localisedUrls,
|
|
66
|
-
})
|
|
67
|
-
);
|
|
68
|
-
const crossLanguage = () => targetLanguage() !== context.language();
|
|
69
|
-
const masked = () => rewrite && crossLanguage();
|
|
70
|
-
// Declared `data-*` attributes reach the anchor through getters, so each
|
|
71
|
-
// keeps its own reactivity like the explicitly forwarded props.
|
|
72
|
-
const dataAttributes = Object.defineProperties(
|
|
73
|
-
{},
|
|
74
|
-
Object.fromEntries(
|
|
75
|
-
Object.keys(props)
|
|
76
|
-
.filter(key => key.startsWith('data-'))
|
|
77
|
-
.map(key => [
|
|
78
|
-
key,
|
|
79
|
-
{
|
|
80
|
-
enumerable: true,
|
|
81
|
-
get: () => props[key as `data-${string}`],
|
|
82
|
-
},
|
|
83
|
-
]),
|
|
84
|
-
),
|
|
85
|
-
);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
86
61
|
|
|
87
62
|
return (
|
|
88
|
-
<Link
|
|
89
|
-
{...
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
63
|
+
<Link<AnyRouter, string, string, string, string>
|
|
64
|
+
{...options}
|
|
65
|
+
to={router.options.rewrite ? props.to : pathname()}
|
|
66
|
+
mask={
|
|
67
|
+
router.options.rewrite && !externalTarget()
|
|
68
|
+
? {
|
|
69
|
+
to: pathname(),
|
|
70
|
+
inheritSearch: true,
|
|
71
|
+
hash: props.hash,
|
|
72
|
+
state: props.state,
|
|
73
|
+
}
|
|
74
|
+
: undefined
|
|
75
|
+
}
|
|
76
|
+
hreflang={
|
|
77
|
+
targetLanguage() === context.language() ? undefined : targetLanguage()
|
|
78
|
+
}
|
|
104
79
|
>
|
|
105
80
|
{props.children}
|
|
106
81
|
</Link>
|
|
107
82
|
);
|
|
108
83
|
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Language-invariant active check: `to="/products"` is active whether the
|
|
112
|
-
* current location is `/en/products` or `/produkty` under a mapped locale.
|
|
113
|
-
*/
|
|
114
|
-
export function useIsLocalizedActive(canonicalTarget: string): () => boolean {
|
|
115
|
-
const context = Solid.useContext(I18nContext);
|
|
116
|
-
const location = useLocation();
|
|
117
|
-
return () =>
|
|
118
|
-
canonicalPath(location().pathname, {
|
|
119
|
-
languages: [...context.languages],
|
|
120
|
-
localisedUrls: context.localisedUrls,
|
|
121
|
-
}) === canonicalTarget;
|
|
122
|
-
}
|
package/src/i18n/index.ts
CHANGED
|
@@ -22,11 +22,7 @@ export {
|
|
|
22
22
|
} from '@modern-js/i18n-runtime-extensions/urlRewrite';
|
|
23
23
|
export { I18nContext } from './context';
|
|
24
24
|
export { I18nProvider, type I18nProviderProps } from './I18nProvider';
|
|
25
|
-
export {
|
|
26
|
-
LocalizedLink,
|
|
27
|
-
type LocalizedLinkProps,
|
|
28
|
-
useIsLocalizedActive,
|
|
29
|
-
} from './LocalizedLink';
|
|
25
|
+
export { LocalizedLink, type LocalizedLinkProps } from './LocalizedLink';
|
|
30
26
|
export {
|
|
31
27
|
createLatestLanguageSync,
|
|
32
28
|
type SolidLatestLanguageSyncOptions,
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/** This entry contains identity only. Select client, router or server explicitly. */
|
|
2
2
|
export const SOLID_RENDERER_PROFILE = {
|
|
3
3
|
renderer: 'solid',
|
|
4
|
-
solid: '2.0.0-rc.
|
|
5
|
-
web: '2.0.0-rc.
|
|
4
|
+
solid: '2.0.0-rc.15',
|
|
5
|
+
web: '2.0.0-rc.15',
|
|
6
6
|
router: '@modern-js/renderer-solid/router@3.8.3',
|
|
7
7
|
routerSource: '4fbd65c5c3b40be87a6248867c22021c1c19bba8',
|
|
8
|
-
routerCore: '1.171.
|
|
9
|
-
history: '1.162.
|
|
8
|
+
routerCore: '1.171.38',
|
|
9
|
+
history: '1.162.5',
|
|
10
10
|
publicRouteData: {
|
|
11
11
|
containers: ['plain-record', 'null-record', 'array'],
|
|
12
12
|
values: 'canonical-scalars',
|
|
@@ -19,7 +19,7 @@ export const SOLID_RENDERER_PROFILE = {
|
|
|
19
19
|
providerOverrides: 'unsupported',
|
|
20
20
|
},
|
|
21
21
|
nativePromiseMetadata: {
|
|
22
|
-
runtime: '2.0.0-rc.
|
|
22
|
+
runtime: '2.0.0-rc.15',
|
|
23
23
|
fields: ['s', 'v'],
|
|
24
24
|
status: [0, 1, 2],
|
|
25
25
|
handle: 'sealed-with-checked-metadata',
|
package/src/manifest.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
readRendererIdentity,
|
|
6
6
|
} from '@modern-js/renderer-core/identity';
|
|
7
7
|
|
|
8
|
-
export const SOLID_COMPILER_VERSION = '2.0.0-rc.
|
|
8
|
+
export const SOLID_COMPILER_VERSION = '2.0.0-rc.15';
|
|
9
9
|
export function solidModuleManifestFilename(entryName: string): string {
|
|
10
10
|
return nativeModuleManifestFilename('solid', entryName);
|
|
11
11
|
}
|
package/src/plugin/index.ts
CHANGED
|
@@ -32,8 +32,6 @@ export const rendererAdapter: NativeRendererAdapter<'solid'> =
|
|
|
32
32
|
'solid-js',
|
|
33
33
|
'@solidjs/web',
|
|
34
34
|
'@solidjs/signals',
|
|
35
|
-
'seroval',
|
|
36
|
-
'seroval-plugins',
|
|
37
35
|
'@modern-js/renderer-solid',
|
|
38
36
|
'@modern-js/renderer-solid/client',
|
|
39
37
|
'@modern-js/renderer-solid/router',
|
|
@@ -64,7 +62,6 @@ export const rendererAdapter: NativeRendererAdapter<'solid'> =
|
|
|
64
62
|
},
|
|
65
63
|
devDependencies: {
|
|
66
64
|
[profile.compiler.name]: profile.compiler.version,
|
|
67
|
-
'@solidjs/babel-plugin': profile.compiler.version,
|
|
68
65
|
},
|
|
69
66
|
}),
|
|
70
67
|
generateAppSources: generateSolidAppSources,
|
|
@@ -36,7 +36,7 @@ module.exports = function preserveSolidImport(source, inputMap) {
|
|
|
36
36
|
});
|
|
37
37
|
if (matched !== 1 || !result) {
|
|
38
38
|
throw new Error(
|
|
39
|
-
'Solid native browser URL import contract changed. Expected one import(entryUrl) in @solidjs/web 2.0.0-rc.
|
|
39
|
+
'Solid native browser URL import contract changed. Expected one import(entryUrl) in @solidjs/web 2.0.0-rc.15; update and revalidate the compiler integration.',
|
|
40
40
|
);
|
|
41
41
|
}
|
|
42
42
|
callback(null, result.code, result.map);
|
package/src/plugin/profile.ts
CHANGED
|
@@ -4,7 +4,7 @@ export const solidProfile: RendererBuildProfile<'solid'> = {
|
|
|
4
4
|
renderer: 'solid',
|
|
5
5
|
status: 'preview',
|
|
6
6
|
protocolVersion: 1,
|
|
7
|
-
minimumNode: '26.
|
|
7
|
+
minimumNode: '26.12.0',
|
|
8
8
|
hmr: {
|
|
9
9
|
editedBoundary: 'may-reset',
|
|
10
10
|
unaffectedComponents: 'preserved',
|
|
@@ -12,24 +12,24 @@ export const solidProfile: RendererBuildProfile<'solid'> = {
|
|
|
12
12
|
roots: 'single',
|
|
13
13
|
cleanup: 'exactly-once',
|
|
14
14
|
},
|
|
15
|
-
compiler: { name: '@solidjs/compiler', version: '2.0.0-rc.
|
|
16
|
-
hydration: { name: '@solidjs/web', version: '2.0.0-rc.
|
|
15
|
+
compiler: { name: '@solidjs/compiler', version: '2.0.0-rc.15' },
|
|
16
|
+
hydration: { name: '@solidjs/web', version: '2.0.0-rc.15' },
|
|
17
17
|
router: {
|
|
18
18
|
name: '@modern-js/renderer-solid',
|
|
19
19
|
version: '3.8.3',
|
|
20
20
|
coreName: '@tanstack/router-core',
|
|
21
|
-
coreVersion: '1.171.
|
|
21
|
+
coreVersion: '1.171.38',
|
|
22
22
|
},
|
|
23
23
|
sourceExtensions: ['.tsx', '.ts', '.jsx', '.js'],
|
|
24
24
|
jsxImportSource: '@solidjs/web',
|
|
25
25
|
dependencies: {
|
|
26
|
-
'
|
|
27
|
-
|
|
28
|
-
'
|
|
29
|
-
'@solidjs/
|
|
26
|
+
'@tanstack/router-core':
|
|
27
|
+
'https://github.com/BleedingDev/router/releases/download/ultramodern-router-core-585d3233f7f5/tanstack-router-core-1.171.38.tgz',
|
|
28
|
+
'solid-js': '2.0.0-rc.15',
|
|
29
|
+
'@solidjs/web': '2.0.0-rc.15',
|
|
30
|
+
'@solidjs/signals': '2.0.0-rc.15',
|
|
31
|
+
'@solidjs/compiler': '2.0.0-rc.15',
|
|
30
32
|
'@modern-js/renderer-solid': '3.8.3',
|
|
31
|
-
seroval: '1.6.8',
|
|
32
|
-
'seroval-plugins': '1.6.8',
|
|
33
33
|
},
|
|
34
34
|
capabilities: {
|
|
35
35
|
worker: true,
|
package/src/route-completion.tsx
CHANGED
|
@@ -10,7 +10,10 @@ import {
|
|
|
10
10
|
preparePublicContextData,
|
|
11
11
|
useMatch,
|
|
12
12
|
} from './router-binding/index';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
assertNativeSerializationOptions,
|
|
15
|
+
registerPublicRouteDataOwner,
|
|
16
|
+
} from './router-binding/registryTransfer';
|
|
14
17
|
|
|
15
18
|
interface CompletionRecord {
|
|
16
19
|
readonly failure: Accessor<{ reason: unknown } | undefined>;
|
|
@@ -52,6 +55,7 @@ export function registerRouteCompletionScope(
|
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
export const createApplicationRouter: CreateRouterFn = options => {
|
|
58
|
+
assertNativeSerializationOptions(options);
|
|
55
59
|
const scope = options.routeTree
|
|
56
60
|
? routeScopes.get(options.routeTree)
|
|
57
61
|
: undefined;
|
|
@@ -62,7 +62,7 @@ function InlineCssStyle({
|
|
|
62
62
|
attrs,
|
|
63
63
|
children,
|
|
64
64
|
}: {
|
|
65
|
-
attrs
|
|
65
|
+
attrs: Record<string, any> | undefined;
|
|
66
66
|
children?: RouterManagedTag['children'];
|
|
67
67
|
}) {
|
|
68
68
|
const isInlineCssPlaceholder = children === undefined;
|
|
@@ -85,7 +85,7 @@ function InlineCssStyle({
|
|
|
85
85
|
|
|
86
86
|
function HeadElement(props: {
|
|
87
87
|
tag: 'meta' | 'link' | 'style';
|
|
88
|
-
attrs
|
|
88
|
+
attrs: Record<string, any> | undefined;
|
|
89
89
|
children?: unknown;
|
|
90
90
|
}): JSX.Element | null {
|
|
91
91
|
// Each branch must live in its own `case` block so the Solid compiler emits
|
|
@@ -101,11 +101,12 @@ function HeadElement(props: {
|
|
|
101
101
|
let element: Element;
|
|
102
102
|
switch (props.tag) {
|
|
103
103
|
case 'style': {
|
|
104
|
-
const attrs = {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
const attrs = { ...props.attrs };
|
|
105
|
+
// The managed child text owns this field, including when it is absent.
|
|
106
|
+
delete attrs.innerHTML;
|
|
107
|
+
if (typeof props.children === 'string') {
|
|
108
|
+
attrs.innerHTML = props.children;
|
|
109
|
+
}
|
|
109
110
|
element = (<style {...attrs} />) as unknown as Element;
|
|
110
111
|
break;
|
|
111
112
|
}
|
|
@@ -125,7 +126,7 @@ function HeadElement(props: {
|
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
function Title(props: {
|
|
128
|
-
attrs
|
|
129
|
+
attrs: Record<string, any> | undefined;
|
|
129
130
|
children?: unknown;
|
|
130
131
|
}): JSX.Element | null {
|
|
131
132
|
let el: HTMLTitleElement | undefined;
|
|
@@ -158,7 +159,7 @@ function Title(props: {
|
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
function Script(props: {
|
|
161
|
-
attrs
|
|
162
|
+
attrs: Record<string, any> | undefined;
|
|
162
163
|
children?: unknown;
|
|
163
164
|
}): JSX.Element | null {
|
|
164
165
|
const router = useRouter();
|
|
@@ -79,16 +79,16 @@ function MatchesInner() {
|
|
|
79
79
|
getResetKey={() => router.stores.matches.get()}
|
|
80
80
|
render={matchContent}
|
|
81
81
|
errorComponent={ErrorComponent}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
{...(process.env.NODE_ENV !== 'production'
|
|
83
|
+
? {
|
|
84
|
+
onCatch: (error: Error) => {
|
|
85
85
|
console.warn(
|
|
86
86
|
`Warning: The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`,
|
|
87
87
|
);
|
|
88
88
|
console.warn(`Warning: ${error.message || error.toString()}`);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
: {})}
|
|
92
92
|
/>
|
|
93
93
|
</NearestMatchContext>
|
|
94
94
|
);
|
|
@@ -126,10 +126,10 @@ export function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>() {
|
|
|
126
126
|
router.stores.resolvedLocation.get();
|
|
127
127
|
router.stores.status.get();
|
|
128
128
|
return router.matchRoute(rest as any, {
|
|
129
|
-
pending,
|
|
130
|
-
caseSensitive,
|
|
131
|
-
fuzzy,
|
|
132
|
-
includeSearch,
|
|
129
|
+
...(pending !== undefined ? { pending } : {}),
|
|
130
|
+
...(caseSensitive !== undefined ? { caseSensitive } : {}),
|
|
131
|
+
...(fuzzy !== undefined ? { fuzzy } : {}),
|
|
132
|
+
...(includeSearch !== undefined ? { includeSearch } : {}),
|
|
133
133
|
});
|
|
134
134
|
});
|
|
135
135
|
};
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"sourcePath": "packages/solid-router/src",
|
|
15
15
|
"upstreamPackage": "@tanstack/solid-router",
|
|
16
16
|
"upstreamVersion": "1.170.36",
|
|
17
|
-
"routerCoreVersion": "1.171.
|
|
17
|
+
"routerCoreVersion": "1.171.37",
|
|
18
18
|
"files": ["Scripts.tsx", "link.tsx"],
|
|
19
19
|
"adaptation": "Native body-script composition and positional search equality are ported from the matching router-core release. The owned binding retains Solid 2 RC.13 JSX, NoHydration, keyed public match transfer and its module-keyed client-assets resolver."
|
|
20
20
|
}
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"utils.ts": "a398c76ac378efe6f8b9aa859a5335d4f07cc692a31754fa93c8bf3e5df0b6ff"
|
|
68
68
|
},
|
|
69
69
|
"localChanges": [
|
|
70
|
-
"The public router surface omits InjectedHtmlEntry, isPlainArray and isPlainObject, which router-core 1.171.
|
|
70
|
+
"The public router surface omits InjectedHtmlEntry, isPlainArray and isPlainObject, which router-core 1.171.37 no longer exports. Managed SSR uses immutable public route data and native Solid 2 promise serialization. Custom serializationAdapters are unsupported and rejected before router construction or document commitment; the local public option types do not admit them.",
|
|
71
71
|
"Authored JSX types import @solidjs/web and have explicit return annotations for Solid 2 declaration generation.",
|
|
72
72
|
"Hydration state and keyed match transfer use Solid 2 RC.13 public isHydrating, isHydratable, getHydrationWriter and takeHydrationValue APIs.",
|
|
73
73
|
"Explicit public beforeLoad results transfer after canonical validation; private request context stays in owner closures. Initial hydration inherits checked server beforeLoad contributions, invokes the native client route-context callback and preserves client options context without rerunning initial beforeLoad callbacks or loaders.",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
],
|
|
84
84
|
"nativeProtocolLimitations": [
|
|
85
85
|
{
|
|
86
|
-
"runtime": "@solidjs/web@2.0.0-rc.
|
|
86
|
+
"runtime": "@solidjs/web@2.0.0-rc.15 with Seroval 1.6.8",
|
|
87
87
|
"trigger": "Direct native writer injection of a rejected whole-match Promise before the client binding loads",
|
|
88
88
|
"observed": "Native inline resolver scripts reject registry Promises without a rejection handler; browser page errors occur before router construction. Binding claims cannot retroactively handle those errors.",
|
|
89
89
|
"supportedProducer": "The maintained match producer writes only settled synchronous records and excludes pending matches. Critical public-data failures are rejected before headers; unsupported deferred values fail the owning session and abort native serialization.",
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import type { JSX } from '@solidjs/web';
|
|
2
|
-
import type {
|
|
3
|
-
AnyRouter,
|
|
4
|
-
RegisteredRouter,
|
|
5
|
-
RouterOptions,
|
|
6
|
-
} from '@tanstack/router-core';
|
|
2
|
+
import type { AnyRouter, RegisteredRouter } from '@tanstack/router-core';
|
|
7
3
|
import { isServer } from '@tanstack/router-core/isServer';
|
|
8
4
|
import * as Solid from 'solid-js';
|
|
9
5
|
import { setupFlightDataConsumer } from './flightData';
|
|
10
6
|
import { Matches } from './Matches';
|
|
11
7
|
import {
|
|
8
|
+
assertNativeSerializationOptions,
|
|
12
9
|
requireManagedPublicRouter,
|
|
13
10
|
serializeMatchTransfer,
|
|
14
11
|
} from './registryTransfer';
|
|
15
12
|
import { routerContext } from './routerContext';
|
|
13
|
+
import type { RouterOptions } from './routerOptions';
|
|
16
14
|
import { SafeFragment } from './SafeFragment';
|
|
17
15
|
|
|
18
16
|
const RouterContext = routerContext as unknown as Solid.Component<{
|
|
@@ -30,6 +28,7 @@ export function RouterContextProvider<
|
|
|
30
28
|
}: RouterProps<TRouter, TDehydrated> & {
|
|
31
29
|
children: () => JSX.Element;
|
|
32
30
|
}) {
|
|
31
|
+
assertNativeSerializationOptions(rest);
|
|
33
32
|
requireManagedPublicRouter(router);
|
|
34
33
|
if (Object.keys(rest).length > 0) {
|
|
35
34
|
Solid.runWithOwner(null, () => {
|
|
@@ -162,9 +162,14 @@ export function Rendered() {
|
|
|
162
162
|
Solid.onSettled(() => {
|
|
163
163
|
const resolvedLocation = getResolvedLocation(router);
|
|
164
164
|
if (resolvedLocation) {
|
|
165
|
+
const { fromLocation, ...changeInfo } = getLocationChangeInfo(
|
|
166
|
+
resolvedLocation,
|
|
167
|
+
resolvedLocation,
|
|
168
|
+
);
|
|
165
169
|
router.emit({
|
|
166
170
|
type: 'onRendered',
|
|
167
|
-
...
|
|
171
|
+
...changeInfo,
|
|
172
|
+
...(fromLocation !== undefined ? { fromLocation } : {}),
|
|
168
173
|
});
|
|
169
174
|
}
|
|
170
175
|
});
|
|
@@ -154,7 +154,9 @@ export const useTags = (assetCrossOrigin?: AssetCrossOriginConfig) => {
|
|
|
154
154
|
...manifest.inlineStyle.attrs,
|
|
155
155
|
nonce,
|
|
156
156
|
},
|
|
157
|
-
|
|
157
|
+
...(manifest.inlineStyle.children !== undefined
|
|
158
|
+
? { children: manifest.inlineStyle.children }
|
|
159
|
+
: {}),
|
|
158
160
|
inlineCss: true,
|
|
159
161
|
});
|
|
160
162
|
}
|
|
@@ -192,7 +194,7 @@ export const useTags = (assetCrossOrigin?: AssetCrossOriginConfig) => {
|
|
|
192
194
|
...attrs,
|
|
193
195
|
nonce,
|
|
194
196
|
},
|
|
195
|
-
children: children
|
|
197
|
+
...(children != null ? { children: String(children) } : {}),
|
|
196
198
|
})) satisfies Array<RouterManagedTag>;
|
|
197
199
|
});
|
|
198
200
|
|
|
@@ -206,7 +208,7 @@ export const useTags = (assetCrossOrigin?: AssetCrossOriginConfig) => {
|
|
|
206
208
|
...attrs,
|
|
207
209
|
nonce,
|
|
208
210
|
},
|
|
209
|
-
children: children
|
|
211
|
+
...(children != null ? { children: String(children) } : {}),
|
|
210
212
|
})) satisfies Array<RouterManagedTag>;
|
|
211
213
|
});
|
|
212
214
|
|
|
@@ -26,7 +26,6 @@ export type {
|
|
|
26
26
|
AnyRouterWithContext,
|
|
27
27
|
AnyRouteWithContext,
|
|
28
28
|
AnySchema,
|
|
29
|
-
AnySerializationAdapter,
|
|
30
29
|
AnyValidator,
|
|
31
30
|
AnyValidatorAdapter,
|
|
32
31
|
AnyValidatorFn,
|
|
@@ -153,7 +152,6 @@ export type {
|
|
|
153
152
|
RouterEvents,
|
|
154
153
|
RouterListener,
|
|
155
154
|
RouterManagedTag,
|
|
156
|
-
RouterOptions,
|
|
157
155
|
RouterState,
|
|
158
156
|
RoutesById,
|
|
159
157
|
RoutesByPath,
|
|
@@ -163,7 +161,6 @@ export type {
|
|
|
163
161
|
SearchSchemaInput,
|
|
164
162
|
SearchSerializer,
|
|
165
163
|
SerializableExtensions,
|
|
166
|
-
SerializationAdapter,
|
|
167
164
|
StaticDataRouteOption,
|
|
168
165
|
StringifyParamsFn,
|
|
169
166
|
ToMaskOptions,
|
|
@@ -197,7 +194,6 @@ export {
|
|
|
197
194
|
cleanPath,
|
|
198
195
|
composeRewrites,
|
|
199
196
|
createControlledPromise,
|
|
200
|
-
createSerializationAdapter,
|
|
201
197
|
DEFAULT_PROTOCOL_ALLOWLIST,
|
|
202
198
|
deepEqual,
|
|
203
199
|
defaultParseSearch,
|
|
@@ -291,6 +287,7 @@ export {
|
|
|
291
287
|
rootRouteWithContext,
|
|
292
288
|
} from './route';
|
|
293
289
|
export { createRouter, Router } from './router';
|
|
290
|
+
export type { RouterOptions } from './routerOptions';
|
|
294
291
|
export { ScriptOnce } from './ScriptOnce';
|
|
295
292
|
export { Scripts } from './Scripts';
|
|
296
293
|
export {
|
|
@@ -505,9 +505,9 @@ export function useLinkProps<
|
|
|
505
505
|
}
|
|
506
506
|
|
|
507
507
|
const defineGetters = (getters: Record<string, () => any>) => {
|
|
508
|
-
for (const key of Object.
|
|
508
|
+
for (const [key, get] of Object.entries(getters)) {
|
|
509
509
|
Object.defineProperty(linkProps, key, {
|
|
510
|
-
get
|
|
510
|
+
get,
|
|
511
511
|
enumerable: true,
|
|
512
512
|
configurable: true,
|
|
513
513
|
});
|
|
@@ -78,8 +78,21 @@ export function registerPublicRouteDataOwner(
|
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/** Managed match transfer uses the immutable public-data contract, not custom adapters. */
|
|
82
|
+
export function assertNativeSerializationOptions(options: object): void {
|
|
83
|
+
if ('serializationAdapters' in options) {
|
|
84
|
+
const error = new DataProtocolError(
|
|
85
|
+
'Solid serializationAdapters are unsupported by the immutable public-data profile; return public records, arrays and scalars instead',
|
|
86
|
+
);
|
|
87
|
+
const owner: RequestSession | undefined = getRequestEvent()?.locals.session;
|
|
88
|
+
owner?.fail(error);
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
81
93
|
/** Framework SSR accepts only routers that passed its public-data factory boundary. */
|
|
82
94
|
export function requireManagedPublicRouter(router: AnyRouter): void {
|
|
95
|
+
assertNativeSerializationOptions(router.options);
|
|
83
96
|
const owner: RequestSession | undefined = getRequestEvent()?.locals.session;
|
|
84
97
|
if (
|
|
85
98
|
!owner ||
|
|
@@ -268,6 +281,11 @@ export function primeRouterFromRegistry(router: AnyRouter): boolean {
|
|
|
268
281
|
try {
|
|
269
282
|
for (const [index, match] of matches.entries()) {
|
|
270
283
|
const entry = entries[index]!;
|
|
284
|
+
const beforeLoadContext = preparePublicContextData(
|
|
285
|
+
entry.beforeLoadContext,
|
|
286
|
+
owner,
|
|
287
|
+
privateContexts,
|
|
288
|
+
) as Record<string, unknown> | undefined;
|
|
271
289
|
const checked: TransferredMatch = {
|
|
272
290
|
...entry,
|
|
273
291
|
loaderData: prepareHydratedLoaderData(
|
|
@@ -275,11 +293,7 @@ export function primeRouterFromRegistry(router: AnyRouter): boolean {
|
|
|
275
293
|
owner,
|
|
276
294
|
privateContexts,
|
|
277
295
|
),
|
|
278
|
-
beforeLoadContext:
|
|
279
|
-
entry.beforeLoadContext,
|
|
280
|
-
owner,
|
|
281
|
-
privateContexts,
|
|
282
|
-
) as Record<string, unknown> | undefined,
|
|
296
|
+
...(beforeLoadContext !== undefined ? { beforeLoadContext } : {}),
|
|
283
297
|
error: preparePublicContextData(entry.error, owner, privateContexts),
|
|
284
298
|
};
|
|
285
299
|
entries[index] = checked;
|
|
@@ -356,7 +370,10 @@ function applyTransferredMatch(
|
|
|
356
370
|
__beforeLoadContext: entry.beforeLoadContext,
|
|
357
371
|
} as AnyRouteMatch;
|
|
358
372
|
if ('loaderData' in entry) next.loaderData = entry.loaderData;
|
|
359
|
-
if ('ssr' in entry)
|
|
373
|
+
if ('ssr' in entry) {
|
|
374
|
+
if (entry.ssr === undefined) delete next.ssr;
|
|
375
|
+
else next.ssr = entry.ssr;
|
|
376
|
+
}
|
|
360
377
|
return next;
|
|
361
378
|
}
|
|
362
379
|
|
|
@@ -133,7 +133,7 @@ export class RouteApi<
|
|
|
133
133
|
return useNavigate({ from: router.routesById[this.id as string].fullPath });
|
|
134
134
|
};
|
|
135
135
|
|
|
136
|
-
notFound = (opts?: NotFoundError) => {
|
|
136
|
+
override notFound = (opts?: NotFoundError) => {
|
|
137
137
|
return notFound({ routeId: this.id as string, ...opts });
|
|
138
138
|
};
|
|
139
139
|
|
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
import { RouterCore } from '@tanstack/router-core';
|
|
10
10
|
import { isServer } from '@tanstack/router-core/isServer';
|
|
11
11
|
import {
|
|
12
|
+
assertNativeSerializationOptions,
|
|
12
13
|
installPublicContextPublication,
|
|
13
14
|
primeRouterFromRegistry,
|
|
14
15
|
} from './registryTransfer';
|
|
@@ -104,6 +105,7 @@ export class Router<
|
|
|
104
105
|
TDehydrated
|
|
105
106
|
>,
|
|
106
107
|
) {
|
|
108
|
+
assertNativeSerializationOptions(options);
|
|
107
109
|
super(options, getStoreFactory);
|
|
108
110
|
installPublicContextPublication(this);
|
|
109
111
|
// The hydration-claiming boot (see registryTransfer). Router creation is
|