@riebeckite/honox 0.0.32 → 0.0.33
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 +82 -60
- package/dist/server.js +6 -0
- package/dist/src/asset_entries.d.ts +2 -1
- package/dist/src/content_assets.d.ts +1 -1
- package/dist/src/content_watch.d.ts +2 -1
- package/dist/src/endpoints.d.ts +1 -1
- package/dist/src/ssg/output_cache.d.ts +2 -2
- package/dist/src/ssg/types.d.ts +3 -2
- package/dist/src/ui/primitives.d.ts +36 -18
- package/dist/src/ui/primitives.js +221 -0
- package/dist/src/vite_runner.d.ts +2 -1
- package/package.json +10 -9
- package/style.css +249 -0
package/dist/index.js
CHANGED
|
@@ -293,20 +293,17 @@ import {
|
|
|
293
293
|
// src/content_assets.ts
|
|
294
294
|
import fs5 from "node:fs/promises";
|
|
295
295
|
import path7 from "node:path";
|
|
296
|
-
import {
|
|
297
|
-
|
|
298
|
-
isImagePath as isImagePath2,
|
|
299
|
-
normalizeContentPath as normalizeContentPath2
|
|
300
|
-
} from "@riebeckite/core";
|
|
296
|
+
import { isImagePath as isImagePath2, normalizeContentPath as normalizeContentPath2 } from "@riebeckite/core";
|
|
297
|
+
import { isIgnoredContentPath as isIgnoredContentPath2 } from "@riebeckite/node";
|
|
301
298
|
|
|
302
299
|
// src/content_watch.ts
|
|
303
300
|
import path6 from "node:path";
|
|
304
301
|
import {
|
|
305
302
|
isAttachmentPath,
|
|
306
|
-
isIgnoredContentPath,
|
|
307
303
|
isImagePath,
|
|
308
304
|
normalizeContentPath
|
|
309
305
|
} from "@riebeckite/core";
|
|
306
|
+
import { isIgnoredContentPath } from "@riebeckite/node";
|
|
310
307
|
|
|
311
308
|
// src/runtime_modules.ts
|
|
312
309
|
var riebeckiteConfigModuleId = "virtual:riebeckite/config";
|
|
@@ -355,11 +352,15 @@ export const config = resolveHonoxConfig(
|
|
|
355
352
|
}
|
|
356
353
|
function createContentModule() {
|
|
357
354
|
return `import { ContentManager } from "@riebeckite/core";
|
|
355
|
+
import { FileSystemContentSource } from "@riebeckite/node";
|
|
358
356
|
import { config } from ${JSON.stringify(riebeckiteConfigModuleId)};
|
|
359
357
|
|
|
360
358
|
export const content = new ContentManager(
|
|
361
|
-
config.content.
|
|
362
|
-
|
|
359
|
+
config.content.source ?? new FileSystemContentSource(
|
|
360
|
+
config.content.directory,
|
|
361
|
+
config.content.exclude,
|
|
362
|
+
),
|
|
363
|
+
[],
|
|
363
364
|
{ config, plugins: config.plugins },
|
|
364
365
|
);
|
|
365
366
|
`;
|
|
@@ -996,7 +997,7 @@ async function writeSsgOutputMetrics(metrics) {
|
|
|
996
997
|
}
|
|
997
998
|
|
|
998
999
|
// src/ssg/output_cache.ts
|
|
999
|
-
var
|
|
1000
|
+
var outputCacheValidationConcurrency = 12;
|
|
1000
1001
|
function decideOutputCacheRejection(decision) {
|
|
1001
1002
|
if (!decision.changeSetPresent) return "change-set-unavailable";
|
|
1002
1003
|
if (decision.changeSetRequiresFullRegeneration)
|
|
@@ -1112,7 +1113,6 @@ async function saveOutputCache(path11, state, outputDirectory, timingsMs) {
|
|
|
1112
1113
|
const entriesPath = outputCacheEntriesPath(path11);
|
|
1113
1114
|
const temporaryPath = `${path11}.${randomUUID2()}.tmp`;
|
|
1114
1115
|
try {
|
|
1115
|
-
await waitForFaultInjection("metadata-save-start");
|
|
1116
1116
|
const outputs = await measure(
|
|
1117
1117
|
timingsMs,
|
|
1118
1118
|
"outputCacheEntriesWrite",
|
|
@@ -1140,7 +1140,6 @@ async function saveOutputCache(path11, state, outputDirectory, timingsMs) {
|
|
|
1140
1140
|
"outputCacheRename",
|
|
1141
1141
|
() => replaceFile(temporaryPath, path11)
|
|
1142
1142
|
);
|
|
1143
|
-
await waitForFaultInjection("metadata-committed");
|
|
1144
1143
|
const checksum = createHash3("sha256").update(serialized).digest("hex");
|
|
1145
1144
|
if (state.finalOutputInventory && state.configFile) {
|
|
1146
1145
|
await saveFastPathCache(
|
|
@@ -1197,7 +1196,6 @@ async function saveOutputCacheEntries(directory, outputDirectory, outputs, final
|
|
|
1197
1196
|
const source = resolveOutputCacheFile(outputDirectory, outputPath2);
|
|
1198
1197
|
const cachePath = outputCacheEntryName(outputPath2);
|
|
1199
1198
|
const destination = join3(directory, cachePath);
|
|
1200
|
-
await waitForFaultInjection("entry-create-start");
|
|
1201
1199
|
await replaceOutputCacheEntry(source, destination, timingsMs);
|
|
1202
1200
|
const checksum = finalOutputInventory?.[outputPath2];
|
|
1203
1201
|
if (!checksum) {
|
|
@@ -1216,20 +1214,43 @@ async function validateOutputCacheEntries(outputCachePath, entries, timingsMs) {
|
|
|
1216
1214
|
try {
|
|
1217
1215
|
const directory = outputCacheEntriesPath(outputCachePath);
|
|
1218
1216
|
if (!await isSafeOutputCacheEntriesDirectory(directory)) return false;
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1217
|
+
const entriesToValidate = Object.entries(entries);
|
|
1218
|
+
let nextEntryIndex = 0;
|
|
1219
|
+
let valid = true;
|
|
1220
|
+
const validateEntry = async () => {
|
|
1221
|
+
while (valid) {
|
|
1222
|
+
const next = entriesToValidate[nextEntryIndex++];
|
|
1223
|
+
if (!next) return;
|
|
1224
|
+
const [outputPath2, entry] = next;
|
|
1225
|
+
if (!isSafeLogicalOutputPath(outputPath2) || entry.cachePath !== outputCacheEntryName(outputPath2) || !isChecksum(entry.checksum)) {
|
|
1226
|
+
valid = false;
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1229
|
+
const path11 = resolveOutputCacheFile(directory, entry.cachePath);
|
|
1230
|
+
if (!await isRegularFile(path11)) {
|
|
1231
|
+
valid = false;
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
if (await measure(
|
|
1235
|
+
timingsMs,
|
|
1236
|
+
"outputCacheEntryChecksum",
|
|
1237
|
+
() => checksumFile(path11)
|
|
1238
|
+
) !== entry.checksum)
|
|
1239
|
+
valid = false;
|
|
1222
1240
|
}
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1241
|
+
};
|
|
1242
|
+
await Promise.all(
|
|
1243
|
+
Array.from(
|
|
1244
|
+
{
|
|
1245
|
+
length: Math.min(
|
|
1246
|
+
outputCacheValidationConcurrency,
|
|
1247
|
+
entriesToValidate.length
|
|
1248
|
+
)
|
|
1249
|
+
},
|
|
1250
|
+
validateEntry
|
|
1251
|
+
)
|
|
1252
|
+
);
|
|
1253
|
+
return valid;
|
|
1233
1254
|
} catch {
|
|
1234
1255
|
return false;
|
|
1235
1256
|
}
|
|
@@ -1263,7 +1284,6 @@ async function saveFastPathCache(path11, state, timingsMs) {
|
|
|
1263
1284
|
}
|
|
1264
1285
|
const temporaryPath = `${path11}.${randomUUID2()}.tmp`;
|
|
1265
1286
|
try {
|
|
1266
|
-
await waitForFaultInjection("sidecar-save-start");
|
|
1267
1287
|
await measure(
|
|
1268
1288
|
timingsMs,
|
|
1269
1289
|
"sidecarWrite",
|
|
@@ -1275,7 +1295,6 @@ async function saveFastPathCache(path11, state, timingsMs) {
|
|
|
1275
1295
|
"sidecarRename",
|
|
1276
1296
|
() => replaceFile(temporaryPath, path11)
|
|
1277
1297
|
);
|
|
1278
|
-
await waitForFaultInjection("sidecar-committed");
|
|
1279
1298
|
} catch (error) {
|
|
1280
1299
|
await rm2(temporaryPath, { force: true }).catch(() => void 0);
|
|
1281
1300
|
throw error;
|
|
@@ -1407,19 +1426,16 @@ async function replaceOutputCacheEntry(source, destination, timingsMs) {
|
|
|
1407
1426
|
"outputCacheEntryWrite",
|
|
1408
1427
|
() => writeFile2(temporaryPath, new Uint8Array())
|
|
1409
1428
|
);
|
|
1410
|
-
await waitForFaultInjection("entry-body-write");
|
|
1411
1429
|
await measure(
|
|
1412
1430
|
timingsMs,
|
|
1413
1431
|
"outputCacheEntryCopy",
|
|
1414
1432
|
() => copyFile(source, temporaryPath)
|
|
1415
1433
|
);
|
|
1416
|
-
await waitForFaultInjection("entry-rename-before");
|
|
1417
1434
|
await measure(
|
|
1418
1435
|
timingsMs,
|
|
1419
1436
|
"outputCacheEntryRename",
|
|
1420
1437
|
() => replaceFile(temporaryPath, destination)
|
|
1421
1438
|
);
|
|
1422
|
-
await waitForFaultInjection("entry-committed");
|
|
1423
1439
|
} catch (error) {
|
|
1424
1440
|
await rm2(temporaryPath, { force: true }).catch(() => void 0);
|
|
1425
1441
|
throw error;
|
|
@@ -1428,7 +1444,6 @@ async function replaceOutputCacheEntry(source, destination, timingsMs) {
|
|
|
1428
1444
|
async function collectUnreferencedOutputCacheEntries(directory, outputs, timingsMs) {
|
|
1429
1445
|
try {
|
|
1430
1446
|
if (!await isSafeOutputCacheEntriesDirectory(directory)) return;
|
|
1431
|
-
await waitForFaultInjection("gc-start");
|
|
1432
1447
|
const referenced = new Set(
|
|
1433
1448
|
Object.values(outputs).map((entry) => entry.cachePath)
|
|
1434
1449
|
);
|
|
@@ -1443,7 +1458,6 @@ async function collectUnreferencedOutputCacheEntries(directory, outputs, timings
|
|
|
1443
1458
|
}
|
|
1444
1459
|
const path11 = join3(directory, entry.name);
|
|
1445
1460
|
if (await isRegularFile(path11)) {
|
|
1446
|
-
await waitForFaultInjection("gc-entry-delete");
|
|
1447
1461
|
await measure(
|
|
1448
1462
|
timingsMs,
|
|
1449
1463
|
"outputCacheGcDelete",
|
|
@@ -1455,25 +1469,6 @@ async function collectUnreferencedOutputCacheEntries(directory, outputs, timings
|
|
|
1455
1469
|
return;
|
|
1456
1470
|
}
|
|
1457
1471
|
}
|
|
1458
|
-
async function waitForFaultInjection(point) {
|
|
1459
|
-
if (process.env.NODE_ENV !== "test" || process.env.RIEBECKITE_SSG_FAULT_INJECTION !== "1" || process.env.RIEBECKITE_SSG_FAULT_POINT !== point) {
|
|
1460
|
-
return;
|
|
1461
|
-
}
|
|
1462
|
-
const occurrence = Number.parseInt(
|
|
1463
|
-
process.env.RIEBECKITE_SSG_FAULT_OCCURRENCE ?? "1",
|
|
1464
|
-
10
|
|
1465
|
-
);
|
|
1466
|
-
const count = (faultInjectionCounts.get(point) ?? 0) + 1;
|
|
1467
|
-
faultInjectionCounts.set(point, count);
|
|
1468
|
-
if (!Number.isSafeInteger(occurrence) || occurrence < 1 || count !== occurrence)
|
|
1469
|
-
return;
|
|
1470
|
-
const signalFile = process.env.RIEBECKITE_SSG_FAULT_SIGNAL_FILE;
|
|
1471
|
-
if (!signalFile) return;
|
|
1472
|
-
await writeFile2(signalFile, `${point}
|
|
1473
|
-
`, "utf8");
|
|
1474
|
-
await new Promise(() => {
|
|
1475
|
-
});
|
|
1476
|
-
}
|
|
1477
1472
|
|
|
1478
1473
|
// src/ssg_plugin.ts
|
|
1479
1474
|
var defaultEntry = "./src/index.tsx";
|
|
@@ -1543,8 +1538,17 @@ function riebeckiteSsg(options = {}) {
|
|
|
1543
1538
|
...config.resolve,
|
|
1544
1539
|
builtins: [...config.resolve.builtins, /^node:/]
|
|
1545
1540
|
},
|
|
1546
|
-
plugins: [
|
|
1541
|
+
plugins: [
|
|
1542
|
+
{
|
|
1543
|
+
name: "riebeckite-ssg-package-resolution",
|
|
1544
|
+
enforce: "post",
|
|
1545
|
+
configResolved(runtimeConfig) {
|
|
1546
|
+
runtimeConfig.resolve.alias = [];
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
],
|
|
1547
1550
|
build: { ssr: true },
|
|
1551
|
+
oxc: { jsx: { runtime: "automatic", importSource: "hono/jsx" } },
|
|
1548
1552
|
environments: {
|
|
1549
1553
|
ssr: { resolve: { noExternal: [/^honox(?:\/.*)?$/] } }
|
|
1550
1554
|
},
|
|
@@ -1924,14 +1928,12 @@ function riebeckiteSsg(options = {}) {
|
|
|
1924
1928
|
"publicFingerprint",
|
|
1925
1929
|
() => fingerprintDirectory(resolve2(publicDir))
|
|
1926
1930
|
) : void 0;
|
|
1927
|
-
await waitForFaultInjection("build-state-before");
|
|
1928
1931
|
await saveOutputCache(
|
|
1929
1932
|
outputCache.path,
|
|
1930
1933
|
outputCache.state,
|
|
1931
1934
|
outputCache.outDir,
|
|
1932
1935
|
outputCache.timingsMs
|
|
1933
1936
|
);
|
|
1934
|
-
await waitForFaultInjection("build-state-committed");
|
|
1935
1937
|
} catch (error) {
|
|
1936
1938
|
this.warn(
|
|
1937
1939
|
`SSG output cache could not be saved; the next build regenerates every output. ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -2107,15 +2109,24 @@ function createClientModule(config, development) {
|
|
|
2107
2109
|
for (const [index, entry] of config.plugins.flatMap((plugin) => plugin.clientEntries ?? []).entries()) {
|
|
2108
2110
|
const localName = `pluginClientInitializer${index}`;
|
|
2109
2111
|
const importTarget = entry.exportName ? `{ ${entry.exportName} as ${localName} }` : localName;
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2112
|
+
if (entry.presenceSelector === void 0) {
|
|
2113
|
+
imports.push(
|
|
2114
|
+
`import ${importTarget} from ${JSON.stringify(entry.moduleSpecifier)};`
|
|
2115
|
+
);
|
|
2116
|
+
}
|
|
2113
2117
|
const publicConfig = entry.publicConfig;
|
|
2114
2118
|
const serializedConfig = publicConfig === void 0 ? "undefined" : serializePublicClientConfig(publicConfig);
|
|
2115
2119
|
const initializer = entry.initializerArguments === "context" ? `${localName}(context)` : entry.initializerArguments === "root" ? `${localName}(context.root)` : `${localName}(context.config)`;
|
|
2116
2120
|
const initializers = entry.scope === "app" ? appInitializers : pageInitializers;
|
|
2121
|
+
if (entry.presenceSelector === void 0) {
|
|
2122
|
+
initializers.push(
|
|
2123
|
+
`mountPluginClientInitializer(${JSON.stringify(entry.scope ?? "page")}, ${JSON.stringify(entry.moduleSpecifier)}, root, ${serializedConfig}, (context) => ${initializer})`
|
|
2124
|
+
);
|
|
2125
|
+
continue;
|
|
2126
|
+
}
|
|
2127
|
+
const dynamicInitializer = entry.initializerArguments === "context" ? `initializer(context)` : entry.initializerArguments === "root" ? `initializer(context.root)` : `initializer(context.config)`;
|
|
2117
2128
|
initializers.push(
|
|
2118
|
-
`
|
|
2129
|
+
`mountConditionalPluginClientInitializer(${JSON.stringify(entry.scope ?? "page")}, ${JSON.stringify(entry.moduleSpecifier)}, root, ${serializedConfig}, ${JSON.stringify(entry.presenceSelector)}, async () => { const { ${entry.exportName ?? "default"}: initializer } = await import(${JSON.stringify(entry.moduleSpecifier)}); return (context) => ${dynamicInitializer}; })`
|
|
2119
2130
|
);
|
|
2120
2131
|
}
|
|
2121
2132
|
return `${imports.join("\n")}
|
|
@@ -2127,6 +2138,14 @@ function mountPluginClientInitializer(scope, name, root, config, initialize) {
|
|
|
2127
2138
|
void lifecycle.mount({ scope, name, root, config, initialize });
|
|
2128
2139
|
}
|
|
2129
2140
|
|
|
2141
|
+
function mountConditionalPluginClientInitializer(scope, name, root, config, presenceSelector, load) {
|
|
2142
|
+
if (!root.querySelector(presenceSelector)) return;
|
|
2143
|
+
void load().then((initialize) => {
|
|
2144
|
+
if ("isConnected" in root && !root.isConnected) return;
|
|
2145
|
+
void lifecycle.mount({ scope, name, root, config, initialize });
|
|
2146
|
+
}, (error) => console.error("[riebeckite] Client initializer module failed: " + name, error));
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2130
2149
|
function mountAppClientInitializers(root) {
|
|
2131
2150
|
${appInitializers.map((initializer) => ` ${initializer};`).join("\n")}
|
|
2132
2151
|
}
|
|
@@ -2166,14 +2185,14 @@ export async function disposeRiebeckiteClient() {
|
|
|
2166
2185
|
// src/development_inspector.ts
|
|
2167
2186
|
import {
|
|
2168
2187
|
buildOutputPlan as buildOutputPlan2,
|
|
2169
|
-
ContentManager
|
|
2170
|
-
FileSystemContentSource
|
|
2188
|
+
ContentManager
|
|
2171
2189
|
} from "@riebeckite/core";
|
|
2172
2190
|
import {
|
|
2173
2191
|
collectDevelopmentDiagnostics,
|
|
2174
2192
|
diagnoseOutputPlan,
|
|
2175
2193
|
sortDevelopmentDiagnostics
|
|
2176
2194
|
} from "@riebeckite/diagnostics";
|
|
2195
|
+
import { FileSystemContentSource } from "@riebeckite/node";
|
|
2177
2196
|
var clientModuleId2 = "virtual:riebeckite/development-inspector";
|
|
2178
2197
|
var resolvedClientModuleId2 = `\0${clientModuleId2}`;
|
|
2179
2198
|
var reportPath = "/__riebeckite/inspector/report";
|
|
@@ -2919,6 +2938,9 @@ function riebeckite(options = {}, onApplicationResolved) {
|
|
|
2919
2938
|
define: {
|
|
2920
2939
|
"process.env.RIEBECKITE_APP_ROOT": JSON.stringify(appRoot)
|
|
2921
2940
|
},
|
|
2941
|
+
oxc: {
|
|
2942
|
+
jsx: { runtime: "automatic", importSource: "hono/jsx" }
|
|
2943
|
+
},
|
|
2922
2944
|
server: {
|
|
2923
2945
|
watch: {
|
|
2924
2946
|
ignored: ["**/.riebeckite/**"]
|
package/dist/server.js
CHANGED
|
@@ -35,6 +35,11 @@ async function resolveRiebeckiteContentRequest(c, content, parameter = "slug") {
|
|
|
35
35
|
const requestedSlug = c.req.param(parameter);
|
|
36
36
|
if (!requestedSlug) return { kind: "response", response: c.notFound() };
|
|
37
37
|
if (contentExtensionPattern.test(requestedSlug)) {
|
|
38
|
+
const page = await content.resolvePage(c.req.path);
|
|
39
|
+
if (page) {
|
|
40
|
+
applyRiebeckiteRouteContext(c, { kind: "page", page });
|
|
41
|
+
return { kind: "page", page };
|
|
42
|
+
}
|
|
38
43
|
return { kind: "response", response: c.notFound() };
|
|
39
44
|
}
|
|
40
45
|
return resolveRouteRequest(c, content);
|
|
@@ -250,6 +255,7 @@ import {
|
|
|
250
255
|
} from "@riebeckite/ui";
|
|
251
256
|
|
|
252
257
|
// src/ui/primitives.tsx
|
|
258
|
+
import { escapeScriptJson, uniqueStrings } from "@riebeckite/core";
|
|
253
259
|
import { ColorModeScript } from "@riebeckite/plugin-color-mode";
|
|
254
260
|
import { raw } from "hono/html";
|
|
255
261
|
import { Link, Script } from "honox/server";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type ResolvedRiebeckiteConfig } from "@riebeckite/core";
|
|
2
|
-
|
|
2
|
+
type GeneratedAssetPaths = {
|
|
3
3
|
frameworkStyles: string;
|
|
4
4
|
pluginStyles: string;
|
|
5
5
|
themeStyles: string;
|
|
6
6
|
};
|
|
7
7
|
export declare function writeRiebeckiteAssetEntries(config: ResolvedRiebeckiteConfig, paths: GeneratedAssetPaths): void;
|
|
8
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Plugin, ViteDevServer } from "vite";
|
|
2
|
-
|
|
2
|
+
type RiebeckiteContentWatchOptions = {
|
|
3
3
|
appRoot: () => string;
|
|
4
4
|
contentRoot: () => string;
|
|
5
5
|
exclude: () => readonly string[];
|
|
@@ -9,3 +9,4 @@ export declare function isSiteAssetPath(logicalPath: string): boolean;
|
|
|
9
9
|
export declare function isPathInsideDirectory(directory: string, file: string): boolean;
|
|
10
10
|
export declare function toLogicalPath(directory: string, file: string): string;
|
|
11
11
|
export declare function invalidateApplicationRuntime(server: Pick<ViteDevServer, "environments">, appRoot: string): number;
|
|
12
|
+
export {};
|
package/dist/src/endpoints.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { NoChangeFastPathOutputMetrics, NoChangeFastPathResult, OutputCacheDecision, OutputCacheRejectionReason } from "./types.js";
|
|
2
|
-
|
|
2
|
+
type OutputCacheEntry = {
|
|
3
3
|
cachePath: string;
|
|
4
4
|
checksum: string;
|
|
5
5
|
};
|
|
@@ -26,4 +26,4 @@ export declare function loadOutputCache(path: string, timingsMs?: Record<string,
|
|
|
26
26
|
}) | undefined>;
|
|
27
27
|
export declare function saveOutputCache(path: string, state: OutputCacheState, outputDirectory: string, timingsMs?: Record<string, number>): Promise<string>;
|
|
28
28
|
export declare function decodeOutput(outputCachePath: string, entry: OutputCacheEntry): Promise<Uint8Array>;
|
|
29
|
-
export
|
|
29
|
+
export {};
|
package/dist/src/ssg/types.d.ts
CHANGED
|
@@ -5,13 +5,13 @@ export type GeneratedOutputAsset = {
|
|
|
5
5
|
fileName: string;
|
|
6
6
|
source: string | Uint8Array;
|
|
7
7
|
};
|
|
8
|
-
|
|
8
|
+
type SsgGeneratedHtmlDiagnostic = {
|
|
9
9
|
severity: "info" | "warning" | "error";
|
|
10
10
|
message: string;
|
|
11
11
|
code?: string;
|
|
12
12
|
filePath?: string;
|
|
13
13
|
};
|
|
14
|
-
|
|
14
|
+
type SsgHtmlInspectorPlugin = {
|
|
15
15
|
name?: string;
|
|
16
16
|
inspectGeneratedHtml?: (page: {
|
|
17
17
|
path: string;
|
|
@@ -125,3 +125,4 @@ export type NoChangeFastPathOutputMetrics = {
|
|
|
125
125
|
outputFilesHashed: number;
|
|
126
126
|
outputBytesHashed: number;
|
|
127
127
|
};
|
|
128
|
+
export {};
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import type { PluginHeadTag, PostContent, PublicContentEntry, ResolvedRiebeckiteConfig } from "@riebeckite/core";
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { PluginHeadTag, PostContent, PublicContentEntry, ResolvedRiebeckiteConfig, SeoMetadata } from "@riebeckite/core";
|
|
2
|
+
type PrimitiveChildren = unknown;
|
|
3
|
+
type PrimitiveProps = {
|
|
4
4
|
children?: PrimitiveChildren;
|
|
5
5
|
class?: string;
|
|
6
6
|
className?: string;
|
|
7
7
|
};
|
|
8
|
-
|
|
8
|
+
type PrimitiveClassProps = {
|
|
9
9
|
class?: string;
|
|
10
10
|
className?: string;
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
type ArticleProps = PrimitiveProps & {
|
|
13
13
|
post?: PostContent;
|
|
14
14
|
entry?: PublicContentEntry;
|
|
15
15
|
};
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
type ArticleLayoutProps = PrimitiveProps;
|
|
17
|
+
type ArticleHeaderProps = (PrimitiveClassProps & {
|
|
18
18
|
dangerouslySetInnerHTML: {
|
|
19
19
|
__html: string;
|
|
20
20
|
};
|
|
@@ -23,26 +23,26 @@ export type ArticleHeaderProps = (PrimitiveClassProps & {
|
|
|
23
23
|
dangerouslySetInnerHTML?: never;
|
|
24
24
|
children?: PrimitiveChildren;
|
|
25
25
|
});
|
|
26
|
-
|
|
26
|
+
type ArticleContentProps = PrimitiveClassProps & {
|
|
27
27
|
children?: PrimitiveChildren;
|
|
28
28
|
};
|
|
29
|
-
|
|
29
|
+
type ArticleMetaProps = PrimitiveProps & {
|
|
30
30
|
label?: string;
|
|
31
31
|
};
|
|
32
|
-
|
|
32
|
+
type SidebarProps = PrimitiveProps & {
|
|
33
33
|
label?: string;
|
|
34
34
|
};
|
|
35
|
-
|
|
35
|
+
type ArticleFooterProps = PrimitiveProps;
|
|
36
36
|
export declare function Article(props: ArticleProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
37
37
|
export declare function ArticleLayout(props: ArticleLayoutProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
38
38
|
export declare function ArticleHeader(props: ArticleHeaderProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
39
39
|
export declare function ArticleMeta(props: ArticleMetaProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
40
40
|
export declare function ArticleContent(props: ArticleContentProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
41
|
-
|
|
41
|
+
type ArticleBodyProps = PrimitiveClassProps & {
|
|
42
42
|
html?: string;
|
|
43
43
|
};
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
type HtmlFragmentSource = "markdown" | "plugin-page";
|
|
45
|
+
type HtmlFragmentProps = {
|
|
46
46
|
html: string;
|
|
47
47
|
source: HtmlFragmentSource;
|
|
48
48
|
};
|
|
@@ -53,7 +53,7 @@ export declare function HtmlFragment(props: HtmlFragmentProps): import("hono/uti
|
|
|
53
53
|
* Owns the `.rb-article-content` Stable Hook so Sites never hand-write it.
|
|
54
54
|
*/
|
|
55
55
|
export declare function ArticleBody(props: ArticleBodyProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
56
|
-
|
|
56
|
+
type PageBodyProps = PrimitiveClassProps & {
|
|
57
57
|
html: string;
|
|
58
58
|
};
|
|
59
59
|
/**
|
|
@@ -65,7 +65,7 @@ export type PageBodyProps = PrimitiveClassProps & {
|
|
|
65
65
|
export declare function PageBody(props: PageBodyProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
66
66
|
export declare function ArticleFooter(props: ArticleFooterProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
67
67
|
export declare function Sidebar(props: SidebarProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
68
|
-
|
|
68
|
+
type ThemeRootProps = {
|
|
69
69
|
theme?: ResolvedRiebeckiteConfig["theme"];
|
|
70
70
|
lang?: string;
|
|
71
71
|
children?: PrimitiveChildren;
|
|
@@ -84,7 +84,7 @@ export declare function themeRootAttributes(theme: ResolvedRiebeckiteConfig["the
|
|
|
84
84
|
* `<head>` and `<body>` as children.
|
|
85
85
|
*/
|
|
86
86
|
export declare function ThemeRoot(props: ThemeRootProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
87
|
-
|
|
87
|
+
type PluginHeadTagsProps = {
|
|
88
88
|
tags?: readonly PluginHeadTag[];
|
|
89
89
|
};
|
|
90
90
|
/**
|
|
@@ -93,12 +93,14 @@ export type PluginHeadTagsProps = {
|
|
|
93
93
|
* The Site owns placement; this primitive owns the conversion and ordering.
|
|
94
94
|
*/
|
|
95
95
|
export declare function PluginHeadTags(props: PluginHeadTagsProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
96
|
-
|
|
96
|
+
type RiebeckiteHeadProps = {
|
|
97
97
|
title?: string;
|
|
98
98
|
headTags?: readonly PluginHeadTag[];
|
|
99
99
|
faviconHref?: string | null;
|
|
100
100
|
colorModeScript?: boolean;
|
|
101
101
|
stylesheets?: readonly string[];
|
|
102
|
+
themeStyle?: string;
|
|
103
|
+
themeStylesheets?: readonly string[];
|
|
102
104
|
clientSrc?: string | null;
|
|
103
105
|
prod?: boolean;
|
|
104
106
|
children?: PrimitiveChildren;
|
|
@@ -111,3 +113,19 @@ export type RiebeckiteHeadProps = {
|
|
|
111
113
|
* surrounding `<head>` so it can add its own elements next to this primitive.
|
|
112
114
|
*/
|
|
113
115
|
export declare function RiebeckiteHead(props: RiebeckiteHeadProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
116
|
+
type SeoHeadProps = {
|
|
117
|
+
seo: SeoMetadata;
|
|
118
|
+
siteTitle: string;
|
|
119
|
+
author?: string;
|
|
120
|
+
ogLocale?: string;
|
|
121
|
+
ogAlternates?: readonly string[];
|
|
122
|
+
twitterSite?: string;
|
|
123
|
+
feedLinks?: readonly {
|
|
124
|
+
href: string;
|
|
125
|
+
type: string;
|
|
126
|
+
}[];
|
|
127
|
+
};
|
|
128
|
+
export declare function SeoHead(props: SeoHeadProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
129
|
+
export declare function getThemeStyle(tokens: ResolvedRiebeckiteConfig["theme"]["tokens"]): string;
|
|
130
|
+
export declare function getThemeStylesheets(userCss: readonly string[]): string[];
|
|
131
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/ui/primitives.tsx
|
|
2
|
+
import { escapeScriptJson, uniqueStrings } from "@riebeckite/core";
|
|
2
3
|
import { ColorModeScript } from "@riebeckite/plugin-color-mode";
|
|
3
4
|
import { raw } from "hono/html";
|
|
4
5
|
import { Link, Script } from "honox/server";
|
|
@@ -161,11 +162,228 @@ function RiebeckiteHead(props) {
|
|
|
161
162
|
faviconHref ? /* @__PURE__ */ jsx("link", { rel: "icon", href: faviconHref }) : null,
|
|
162
163
|
colorModeScript ? /* @__PURE__ */ jsx(ColorModeScript, {}) : null,
|
|
163
164
|
stylesheets.map((href) => /* @__PURE__ */ jsx(Link, { href, rel: "stylesheet", prod: props.prod }, href)),
|
|
165
|
+
props.themeStyle ? /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: props.themeStyle } }) : null,
|
|
166
|
+
props.themeStylesheets?.map((href) => /* @__PURE__ */ jsx(Link, { href, rel: "stylesheet", prod: props.prod }, href)),
|
|
164
167
|
/* @__PURE__ */ jsx(PluginHeadTags, { tags: props.headTags ?? site?.headTags }),
|
|
165
168
|
clientSrc ? /* @__PURE__ */ jsx(Script, { src: clientSrc, async: true, prod: props.prod }) : null,
|
|
166
169
|
props.children
|
|
167
170
|
] });
|
|
168
171
|
}
|
|
172
|
+
function SeoHead(props) {
|
|
173
|
+
const { seo } = props;
|
|
174
|
+
const twitterCard = seo.imageUrl ? "summary_large_image" : "summary";
|
|
175
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
176
|
+
/* @__PURE__ */ jsx(
|
|
177
|
+
"meta",
|
|
178
|
+
{
|
|
179
|
+
name: "description",
|
|
180
|
+
content: seo.description,
|
|
181
|
+
"data-riebeckite-head": "page"
|
|
182
|
+
}
|
|
183
|
+
),
|
|
184
|
+
props.author ? /* @__PURE__ */ jsx(
|
|
185
|
+
"meta",
|
|
186
|
+
{
|
|
187
|
+
name: "author",
|
|
188
|
+
content: props.author,
|
|
189
|
+
"data-riebeckite-head": "page"
|
|
190
|
+
}
|
|
191
|
+
) : null,
|
|
192
|
+
seo.noindex ? /* @__PURE__ */ jsx(
|
|
193
|
+
"meta",
|
|
194
|
+
{
|
|
195
|
+
name: "robots",
|
|
196
|
+
content: "noindex, nofollow",
|
|
197
|
+
"data-riebeckite-head": "page"
|
|
198
|
+
}
|
|
199
|
+
) : null,
|
|
200
|
+
/* @__PURE__ */ jsx("title", { children: seo.title }),
|
|
201
|
+
seo.canonicalUrl ? /* @__PURE__ */ jsx(
|
|
202
|
+
"link",
|
|
203
|
+
{
|
|
204
|
+
rel: "canonical",
|
|
205
|
+
href: seo.canonicalUrl,
|
|
206
|
+
"data-riebeckite-head": "page"
|
|
207
|
+
}
|
|
208
|
+
) : null,
|
|
209
|
+
/* @__PURE__ */ jsx(
|
|
210
|
+
"meta",
|
|
211
|
+
{
|
|
212
|
+
property: "og:title",
|
|
213
|
+
content: seo.title,
|
|
214
|
+
"data-riebeckite-head": "page"
|
|
215
|
+
}
|
|
216
|
+
),
|
|
217
|
+
/* @__PURE__ */ jsx(
|
|
218
|
+
"meta",
|
|
219
|
+
{
|
|
220
|
+
property: "og:description",
|
|
221
|
+
content: seo.description,
|
|
222
|
+
"data-riebeckite-head": "page"
|
|
223
|
+
}
|
|
224
|
+
),
|
|
225
|
+
/* @__PURE__ */ jsx("meta", { property: "og:type", content: seo.type, "data-riebeckite-head": "page" }),
|
|
226
|
+
seo.canonicalUrl ? /* @__PURE__ */ jsx(
|
|
227
|
+
"meta",
|
|
228
|
+
{
|
|
229
|
+
property: "og:url",
|
|
230
|
+
content: seo.canonicalUrl,
|
|
231
|
+
"data-riebeckite-head": "page"
|
|
232
|
+
}
|
|
233
|
+
) : null,
|
|
234
|
+
/* @__PURE__ */ jsx(
|
|
235
|
+
"meta",
|
|
236
|
+
{
|
|
237
|
+
property: "og:site_name",
|
|
238
|
+
content: props.siteTitle,
|
|
239
|
+
"data-riebeckite-head": "page"
|
|
240
|
+
}
|
|
241
|
+
),
|
|
242
|
+
props.ogLocale ? /* @__PURE__ */ jsx(
|
|
243
|
+
"meta",
|
|
244
|
+
{
|
|
245
|
+
property: "og:locale",
|
|
246
|
+
content: props.ogLocale,
|
|
247
|
+
"data-riebeckite-head": "page"
|
|
248
|
+
}
|
|
249
|
+
) : null,
|
|
250
|
+
props.ogAlternates?.map((locale) => /* @__PURE__ */ jsx(
|
|
251
|
+
"meta",
|
|
252
|
+
{
|
|
253
|
+
property: "og:locale:alternate",
|
|
254
|
+
content: locale,
|
|
255
|
+
"data-riebeckite-head": "page"
|
|
256
|
+
},
|
|
257
|
+
locale
|
|
258
|
+
)),
|
|
259
|
+
seo.imageUrl ? /* @__PURE__ */ jsx(
|
|
260
|
+
"meta",
|
|
261
|
+
{
|
|
262
|
+
property: "og:image",
|
|
263
|
+
content: seo.imageUrl,
|
|
264
|
+
"data-riebeckite-head": "page"
|
|
265
|
+
}
|
|
266
|
+
) : null,
|
|
267
|
+
seo.publishedTime ? /* @__PURE__ */ jsx(
|
|
268
|
+
"meta",
|
|
269
|
+
{
|
|
270
|
+
property: "article:published_time",
|
|
271
|
+
content: seo.publishedTime,
|
|
272
|
+
"data-riebeckite-head": "page"
|
|
273
|
+
}
|
|
274
|
+
) : null,
|
|
275
|
+
seo.modifiedTime ? /* @__PURE__ */ jsx(
|
|
276
|
+
"meta",
|
|
277
|
+
{
|
|
278
|
+
property: "article:modified_time",
|
|
279
|
+
content: seo.modifiedTime,
|
|
280
|
+
"data-riebeckite-head": "page"
|
|
281
|
+
}
|
|
282
|
+
) : null,
|
|
283
|
+
seo.tags.map((tag) => /* @__PURE__ */ jsx(
|
|
284
|
+
"meta",
|
|
285
|
+
{
|
|
286
|
+
property: "article:tag",
|
|
287
|
+
content: tag,
|
|
288
|
+
"data-riebeckite-head": "page"
|
|
289
|
+
},
|
|
290
|
+
tag
|
|
291
|
+
)),
|
|
292
|
+
/* @__PURE__ */ jsx(
|
|
293
|
+
"meta",
|
|
294
|
+
{
|
|
295
|
+
name: "twitter:card",
|
|
296
|
+
content: twitterCard,
|
|
297
|
+
"data-riebeckite-head": "page"
|
|
298
|
+
}
|
|
299
|
+
),
|
|
300
|
+
/* @__PURE__ */ jsx(
|
|
301
|
+
"meta",
|
|
302
|
+
{
|
|
303
|
+
name: "twitter:title",
|
|
304
|
+
content: seo.title,
|
|
305
|
+
"data-riebeckite-head": "page"
|
|
306
|
+
}
|
|
307
|
+
),
|
|
308
|
+
/* @__PURE__ */ jsx(
|
|
309
|
+
"meta",
|
|
310
|
+
{
|
|
311
|
+
name: "twitter:description",
|
|
312
|
+
content: seo.description,
|
|
313
|
+
"data-riebeckite-head": "page"
|
|
314
|
+
}
|
|
315
|
+
),
|
|
316
|
+
props.twitterSite ? /* @__PURE__ */ jsx(
|
|
317
|
+
"meta",
|
|
318
|
+
{
|
|
319
|
+
name: "twitter:site",
|
|
320
|
+
content: props.twitterSite,
|
|
321
|
+
"data-riebeckite-head": "page"
|
|
322
|
+
}
|
|
323
|
+
) : null,
|
|
324
|
+
seo.imageUrl ? /* @__PURE__ */ jsx(
|
|
325
|
+
"meta",
|
|
326
|
+
{
|
|
327
|
+
name: "twitter:image",
|
|
328
|
+
content: seo.imageUrl,
|
|
329
|
+
"data-riebeckite-head": "page"
|
|
330
|
+
}
|
|
331
|
+
) : null,
|
|
332
|
+
props.feedLinks?.map((feed) => /* @__PURE__ */ jsx(
|
|
333
|
+
"link",
|
|
334
|
+
{
|
|
335
|
+
rel: "alternate",
|
|
336
|
+
type: feed.type,
|
|
337
|
+
href: feed.href,
|
|
338
|
+
"data-riebeckite-head": "global"
|
|
339
|
+
},
|
|
340
|
+
feed.href
|
|
341
|
+
)),
|
|
342
|
+
seo.jsonLd ? /* @__PURE__ */ jsx(
|
|
343
|
+
"script",
|
|
344
|
+
{
|
|
345
|
+
type: "application/ld+json",
|
|
346
|
+
"data-riebeckite-head": "page",
|
|
347
|
+
dangerouslySetInnerHTML: {
|
|
348
|
+
__html: escapeScriptJson(JSON.stringify(seo.jsonLd))
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
) : null
|
|
352
|
+
] });
|
|
353
|
+
}
|
|
354
|
+
function getThemeStyle(tokens) {
|
|
355
|
+
const variables = [
|
|
356
|
+
["--rb-color-paper", tokens.color?.paper],
|
|
357
|
+
["--rb-color-ink", tokens.color?.ink],
|
|
358
|
+
["--rb-color-muted", tokens.color?.muted],
|
|
359
|
+
["--rb-color-accent", tokens.color?.accent],
|
|
360
|
+
["--rb-color-link", tokens.color?.link],
|
|
361
|
+
["--rb-color-focus", tokens.color?.focus],
|
|
362
|
+
["--rb-color-selected", tokens.color?.selected],
|
|
363
|
+
["--rb-color-border", tokens.color?.border],
|
|
364
|
+
["--rb-color-border-strong", tokens.color?.borderStrong],
|
|
365
|
+
["--rb-color-surface", tokens.color?.surface],
|
|
366
|
+
["--rb-color-surface-hover", tokens.color?.surfaceHover],
|
|
367
|
+
["--rb-color-overlay", tokens.color?.overlay],
|
|
368
|
+
["--rb-color-danger", tokens.color?.danger],
|
|
369
|
+
["--rb-color-success", tokens.color?.success],
|
|
370
|
+
["--rb-color-code-background", tokens.color?.codeBackground],
|
|
371
|
+
["--rb-color-code-ink", tokens.color?.codeInk],
|
|
372
|
+
["--rb-color-code-inline", tokens.color?.codeInline],
|
|
373
|
+
["--rb-font-body", tokens.typography?.bodyFont],
|
|
374
|
+
["--rb-font-heading", tokens.typography?.headingFont],
|
|
375
|
+
["--rb-font-mono", tokens.typography?.monoFont],
|
|
376
|
+
["--rb-layout-page-max", tokens.layout?.pageMaxWidth],
|
|
377
|
+
["--rb-layout-article-max", tokens.layout?.articleMaxWidth],
|
|
378
|
+
["--rb-layout-sidebar", tokens.layout?.sidebarWidth],
|
|
379
|
+
["--rb-layout-gap", tokens.layout?.contentGap]
|
|
380
|
+
];
|
|
381
|
+
const declarations = variables.filter((variable) => Boolean(variable[1])).map(([name, value]) => `${name}: ${value};`);
|
|
382
|
+
return declarations.length === 0 ? "" : `:root { ${declarations.join(" ")} }`;
|
|
383
|
+
}
|
|
384
|
+
function getThemeStylesheets(userCss) {
|
|
385
|
+
return uniqueStrings([...userCss]);
|
|
386
|
+
}
|
|
169
387
|
function joinClassNames(...classNames) {
|
|
170
388
|
return classNames.filter(Boolean).join(" ");
|
|
171
389
|
}
|
|
@@ -181,7 +399,10 @@ export {
|
|
|
181
399
|
PageBody,
|
|
182
400
|
PluginHeadTags,
|
|
183
401
|
RiebeckiteHead,
|
|
402
|
+
SeoHead,
|
|
184
403
|
Sidebar,
|
|
185
404
|
ThemeRoot,
|
|
405
|
+
getThemeStyle,
|
|
406
|
+
getThemeStylesheets,
|
|
186
407
|
themeRootAttributes
|
|
187
408
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ResolvedRiebeckiteConfig, Tracer } from "@riebeckite/core";
|
|
2
2
|
import { type RiebeckiteConfigLoaderOptions } from "./config_loader.js";
|
|
3
|
-
|
|
3
|
+
type HonoxApplicationOptions = {
|
|
4
4
|
root: string;
|
|
5
5
|
tracer?: Tracer;
|
|
6
6
|
server?: {
|
|
@@ -29,3 +29,4 @@ export declare class HonoxApplicationRootError extends Error {
|
|
|
29
29
|
export declare function resolveHonoxApplication(options: ResolveHonoxApplicationOptions): Promise<ResolvedHonoxApplication>;
|
|
30
30
|
export declare function startHonoxDevServer(options: HonoxApplicationOptions): Promise<void>;
|
|
31
31
|
export declare function buildHonoxApplication(options: HonoxApplicationOptions): Promise<void>;
|
|
32
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riebeckite/honox",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.33",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -40,19 +40,20 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@babel/parser": "^7.29.3",
|
|
43
|
+
"@riebeckite/core": "0.0.33",
|
|
44
|
+
"@riebeckite/diagnostics": "0.0.33",
|
|
45
|
+
"@riebeckite/node": "0.0.33",
|
|
46
|
+
"@riebeckite/plugin-color-mode": "0.0.33",
|
|
47
|
+
"@riebeckite/spa": "0.0.33",
|
|
48
|
+
"@riebeckite/ui": "0.0.33",
|
|
43
49
|
"esbuild": "^0.28.2",
|
|
44
50
|
"hono": "^4.12.25",
|
|
45
51
|
"honox": "0.1.56",
|
|
46
|
-
"vite": "^8.
|
|
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"
|
|
52
|
+
"vite": "^8.3.5"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
|
-
"
|
|
55
|
-
"
|
|
55
|
+
"@riebeckite/test": "0.0.33",
|
|
56
|
+
"tsx": "^4.22.4"
|
|
56
57
|
},
|
|
57
58
|
"publishConfig": {
|
|
58
59
|
"access": "public"
|
package/style.css
CHANGED
|
@@ -22,6 +22,21 @@
|
|
|
22
22
|
|
|
23
23
|
.rb-article-body {
|
|
24
24
|
min-width: 0;
|
|
25
|
+
padding-inline: var(--rb-space-2, 1rem);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.rb-article {
|
|
29
|
+
width: min(100%, var(--rb-layout-page-max, 80rem));
|
|
30
|
+
max-width: none;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
:is(:root, .rb-theme-root)[data-article-layout="full-width"] .rb-article {
|
|
34
|
+
width: 100%;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
:is(:root, .rb-theme-root)[data-article-layout="full-width"]
|
|
38
|
+
.rb-article-body {
|
|
39
|
+
max-width: none;
|
|
25
40
|
}
|
|
26
41
|
|
|
27
42
|
.rb-page-body {
|
|
@@ -80,3 +95,237 @@
|
|
|
80
95
|
transform: translateY(0);
|
|
81
96
|
}
|
|
82
97
|
}
|
|
98
|
+
@layer components {
|
|
99
|
+
.rb-article-header h1 {
|
|
100
|
+
word-break: auto-phrase;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.rb-article-content :where(h1, h2, h3, h4, h5, h6) {
|
|
104
|
+
font-weight: 600;
|
|
105
|
+
line-height: 1.3;
|
|
106
|
+
text-wrap: balance;
|
|
107
|
+
word-break: auto-phrase;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.rb-article-content :where(h1) {
|
|
111
|
+
margin-block: 0 1em;
|
|
112
|
+
font-size: 2.25em;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.rb-article-content :where(h2) {
|
|
116
|
+
margin-block: 2em 1em;
|
|
117
|
+
font-size: 1.5em;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.rb-article-content :where(h3) {
|
|
121
|
+
margin-block: 1.6em 0.6em;
|
|
122
|
+
font-size: 1.25em;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.rb-article-content :where(h4) {
|
|
126
|
+
margin-block: 1.5em 0.5em;
|
|
127
|
+
font-size: 1em;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.rb-article-content :where(p) {
|
|
131
|
+
margin-block: 1.25em;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.rb-article-content :where(a) {
|
|
135
|
+
color: inherit;
|
|
136
|
+
text-decoration: underline;
|
|
137
|
+
text-decoration-thickness: 1px;
|
|
138
|
+
text-underline-offset: 0.2em;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.rb-article-content :where(strong) {
|
|
142
|
+
font-weight: 600;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.rb-article-content :where(ul) {
|
|
146
|
+
list-style-type: disc;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.rb-article-content :where(ol) {
|
|
150
|
+
list-style-type: decimal;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.rb-article-content :where(ol[type="A"]) {
|
|
154
|
+
list-style-type: upper-alpha;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.rb-article-content :where(ol[type="a"]) {
|
|
158
|
+
list-style-type: lower-alpha;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.rb-article-content :where(ol[type="I"]) {
|
|
162
|
+
list-style-type: upper-roman;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.rb-article-content :where(ol[type="i"]) {
|
|
166
|
+
list-style-type: lower-roman;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.rb-article-content :where(ul, ol) {
|
|
170
|
+
margin-block: 1.25em;
|
|
171
|
+
padding-inline-start: 1.625em;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.rb-article-content :where(li) {
|
|
175
|
+
margin-block: 0.5em;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.rb-article-content :where(ul ul, ul ol, ol ul, ol ol) {
|
|
179
|
+
margin-block: 0.75em;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.rb-article-content :where(.task-list-item) {
|
|
183
|
+
list-style: none;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.rb-article-content :where(.task-list-item) > :where(input[type="checkbox"]) {
|
|
187
|
+
margin-inline-end: 0.5em;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.rb-article-content :where(blockquote) {
|
|
191
|
+
margin-block: 2em;
|
|
192
|
+
padding-inline-start: 1em;
|
|
193
|
+
border-inline-start: 2px solid var(--rb-color-border);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.rb-article-content :where(hr) {
|
|
197
|
+
margin-block: 3em;
|
|
198
|
+
border: 0;
|
|
199
|
+
border-block-start: 1px solid var(--rb-color-border);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.rb-article-content :where(:not(pre) > code) {
|
|
203
|
+
font-family: var(--rb-font-mono);
|
|
204
|
+
font-size: 0.875em;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.rb-article-content :where(pre):not(:where(.rr-code *)) {
|
|
208
|
+
margin-block: 1.5em;
|
|
209
|
+
padding: 0.75rem 1rem;
|
|
210
|
+
border-radius: 6px;
|
|
211
|
+
background: var(--rb-color-code-background);
|
|
212
|
+
color: var(--rb-color-ink);
|
|
213
|
+
font-family: var(--rb-font-mono);
|
|
214
|
+
font-size: 0.875em;
|
|
215
|
+
line-height: 1.7;
|
|
216
|
+
overflow-x: auto;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.rb-article-content :where(pre):not(:where(.rr-code *)) :where(code) {
|
|
220
|
+
background: none;
|
|
221
|
+
border: 0;
|
|
222
|
+
padding: 0;
|
|
223
|
+
font-size: inherit;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.rb-article-content :where(table) {
|
|
227
|
+
width: 100%;
|
|
228
|
+
max-width: 100%;
|
|
229
|
+
border-collapse: collapse;
|
|
230
|
+
table-layout: auto;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.rb-article-content :where(.rb-table-scroll) {
|
|
234
|
+
max-width: 100%;
|
|
235
|
+
margin-block: 1.5em;
|
|
236
|
+
overflow-x: auto;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.rb-article-content :where(figure) {
|
|
240
|
+
margin-block: 2em;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.rb-article-content :where(figure > *) {
|
|
244
|
+
margin-block: 0;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.rb-article-content :where(figcaption) {
|
|
248
|
+
color: var(--rb-color-muted);
|
|
249
|
+
font-size: 0.875em;
|
|
250
|
+
line-height: 1.43;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.rb-source-fallback {
|
|
254
|
+
inline-size: 100%;
|
|
255
|
+
margin-block: 0.75rem 0;
|
|
256
|
+
border-block-start: 1px solid var(--rb-color-border);
|
|
257
|
+
color: var(--rb-color-muted);
|
|
258
|
+
font-size: 0.8125rem;
|
|
259
|
+
text-align: start;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
figure > .rb-source-fallback {
|
|
263
|
+
margin-block: 0;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.rb-source-fallback > summary {
|
|
267
|
+
padding: 0.5rem 0.75rem;
|
|
268
|
+
cursor: pointer;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.rb-source-fallback > pre {
|
|
272
|
+
overflow: auto;
|
|
273
|
+
margin: 0 0.75rem 0.75rem;
|
|
274
|
+
padding: 0.75rem;
|
|
275
|
+
border: 1px solid var(--rb-color-border);
|
|
276
|
+
border-radius: 6px;
|
|
277
|
+
background: var(--rb-color-code-background);
|
|
278
|
+
color: var(--rb-color-ink);
|
|
279
|
+
font-size: 0.8125rem;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.rb-article-content :where(dl) {
|
|
283
|
+
margin-block: 1.25em;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.rb-article-content :where(dt) {
|
|
287
|
+
margin-block-start: 1.25em;
|
|
288
|
+
font-weight: 600;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.rb-article-content :where(dd) {
|
|
292
|
+
margin-block-start: 0.5em;
|
|
293
|
+
padding-inline-start: 1.625em;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.rb-article-content :where(kbd) {
|
|
297
|
+
padding: 0.15em 0.4em;
|
|
298
|
+
border: 1px solid var(--rb-color-border);
|
|
299
|
+
border-radius: 4px;
|
|
300
|
+
background: var(--rb-color-surface);
|
|
301
|
+
color: inherit;
|
|
302
|
+
font-family: var(--rb-font-mono);
|
|
303
|
+
font-size: 0.875em;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.rb-article-content :where(img, picture, video) {
|
|
307
|
+
margin-block: 2em;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.rb-article-content :where(picture > img) {
|
|
311
|
+
margin-block: 0;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.rb-article-content > :where(:first-child) {
|
|
315
|
+
margin-block-start: 0;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.rb-article-content > :where(:last-child) {
|
|
319
|
+
margin-block-end: 0;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.rb-article-content :where(hr, h2, h3, h4) + * {
|
|
323
|
+
margin-block-start: 0;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
@media (max-width: 48rem) {
|
|
327
|
+
.rb-article-content {
|
|
328
|
+
overflow-wrap: break-word;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|