@riebeckite/honox 0.0.31 → 0.0.32
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 +457 -79
- package/dist/src/client_module.d.ts +1 -1
- package/dist/src/ui/primitives.js +8 -2
- package/dist/src/vite_runner.d.ts +1 -1
- package/package.json +7 -6
package/dist/index.js
CHANGED
|
@@ -1167,7 +1167,7 @@ function isOutputCacheState(value) {
|
|
|
1167
1167
|
}
|
|
1168
1168
|
function isOutputInventory(value) {
|
|
1169
1169
|
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.entries(value).every(
|
|
1170
|
-
([
|
|
1170
|
+
([outputPath2, checksum]) => isSafeLogicalOutputPath(outputPath2) && isChecksum(checksum)
|
|
1171
1171
|
);
|
|
1172
1172
|
}
|
|
1173
1173
|
function isOutputCacheEntries(value) {
|
|
@@ -1175,7 +1175,7 @@ function isOutputCacheEntries(value) {
|
|
|
1175
1175
|
return false;
|
|
1176
1176
|
}
|
|
1177
1177
|
return Object.entries(value).every(
|
|
1178
|
-
([
|
|
1178
|
+
([outputPath2, entry]) => isSafeLogicalOutputPath(outputPath2) && typeof entry === "object" && entry !== null && typeof entry.cachePath === "string" && entry.cachePath === outputCacheEntryName(outputPath2) && isChecksum(entry.checksum)
|
|
1179
1179
|
);
|
|
1180
1180
|
}
|
|
1181
1181
|
function outputCacheEntriesPath(outputCachePath) {
|
|
@@ -1184,31 +1184,31 @@ function outputCacheEntriesPath(outputCachePath) {
|
|
|
1184
1184
|
async function saveOutputCacheEntries(directory, outputDirectory, outputs, finalOutputInventory, timingsMs) {
|
|
1185
1185
|
await ensureOutputCacheEntriesDirectory(directory);
|
|
1186
1186
|
const entries = {};
|
|
1187
|
-
for (const
|
|
1188
|
-
assertSafeLogicalOutputPath(
|
|
1189
|
-
const existing = outputs[
|
|
1187
|
+
for (const outputPath2 of Object.keys(outputs).sort()) {
|
|
1188
|
+
assertSafeLogicalOutputPath(outputPath2);
|
|
1189
|
+
const existing = outputs[outputPath2];
|
|
1190
1190
|
if (existing.cachePath && existing.checksum) {
|
|
1191
|
-
if (existing.cachePath !== outputCacheEntryName(
|
|
1192
|
-
throw new Error(`Invalid SSG output cache entry: ${
|
|
1191
|
+
if (existing.cachePath !== outputCacheEntryName(outputPath2) || !isChecksum(existing.checksum)) {
|
|
1192
|
+
throw new Error(`Invalid SSG output cache entry: ${outputPath2}`);
|
|
1193
1193
|
}
|
|
1194
|
-
entries[
|
|
1194
|
+
entries[outputPath2] = existing;
|
|
1195
1195
|
continue;
|
|
1196
1196
|
}
|
|
1197
|
-
const source = resolveOutputCacheFile(outputDirectory,
|
|
1198
|
-
const cachePath = outputCacheEntryName(
|
|
1197
|
+
const source = resolveOutputCacheFile(outputDirectory, outputPath2);
|
|
1198
|
+
const cachePath = outputCacheEntryName(outputPath2);
|
|
1199
1199
|
const destination = join3(directory, cachePath);
|
|
1200
1200
|
await waitForFaultInjection("entry-create-start");
|
|
1201
1201
|
await replaceOutputCacheEntry(source, destination, timingsMs);
|
|
1202
|
-
const checksum = finalOutputInventory?.[
|
|
1202
|
+
const checksum = finalOutputInventory?.[outputPath2];
|
|
1203
1203
|
if (!checksum) {
|
|
1204
1204
|
const cachedChecksum = await checksumFile(destination);
|
|
1205
1205
|
if (!cachedChecksum) {
|
|
1206
|
-
throw new Error(`Could not checksum cached output: ${
|
|
1206
|
+
throw new Error(`Could not checksum cached output: ${outputPath2}`);
|
|
1207
1207
|
}
|
|
1208
|
-
entries[
|
|
1208
|
+
entries[outputPath2] = { cachePath, checksum: cachedChecksum };
|
|
1209
1209
|
continue;
|
|
1210
1210
|
}
|
|
1211
|
-
entries[
|
|
1211
|
+
entries[outputPath2] = { cachePath, checksum };
|
|
1212
1212
|
}
|
|
1213
1213
|
return entries;
|
|
1214
1214
|
}
|
|
@@ -1216,8 +1216,8 @@ async function validateOutputCacheEntries(outputCachePath, entries, timingsMs) {
|
|
|
1216
1216
|
try {
|
|
1217
1217
|
const directory = outputCacheEntriesPath(outputCachePath);
|
|
1218
1218
|
if (!await isSafeOutputCacheEntriesDirectory(directory)) return false;
|
|
1219
|
-
for (const [
|
|
1220
|
-
if (!isSafeLogicalOutputPath(
|
|
1219
|
+
for (const [outputPath2, entry] of Object.entries(entries)) {
|
|
1220
|
+
if (!isSafeLogicalOutputPath(outputPath2) || entry.cachePath !== outputCacheEntryName(outputPath2) || !isChecksum(entry.checksum)) {
|
|
1221
1221
|
return false;
|
|
1222
1222
|
}
|
|
1223
1223
|
const path11 = resolveOutputCacheFile(directory, entry.cachePath);
|
|
@@ -1358,8 +1358,8 @@ function assertSafeLogicalOutputPath(path11) {
|
|
|
1358
1358
|
throw new Error(`Invalid SSG output path: ${path11}`);
|
|
1359
1359
|
}
|
|
1360
1360
|
}
|
|
1361
|
-
function outputCacheEntryName(
|
|
1362
|
-
return createHash3("sha256").update(
|
|
1361
|
+
function outputCacheEntryName(outputPath2) {
|
|
1362
|
+
return createHash3("sha256").update(outputPath2).digest("hex");
|
|
1363
1363
|
}
|
|
1364
1364
|
function isChecksum(value) {
|
|
1365
1365
|
return typeof value === "string" && /^[a-f0-9]{64}$/u.test(value);
|
|
@@ -1595,7 +1595,7 @@ function riebeckiteSsg(options = {}) {
|
|
|
1595
1595
|
);
|
|
1596
1596
|
viteClientAssetPaths = [
|
|
1597
1597
|
.../* @__PURE__ */ new Set([...viteClientAssetPaths, ...Object.keys(bundle)])
|
|
1598
|
-
].filter((
|
|
1598
|
+
].filter((outputPath2) => !siteOwnedOutputPaths.has(outputPath2)).sort();
|
|
1599
1599
|
const siteOutputCollisions = findBuildOutputSiteCollisions(
|
|
1600
1600
|
Object.keys(bundle),
|
|
1601
1601
|
siteOwnedOutputPaths
|
|
@@ -2091,12 +2091,18 @@ function riebeckiteClientModule(getConfig) {
|
|
|
2091
2091
|
}
|
|
2092
2092
|
function createClientModule(config, development) {
|
|
2093
2093
|
const imports = [];
|
|
2094
|
-
const
|
|
2094
|
+
const appInitializers = [];
|
|
2095
|
+
const pageInitializers = [];
|
|
2096
|
+
imports.push('import { ClientLifecycle } from "@riebeckite/core/client";');
|
|
2097
|
+
if (config.spa !== void 0) {
|
|
2098
|
+
imports.push('import { createClient } from "honox/client";');
|
|
2099
|
+
imports.push('import { startSpaNavigation } from "@riebeckite/spa";');
|
|
2100
|
+
}
|
|
2095
2101
|
if (development) {
|
|
2096
2102
|
imports.push(
|
|
2097
2103
|
'import { initDevelopmentInspector } from "virtual:riebeckite/development-inspector";'
|
|
2098
2104
|
);
|
|
2099
|
-
|
|
2105
|
+
appInitializers.push("initDevelopmentInspector()");
|
|
2100
2106
|
}
|
|
2101
2107
|
for (const [index, entry] of config.plugins.flatMap((plugin) => plugin.clientEntries ?? []).entries()) {
|
|
2102
2108
|
const localName = `pluginClientInitializer${index}`;
|
|
@@ -2105,41 +2111,123 @@ function createClientModule(config, development) {
|
|
|
2105
2111
|
`import ${importTarget} from ${JSON.stringify(entry.moduleSpecifier)};`
|
|
2106
2112
|
);
|
|
2107
2113
|
const publicConfig = entry.publicConfig;
|
|
2108
|
-
const
|
|
2114
|
+
const serializedConfig = publicConfig === void 0 ? "undefined" : serializePublicClientConfig(publicConfig);
|
|
2115
|
+
const initializer = entry.initializerArguments === "context" ? `${localName}(context)` : entry.initializerArguments === "root" ? `${localName}(context.root)` : `${localName}(context.config)`;
|
|
2116
|
+
const initializers = entry.scope === "app" ? appInitializers : pageInitializers;
|
|
2109
2117
|
initializers.push(
|
|
2110
|
-
`
|
|
2118
|
+
`mountPluginClientInitializer(${JSON.stringify(entry.scope ?? "page")}, ${JSON.stringify(entry.moduleSpecifier)}, root, ${serializedConfig}, (context) => ${initializer})`
|
|
2111
2119
|
);
|
|
2112
2120
|
}
|
|
2113
2121
|
return `${imports.join("\n")}
|
|
2114
2122
|
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
}
|
|
2123
|
+
const lifecycle = new ClientLifecycle();
|
|
2124
|
+
let stopSpaNavigation;
|
|
2125
|
+
|
|
2126
|
+
function mountPluginClientInitializer(scope, name, root, config, initialize) {
|
|
2127
|
+
void lifecycle.mount({ scope, name, root, config, initialize });
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
function mountAppClientInitializers(root) {
|
|
2131
|
+
${appInitializers.map((initializer) => ` ${initializer};`).join("\n")}
|
|
2124
2132
|
}
|
|
2125
2133
|
|
|
2126
|
-
function
|
|
2127
|
-
|
|
2134
|
+
function mountPageClientInitializers(root) {
|
|
2135
|
+
${pageInitializers.map((initializer) => ` ${initializer};`).join("\n")}
|
|
2128
2136
|
}
|
|
2129
2137
|
|
|
2130
2138
|
export function initRiebeckiteClient() {
|
|
2131
|
-
|
|
2139
|
+
mountAppClientInitializers(document);
|
|
2140
|
+
mountPageClientInitializers(document.querySelector("#main-content") ?? document);
|
|
2141
|
+
${config.spa === void 0 ? "" : ` stopSpaNavigation ??= startSpaNavigation({
|
|
2142
|
+
...${serializePublicClientConfig(config.spa)},
|
|
2143
|
+
onBeforePageCommit: () => lifecycle.unmount("page"),
|
|
2144
|
+
onPageCommit: async ({ root, signal }) => {
|
|
2145
|
+
if (signal.aborted) return;
|
|
2146
|
+
await createClient();
|
|
2147
|
+
if (signal.aborted || !root.isConnected) return;
|
|
2148
|
+
mountPageClientInitializers(root);
|
|
2149
|
+
},
|
|
2150
|
+
});`}
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
export async function remountRiebeckitePage(root) {
|
|
2154
|
+
await lifecycle.unmount("page");
|
|
2155
|
+
mountPageClientInitializers(root);
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
export async function disposeRiebeckiteClient() {
|
|
2159
|
+
stopSpaNavigation?.();
|
|
2160
|
+
stopSpaNavigation = undefined;
|
|
2161
|
+
await lifecycle.dispose();
|
|
2132
2162
|
}
|
|
2133
2163
|
`;
|
|
2134
2164
|
}
|
|
2135
2165
|
|
|
2136
2166
|
// src/development_inspector.ts
|
|
2137
|
-
import {
|
|
2167
|
+
import {
|
|
2168
|
+
buildOutputPlan as buildOutputPlan2,
|
|
2169
|
+
ContentManager,
|
|
2170
|
+
FileSystemContentSource
|
|
2171
|
+
} from "@riebeckite/core";
|
|
2172
|
+
import {
|
|
2173
|
+
collectDevelopmentDiagnostics,
|
|
2174
|
+
diagnoseOutputPlan,
|
|
2175
|
+
sortDevelopmentDiagnostics
|
|
2176
|
+
} from "@riebeckite/diagnostics";
|
|
2138
2177
|
var clientModuleId2 = "virtual:riebeckite/development-inspector";
|
|
2139
2178
|
var resolvedClientModuleId2 = `\0${clientModuleId2}`;
|
|
2140
|
-
var
|
|
2179
|
+
var reportPath = "/__riebeckite/inspector/report";
|
|
2180
|
+
var outputPath = "/__riebeckite/inspector/output";
|
|
2181
|
+
var listedOutputLimit = 20;
|
|
2141
2182
|
function riebeckiteDevelopmentInspector(getApplication) {
|
|
2142
2183
|
let revision = 0;
|
|
2184
|
+
let inspection = null;
|
|
2185
|
+
const inspectApplication = (application, currentRevision) => {
|
|
2186
|
+
if (inspection?.revision === currentRevision && inspection.application === application) {
|
|
2187
|
+
return inspection;
|
|
2188
|
+
}
|
|
2189
|
+
if (inspection) {
|
|
2190
|
+
const previous = inspection;
|
|
2191
|
+
const disposePrevious = () => {
|
|
2192
|
+
void previous.dispose().catch(() => {
|
|
2193
|
+
});
|
|
2194
|
+
};
|
|
2195
|
+
void Promise.allSettled([previous.report, previous.output]).then(
|
|
2196
|
+
disposePrevious
|
|
2197
|
+
);
|
|
2198
|
+
inspection = null;
|
|
2199
|
+
}
|
|
2200
|
+
const content = createInspectionContent(application);
|
|
2201
|
+
let disposed = false;
|
|
2202
|
+
const dispose = async () => {
|
|
2203
|
+
if (disposed) return;
|
|
2204
|
+
disposed = true;
|
|
2205
|
+
await content.dispose();
|
|
2206
|
+
};
|
|
2207
|
+
const report = collectDevelopmentDiagnostics({
|
|
2208
|
+
config: application.config,
|
|
2209
|
+
content,
|
|
2210
|
+
revision: currentRevision,
|
|
2211
|
+
includeOutput: false
|
|
2212
|
+
});
|
|
2213
|
+
const output = report.then(
|
|
2214
|
+
() => inspectContentOutputs(content),
|
|
2215
|
+
() => inspectContentOutputs(content)
|
|
2216
|
+
);
|
|
2217
|
+
const entry = {
|
|
2218
|
+
application,
|
|
2219
|
+
revision: currentRevision,
|
|
2220
|
+
report,
|
|
2221
|
+
output,
|
|
2222
|
+
dispose
|
|
2223
|
+
};
|
|
2224
|
+
inspection = entry;
|
|
2225
|
+
void report.catch(() => {
|
|
2226
|
+
if (inspection === entry) inspection = null;
|
|
2227
|
+
void output.then(dispose, dispose);
|
|
2228
|
+
});
|
|
2229
|
+
return entry;
|
|
2230
|
+
};
|
|
2143
2231
|
return {
|
|
2144
2232
|
name: "riebeckite-development-inspector",
|
|
2145
2233
|
apply: "serve",
|
|
@@ -2151,7 +2239,7 @@ function riebeckiteDevelopmentInspector(getApplication) {
|
|
|
2151
2239
|
return id === resolvedClientModuleId2 ? inspectorClientModule() : null;
|
|
2152
2240
|
},
|
|
2153
2241
|
configureServer(server) {
|
|
2154
|
-
const
|
|
2242
|
+
const reportMiddleware = async (request, response) => {
|
|
2155
2243
|
if (!isLocalRequest(request.headers.host, server)) {
|
|
2156
2244
|
response.statusCode = 403;
|
|
2157
2245
|
response.end();
|
|
@@ -2159,25 +2247,16 @@ function riebeckiteDevelopmentInspector(getApplication) {
|
|
|
2159
2247
|
}
|
|
2160
2248
|
try {
|
|
2161
2249
|
const application = getApplication();
|
|
2162
|
-
const report = await
|
|
2163
|
-
config: application.config,
|
|
2164
|
-
revision
|
|
2165
|
-
});
|
|
2250
|
+
const report = await inspectApplication(application, revision).report;
|
|
2166
2251
|
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
2167
2252
|
response.setHeader("cache-control", "no-store");
|
|
2168
|
-
const currentPage = currentPageFromRequest(request.url);
|
|
2169
2253
|
response.end(
|
|
2170
2254
|
JSON.stringify({
|
|
2171
2255
|
...report,
|
|
2172
2256
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2173
|
-
currentPage,
|
|
2257
|
+
currentPage: currentPageFromRequest(request.url),
|
|
2174
2258
|
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
|
-
}
|
|
2259
|
+
plugins: application.config.plugins.map((plugin) => plugin.name)
|
|
2181
2260
|
})
|
|
2182
2261
|
);
|
|
2183
2262
|
} catch {
|
|
@@ -2186,8 +2265,39 @@ function riebeckiteDevelopmentInspector(getApplication) {
|
|
|
2186
2265
|
response.end(JSON.stringify({ code: "INSPECTOR_REPORT_FAILED" }));
|
|
2187
2266
|
}
|
|
2188
2267
|
};
|
|
2189
|
-
|
|
2190
|
-
|
|
2268
|
+
const outputMiddleware = async (request, response) => {
|
|
2269
|
+
if (!isLocalRequest(request.headers.host, server)) {
|
|
2270
|
+
response.statusCode = 403;
|
|
2271
|
+
response.end();
|
|
2272
|
+
return;
|
|
2273
|
+
}
|
|
2274
|
+
try {
|
|
2275
|
+
const application = getApplication();
|
|
2276
|
+
const entry = inspectApplication(application, revision);
|
|
2277
|
+
const result = await entry.output;
|
|
2278
|
+
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
2279
|
+
response.setHeader("cache-control", "no-store");
|
|
2280
|
+
response.end(
|
|
2281
|
+
JSON.stringify({
|
|
2282
|
+
version: 1,
|
|
2283
|
+
revision: entry.revision,
|
|
2284
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2285
|
+
...result,
|
|
2286
|
+
diagnostics: sortDevelopmentDiagnostics(result.diagnostics)
|
|
2287
|
+
})
|
|
2288
|
+
);
|
|
2289
|
+
} catch {
|
|
2290
|
+
response.statusCode = 500;
|
|
2291
|
+
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
2292
|
+
response.end(JSON.stringify({ code: "INSPECTOR_OUTPUT_FAILED" }));
|
|
2293
|
+
}
|
|
2294
|
+
};
|
|
2295
|
+
server.middlewares.use(reportPath, reportMiddleware);
|
|
2296
|
+
server.middlewares.use(outputPath, outputMiddleware);
|
|
2297
|
+
return () => {
|
|
2298
|
+
prioritizeMiddleware(server, outputMiddleware, outputPath);
|
|
2299
|
+
prioritizeMiddleware(server, reportMiddleware, reportPath);
|
|
2300
|
+
};
|
|
2191
2301
|
},
|
|
2192
2302
|
handleHotUpdate({ server }) {
|
|
2193
2303
|
revision += 1;
|
|
@@ -2195,16 +2305,142 @@ function riebeckiteDevelopmentInspector(getApplication) {
|
|
|
2195
2305
|
}
|
|
2196
2306
|
};
|
|
2197
2307
|
}
|
|
2308
|
+
function createInspectionContent(application) {
|
|
2309
|
+
const { config, contentRoot } = application;
|
|
2310
|
+
return new ContentManager(
|
|
2311
|
+
config.content.source ?? new FileSystemContentSource(contentRoot, config.content.exclude),
|
|
2312
|
+
config.content.exclude,
|
|
2313
|
+
{ config, commitBuildState: false }
|
|
2314
|
+
);
|
|
2315
|
+
}
|
|
2316
|
+
async function inspectContentOutputs(content) {
|
|
2317
|
+
try {
|
|
2318
|
+
const changes = await content.getOutputChangeSet();
|
|
2319
|
+
const plan = buildOutputPlan2({
|
|
2320
|
+
inventory: [...changes.affected, ...changes.unchanged],
|
|
2321
|
+
removed: changes.removed,
|
|
2322
|
+
affectedPaths: new Set(changes.affected.map((output) => output.path)),
|
|
2323
|
+
cacheAvailable: changes.unchanged.length > 0
|
|
2324
|
+
});
|
|
2325
|
+
return {
|
|
2326
|
+
output: inspectOutput(changes, plan),
|
|
2327
|
+
dependencies: inspectDependencies(changes),
|
|
2328
|
+
diagnostics: diagnoseOutputPlan(plan)
|
|
2329
|
+
};
|
|
2330
|
+
} catch {
|
|
2331
|
+
return {
|
|
2332
|
+
output: {
|
|
2333
|
+
status: "unavailable",
|
|
2334
|
+
reason: "output inspection failed"
|
|
2335
|
+
},
|
|
2336
|
+
dependencies: {
|
|
2337
|
+
status: "unavailable",
|
|
2338
|
+
reason: "dependency inspection failed"
|
|
2339
|
+
},
|
|
2340
|
+
diagnostics: []
|
|
2341
|
+
};
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
function inspectOutput(changes, plan) {
|
|
2345
|
+
return {
|
|
2346
|
+
status: "available",
|
|
2347
|
+
candidateOutputCount: changes.candidateOutputCount,
|
|
2348
|
+
affectedOutputCount: changes.affectedOutputCount,
|
|
2349
|
+
unchangedOutputCount: changes.unchangedOutputCount,
|
|
2350
|
+
removedOutputCount: changes.removedOutputCount,
|
|
2351
|
+
fullRegenerationRequired: changes.fullRegenerationRequired,
|
|
2352
|
+
conflicts: plan.conflicts.map((conflict) => ({
|
|
2353
|
+
path: conflict.path,
|
|
2354
|
+
owners: conflict.owners
|
|
2355
|
+
})),
|
|
2356
|
+
affected: changes.affected.slice(0, listedOutputLimit).map(listOutput),
|
|
2357
|
+
hiddenAffectedCount: Math.max(
|
|
2358
|
+
0,
|
|
2359
|
+
changes.affected.length - listedOutputLimit
|
|
2360
|
+
),
|
|
2361
|
+
removed: changes.removed.slice(0, listedOutputLimit).map(listOutput),
|
|
2362
|
+
hiddenRemovedCount: Math.max(0, changes.removed.length - listedOutputLimit)
|
|
2363
|
+
};
|
|
2364
|
+
}
|
|
2365
|
+
function inspectDependencies(changes) {
|
|
2366
|
+
const outputs = [...changes.affected, ...changes.unchanged];
|
|
2367
|
+
const kinds = /* @__PURE__ */ new Map();
|
|
2368
|
+
const listed = [];
|
|
2369
|
+
let dependencyCount = 0;
|
|
2370
|
+
let dependentOutputCount = 0;
|
|
2371
|
+
let unknownOutputCount = 0;
|
|
2372
|
+
let hiddenOutputCount = 0;
|
|
2373
|
+
for (const output of outputs) {
|
|
2374
|
+
for (const dependency of output.dependencies) {
|
|
2375
|
+
dependencyCount += 1;
|
|
2376
|
+
kinds.set(dependency.type, (kinds.get(dependency.type) ?? 0) + 1);
|
|
2377
|
+
}
|
|
2378
|
+
if (output.dependencies.some(({ type }) => type === "unknown")) {
|
|
2379
|
+
unknownOutputCount += 1;
|
|
2380
|
+
}
|
|
2381
|
+
if (output.dependencies.length === 0) continue;
|
|
2382
|
+
dependentOutputCount += 1;
|
|
2383
|
+
if (listed.length < listedOutputLimit) {
|
|
2384
|
+
listed.push({
|
|
2385
|
+
path: output.path,
|
|
2386
|
+
dependencies: output.dependencies.map(dependencyLabel)
|
|
2387
|
+
});
|
|
2388
|
+
} else {
|
|
2389
|
+
hiddenOutputCount += 1;
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
return {
|
|
2393
|
+
status: "available",
|
|
2394
|
+
outputCount: outputs.length,
|
|
2395
|
+
dependentOutputCount,
|
|
2396
|
+
dependencyCount,
|
|
2397
|
+
unknownOutputCount,
|
|
2398
|
+
kinds: [...kinds.entries()].sort(([left], [right]) => left.localeCompare(right)).map(([kind, count]) => ({ kind, count })),
|
|
2399
|
+
outputs: listed,
|
|
2400
|
+
hiddenOutputCount
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2403
|
+
function listOutput(output) {
|
|
2404
|
+
return {
|
|
2405
|
+
path: output.path,
|
|
2406
|
+
kind: output.kind,
|
|
2407
|
+
producer: output.producer
|
|
2408
|
+
};
|
|
2409
|
+
}
|
|
2410
|
+
function dependencyLabel(dependency) {
|
|
2411
|
+
switch (dependency.type) {
|
|
2412
|
+
case "content":
|
|
2413
|
+
return `content:${dependency.slug}`;
|
|
2414
|
+
case "tag":
|
|
2415
|
+
return `tag:${dependency.tag}`;
|
|
2416
|
+
case "folder":
|
|
2417
|
+
return `folder:${dependency.folder}`;
|
|
2418
|
+
case "file":
|
|
2419
|
+
return `file:${dependency.path}`;
|
|
2420
|
+
case "public-location":
|
|
2421
|
+
return `public-location:${dependency.pathname}`;
|
|
2422
|
+
case "projection":
|
|
2423
|
+
return `projection:${dependency.projection}`;
|
|
2424
|
+
case "external":
|
|
2425
|
+
return `external:${dependency.id}`;
|
|
2426
|
+
case "content-query":
|
|
2427
|
+
return `content-query:${dependency.properties.join(",")}${dependency.unknown ? "?" : ""}`;
|
|
2428
|
+
case "global":
|
|
2429
|
+
return "global";
|
|
2430
|
+
case "unknown":
|
|
2431
|
+
return "unknown";
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2198
2434
|
function currentPageFromRequest(url) {
|
|
2199
|
-
const value = new URL(url ??
|
|
2435
|
+
const value = new URL(url ?? reportPath, "http://localhost").searchParams.get(
|
|
2200
2436
|
"path"
|
|
2201
2437
|
);
|
|
2202
|
-
return value
|
|
2438
|
+
return value?.startsWith("/") && !value.startsWith("//") ? value : "/";
|
|
2203
2439
|
}
|
|
2204
|
-
function prioritizeMiddleware(server, middleware) {
|
|
2440
|
+
function prioritizeMiddleware(server, middleware, path11) {
|
|
2205
2441
|
const stack = server.middlewares.stack;
|
|
2206
2442
|
const index = stack?.findIndex(
|
|
2207
|
-
(layer) => layer.handle === middleware || layer.route ===
|
|
2443
|
+
(layer) => layer.handle === middleware || layer.route === path11
|
|
2208
2444
|
) ?? -1;
|
|
2209
2445
|
if (index > 0 && stack) stack.unshift(...stack.splice(index, 1));
|
|
2210
2446
|
}
|
|
@@ -2218,7 +2454,8 @@ function isLocalRequest(host, server) {
|
|
|
2218
2454
|
}
|
|
2219
2455
|
function inspectorClientModule() {
|
|
2220
2456
|
return `
|
|
2221
|
-
const
|
|
2457
|
+
const reportEndpoint = ${JSON.stringify(reportPath)};
|
|
2458
|
+
const outputEndpoint = ${JSON.stringify(outputPath)};
|
|
2222
2459
|
const panelId = "riebeckite-development-inspector";
|
|
2223
2460
|
|
|
2224
2461
|
export function initDevelopmentInspector() {
|
|
@@ -2228,23 +2465,57 @@ export function initDevelopmentInspector() {
|
|
|
2228
2465
|
let generation = 0;
|
|
2229
2466
|
let report;
|
|
2230
2467
|
let activeTab = 0;
|
|
2468
|
+
let refreshing = false;
|
|
2469
|
+
let pendingRefresh = false;
|
|
2470
|
+
let loadingTimer;
|
|
2231
2471
|
const tabs = ["Overview", "Diagnostics", "Dependencies", "Plugins", "Output"];
|
|
2232
2472
|
const refresh = async () => {
|
|
2233
2473
|
if (!panel?.isConnected) return;
|
|
2474
|
+
if (refreshing) {
|
|
2475
|
+
pendingRefresh = true;
|
|
2476
|
+
return;
|
|
2477
|
+
}
|
|
2478
|
+
refreshing = true;
|
|
2234
2479
|
controller?.abort();
|
|
2235
2480
|
controller = new AbortController();
|
|
2236
2481
|
const current = ++generation;
|
|
2237
2482
|
try {
|
|
2238
|
-
const response = await fetch(
|
|
2483
|
+
const response = await fetch(reportEndpoint + "?path=" + encodeURIComponent(location.pathname), { cache: "no-store", signal: controller.signal });
|
|
2239
2484
|
if (!response.ok) throw new Error("Inspector report is unavailable.");
|
|
2240
2485
|
const next = await response.json();
|
|
2241
2486
|
if (current !== generation || !panel?.isConnected) return;
|
|
2242
2487
|
report = next;
|
|
2243
2488
|
render();
|
|
2489
|
+
void loadOutput(current);
|
|
2490
|
+
} catch (error) {
|
|
2491
|
+
if (error.name === "AbortError" || current !== generation) return;
|
|
2492
|
+
clearInterval(loadingTimer);
|
|
2493
|
+
renderFailure(panel.shadowRoot, error instanceof Error ? error.message : String(error));
|
|
2494
|
+
panel.shadowRoot.querySelector("[data-close]").addEventListener("click", close);
|
|
2495
|
+
} finally {
|
|
2496
|
+
refreshing = false;
|
|
2497
|
+
if (pendingRefresh) {
|
|
2498
|
+
pendingRefresh = false;
|
|
2499
|
+
void refresh();
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
};
|
|
2503
|
+
const loadOutput = async (current) => {
|
|
2504
|
+
try {
|
|
2505
|
+
const response = await fetch(outputEndpoint, { cache: "no-store", signal: controller.signal });
|
|
2506
|
+
if (!response.ok) throw new Error("Inspector output is unavailable.");
|
|
2507
|
+
const next = await response.json();
|
|
2508
|
+
if (current !== generation || !panel?.isConnected) return;
|
|
2509
|
+
report.output = next.output;
|
|
2510
|
+
report.dependencies = next.dependencies;
|
|
2511
|
+
report.diagnostics = report.diagnostics.concat(next.diagnostics);
|
|
2512
|
+
report.summary = summarize(report.diagnostics);
|
|
2513
|
+
render();
|
|
2244
2514
|
} catch (error) {
|
|
2245
2515
|
if (error.name === "AbortError" || current !== generation) return;
|
|
2246
|
-
|
|
2247
|
-
|
|
2516
|
+
report.output = { status: "unavailable", reason: "output inspection failed" };
|
|
2517
|
+
report.dependencies = { status: "unavailable", reason: "dependency inspection failed" };
|
|
2518
|
+
render();
|
|
2248
2519
|
}
|
|
2249
2520
|
};
|
|
2250
2521
|
const open = () => {
|
|
@@ -2252,16 +2523,30 @@ export function initDevelopmentInspector() {
|
|
|
2252
2523
|
panel = document.createElement("div");
|
|
2253
2524
|
panel.id = panelId;
|
|
2254
2525
|
panel.attachShadow({ mode: "open" });
|
|
2255
|
-
document.body.append(panel);
|
|
2256
2526
|
}
|
|
2257
|
-
|
|
2527
|
+
if (!panel.isConnected) document.body.append(panel);
|
|
2528
|
+
showLoading();
|
|
2529
|
+
void refresh();
|
|
2258
2530
|
};
|
|
2259
2531
|
const close = () => {
|
|
2260
2532
|
generation += 1;
|
|
2533
|
+
pendingRefresh = false;
|
|
2261
2534
|
controller?.abort();
|
|
2535
|
+
clearInterval(loadingTimer);
|
|
2262
2536
|
panel?.remove();
|
|
2263
2537
|
launcher?.focus();
|
|
2264
2538
|
};
|
|
2539
|
+
const showLoading = () => {
|
|
2540
|
+
if (!panel) return;
|
|
2541
|
+
clearInterval(loadingTimer);
|
|
2542
|
+
panel.shadowRoot.innerHTML = '<style>' + styles + '</style><section role="dialog" aria-modal="false" aria-labelledby="rb-loading-title"><header><strong id="rb-loading-title">Riebeckite Inspector</strong><button type="button" data-close aria-label="Close inspector">Close</button></header><p class="status" aria-live="polite">Loading inspector report…</p></section>';
|
|
2543
|
+
const status = panel.shadowRoot.querySelector(".status");
|
|
2544
|
+
const started = Date.now();
|
|
2545
|
+
loadingTimer = setInterval(() => {
|
|
2546
|
+
if (status?.isConnected) status.textContent = 'Loading inspector report… ' + Math.round((Date.now() - started) / 1000) + 's';
|
|
2547
|
+
}, 1000);
|
|
2548
|
+
panel.shadowRoot.querySelector("[data-close]").addEventListener("click", close);
|
|
2549
|
+
};
|
|
2265
2550
|
launcher = document.createElement("button");
|
|
2266
2551
|
launcher.type = "button";
|
|
2267
2552
|
launcher.textContent = "Inspector";
|
|
@@ -2282,8 +2567,9 @@ export function initDevelopmentInspector() {
|
|
|
2282
2567
|
import.meta.hot?.on("riebeckite:inspector", refresh);
|
|
2283
2568
|
|
|
2284
2569
|
function render() {
|
|
2570
|
+
clearInterval(loadingTimer);
|
|
2285
2571
|
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>';
|
|
2572
|
+
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">' + (report.output ? "Inspector report updated" : "Inspector report updated · loading output plan…") + '</p></section>';
|
|
2287
2573
|
root.querySelector("[data-close]").addEventListener("click", close);
|
|
2288
2574
|
root.querySelectorAll("[data-tab]").forEach((button) => button.addEventListener("click", () => { activeTab = Number(button.dataset.tab); render(); }));
|
|
2289
2575
|
root.querySelector("[role=tablist]").addEventListener("keydown", (event) => {
|
|
@@ -2298,20 +2584,78 @@ export function initDevelopmentInspector() {
|
|
|
2298
2584
|
function panelContent() {
|
|
2299
2585
|
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
2586
|
if (activeTab === 1) return diagnosticList(report.diagnostics);
|
|
2301
|
-
if (activeTab === 2) return
|
|
2587
|
+
if (activeTab === 2) return dependencyReport(report.dependencies);
|
|
2302
2588
|
if (activeTab === 3) return '<ul>' + (report.plugins.map((plugin) => '<li>' + escapeHtml(plugin) + '</li>').join("") || "<li>No plugins configured.</li>") + '</ul>';
|
|
2303
|
-
return
|
|
2589
|
+
return outputReport(report.output);
|
|
2304
2590
|
}
|
|
2305
2591
|
}
|
|
2306
2592
|
|
|
2593
|
+
function summarize(diagnostics) {
|
|
2594
|
+
return {
|
|
2595
|
+
errors: diagnostics.filter((diagnostic) => diagnostic.severity === "error").length,
|
|
2596
|
+
warnings: diagnostics.filter((diagnostic) => diagnostic.severity === "warning").length,
|
|
2597
|
+
info: diagnostics.filter((diagnostic) => diagnostic.severity === "info").length,
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2307
2601
|
function diagnosticList(diagnostics) {
|
|
2308
2602
|
return '<ul>' + (diagnostics.map((diagnostic) =>
|
|
2309
2603
|
'<li data-severity="' + escapeHtml(diagnostic.severity) + '"><b>' + escapeHtml(diagnostic.code) + '</b> ' + escapeHtml(diagnostic.message) + location(diagnostic) + '</li>'
|
|
2310
2604
|
).join("") || "<li>No diagnostic findings.</li>") + '</ul>';
|
|
2311
2605
|
}
|
|
2312
2606
|
|
|
2607
|
+
function outputReport(output) {
|
|
2608
|
+
if (!output) return '<p class="status" aria-live="polite">Loading output plan…</p>';
|
|
2609
|
+
if (output.status !== "available") return unavailable("Output", output.reason);
|
|
2610
|
+
return '<dl>' +
|
|
2611
|
+
'<dt>Candidate</dt><dd>' + output.candidateOutputCount + '</dd>' +
|
|
2612
|
+
'<dt>Affected</dt><dd>' + output.affectedOutputCount + '</dd>' +
|
|
2613
|
+
'<dt>Unchanged</dt><dd>' + output.unchangedOutputCount + '</dd>' +
|
|
2614
|
+
'<dt>Removed</dt><dd>' + output.removedOutputCount + '</dd>' +
|
|
2615
|
+
'<dt>Full regeneration</dt><dd>' + (output.fullRegenerationRequired ? "required" : "not required") + '</dd>' +
|
|
2616
|
+
'<dt>Owner conflicts</dt><dd>' + output.conflicts.length + '</dd>' +
|
|
2617
|
+
'</dl>' +
|
|
2618
|
+
listedOutputs("Affected outputs", output.affected, output.hiddenAffectedCount) +
|
|
2619
|
+
listedOutputs("Removed outputs", output.removed, output.hiddenRemovedCount) +
|
|
2620
|
+
conflictList(output.conflicts);
|
|
2621
|
+
}
|
|
2622
|
+
|
|
2623
|
+
function listedOutputs(title, outputs, hiddenCount) {
|
|
2624
|
+
if (outputs.length === 0) return "";
|
|
2625
|
+
return '<h3>' + escapeHtml(title) + '</h3><ul>' + outputs.map((output) =>
|
|
2626
|
+
'<li><code>' + escapeHtml(output.path) + '</code> <small>' + escapeHtml(output.kind) + ' · ' + escapeHtml(output.producer) + '</small></li>'
|
|
2627
|
+
).join("") + '</ul>' + (hiddenCount > 0 ? '<p class="more">' + hiddenCount + ' more not shown.</p>' : "");
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
function conflictList(conflicts) {
|
|
2631
|
+
if (conflicts.length === 0) return "";
|
|
2632
|
+
return '<h3>Owner conflicts</h3><ul>' + conflicts.map((conflict) =>
|
|
2633
|
+
'<li><code>' + escapeHtml(conflict.path) + '</code> <small>' + escapeHtml(conflict.owners.join(", ")) + '</small></li>'
|
|
2634
|
+
).join("") + '</ul>';
|
|
2635
|
+
}
|
|
2636
|
+
|
|
2637
|
+
function dependencyReport(dependencies) {
|
|
2638
|
+
if (!dependencies) return '<p class="status" aria-live="polite">Loading dependencies…</p>';
|
|
2639
|
+
if (dependencies.status !== "available") return unavailable("Dependencies", dependencies.reason);
|
|
2640
|
+
return '<dl>' +
|
|
2641
|
+
'<dt>Outputs</dt><dd>' + dependencies.outputCount + '</dd>' +
|
|
2642
|
+
'<dt>With dependencies</dt><dd>' + dependencies.dependentOutputCount + '</dd>' +
|
|
2643
|
+
'<dt>Dependencies</dt><dd>' + dependencies.dependencyCount + '</dd>' +
|
|
2644
|
+
'<dt>Unknown outputs</dt><dd>' + dependencies.unknownOutputCount + '</dd>' +
|
|
2645
|
+
'</dl>' +
|
|
2646
|
+
(dependencies.kinds.length === 0 ? "<p>No output dependencies.</p>" :
|
|
2647
|
+
'<h3>Kinds</h3><ul>' + dependencies.kinds.map((kind) =>
|
|
2648
|
+
'<li>' + escapeHtml(kind.kind) + ' <small>' + kind.count + '</small></li>'
|
|
2649
|
+
).join("") + '</ul>') +
|
|
2650
|
+
(dependencies.outputs.length === 0 ? "" :
|
|
2651
|
+
'<h3>Outputs</h3><ul>' + dependencies.outputs.map((output) =>
|
|
2652
|
+
'<li><code>' + escapeHtml(output.path) + '</code><br><small>' + escapeHtml(output.dependencies.join(", ")) + '</small></li>'
|
|
2653
|
+
).join("") + '</ul>') +
|
|
2654
|
+
(dependencies.hiddenOutputCount > 0 ? '<p class="more">' + dependencies.hiddenOutputCount + ' more outputs not shown.</p>' : "");
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2313
2657
|
function unavailable(subject, capability) {
|
|
2314
|
-
return '<p class="partial">' + escapeHtml(subject) + ': ' + escapeHtml(capability) + '
|
|
2658
|
+
return '<p class="partial">' + escapeHtml(subject) + ' unavailable: ' + escapeHtml(capability) + '.</p>';
|
|
2315
2659
|
}
|
|
2316
2660
|
|
|
2317
2661
|
function renderFailure(root, message) {
|
|
@@ -2327,7 +2671,7 @@ function escapeHtml(value) {
|
|
|
2327
2671
|
return String(value).replace(/[&<>"]/g, (character) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[character]);
|
|
2328
2672
|
}
|
|
2329
2673
|
|
|
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}}';
|
|
2674
|
+
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}.more{color:#b8b8b8;margin:4px 0}h3{color:#b8b8b8;font-size:12px;margin:12px 0 4px;text-transform:uppercase}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
2675
|
`;
|
|
2332
2676
|
}
|
|
2333
2677
|
|
|
@@ -2340,6 +2684,14 @@ var viteConfigFileNames = [
|
|
|
2340
2684
|
"vite.config.js",
|
|
2341
2685
|
"vite.config.mjs"
|
|
2342
2686
|
];
|
|
2687
|
+
var ignoredApplicationRootDirectoryNames = /* @__PURE__ */ new Set([
|
|
2688
|
+
".git",
|
|
2689
|
+
".riebeckite",
|
|
2690
|
+
"node_modules",
|
|
2691
|
+
"test",
|
|
2692
|
+
"tests",
|
|
2693
|
+
"templates"
|
|
2694
|
+
]);
|
|
2343
2695
|
async function resolveHonoxApplicationRoot(configRoot, startDirectory) {
|
|
2344
2696
|
const roots = await findViteApplicationRoots(configRoot, startDirectory);
|
|
2345
2697
|
if (roots.length === 1) return roots[0];
|
|
@@ -2402,12 +2754,24 @@ async function startHonoxDevServer(options) {
|
|
|
2402
2754
|
});
|
|
2403
2755
|
}
|
|
2404
2756
|
await server.listen(options.server?.port);
|
|
2405
|
-
|
|
2757
|
+
const urls = [
|
|
2406
2758
|
...server.resolvedUrls?.local ?? [],
|
|
2407
2759
|
...server.resolvedUrls?.network ?? []
|
|
2408
|
-
]
|
|
2409
|
-
server
|
|
2410
|
-
|
|
2760
|
+
];
|
|
2761
|
+
const shutdown = waitForShutdown(server);
|
|
2762
|
+
try {
|
|
2763
|
+
server.printUrls();
|
|
2764
|
+
await options.onServerReady?.(urls);
|
|
2765
|
+
} catch (error) {
|
|
2766
|
+
shutdown.dispose();
|
|
2767
|
+
if (shutdown.isClosing()) {
|
|
2768
|
+
await shutdown.promise;
|
|
2769
|
+
return;
|
|
2770
|
+
}
|
|
2771
|
+
await server.close();
|
|
2772
|
+
throw error;
|
|
2773
|
+
}
|
|
2774
|
+
await shutdown.promise;
|
|
2411
2775
|
});
|
|
2412
2776
|
}
|
|
2413
2777
|
async function buildHonoxApplication(options) {
|
|
@@ -2438,14 +2802,28 @@ async function withWorkingDirectory(root, task) {
|
|
|
2438
2802
|
async function runTraced(tracer, name, buildTask) {
|
|
2439
2803
|
return tracer ? await tracer.span(name, {}, buildTask) : await buildTask();
|
|
2440
2804
|
}
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2805
|
+
function waitForShutdown(server) {
|
|
2806
|
+
let resolve3 = () => {
|
|
2807
|
+
};
|
|
2808
|
+
let closing = false;
|
|
2809
|
+
const close = () => {
|
|
2810
|
+
if (closing) return;
|
|
2811
|
+
closing = true;
|
|
2812
|
+
void server.close().finally(resolve3);
|
|
2813
|
+
};
|
|
2814
|
+
const promise = new Promise((resolvePromise) => {
|
|
2815
|
+
resolve3 = resolvePromise;
|
|
2448
2816
|
});
|
|
2817
|
+
process.once("SIGINT", close);
|
|
2818
|
+
process.once("SIGTERM", close);
|
|
2819
|
+
return {
|
|
2820
|
+
promise,
|
|
2821
|
+
isClosing: () => closing,
|
|
2822
|
+
dispose: () => {
|
|
2823
|
+
process.removeListener("SIGINT", close);
|
|
2824
|
+
process.removeListener("SIGTERM", close);
|
|
2825
|
+
}
|
|
2826
|
+
};
|
|
2449
2827
|
}
|
|
2450
2828
|
async function findViteApplicationRoots(root, startDirectory) {
|
|
2451
2829
|
const applicationRoot = startDirectory ? await findViteApplicationRootFrom(startDirectory, root) : void 0;
|
|
@@ -2458,7 +2836,7 @@ async function findViteApplicationRoots(root, startDirectory) {
|
|
|
2458
2836
|
if (await hasViteConfig(directory)) applicationRoots.push(directory);
|
|
2459
2837
|
const entries = await fs7.readdir(directory, { withFileTypes: true });
|
|
2460
2838
|
for (const entry of entries) {
|
|
2461
|
-
if (!entry.isDirectory() ||
|
|
2839
|
+
if (!entry.isDirectory() || ignoredApplicationRootDirectoryNames.has(entry.name)) {
|
|
2462
2840
|
continue;
|
|
2463
2841
|
}
|
|
2464
2842
|
directories.push(path9.join(directory, entry.name));
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ResolvedRiebeckiteConfig } from "@riebeckite/core";
|
|
2
2
|
import type { Plugin } from "vite";
|
|
3
|
-
export declare function riebeckiteClientModule(getConfig: () => Pick<ResolvedRiebeckiteConfig, "plugins">): Plugin;
|
|
3
|
+
export declare function riebeckiteClientModule(getConfig: () => Pick<ResolvedRiebeckiteConfig, "plugins" | "spa">): Plugin;
|
|
@@ -128,20 +128,26 @@ function PluginHeadTags(props) {
|
|
|
128
128
|
function renderPluginHeadTag(tag, index) {
|
|
129
129
|
const key = `${tag.tag}-${index}`;
|
|
130
130
|
if (tag.tag === "meta") {
|
|
131
|
-
return /* @__PURE__ */ createElement("meta", { ...tag.attrs, key });
|
|
131
|
+
return /* @__PURE__ */ createElement("meta", { ...tag.attrs, "data-riebeckite-head": "page", key });
|
|
132
132
|
}
|
|
133
133
|
if (tag.tag === "link") {
|
|
134
|
-
return /* @__PURE__ */ createElement("link", { ...tag.attrs, key });
|
|
134
|
+
return /* @__PURE__ */ createElement("link", { ...tag.attrs, "data-riebeckite-head": "page", key });
|
|
135
135
|
}
|
|
136
136
|
return /* @__PURE__ */ createElement(
|
|
137
137
|
"script",
|
|
138
138
|
{
|
|
139
139
|
...tag.attrs,
|
|
140
|
+
"data-riebeckite-head": isDataScript(tag) ? "page" : void 0,
|
|
140
141
|
key,
|
|
141
142
|
dangerouslySetInnerHTML: tag.children ? { __html: tag.children } : void 0
|
|
142
143
|
}
|
|
143
144
|
);
|
|
144
145
|
}
|
|
146
|
+
function isDataScript(tag) {
|
|
147
|
+
if (tag.tag !== "script") return false;
|
|
148
|
+
const type = tag.attrs?.type?.trim().toLowerCase();
|
|
149
|
+
return type === "application/ld+json" || type === "application/json";
|
|
150
|
+
}
|
|
145
151
|
function RiebeckiteHead(props) {
|
|
146
152
|
const site = useSiteContext();
|
|
147
153
|
const faviconHref = props.faviconHref === void 0 ? "/favicon.ico" : props.faviconHref;
|
|
@@ -8,7 +8,7 @@ export type HonoxApplicationOptions = {
|
|
|
8
8
|
open?: boolean;
|
|
9
9
|
port?: number;
|
|
10
10
|
};
|
|
11
|
-
onServerReady?: (urls: readonly string[]) => void
|
|
11
|
+
onServerReady?: (urls: readonly string[]) => void | Promise<void>;
|
|
12
12
|
restartOnChange?: readonly string[];
|
|
13
13
|
};
|
|
14
14
|
export type ResolvedHonoxApplication = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riebeckite/honox",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.32",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -44,14 +44,15 @@
|
|
|
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/diagnostics": "0.0.
|
|
49
|
-
"@riebeckite/plugin-color-mode": "0.0.
|
|
50
|
-
"@riebeckite/ui": "0.0.
|
|
47
|
+
"@riebeckite/core": "0.0.32",
|
|
48
|
+
"@riebeckite/diagnostics": "0.0.32",
|
|
49
|
+
"@riebeckite/plugin-color-mode": "0.0.32",
|
|
50
|
+
"@riebeckite/ui": "0.0.32",
|
|
51
|
+
"@riebeckite/spa": "0.0.32"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"tsx": "^4.22.4",
|
|
54
|
-
"@riebeckite/test": "0.0.
|
|
55
|
+
"@riebeckite/test": "0.0.32"
|
|
55
56
|
},
|
|
56
57
|
"publishConfig": {
|
|
57
58
|
"access": "public"
|