@riebeckite/honox 0.0.30 → 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 +635 -50
- 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/ui/primitives.d.ts +0 -2
- package/dist/src/ui/primitives.js +10 -12
- package/dist/src/vite_runner.d.ts +1 -1
- package/package.json +7 -5
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
|
|
@@ -2069,27 +2069,41 @@ function isNotFoundError2(error) {
|
|
|
2069
2069
|
}
|
|
2070
2070
|
|
|
2071
2071
|
// src/client_module.ts
|
|
2072
|
-
import {
|
|
2073
|
-
serializePublicClientConfig
|
|
2074
|
-
} from "@riebeckite/core";
|
|
2072
|
+
import { serializePublicClientConfig } from "@riebeckite/core";
|
|
2075
2073
|
var clientModuleId = "virtual:riebeckite/client";
|
|
2076
2074
|
var resolvedClientModuleId = `\0${clientModuleId}`;
|
|
2077
2075
|
function riebeckiteClientModule(getConfig) {
|
|
2076
|
+
let development = false;
|
|
2078
2077
|
return {
|
|
2079
2078
|
name: "riebeckite-client-module",
|
|
2079
|
+
config(_config, environment) {
|
|
2080
|
+
development = environment.command === "serve";
|
|
2081
|
+
},
|
|
2080
2082
|
resolveId(id) {
|
|
2081
2083
|
if (id === clientModuleId) return resolvedClientModuleId;
|
|
2082
2084
|
return null;
|
|
2083
2085
|
},
|
|
2084
2086
|
load(id) {
|
|
2085
2087
|
if (id !== resolvedClientModuleId) return null;
|
|
2086
|
-
return createClientModule(getConfig());
|
|
2088
|
+
return createClientModule(getConfig(), development);
|
|
2087
2089
|
}
|
|
2088
2090
|
};
|
|
2089
2091
|
}
|
|
2090
|
-
function createClientModule(config) {
|
|
2092
|
+
function createClientModule(config, development) {
|
|
2091
2093
|
const imports = [];
|
|
2092
|
-
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
|
+
}
|
|
2101
|
+
if (development) {
|
|
2102
|
+
imports.push(
|
|
2103
|
+
'import { initDevelopmentInspector } from "virtual:riebeckite/development-inspector";'
|
|
2104
|
+
);
|
|
2105
|
+
appInitializers.push("initDevelopmentInspector()");
|
|
2106
|
+
}
|
|
2093
2107
|
for (const [index, entry] of config.plugins.flatMap((plugin) => plugin.clientEntries ?? []).entries()) {
|
|
2094
2108
|
const localName = `pluginClientInitializer${index}`;
|
|
2095
2109
|
const importTarget = entry.exportName ? `{ ${entry.exportName} as ${localName} }` : localName;
|
|
@@ -2097,31 +2111,567 @@ function createClientModule(config) {
|
|
|
2097
2111
|
`import ${importTarget} from ${JSON.stringify(entry.moduleSpecifier)};`
|
|
2098
2112
|
);
|
|
2099
2113
|
const publicConfig = entry.publicConfig;
|
|
2100
|
-
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;
|
|
2101
2117
|
initializers.push(
|
|
2102
|
-
`
|
|
2118
|
+
`mountPluginClientInitializer(${JSON.stringify(entry.scope ?? "page")}, ${JSON.stringify(entry.moduleSpecifier)}, root, ${serializedConfig}, (context) => ${initializer})`
|
|
2103
2119
|
);
|
|
2104
2120
|
}
|
|
2105
2121
|
return `${imports.join("\n")}
|
|
2106
2122
|
|
|
2107
|
-
|
|
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")}
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
function mountPageClientInitializers(root) {
|
|
2135
|
+
${pageInitializers.map((initializer) => ` ${initializer};`).join("\n")}
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
export function initRiebeckiteClient() {
|
|
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();
|
|
2162
|
+
}
|
|
2163
|
+
`;
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
// src/development_inspector.ts
|
|
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";
|
|
2177
|
+
var clientModuleId2 = "virtual:riebeckite/development-inspector";
|
|
2178
|
+
var resolvedClientModuleId2 = `\0${clientModuleId2}`;
|
|
2179
|
+
var reportPath = "/__riebeckite/inspector/report";
|
|
2180
|
+
var outputPath = "/__riebeckite/inspector/output";
|
|
2181
|
+
var listedOutputLimit = 20;
|
|
2182
|
+
function riebeckiteDevelopmentInspector(getApplication) {
|
|
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
|
+
};
|
|
2231
|
+
return {
|
|
2232
|
+
name: "riebeckite-development-inspector",
|
|
2233
|
+
apply: "serve",
|
|
2234
|
+
enforce: "pre",
|
|
2235
|
+
resolveId(id) {
|
|
2236
|
+
return id === clientModuleId2 ? resolvedClientModuleId2 : null;
|
|
2237
|
+
},
|
|
2238
|
+
load(id) {
|
|
2239
|
+
return id === resolvedClientModuleId2 ? inspectorClientModule() : null;
|
|
2240
|
+
},
|
|
2241
|
+
configureServer(server) {
|
|
2242
|
+
const reportMiddleware = async (request, response) => {
|
|
2243
|
+
if (!isLocalRequest(request.headers.host, server)) {
|
|
2244
|
+
response.statusCode = 403;
|
|
2245
|
+
response.end();
|
|
2246
|
+
return;
|
|
2247
|
+
}
|
|
2248
|
+
try {
|
|
2249
|
+
const application = getApplication();
|
|
2250
|
+
const report = await inspectApplication(application, revision).report;
|
|
2251
|
+
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
2252
|
+
response.setHeader("cache-control", "no-store");
|
|
2253
|
+
response.end(
|
|
2254
|
+
JSON.stringify({
|
|
2255
|
+
...report,
|
|
2256
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2257
|
+
currentPage: currentPageFromRequest(request.url),
|
|
2258
|
+
theme: application.config.theme.name,
|
|
2259
|
+
plugins: application.config.plugins.map((plugin) => plugin.name)
|
|
2260
|
+
})
|
|
2261
|
+
);
|
|
2262
|
+
} catch {
|
|
2263
|
+
response.statusCode = 500;
|
|
2264
|
+
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
2265
|
+
response.end(JSON.stringify({ code: "INSPECTOR_REPORT_FAILED" }));
|
|
2266
|
+
}
|
|
2267
|
+
};
|
|
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
|
+
};
|
|
2301
|
+
},
|
|
2302
|
+
handleHotUpdate({ server }) {
|
|
2303
|
+
revision += 1;
|
|
2304
|
+
server.hot.send({ type: "custom", event: "riebeckite:inspector" });
|
|
2305
|
+
}
|
|
2306
|
+
};
|
|
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) {
|
|
2108
2317
|
try {
|
|
2109
|
-
const
|
|
2110
|
-
|
|
2111
|
-
|
|
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;
|
|
2112
2390
|
}
|
|
2113
|
-
} catch (error) {
|
|
2114
|
-
reportPluginClientError(name, error);
|
|
2115
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
|
+
};
|
|
2116
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
|
+
}
|
|
2434
|
+
function currentPageFromRequest(url) {
|
|
2435
|
+
const value = new URL(url ?? reportPath, "http://localhost").searchParams.get(
|
|
2436
|
+
"path"
|
|
2437
|
+
);
|
|
2438
|
+
return value?.startsWith("/") && !value.startsWith("//") ? value : "/";
|
|
2439
|
+
}
|
|
2440
|
+
function prioritizeMiddleware(server, middleware, path11) {
|
|
2441
|
+
const stack = server.middlewares.stack;
|
|
2442
|
+
const index = stack?.findIndex(
|
|
2443
|
+
(layer) => layer.handle === middleware || layer.route === path11
|
|
2444
|
+
) ?? -1;
|
|
2445
|
+
if (index > 0 && stack) stack.unshift(...stack.splice(index, 1));
|
|
2446
|
+
}
|
|
2447
|
+
function isLocalRequest(host, server) {
|
|
2448
|
+
if (!host) return false;
|
|
2449
|
+
const hostname = host.replace(/:\d+$/, "").toLowerCase();
|
|
2450
|
+
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]")
|
|
2451
|
+
return true;
|
|
2452
|
+
const address = server.httpServer?.address();
|
|
2453
|
+
return typeof address === "object" && address?.address === hostname;
|
|
2454
|
+
}
|
|
2455
|
+
function inspectorClientModule() {
|
|
2456
|
+
return `
|
|
2457
|
+
const reportEndpoint = ${JSON.stringify(reportPath)};
|
|
2458
|
+
const outputEndpoint = ${JSON.stringify(outputPath)};
|
|
2459
|
+
const panelId = "riebeckite-development-inspector";
|
|
2117
2460
|
|
|
2118
|
-
function
|
|
2119
|
-
|
|
2461
|
+
export function initDevelopmentInspector() {
|
|
2462
|
+
let panel;
|
|
2463
|
+
let launcher;
|
|
2464
|
+
let controller;
|
|
2465
|
+
let generation = 0;
|
|
2466
|
+
let report;
|
|
2467
|
+
let activeTab = 0;
|
|
2468
|
+
let refreshing = false;
|
|
2469
|
+
let pendingRefresh = false;
|
|
2470
|
+
let loadingTimer;
|
|
2471
|
+
const tabs = ["Overview", "Diagnostics", "Dependencies", "Plugins", "Output"];
|
|
2472
|
+
const refresh = async () => {
|
|
2473
|
+
if (!panel?.isConnected) return;
|
|
2474
|
+
if (refreshing) {
|
|
2475
|
+
pendingRefresh = true;
|
|
2476
|
+
return;
|
|
2477
|
+
}
|
|
2478
|
+
refreshing = true;
|
|
2479
|
+
controller?.abort();
|
|
2480
|
+
controller = new AbortController();
|
|
2481
|
+
const current = ++generation;
|
|
2482
|
+
try {
|
|
2483
|
+
const response = await fetch(reportEndpoint + "?path=" + encodeURIComponent(location.pathname), { cache: "no-store", signal: controller.signal });
|
|
2484
|
+
if (!response.ok) throw new Error("Inspector report is unavailable.");
|
|
2485
|
+
const next = await response.json();
|
|
2486
|
+
if (current !== generation || !panel?.isConnected) return;
|
|
2487
|
+
report = next;
|
|
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();
|
|
2514
|
+
} catch (error) {
|
|
2515
|
+
if (error.name === "AbortError" || current !== generation) return;
|
|
2516
|
+
report.output = { status: "unavailable", reason: "output inspection failed" };
|
|
2517
|
+
report.dependencies = { status: "unavailable", reason: "dependency inspection failed" };
|
|
2518
|
+
render();
|
|
2519
|
+
}
|
|
2520
|
+
};
|
|
2521
|
+
const open = () => {
|
|
2522
|
+
if (!panel) {
|
|
2523
|
+
panel = document.createElement("div");
|
|
2524
|
+
panel.id = panelId;
|
|
2525
|
+
panel.attachShadow({ mode: "open" });
|
|
2526
|
+
}
|
|
2527
|
+
if (!panel.isConnected) document.body.append(panel);
|
|
2528
|
+
showLoading();
|
|
2529
|
+
void refresh();
|
|
2530
|
+
};
|
|
2531
|
+
const close = () => {
|
|
2532
|
+
generation += 1;
|
|
2533
|
+
pendingRefresh = false;
|
|
2534
|
+
controller?.abort();
|
|
2535
|
+
clearInterval(loadingTimer);
|
|
2536
|
+
panel?.remove();
|
|
2537
|
+
launcher?.focus();
|
|
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
|
+
};
|
|
2550
|
+
launcher = document.createElement("button");
|
|
2551
|
+
launcher.type = "button";
|
|
2552
|
+
launcher.textContent = "Inspector";
|
|
2553
|
+
launcher.setAttribute("aria-label", "Open Riebeckite Development Inspector");
|
|
2554
|
+
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";
|
|
2555
|
+
launcher.addEventListener("click", open);
|
|
2556
|
+
document.body.append(launcher);
|
|
2557
|
+
window.addEventListener("keydown", (event) => {
|
|
2558
|
+
const editable = event.target instanceof HTMLElement && (event.target.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(event.target.tagName));
|
|
2559
|
+
if (event.key === "Escape" && panel?.isConnected) {
|
|
2560
|
+
event.preventDefault();
|
|
2561
|
+
close();
|
|
2562
|
+
} else if (event.key.toLowerCase() === "r" && event.ctrlKey && event.altKey && !editable) {
|
|
2563
|
+
event.preventDefault();
|
|
2564
|
+
panel?.isConnected ? close() : open();
|
|
2565
|
+
}
|
|
2566
|
+
});
|
|
2567
|
+
import.meta.hot?.on("riebeckite:inspector", refresh);
|
|
2568
|
+
|
|
2569
|
+
function render() {
|
|
2570
|
+
clearInterval(loadingTimer);
|
|
2571
|
+
const root = panel.shadowRoot;
|
|
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>';
|
|
2573
|
+
root.querySelector("[data-close]").addEventListener("click", close);
|
|
2574
|
+
root.querySelectorAll("[data-tab]").forEach((button) => button.addEventListener("click", () => { activeTab = Number(button.dataset.tab); render(); }));
|
|
2575
|
+
root.querySelector("[role=tablist]").addEventListener("keydown", (event) => {
|
|
2576
|
+
if (event.key === "Home") activeTab = 0;
|
|
2577
|
+
else if (event.key === "End") activeTab = tabs.length - 1;
|
|
2578
|
+
else if (event.key === "ArrowRight" || event.key === "ArrowDown") activeTab = (activeTab + 1) % tabs.length;
|
|
2579
|
+
else if (event.key === "ArrowLeft" || event.key === "ArrowUp") activeTab = (activeTab + tabs.length - 1) % tabs.length;
|
|
2580
|
+
else return;
|
|
2581
|
+
event.preventDefault(); render(); root.querySelector('[data-tab="' + activeTab + '"]').focus();
|
|
2582
|
+
});
|
|
2583
|
+
}
|
|
2584
|
+
function panelContent() {
|
|
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>';
|
|
2586
|
+
if (activeTab === 1) return diagnosticList(report.diagnostics);
|
|
2587
|
+
if (activeTab === 2) return dependencyReport(report.dependencies);
|
|
2588
|
+
if (activeTab === 3) return '<ul>' + (report.plugins.map((plugin) => '<li>' + escapeHtml(plugin) + '</li>').join("") || "<li>No plugins configured.</li>") + '</ul>';
|
|
2589
|
+
return outputReport(report.output);
|
|
2590
|
+
}
|
|
2120
2591
|
}
|
|
2121
2592
|
|
|
2122
|
-
|
|
2123
|
-
|
|
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
|
+
|
|
2601
|
+
function diagnosticList(diagnostics) {
|
|
2602
|
+
return '<ul>' + (diagnostics.map((diagnostic) =>
|
|
2603
|
+
'<li data-severity="' + escapeHtml(diagnostic.severity) + '"><b>' + escapeHtml(diagnostic.code) + '</b> ' + escapeHtml(diagnostic.message) + location(diagnostic) + '</li>'
|
|
2604
|
+
).join("") || "<li>No diagnostic findings.</li>") + '</ul>';
|
|
2605
|
+
}
|
|
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
|
+
|
|
2657
|
+
function unavailable(subject, capability) {
|
|
2658
|
+
return '<p class="partial">' + escapeHtml(subject) + ' unavailable: ' + escapeHtml(capability) + '.</p>';
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
function renderFailure(root, message) {
|
|
2662
|
+
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>';
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2665
|
+
function location(diagnostic) {
|
|
2666
|
+
const location = diagnostic.location;
|
|
2667
|
+
return location?.file ? ' <small>(' + escapeHtml(location.file) + (location.line ? ':' + location.line : '') + ')</small>' : '';
|
|
2668
|
+
}
|
|
2669
|
+
|
|
2670
|
+
function escapeHtml(value) {
|
|
2671
|
+
return String(value).replace(/[&<>"]/g, (character) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[character]);
|
|
2124
2672
|
}
|
|
2673
|
+
|
|
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}}';
|
|
2125
2675
|
`;
|
|
2126
2676
|
}
|
|
2127
2677
|
|
|
@@ -2134,6 +2684,14 @@ var viteConfigFileNames = [
|
|
|
2134
2684
|
"vite.config.js",
|
|
2135
2685
|
"vite.config.mjs"
|
|
2136
2686
|
];
|
|
2687
|
+
var ignoredApplicationRootDirectoryNames = /* @__PURE__ */ new Set([
|
|
2688
|
+
".git",
|
|
2689
|
+
".riebeckite",
|
|
2690
|
+
"node_modules",
|
|
2691
|
+
"test",
|
|
2692
|
+
"tests",
|
|
2693
|
+
"templates"
|
|
2694
|
+
]);
|
|
2137
2695
|
async function resolveHonoxApplicationRoot(configRoot, startDirectory) {
|
|
2138
2696
|
const roots = await findViteApplicationRoots(configRoot, startDirectory);
|
|
2139
2697
|
if (roots.length === 1) return roots[0];
|
|
@@ -2196,12 +2754,24 @@ async function startHonoxDevServer(options) {
|
|
|
2196
2754
|
});
|
|
2197
2755
|
}
|
|
2198
2756
|
await server.listen(options.server?.port);
|
|
2199
|
-
|
|
2757
|
+
const urls = [
|
|
2200
2758
|
...server.resolvedUrls?.local ?? [],
|
|
2201
2759
|
...server.resolvedUrls?.network ?? []
|
|
2202
|
-
]
|
|
2203
|
-
server
|
|
2204
|
-
|
|
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;
|
|
2205
2775
|
});
|
|
2206
2776
|
}
|
|
2207
2777
|
async function buildHonoxApplication(options) {
|
|
@@ -2232,14 +2802,28 @@ async function withWorkingDirectory(root, task) {
|
|
|
2232
2802
|
async function runTraced(tracer, name, buildTask) {
|
|
2233
2803
|
return tracer ? await tracer.span(name, {}, buildTask) : await buildTask();
|
|
2234
2804
|
}
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
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;
|
|
2242
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
|
+
};
|
|
2243
2827
|
}
|
|
2244
2828
|
async function findViteApplicationRoots(root, startDirectory) {
|
|
2245
2829
|
const applicationRoot = startDirectory ? await findViteApplicationRootFrom(startDirectory, root) : void 0;
|
|
@@ -2252,7 +2836,7 @@ async function findViteApplicationRoots(root, startDirectory) {
|
|
|
2252
2836
|
if (await hasViteConfig(directory)) applicationRoots.push(directory);
|
|
2253
2837
|
const entries = await fs7.readdir(directory, { withFileTypes: true });
|
|
2254
2838
|
for (const entry of entries) {
|
|
2255
|
-
if (!entry.isDirectory() ||
|
|
2839
|
+
if (!entry.isDirectory() || ignoredApplicationRootDirectoryNames.has(entry.name)) {
|
|
2256
2840
|
continue;
|
|
2257
2841
|
}
|
|
2258
2842
|
directories.push(path9.join(directory, entry.name));
|
|
@@ -2356,7 +2940,8 @@ function riebeckite(options = {}, onApplicationResolved) {
|
|
|
2356
2940
|
appRoot: () => requireApplication(application).appRoot,
|
|
2357
2941
|
contentRoot: () => requireApplication(application).contentRoot,
|
|
2358
2942
|
exclude: () => getConfig().content.exclude ?? []
|
|
2359
|
-
})
|
|
2943
|
+
}),
|
|
2944
|
+
riebeckiteDevelopmentInspector(() => requireApplication(application))
|
|
2360
2945
|
];
|
|
2361
2946
|
}
|
|
2362
2947
|
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" | "spa">): Plugin;
|
|
@@ -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);
|
|
@@ -136,20 +128,26 @@ function PluginHeadTags(props) {
|
|
|
136
128
|
function renderPluginHeadTag(tag, index) {
|
|
137
129
|
const key = `${tag.tag}-${index}`;
|
|
138
130
|
if (tag.tag === "meta") {
|
|
139
|
-
return /* @__PURE__ */ createElement("meta", { ...tag.attrs, key });
|
|
131
|
+
return /* @__PURE__ */ createElement("meta", { ...tag.attrs, "data-riebeckite-head": "page", key });
|
|
140
132
|
}
|
|
141
133
|
if (tag.tag === "link") {
|
|
142
|
-
return /* @__PURE__ */ createElement("link", { ...tag.attrs, key });
|
|
134
|
+
return /* @__PURE__ */ createElement("link", { ...tag.attrs, "data-riebeckite-head": "page", key });
|
|
143
135
|
}
|
|
144
136
|
return /* @__PURE__ */ createElement(
|
|
145
137
|
"script",
|
|
146
138
|
{
|
|
147
139
|
...tag.attrs,
|
|
140
|
+
"data-riebeckite-head": isDataScript(tag) ? "page" : void 0,
|
|
148
141
|
key,
|
|
149
142
|
dangerouslySetInnerHTML: tag.children ? { __html: tag.children } : void 0
|
|
150
143
|
}
|
|
151
144
|
);
|
|
152
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
|
+
}
|
|
153
151
|
function RiebeckiteHead(props) {
|
|
154
152
|
const site = useSiteContext();
|
|
155
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,13 +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/
|
|
49
|
-
"@riebeckite/plugin-color-mode": "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"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
54
|
"tsx": "^4.22.4",
|
|
53
|
-
"@riebeckite/test": "0.0.
|
|
55
|
+
"@riebeckite/test": "0.0.32"
|
|
54
56
|
},
|
|
55
57
|
"publishConfig": {
|
|
56
58
|
"access": "public"
|