@reckona/mreact-router 0.0.96 → 0.0.98
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/README.md +4 -0
- package/dist/actions.d.ts +7 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +26 -2
- package/dist/actions.js.map +1 -1
- package/dist/adapters/aws-lambda.d.ts.map +1 -1
- package/dist/adapters/aws-lambda.js +10 -7
- package/dist/adapters/aws-lambda.js.map +1 -1
- package/dist/adapters/static.d.ts.map +1 -1
- package/dist/adapters/static.js +13 -0
- package/dist/adapters/static.js.map +1 -1
- package/dist/build.d.ts +38 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +1093 -307
- package/dist/build.js.map +1 -1
- package/dist/bundle-pipeline.d.ts +7 -0
- package/dist/bundle-pipeline.d.ts.map +1 -1
- package/dist/bundle-pipeline.js +121 -69
- package/dist/bundle-pipeline.js.map +1 -1
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +10 -8
- package/dist/cache.js.map +1 -1
- package/dist/cli-options.d.ts +1 -0
- package/dist/cli-options.d.ts.map +1 -1
- package/dist/cli-options.js +16 -0
- package/dist/cli-options.js.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +6 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +120 -9
- package/dist/client.js.map +1 -1
- package/dist/csrf.d.ts.map +1 -1
- package/dist/csrf.js +7 -3
- package/dist/csrf.js.map +1 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +18 -1
- package/dist/http.js.map +1 -1
- package/dist/import-policy.d.ts.map +1 -1
- package/dist/import-policy.js +7 -3
- package/dist/import-policy.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/link.d.ts +5 -3
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +92 -3
- package/dist/link.js.map +1 -1
- package/dist/logger.d.ts +7 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/module-runner.d.ts +2 -0
- package/dist/module-runner.d.ts.map +1 -1
- package/dist/module-runner.js +1 -0
- package/dist/module-runner.js.map +1 -1
- package/dist/native-route-matcher.d.ts +2 -1
- package/dist/native-route-matcher.d.ts.map +1 -1
- package/dist/native-route-matcher.js +13 -2
- package/dist/native-route-matcher.js.map +1 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +121 -6
- package/dist/render.js.map +1 -1
- package/dist/route-source.d.ts +11 -11
- package/dist/route-source.d.ts.map +1 -1
- package/dist/route-source.js +32 -25
- package/dist/route-source.js.map +1 -1
- package/dist/route-styles.d.ts +6 -0
- package/dist/route-styles.d.ts.map +1 -1
- package/dist/route-styles.js +10 -1
- package/dist/route-styles.js.map +1 -1
- package/dist/serve.d.ts +5 -0
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +7 -4
- package/dist/serve.js.map +1 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +32 -5
- package/dist/vite.js.map +1 -1
- package/package.json +11 -11
- package/src/actions.ts +42 -2
- package/src/adapters/aws-lambda.ts +33 -16
- package/src/adapters/static.ts +25 -0
- package/src/build.ts +1605 -421
- package/src/bundle-pipeline.ts +136 -70
- package/src/cache.ts +13 -8
- package/src/cli-options.ts +20 -0
- package/src/cli.ts +1 -0
- package/src/client.ts +152 -15
- package/src/csrf.ts +8 -3
- package/src/http.ts +21 -1
- package/src/import-policy.ts +8 -3
- package/src/index.ts +5 -0
- package/src/link.ts +135 -8
- package/src/logger.ts +9 -1
- package/src/module-runner.ts +4 -0
- package/src/native-route-matcher.ts +13 -2
- package/src/render.ts +181 -6
- package/src/route-source.ts +33 -20
- package/src/route-styles.ts +17 -1
- package/src/serve.ts +11 -6
- package/src/vite.ts +41 -5
package/dist/client.js
CHANGED
|
@@ -16,6 +16,7 @@ import { escapeHtmlQuotedAttribute as escapeHtmlAttribute } from "@reckona/mreac
|
|
|
16
16
|
import { workspacePackageFile } from "./workspace-packages.js";
|
|
17
17
|
const nodeBuiltinPackages = new Set(builtinModules.flatMap((name) => [name, `node:${name}`]));
|
|
18
18
|
const clientBoundaryInferenceServerOnlyReferenceCode = "MR_CLIENT_BOUNDARY_INFERENCE_SERVER_ONLY_REFERENCE";
|
|
19
|
+
const clientBoundaryInferenceFunctionCallInteractiveCode = "MR_CLIENT_BOUNDARY_INFERENCE_FUNCTION_CALL_INTERACTIVE";
|
|
19
20
|
const clientBoundaryInferenceUnsupportedReferenceCode = "MR_CLIENT_BOUNDARY_INFERENCE_UNSUPPORTED_REFERENCE";
|
|
20
21
|
export async function routeToClientManifestEntry(route) {
|
|
21
22
|
if (route.kind !== "page") {
|
|
@@ -76,7 +77,7 @@ export async function inferClientRouteModule(options) {
|
|
|
76
77
|
}))
|
|
77
78
|
: routeInference;
|
|
78
79
|
if (options.appDir === undefined) {
|
|
79
|
-
return mergedRouteInference;
|
|
80
|
+
return withClientRouteDiagnosticPath(mergedRouteInference, options.routePath);
|
|
80
81
|
}
|
|
81
82
|
const shellInferences = await inferClientRouteShellModules({
|
|
82
83
|
appDir: options.appDir,
|
|
@@ -84,14 +85,14 @@ export async function inferClientRouteModule(options) {
|
|
|
84
85
|
filename: options.filename,
|
|
85
86
|
sourceTransform,
|
|
86
87
|
});
|
|
87
|
-
return {
|
|
88
|
+
return withClientRouteDiagnosticPath({
|
|
88
89
|
client: mergedRouteInference.client || shellInferences.some((inference) => inference.client),
|
|
89
90
|
clientBoundaryImports: mergedRouteInference.clientBoundaryImports,
|
|
90
91
|
diagnostics: [
|
|
91
92
|
...mergedRouteInference.diagnostics,
|
|
92
93
|
...shellInferences.flatMap((inference) => inference.diagnostics),
|
|
93
94
|
],
|
|
94
|
-
};
|
|
95
|
+
}, options.routePath);
|
|
95
96
|
}
|
|
96
97
|
catch (error) {
|
|
97
98
|
throw new Error(`Failed to infer client route for ${options.routePath ?? "<unknown>"} (${options.filename}).\n${errorMessage(error)}`, { cause: error });
|
|
@@ -272,18 +273,26 @@ export async function collectClientRouteReferences(options) {
|
|
|
272
273
|
clientBoundaryImports: routeInference.clientBoundaryImports,
|
|
273
274
|
clientReferenceImports,
|
|
274
275
|
clientReferenceManifest,
|
|
275
|
-
diagnostics: sources
|
|
276
|
+
diagnostics: sources
|
|
277
|
+
.flatMap((source) => source.inference.diagnostics)
|
|
278
|
+
.map((diagnostic) => withClientRouteDiagnosticPath(diagnostic, options.routePath)),
|
|
276
279
|
usesNavigationLink: routeInference.usesNavigationLink ||
|
|
277
280
|
sources.some((source) => source.filename !== options.filename && source.inference.usesNavigationLink),
|
|
278
281
|
};
|
|
279
282
|
}
|
|
280
283
|
export async function resolveNavigationRuntime(options) {
|
|
281
284
|
const cache = options.cache ?? createClientRouteInferenceCache();
|
|
285
|
+
const sourceTransform = clientRouteSourceTransformForVitePlugins(options.vitePlugins);
|
|
286
|
+
const code = await transformClientRouteSource({
|
|
287
|
+
code: options.code,
|
|
288
|
+
filename: options.filename,
|
|
289
|
+
sourceTransform,
|
|
290
|
+
});
|
|
282
291
|
// Read the override from the cached module context so the dev server does not
|
|
283
292
|
// re-parse every page route on each request.
|
|
284
293
|
const moduleContext = await compilerModuleContextForSource({
|
|
285
294
|
cache,
|
|
286
|
-
code
|
|
295
|
+
code,
|
|
287
296
|
filename: options.filename,
|
|
288
297
|
});
|
|
289
298
|
const override = readTopLevelBooleanExportFromContext(moduleContext, "navigationRuntime");
|
|
@@ -489,6 +498,10 @@ async function inferClientRouteModuleSource(options) {
|
|
|
489
498
|
}
|
|
490
499
|
}
|
|
491
500
|
if (renderedByCall && !renderedByJsx) {
|
|
501
|
+
diagnostics.push(functionCallInteractiveImportDiagnostic({
|
|
502
|
+
filename: options.filename,
|
|
503
|
+
reference,
|
|
504
|
+
}));
|
|
492
505
|
continue;
|
|
493
506
|
}
|
|
494
507
|
if (!importedBoundary) {
|
|
@@ -729,6 +742,22 @@ function serverOnlyClientImportReferenceDiagnostic(options) {
|
|
|
729
742
|
source: options.reference.source,
|
|
730
743
|
};
|
|
731
744
|
}
|
|
745
|
+
function functionCallInteractiveImportDiagnostic(options) {
|
|
746
|
+
const localNames = options.reference.localNames.filter(startsUppercase);
|
|
747
|
+
const component = localNames[0] ?? options.reference.localNames[0] ?? options.reference.source;
|
|
748
|
+
const componentUsage = startsUppercase(component) ? `<${component} />` : "JSX";
|
|
749
|
+
return {
|
|
750
|
+
code: clientBoundaryInferenceFunctionCallInteractiveCode,
|
|
751
|
+
filename: options.filename,
|
|
752
|
+
level: "warn",
|
|
753
|
+
localNames: localNames.length === 0 ? options.reference.localNames : localNames,
|
|
754
|
+
message: `${options.filename}: interactive component import ${JSON.stringify(options.reference.source)} ` +
|
|
755
|
+
`is rendered through a function call as ${component}(), so its event handlers or cell() state ` +
|
|
756
|
+
"will not hydrate as a client boundary. Render it through JSX such as " +
|
|
757
|
+
`${componentUsage}, or move the call behind an explicit client boundary.`,
|
|
758
|
+
source: options.reference.source,
|
|
759
|
+
};
|
|
760
|
+
}
|
|
732
761
|
function unsupportedClientImportReferenceDiagnostic(options) {
|
|
733
762
|
if (options.reference.sideEffect) {
|
|
734
763
|
return undefined;
|
|
@@ -756,7 +785,23 @@ function startsUppercase(value) {
|
|
|
756
785
|
return /^[A-Z]/.test(value);
|
|
757
786
|
}
|
|
758
787
|
export function formatClientRouteInferenceDiagnostic(diagnostic) {
|
|
759
|
-
|
|
788
|
+
const route = diagnostic.routePath === undefined ? "" : ` on route ${JSON.stringify(diagnostic.routePath)}`;
|
|
789
|
+
return `${diagnostic.code}: ${diagnostic.message}${route}`;
|
|
790
|
+
}
|
|
791
|
+
function withClientRouteDiagnosticPath(value, routePath) {
|
|
792
|
+
if (routePath === undefined) {
|
|
793
|
+
return value;
|
|
794
|
+
}
|
|
795
|
+
if ("diagnostics" in value) {
|
|
796
|
+
return {
|
|
797
|
+
...value,
|
|
798
|
+
diagnostics: value.diagnostics.map((diagnostic) => withClientRouteDiagnosticPath(diagnostic, routePath)),
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
return {
|
|
802
|
+
...value,
|
|
803
|
+
routePath: value.routePath ?? routePath,
|
|
804
|
+
};
|
|
760
805
|
}
|
|
761
806
|
async function resolveAppLocalModule(options) {
|
|
762
807
|
if (!options.specifier.startsWith(".")) {
|
|
@@ -1015,6 +1060,7 @@ export async function buildClientRouteOutput(options) {
|
|
|
1015
1060
|
const dropConsoleFunctions = options.dropConsoleFunctions ?? resolveClientConsolePureFunctions(options.dropClientConsole);
|
|
1016
1061
|
const bundled = await bundleRouterModule({
|
|
1017
1062
|
code: entry.code,
|
|
1063
|
+
cacheDir: options.cacheDir,
|
|
1018
1064
|
define: {
|
|
1019
1065
|
__MREACT_CLIENT_DEVTOOLS__: "false",
|
|
1020
1066
|
},
|
|
@@ -1046,6 +1092,7 @@ export async function buildClientRouteBatchOutput(options) {
|
|
|
1046
1092
|
})));
|
|
1047
1093
|
const bundled = await bundleRouterModules({
|
|
1048
1094
|
base: options.assetBaseUrl ?? "/_mreact/client/",
|
|
1095
|
+
cacheDir: options.cacheDir,
|
|
1049
1096
|
define: {
|
|
1050
1097
|
__MREACT_CLIENT_DEVTOOLS__: "false",
|
|
1051
1098
|
},
|
|
@@ -1486,6 +1533,10 @@ export async function __mreactPrefetch(url) {
|
|
|
1486
1533
|
return false;
|
|
1487
1534
|
}
|
|
1488
1535
|
|
|
1536
|
+
if (__mreactIsCurrentLocationNavigationHref(href)) {
|
|
1537
|
+
return false;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1489
1540
|
const script = __mreactRouteScriptForNavigationUrl(href);
|
|
1490
1541
|
|
|
1491
1542
|
if (script === undefined) {
|
|
@@ -1505,11 +1556,43 @@ function __mreactPrefetchNavigationHtml(href) {
|
|
|
1505
1556
|
return false;
|
|
1506
1557
|
}
|
|
1507
1558
|
|
|
1508
|
-
|
|
1559
|
+
__mreactRememberNavigationHtml(href, html);
|
|
1509
1560
|
return true;
|
|
1510
1561
|
}).catch(() => false);
|
|
1511
1562
|
}
|
|
1512
1563
|
|
|
1564
|
+
const __mreactNavigationHtmlCacheMaxEntries = 64;
|
|
1565
|
+
|
|
1566
|
+
function __mreactCachedNavigationHtml(href) {
|
|
1567
|
+
const html = __mreactNavigationState.cache.get(href);
|
|
1568
|
+
|
|
1569
|
+
if (html === undefined) {
|
|
1570
|
+
return undefined;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
__mreactNavigationState.cache.delete(href);
|
|
1574
|
+
__mreactNavigationState.cache.set(href, html);
|
|
1575
|
+
return html;
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
function __mreactRememberNavigationHtml(href, html) {
|
|
1579
|
+
if (__mreactNavigationState.cache.has(href)) {
|
|
1580
|
+
__mreactNavigationState.cache.delete(href);
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
__mreactNavigationState.cache.set(href, html);
|
|
1584
|
+
|
|
1585
|
+
while (__mreactNavigationState.cache.size > __mreactNavigationHtmlCacheMaxEntries) {
|
|
1586
|
+
const oldestHref = __mreactNavigationState.cache.keys().next().value;
|
|
1587
|
+
|
|
1588
|
+
if (oldestHref === undefined) {
|
|
1589
|
+
return;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
__mreactNavigationState.cache.delete(oldestHref);
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1513
1596
|
function __mreactPrefetchRouteScript(script) {
|
|
1514
1597
|
if (typeof document === "undefined") {
|
|
1515
1598
|
return false;
|
|
@@ -1550,14 +1633,14 @@ export async function __mreactNavigate(url, options = {}) {
|
|
|
1550
1633
|
__mreactSetNavigationState(__mreactPendingNavigationState(href, options.type ?? "push"));
|
|
1551
1634
|
|
|
1552
1635
|
try {
|
|
1553
|
-
const cachedHtml =
|
|
1636
|
+
const cachedHtml = __mreactCachedNavigationHtml(href);
|
|
1554
1637
|
const html = cachedHtml ?? await __mreactFetchNavigationHtml(href);
|
|
1555
1638
|
|
|
1556
1639
|
if (typeof html !== "string") {
|
|
1557
1640
|
return false;
|
|
1558
1641
|
}
|
|
1559
1642
|
|
|
1560
|
-
|
|
1643
|
+
__mreactRememberNavigationHtml(href, html);
|
|
1561
1644
|
return await __mreactApplyNavigationHtmlWithOptionalTransition(html, href, options);
|
|
1562
1645
|
} finally {
|
|
1563
1646
|
__mreactSetNavigationState(__mreactIdleNavigationState());
|
|
@@ -2223,6 +2306,24 @@ function __mreactIsHashOnlyNavigation(nextUrl) {
|
|
|
2223
2306
|
nextUrl.hash !== location.hash;
|
|
2224
2307
|
}
|
|
2225
2308
|
|
|
2309
|
+
function __mreactIsCurrentLocationNavigationHref(href) {
|
|
2310
|
+
if (typeof location === "undefined") {
|
|
2311
|
+
return false;
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
return __mreactIsCurrentLocationNavigation(new URL(href, location.href));
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
function __mreactIsCurrentLocationNavigation(nextUrl) {
|
|
2318
|
+
if (typeof location === "undefined") {
|
|
2319
|
+
return false;
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
return nextUrl.origin === location.origin &&
|
|
2323
|
+
nextUrl.pathname === location.pathname &&
|
|
2324
|
+
nextUrl.search === location.search;
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2226
2327
|
function __mreactInstallNavigation() {
|
|
2227
2328
|
if (__mreactNavigationState.installed || typeof document === "undefined") {
|
|
2228
2329
|
return;
|
|
@@ -2285,6 +2386,16 @@ function __mreactInstallNavigation() {
|
|
|
2285
2386
|
return;
|
|
2286
2387
|
}
|
|
2287
2388
|
|
|
2389
|
+
if (__mreactIsCurrentLocationNavigation(nextUrl)) {
|
|
2390
|
+
event.preventDefault();
|
|
2391
|
+
|
|
2392
|
+
if (__mreactAnchorScrollMode(anchor) !== false && nextUrl.hash === "") {
|
|
2393
|
+
__mreactScrollTo(0, 0);
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
return;
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2288
2399
|
event.preventDefault();
|
|
2289
2400
|
void __mreactNavigate(nextUrl.href, {
|
|
2290
2401
|
scroll: __mreactAnchorScrollMode(anchor),
|