@markless/router 0.6.0 → 0.7.0
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/{create-server-entry-DaYssO9x.js → create-server-entry-yboa-2m6.js} +5 -3
- package/dist/index.js +1 -1
- package/dist/{request-locals-z3rJTizs.js → request-locals-BDAhNpEa.js} +5 -1
- package/dist/vite/runtime/create-server-entry.js +1 -1
- package/dist/vite/runtime/mdx-route.js +60 -1
- package/dist/vite.js +37 -5
- package/package.json +4 -4
- package/src/vite/entries/fragment-entry.ts +7 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ROUTE_SCRIPT_TYPE, c as
|
|
1
|
+
import { a as ROUTE_SCRIPT_TYPE, c as servedHtmlAttributesScript, d as REPLACE_ATTRIBUTE, f as SCROLL_ATTRIBUTE, i as HTML_ATTRIBUTES_SLOT, l as LINK_ATTRIBUTE, n as requestLocals, o as SERVED_HTML_ATTRIBUTES_PROPERTY, r as takeMiddlewareHeaders, u as PREFETCH_ATTRIBUTE } from "./request-locals-BDAhNpEa.js";
|
|
2
2
|
import { i as matchRouteManifest, n as buildRouteManifestFromFileIds, o as normalizeRouteFileId } from "./route-manifest-DMizh42B.js";
|
|
3
3
|
import { n as __marklessDebugBootstrapSource } from "./debug-channel-Di6SppZv.js";
|
|
4
4
|
import { CONTAINER_ATTRIBUTE, PROTOCOL_CONTAINER_END_COMMENT, PROTOCOL_CONTAINER_START_COMMENT, PROTOCOL_LOCATOR_PATHS_ATTRIBUTE } from "@markless/web/fns/container-region";
|
|
@@ -864,16 +864,17 @@ function createServerEntry(options) {
|
|
|
864
864
|
resumeModuleUrl: options.resumeEntryPath ?? baseArtifact?.resumeModuleUrl,
|
|
865
865
|
modulePreloads: (html, resumes) => landingModulePreloads(resumes ? options.routeSsrModulePreloads?.[file] : void 0, linkBridges?.[html.includes("href=\"#/") ? 1 : 0])
|
|
866
866
|
};
|
|
867
|
+
const headStart = (documentLoads && fragmentNavigation && !fragment ? servedHtmlAttributesScript() : "") + (options.importMap ?? "");
|
|
867
868
|
if (options.render === "blocking") {
|
|
868
869
|
const pageHtml = splitPageHtml(await renderToString(routedArtifact, renderOptions));
|
|
869
870
|
privateToVisitor();
|
|
870
|
-
const shell = await renderDocumentShell(documentModule, pageProps, pageHtml.headHtml,
|
|
871
|
+
const shell = await renderDocumentShell(documentModule, pageProps, pageHtml.headHtml, headStart);
|
|
871
872
|
return new Response(wholeDocument(shell, pageHtml, fragment, documentLoads), http.commit(status, headers));
|
|
872
873
|
}
|
|
873
874
|
const stream = await renderToStream(routedArtifact, renderOptions);
|
|
874
875
|
privateToVisitor();
|
|
875
876
|
const pageHtml = splitPageHtml(stream.shell);
|
|
876
|
-
const shell = await renderDocumentShell(documentModule, pageProps, pageHtml.headHtml,
|
|
877
|
+
const shell = await renderDocumentShell(documentModule, pageProps, pageHtml.headHtml, headStart);
|
|
877
878
|
if (stream.pendingArmCount === 0) return new Response(wholeDocument(shell, pageHtml, fragment, documentLoads), http.commit(status, headers));
|
|
878
879
|
const placed = placePage(shell, DOCUMENT_CHILDREN_PLACEHOLDER, pageHtml);
|
|
879
880
|
const prefix = fragment ? fragmentDocument(shell, pageHtml, documentLoads) + FRAGMENT_REGION_END : placed.prefix;
|
|
@@ -1269,6 +1270,7 @@ function fragmentConfig(fragment, documentLoads) {
|
|
|
1269
1270
|
replaceAttribute: REPLACE_ATTRIBUTE,
|
|
1270
1271
|
scrollAttribute: SCROLL_ATTRIBUTE,
|
|
1271
1272
|
routeScriptType: ROUTE_SCRIPT_TYPE,
|
|
1273
|
+
servedHtmlAttributesProperty: SERVED_HTML_ATTRIBUTES_PROPERTY,
|
|
1272
1274
|
retireProperty: CONTAINER_RETIRE_PROPERTY,
|
|
1273
1275
|
streamExecutorGlobal: STREAM_ARM_EXECUTOR_GLOBAL,
|
|
1274
1276
|
streamedArmSelector: STREAMED_ARM_SELECTOR,
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as REPLACE_ATTRIBUTE, f as SCROLL_ATTRIBUTE, i as HTML_ATTRIBUTES_SLOT, l as LINK_ATTRIBUTE, s as routeMountTarget, t as rememberRequestLocals, u as PREFETCH_ATTRIBUTE } from "./request-locals-BDAhNpEa.js";
|
|
2
2
|
import { a as normalizeRequestPathname, c as parseRequestFile, i as matchRouteManifest, l as transformRequestFileSource, n as buildRouteManifestFromFileIds, o as normalizeRouteFileId, s as normalizeRequestFileId } from "./route-manifest-DMizh42B.js";
|
|
3
3
|
import { createExternalDelegateStructureTokens, createExternalDelegateView } from "@markless/web/fns/external-delegate";
|
|
4
4
|
import { render } from "@markless/web/render";
|
|
@@ -8,6 +8,10 @@ const PREFETCH_ATTRIBUTE = "data-markless-router-prefetch";
|
|
|
8
8
|
//#region src/route-dom.ts
|
|
9
9
|
const ROUTE_SCRIPT_TYPE = "@markless/core/route";
|
|
10
10
|
const HTML_ATTRIBUTES_SLOT = "__marklessRouterHtmlAttributes";
|
|
11
|
+
const SERVED_HTML_ATTRIBUTES_PROPERTY = "__marklessServedHtmlAttributes";
|
|
12
|
+
function servedHtmlAttributesScript() {
|
|
13
|
+
return `<script>document.documentElement.${SERVED_HTML_ATTRIBUTES_PROPERTY}=document.documentElement.getAttributeNames()<\/script>`;
|
|
14
|
+
}
|
|
11
15
|
function routeMountTarget(document, currentRoot) {
|
|
12
16
|
const root = currentRoot ?? document.querySelector(`script[type="@markless/core/route"]`)?.parentElement;
|
|
13
17
|
if (!root) return document.body;
|
|
@@ -87,4 +91,4 @@ function takeMiddlewareHeaders(request) {
|
|
|
87
91
|
return record.taken;
|
|
88
92
|
}
|
|
89
93
|
//#endregion
|
|
90
|
-
export { ROUTE_SCRIPT_TYPE as a,
|
|
94
|
+
export { ROUTE_SCRIPT_TYPE as a, servedHtmlAttributesScript as c, REPLACE_ATTRIBUTE as d, SCROLL_ATTRIBUTE as f, HTML_ATTRIBUTES_SLOT as i, LINK_ATTRIBUTE as l, requestLocals as n, SERVED_HTML_ATTRIBUTES_PROPERTY as o, takeMiddlewareHeaders as r, routeMountTarget as s, rememberRequestLocals as t, PREFETCH_ATTRIBUTE as u };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as routerLinkBridgeModules, t as createServerEntry } from "../../create-server-entry-
|
|
1
|
+
import { n as routerLinkBridgeModules, t as createServerEntry } from "../../create-server-entry-yboa-2m6.js";
|
|
2
2
|
export { createServerEntry, routerLinkBridgeModules };
|
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
import { i as protocolStateVersion, n as protocolInstanceQualifies, t as protocolInstancePath } from "../../protocol-constants-B4WxrZAS.js";
|
|
2
2
|
//#endregion
|
|
3
|
+
//#region ../serializer/src/protocol-record-keys.ts
|
|
4
|
+
/** The field names each templated record list may spell, in the order its templates index them. */
|
|
5
|
+
const PROTOCOL_RECORD_KEYS = {
|
|
6
|
+
"markless/state": {
|
|
7
|
+
computed: "graphNodeId name async deriveSymbolId value version root $type $ref source flags records id type fields items entries values bytes arrayType buffer byteOffset length byteLength directValue dependencies path snapshot status key error",
|
|
8
|
+
sharedSeeds: "graphNodeId deriveSymbolId dependencies path reads",
|
|
9
|
+
sharedDefinitions: "id name exportedName scope version graphNodeIds projectionIds dependencies definitionId definitionName returnProperties kind graphNodeId path"
|
|
10
|
+
},
|
|
11
|
+
"markless/view": {
|
|
12
|
+
domUpdates: "hostNodeId source graphNodeId path target kind prefix suffix trueValue falseValue textNode name constantClass leadingClass symbolId",
|
|
13
|
+
behaviors: "hostNodeId source functionSource inputSources inputValues inputGraphReads inputIndex graphNodeId path symbolId usesGraph",
|
|
14
|
+
elementHandles: "hostNodeId handleId name plural"
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region ../serializer/src/protocol-templated-lists.ts
|
|
19
|
+
/**
|
|
20
|
+
* The record lists a payload script may serve as record templates instead of a plain array. The
|
|
21
|
+
* inline resumer reads the others at page load, before any decoder has loaded, so they stay plain.
|
|
22
|
+
*/
|
|
23
|
+
const PROTOCOL_TEMPLATED_LISTS = {
|
|
24
|
+
"markless/state": [
|
|
25
|
+
"computed",
|
|
26
|
+
"sharedSeeds",
|
|
27
|
+
"sharedDefinitions"
|
|
28
|
+
],
|
|
29
|
+
"markless/view": [
|
|
30
|
+
"domUpdates",
|
|
31
|
+
"behaviors",
|
|
32
|
+
"elementHandles"
|
|
33
|
+
]
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region ../serializer/src/protocol-record-templates.ts
|
|
37
|
+
function expandRecordTemplates(list, keys = "") {
|
|
38
|
+
if (Array.isArray(list)) return list;
|
|
39
|
+
const { t, r } = list;
|
|
40
|
+
const names = keys.split(" ");
|
|
41
|
+
const parts = t.map((text) => text.replace(/~(\d+):/g, (_, at) => `"${names[+at]}":`).split(/\^(\d+)/));
|
|
42
|
+
return r.map((ref) => {
|
|
43
|
+
if (typeof ref === "number") return JSON.parse(parts[ref][0]);
|
|
44
|
+
if (!Array.isArray(ref)) return ref;
|
|
45
|
+
const part = parts[ref[0]];
|
|
46
|
+
let text = part[0];
|
|
47
|
+
for (let at = 1; at < part.length; at += 2) text += ref[+part[at] + 1] + part[at + 1];
|
|
48
|
+
return JSON.parse(text);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** Expands, in place, every templated list of a freshly parsed payload script. */
|
|
52
|
+
function decodeProtocolPayloadLists(type, payload) {
|
|
53
|
+
const record = payload;
|
|
54
|
+
const keys = PROTOCOL_RECORD_KEYS[type];
|
|
55
|
+
if (record) for (const key of PROTOCOL_TEMPLATED_LISTS[type]) {
|
|
56
|
+
const list = record[key];
|
|
57
|
+
if (list && !Array.isArray(list)) record[key] = expandRecordTemplates(list, keys[key]);
|
|
58
|
+
}
|
|
59
|
+
return payload;
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
3
62
|
//#region ../serializer/src/storage-cookie.ts
|
|
4
63
|
const STORAGE_RENDER_CONTEXT_READER = "storageValue";
|
|
5
64
|
//#endregion
|
|
@@ -747,7 +806,7 @@ function locate(root, view, host) {
|
|
|
747
806
|
}
|
|
748
807
|
function readScript(root, type) {
|
|
749
808
|
const text = root.querySelector(`script[type="${type}"]`)?.textContent;
|
|
750
|
-
return text ? JSON.parse(text) : void 0;
|
|
809
|
+
return text ? decodeProtocolPayloadLists(type, JSON.parse(text)) : void 0;
|
|
751
810
|
}
|
|
752
811
|
function references(value, id) {
|
|
753
812
|
return value === id || !!value && typeof value === "object" && Object.values(value).some((child) => references(child, id));
|
package/dist/vite.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { l as transformRequestFileSource, n as buildRouteManifestFromFileIds, o as normalizeRouteFileId, r as isPageModuleFile, t as assertNoEndpointConflicts } from "./route-manifest-DMizh42B.js";
|
|
1
|
+
import { d as REPLACE_ATTRIBUTE, f as SCROLL_ATTRIBUTE, l as LINK_ATTRIBUTE, u as PREFETCH_ATTRIBUTE } from "./request-locals-BDAhNpEa.js";
|
|
2
|
+
import { i as matchRouteManifest, l as transformRequestFileSource, n as buildRouteManifestFromFileIds, o as normalizeRouteFileId, r as isPageModuleFile, t as assertNoEndpointConflicts } from "./route-manifest-DMizh42B.js";
|
|
3
3
|
import { t as __marklessRouteHref } from "./route-href-CGooO_g6.js";
|
|
4
4
|
import { r as protocolIslandSegment } from "./protocol-constants-B4WxrZAS.js";
|
|
5
|
-
import { a as runFragmentNavigation, i as FRAGMENT_PATH_PREFIX, n as routerLinkBridgeModules, o as startFragmentNavigation, s as listenForLinkIntent } from "./create-server-entry-
|
|
5
|
+
import { a as runFragmentNavigation, i as FRAGMENT_PATH_PREFIX, n as routerLinkBridgeModules, o as startFragmentNavigation, s as listenForLinkIntent } from "./create-server-entry-yboa-2m6.js";
|
|
6
6
|
import { dirname, extname, isAbsolute, join, normalize, relative, resolve } from "pathe";
|
|
7
|
-
import { decodePath, joinURL, parsePath, parseQuery, parseURL, stringifyQuery, withLeadingSlash, withQuery, withoutLeadingSlash } from "ufo";
|
|
8
|
-
import { existsSync } from "node:fs";
|
|
7
|
+
import { decodePath, joinURL, parsePath, parseQuery, parseURL, stringifyQuery, withLeadingSlash, withQuery, withoutBase, withoutLeadingSlash } from "ufo";
|
|
8
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
9
9
|
import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
10
10
|
import { nitro } from "nitro/vite";
|
|
11
11
|
import { minifySync, sortUserPlugins } from "vite";
|
|
@@ -1574,6 +1574,7 @@ function router(options = {}) {
|
|
|
1574
1574
|
return [
|
|
1575
1575
|
routerConfigPlugin(nitroPlugins, resumeEntry, prerenderWakeEntry, navigationEntry, routePreloads, fragmentEntry, serverBuildState()),
|
|
1576
1576
|
devSourceModuleRequestPlugin(),
|
|
1577
|
+
devPageForUrlPlugin(options),
|
|
1577
1578
|
pageServerOnlyPropsPlugin(),
|
|
1578
1579
|
mdxTransformPlugin(),
|
|
1579
1580
|
requestFileTransformPlugin(),
|
|
@@ -1595,6 +1596,37 @@ function pageServerOnlyPropsPlugin() {
|
|
|
1595
1596
|
}
|
|
1596
1597
|
};
|
|
1597
1598
|
}
|
|
1599
|
+
function devPageForUrlPlugin(options) {
|
|
1600
|
+
return {
|
|
1601
|
+
name: "markless-router:dev-page-for-url",
|
|
1602
|
+
apply: "serve",
|
|
1603
|
+
configResolved(config) {
|
|
1604
|
+
config.plugins.find((plugin) => typeof plugin.api?.declarePageForUrl === "function")?.api.declarePageForUrl((href) => devPageForUrl(config.root, config.base, options.mode, href));
|
|
1605
|
+
}
|
|
1606
|
+
};
|
|
1607
|
+
}
|
|
1608
|
+
function devPageForUrl(root, base, mode, href) {
|
|
1609
|
+
let url;
|
|
1610
|
+
try {
|
|
1611
|
+
url = new URL(href);
|
|
1612
|
+
} catch {
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
const pagesDir = join(root, "pages");
|
|
1616
|
+
if (!existsSync(pagesDir)) return void 0;
|
|
1617
|
+
const fileIds = readdirSync(pagesDir, {
|
|
1618
|
+
recursive: true,
|
|
1619
|
+
encoding: "utf8"
|
|
1620
|
+
}).map((file) => join("pages", file));
|
|
1621
|
+
let manifest;
|
|
1622
|
+
try {
|
|
1623
|
+
manifest = buildRouteManifestFromFileIds(fileIds);
|
|
1624
|
+
} catch {
|
|
1625
|
+
return;
|
|
1626
|
+
}
|
|
1627
|
+
const pathname = mode === "hash" && url.hash.startsWith("#/") ? url.hash.slice(1) : withoutBase(url.pathname, base);
|
|
1628
|
+
return matchRouteManifest(pathname, manifest)?.route.file ?? manifest.statusPages.notFound;
|
|
1629
|
+
}
|
|
1598
1630
|
function devSourceModuleRequestPlugin() {
|
|
1599
1631
|
let root = "";
|
|
1600
1632
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markless/router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Markless router: client-side navigation with SSR streaming and build-time preload maps.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -64,11 +64,11 @@
|
|
|
64
64
|
"pathe": "^2.0.3",
|
|
65
65
|
"satteri": "0.6.3",
|
|
66
66
|
"ufo": "^1.6.4",
|
|
67
|
-
"@markless/
|
|
68
|
-
"@markless/
|
|
67
|
+
"@markless/web": "0.7.0",
|
|
68
|
+
"@markless/bundler": "0.7.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@markless/analyzer": "0.
|
|
71
|
+
"@markless/analyzer": "0.7.0"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
74
|
"typescript": "^5.9.3",
|
|
@@ -9,6 +9,7 @@ export interface FragmentNavigationConfig {
|
|
|
9
9
|
readonly replaceAttribute: string;
|
|
10
10
|
readonly scrollAttribute: string;
|
|
11
11
|
readonly routeScriptType: string;
|
|
12
|
+
readonly servedHtmlAttributesProperty: string;
|
|
12
13
|
readonly retireProperty: string;
|
|
13
14
|
readonly streamExecutorGlobal: string;
|
|
14
15
|
readonly streamedArmSelector: string;
|
|
@@ -409,10 +410,13 @@ async function mergeHead(d: Document, next: Document) {
|
|
|
409
410
|
// Only attributes a server document set are the server's to remove: scripts own the rest (a theme class).
|
|
410
411
|
const serverHtmlAttributes = new WeakMap<Document, Set<string>>();
|
|
411
412
|
|
|
412
|
-
function syncHtmlAttributes(d: Document, next: Document): void {
|
|
413
|
+
function syncHtmlAttributes(d: Document, next: Document, servedProperty: string): void {
|
|
413
414
|
const root = d.documentElement;
|
|
414
415
|
const incoming = next.documentElement;
|
|
415
|
-
|
|
416
|
+
const served =
|
|
417
|
+
serverHtmlAttributes.get(d) ??
|
|
418
|
+
((root as unknown as Record<string, readonly string[] | undefined>)[servedProperty] || []);
|
|
419
|
+
for (const name of served)
|
|
416
420
|
if (!incoming.hasAttribute(name)) root.removeAttribute(name);
|
|
417
421
|
for (const attribute of incoming.attributes)
|
|
418
422
|
if (root.getAttribute(attribute.name) !== attribute.value)
|
|
@@ -702,7 +706,7 @@ export async function navigate(
|
|
|
702
706
|
(w as unknown as Record<string, unknown>)[state.config.streamExecutorGlobal] = undefined;
|
|
703
707
|
for (const element of d.querySelectorAll(state.config.streamedArmSelector)) element.remove();
|
|
704
708
|
state.shown = pageKey(new URL(w.location.href));
|
|
705
|
-
if (documentLoads) syncHtmlAttributes(d, next);
|
|
709
|
+
if (documentLoads) syncHtmlAttributes(d, next, state.config.servedHtmlAttributesProperty);
|
|
706
710
|
let region: Element;
|
|
707
711
|
let end: Comment;
|
|
708
712
|
let scripts: Element[];
|