@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/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, extname, join, relative, sep } from "node:path";
|
|
4
|
+
import { basename, dirname, extname, isAbsolute, join, relative, sep } from "node:path";
|
|
5
5
|
import { analyzeBoundaryGraph, collectClientRouteModuleAnalysis, formatDiagnostic, } from "@reckona/mreact-compiler";
|
|
6
6
|
import { collectClientRouteModuleAnalysisFromContext, createCompilerModuleContext, hasUnguardedBrowserGlobalReference, readTopLevelBooleanExport, readTopLevelBooleanExportFromContext, stripTypeScriptWithOxc, transformCompilerModuleContext, } from "@reckona/mreact-compiler/internal";
|
|
7
7
|
import { assetPath } from "./assets.js";
|
|
@@ -1318,6 +1318,12 @@ export async function buildNavigationRuntimeBundle(options = {}) {
|
|
|
1318
1318
|
export async function buildClientRouteOutput(options) {
|
|
1319
1319
|
const entry = await buildClientRouteEntrySource(options);
|
|
1320
1320
|
const dropConsoleFunctions = options.dropConsoleFunctions ?? resolveClientConsolePureFunctions(options.dropClientConsole);
|
|
1321
|
+
const sourceRegionModulePaths = options.debugLabels === true ? undefined : new Set([options.filename]);
|
|
1322
|
+
const runtimePlugin = workspaceRuntimePlugin({
|
|
1323
|
+
debugLabels: options.debugLabels === true,
|
|
1324
|
+
routeFiles: [options.filename],
|
|
1325
|
+
sourceRegionModulePaths,
|
|
1326
|
+
});
|
|
1321
1327
|
const bundled = await bundleRouterModule({
|
|
1322
1328
|
code: entry.code,
|
|
1323
1329
|
cacheDir: options.cacheDir,
|
|
@@ -1329,7 +1335,8 @@ export async function buildClientRouteOutput(options) {
|
|
|
1329
1335
|
minify: options.minify === true,
|
|
1330
1336
|
platform: "browser",
|
|
1331
1337
|
preserveExports: true,
|
|
1332
|
-
|
|
1338
|
+
sourceRegionModulePaths,
|
|
1339
|
+
plugins: [runtimePlugin],
|
|
1333
1340
|
sourceMap: options.sourceMap,
|
|
1334
1341
|
vitePlugins: options.vitePlugins,
|
|
1335
1342
|
});
|
|
@@ -1350,6 +1357,15 @@ export async function buildClientRouteBatchOutput(options) {
|
|
|
1350
1357
|
vitePlugins: options.vitePlugins ?? route.vitePlugins,
|
|
1351
1358
|
}),
|
|
1352
1359
|
})));
|
|
1360
|
+
const debugLabels = options.routes.some((route) => route.debugLabels === true);
|
|
1361
|
+
const sourceRegionModulePaths = debugLabels
|
|
1362
|
+
? undefined
|
|
1363
|
+
: new Set(entries.map((entry) => entry.filename));
|
|
1364
|
+
const runtimePlugin = workspaceRuntimePlugin({
|
|
1365
|
+
debugLabels,
|
|
1366
|
+
routeFiles: entries.map((entry) => entry.filename),
|
|
1367
|
+
sourceRegionModulePaths,
|
|
1368
|
+
});
|
|
1353
1369
|
const bundled = await bundleRouterModules({
|
|
1354
1370
|
base: options.assetBaseUrl ?? "/_mreact/client/",
|
|
1355
1371
|
cacheDir: options.cacheDir,
|
|
@@ -1363,7 +1379,8 @@ export async function buildClientRouteBatchOutput(options) {
|
|
|
1363
1379
|
})),
|
|
1364
1380
|
minify: options.minify === true,
|
|
1365
1381
|
platform: "browser",
|
|
1366
|
-
|
|
1382
|
+
sourceRegionModulePaths,
|
|
1383
|
+
plugins: [runtimePlugin],
|
|
1367
1384
|
root: options.projectRoot,
|
|
1368
1385
|
sourceMap: options.sourceMap,
|
|
1369
1386
|
dropConsoleFunctions: options.dropConsoleFunctions,
|
|
@@ -1392,13 +1409,20 @@ export async function buildClientRouteEntrySource(options) {
|
|
|
1392
1409
|
filename: options.filename,
|
|
1393
1410
|
});
|
|
1394
1411
|
const routeSourceAnalysis = collectClientRouteModuleAnalysisFromContext(moduleContext);
|
|
1412
|
+
const compilerFilename = options.debugLabels === true ? basename(options.filename) : options.filename;
|
|
1413
|
+
const compilerModuleContext = compilerFilename === options.filename
|
|
1414
|
+
? moduleContext
|
|
1415
|
+
: createCompilerModuleContext({
|
|
1416
|
+
code: options.code,
|
|
1417
|
+
filename: compilerFilename,
|
|
1418
|
+
});
|
|
1395
1419
|
const compiled = transformCompilerModuleContext({
|
|
1396
1420
|
code: options.code,
|
|
1397
1421
|
clientBoundaryImports: options.clientBoundaryImports ?? [],
|
|
1398
|
-
filename:
|
|
1399
|
-
moduleContext,
|
|
1422
|
+
filename: compilerFilename,
|
|
1423
|
+
moduleContext: compilerModuleContext,
|
|
1400
1424
|
target: "client",
|
|
1401
|
-
dev: options.
|
|
1425
|
+
dev: options.debugLabels === true,
|
|
1402
1426
|
});
|
|
1403
1427
|
if (compiled.diagnostics.length > 0) {
|
|
1404
1428
|
throw new Error(compiled.diagnostics
|
|
@@ -1416,7 +1440,9 @@ export async function buildClientRouteEntrySource(options) {
|
|
|
1416
1440
|
const routeId = routeIdForPath(options.routePath);
|
|
1417
1441
|
const routeUsesCells = detectRouteCellStateHint(compiled.code);
|
|
1418
1442
|
const routeUsesReactiveEffect = detectRouteReactiveEffectHint(compiled.code);
|
|
1419
|
-
const
|
|
1443
|
+
const routeUsesDomRefs = compiled.metadata.imports.some((entry) => entry.source === "@reckona/mreact-reactive-dom" &&
|
|
1444
|
+
entry.specifiers.includes("bindDomRef"));
|
|
1445
|
+
const routeUsesCleanupScope = routeUsesCells || routeUsesReactiveEffect || routeUsesDomRefs;
|
|
1420
1446
|
const routeExplicitlyRequiresHydration = isExplicitClientRouteSource(routeSourceAnalysis, options.filename);
|
|
1421
1447
|
const routeHasEventBindings = (compiled.metadata.eventHydrationManifest?.events.length ?? 0) > 0;
|
|
1422
1448
|
const routeCapturesEventBindings = compiled.code.includes("__mreactEventBindings");
|
|
@@ -1427,6 +1453,7 @@ export async function buildClientRouteEntrySource(options) {
|
|
|
1427
1453
|
const routeRequiresFullHydration = routeExplicitlyRequiresHydration ||
|
|
1428
1454
|
routeUsesCells ||
|
|
1429
1455
|
routeUsesReactiveEffect ||
|
|
1456
|
+
routeUsesDomRefs ||
|
|
1430
1457
|
routeHasEventBindings;
|
|
1431
1458
|
const routeUsesOnlyClientReferenceBoundaries = !routeRequiresFullHydration &&
|
|
1432
1459
|
clientReferenceManifest.length > 0 &&
|
|
@@ -1447,7 +1474,7 @@ export async function buildClientRouteEntrySource(options) {
|
|
|
1447
1474
|
? `import { bindCapturedEvent as __mreactBindCapturedEvent } from "@reckona/mreact-reactive-dom/internal";\n`
|
|
1448
1475
|
: "";
|
|
1449
1476
|
const routeReactiveDomMetadataImport = !routeUsesOnlyClientReferenceBoundaries
|
|
1450
|
-
? `${routeCapturedEventImport}import { withEventBindingMetadata as __mreactWithEventBindingMetadata, withPropBindingMetadata as __mreactWithPropBindingMetadata } from "@reckona/mreact-reactive-dom";\n`
|
|
1477
|
+
? `${routeCapturedEventImport}import { ${routeUsesDomRefs ? "getDomRefBindings as __mreactGetDomRefBindings, " : ""}withEventBindingMetadata as __mreactWithEventBindingMetadata, withPropBindingMetadata as __mreactWithPropBindingMetadata } from "@reckona/mreact-reactive-dom";\n`
|
|
1451
1478
|
: "";
|
|
1452
1479
|
const navigationStateDeclaration = inlineClientNavigation
|
|
1453
1480
|
? `const __mreactNavigationState = __mreactGlobal.__mreactNavigationState ??= {
|
|
@@ -1723,9 +1750,10 @@ __mreactGlobal.__mreactRouteCell = (nativeCell, initial) => {
|
|
|
1723
1750
|
__mreactActiveCellIndex = 0;
|
|
1724
1751
|
}
|
|
1725
1752
|
return () => {
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1753
|
+
__mreactRunLifecycleTasks(
|
|
1754
|
+
Array.from(__mreactRouteEffectDisposers),
|
|
1755
|
+
(__mreactDispose) => __mreactDispose(),
|
|
1756
|
+
);
|
|
1729
1757
|
__mreactRouteEffectDisposers.clear();
|
|
1730
1758
|
};
|
|
1731
1759
|
});
|
|
@@ -1736,13 +1764,33 @@ __mreactGlobal.__mreactRouteCell = (nativeCell, initial) => {
|
|
|
1736
1764
|
? ` __mreactDisposeRoute(__mreactRouteId);
|
|
1737
1765
|
const __mreactRouteEffectDisposers = new Set();
|
|
1738
1766
|
__mreactRouteDisposers.set(__mreactRouteId, () => {
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1767
|
+
__mreactRunLifecycleTasks(
|
|
1768
|
+
Array.from(__mreactRouteEffectDisposers),
|
|
1769
|
+
(__mreactDispose) => __mreactDispose(),
|
|
1770
|
+
);
|
|
1742
1771
|
__mreactRouteEffectDisposers.clear();
|
|
1743
1772
|
});
|
|
1744
1773
|
`
|
|
1745
1774
|
: "";
|
|
1775
|
+
const routeLifecycleFunctions = `
|
|
1776
|
+
function __mreactRunLifecycleTasks(values, run) {
|
|
1777
|
+
let firstError;
|
|
1778
|
+
|
|
1779
|
+
for (const value of values) {
|
|
1780
|
+
try {
|
|
1781
|
+
run(value);
|
|
1782
|
+
} catch (error) {
|
|
1783
|
+
firstError ??= error;
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
if (firstError !== undefined) {
|
|
1788
|
+
queueMicrotask(() => {
|
|
1789
|
+
throw firstError;
|
|
1790
|
+
});
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
`;
|
|
1746
1794
|
const routeCellDropFunction = routeUsesCells
|
|
1747
1795
|
? `
|
|
1748
1796
|
function __mreactDropMismatchedRouteState(previousState, nextState) {
|
|
@@ -1768,12 +1816,18 @@ function __mreactDisposeRoute(routeId) {
|
|
|
1768
1816
|
}
|
|
1769
1817
|
`
|
|
1770
1818
|
: "";
|
|
1771
|
-
const routeCleanupNavigationDispose =
|
|
1772
|
-
|
|
1773
|
-
|
|
1819
|
+
const routeCleanupNavigationDispose = ` if (currentRouteId !== nextRouteId) {
|
|
1820
|
+
const __mreactRegisteredRouteDisposers = __mreactGlobal.__mreactRouteDisposers;
|
|
1821
|
+
const __mreactRegisteredRouteDispose = __mreactRegisteredRouteDisposers?.get(currentRouteId);
|
|
1822
|
+
if (__mreactRegisteredRouteDispose !== undefined) {
|
|
1823
|
+
__mreactRegisteredRouteDisposers.delete(currentRouteId);
|
|
1824
|
+
__mreactRunLifecycleTasks(
|
|
1825
|
+
[__mreactRegisteredRouteDispose],
|
|
1826
|
+
(__mreactDispose) => __mreactDispose(),
|
|
1827
|
+
);
|
|
1828
|
+
}
|
|
1774
1829
|
}
|
|
1775
|
-
|
|
1776
|
-
: "";
|
|
1830
|
+
`;
|
|
1777
1831
|
const routeNodeResolver = routeUsesCells
|
|
1778
1832
|
? `
|
|
1779
1833
|
function __mreactResolveRouteNode(value) {
|
|
@@ -1812,9 +1866,7 @@ function __mreactResolveRouteNode(value) {
|
|
|
1812
1866
|
const previousDisposers = current.__mreactEventDisposers;
|
|
1813
1867
|
|
|
1814
1868
|
if (Array.isArray(previousDisposers)) {
|
|
1815
|
-
|
|
1816
|
-
dispose();
|
|
1817
|
-
}
|
|
1869
|
+
__mreactRunLifecycleTasks(previousDisposers, (dispose) => dispose());
|
|
1818
1870
|
}
|
|
1819
1871
|
|
|
1820
1872
|
const rawBindings = next.__mreactEventBindings;
|
|
@@ -1843,14 +1895,26 @@ function __mreactResolveRouteNode(value) {
|
|
|
1843
1895
|
const previousDisposers = current.__mreactEventDisposers;
|
|
1844
1896
|
|
|
1845
1897
|
if (Array.isArray(previousDisposers)) {
|
|
1846
|
-
|
|
1847
|
-
dispose();
|
|
1848
|
-
}
|
|
1898
|
+
__mreactRunLifecycleTasks(previousDisposers, (dispose) => dispose());
|
|
1849
1899
|
}
|
|
1850
1900
|
|
|
1851
1901
|
current.__mreactEventDisposers = [];
|
|
1852
1902
|
current.__mreactHasEvents = false;
|
|
1853
1903
|
}
|
|
1904
|
+
`;
|
|
1905
|
+
const routeDomRefBindingSyncFunction = routeUsesDomRefs
|
|
1906
|
+
? `function __mreactSyncDomRefBindings(current, next) {
|
|
1907
|
+
__mreactRunLifecycleTasks(
|
|
1908
|
+
Array.from(__mreactGetDomRefBindings(current)),
|
|
1909
|
+
(binding) => binding.dispose(),
|
|
1910
|
+
);
|
|
1911
|
+
__mreactRunLifecycleTasks(
|
|
1912
|
+
Array.from(__mreactGetDomRefBindings(next)),
|
|
1913
|
+
(binding) => binding.retarget(current),
|
|
1914
|
+
);
|
|
1915
|
+
}
|
|
1916
|
+
`
|
|
1917
|
+
: `function __mreactSyncDomRefBindings() {}
|
|
1854
1918
|
`;
|
|
1855
1919
|
const boundaryOnlyHydrationBlock = routeRequiresFullHydration
|
|
1856
1920
|
? ""
|
|
@@ -1909,6 +1973,7 @@ ${routeCellHydrationIndent}__mreactMarker.setAttribute(__mreactRouteHydratedAttr
|
|
|
1909
1973
|
${routeCellHydrationIndent}__mreactMarkRouteHydrated();
|
|
1910
1974
|
${routeCellHydrationEnd}}
|
|
1911
1975
|
${routeCellDropFunction}
|
|
1976
|
+
${routeLifecycleFunctions}
|
|
1912
1977
|
${routeCleanupFunction}
|
|
1913
1978
|
|
|
1914
1979
|
function __mreactMarkRouteHydrated() {
|
|
@@ -2495,13 +2560,14 @@ function __mreactApplyNavigationHtml(html, url) {
|
|
|
2495
2560
|
const currentRouteId = currentMarker.getAttribute("${routeHydrationContract.routeMarkerAttribute}");
|
|
2496
2561
|
const nextRouteId = nextMarker.getAttribute("${routeHydrationContract.routeMarkerAttribute}");
|
|
2497
2562
|
|
|
2563
|
+
${routeCleanupNavigationDispose}
|
|
2498
2564
|
__mreactMarkRouteHydrating();
|
|
2499
2565
|
__mreactSyncHeadMetadata(template.content, html);
|
|
2500
2566
|
if (!__mreactApplyNavigationShellHtml(currentMarker, nextMarker)) {
|
|
2501
2567
|
__mreactUnmountCompatBoundaries(currentMarker);
|
|
2502
2568
|
__mreactResumeNode(currentMarker, nextMarker);
|
|
2503
2569
|
}
|
|
2504
|
-
|
|
2570
|
+
__mreactSyncRouteDataScripts(template.content, currentRouteId, nextRouteId);
|
|
2505
2571
|
|
|
2506
2572
|
const script = template.content.querySelector('script[type="module"][src]')?.getAttribute("src");
|
|
2507
2573
|
if (script !== null && script !== undefined) {
|
|
@@ -3658,6 +3724,7 @@ function __mreactResumeNode(current, next) {
|
|
|
3658
3724
|
}
|
|
3659
3725
|
|
|
3660
3726
|
__mreactSyncEventBindings(current, next);
|
|
3727
|
+
__mreactSyncDomRefBindings(current, next);
|
|
3661
3728
|
__mreactSyncAttributes(current, next);
|
|
3662
3729
|
__mreactSyncPropBindings(current, next);
|
|
3663
3730
|
__mreactResumeChildren(current, next);
|
|
@@ -3680,6 +3747,7 @@ function __mreactShouldReplaceNode(current, next) {
|
|
|
3680
3747
|
}
|
|
3681
3748
|
|
|
3682
3749
|
${routeEventBindingSyncFunction}
|
|
3750
|
+
${routeDomRefBindingSyncFunction}
|
|
3683
3751
|
|
|
3684
3752
|
function __mreactSyncAttributes(current, next) {
|
|
3685
3753
|
for (const attribute of Array.from(current.attributes)) {
|
|
@@ -3699,9 +3767,7 @@ function __mreactSyncPropBindings(current, next) {
|
|
|
3699
3767
|
const previousBindings = current.__mreactPropBindings;
|
|
3700
3768
|
|
|
3701
3769
|
if (Array.isArray(previousBindings)) {
|
|
3702
|
-
|
|
3703
|
-
binding.dispose?.();
|
|
3704
|
-
}
|
|
3770
|
+
__mreactRunLifecycleTasks(previousBindings, (binding) => binding.dispose?.());
|
|
3705
3771
|
}
|
|
3706
3772
|
|
|
3707
3773
|
const bindings = next.__mreactPropBindings;
|
|
@@ -3717,9 +3783,7 @@ function __mreactSyncPropBindings(current, next) {
|
|
|
3717
3783
|
next.__mreactPropBindings = [];
|
|
3718
3784
|
next.__mreactHasReactiveProps = false;
|
|
3719
3785
|
|
|
3720
|
-
|
|
3721
|
-
binding.retarget?.(current);
|
|
3722
|
-
}
|
|
3786
|
+
__mreactRunLifecycleTasks(bindings, (binding) => binding.retarget?.(current));
|
|
3723
3787
|
}
|
|
3724
3788
|
|
|
3725
3789
|
function __mreactResumeChildren(current, next) {
|
|
@@ -3885,22 +3949,33 @@ export function invalidateReactiveDevtoolsCache() {}
|
|
|
3885
3949
|
export function prepareReactiveEffectRunDevtoolsEvent() { return undefined; }`,
|
|
3886
3950
|
loader: "ts",
|
|
3887
3951
|
}));
|
|
3952
|
+
if (options.sourceRegionModulePaths !== undefined) {
|
|
3953
|
+
buildApi.onLoad({ filter: /.*/ }, (args) => {
|
|
3954
|
+
if (isAbsolute(args.path) &&
|
|
3955
|
+
isRouteClientDependencySourcePath(args.path, routeFiles) &&
|
|
3956
|
+
!runtimePackageDirs.some((runtimePackageDir) => args.path.startsWith(`${runtimePackageDir}${sep}`))) {
|
|
3957
|
+
options.sourceRegionModulePaths?.add(args.path);
|
|
3958
|
+
}
|
|
3959
|
+
return undefined;
|
|
3960
|
+
});
|
|
3961
|
+
}
|
|
3888
3962
|
buildApi.onLoad({ filter: /\.(?:mreact\.)?[cm]?[jt]sx$/ }, async (args) => {
|
|
3889
3963
|
if (!isRouteClientDependencySourcePath(args.path, routeFiles)) {
|
|
3890
3964
|
return undefined;
|
|
3891
3965
|
}
|
|
3892
3966
|
const source = await readFile(args.path, "utf8");
|
|
3967
|
+
const compilerFilename = options.debugLabels ? basename(args.path) : args.path;
|
|
3893
3968
|
const moduleContext = createCompilerModuleContext({
|
|
3894
3969
|
code: source,
|
|
3895
|
-
filename:
|
|
3970
|
+
filename: compilerFilename,
|
|
3896
3971
|
});
|
|
3897
3972
|
if (!hasJsxSyntax(moduleContext.program)) {
|
|
3898
3973
|
return undefined;
|
|
3899
3974
|
}
|
|
3900
3975
|
const output = transformCompilerModuleContext({
|
|
3901
3976
|
code: source,
|
|
3902
|
-
dev:
|
|
3903
|
-
filename:
|
|
3977
|
+
dev: options.debugLabels,
|
|
3978
|
+
filename: compilerFilename,
|
|
3904
3979
|
mode: isCompatSourcePath(args.path) ? "compat" : "reactive",
|
|
3905
3980
|
moduleContext,
|
|
3906
3981
|
target: "client",
|