@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 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
- ([outputPath, checksum]) => isSafeLogicalOutputPath(outputPath) && isChecksum(checksum)
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
- ([outputPath, entry]) => isSafeLogicalOutputPath(outputPath) && typeof entry === "object" && entry !== null && typeof entry.cachePath === "string" && entry.cachePath === outputCacheEntryName(outputPath) && isChecksum(entry.checksum)
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 outputPath of Object.keys(outputs).sort()) {
1188
- assertSafeLogicalOutputPath(outputPath);
1189
- const existing = outputs[outputPath];
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(outputPath) || !isChecksum(existing.checksum)) {
1192
- throw new Error(`Invalid SSG output cache entry: ${outputPath}`);
1191
+ if (existing.cachePath !== outputCacheEntryName(outputPath2) || !isChecksum(existing.checksum)) {
1192
+ throw new Error(`Invalid SSG output cache entry: ${outputPath2}`);
1193
1193
  }
1194
- entries[outputPath] = existing;
1194
+ entries[outputPath2] = existing;
1195
1195
  continue;
1196
1196
  }
1197
- const source = resolveOutputCacheFile(outputDirectory, outputPath);
1198
- const cachePath = outputCacheEntryName(outputPath);
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?.[outputPath];
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: ${outputPath}`);
1206
+ throw new Error(`Could not checksum cached output: ${outputPath2}`);
1207
1207
  }
1208
- entries[outputPath] = { cachePath, checksum: cachedChecksum };
1208
+ entries[outputPath2] = { cachePath, checksum: cachedChecksum };
1209
1209
  continue;
1210
1210
  }
1211
- entries[outputPath] = { cachePath, checksum };
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 [outputPath, entry] of Object.entries(entries)) {
1220
- if (!isSafeLogicalOutputPath(outputPath) || entry.cachePath !== outputCacheEntryName(outputPath) || !isChecksum(entry.checksum)) {
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(outputPath) {
1362
- return createHash3("sha256").update(outputPath).digest("hex");
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((outputPath) => !siteOwnedOutputPaths.has(outputPath)).sort();
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 initializers = [];
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 initializer = publicConfig === void 0 ? `${localName}()` : `${localName}(${serializePublicClientConfig(publicConfig)})`;
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
- `runPluginClientInitializer(${JSON.stringify(entry.moduleSpecifier)}, () => ${initializer})`
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
- function runPluginClientInitializer(name, initialize) {
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 result = initialize();
2110
- if (result && typeof result.then === "function") {
2111
- result.catch((error) => reportPluginClientError(name, error));
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 reportPluginClientError(name, error) {
2119
- console.error("[riebeckite] Plugin client initializer failed: " + name, error);
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
- export function initRiebeckiteClient() {
2123
- ${initializers.map((initializer) => ` ${initializer};`).join("\n")}
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) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" })[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
- options.onServerReady?.([
2757
+ const urls = [
2200
2758
  ...server.resolvedUrls?.local ?? [],
2201
2759
  ...server.resolvedUrls?.network ?? []
2202
- ]);
2203
- server.printUrls();
2204
- await waitForShutdown(server);
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
- async function waitForShutdown(server) {
2236
- await new Promise((resolve3) => {
2237
- const close = () => {
2238
- void server.close().finally(resolve3);
2239
- };
2240
- process.once("SIGINT", close);
2241
- process.once("SIGTERM", close);
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() || entry.name === "node_modules" || entry.name === ".git" || entry.name === "tests") {
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 { type ResolvedRiebeckiteConfig } from "@riebeckite/core";
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;
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from "vite";
2
+ import type { ResolvedHonoxApplication } from "./vite_runner.js";
3
+ export declare function riebeckiteDevelopmentInspector(getApplication: () => ResolvedHonoxApplication): 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
- const dataSlot = props["data-slot"] ?? "article-body";
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.30",
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.30",
48
- "@riebeckite/ui": "0.0.30",
49
- "@riebeckite/plugin-color-mode": "0.0.30"
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.30"
55
+ "@riebeckite/test": "0.0.32"
54
56
  },
55
57
  "publishConfig": {
56
58
  "access": "public"