@reckona/mreact-router 0.0.195 → 0.0.196
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/bundle-pipeline.d.ts +2 -0
- package/dist/bundle-pipeline.d.ts.map +1 -1
- package/dist/bundle-pipeline.js +25 -3
- package/dist/bundle-pipeline.js.map +1 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +110 -35
- package/dist/client.js.map +1 -1
- package/dist/vite.js +1 -0
- package/dist/vite.js.map +1 -1
- package/package.json +11 -11
- package/src/bundle-pipeline.ts +50 -3
- package/src/client.ts +127 -36
- package/src/vite.ts +1 -0
package/src/client.ts
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, extname, join, relative, sep } from "node:path";
|
|
4
|
+
import { basename, dirname, extname, isAbsolute, join, relative, sep } from "node:path";
|
|
5
5
|
import {
|
|
6
6
|
analyzeBoundaryGraph,
|
|
7
7
|
collectClientRouteModuleAnalysis,
|
|
@@ -68,6 +68,7 @@ export interface ClientRouteManifestEntry {
|
|
|
68
68
|
export interface BuildClientRouteOutputOptions {
|
|
69
69
|
cacheDir?: string | undefined;
|
|
70
70
|
code: string;
|
|
71
|
+
debugLabels?: boolean | undefined;
|
|
71
72
|
clientBoundaryImports?: readonly string[] | undefined;
|
|
72
73
|
clientReferenceImports?: readonly ClientReferenceImport[] | undefined;
|
|
73
74
|
clientReferenceManifest?: readonly ClientReferenceMetadata[] | undefined;
|
|
@@ -2104,6 +2105,13 @@ export async function buildClientRouteOutput(
|
|
|
2104
2105
|
const entry = await buildClientRouteEntrySource(options);
|
|
2105
2106
|
const dropConsoleFunctions =
|
|
2106
2107
|
options.dropConsoleFunctions ?? resolveClientConsolePureFunctions(options.dropClientConsole);
|
|
2108
|
+
const sourceRegionModulePaths =
|
|
2109
|
+
options.debugLabels === true ? undefined : new Set([options.filename]);
|
|
2110
|
+
const runtimePlugin = workspaceRuntimePlugin({
|
|
2111
|
+
debugLabels: options.debugLabels === true,
|
|
2112
|
+
routeFiles: [options.filename],
|
|
2113
|
+
sourceRegionModulePaths,
|
|
2114
|
+
});
|
|
2107
2115
|
const bundled = await bundleRouterModule({
|
|
2108
2116
|
code: entry.code,
|
|
2109
2117
|
cacheDir: options.cacheDir,
|
|
@@ -2115,7 +2123,8 @@ export async function buildClientRouteOutput(
|
|
|
2115
2123
|
minify: options.minify === true,
|
|
2116
2124
|
platform: "browser",
|
|
2117
2125
|
preserveExports: true,
|
|
2118
|
-
|
|
2126
|
+
sourceRegionModulePaths,
|
|
2127
|
+
plugins: [runtimePlugin],
|
|
2119
2128
|
sourceMap: options.sourceMap,
|
|
2120
2129
|
vitePlugins: options.vitePlugins,
|
|
2121
2130
|
});
|
|
@@ -2149,6 +2158,15 @@ export async function buildClientRouteBatchOutput(options: {
|
|
|
2149
2158
|
}),
|
|
2150
2159
|
})),
|
|
2151
2160
|
);
|
|
2161
|
+
const debugLabels = options.routes.some((route) => route.debugLabels === true);
|
|
2162
|
+
const sourceRegionModulePaths = debugLabels
|
|
2163
|
+
? undefined
|
|
2164
|
+
: new Set(entries.map((entry) => entry.filename));
|
|
2165
|
+
const runtimePlugin = workspaceRuntimePlugin({
|
|
2166
|
+
debugLabels,
|
|
2167
|
+
routeFiles: entries.map((entry) => entry.filename),
|
|
2168
|
+
sourceRegionModulePaths,
|
|
2169
|
+
});
|
|
2152
2170
|
const bundled = await bundleRouterModules({
|
|
2153
2171
|
base: options.assetBaseUrl ?? "/_mreact/client/",
|
|
2154
2172
|
cacheDir: options.cacheDir,
|
|
@@ -2162,7 +2180,8 @@ export async function buildClientRouteBatchOutput(options: {
|
|
|
2162
2180
|
})),
|
|
2163
2181
|
minify: options.minify === true,
|
|
2164
2182
|
platform: "browser",
|
|
2165
|
-
|
|
2183
|
+
sourceRegionModulePaths,
|
|
2184
|
+
plugins: [runtimePlugin],
|
|
2166
2185
|
root: options.projectRoot,
|
|
2167
2186
|
sourceMap: options.sourceMap,
|
|
2168
2187
|
dropConsoleFunctions: options.dropConsoleFunctions,
|
|
@@ -2199,13 +2218,22 @@ export async function buildClientRouteEntrySource(
|
|
|
2199
2218
|
filename: options.filename,
|
|
2200
2219
|
});
|
|
2201
2220
|
const routeSourceAnalysis = collectClientRouteModuleAnalysisFromContext(moduleContext);
|
|
2221
|
+
const compilerFilename =
|
|
2222
|
+
options.debugLabels === true ? basename(options.filename) : options.filename;
|
|
2223
|
+
const compilerModuleContext =
|
|
2224
|
+
compilerFilename === options.filename
|
|
2225
|
+
? moduleContext
|
|
2226
|
+
: createCompilerModuleContext({
|
|
2227
|
+
code: options.code,
|
|
2228
|
+
filename: compilerFilename,
|
|
2229
|
+
});
|
|
2202
2230
|
const compiled = transformCompilerModuleContext({
|
|
2203
2231
|
code: options.code,
|
|
2204
2232
|
clientBoundaryImports: options.clientBoundaryImports ?? [],
|
|
2205
|
-
filename:
|
|
2206
|
-
moduleContext,
|
|
2233
|
+
filename: compilerFilename,
|
|
2234
|
+
moduleContext: compilerModuleContext,
|
|
2207
2235
|
target: "client",
|
|
2208
|
-
dev: options.
|
|
2236
|
+
dev: options.debugLabels === true,
|
|
2209
2237
|
});
|
|
2210
2238
|
|
|
2211
2239
|
if (compiled.diagnostics.length > 0) {
|
|
@@ -2238,7 +2266,12 @@ export async function buildClientRouteEntrySource(
|
|
|
2238
2266
|
const routeId = routeIdForPath(options.routePath);
|
|
2239
2267
|
const routeUsesCells = detectRouteCellStateHint(compiled.code);
|
|
2240
2268
|
const routeUsesReactiveEffect = detectRouteReactiveEffectHint(compiled.code);
|
|
2241
|
-
const
|
|
2269
|
+
const routeUsesDomRefs = compiled.metadata.imports.some(
|
|
2270
|
+
(entry) =>
|
|
2271
|
+
entry.source === "@reckona/mreact-reactive-dom" &&
|
|
2272
|
+
entry.specifiers.includes("bindDomRef"),
|
|
2273
|
+
);
|
|
2274
|
+
const routeUsesCleanupScope = routeUsesCells || routeUsesReactiveEffect || routeUsesDomRefs;
|
|
2242
2275
|
const routeExplicitlyRequiresHydration = isExplicitClientRouteSource(
|
|
2243
2276
|
routeSourceAnalysis,
|
|
2244
2277
|
options.filename,
|
|
@@ -2254,6 +2287,7 @@ export async function buildClientRouteEntrySource(
|
|
|
2254
2287
|
routeExplicitlyRequiresHydration ||
|
|
2255
2288
|
routeUsesCells ||
|
|
2256
2289
|
routeUsesReactiveEffect ||
|
|
2290
|
+
routeUsesDomRefs ||
|
|
2257
2291
|
routeHasEventBindings;
|
|
2258
2292
|
const routeUsesOnlyClientReferenceBoundaries =
|
|
2259
2293
|
!routeRequiresFullHydration &&
|
|
@@ -2276,7 +2310,7 @@ export async function buildClientRouteEntrySource(
|
|
|
2276
2310
|
? `import { bindCapturedEvent as __mreactBindCapturedEvent } from "@reckona/mreact-reactive-dom/internal";\n`
|
|
2277
2311
|
: "";
|
|
2278
2312
|
const routeReactiveDomMetadataImport = !routeUsesOnlyClientReferenceBoundaries
|
|
2279
|
-
? `${routeCapturedEventImport}import { withEventBindingMetadata as __mreactWithEventBindingMetadata, withPropBindingMetadata as __mreactWithPropBindingMetadata } from "@reckona/mreact-reactive-dom";\n`
|
|
2313
|
+
? `${routeCapturedEventImport}import { ${routeUsesDomRefs ? "getDomRefBindings as __mreactGetDomRefBindings, " : ""}withEventBindingMetadata as __mreactWithEventBindingMetadata, withPropBindingMetadata as __mreactWithPropBindingMetadata } from "@reckona/mreact-reactive-dom";\n`
|
|
2280
2314
|
: "";
|
|
2281
2315
|
const navigationStateDeclaration = inlineClientNavigation
|
|
2282
2316
|
? `const __mreactNavigationState = __mreactGlobal.__mreactNavigationState ??= {
|
|
@@ -2552,9 +2586,10 @@ __mreactGlobal.__mreactRouteCell = (nativeCell, initial) => {
|
|
|
2552
2586
|
__mreactActiveCellIndex = 0;
|
|
2553
2587
|
}
|
|
2554
2588
|
return () => {
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2589
|
+
__mreactRunLifecycleTasks(
|
|
2590
|
+
Array.from(__mreactRouteEffectDisposers),
|
|
2591
|
+
(__mreactDispose) => __mreactDispose(),
|
|
2592
|
+
);
|
|
2558
2593
|
__mreactRouteEffectDisposers.clear();
|
|
2559
2594
|
};
|
|
2560
2595
|
});
|
|
@@ -2566,13 +2601,33 @@ __mreactGlobal.__mreactRouteCell = (nativeCell, initial) => {
|
|
|
2566
2601
|
? ` __mreactDisposeRoute(__mreactRouteId);
|
|
2567
2602
|
const __mreactRouteEffectDisposers = new Set();
|
|
2568
2603
|
__mreactRouteDisposers.set(__mreactRouteId, () => {
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2604
|
+
__mreactRunLifecycleTasks(
|
|
2605
|
+
Array.from(__mreactRouteEffectDisposers),
|
|
2606
|
+
(__mreactDispose) => __mreactDispose(),
|
|
2607
|
+
);
|
|
2572
2608
|
__mreactRouteEffectDisposers.clear();
|
|
2573
2609
|
});
|
|
2574
2610
|
`
|
|
2575
2611
|
: "";
|
|
2612
|
+
const routeLifecycleFunctions = `
|
|
2613
|
+
function __mreactRunLifecycleTasks(values, run) {
|
|
2614
|
+
let firstError;
|
|
2615
|
+
|
|
2616
|
+
for (const value of values) {
|
|
2617
|
+
try {
|
|
2618
|
+
run(value);
|
|
2619
|
+
} catch (error) {
|
|
2620
|
+
firstError ??= error;
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2623
|
+
|
|
2624
|
+
if (firstError !== undefined) {
|
|
2625
|
+
queueMicrotask(() => {
|
|
2626
|
+
throw firstError;
|
|
2627
|
+
});
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
`;
|
|
2576
2631
|
const routeCellDropFunction = routeUsesCells
|
|
2577
2632
|
? `
|
|
2578
2633
|
function __mreactDropMismatchedRouteState(previousState, nextState) {
|
|
@@ -2598,12 +2653,18 @@ function __mreactDisposeRoute(routeId) {
|
|
|
2598
2653
|
}
|
|
2599
2654
|
`
|
|
2600
2655
|
: "";
|
|
2601
|
-
const routeCleanupNavigationDispose =
|
|
2602
|
-
|
|
2603
|
-
|
|
2656
|
+
const routeCleanupNavigationDispose = ` if (currentRouteId !== nextRouteId) {
|
|
2657
|
+
const __mreactRegisteredRouteDisposers = __mreactGlobal.__mreactRouteDisposers;
|
|
2658
|
+
const __mreactRegisteredRouteDispose = __mreactRegisteredRouteDisposers?.get(currentRouteId);
|
|
2659
|
+
if (__mreactRegisteredRouteDispose !== undefined) {
|
|
2660
|
+
__mreactRegisteredRouteDisposers.delete(currentRouteId);
|
|
2661
|
+
__mreactRunLifecycleTasks(
|
|
2662
|
+
[__mreactRegisteredRouteDispose],
|
|
2663
|
+
(__mreactDispose) => __mreactDispose(),
|
|
2664
|
+
);
|
|
2665
|
+
}
|
|
2604
2666
|
}
|
|
2605
|
-
|
|
2606
|
-
: "";
|
|
2667
|
+
`;
|
|
2607
2668
|
const routeNodeResolver = routeUsesCells
|
|
2608
2669
|
? `
|
|
2609
2670
|
function __mreactResolveRouteNode(value) {
|
|
@@ -2642,9 +2703,7 @@ function __mreactResolveRouteNode(value) {
|
|
|
2642
2703
|
const previousDisposers = current.__mreactEventDisposers;
|
|
2643
2704
|
|
|
2644
2705
|
if (Array.isArray(previousDisposers)) {
|
|
2645
|
-
|
|
2646
|
-
dispose();
|
|
2647
|
-
}
|
|
2706
|
+
__mreactRunLifecycleTasks(previousDisposers, (dispose) => dispose());
|
|
2648
2707
|
}
|
|
2649
2708
|
|
|
2650
2709
|
const rawBindings = next.__mreactEventBindings;
|
|
@@ -2673,14 +2732,26 @@ function __mreactResolveRouteNode(value) {
|
|
|
2673
2732
|
const previousDisposers = current.__mreactEventDisposers;
|
|
2674
2733
|
|
|
2675
2734
|
if (Array.isArray(previousDisposers)) {
|
|
2676
|
-
|
|
2677
|
-
dispose();
|
|
2678
|
-
}
|
|
2735
|
+
__mreactRunLifecycleTasks(previousDisposers, (dispose) => dispose());
|
|
2679
2736
|
}
|
|
2680
2737
|
|
|
2681
2738
|
current.__mreactEventDisposers = [];
|
|
2682
2739
|
current.__mreactHasEvents = false;
|
|
2683
2740
|
}
|
|
2741
|
+
`;
|
|
2742
|
+
const routeDomRefBindingSyncFunction = routeUsesDomRefs
|
|
2743
|
+
? `function __mreactSyncDomRefBindings(current, next) {
|
|
2744
|
+
__mreactRunLifecycleTasks(
|
|
2745
|
+
Array.from(__mreactGetDomRefBindings(current)),
|
|
2746
|
+
(binding) => binding.dispose(),
|
|
2747
|
+
);
|
|
2748
|
+
__mreactRunLifecycleTasks(
|
|
2749
|
+
Array.from(__mreactGetDomRefBindings(next)),
|
|
2750
|
+
(binding) => binding.retarget(current),
|
|
2751
|
+
);
|
|
2752
|
+
}
|
|
2753
|
+
`
|
|
2754
|
+
: `function __mreactSyncDomRefBindings() {}
|
|
2684
2755
|
`;
|
|
2685
2756
|
const boundaryOnlyHydrationBlock = routeRequiresFullHydration
|
|
2686
2757
|
? ""
|
|
@@ -2740,6 +2811,7 @@ ${routeCellHydrationIndent}__mreactMarker.setAttribute(__mreactRouteHydratedAttr
|
|
|
2740
2811
|
${routeCellHydrationIndent}__mreactMarkRouteHydrated();
|
|
2741
2812
|
${routeCellHydrationEnd}}
|
|
2742
2813
|
${routeCellDropFunction}
|
|
2814
|
+
${routeLifecycleFunctions}
|
|
2743
2815
|
${routeCleanupFunction}
|
|
2744
2816
|
|
|
2745
2817
|
function __mreactMarkRouteHydrated() {
|
|
@@ -3327,13 +3399,14 @@ function __mreactApplyNavigationHtml(html, url) {
|
|
|
3327
3399
|
const currentRouteId = currentMarker.getAttribute("${routeHydrationContract.routeMarkerAttribute}");
|
|
3328
3400
|
const nextRouteId = nextMarker.getAttribute("${routeHydrationContract.routeMarkerAttribute}");
|
|
3329
3401
|
|
|
3402
|
+
${routeCleanupNavigationDispose}
|
|
3330
3403
|
__mreactMarkRouteHydrating();
|
|
3331
3404
|
__mreactSyncHeadMetadata(template.content, html);
|
|
3332
3405
|
if (!__mreactApplyNavigationShellHtml(currentMarker, nextMarker)) {
|
|
3333
3406
|
__mreactUnmountCompatBoundaries(currentMarker);
|
|
3334
3407
|
__mreactResumeNode(currentMarker, nextMarker);
|
|
3335
3408
|
}
|
|
3336
|
-
|
|
3409
|
+
__mreactSyncRouteDataScripts(template.content, currentRouteId, nextRouteId);
|
|
3337
3410
|
|
|
3338
3411
|
const script = template.content.querySelector('script[type="module"][src]')?.getAttribute("src");
|
|
3339
3412
|
if (script !== null && script !== undefined) {
|
|
@@ -4491,6 +4564,7 @@ function __mreactResumeNode(current, next) {
|
|
|
4491
4564
|
}
|
|
4492
4565
|
|
|
4493
4566
|
__mreactSyncEventBindings(current, next);
|
|
4567
|
+
__mreactSyncDomRefBindings(current, next);
|
|
4494
4568
|
__mreactSyncAttributes(current, next);
|
|
4495
4569
|
__mreactSyncPropBindings(current, next);
|
|
4496
4570
|
__mreactResumeChildren(current, next);
|
|
@@ -4513,6 +4587,7 @@ function __mreactShouldReplaceNode(current, next) {
|
|
|
4513
4587
|
}
|
|
4514
4588
|
|
|
4515
4589
|
${routeEventBindingSyncFunction}
|
|
4590
|
+
${routeDomRefBindingSyncFunction}
|
|
4516
4591
|
|
|
4517
4592
|
function __mreactSyncAttributes(current, next) {
|
|
4518
4593
|
for (const attribute of Array.from(current.attributes)) {
|
|
@@ -4532,9 +4607,7 @@ function __mreactSyncPropBindings(current, next) {
|
|
|
4532
4607
|
const previousBindings = current.__mreactPropBindings;
|
|
4533
4608
|
|
|
4534
4609
|
if (Array.isArray(previousBindings)) {
|
|
4535
|
-
|
|
4536
|
-
binding.dispose?.();
|
|
4537
|
-
}
|
|
4610
|
+
__mreactRunLifecycleTasks(previousBindings, (binding) => binding.dispose?.());
|
|
4538
4611
|
}
|
|
4539
4612
|
|
|
4540
4613
|
const bindings = next.__mreactPropBindings;
|
|
@@ -4550,9 +4623,7 @@ function __mreactSyncPropBindings(current, next) {
|
|
|
4550
4623
|
next.__mreactPropBindings = [];
|
|
4551
4624
|
next.__mreactHasReactiveProps = false;
|
|
4552
4625
|
|
|
4553
|
-
|
|
4554
|
-
binding.retarget?.(current);
|
|
4555
|
-
}
|
|
4626
|
+
__mreactRunLifecycleTasks(bindings, (binding) => binding.retarget?.(current));
|
|
4556
4627
|
}
|
|
4557
4628
|
|
|
4558
4629
|
function __mreactResumeChildren(current, next) {
|
|
@@ -4605,7 +4676,11 @@ function __mreactResumeChildren(current, next) {
|
|
|
4605
4676
|
};
|
|
4606
4677
|
}
|
|
4607
4678
|
|
|
4608
|
-
function workspaceRuntimePlugin(options: {
|
|
4679
|
+
function workspaceRuntimePlugin(options: {
|
|
4680
|
+
debugLabels: boolean;
|
|
4681
|
+
routeFiles: readonly string[];
|
|
4682
|
+
sourceRegionModulePaths?: Set<string> | undefined;
|
|
4683
|
+
}) {
|
|
4609
4684
|
const routeFiles = new Set(options.routeFiles);
|
|
4610
4685
|
const packageFile = (monorepoDir: string, packageName: string, entry: string): string =>
|
|
4611
4686
|
workspacePackageFile({
|
|
@@ -4733,15 +4808,31 @@ export function invalidateReactiveDevtoolsCache() {}
|
|
|
4733
4808
|
export function prepareReactiveEffectRunDevtoolsEvent() { return undefined; }`,
|
|
4734
4809
|
loader: "ts",
|
|
4735
4810
|
}));
|
|
4811
|
+
if (options.sourceRegionModulePaths !== undefined) {
|
|
4812
|
+
buildApi.onLoad({ filter: /.*/ }, (args) => {
|
|
4813
|
+
if (
|
|
4814
|
+
isAbsolute(args.path) &&
|
|
4815
|
+
isRouteClientDependencySourcePath(args.path, routeFiles) &&
|
|
4816
|
+
!runtimePackageDirs.some(
|
|
4817
|
+
(runtimePackageDir) => args.path.startsWith(`${runtimePackageDir}${sep}`),
|
|
4818
|
+
)
|
|
4819
|
+
) {
|
|
4820
|
+
options.sourceRegionModulePaths?.add(args.path);
|
|
4821
|
+
}
|
|
4822
|
+
|
|
4823
|
+
return undefined;
|
|
4824
|
+
});
|
|
4825
|
+
}
|
|
4736
4826
|
buildApi.onLoad({ filter: /\.(?:mreact\.)?[cm]?[jt]sx$/ }, async (args) => {
|
|
4737
4827
|
if (!isRouteClientDependencySourcePath(args.path, routeFiles)) {
|
|
4738
4828
|
return undefined;
|
|
4739
4829
|
}
|
|
4740
4830
|
|
|
4741
4831
|
const source = await readFile(args.path, "utf8");
|
|
4832
|
+
const compilerFilename = options.debugLabels ? basename(args.path) : args.path;
|
|
4742
4833
|
const moduleContext = createCompilerModuleContext({
|
|
4743
4834
|
code: source,
|
|
4744
|
-
filename:
|
|
4835
|
+
filename: compilerFilename,
|
|
4745
4836
|
});
|
|
4746
4837
|
|
|
4747
4838
|
if (!hasJsxSyntax(moduleContext.program)) {
|
|
@@ -4750,8 +4841,8 @@ export function prepareReactiveEffectRunDevtoolsEvent() { return undefined; }`,
|
|
|
4750
4841
|
|
|
4751
4842
|
const output = transformCompilerModuleContext({
|
|
4752
4843
|
code: source,
|
|
4753
|
-
dev:
|
|
4754
|
-
filename:
|
|
4844
|
+
dev: options.debugLabels,
|
|
4845
|
+
filename: compilerFilename,
|
|
4755
4846
|
mode: isCompatSourcePath(args.path) ? "compat" : "reactive",
|
|
4756
4847
|
moduleContext,
|
|
4757
4848
|
target: "client",
|
package/src/vite.ts
CHANGED
|
@@ -848,6 +848,7 @@ async function renderAppRouterClientRouteDevModule(
|
|
|
848
848
|
clientReferenceImports: references.clientReferenceImports,
|
|
849
849
|
clientReferenceManifest: references.clientReferenceManifest,
|
|
850
850
|
clientNavigation: navigation || detectAnchorElementUsage(clientSource, route.file),
|
|
851
|
+
debugLabels: true,
|
|
851
852
|
filename: route.file,
|
|
852
853
|
routeMayUseOutOfOrderFragments: true,
|
|
853
854
|
routePath: route.path,
|