@reckona/mreact-router 0.0.55 → 0.0.56
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/build.d.ts.map +1 -1
- package/dist/build.js +8 -0
- package/dist/build.js.map +1 -1
- package/dist/client.d.ts +9 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +218 -20
- package/dist/client.js.map +1 -1
- package/dist/vite.d.ts +3 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +10 -2
- package/dist/vite.js.map +1 -1
- package/package.json +11 -11
package/dist/client.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { readFile, stat } from "node:fs/promises";
|
|
3
3
|
import { builtinModules } from "node:module";
|
|
4
|
-
import { dirname, join, relative, sep } from "node:path";
|
|
4
|
+
import { dirname, extname, join, relative, sep } from "node:path";
|
|
5
5
|
import { collectClientRouteModuleAnalysis, formatDiagnostic, } from "@reckona/mreact-compiler";
|
|
6
6
|
import { collectClientRouteModuleAnalysisFromContext, createCompilerModuleContext, transformCompilerModuleContext, } from "@reckona/mreact-compiler/internal";
|
|
7
7
|
import { assetPath } from "./assets.js";
|
|
@@ -40,6 +40,7 @@ export function createClientRouteInferenceCache() {
|
|
|
40
40
|
moduleContextByFile: new Map(),
|
|
41
41
|
resolvedByImport: new Map(),
|
|
42
42
|
sourceByFile: new Map(),
|
|
43
|
+
transformedSourceByFile: new Map(),
|
|
43
44
|
};
|
|
44
45
|
}
|
|
45
46
|
export async function isClientRouteModule(options) {
|
|
@@ -47,14 +48,21 @@ export async function isClientRouteModule(options) {
|
|
|
47
48
|
}
|
|
48
49
|
export async function inferClientRouteModule(options) {
|
|
49
50
|
const cache = options.cache ?? createClientRouteInferenceCache();
|
|
51
|
+
const sourceTransform = clientRouteSourceTransformForVitePlugins(options.vitePlugins);
|
|
52
|
+
const code = await transformClientRouteSource({
|
|
53
|
+
code: options.code,
|
|
54
|
+
filename: options.filename,
|
|
55
|
+
sourceTransform,
|
|
56
|
+
});
|
|
50
57
|
try {
|
|
51
58
|
const routeInference = await inferClientRouteModuleSource({
|
|
52
59
|
cache,
|
|
53
|
-
code
|
|
60
|
+
code,
|
|
54
61
|
filename: options.filename,
|
|
55
|
-
moduleContext: options.moduleContext,
|
|
62
|
+
...(sourceTransform === undefined ? { moduleContext: options.moduleContext } : {}),
|
|
56
63
|
root: true,
|
|
57
64
|
seen: new Set(),
|
|
65
|
+
sourceTransform,
|
|
58
66
|
});
|
|
59
67
|
if (options.appDir === undefined) {
|
|
60
68
|
return routeInference;
|
|
@@ -63,6 +71,7 @@ export async function inferClientRouteModule(options) {
|
|
|
63
71
|
appDir: options.appDir,
|
|
64
72
|
cache,
|
|
65
73
|
filename: options.filename,
|
|
74
|
+
sourceTransform,
|
|
66
75
|
});
|
|
67
76
|
return {
|
|
68
77
|
client: routeInference.client || shellInferences.some((inference) => inference.client),
|
|
@@ -79,18 +88,25 @@ export async function inferClientRouteModule(options) {
|
|
|
79
88
|
}
|
|
80
89
|
export async function collectClientRouteReferences(options) {
|
|
81
90
|
const cache = options.cache ?? createClientRouteInferenceCache();
|
|
91
|
+
const sourceTransform = clientRouteSourceTransformForVitePlugins(options.vitePlugins);
|
|
92
|
+
const code = await transformClientRouteSource({
|
|
93
|
+
code: options.code,
|
|
94
|
+
filename: options.filename,
|
|
95
|
+
sourceTransform,
|
|
96
|
+
});
|
|
82
97
|
const routeModuleContext = await compilerModuleContextForSource({
|
|
83
98
|
cache,
|
|
84
|
-
code
|
|
99
|
+
code,
|
|
85
100
|
filename: options.filename,
|
|
86
101
|
});
|
|
87
102
|
const routeInference = await inferClientRouteModuleSource({
|
|
88
103
|
cache,
|
|
89
|
-
code
|
|
104
|
+
code,
|
|
90
105
|
filename: options.filename,
|
|
91
106
|
moduleContext: routeModuleContext,
|
|
92
107
|
root: true,
|
|
93
108
|
seen: new Set(),
|
|
109
|
+
sourceTransform,
|
|
94
110
|
});
|
|
95
111
|
const sources = [];
|
|
96
112
|
const seenSourceFiles = new Set();
|
|
@@ -113,6 +129,7 @@ export async function collectClientRouteReferences(options) {
|
|
|
113
129
|
moduleContext,
|
|
114
130
|
root: true,
|
|
115
131
|
seen: new Set(),
|
|
132
|
+
sourceTransform,
|
|
116
133
|
}));
|
|
117
134
|
sources.push({
|
|
118
135
|
code: sourceOptions.code,
|
|
@@ -121,19 +138,19 @@ export async function collectClientRouteReferences(options) {
|
|
|
121
138
|
moduleContext,
|
|
122
139
|
});
|
|
123
140
|
for (const referenceFile of inference.clientReferenceSourceFiles) {
|
|
124
|
-
const code = stripRouteClientOnlyExports(await
|
|
141
|
+
const code = stripRouteClientOnlyExports(await readClientRouteSource({ cache, filename: referenceFile, sourceTransform }));
|
|
125
142
|
await addSource({ code, filename: referenceFile });
|
|
126
143
|
}
|
|
127
144
|
};
|
|
128
145
|
await addSource({
|
|
129
|
-
code
|
|
146
|
+
code,
|
|
130
147
|
filename: options.filename,
|
|
131
148
|
inference: routeInference,
|
|
132
149
|
moduleContext: routeModuleContext,
|
|
133
150
|
});
|
|
134
151
|
if (options.appDir !== undefined) {
|
|
135
152
|
for (const shell of await clientShellFilesForPage(options.appDir, options.filename)) {
|
|
136
|
-
const code = stripRouteClientOnlyExports(await
|
|
153
|
+
const code = stripRouteClientOnlyExports(await readClientRouteSource({ cache, filename: shell, sourceTransform }));
|
|
137
154
|
const moduleContext = await compilerModuleContextForSource({
|
|
138
155
|
cache,
|
|
139
156
|
code,
|
|
@@ -149,6 +166,7 @@ export async function collectClientRouteReferences(options) {
|
|
|
149
166
|
moduleContext,
|
|
150
167
|
root: true,
|
|
151
168
|
seen: new Set(),
|
|
169
|
+
sourceTransform,
|
|
152
170
|
}),
|
|
153
171
|
moduleContext,
|
|
154
172
|
});
|
|
@@ -202,13 +220,18 @@ export async function collectClientRouteReferences(options) {
|
|
|
202
220
|
}
|
|
203
221
|
async function inferClientRouteShellModules(options) {
|
|
204
222
|
return Promise.all((await clientShellFilesForPage(options.appDir, options.filename)).map(async (shell) => {
|
|
205
|
-
const code = stripRouteClientOnlyExports(await
|
|
223
|
+
const code = stripRouteClientOnlyExports(await readClientRouteSource({
|
|
224
|
+
cache: options.cache,
|
|
225
|
+
filename: shell,
|
|
226
|
+
sourceTransform: options.sourceTransform,
|
|
227
|
+
}));
|
|
206
228
|
return await inferClientRouteModuleSource({
|
|
207
229
|
cache: options.cache,
|
|
208
230
|
code,
|
|
209
231
|
filename: shell,
|
|
210
232
|
root: true,
|
|
211
233
|
seen: new Set(),
|
|
234
|
+
sourceTransform: options.sourceTransform,
|
|
212
235
|
});
|
|
213
236
|
}));
|
|
214
237
|
}
|
|
@@ -232,7 +255,7 @@ function isExplicitClientRouteSource(analysis, filename) {
|
|
|
232
255
|
return analysis.hasUseClientDirective || isClientBoundaryFilename(filename);
|
|
233
256
|
}
|
|
234
257
|
function isClientBoundaryFilename(filename) {
|
|
235
|
-
return /\.client(?:\.mreact)?\.[cm]?[jt]sx?$/.test(filename);
|
|
258
|
+
return /\.(?:client|compat)(?:\.mreact)?\.[cm]?[jt]sx?$/.test(filename);
|
|
236
259
|
}
|
|
237
260
|
function isServerOnlyClientRouteSource(analysis) {
|
|
238
261
|
return analysis.hasUseServerDirective;
|
|
@@ -297,6 +320,7 @@ async function inferClientRouteModuleSource(options) {
|
|
|
297
320
|
continue;
|
|
298
321
|
}
|
|
299
322
|
const resolved = await resolveAppLocalModule({
|
|
323
|
+
allowExplicitNonSource: options.sourceTransform !== undefined,
|
|
300
324
|
cache: options.cache,
|
|
301
325
|
importer: options.filename,
|
|
302
326
|
specifier: reference.source,
|
|
@@ -304,7 +328,11 @@ async function inferClientRouteModuleSource(options) {
|
|
|
304
328
|
if (resolved === undefined) {
|
|
305
329
|
continue;
|
|
306
330
|
}
|
|
307
|
-
const source = await
|
|
331
|
+
const source = await readClientRouteSource({
|
|
332
|
+
cache: options.cache,
|
|
333
|
+
filename: resolved,
|
|
334
|
+
sourceTransform: options.sourceTransform,
|
|
335
|
+
});
|
|
308
336
|
const imported = await inferClientRouteModuleSource({
|
|
309
337
|
cache: options.cache,
|
|
310
338
|
code: source,
|
|
@@ -316,6 +344,7 @@ async function inferClientRouteModuleSource(options) {
|
|
|
316
344
|
}),
|
|
317
345
|
root: false,
|
|
318
346
|
seen: options.seen,
|
|
347
|
+
sourceTransform: options.sourceTransform,
|
|
319
348
|
});
|
|
320
349
|
diagnostics.push(...imported.diagnostics);
|
|
321
350
|
if (!imported.client) {
|
|
@@ -364,6 +393,7 @@ async function inferClientRouteModuleSource(options) {
|
|
|
364
393
|
if (!options.root) {
|
|
365
394
|
for (const reference of analysis.staticExports) {
|
|
366
395
|
const resolved = await resolveAppLocalModule({
|
|
396
|
+
allowExplicitNonSource: options.sourceTransform !== undefined,
|
|
367
397
|
cache: options.cache,
|
|
368
398
|
importer: options.filename,
|
|
369
399
|
specifier: reference.source,
|
|
@@ -371,7 +401,11 @@ async function inferClientRouteModuleSource(options) {
|
|
|
371
401
|
if (resolved === undefined) {
|
|
372
402
|
continue;
|
|
373
403
|
}
|
|
374
|
-
const source = await
|
|
404
|
+
const source = await readClientRouteSource({
|
|
405
|
+
cache: options.cache,
|
|
406
|
+
filename: resolved,
|
|
407
|
+
sourceTransform: options.sourceTransform,
|
|
408
|
+
});
|
|
375
409
|
const exported = await inferClientRouteModuleSource({
|
|
376
410
|
cache: options.cache,
|
|
377
411
|
code: source,
|
|
@@ -383,6 +417,7 @@ async function inferClientRouteModuleSource(options) {
|
|
|
383
417
|
}),
|
|
384
418
|
root: false,
|
|
385
419
|
seen: options.seen,
|
|
420
|
+
sourceTransform: options.sourceTransform,
|
|
386
421
|
});
|
|
387
422
|
diagnostics.push(...exported.diagnostics);
|
|
388
423
|
if (exported.clientBoundaryModule) {
|
|
@@ -562,19 +597,27 @@ async function resolveAppLocalModule(options) {
|
|
|
562
597
|
if (!options.specifier.startsWith(".")) {
|
|
563
598
|
return undefined;
|
|
564
599
|
}
|
|
565
|
-
const cacheKey = `${options.importer}\0${options.specifier}`;
|
|
600
|
+
const cacheKey = `${options.importer}\0${options.specifier}\0${options.allowExplicitNonSource === true ? "explicit" : "source"}`;
|
|
566
601
|
const cached = options.cache.resolvedByImport.get(cacheKey);
|
|
567
602
|
if (cached !== undefined) {
|
|
568
603
|
return cached;
|
|
569
604
|
}
|
|
570
|
-
const resolved = resolveAppLocalModuleUncached(
|
|
605
|
+
const resolved = resolveAppLocalModuleUncached({
|
|
606
|
+
allowExplicitNonSource: options.allowExplicitNonSource === true,
|
|
607
|
+
importer: options.importer,
|
|
608
|
+
specifier: options.specifier,
|
|
609
|
+
});
|
|
571
610
|
options.cache.resolvedByImport.set(cacheKey, resolved);
|
|
572
611
|
return resolved;
|
|
573
612
|
}
|
|
574
|
-
async function resolveAppLocalModuleUncached(
|
|
613
|
+
async function resolveAppLocalModuleUncached(options) {
|
|
614
|
+
const { importer, specifier } = options;
|
|
575
615
|
const base = join(dirname(importer), specifier);
|
|
576
616
|
const candidates = sourceModuleCandidates(base);
|
|
577
617
|
if (candidates.length === 0) {
|
|
618
|
+
if (options.allowExplicitNonSource && extname(base) !== "" && (await isFile(base))) {
|
|
619
|
+
return base;
|
|
620
|
+
}
|
|
578
621
|
return undefined;
|
|
579
622
|
}
|
|
580
623
|
for (const candidate of candidates) {
|
|
@@ -608,6 +651,126 @@ async function readCachedFile(cache, filename) {
|
|
|
608
651
|
cache.sourceByFile.set(filename, source);
|
|
609
652
|
return (await source).source;
|
|
610
653
|
}
|
|
654
|
+
async function readClientRouteSource(options) {
|
|
655
|
+
if (options.sourceTransform === undefined) {
|
|
656
|
+
return readCachedFile(options.cache, options.filename);
|
|
657
|
+
}
|
|
658
|
+
const signature = await sourceFileSignature(options.filename);
|
|
659
|
+
const cacheKey = `${options.filename}\0${options.sourceTransform.cacheKey}`;
|
|
660
|
+
const cached = options.cache.transformedSourceByFile.get(cacheKey);
|
|
661
|
+
if (cached !== undefined) {
|
|
662
|
+
const source = await cached;
|
|
663
|
+
if (source.signature === signature) {
|
|
664
|
+
return source.source;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
const source = readCachedFile(options.cache, options.filename).then(async (code) => ({
|
|
668
|
+
signature,
|
|
669
|
+
source: await options.sourceTransform.transform(options.filename, code),
|
|
670
|
+
}));
|
|
671
|
+
options.cache.transformedSourceByFile.set(cacheKey, source);
|
|
672
|
+
return (await source).source;
|
|
673
|
+
}
|
|
674
|
+
async function transformClientRouteSource(options) {
|
|
675
|
+
return options.sourceTransform === undefined
|
|
676
|
+
? options.code
|
|
677
|
+
: await options.sourceTransform.transform(options.filename, options.code);
|
|
678
|
+
}
|
|
679
|
+
function clientRouteSourceTransformForVitePlugins(pluginOptions) {
|
|
680
|
+
const plugins = orderVitePlugins(flattenVitePlugins(pluginOptions)).filter((plugin) => hasViteTransformHook(plugin));
|
|
681
|
+
if (plugins.length === 0) {
|
|
682
|
+
return undefined;
|
|
683
|
+
}
|
|
684
|
+
return {
|
|
685
|
+
cacheKey: plugins.map((plugin, index) => `${index}:${plugin.name}`).join("\0"),
|
|
686
|
+
async transform(filename, code) {
|
|
687
|
+
let nextCode = code;
|
|
688
|
+
for (const plugin of plugins) {
|
|
689
|
+
const handler = viteTransformHookHandler(plugin);
|
|
690
|
+
if (handler === undefined) {
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
const result = await handler.call(createClientRouteViteTransformContext(plugin.name), nextCode, filename, { ssr: false });
|
|
694
|
+
if (typeof result === "string") {
|
|
695
|
+
nextCode = result;
|
|
696
|
+
}
|
|
697
|
+
else if (result !== null && result !== undefined && typeof result === "object") {
|
|
698
|
+
const codeResult = result.code;
|
|
699
|
+
if (typeof codeResult === "string") {
|
|
700
|
+
nextCode = codeResult;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
return nextCode;
|
|
705
|
+
},
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
function flattenVitePlugins(pluginOptions) {
|
|
709
|
+
const plugins = [];
|
|
710
|
+
const visit = (option) => {
|
|
711
|
+
if (option === false || option === null || option === undefined) {
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
if (Array.isArray(option)) {
|
|
715
|
+
for (const child of option) {
|
|
716
|
+
visit(child);
|
|
717
|
+
}
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
if (typeof option === "object" && "then" in option) {
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
plugins.push(option);
|
|
724
|
+
};
|
|
725
|
+
for (const option of pluginOptions ?? []) {
|
|
726
|
+
visit(option);
|
|
727
|
+
}
|
|
728
|
+
return plugins;
|
|
729
|
+
}
|
|
730
|
+
function orderVitePlugins(plugins) {
|
|
731
|
+
return [
|
|
732
|
+
...plugins.filter((plugin) => plugin.enforce === "pre"),
|
|
733
|
+
...plugins.filter((plugin) => plugin.enforce !== "pre" && plugin.enforce !== "post"),
|
|
734
|
+
...plugins.filter((plugin) => plugin.enforce === "post"),
|
|
735
|
+
];
|
|
736
|
+
}
|
|
737
|
+
function hasViteTransformHook(plugin) {
|
|
738
|
+
return viteTransformHookHandler(plugin) !== undefined;
|
|
739
|
+
}
|
|
740
|
+
function viteTransformHookHandler(plugin) {
|
|
741
|
+
const transform = plugin.transform;
|
|
742
|
+
if (typeof transform === "function") {
|
|
743
|
+
return transform;
|
|
744
|
+
}
|
|
745
|
+
if (transform !== null && typeof transform === "object") {
|
|
746
|
+
const handler = transform.handler;
|
|
747
|
+
if (typeof handler === "function") {
|
|
748
|
+
return handler;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
return undefined;
|
|
752
|
+
}
|
|
753
|
+
function createClientRouteViteTransformContext(pluginName) {
|
|
754
|
+
return {
|
|
755
|
+
addWatchFile() { },
|
|
756
|
+
async resolve() {
|
|
757
|
+
return null;
|
|
758
|
+
},
|
|
759
|
+
error(error) {
|
|
760
|
+
if (error instanceof Error) {
|
|
761
|
+
throw error;
|
|
762
|
+
}
|
|
763
|
+
throw new Error(String(error));
|
|
764
|
+
},
|
|
765
|
+
warn() { },
|
|
766
|
+
getCombinedSourcemap() {
|
|
767
|
+
return null;
|
|
768
|
+
},
|
|
769
|
+
parse() {
|
|
770
|
+
throw new Error(`${pluginName}: client route import analysis cannot provide Rollup parser context.`);
|
|
771
|
+
},
|
|
772
|
+
};
|
|
773
|
+
}
|
|
611
774
|
async function sourceFileSignature(filename) {
|
|
612
775
|
const stats = await stat(filename);
|
|
613
776
|
return `${stats.mtimeMs}\0${stats.size}`;
|
|
@@ -685,6 +848,7 @@ export async function buildClientRouteOutput(options) {
|
|
|
685
848
|
});
|
|
686
849
|
const compiled = transformCompilerModuleContext({
|
|
687
850
|
code: options.code,
|
|
851
|
+
clientBoundaryImports: options.clientBoundaryImports ?? [],
|
|
688
852
|
filename: options.filename,
|
|
689
853
|
moduleContext,
|
|
690
854
|
target: "client",
|
|
@@ -697,8 +861,9 @@ export async function buildClientRouteOutput(options) {
|
|
|
697
861
|
}
|
|
698
862
|
const clientNavigation = options.clientNavigation ?? detectClientNavigationHint(options.code);
|
|
699
863
|
const clientReferenceManifest = options.clientReferenceManifest ?? (await inferClientReferenceManifestForBundle(options));
|
|
864
|
+
const compatClientReferenceNames = compatClientReferenceComponentNames(clientReferenceManifest);
|
|
700
865
|
const clientReferenceImportBlock = emitClientReferenceImportBlock(options.clientReferenceImports ?? []);
|
|
701
|
-
const clientReferenceRegistry = emitClientReferenceRegistry(clientReferenceManifest, options.clientReferenceImports ?? []);
|
|
866
|
+
const clientReferenceRegistry = emitClientReferenceRegistry(clientReferenceManifest, options.clientReferenceImports ?? [], compatClientReferenceNames);
|
|
702
867
|
const routeComponentExpression = routeComponentExpressionForComponents(compiled.metadata.components);
|
|
703
868
|
const routeId = routeIdForPath(options.routePath);
|
|
704
869
|
const routeUsesCells = detectRouteCellStateHint(compiled.code);
|
|
@@ -892,7 +1057,7 @@ ${routeCellHydrationIndent}}
|
|
|
892
1057
|
${routeCellHydrationIndent} return;
|
|
893
1058
|
${routeCellHydrationIndent}}
|
|
894
1059
|
`;
|
|
895
|
-
const entry = `${routeCellEffectImport}${routeCleanupScopeImport}${clientReferenceImportBlock}${routeHydrationCode}
|
|
1060
|
+
const entry = `${routeCellEffectImport}${routeCleanupScopeImport}${emitCompatClientReferenceImportBlock(compatClientReferenceNames)}${clientReferenceImportBlock}${routeHydrationCode}
|
|
896
1061
|
|
|
897
1062
|
const __mreactRouteId = ${JSON.stringify(routeId)};
|
|
898
1063
|
const __mreactRouteStateSignature = ${JSON.stringify(routeStateSignature)};
|
|
@@ -924,6 +1089,7 @@ export function __mreactHydrateRoute() {
|
|
|
924
1089
|
}
|
|
925
1090
|
${routeCellHydrationStart}${routeCleanupHydrationStart}${boundaryOnlyHydrationBlock}${routeComponentGuard}${routeCellHydrationIndent}const __mreactNode = ${routeNodeExpression};
|
|
926
1091
|
${routeCellHydrationIndent}__mreactResumeRoute(__mreactMarker, __mreactNode);
|
|
1092
|
+
${routeCellHydrationIndent}__mreactHydrateClientBoundaries(__mreactMarker, __mreactClientReferences, __mreactClientReferenceComponents);
|
|
927
1093
|
${routeCellHydrationIndent}__mreactMarker.setAttribute("data-mreact-hydrated", "true");
|
|
928
1094
|
${routeCellHydrationEnd}}
|
|
929
1095
|
${routeCellDropFunction}
|
|
@@ -1798,7 +1964,9 @@ function __mreactHydrateClientBoundaries(marker, references, components) {
|
|
|
1798
1964
|
|
|
1799
1965
|
for (const placeholder of placeholders) {
|
|
1800
1966
|
const name = placeholder.getAttribute("data-mreact-client-boundary");
|
|
1801
|
-
const
|
|
1967
|
+
const entry = name === null ? undefined : components.get(name);
|
|
1968
|
+
const component = typeof entry === "function" ? entry : entry?.component;
|
|
1969
|
+
const compat = entry?.compat === true;
|
|
1802
1970
|
|
|
1803
1971
|
if (typeof component !== "function") {
|
|
1804
1972
|
return false;
|
|
@@ -1808,6 +1976,17 @@ function __mreactHydrateClientBoundaries(marker, references, components) {
|
|
|
1808
1976
|
const props = propsElement?.textContent === undefined || propsElement.textContent === ""
|
|
1809
1977
|
? {}
|
|
1810
1978
|
: JSON.parse(propsElement.textContent);
|
|
1979
|
+
|
|
1980
|
+
if (compat) {
|
|
1981
|
+
const container = document.createElement("span");
|
|
1982
|
+
container.setAttribute("data-mreact-compat-boundary", name ?? "");
|
|
1983
|
+
container.style.display = "contents";
|
|
1984
|
+
placeholder.replaceWith(container);
|
|
1985
|
+
__mreactCompatCreateRoot(container).render(__mreactCompatCreateElement(component, props));
|
|
1986
|
+
propsElement?.remove();
|
|
1987
|
+
continue;
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1811
1990
|
const node = component(props);
|
|
1812
1991
|
|
|
1813
1992
|
placeholder.replaceWith(node);
|
|
@@ -2230,6 +2409,7 @@ function __mreactResumeChildren(current, next) {
|
|
|
2230
2409
|
preserveExports: true,
|
|
2231
2410
|
plugins: [workspaceRuntimePlugin({ routeFile: options.filename })],
|
|
2232
2411
|
sourceMap: options.sourceMap,
|
|
2412
|
+
vitePlugins: options.vitePlugins,
|
|
2233
2413
|
});
|
|
2234
2414
|
return {
|
|
2235
2415
|
code: bundled.code,
|
|
@@ -2325,6 +2505,7 @@ export function currentDevtoolsEmitter() { return undefined; }`,
|
|
|
2325
2505
|
code: source,
|
|
2326
2506
|
dev: true,
|
|
2327
2507
|
filename: args.path,
|
|
2508
|
+
mode: isCompatSourcePath(args.path) ? "compat" : "reactive",
|
|
2328
2509
|
moduleContext,
|
|
2329
2510
|
target: "client",
|
|
2330
2511
|
});
|
|
@@ -2345,6 +2526,9 @@ export function currentDevtoolsEmitter() { return undefined; }`,
|
|
|
2345
2526
|
function isRouteClientDependencySourcePath(path, routeFile) {
|
|
2346
2527
|
return path !== routeFile && !path.includes(`${sep}node_modules${sep}`);
|
|
2347
2528
|
}
|
|
2529
|
+
function isCompatSourcePath(path) {
|
|
2530
|
+
return /\.compat(?:\.mreact)?(?:\.[cm]?[jt]sx?)?$/.test(path);
|
|
2531
|
+
}
|
|
2348
2532
|
/**
|
|
2349
2533
|
* Detects the `export const clientNavigation = false` hint in a page module
|
|
2350
2534
|
* source. Returns the hinted value, or `true` when no hint is present (i.e.,
|
|
@@ -2414,7 +2598,7 @@ function emitClientReferenceImportBlock(imports) {
|
|
|
2414
2598
|
})
|
|
2415
2599
|
.join("\n")}\n`;
|
|
2416
2600
|
}
|
|
2417
|
-
function emitClientReferenceRegistry(manifest, imports) {
|
|
2601
|
+
function emitClientReferenceRegistry(manifest, imports, compatNames) {
|
|
2418
2602
|
const importedExpressions = new Map(imports.map((reference, index) => [
|
|
2419
2603
|
reference.name,
|
|
2420
2604
|
isIdentifierName(reference.exportName)
|
|
@@ -2425,10 +2609,24 @@ function emitClientReferenceRegistry(manifest, imports) {
|
|
|
2425
2609
|
const expression = importedExpressions.get(reference.name) ?? clientReferenceExpression(reference.name);
|
|
2426
2610
|
return expression === undefined
|
|
2427
2611
|
? []
|
|
2428
|
-
: [
|
|
2612
|
+
: [
|
|
2613
|
+
compatNames.has(reference.name)
|
|
2614
|
+
? ` [${JSON.stringify(reference.name)}, { component: ${expression}, compat: true }],`
|
|
2615
|
+
: ` [${JSON.stringify(reference.name)}, ${expression}],`,
|
|
2616
|
+
];
|
|
2429
2617
|
});
|
|
2430
2618
|
return ["const __mreactClientReferenceComponents = new Map([", ...entries, "]);"].join("\n");
|
|
2431
2619
|
}
|
|
2620
|
+
function compatClientReferenceComponentNames(manifest) {
|
|
2621
|
+
return new Set(manifest
|
|
2622
|
+
.filter((reference) => isCompatSourcePath(reference.moduleId))
|
|
2623
|
+
.map((reference) => reference.name));
|
|
2624
|
+
}
|
|
2625
|
+
function emitCompatClientReferenceImportBlock(compatNames) {
|
|
2626
|
+
return compatNames.size === 0
|
|
2627
|
+
? ""
|
|
2628
|
+
: 'import { createElement as __mreactCompatCreateElement, createRoot as __mreactCompatCreateRoot } from "@reckona/mreact-compat";\n';
|
|
2629
|
+
}
|
|
2432
2630
|
function clientReferenceLocalName(index) {
|
|
2433
2631
|
return `__mreactClientReference${index}`;
|
|
2434
2632
|
}
|