@bleedingdev/modern-js-plugin-tanstack 3.8.3-ultramodern.6 → 3.9.0-ultramodern.10
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/cjs/cli/index.js +9 -0
- package/dist/cjs/cli/tanstackTypes/source.js +3 -1
- package/dist/cjs/runtime/basepathRewrite.js +13 -6
- package/dist/cjs/runtime/lifecycle.js +7 -7
- package/dist/cjs/runtime/plugin.js +1 -1
- package/dist/cjs/runtime/plugin.node.js +5 -1
- package/dist/cjs/runtime/prefetchLink.js +2 -7
- package/dist/cjs/runtime/register.js +0 -2
- package/dist/cjs/runtime/routeTree/construction.js +2 -0
- package/dist/cjs/runtime/router.js +25 -9
- package/dist/cjs/runtime/state.js +2 -2
- package/dist/cjs/runtime/utils.js +2 -0
- package/dist/esm/cli/index.mjs +13 -5
- package/dist/esm/cli/tanstackTypes/source.mjs +3 -1
- package/dist/esm/runtime/basepathRewrite.mjs +10 -3
- package/dist/esm/runtime/lifecycle.mjs +1 -1
- package/dist/esm/runtime/plugin.mjs +1 -1
- package/dist/esm/runtime/plugin.node.mjs +5 -1
- package/dist/esm/runtime/prefetchLink.mjs +1 -6
- package/dist/esm/runtime/register.mjs +0 -2
- package/dist/esm/runtime/routeTree/construction.mjs +2 -0
- package/dist/esm/runtime/router.mjs +27 -11
- package/dist/esm/runtime/state.mjs +1 -1
- package/dist/esm/runtime/utils.mjs +2 -0
- package/dist/esm-node/cli/index.mjs +15 -5
- package/dist/esm-node/cli/tanstackTypes/source.mjs +3 -1
- package/dist/esm-node/runtime/basepathRewrite.mjs +10 -3
- package/dist/esm-node/runtime/lifecycle.mjs +1 -1
- package/dist/esm-node/runtime/plugin.mjs +1 -1
- package/dist/esm-node/runtime/plugin.node.mjs +5 -1
- package/dist/esm-node/runtime/prefetchLink.mjs +1 -6
- package/dist/esm-node/runtime/register.mjs +0 -2
- package/dist/esm-node/runtime/routeTree/construction.mjs +2 -0
- package/dist/esm-node/runtime/router.mjs +27 -11
- package/dist/esm-node/runtime/state.mjs +1 -1
- package/dist/esm-node/runtime/utils.mjs +2 -0
- package/dist/types/cli/index.d.ts +5 -5
- package/dist/types/cli/tanstackTypes/shared.d.ts +1 -1
- package/dist/types/cli/tanstackTypes.d.ts +3 -3
- package/dist/types/cli.d.ts +2 -2
- package/dist/types/runtime/basepathRewrite.d.ts +2 -1
- package/dist/types/runtime/dataMutation.d.ts +3 -3
- package/dist/types/runtime/index.d.ts +14 -14
- package/dist/types/runtime/lifecycle.d.ts +9 -2
- package/dist/types/runtime/loaderBridge.d.ts +2 -2
- package/dist/types/runtime/plugin.d.ts +2 -2
- package/dist/types/runtime/plugin.node.d.ts +2 -2
- package/dist/types/runtime/plugin.worker.d.ts +1 -1
- package/dist/types/runtime/pluginShared.d.ts +2 -2
- package/dist/types/runtime/register.d.ts +1 -9
- package/dist/types/runtime/routeTree/construction.d.ts +1 -1
- package/dist/types/runtime/routeTree/index.d.ts +2 -2
- package/dist/types/runtime/routeTree/loaders.d.ts +1 -1
- package/dist/types/runtime/routeTree/tanstackRoutes.d.ts +1 -1
- package/dist/types/runtime/router.d.ts +2 -13
- package/dist/types/runtime/rsc/CompositeComponent.d.ts +1 -1
- package/dist/types/runtime/rsc/RscNodeRenderer.d.ts +1 -1
- package/dist/types/runtime/rsc/client.d.ts +4 -4
- package/dist/types/runtime/rsc/createRscProxy.d.ts +1 -1
- package/dist/types/runtime/rsc/payloadFetch.d.ts +1 -1
- package/dist/types/runtime/rsc/payloadRouter.d.ts +2 -2
- package/dist/types/runtime/rsc/payloadStorage.d.ts +1 -1
- package/dist/types/runtime/rsc/server.d.ts +3 -3
- package/dist/types/runtime/rsc/shared.d.ts +1 -1
- package/dist/types/runtime/rsc/slotUsageSanitizer.d.ts +1 -1
- package/dist/types/runtime/ssrManagedTags.d.ts +1 -1
- package/dist/types/runtime/ssrPreload.d.ts +1 -1
- package/dist/types/runtime/state.d.ts +1 -1
- package/dist/types/runtime/submitAction.d.ts +1 -1
- package/dist/types/runtime/types.d.ts +2 -1
- package/dist/types/runtime/utils.d.ts +1 -1
- package/dist/types/runtime.d.ts +1 -1
- package/package.json +19 -16
- package/rstest.config.mts +1 -24
- package/src/cli/index.ts +10 -0
- package/src/cli/tanstackTypes/source.ts +3 -1
- package/src/runtime/basepathRewrite.ts +11 -2
- package/src/runtime/lifecycle.ts +14 -3
- package/src/runtime/plugin.node.tsx +9 -2
- package/src/runtime/plugin.tsx +5 -1
- package/src/runtime/prefetchLink.tsx +1 -23
- package/src/runtime/register.ts +1 -12
- package/src/runtime/routeTree/construction.ts +2 -0
- package/src/runtime/router.ts +25 -40
- package/src/runtime/state.ts +1 -1
- package/src/runtime/types.ts +2 -2
- package/src/runtime/utils.tsx +3 -1
- package/tests/router/cli.test.ts +148 -824
- package/tests/router/dataMutation.test.tsx +17 -85
- package/tests/router/flightSerialization.roundtrip.test.tsx +9 -6
- package/tests/router/generateRouteArtifacts.test.ts +68 -28
- package/tests/router/loaderBridge.test.ts +0 -25
- package/tests/router/localisedIdentity.test.tsx +95 -0
- package/tests/router/prefetchLink.test.tsx +17 -21
- package/tests/router/prefetchLinkPreload.test.tsx +11 -31
- package/tests/router/routeHooks.test.ts +41 -105
- package/tests/router/routeTree.test.ts +144 -836
- package/tests/router/rsc.test.tsx +131 -166
- package/tests/router/serverPlugin.test.ts +43 -1
- package/tests/router/tanstackTypes.test.ts +109 -973
- package/tests/realm-isolation.test.ts +0 -114
- package/tests/router/fastDefaults.test.ts +0 -32
- package/tests/router/fixtures/legacyRuntimeRouter.ts +0 -10
- package/tests/router/fixtures/rscDecoderSecurityChild.cjs +0 -162
- package/tests/router/hooks.test.ts +0 -40
- package/tests/router/hydrationBoundary.test.tsx +0 -23
- package/tests/router/packageSurface.test.ts +0 -24
- package/tests/router/preloadRedirect.test.ts +0 -64
- package/tests/router/register.test.ts +0 -8
- package/tests/router/routerCompatibility.test.ts +0 -239
- package/tests/router/rscDecoderSecurity.test.ts +0 -113
- package/tests/router/rscPayloadRouterMatrix.test.ts +0 -197
- /package/dist/esm/{rslib-runtime.mjs → rslib-runtime~1.mjs} +0 -0
- /package/dist/esm-node/{rslib-runtime.mjs → rslib-runtime~0.mjs} +0 -0
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import type { RouterProviderFactory } from '@modern-js/runtime/context';
|
|
2
|
-
import { rstest } from '@rstest/core';
|
|
3
|
-
import type { RouterExtendsHooks } from '../src/runtime/hooks';
|
|
4
|
-
|
|
5
|
-
const REGISTRY_SLOT: unique symbol = Symbol.for(
|
|
6
|
-
'@modern-js/runtime:router-providers:v3',
|
|
7
|
-
);
|
|
8
|
-
const host = globalThis as { [REGISTRY_SLOT]?: unknown };
|
|
9
|
-
|
|
10
|
-
type RuntimeContextModule = typeof import('@modern-js/runtime/context');
|
|
11
|
-
type RouterModule = typeof import('../src/runtime/router');
|
|
12
|
-
|
|
13
|
-
type Vertical = {
|
|
14
|
-
context: RuntimeContextModule;
|
|
15
|
-
factory: RouterProviderFactory;
|
|
16
|
-
hooks: RouterExtendsHooks;
|
|
17
|
-
Link: unknown;
|
|
18
|
-
routerPlugin: RouterModule['routerPlugin'];
|
|
19
|
-
useMatches: unknown;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
async function loadVertical(): Promise<Vertical> {
|
|
23
|
-
rstest.resetModules();
|
|
24
|
-
const routerModule = (await import('../src/runtime/router')) as RouterModule;
|
|
25
|
-
const context = (await import(
|
|
26
|
-
'@modern-js/runtime/context'
|
|
27
|
-
)) as RuntimeContextModule;
|
|
28
|
-
const { tanstackRouterProviderFactory } = await import(
|
|
29
|
-
'../src/runtime/register'
|
|
30
|
-
);
|
|
31
|
-
const { routerProviderRegistryHooks } = await import('../src/runtime/hooks');
|
|
32
|
-
const { Link } = await import('../src/runtime/prefetchLink');
|
|
33
|
-
const { useMatches } = await import('../src/runtime/routeHooks');
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
context,
|
|
37
|
-
factory: tanstackRouterProviderFactory,
|
|
38
|
-
hooks: routerProviderRegistryHooks,
|
|
39
|
-
Link,
|
|
40
|
-
routerPlugin: routerModule.routerPlugin,
|
|
41
|
-
useMatches,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function setupRouterWrapper(vertical: Vertical) {
|
|
46
|
-
let onBeforeRender:
|
|
47
|
-
| ((context: any, interrupt: (value?: unknown) => unknown) => unknown)
|
|
48
|
-
| undefined;
|
|
49
|
-
|
|
50
|
-
const plugin = vertical.routerPlugin({ framework: 'tanstack' });
|
|
51
|
-
plugin.setup?.({
|
|
52
|
-
getHooks: () => vertical.hooks,
|
|
53
|
-
getRuntimeConfig: () => ({ router: { framework: 'tanstack' } }),
|
|
54
|
-
onBeforeRender: listener => {
|
|
55
|
-
onBeforeRender = listener;
|
|
56
|
-
},
|
|
57
|
-
wrapRoot: () => undefined,
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
expect(typeof onBeforeRender).toBe('function');
|
|
61
|
-
const runtimeContext: any = {};
|
|
62
|
-
onBeforeRender?.(runtimeContext, () => undefined);
|
|
63
|
-
return runtimeContext.router as { Link: unknown; useMatches: unknown };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
describe('TanStack provider runtime-realm isolation', () => {
|
|
67
|
-
beforeEach(() => {
|
|
68
|
-
delete host[REGISTRY_SLOT];
|
|
69
|
-
rstest.resetModules();
|
|
70
|
-
(
|
|
71
|
-
globalThis as typeof globalThis & {
|
|
72
|
-
__webpack_require__?: { u: (chunkId: unknown) => string };
|
|
73
|
-
}
|
|
74
|
-
).__webpack_require__ = { u: chunkId => String(chunkId) };
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
afterEach(() => {
|
|
78
|
-
delete host[REGISTRY_SLOT];
|
|
79
|
-
rstest.resetModules();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('binds each production router wrapper to its own real provider graph', async () => {
|
|
83
|
-
const warnSpy = rstest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
84
|
-
try {
|
|
85
|
-
const verticalA = await loadVertical();
|
|
86
|
-
const routerA = setupRouterWrapper(verticalA);
|
|
87
|
-
expect(routerA.Link).toBe(verticalA.Link);
|
|
88
|
-
expect(routerA.useMatches).toBe(verticalA.useMatches);
|
|
89
|
-
|
|
90
|
-
const verticalB = await loadVertical();
|
|
91
|
-
expect(verticalB.context).not.toBe(verticalA.context);
|
|
92
|
-
expect(verticalB.factory).not.toBe(verticalA.factory);
|
|
93
|
-
expect(verticalB.Link).not.toBe(verticalA.Link);
|
|
94
|
-
expect(verticalB.useMatches).not.toBe(verticalA.useMatches);
|
|
95
|
-
|
|
96
|
-
const routerB = setupRouterWrapper(verticalB);
|
|
97
|
-
expect(routerB.Link).toBe(verticalB.Link);
|
|
98
|
-
expect(routerB.useMatches).toBe(verticalB.useMatches);
|
|
99
|
-
expect(routerB.Link).not.toBe(verticalA.Link);
|
|
100
|
-
expect(routerB.useMatches).not.toBe(verticalA.useMatches);
|
|
101
|
-
|
|
102
|
-
// Mixed-version callers that do not supply a realm still see the shared
|
|
103
|
-
// keep-first fallback, but production wrappers no longer consume it.
|
|
104
|
-
expect(verticalB.context.resolveRouterProvider('tanstack')).toBe(
|
|
105
|
-
verticalA.factory,
|
|
106
|
-
);
|
|
107
|
-
expect(warnSpy).toHaveBeenCalledWith(
|
|
108
|
-
expect.stringMatching(/keeping the first registration/),
|
|
109
|
-
);
|
|
110
|
-
} finally {
|
|
111
|
-
warnSpy.mockRestore();
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
});
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getModernTanstackRouterFastDefaults,
|
|
3
|
-
modernTanstackRouterFastDefaults,
|
|
4
|
-
} from '../../src/runtime/types';
|
|
5
|
-
|
|
6
|
-
describe('tanstack router fast defaults', () => {
|
|
7
|
-
test('enables structural sharing by default', () => {
|
|
8
|
-
expect(modernTanstackRouterFastDefaults).toEqual({
|
|
9
|
-
defaultStructuralSharing: true,
|
|
10
|
-
});
|
|
11
|
-
expect(getModernTanstackRouterFastDefaults()).toEqual({
|
|
12
|
-
defaultStructuralSharing: true,
|
|
13
|
-
});
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
test('allows explicit structural sharing override', () => {
|
|
17
|
-
expect(
|
|
18
|
-
getModernTanstackRouterFastDefaults({
|
|
19
|
-
defaultStructuralSharing: true,
|
|
20
|
-
}),
|
|
21
|
-
).toEqual({
|
|
22
|
-
defaultStructuralSharing: true,
|
|
23
|
-
});
|
|
24
|
-
expect(
|
|
25
|
-
getModernTanstackRouterFastDefaults({
|
|
26
|
-
defaultStructuralSharing: false,
|
|
27
|
-
}),
|
|
28
|
-
).toEqual({
|
|
29
|
-
defaultStructuralSharing: false,
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
});
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
let invocationCount = 0;
|
|
2
|
-
|
|
3
|
-
export const routerPlugin = (
|
|
4
|
-
_userConfig: Record<string, unknown> = {},
|
|
5
|
-
): { name?: string; setup?: (...args: unknown[]) => unknown } => {
|
|
6
|
-
invocationCount += 1;
|
|
7
|
-
throw new Error('The legacy global router wrapper must not be invoked.');
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export const getLegacyRouterPluginInvocationCount = () => invocationCount;
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
const path = require('node:path');
|
|
2
|
-
|
|
3
|
-
const scenario = process.argv[2];
|
|
4
|
-
const serverPath = process.argv[3];
|
|
5
|
-
const clientPath = process.argv[4];
|
|
6
|
-
let moduleLoads = 0;
|
|
7
|
-
|
|
8
|
-
global.__webpack_chunk_load__ = async () => {};
|
|
9
|
-
global.__webpack_require__ = () => {
|
|
10
|
-
moduleLoads += 1;
|
|
11
|
-
return {
|
|
12
|
-
action(formData) {
|
|
13
|
-
return formData;
|
|
14
|
-
},
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
global.__rspack_rsc_hot_reloader__ = { on: () => () => {} };
|
|
18
|
-
global.__rspack_rsc_manifest__ = {
|
|
19
|
-
clientManifest: {},
|
|
20
|
-
entryCssFiles: {},
|
|
21
|
-
entryJsFiles: [],
|
|
22
|
-
moduleLoading: { prefix: '', crossOrigin: '' },
|
|
23
|
-
serverConsumerModuleMap: {},
|
|
24
|
-
serverManifest: Object.fromEntries(
|
|
25
|
-
Array.from({ length: 8 }, (_, index) => [
|
|
26
|
-
`action-${index}`,
|
|
27
|
-
{ id: 'server-module', chunks: [], name: 'action' },
|
|
28
|
-
]),
|
|
29
|
-
),
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
let mapArrayConstructions = 0;
|
|
33
|
-
if (scenario === 'cycle') {
|
|
34
|
-
const NativeMap = Map;
|
|
35
|
-
global.Map = class CountedMap extends NativeMap {
|
|
36
|
-
constructor(iterable) {
|
|
37
|
-
if (Array.isArray(iterable)) {
|
|
38
|
-
mapArrayConstructions += 1;
|
|
39
|
-
}
|
|
40
|
-
super(iterable);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const server = require(path.resolve(serverPath));
|
|
46
|
-
|
|
47
|
-
function output(value) {
|
|
48
|
-
process.stdout.write(JSON.stringify(value), () => process.exit(0));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function main() {
|
|
52
|
-
switch (scenario) {
|
|
53
|
-
case 'cycle': {
|
|
54
|
-
const body = new FormData();
|
|
55
|
-
body.set(
|
|
56
|
-
'0',
|
|
57
|
-
JSON.stringify([
|
|
58
|
-
...Array.from({ length: 8 }, (_, index) => [`key-${index}`, index]),
|
|
59
|
-
...Array.from({ length: 8 }, () => '$Q0'),
|
|
60
|
-
]),
|
|
61
|
-
);
|
|
62
|
-
let error;
|
|
63
|
-
try {
|
|
64
|
-
await server.decodeReply(body);
|
|
65
|
-
} catch (caught) {
|
|
66
|
-
error = caught;
|
|
67
|
-
}
|
|
68
|
-
output({ mapArrayConstructions, rejected: error instanceof Error });
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
case 'referenced-form-data': {
|
|
72
|
-
const body = new FormData();
|
|
73
|
-
body.append('_1_item', 'first');
|
|
74
|
-
body.append('_2_item', 'second');
|
|
75
|
-
body.append('0', JSON.stringify(['$K1', '$K2']));
|
|
76
|
-
let keyIterations = 0;
|
|
77
|
-
const originalKeys = body.keys.bind(body);
|
|
78
|
-
body.keys = () => {
|
|
79
|
-
keyIterations += 1;
|
|
80
|
-
return originalKeys();
|
|
81
|
-
};
|
|
82
|
-
const decoded = await server.decodeReply(body);
|
|
83
|
-
output({
|
|
84
|
-
keyIterations,
|
|
85
|
-
values: decoded.map(value => value.get('item')),
|
|
86
|
-
});
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
case 'blob-type': {
|
|
90
|
-
const body = new FormData();
|
|
91
|
-
body.set('1', 'not-a-blob');
|
|
92
|
-
body.set('0', JSON.stringify('$B1'));
|
|
93
|
-
let error;
|
|
94
|
-
try {
|
|
95
|
-
await server.decodeReply(body);
|
|
96
|
-
} catch (caught) {
|
|
97
|
-
error = caught;
|
|
98
|
-
}
|
|
99
|
-
output({
|
|
100
|
-
rejected: error instanceof Error,
|
|
101
|
-
returnedString: error === undefined,
|
|
102
|
-
});
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
case 'async-iterator': {
|
|
106
|
-
let throwCalls = 0;
|
|
107
|
-
const reason = new Error('iterator failed');
|
|
108
|
-
const iterator = {
|
|
109
|
-
next: () => Promise.reject(reason),
|
|
110
|
-
throw: () => {
|
|
111
|
-
throwCalls += 1;
|
|
112
|
-
return throwCalls < 6
|
|
113
|
-
? Promise.reject(reason)
|
|
114
|
-
: {
|
|
115
|
-
// biome-ignore lint/suspicious/noThenProperty: The regression requires a deliberately pending thenable to bound the vulnerable recursion.
|
|
116
|
-
then: () => {},
|
|
117
|
-
};
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
const iterable = { [Symbol.asyncIterator]: () => iterator };
|
|
121
|
-
try {
|
|
122
|
-
await server.decodeReplyFromAsyncIterable(iterable);
|
|
123
|
-
} catch {}
|
|
124
|
-
await new Promise(resolve => setImmediate(resolve));
|
|
125
|
-
output({ throwCalls });
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
case 'action-load': {
|
|
129
|
-
const body = new FormData();
|
|
130
|
-
for (let index = 0; index < 8; index += 1) {
|
|
131
|
-
body.append(`$ACTION_ID_action-${index}`, '');
|
|
132
|
-
}
|
|
133
|
-
const action = await server.decodeAction(body);
|
|
134
|
-
if (action === null) {
|
|
135
|
-
throw new Error('Expected an action');
|
|
136
|
-
}
|
|
137
|
-
const submitted = await action();
|
|
138
|
-
output({
|
|
139
|
-
moduleLoads,
|
|
140
|
-
submittedEntries: Array.from(submitted.entries()),
|
|
141
|
-
});
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
case 'form-data-roundtrip': {
|
|
145
|
-
const client = require(path.resolve(clientPath));
|
|
146
|
-
const nested = new FormData();
|
|
147
|
-
nested.append('item', 'first');
|
|
148
|
-
nested.append('item', 'second');
|
|
149
|
-
const encoded = await client.encodeReply({ nested });
|
|
150
|
-
const decoded = await server.decodeReply(encoded);
|
|
151
|
-
output({ values: decoded.nested.getAll('item') });
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
default:
|
|
155
|
-
throw new Error(`Unknown scenario: ${scenario}`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
main().catch(error => {
|
|
160
|
-
console.error(error);
|
|
161
|
-
process.exitCode = 1;
|
|
162
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
modifyRoutes as canonicalModifyRoutes,
|
|
3
|
-
routerProviderRegistryHooks,
|
|
4
|
-
} from '@modern-js/runtime/context';
|
|
5
|
-
import * as tanstackHooks from '../../src/runtime/hooks';
|
|
6
|
-
import { applyRouterRuntimeState } from '../../src/runtime/lifecycle';
|
|
7
|
-
import { tanstackRouterPlugin as browserPlugin } from '../../src/runtime/plugin';
|
|
8
|
-
import { tanstackRouterPlugin as nodePlugin } from '../../src/runtime/plugin.node';
|
|
9
|
-
import { getTanstackRouterState } from '../../src/runtime/state';
|
|
10
|
-
|
|
11
|
-
describe('tanstack router hooks single declaration source', () => {
|
|
12
|
-
test('re-exports the canonical hook instances owned by @modern-js/runtime', () => {
|
|
13
|
-
// Identity matters: separate instances would split the hook registry
|
|
14
|
-
// between the built-in router wrapper and this provider.
|
|
15
|
-
expect(tanstackHooks.modifyRoutes).toBe(canonicalModifyRoutes);
|
|
16
|
-
expect(tanstackHooks.routerProviderRegistryHooks).toBe(
|
|
17
|
-
routerProviderRegistryHooks,
|
|
18
|
-
);
|
|
19
|
-
expect(tanstackHooks.modifyRoutes).toBe(
|
|
20
|
-
routerProviderRegistryHooks.modifyRoutes,
|
|
21
|
-
);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test('both runtime plugins register the canonical hook registry object', () => {
|
|
25
|
-
expect(browserPlugin().registryHooks).toBe(routerProviderRegistryHooks);
|
|
26
|
-
expect(nodePlugin().registryHooks).toBe(routerProviderRegistryHooks);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe('tanstack router runtime state accessor', () => {
|
|
31
|
-
test('returns undefined before a tanstack router instance is created', () => {
|
|
32
|
-
const context = {};
|
|
33
|
-
|
|
34
|
-
applyRouterRuntimeState(context as never, {
|
|
35
|
-
framework: 'tanstack',
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
expect(getTanstackRouterState(context)).toBeUndefined();
|
|
39
|
-
});
|
|
40
|
-
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { isValidElement, Suspense } from 'react';
|
|
2
|
-
import { wrapTanstackSsrHydrationBoundary } from '../../src/runtime/hydrationBoundary';
|
|
3
|
-
|
|
4
|
-
describe('tanstack SSR hydration boundary', () => {
|
|
5
|
-
it('wraps SSR hydration content in a Suspense boundary', () => {
|
|
6
|
-
const routerContent = <main data-testid="router" />;
|
|
7
|
-
|
|
8
|
-
const wrapped = wrapTanstackSsrHydrationBoundary(routerContent, true);
|
|
9
|
-
|
|
10
|
-
expect(isValidElement(wrapped)).toBe(true);
|
|
11
|
-
expect(wrapped.type).toBe(Suspense);
|
|
12
|
-
expect(wrapped.props.fallback).toBe(null);
|
|
13
|
-
expect(wrapped.props.children).toBe(routerContent);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('keeps non-SSR router content unwrapped', () => {
|
|
17
|
-
const routerContent = <main data-testid="router" />;
|
|
18
|
-
|
|
19
|
-
expect(wrapTanstackSsrHydrationBoundary(routerContent, false)).toBe(
|
|
20
|
-
routerContent,
|
|
21
|
-
);
|
|
22
|
-
});
|
|
23
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
|
|
4
|
-
describe('tanstack package public surface', () => {
|
|
5
|
-
test('package manifest exposes the runtime subpath used by app fixtures', () => {
|
|
6
|
-
const packageJson = JSON.parse(
|
|
7
|
-
readFileSync(path.join(__dirname, '../../package.json'), 'utf-8'),
|
|
8
|
-
) as {
|
|
9
|
-
exports: Record<string, unknown>;
|
|
10
|
-
typesVersions?: Record<string, Record<string, string[]>>;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
expect(packageJson.exports['./runtime']).toEqual({
|
|
14
|
-
types: './dist/types/runtime/index.d.ts',
|
|
15
|
-
node: {
|
|
16
|
-
module: './dist/esm/runtime/index.mjs',
|
|
17
|
-
},
|
|
18
|
-
default: './dist/esm/runtime/index.mjs',
|
|
19
|
-
});
|
|
20
|
-
expect(packageJson.typesVersions?.['*']?.runtime).toEqual([
|
|
21
|
-
'./dist/types/runtime/index.d.ts',
|
|
22
|
-
]);
|
|
23
|
-
});
|
|
24
|
-
});
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { createMemoryHistory } from '@tanstack/history';
|
|
2
|
-
import {
|
|
3
|
-
createRootRoute,
|
|
4
|
-
createRoute,
|
|
5
|
-
createRouter,
|
|
6
|
-
redirect,
|
|
7
|
-
} from '@tanstack/react-router';
|
|
8
|
-
|
|
9
|
-
describe('tanstack router-core preload redirects', () => {
|
|
10
|
-
afterEach(() => {
|
|
11
|
-
rstest.restoreAllMocks();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test('resolves concurrent preload redirects without stale loader work', async () => {
|
|
15
|
-
const consoleErrorSpy = rstest
|
|
16
|
-
.spyOn(console, 'error')
|
|
17
|
-
.mockImplementation(() => {});
|
|
18
|
-
const rootRoute = createRootRoute();
|
|
19
|
-
const indexRoute = createRoute({
|
|
20
|
-
getParentRoute: () => rootRoute,
|
|
21
|
-
path: '/',
|
|
22
|
-
component: () => null,
|
|
23
|
-
});
|
|
24
|
-
let redirectLoaderCalls = 0;
|
|
25
|
-
const redirectRoute = createRoute({
|
|
26
|
-
getParentRoute: () => rootRoute,
|
|
27
|
-
path: '/redirect',
|
|
28
|
-
loader: async () => {
|
|
29
|
-
redirectLoaderCalls += 1;
|
|
30
|
-
await Promise.resolve();
|
|
31
|
-
throw redirect({ to: '/target' });
|
|
32
|
-
},
|
|
33
|
-
component: () => null,
|
|
34
|
-
});
|
|
35
|
-
const targetLoader = rstest.fn(async () => 'target');
|
|
36
|
-
const targetRoute = createRoute({
|
|
37
|
-
getParentRoute: () => rootRoute,
|
|
38
|
-
path: '/target',
|
|
39
|
-
loader: targetLoader,
|
|
40
|
-
component: () => null,
|
|
41
|
-
});
|
|
42
|
-
const router = createRouter({
|
|
43
|
-
routeTree: rootRoute.addChildren([
|
|
44
|
-
indexRoute,
|
|
45
|
-
redirectRoute,
|
|
46
|
-
targetRoute,
|
|
47
|
-
]),
|
|
48
|
-
history: createMemoryHistory({
|
|
49
|
-
initialEntries: ['/'],
|
|
50
|
-
}),
|
|
51
|
-
defaultStructuralSharing: true,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
await Promise.all([
|
|
55
|
-
router.preloadRoute({ to: '/redirect' }),
|
|
56
|
-
router.preloadRoute({ to: '/redirect' }),
|
|
57
|
-
]);
|
|
58
|
-
|
|
59
|
-
expect(consoleErrorSpy).not.toHaveBeenCalled();
|
|
60
|
-
expect(router.options.defaultStructuralSharing).toBe(true);
|
|
61
|
-
expect(redirectLoaderCalls).toBe(1);
|
|
62
|
-
expect(targetLoader).toHaveBeenCalledTimes(1);
|
|
63
|
-
});
|
|
64
|
-
});
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { resolveRouterProvider } from '@modern-js/runtime/context';
|
|
2
|
-
import '../../src/runtime/register';
|
|
3
|
-
|
|
4
|
-
describe("'@modern-js/plugin-tanstack/runtime' import side effects", () => {
|
|
5
|
-
it('registers the tanstack router provider', () => {
|
|
6
|
-
expect(typeof resolveRouterProvider('tanstack')).toBe('function');
|
|
7
|
-
});
|
|
8
|
-
});
|