@riebeckite/honox 0.0.29 → 0.0.31
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/index.js +333 -9
- package/dist/server.js +1 -1
- package/dist/src/client_module.d.ts +2 -2
- package/dist/src/development_inspector.d.ts +3 -0
- package/dist/src/ssg/build_output.d.ts +1 -0
- package/dist/src/ssg/types.d.ts +17 -12
- package/dist/src/ui/primitives.d.ts +0 -2
- package/dist/src/ui/primitives.js +2 -10
- package/dist/src/vite_runner.d.ts +7 -0
- package/package.json +6 -5
package/dist/index.js
CHANGED
|
@@ -284,6 +284,7 @@ function isJavaScriptModule(filePath) {
|
|
|
284
284
|
// src/ssg_plugin.ts
|
|
285
285
|
import { rm as rm3 } from "node:fs/promises";
|
|
286
286
|
import { join as join4, relative as relative3, resolve as resolve2 } from "node:path";
|
|
287
|
+
import { buildOutputPlan, compareOutputPlan } from "@riebeckite/core";
|
|
287
288
|
import { defaultExtensionMap, redirectPlugin, toSSG } from "hono/ssg";
|
|
288
289
|
import {
|
|
289
290
|
createServer
|
|
@@ -728,6 +729,33 @@ async function discardClientBuildArtifacts(artifacts) {
|
|
|
728
729
|
if (!artifacts) return;
|
|
729
730
|
await rm(artifacts.stagingDirectory, { recursive: true, force: true });
|
|
730
731
|
}
|
|
732
|
+
async function collectBuildOutputPaths(directory, relativeDirectory = "") {
|
|
733
|
+
const entries = await readdir(directory, { withFileTypes: true }).catch(
|
|
734
|
+
(error) => {
|
|
735
|
+
if (isMissingDirectoryError(error)) return void 0;
|
|
736
|
+
throw error;
|
|
737
|
+
}
|
|
738
|
+
);
|
|
739
|
+
if (!entries) return [];
|
|
740
|
+
const paths = [];
|
|
741
|
+
for (const entry of entries) {
|
|
742
|
+
const relativePath = join(relativeDirectory, entry.name).replaceAll(
|
|
743
|
+
"\\",
|
|
744
|
+
"/"
|
|
745
|
+
);
|
|
746
|
+
if (entry.isDirectory()) {
|
|
747
|
+
paths.push(
|
|
748
|
+
...await collectBuildOutputPaths(
|
|
749
|
+
join(directory, entry.name),
|
|
750
|
+
relativePath
|
|
751
|
+
)
|
|
752
|
+
);
|
|
753
|
+
} else if (entry.isFile()) {
|
|
754
|
+
paths.push(relativePath);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
return paths.sort();
|
|
758
|
+
}
|
|
731
759
|
function collectClientAssetPaths(manifestSource) {
|
|
732
760
|
let manifest;
|
|
733
761
|
try {
|
|
@@ -1503,6 +1531,7 @@ function riebeckiteSsg(options = {}) {
|
|
|
1503
1531
|
}
|
|
1504
1532
|
const timingsMs = process.env.RIEBECKITE_SSG_METRICS_FILE ? {} : void 0;
|
|
1505
1533
|
const outDir = resolve2(config.root, config.build.outDir);
|
|
1534
|
+
let viteClientAssetPaths = [];
|
|
1506
1535
|
removeVirtualEntryChunk(bundle, resolvedVirtualId);
|
|
1507
1536
|
const server = await measure(
|
|
1508
1537
|
timingsMs,
|
|
@@ -1525,6 +1554,7 @@ function riebeckiteSsg(options = {}) {
|
|
|
1525
1554
|
);
|
|
1526
1555
|
try {
|
|
1527
1556
|
await restoreClientBuildArtifacts(outDir, clientBuildArtifacts);
|
|
1557
|
+
viteClientAssetPaths = await collectBuildOutputPaths(outDir);
|
|
1528
1558
|
logSsgDiagnostics(
|
|
1529
1559
|
this,
|
|
1530
1560
|
`SSR noExternal=${formatSsrNoExternal()} · client manifest ${clientBuildArtifacts ? "restored" : "not found"}`
|
|
@@ -1563,6 +1593,9 @@ function riebeckiteSsg(options = {}) {
|
|
|
1563
1593
|
"siteOwnedOutputs",
|
|
1564
1594
|
() => collectSiteOwnedOutputPaths(config.publicDir)
|
|
1565
1595
|
);
|
|
1596
|
+
viteClientAssetPaths = [
|
|
1597
|
+
.../* @__PURE__ */ new Set([...viteClientAssetPaths, ...Object.keys(bundle)])
|
|
1598
|
+
].filter((outputPath) => !siteOwnedOutputPaths.has(outputPath)).sort();
|
|
1566
1599
|
const siteOutputCollisions = findBuildOutputSiteCollisions(
|
|
1567
1600
|
Object.keys(bundle),
|
|
1568
1601
|
siteOwnedOutputPaths
|
|
@@ -1588,6 +1621,12 @@ function riebeckiteSsg(options = {}) {
|
|
|
1588
1621
|
const reusablePaths = new Set(
|
|
1589
1622
|
canUseIncremental ? (outputChangeSet?.unchanged ?? []).map((output) => output.path) : []
|
|
1590
1623
|
);
|
|
1624
|
+
const inventory = [
|
|
1625
|
+
...outputChangeSet?.affected ?? [],
|
|
1626
|
+
...outputChangeSet?.unchanged ?? []
|
|
1627
|
+
];
|
|
1628
|
+
const inventoryPaths = new Set(inventory.map((output) => output.path));
|
|
1629
|
+
const honoStaticRoutePaths = /* @__PURE__ */ new Set();
|
|
1591
1630
|
logSsgDiagnostics(
|
|
1592
1631
|
this,
|
|
1593
1632
|
`output cache ${canUseIncremental ? "hit" : `miss (${outputCacheRejectionReason})`} · ${reusablePaths.size} reusable outputs`
|
|
@@ -1631,6 +1670,19 @@ function riebeckiteSsg(options = {}) {
|
|
|
1631
1670
|
manifestHookCacheMiss: 0,
|
|
1632
1671
|
manifestHookDurationMs: 0,
|
|
1633
1672
|
manifestHookPlugins: {},
|
|
1673
|
+
plannedOutputCount: 0,
|
|
1674
|
+
actualOutputCount: 0,
|
|
1675
|
+
matchedOutputCount: 0,
|
|
1676
|
+
missingInPlanCount: 0,
|
|
1677
|
+
missingInDistCount: 0,
|
|
1678
|
+
unknownOutputCount: 0,
|
|
1679
|
+
ownerConflictCount: 0,
|
|
1680
|
+
publicationViolationCount: 0,
|
|
1681
|
+
plannedGenerateOutputCount: 0,
|
|
1682
|
+
plannedReuseOutputCount: 0,
|
|
1683
|
+
plannedRemoveOutputCount: 0,
|
|
1684
|
+
plannedUnknownOutputCount: 0,
|
|
1685
|
+
outputPlanMemoryDeltaBytes: 0,
|
|
1634
1686
|
outputCacheDecision,
|
|
1635
1687
|
outputCacheRejectionReason: outputCacheRejectionReason ?? null,
|
|
1636
1688
|
timingsMs: timingsMs ?? {}
|
|
@@ -1648,6 +1700,9 @@ function riebeckiteSsg(options = {}) {
|
|
|
1648
1700
|
"\\",
|
|
1649
1701
|
"/"
|
|
1650
1702
|
);
|
|
1703
|
+
if (!inventoryPaths.has(fileName)) {
|
|
1704
|
+
honoStaticRoutePaths.add(fileName);
|
|
1705
|
+
}
|
|
1651
1706
|
if (siteOwnedOutputPaths.has(fileName)) {
|
|
1652
1707
|
shadowedOutputs.add(fileName);
|
|
1653
1708
|
return;
|
|
@@ -1775,7 +1830,18 @@ function riebeckiteSsg(options = {}) {
|
|
|
1775
1830
|
timingsMs,
|
|
1776
1831
|
outDir,
|
|
1777
1832
|
publicDir: config.publicDir,
|
|
1778
|
-
configFile: config.configFile
|
|
1833
|
+
configFile: config.configFile,
|
|
1834
|
+
outputPlanInput: {
|
|
1835
|
+
inventory,
|
|
1836
|
+
affectedPaths: new Set(
|
|
1837
|
+
(outputChangeSet?.affected ?? []).map((output) => output.path)
|
|
1838
|
+
),
|
|
1839
|
+
removed: outputChangeSet?.removed ?? [],
|
|
1840
|
+
cacheAvailable: canUseIncremental,
|
|
1841
|
+
honoStaticRoutePaths,
|
|
1842
|
+
viteClientAssetPaths: new Set(viteClientAssetPaths),
|
|
1843
|
+
sitePublicAssetPaths: siteOwnedOutputPaths
|
|
1844
|
+
}
|
|
1779
1845
|
};
|
|
1780
1846
|
this.info(
|
|
1781
1847
|
`SSG outputs: ${metrics.renderedOutputCount} rendered · ${metrics.reusedOutputCount} reused · ${metrics.deletedOutputCount} removed`
|
|
@@ -1813,6 +1879,44 @@ function riebeckiteSsg(options = {}) {
|
|
|
1813
1879
|
"outputInventory",
|
|
1814
1880
|
() => fingerprintOutputDirectory(outputCache.outDir)
|
|
1815
1881
|
);
|
|
1882
|
+
const finalOutputInventory = outputCache.state.finalOutputInventory;
|
|
1883
|
+
const outputPlanRssBefore = process.memoryUsage().rss;
|
|
1884
|
+
const outputPlan = measureSync(
|
|
1885
|
+
outputCache.timingsMs,
|
|
1886
|
+
"outputPlan",
|
|
1887
|
+
() => buildOutputPlan({
|
|
1888
|
+
...outputCache.outputPlanInput
|
|
1889
|
+
})
|
|
1890
|
+
);
|
|
1891
|
+
const outputPlanComparison = measureSync(
|
|
1892
|
+
outputCache.timingsMs,
|
|
1893
|
+
"outputPlanComparison",
|
|
1894
|
+
() => compareOutputPlan(outputPlan, Object.keys(finalOutputInventory))
|
|
1895
|
+
);
|
|
1896
|
+
outputCache.metrics.plannedOutputCount = outputPlan.entries.length;
|
|
1897
|
+
outputCache.metrics.actualOutputCount = Object.keys(finalOutputInventory).length;
|
|
1898
|
+
outputCache.metrics.matchedOutputCount = outputPlanComparison.matched.length;
|
|
1899
|
+
outputCache.metrics.missingInPlanCount = outputPlanComparison.missingInPlan.length;
|
|
1900
|
+
outputCache.metrics.missingInDistCount = outputPlanComparison.missingInDist.length;
|
|
1901
|
+
outputCache.metrics.unknownOutputCount = outputPlanComparison.unknown.length;
|
|
1902
|
+
outputCache.metrics.ownerConflictCount = outputPlanComparison.ownerConflicts.length;
|
|
1903
|
+
outputCache.metrics.publicationViolationCount = outputPlanComparison.publicationViolations.length;
|
|
1904
|
+
outputCache.metrics.plannedGenerateOutputCount = outputPlan.entries.filter(
|
|
1905
|
+
(entry2) => entry2.action === "generate"
|
|
1906
|
+
).length;
|
|
1907
|
+
outputCache.metrics.plannedReuseOutputCount = outputPlan.entries.filter(
|
|
1908
|
+
(entry2) => entry2.action === "reuse"
|
|
1909
|
+
).length;
|
|
1910
|
+
outputCache.metrics.plannedRemoveOutputCount = outputPlan.entries.filter(
|
|
1911
|
+
(entry2) => entry2.action === "remove"
|
|
1912
|
+
).length;
|
|
1913
|
+
outputCache.metrics.plannedUnknownOutputCount = outputPlan.entries.filter(
|
|
1914
|
+
(entry2) => entry2.action === "unknown"
|
|
1915
|
+
).length;
|
|
1916
|
+
outputCache.metrics.outputPlanMemoryDeltaBytes = Math.max(
|
|
1917
|
+
0,
|
|
1918
|
+
process.memoryUsage().rss - outputPlanRssBefore
|
|
1919
|
+
);
|
|
1816
1920
|
const publicDir = outputCache.publicDir;
|
|
1817
1921
|
outputCache.state.publicDirectory = publicDir ? resolve2(publicDir) : void 0;
|
|
1818
1922
|
outputCache.state.publicFingerprint = publicDir ? await measure(
|
|
@@ -1965,27 +2069,35 @@ function isNotFoundError2(error) {
|
|
|
1965
2069
|
}
|
|
1966
2070
|
|
|
1967
2071
|
// src/client_module.ts
|
|
1968
|
-
import {
|
|
1969
|
-
serializePublicClientConfig
|
|
1970
|
-
} from "@riebeckite/core";
|
|
2072
|
+
import { serializePublicClientConfig } from "@riebeckite/core";
|
|
1971
2073
|
var clientModuleId = "virtual:riebeckite/client";
|
|
1972
2074
|
var resolvedClientModuleId = `\0${clientModuleId}`;
|
|
1973
2075
|
function riebeckiteClientModule(getConfig) {
|
|
2076
|
+
let development = false;
|
|
1974
2077
|
return {
|
|
1975
2078
|
name: "riebeckite-client-module",
|
|
2079
|
+
config(_config, environment) {
|
|
2080
|
+
development = environment.command === "serve";
|
|
2081
|
+
},
|
|
1976
2082
|
resolveId(id) {
|
|
1977
2083
|
if (id === clientModuleId) return resolvedClientModuleId;
|
|
1978
2084
|
return null;
|
|
1979
2085
|
},
|
|
1980
2086
|
load(id) {
|
|
1981
2087
|
if (id !== resolvedClientModuleId) return null;
|
|
1982
|
-
return createClientModule(getConfig());
|
|
2088
|
+
return createClientModule(getConfig(), development);
|
|
1983
2089
|
}
|
|
1984
2090
|
};
|
|
1985
2091
|
}
|
|
1986
|
-
function createClientModule(config) {
|
|
2092
|
+
function createClientModule(config, development) {
|
|
1987
2093
|
const imports = [];
|
|
1988
2094
|
const initializers = [];
|
|
2095
|
+
if (development) {
|
|
2096
|
+
imports.push(
|
|
2097
|
+
'import { initDevelopmentInspector } from "virtual:riebeckite/development-inspector";'
|
|
2098
|
+
);
|
|
2099
|
+
initializers.push("initDevelopmentInspector()");
|
|
2100
|
+
}
|
|
1989
2101
|
for (const [index, entry] of config.plugins.flatMap((plugin) => plugin.clientEntries ?? []).entries()) {
|
|
1990
2102
|
const localName = `pluginClientInitializer${index}`;
|
|
1991
2103
|
const importTarget = entry.exportName ? `{ ${entry.exportName} as ${localName} }` : localName;
|
|
@@ -2021,6 +2133,204 @@ ${initializers.map((initializer) => ` ${initializer};`).join("\n")}
|
|
|
2021
2133
|
`;
|
|
2022
2134
|
}
|
|
2023
2135
|
|
|
2136
|
+
// src/development_inspector.ts
|
|
2137
|
+
import { collectDevelopmentDiagnostics } from "@riebeckite/diagnostics";
|
|
2138
|
+
var clientModuleId2 = "virtual:riebeckite/development-inspector";
|
|
2139
|
+
var resolvedClientModuleId2 = `\0${clientModuleId2}`;
|
|
2140
|
+
var endpointPath = "/__riebeckite/inspector/report";
|
|
2141
|
+
function riebeckiteDevelopmentInspector(getApplication) {
|
|
2142
|
+
let revision = 0;
|
|
2143
|
+
return {
|
|
2144
|
+
name: "riebeckite-development-inspector",
|
|
2145
|
+
apply: "serve",
|
|
2146
|
+
enforce: "pre",
|
|
2147
|
+
resolveId(id) {
|
|
2148
|
+
return id === clientModuleId2 ? resolvedClientModuleId2 : null;
|
|
2149
|
+
},
|
|
2150
|
+
load(id) {
|
|
2151
|
+
return id === resolvedClientModuleId2 ? inspectorClientModule() : null;
|
|
2152
|
+
},
|
|
2153
|
+
configureServer(server) {
|
|
2154
|
+
const middleware = async (request, response) => {
|
|
2155
|
+
if (!isLocalRequest(request.headers.host, server)) {
|
|
2156
|
+
response.statusCode = 403;
|
|
2157
|
+
response.end();
|
|
2158
|
+
return;
|
|
2159
|
+
}
|
|
2160
|
+
try {
|
|
2161
|
+
const application = getApplication();
|
|
2162
|
+
const report = await collectDevelopmentDiagnostics({
|
|
2163
|
+
config: application.config,
|
|
2164
|
+
revision
|
|
2165
|
+
});
|
|
2166
|
+
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
2167
|
+
response.setHeader("cache-control", "no-store");
|
|
2168
|
+
const currentPage = currentPageFromRequest(request.url);
|
|
2169
|
+
response.end(
|
|
2170
|
+
JSON.stringify({
|
|
2171
|
+
...report,
|
|
2172
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2173
|
+
currentPage,
|
|
2174
|
+
theme: application.config.theme.name,
|
|
2175
|
+
plugins: application.config.plugins.map((plugin) => plugin.name),
|
|
2176
|
+
capabilities: {
|
|
2177
|
+
dependencies: "unavailable",
|
|
2178
|
+
output: "unavailable",
|
|
2179
|
+
pageMetadata: "unavailable"
|
|
2180
|
+
}
|
|
2181
|
+
})
|
|
2182
|
+
);
|
|
2183
|
+
} catch {
|
|
2184
|
+
response.statusCode = 500;
|
|
2185
|
+
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
2186
|
+
response.end(JSON.stringify({ code: "INSPECTOR_REPORT_FAILED" }));
|
|
2187
|
+
}
|
|
2188
|
+
};
|
|
2189
|
+
server.middlewares.use(endpointPath, middleware);
|
|
2190
|
+
return () => prioritizeMiddleware(server, middleware);
|
|
2191
|
+
},
|
|
2192
|
+
handleHotUpdate({ server }) {
|
|
2193
|
+
revision += 1;
|
|
2194
|
+
server.hot.send({ type: "custom", event: "riebeckite:inspector" });
|
|
2195
|
+
}
|
|
2196
|
+
};
|
|
2197
|
+
}
|
|
2198
|
+
function currentPageFromRequest(url) {
|
|
2199
|
+
const value = new URL(url ?? endpointPath, "http://localhost").searchParams.get(
|
|
2200
|
+
"path"
|
|
2201
|
+
);
|
|
2202
|
+
return value && value.startsWith("/") && !value.startsWith("//") ? value : "/";
|
|
2203
|
+
}
|
|
2204
|
+
function prioritizeMiddleware(server, middleware) {
|
|
2205
|
+
const stack = server.middlewares.stack;
|
|
2206
|
+
const index = stack?.findIndex(
|
|
2207
|
+
(layer) => layer.handle === middleware || layer.route === endpointPath
|
|
2208
|
+
) ?? -1;
|
|
2209
|
+
if (index > 0 && stack) stack.unshift(...stack.splice(index, 1));
|
|
2210
|
+
}
|
|
2211
|
+
function isLocalRequest(host, server) {
|
|
2212
|
+
if (!host) return false;
|
|
2213
|
+
const hostname = host.replace(/:\d+$/, "").toLowerCase();
|
|
2214
|
+
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]")
|
|
2215
|
+
return true;
|
|
2216
|
+
const address = server.httpServer?.address();
|
|
2217
|
+
return typeof address === "object" && address?.address === hostname;
|
|
2218
|
+
}
|
|
2219
|
+
function inspectorClientModule() {
|
|
2220
|
+
return `
|
|
2221
|
+
const endpoint = ${JSON.stringify(endpointPath)};
|
|
2222
|
+
const panelId = "riebeckite-development-inspector";
|
|
2223
|
+
|
|
2224
|
+
export function initDevelopmentInspector() {
|
|
2225
|
+
let panel;
|
|
2226
|
+
let launcher;
|
|
2227
|
+
let controller;
|
|
2228
|
+
let generation = 0;
|
|
2229
|
+
let report;
|
|
2230
|
+
let activeTab = 0;
|
|
2231
|
+
const tabs = ["Overview", "Diagnostics", "Dependencies", "Plugins", "Output"];
|
|
2232
|
+
const refresh = async () => {
|
|
2233
|
+
if (!panel?.isConnected) return;
|
|
2234
|
+
controller?.abort();
|
|
2235
|
+
controller = new AbortController();
|
|
2236
|
+
const current = ++generation;
|
|
2237
|
+
try {
|
|
2238
|
+
const response = await fetch(endpoint + "?path=" + encodeURIComponent(location.pathname), { cache: "no-store", signal: controller.signal });
|
|
2239
|
+
if (!response.ok) throw new Error("Inspector report is unavailable.");
|
|
2240
|
+
const next = await response.json();
|
|
2241
|
+
if (current !== generation || !panel?.isConnected) return;
|
|
2242
|
+
report = next;
|
|
2243
|
+
render();
|
|
2244
|
+
} catch (error) {
|
|
2245
|
+
if (error.name === "AbortError" || current !== generation) return;
|
|
2246
|
+
renderFailure(panel.shadowRoot, error instanceof Error ? error.message : String(error));
|
|
2247
|
+
panel.shadowRoot.querySelector("[data-close]").addEventListener("click", close);
|
|
2248
|
+
}
|
|
2249
|
+
};
|
|
2250
|
+
const open = () => {
|
|
2251
|
+
if (!panel) {
|
|
2252
|
+
panel = document.createElement("div");
|
|
2253
|
+
panel.id = panelId;
|
|
2254
|
+
panel.attachShadow({ mode: "open" });
|
|
2255
|
+
document.body.append(panel);
|
|
2256
|
+
}
|
|
2257
|
+
refresh();
|
|
2258
|
+
};
|
|
2259
|
+
const close = () => {
|
|
2260
|
+
generation += 1;
|
|
2261
|
+
controller?.abort();
|
|
2262
|
+
panel?.remove();
|
|
2263
|
+
launcher?.focus();
|
|
2264
|
+
};
|
|
2265
|
+
launcher = document.createElement("button");
|
|
2266
|
+
launcher.type = "button";
|
|
2267
|
+
launcher.textContent = "Inspector";
|
|
2268
|
+
launcher.setAttribute("aria-label", "Open Riebeckite Development Inspector");
|
|
2269
|
+
launcher.style.cssText = "position:fixed;right:16px;bottom:16px;z-index:2147483647;border:1px solid #434343;border-radius:4px;background:#171717;color:#fff;padding:8px 12px;font:600 12px system-ui;cursor:pointer";
|
|
2270
|
+
launcher.addEventListener("click", open);
|
|
2271
|
+
document.body.append(launcher);
|
|
2272
|
+
window.addEventListener("keydown", (event) => {
|
|
2273
|
+
const editable = event.target instanceof HTMLElement && (event.target.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(event.target.tagName));
|
|
2274
|
+
if (event.key === "Escape" && panel?.isConnected) {
|
|
2275
|
+
event.preventDefault();
|
|
2276
|
+
close();
|
|
2277
|
+
} else if (event.key.toLowerCase() === "r" && event.ctrlKey && event.altKey && !editable) {
|
|
2278
|
+
event.preventDefault();
|
|
2279
|
+
panel?.isConnected ? close() : open();
|
|
2280
|
+
}
|
|
2281
|
+
});
|
|
2282
|
+
import.meta.hot?.on("riebeckite:inspector", refresh);
|
|
2283
|
+
|
|
2284
|
+
function render() {
|
|
2285
|
+
const root = panel.shadowRoot;
|
|
2286
|
+
root.innerHTML = '<style>' + styles + '</style><section role="dialog" aria-modal="false" aria-labelledby="rb-title" tabindex="-1"><header><div><strong id="rb-title">Riebeckite Inspector</strong><p>Ctrl+Alt+R</p></div><button type="button" data-close aria-label="Close inspector">Close</button></header><div class="summary"><b>' + report.summary.errors + '</b> errors <b>' + report.summary.warnings + '</b> warnings <b>' + report.summary.info + '</b> info</div><div role="tablist" aria-label="Inspector sections">' + tabs.map((tab, index) => '<button id="rb-tab-' + index + '" role="tab" aria-controls="rb-panel-' + index + '" aria-selected="' + (index === activeTab) + '" tabindex="' + (index === activeTab ? 0 : -1) + '" data-tab="' + index + '">' + tab + '</button>').join("") + '</div><div id="rb-panel-' + activeTab + '" role="tabpanel" aria-labelledby="rb-tab-' + activeTab + '" tabindex="0">' + panelContent() + '</div><p class="status" aria-live="polite">Inspector report updated</p></section>';
|
|
2287
|
+
root.querySelector("[data-close]").addEventListener("click", close);
|
|
2288
|
+
root.querySelectorAll("[data-tab]").forEach((button) => button.addEventListener("click", () => { activeTab = Number(button.dataset.tab); render(); }));
|
|
2289
|
+
root.querySelector("[role=tablist]").addEventListener("keydown", (event) => {
|
|
2290
|
+
if (event.key === "Home") activeTab = 0;
|
|
2291
|
+
else if (event.key === "End") activeTab = tabs.length - 1;
|
|
2292
|
+
else if (event.key === "ArrowRight" || event.key === "ArrowDown") activeTab = (activeTab + 1) % tabs.length;
|
|
2293
|
+
else if (event.key === "ArrowLeft" || event.key === "ArrowUp") activeTab = (activeTab + tabs.length - 1) % tabs.length;
|
|
2294
|
+
else return;
|
|
2295
|
+
event.preventDefault(); render(); root.querySelector('[data-tab="' + activeTab + '"]').focus();
|
|
2296
|
+
});
|
|
2297
|
+
}
|
|
2298
|
+
function panelContent() {
|
|
2299
|
+
if (activeTab === 0) return '<dl><dt>Page</dt><dd>' + escapeHtml(report.currentPage) + '</dd><dt>Theme</dt><dd>' + escapeHtml(report.theme) + '</dd><dt>Revision</dt><dd>' + escapeHtml(report.revision) + '</dd></dl>';
|
|
2300
|
+
if (activeTab === 1) return diagnosticList(report.diagnostics);
|
|
2301
|
+
if (activeTab === 2) return unavailable("Dependencies", report.capabilities.dependencies);
|
|
2302
|
+
if (activeTab === 3) return '<ul>' + (report.plugins.map((plugin) => '<li>' + escapeHtml(plugin) + '</li>').join("") || "<li>No plugins configured.</li>") + '</ul>';
|
|
2303
|
+
return unavailable("Output", report.capabilities.output);
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
|
|
2307
|
+
function diagnosticList(diagnostics) {
|
|
2308
|
+
return '<ul>' + (diagnostics.map((diagnostic) =>
|
|
2309
|
+
'<li data-severity="' + escapeHtml(diagnostic.severity) + '"><b>' + escapeHtml(diagnostic.code) + '</b> ' + escapeHtml(diagnostic.message) + location(diagnostic) + '</li>'
|
|
2310
|
+
).join("") || "<li>No diagnostic findings.</li>") + '</ul>';
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
function unavailable(subject, capability) {
|
|
2314
|
+
return '<p class="partial">' + escapeHtml(subject) + ': ' + escapeHtml(capability) + ' in the development inspector.</p>';
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
function renderFailure(root, message) {
|
|
2318
|
+
root.innerHTML = '<style>' + styles + '</style><section role="dialog" aria-modal="false" aria-labelledby="rb-failure-title"><header><strong id="rb-failure-title">Riebeckite Inspector</strong><button type="button" data-close aria-label="Close inspector">Close</button></header><p class="failure" aria-live="polite">' + escapeHtml(message) + '</p></section>';
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
function location(diagnostic) {
|
|
2322
|
+
const location = diagnostic.location;
|
|
2323
|
+
return location?.file ? ' <small>(' + escapeHtml(location.file) + (location.line ? ':' + location.line : '') + ')</small>' : '';
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
function escapeHtml(value) {
|
|
2327
|
+
return String(value).replace(/[&<>"]/g, (character) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[character]);
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
const styles = ':host{all:initial}section{position:fixed;right:16px;bottom:56px;z-index:2147483647;width:min(540px,calc(100vw - 32px));max-height:70vh;overflow:auto;background:#171717;color:#f4f4f4;border:1px solid #555;padding:16px;font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;box-shadow:0 8px 24px #0006}header{display:flex;justify-content:space-between;gap:16px;border-bottom:1px solid #555;padding-bottom:8px}header p,.status,small{color:#b8b8b8;margin:2px 0}.summary{margin:12px 0}button{border:1px solid #666;background:#242424;color:#fff;padding:6px 8px;cursor:pointer}button[aria-selected="true"]{border-color:#e2c57b;color:#ffe08a}.partial{color:#e2c57b}ul{margin:12px 0;padding-left:20px}li{margin:8px 0}li[data-severity="error"]{color:#ff9797}li[data-severity="warning"]{color:#ffe08a}dl{display:grid;grid-template-columns:max-content 1fr;gap:8px 16px}dt{color:#b8b8b8}.failure{color:#ff9797}@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}@media(max-width:560px){section{right:8px;bottom:52px;width:calc(100vw - 32px);max-height:75vh}}';
|
|
2331
|
+
`;
|
|
2332
|
+
}
|
|
2333
|
+
|
|
2024
2334
|
// src/vite_runner.ts
|
|
2025
2335
|
import fs7 from "node:fs/promises";
|
|
2026
2336
|
import path9 from "node:path";
|
|
@@ -2081,8 +2391,21 @@ async function findWorkspaceRoot(configRoot) {
|
|
|
2081
2391
|
async function startHonoxDevServer(options) {
|
|
2082
2392
|
const root = path9.resolve(options.root);
|
|
2083
2393
|
await withWorkingDirectory(root, async () => {
|
|
2084
|
-
const server = await createServer2({ root });
|
|
2085
|
-
|
|
2394
|
+
const server = await createServer2({ root, server: options.server });
|
|
2395
|
+
const restartFiles = new Set(
|
|
2396
|
+
options.restartOnChange?.map((file) => path9.resolve(file))
|
|
2397
|
+
);
|
|
2398
|
+
if (restartFiles.size > 0) {
|
|
2399
|
+
server.watcher.add([...restartFiles]);
|
|
2400
|
+
server.watcher.on("change", (file) => {
|
|
2401
|
+
if (restartFiles.has(path9.resolve(file))) void server.restart();
|
|
2402
|
+
});
|
|
2403
|
+
}
|
|
2404
|
+
await server.listen(options.server?.port);
|
|
2405
|
+
options.onServerReady?.([
|
|
2406
|
+
...server.resolvedUrls?.local ?? [],
|
|
2407
|
+
...server.resolvedUrls?.network ?? []
|
|
2408
|
+
]);
|
|
2086
2409
|
server.printUrls();
|
|
2087
2410
|
await waitForShutdown(server);
|
|
2088
2411
|
});
|
|
@@ -2239,7 +2562,8 @@ function riebeckite(options = {}, onApplicationResolved) {
|
|
|
2239
2562
|
appRoot: () => requireApplication(application).appRoot,
|
|
2240
2563
|
contentRoot: () => requireApplication(application).contentRoot,
|
|
2241
2564
|
exclude: () => getConfig().content.exclude ?? []
|
|
2242
|
-
})
|
|
2565
|
+
}),
|
|
2566
|
+
riebeckiteDevelopmentInspector(() => requireApplication(application))
|
|
2243
2567
|
];
|
|
2244
2568
|
}
|
|
2245
2569
|
function requireApplication(application) {
|
package/dist/server.js
CHANGED
|
@@ -130,7 +130,7 @@ function mountRiebeckiteEndpoints(app, options) {
|
|
|
130
130
|
for (const endpoint of endpoints) {
|
|
131
131
|
const method = endpoint.method ?? "GET";
|
|
132
132
|
const handler = async (context) => {
|
|
133
|
-
const manifest = await options.content.getManifest();
|
|
133
|
+
const manifest = endpoint.requiresManifest === false ? void 0 : await options.content.getManifest();
|
|
134
134
|
const request = await toPluginEndpointRequest(context, method);
|
|
135
135
|
const response = await endpoint.handler({
|
|
136
136
|
config: options.config,
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ResolvedRiebeckiteConfig } from "@riebeckite/core";
|
|
2
2
|
import type { Plugin } from "vite";
|
|
3
|
-
export declare function riebeckiteClientModule(getConfig: () => ResolvedRiebeckiteConfig): Plugin;
|
|
3
|
+
export declare function riebeckiteClientModule(getConfig: () => Pick<ResolvedRiebeckiteConfig, "plugins">): Plugin;
|
|
@@ -13,3 +13,4 @@ export declare function emptyBuildOutputDirectory(outDir: string): Promise<void>
|
|
|
13
13
|
export declare function preserveClientBuildArtifacts(outDir: string): Promise<ClientBuildArtifacts | undefined>;
|
|
14
14
|
export declare function restoreClientBuildArtifacts(outDir: string, artifacts: ClientBuildArtifacts | undefined): Promise<void>;
|
|
15
15
|
export declare function discardClientBuildArtifacts(artifacts: ClientBuildArtifacts | undefined): Promise<void>;
|
|
16
|
+
export declare function collectBuildOutputPaths(directory: string, relativeDirectory?: string): Promise<string[]>;
|
package/dist/src/ssg/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { OutputDescriptor } from "@riebeckite/core";
|
|
1
2
|
import type { toSSG } from "hono/ssg";
|
|
2
3
|
export type GeneratedOutputAsset = {
|
|
3
4
|
type: "asset";
|
|
@@ -44,18 +45,9 @@ export type SsgModule = {
|
|
|
44
45
|
}>;
|
|
45
46
|
};
|
|
46
47
|
getOutputChangeSet(): Promise<{
|
|
47
|
-
affected: readonly
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}[];
|
|
51
|
-
removed: readonly {
|
|
52
|
-
kind: string;
|
|
53
|
-
path: string;
|
|
54
|
-
}[];
|
|
55
|
-
unchanged: readonly {
|
|
56
|
-
kind: string;
|
|
57
|
-
path: string;
|
|
58
|
-
}[];
|
|
48
|
+
affected: readonly OutputDescriptor[];
|
|
49
|
+
removed: readonly OutputDescriptor[];
|
|
50
|
+
unchanged: readonly OutputDescriptor[];
|
|
59
51
|
fullRegenerationRequired: boolean;
|
|
60
52
|
candidateOutputCount: number;
|
|
61
53
|
affectedOutputCount: number;
|
|
@@ -97,6 +89,19 @@ export type SsgOutputMetrics = {
|
|
|
97
89
|
manifestHookCacheMiss: number;
|
|
98
90
|
manifestHookDurationMs: number;
|
|
99
91
|
manifestHookPlugins: Record<string, unknown>;
|
|
92
|
+
plannedOutputCount: number;
|
|
93
|
+
actualOutputCount: number;
|
|
94
|
+
matchedOutputCount: number;
|
|
95
|
+
missingInPlanCount: number;
|
|
96
|
+
missingInDistCount: number;
|
|
97
|
+
unknownOutputCount: number;
|
|
98
|
+
ownerConflictCount: number;
|
|
99
|
+
publicationViolationCount: number;
|
|
100
|
+
plannedGenerateOutputCount: number;
|
|
101
|
+
plannedReuseOutputCount: number;
|
|
102
|
+
plannedRemoveOutputCount: number;
|
|
103
|
+
plannedUnknownOutputCount: number;
|
|
104
|
+
outputPlanMemoryDeltaBytes: number;
|
|
100
105
|
outputCacheDecision: OutputCacheDecision;
|
|
101
106
|
outputCacheRejectionReason: OutputCacheRejectionReason | null;
|
|
102
107
|
timingsMs: Record<string, number>;
|
|
@@ -10,7 +10,6 @@ export type PrimitiveClassProps = {
|
|
|
10
10
|
className?: string;
|
|
11
11
|
};
|
|
12
12
|
export type ArticleProps = PrimitiveProps & {
|
|
13
|
-
"data-slot"?: string;
|
|
14
13
|
post?: PostContent;
|
|
15
14
|
entry?: PublicContentEntry;
|
|
16
15
|
};
|
|
@@ -26,7 +25,6 @@ export type ArticleHeaderProps = (PrimitiveClassProps & {
|
|
|
26
25
|
});
|
|
27
26
|
export type ArticleContentProps = PrimitiveClassProps & {
|
|
28
27
|
children?: PrimitiveChildren;
|
|
29
|
-
"data-slot"?: string;
|
|
30
28
|
};
|
|
31
29
|
export type ArticleMetaProps = PrimitiveProps & {
|
|
32
30
|
label?: string;
|
|
@@ -15,14 +15,7 @@ import {
|
|
|
15
15
|
import { Fragment, jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
16
16
|
import { createElement } from "hono/jsx";
|
|
17
17
|
function Article(props) {
|
|
18
|
-
const article = /* @__PURE__ */ jsx(
|
|
19
|
-
"article",
|
|
20
|
-
{
|
|
21
|
-
class: joinClassNames("rb-article", props.class, props.className),
|
|
22
|
-
"data-slot": props["data-slot"] ?? "article",
|
|
23
|
-
children: props.children
|
|
24
|
-
}
|
|
25
|
-
);
|
|
18
|
+
const article = /* @__PURE__ */ jsx("article", { class: joinClassNames("rb-article", props.class, props.className), children: props.children });
|
|
26
19
|
if (!props.post) return article;
|
|
27
20
|
return /* @__PURE__ */ jsx(ArticleProvider, { entry: props.entry, post: props.post, children: article });
|
|
28
21
|
}
|
|
@@ -68,8 +61,7 @@ function ArticleContent(props) {
|
|
|
68
61
|
props.class,
|
|
69
62
|
props.className
|
|
70
63
|
);
|
|
71
|
-
|
|
72
|
-
return /* @__PURE__ */ jsx("div", { class: className, "data-slot": dataSlot, children: props.children });
|
|
64
|
+
return /* @__PURE__ */ jsx("div", { class: className, children: props.children });
|
|
73
65
|
}
|
|
74
66
|
function HtmlFragment(props) {
|
|
75
67
|
return raw(props.html);
|
|
@@ -3,6 +3,13 @@ import { type RiebeckiteConfigLoaderOptions } from "./config_loader.js";
|
|
|
3
3
|
export type HonoxApplicationOptions = {
|
|
4
4
|
root: string;
|
|
5
5
|
tracer?: Tracer;
|
|
6
|
+
server?: {
|
|
7
|
+
host?: string;
|
|
8
|
+
open?: boolean;
|
|
9
|
+
port?: number;
|
|
10
|
+
};
|
|
11
|
+
onServerReady?: (urls: readonly string[]) => void;
|
|
12
|
+
restartOnChange?: readonly string[];
|
|
6
13
|
};
|
|
7
14
|
export type ResolvedHonoxApplication = {
|
|
8
15
|
config: ResolvedRiebeckiteConfig;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riebeckite/honox",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.31",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -44,13 +44,14 @@
|
|
|
44
44
|
"hono": "^4.12.25",
|
|
45
45
|
"honox": "0.1.56",
|
|
46
46
|
"vite": "^8.0.9",
|
|
47
|
-
"@riebeckite/core": "0.0.
|
|
48
|
-
"@riebeckite/
|
|
49
|
-
"@riebeckite/plugin-color-mode": "0.0.
|
|
47
|
+
"@riebeckite/core": "0.0.31",
|
|
48
|
+
"@riebeckite/diagnostics": "0.0.31",
|
|
49
|
+
"@riebeckite/plugin-color-mode": "0.0.31",
|
|
50
|
+
"@riebeckite/ui": "0.0.31"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"tsx": "^4.22.4",
|
|
53
|
-
"@riebeckite/test": "0.0.
|
|
54
|
+
"@riebeckite/test": "0.0.31"
|
|
54
55
|
},
|
|
55
56
|
"publishConfig": {
|
|
56
57
|
"access": "public"
|