@ox-content/vite-plugin-svelte 3.1.3 → 3.1.4

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.mjs CHANGED
@@ -1,11 +1,8 @@
1
1
  import { a as loadSvelteHtmlHostDomRuntime, i as createSvelteHtmlHostDomRenderer, n as initSvelteHtmlHost, r as readSvelteHtmlHostSlot, t as createSvelteHtmlHostLazyHydrate } from "./html-host-client2.mjs";
2
- import { applyIslandSsrHtml, buildCollectionManifest, collectMdxIslandNamesFromHtml, customHostOxContentOptions, discoverDocumentMdxIslands, intersectHydratableComponentNames, normalizeMarkdownExtensions, oxContent, oxContent as oxContent$1, renderHead, renderIslandComponentImports, renderMarkdown, resolveCascadeOptions, resolveCollectionsOptions, resolveContentRootPath, resolveDocumentComponentImports, resolveMdxForFilePath, resolvePermalinksOptions, stripViteQuery, transformMarkdown } from "@ox-content/vite-plugin";
2
+ import { applyIslandSsrHtml, createHtmlHostHydrate, createHtmlHostIslandRegistry, discoverDocumentMdxIslands, formatHtmlHostDiagnostics, oxContent, oxContent as oxContent$1, renderHead, renderHtmlHost, renderIslandComponentImports, resolveContentRootPath, resolveHtmlHostCollectionDocuments, resolveHtmlHostIslandRegistry, resolveMdxForFilePath, toHtmlHostClientModuleId, toHtmlHostClientModuleId as toHtmlHostClientModuleId$1, transformMarkdown } from "@ox-content/vite-plugin";
3
3
  import { compile } from "svelte/compiler";
4
- import * as fs$1 from "fs";
5
- import * as path$1 from "path";
6
- import path from "node:path";
7
- import fsSync from "node:fs";
8
- import fs from "node:fs/promises";
4
+ import * as fs from "fs";
5
+ import * as path from "path";
9
6
  //#region src/transform.ts
10
7
  const COMPONENT_REGEX = /<([A-Z][a-zA-Z0-9]*)\s*([^>]*?)\s*(?:\/>|>([\s\S]*?)<\/\1>)/g;
11
8
  const PROP_REGEX = /([a-zA-Z0-9-]+)(?:=(?:"([^"]*)"|'([^']*)'|{([^}]*)}|\[([^\]]*)\]))?/g;
@@ -766,7 +763,7 @@ function findMdxIslandRanges(html) {
766
763
  let match;
767
764
  while ((match = openRe.exec(html)) !== null) {
768
765
  const tag = match[1];
769
- const name = decodeHtmlAttr$1(match[3] ?? "");
766
+ const name = decodeHtmlAttr(match[3] ?? "");
770
767
  if (!name) continue;
771
768
  const openStart = match.index;
772
769
  const openEnd = match.index + match[0].length;
@@ -821,7 +818,7 @@ function indexOfTagOpen(html, openNeedle, from) {
821
818
  }
822
819
  function matchAttr(attrs, name) {
823
820
  const match = new RegExp(`\\b${name}="([^"]*)"`, "i").exec(attrs);
824
- return match?.[1] === void 0 ? void 0 : decodeHtmlAttr$1(match[1]);
821
+ return match?.[1] === void 0 ? void 0 : decodeHtmlAttr(match[1]);
825
822
  }
826
823
  function readMdxIslandPayload(island) {
827
824
  const fromAttr = island.propsAttr ? tryParseJson(island.propsAttr) : void 0;
@@ -866,7 +863,7 @@ function tryParseJson(value) {
866
863
  return;
867
864
  }
868
865
  }
869
- function decodeHtmlAttr$1(value) {
866
+ function decodeHtmlAttr(value) {
870
867
  return value.replaceAll("&quot;", "\"").replaceAll("&#39;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
871
868
  }
872
869
  function assertSvelteComponentName(name, filePath) {
@@ -997,8 +994,8 @@ async function resolveComponentsGlob(componentsOption, root) {
997
994
  const patterns = Array.isArray(componentsOption) ? componentsOption : [componentsOption];
998
995
  const result = {};
999
996
  for (const pattern of patterns) for (const file of await globFiles(pattern, root)) {
1000
- const baseName = path$1.basename(file, path$1.extname(file));
1001
- const relativePath = "./" + path$1.relative(root, file).replace(/\\/g, "/");
997
+ const baseName = path.basename(file, path.extname(file));
998
+ const relativePath = "./" + path.relative(root, file).replace(/\\/g, "/");
1002
999
  result[toPascalCase(baseName)] = relativePath;
1003
1000
  }
1004
1001
  return result;
@@ -1007,22 +1004,22 @@ async function globFiles(pattern, root) {
1007
1004
  const files = [];
1008
1005
  const normalized = pattern.replace(/\\/g, "/").replace(/^\.\//, "");
1009
1006
  if (!hasWildcard(normalized)) {
1010
- const fullPath = path$1.resolve(root, normalized);
1011
- if (fs$1.existsSync(fullPath)) files.push(fullPath);
1007
+ const fullPath = path.resolve(root, normalized);
1008
+ if (fs.existsSync(fullPath)) files.push(fullPath);
1012
1009
  return files;
1013
1010
  }
1014
- const baseDir = path$1.resolve(root, staticPrefix(normalized));
1015
- if (!fs$1.existsSync(baseDir)) return files;
1011
+ const baseDir = path.resolve(root, staticPrefix(normalized));
1012
+ if (!fs.existsSync(baseDir)) return files;
1016
1013
  const segments = normalized.split("/");
1017
1014
  const crossesDirectories = normalized.includes("**") || segments.slice(0, -1).some(hasWildcard);
1018
1015
  const candidates = [];
1019
1016
  if (crossesDirectories) await walkDir(baseDir, candidates);
1020
1017
  else {
1021
- const entries = await fs$1.promises.readdir(baseDir, { withFileTypes: true });
1022
- for (const entry of entries) if (entry.isFile()) candidates.push(path$1.join(baseDir, entry.name));
1018
+ const entries = await fs.promises.readdir(baseDir, { withFileTypes: true });
1019
+ for (const entry of entries) if (entry.isFile()) candidates.push(path.join(baseDir, entry.name));
1023
1020
  }
1024
1021
  const matcher = globToRegExp(normalized);
1025
- for (const candidate of candidates) if (matcher.test(path$1.relative(root, candidate).replace(/\\/g, "/"))) files.push(candidate);
1022
+ for (const candidate of candidates) if (matcher.test(path.relative(root, candidate).replace(/\\/g, "/"))) files.push(candidate);
1026
1023
  return files;
1027
1024
  }
1028
1025
  /** Whether a pattern (or one segment of it) contains a wildcard `globToRegExp` expands. */
@@ -1064,9 +1061,9 @@ function globToRegExp(pattern) {
1064
1061
  return new RegExp(`^${source}$`);
1065
1062
  }
1066
1063
  async function walkDir(dir, files) {
1067
- const entries = await fs$1.promises.readdir(dir, { withFileTypes: true });
1064
+ const entries = await fs.promises.readdir(dir, { withFileTypes: true });
1068
1065
  for (const entry of entries) {
1069
- const fullPath = path$1.join(dir, entry.name);
1066
+ const fullPath = path.join(dir, entry.name);
1070
1067
  if (entry.isDirectory()) await walkDir(fullPath, files);
1071
1068
  else if (entry.isFile()) files.push(fullPath);
1072
1069
  }
@@ -1077,248 +1074,69 @@ function toPascalCase(str) {
1077
1074
  //#endregion
1078
1075
  //#region src/html-host-default-renderer.ts
1079
1076
  const defaultRenderSvelteHtmlComponent = async (component, props, slotHtml) => {
1080
- const [{ render }, { createRawSnippet }] = await Promise.all([import("svelte/server"), import("svelte")]);
1081
- const rendered = render(component, { props: slotHtml ? {
1082
- ...props,
1083
- children: createRawSnippet(() => ({ render: () => slotHtml }))
1084
- } : props });
1085
- return rendered.html ?? rendered.body ?? "";
1077
+ return renderWithSvelteRuntime(await loadDefaultSvelteRuntime(), component, props, slotHtml);
1086
1078
  };
1087
- //#endregion
1088
- //#region src/html-host.ts
1089
- const ISLAND_JSON_SCRIPT = /^\s*<script type="application\/json">[\s\S]*?<\/script>/;
1090
- async function renderSvelteHtmlHost(input) {
1091
- const diagnostics = [];
1092
- const modules = resolveHostModules(input, diagnostics);
1093
- const byName = new Map(modules.map((module) => [module.name, module]));
1094
- const cache = /* @__PURE__ */ new Map();
1095
- const renderComponent = input.renderComponent ?? defaultRenderSvelteHtmlComponent;
1096
- return {
1097
- html: markClientModules(await applyIslandSsrHtml(input.html, async (name, props, _filePath, slotHtml) => {
1098
- const module = byName.get(name);
1099
- if (!module) {
1100
- diagnostics.push({
1101
- code: "missing-component",
1102
- message: `Svelte island "${name}" is not registered for this document.`,
1103
- documentPath: input.documentPath,
1104
- component: name
1105
- });
1106
- return slotHtml ?? "";
1107
- }
1108
- const component = await loadComponent(input, module, cache, diagnostics);
1109
- if (!component) return slotHtml ?? "";
1110
- try {
1111
- return await renderComponent(component, props, slotHtml || void 0, {
1112
- component: name,
1113
- moduleId: module.serverModuleId,
1114
- documentPath: input.documentPath
1115
- });
1116
- } catch (error) {
1117
- diagnostics.push({
1118
- code: "ssr-failed",
1119
- message: `Svelte island "${name}" failed to render: ${errorMessage(error)}`,
1120
- documentPath: input.documentPath,
1121
- component: name,
1122
- moduleId: module.serverModuleId
1123
- });
1124
- return slotHtml ?? "";
1125
- }
1126
- }, input.documentPath, modules.map((module) => module.name)), modules),
1127
- modules,
1128
- clientModules: modules.flatMap((module) => module.clientModuleId ? [{
1129
- name: module.name,
1130
- moduleId: module.clientModuleId,
1131
- exportName: module.exportName
1132
- }] : []),
1133
- diagnostics
1079
+ function createSvelteHtmlHostComponentRenderer(loadModule) {
1080
+ let pending;
1081
+ return async (component, props, slotHtml) => {
1082
+ pending ??= loadSvelteRuntimeFromHost(loadModule);
1083
+ return renderWithSvelteRuntime(await pending, component, props, slotHtml);
1134
1084
  };
1135
1085
  }
1136
- function createSvelteHtmlHostHydrate(input) {
1137
- return (element, props) => {
1138
- const name = element.dataset.oxIsland;
1139
- if (!name) return;
1140
- const component = componentFromRegistry(input.components, name);
1141
- if (!component) return;
1142
- const slotHtml = readIslandSlotHtml(element);
1143
- element.innerHTML = "";
1144
- return input.render(component, props, element, slotHtml || void 0);
1145
- };
1146
- }
1147
- function resolveHostModules(input, diagnostics) {
1148
- const names = collectMdxIslandNamesFromHtml(input.html);
1149
- const local = resolveDocumentComponentImports({
1150
- imports: input.imports ?? [],
1151
- documentPath: input.documentPath,
1152
- contentRoot: input.contentRoot ?? resolveContentRootPath(input),
1153
- srcDir: input.srcDir
1154
- });
1155
- for (const diagnostic of local.diagnostics) diagnostics.push({
1156
- ...diagnostic,
1157
- documentPath: input.documentPath
1158
- });
1159
- const localBindings = new Map(local.bindings.map((binding) => [binding.localName, binding]));
1160
- const modules = [];
1161
- for (const name of names) {
1162
- const localBinding = localBindings.get(name);
1163
- const serverModuleId = localBinding ? localBinding.resolvedPath : componentPath(input.components ?? {}, name, input.root);
1164
- if (!serverModuleId) {
1165
- diagnostics.push({
1166
- code: "missing-component",
1167
- message: `Svelte island "${name}" is not registered for this document.`,
1168
- documentPath: input.documentPath,
1169
- component: name
1170
- });
1171
- continue;
1172
- }
1173
- const module = {
1174
- name,
1175
- serverModuleId,
1176
- exportName: localBinding?.imported ?? "default",
1177
- source: localBinding ? "document" : "components"
1178
- };
1179
- const clientModuleId = input.resolveClientModule?.(module, { documentPath: input.documentPath });
1180
- modules.push(clientModuleId ? {
1181
- ...module,
1182
- clientModuleId
1183
- } : module);
1184
- }
1185
- return modules;
1186
- }
1187
- async function loadComponent(input, module, cache, diagnostics) {
1188
- let pending = cache.get(module.serverModuleId);
1189
- if (!pending) {
1190
- pending = input.loadModule(module.serverModuleId);
1191
- cache.set(module.serverModuleId, pending);
1192
- }
1193
- let exports;
1194
- try {
1195
- exports = await pending;
1196
- } catch (error) {
1197
- diagnostics.push({
1198
- code: "module-load-failed",
1199
- message: `Svelte island module "${module.serverModuleId}" failed to load: ${errorMessage(error)}`,
1200
- documentPath: input.documentPath,
1201
- component: module.name,
1202
- moduleId: module.serverModuleId
1203
- });
1204
- return;
1205
- }
1206
- const component = exportedValue(exports, module.exportName);
1207
- if (!component) diagnostics.push({
1208
- code: "missing-export",
1209
- message: `Svelte island "${module.name}" could not find export "${module.exportName}".`,
1210
- documentPath: input.documentPath,
1211
- component: module.name,
1212
- moduleId: module.serverModuleId
1213
- });
1214
- return component == null ? void 0 : component;
1215
- }
1216
- function componentPath(components, name, root = process.cwd()) {
1217
- const specifier = components[name];
1218
- if (!specifier) return;
1219
- return path.resolve(root, specifier.replace(/^\.\//, ""));
1220
- }
1221
- function exportedValue(exports, exportName) {
1222
- if (!exports || typeof exports !== "object") return;
1223
- return exports[exportName];
1224
- }
1225
- function componentFromRegistry(registry, name) {
1226
- return isReadonlyMap(registry) ? registry.get(name) : registry[name];
1227
- }
1228
- function isReadonlyMap(value) {
1229
- return typeof value.get === "function";
1230
- }
1231
- function readIslandSlotHtml(element) {
1232
- const fromAttr = element.dataset.oxContent;
1233
- if (fromAttr) return fromAttr;
1234
- if (element.dataset.oxSsr === "true") return "";
1235
- return element.innerHTML.replace(ISLAND_JSON_SCRIPT, "");
1236
- }
1237
- function markClientModules(html, modules) {
1238
- const clientModules = new Map(modules.filter((module) => module.clientModuleId).map((module) => [module.name, module]));
1239
- if (clientModules.size === 0) return html;
1240
- return html.replace(/<(div|span)\b([^>]*\bdata-ox-island="([^"]+)"[^>]*)>/gi, (openTag, _tag, _attrs, encodedName) => {
1241
- const module = clientModules.get(decodeHtmlAttr(encodedName));
1242
- if (!module?.clientModuleId) return openTag;
1243
- const attrs = [];
1244
- if (!hasAttr(openTag, "data-ox-module")) attrs.push(`data-ox-module="${escapeDoubleQuotedAttr(module.clientModuleId)}"`);
1245
- if (!hasAttr(openTag, "data-ox-export")) attrs.push(`data-ox-export="${escapeDoubleQuotedAttr(module.exportName)}"`);
1246
- return attrs.length === 0 ? openTag : openTag.replace(/>$/, ` ${attrs.join(" ")}>`);
1247
- });
1086
+ async function loadDefaultSvelteRuntime() {
1087
+ const [server, shared] = await Promise.all([import("svelte/server"), import("svelte")]);
1088
+ return resolveSvelteRuntime(server, shared);
1248
1089
  }
1249
- function escapeDoubleQuotedAttr(value) {
1250
- return value.replaceAll("&", "&amp;").replaceAll("\"", "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
1090
+ async function loadSvelteRuntimeFromHost(loadModule) {
1091
+ const [server, shared] = await Promise.all([loadModule("svelte/server"), loadModule("svelte")]);
1092
+ return resolveSvelteRuntime(server, shared);
1251
1093
  }
1252
- function decodeHtmlAttr(value) {
1253
- return value.replaceAll("&quot;", "\"").replaceAll("&#39;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
1094
+ function renderWithSvelteRuntime(runtime, component, props, slotHtml) {
1095
+ const componentProps = slotHtml ? {
1096
+ ...props,
1097
+ children: runtime.createRawSnippet(() => ({ render: () => slotHtml }))
1098
+ } : props;
1099
+ const rendered = runtime.render(component, { props: componentProps });
1100
+ return rendered.html ?? rendered.body ?? "";
1254
1101
  }
1255
- function hasAttr(openTag, name) {
1256
- return new RegExp(`\\s${name}(?:\\s*=|\\s|>|$)`, "i").test(openTag);
1102
+ function resolveSvelteRuntime(server, shared) {
1103
+ return {
1104
+ render: runtimeFunction(server, "render", "svelte/server"),
1105
+ createRawSnippet: runtimeFunction(shared, "createRawSnippet", "svelte")
1106
+ };
1257
1107
  }
1258
- function errorMessage(error) {
1259
- return error instanceof Error ? error.message : String(error);
1108
+ function runtimeFunction(module, name, moduleId) {
1109
+ const value = module && typeof module === "object" ? module[name] : void 0;
1110
+ if (typeof value !== "function") throw new Error(`Svelte HTML host renderer could not load ${moduleId}.${name}.`);
1111
+ return value;
1260
1112
  }
1261
1113
  //#endregion
1262
- //#region src/html-host-registry-paths.ts
1263
- function toSvelteHtmlHostClientModuleId(moduleId, root = process.cwd()) {
1264
- const [pathname, suffix = ""] = splitModuleSuffix(moduleId);
1265
- if (isBareSpecifier(pathname) || pathname.startsWith("/@fs/")) return `${pathname}${suffix}`;
1266
- const rootPath = path.resolve(root);
1267
- const realRoot = existingRealpath(rootPath) ?? rootPath;
1268
- const absolute = path.isAbsolute(pathname) ? path.resolve(pathname) : path.resolve(rootPath, pathname);
1269
- const realAbsolute = existingRealpath(absolute);
1270
- const isInsideRealRoot = realAbsolute ? isInsideRoot(realAbsolute, realRoot) : false;
1271
- const isInsideLexicalRoot = isInsideRoot(absolute, rootPath);
1272
- if (path.isAbsolute(pathname) && !isInsideRealRoot && !isInsideLexicalRoot) return fsSync.existsSync(pathname) ? `/@fs${toPosixPath(pathname)}${suffix}` : `${toPosixPath(pathname)}${suffix}`;
1273
- const relativeRoot = isInsideRealRoot ? realRoot : rootPath;
1274
- const relativePath = isInsideRealRoot && realAbsolute ? realAbsolute : absolute;
1275
- return `/${path.relative(relativeRoot, relativePath).replace(/\\/g, "/")}${suffix}`;
1276
- }
1277
- function resolveDocumentPath(documentPath, root) {
1278
- return path.isAbsolute(documentPath) ? stripViteQuery(documentPath) : path.resolve(root, stripViteQuery(documentPath));
1279
- }
1280
- function resolveWatchFile(file, root) {
1281
- return path.isAbsolute(file) ? stripViteQuery(file) : path.resolve(root, stripViteQuery(file));
1282
- }
1283
- function shouldInvalidate(file, root, srcDir, watchFiles, extraWatchFiles) {
1284
- const changed = path.resolve(file);
1285
- if (watchFiles.some((watchFile) => changed === watchFile)) return true;
1286
- if (extraWatchFiles?.some((watchFile) => changed === resolveWatchFile(watchFile, root))) return true;
1287
- return isInsideRoot(changed, path.resolve(root, srcDir ?? "content"));
1288
- }
1289
- function splitModuleSuffix(moduleId) {
1290
- const match = /[?#]/u.exec(moduleId);
1291
- return match ? [moduleId.slice(0, match.index), moduleId.slice(match.index)] : [moduleId];
1292
- }
1293
- function isBareSpecifier(moduleId) {
1294
- return !moduleId.startsWith(".") && !moduleId.startsWith("/") && !moduleId.includes("\\");
1295
- }
1296
- function isInsideRoot(file, root) {
1297
- const relative = path.relative(path.resolve(root), path.resolve(file));
1298
- return relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative);
1299
- }
1300
- function existingRealpath(file) {
1301
- try {
1302
- return fsSync.realpathSync.native(file);
1303
- } catch {
1304
- return;
1305
- }
1114
+ //#region src/html-host.ts
1115
+ async function renderSvelteHtmlHost(input) {
1116
+ const resolveClientModule = input.resolveClientModule;
1117
+ return await renderHtmlHost({
1118
+ ...input,
1119
+ frameworkName: "Svelte",
1120
+ renderComponent: input.renderComponent ?? defaultRenderSvelteHtmlComponent,
1121
+ resolveClientModule
1122
+ });
1306
1123
  }
1307
- function toPosixPath(file) {
1308
- return file.replace(/\\/g, "/");
1124
+ function createSvelteHtmlHostHydrate(input) {
1125
+ return createHtmlHostHydrate(input);
1309
1126
  }
1310
1127
  //#endregion
1311
1128
  //#region src/html-host-renderer.ts
1312
1129
  var SvelteHtmlHostRenderError = class extends Error {
1313
1130
  diagnostics;
1314
1131
  constructor(diagnostics) {
1315
- super(formatSvelteHtmlHostDiagnostics(diagnostics));
1132
+ super(formatHtmlHostDiagnostics(diagnostics));
1316
1133
  this.name = "SvelteHtmlHostRenderError";
1317
1134
  this.diagnostics = [...diagnostics];
1318
1135
  }
1319
1136
  };
1320
1137
  function createSvelteHtmlHostRenderer(input) {
1321
1138
  const policy = input.diagnostics ?? "throw";
1139
+ const defaultRenderComponent = createSvelteHtmlHostComponentRenderer(input.loadModule);
1322
1140
  return async (html, context) => {
1323
1141
  const root = context.root ?? input.root;
1324
1142
  const result = await renderSvelteHtmlHost({
@@ -1330,288 +1148,33 @@ function createSvelteHtmlHostRenderer(input) {
1330
1148
  imports: context.imports,
1331
1149
  components: context.components ?? input.components,
1332
1150
  loadModule: input.loadModule,
1333
- renderComponent: context.renderComponent ?? input.renderComponent,
1334
- resolveClientModule: context.resolveClientModule ?? input.resolveClientModule ?? ((module) => toSvelteHtmlHostClientModuleId(module.serverModuleId, root))
1151
+ renderComponent: context.renderComponent ?? input.renderComponent ?? defaultRenderComponent,
1152
+ resolveClientModule: context.resolveClientModule ?? input.resolveClientModule ?? ((module) => toHtmlHostClientModuleId$1(module.serverModuleId, root))
1335
1153
  });
1336
1154
  if (policy === "throw" && result.diagnostics.length > 0) throw new SvelteHtmlHostRenderError(result.diagnostics);
1337
1155
  return result;
1338
1156
  };
1339
1157
  }
1340
- function formatSvelteHtmlHostDiagnostics(diagnostics) {
1341
- if (diagnostics.length === 0) return "Svelte HTML host rendering failed.";
1342
- return diagnostics.map((diagnostic) => {
1343
- const details = [
1344
- diagnostic.documentPath,
1345
- diagnostic.component && `component ${diagnostic.component}`,
1346
- diagnostic.moduleId && `module ${diagnostic.moduleId}`
1347
- ].filter(Boolean);
1348
- return `${diagnostic.code}: ${diagnostic.message}${details.length > 0 ? ` (${details.join(", ")})` : ""}`;
1349
- }).join("\n");
1350
- }
1351
- //#endregion
1352
- //#region src/html-host-collection-documents.ts
1353
- function createSvelteHtmlHostCollectionDocuments(input = {}) {
1354
- return (context) => resolveSvelteHtmlHostCollectionDocuments(input, context);
1355
- }
1356
- async function resolveSvelteHtmlHostCollectionDocuments(input, context) {
1357
- const options = resolveCollectionManifestOptions(customHostOxContentOptions(input.oxContent ?? {}));
1358
- if (!options.collections.enabled) return [];
1359
- const manifest = await buildCollectionManifest(context.root, options);
1360
- const names = resolveCollectionNames(input.collections, options.collections);
1361
- const documents = /* @__PURE__ */ new Map();
1362
- for (const name of names) for (const entry of manifest.collections[name] ?? []) {
1363
- const document = await resolveCollectionDocument(context.root, options.srcDir, name, entry);
1364
- if (!document) continue;
1365
- if (input.select && !await input.select(document, context)) continue;
1366
- documents.set(document.documentPath, document);
1367
- }
1368
- return [...documents.values()];
1369
- }
1370
- function resolveCollectionManifestOptions(oxContent) {
1371
- const collections = withoutCollectionInclude(resolveCollectionsOptions(oxContent.collections));
1372
- return {
1373
- srcDir: oxContent.srcDir ?? "content",
1374
- outDir: oxContent.outDir ?? "dist",
1375
- base: oxContent.base ?? "/",
1376
- extensions: normalizeMarkdownExtensions(oxContent.extensions),
1377
- collections,
1378
- permalinks: resolvePermalinksOptions(oxContent.permalinks),
1379
- cascade: resolveCascadeOptions(oxContent.cascade),
1380
- gfm: oxContent.gfm ?? true,
1381
- mdx: oxContent.mdx,
1382
- footnotes: oxContent.footnotes ?? true,
1383
- semanticFootnotes: oxContent.semanticFootnotes ?? false,
1384
- taskLists: oxContent.taskLists ?? true,
1385
- tables: oxContent.tables ?? true,
1386
- strikethrough: oxContent.strikethrough ?? true,
1387
- autolinks: oxContent.autolinks ?? oxContent.gfm ?? true,
1388
- superscript: oxContent.superscript ?? false,
1389
- subscript: oxContent.subscript ?? false,
1390
- smartPunctuation: oxContent.smartPunctuation ?? false,
1391
- autolinkTargetBlank: oxContent.autolinkTargetBlank ?? true,
1392
- linkTargetBlank: oxContent.linkTargetBlank ?? true,
1393
- sourceSpans: oxContent.sourceSpans ?? false,
1394
- frontmatter: oxContent.frontmatter ?? true,
1395
- tocMaxDepth: oxContent.tocMaxDepth ?? 3,
1396
- cjkEmphasis: oxContent.cjkEmphasis ?? false
1397
- };
1398
- }
1399
- function withoutCollectionInclude(collections) {
1400
- return {
1401
- enabled: collections.enabled,
1402
- collections: Object.fromEntries(Object.entries(collections.collections).map(([name, collection]) => [name, {
1403
- ...collection,
1404
- include: []
1405
- }]))
1406
- };
1407
- }
1408
- function resolveCollectionNames(input, collections) {
1409
- const available = Object.keys(collections.collections);
1410
- if (!input) return available;
1411
- const selected = new Set(Array.isArray(input) ? input : [input]);
1412
- return available.filter((name) => selected.has(name));
1413
- }
1414
- async function resolveCollectionDocument(root, srcDir, collection, entry) {
1415
- const candidate = path.resolve(root, srcDir, entry.source);
1416
- let source;
1417
- try {
1418
- source = await fs.readFile(candidate, "utf8");
1419
- } catch {
1420
- return;
1421
- }
1422
- return {
1423
- collection,
1424
- documentPath: candidate,
1425
- entry,
1426
- frontmatter: entry.frontmatter,
1427
- path: entry.path,
1428
- source
1429
- };
1430
- }
1431
1158
  //#endregion
1432
1159
  //#region src/html-host-registry.ts
1433
1160
  const SVELTE_HTML_HOST_MODULES_VIRTUAL_ID = "virtual:ox-content-svelte/html-host/modules";
1434
1161
  function createSvelteHtmlHostIslandRegistry(input = {}) {
1435
- const virtualModuleId = input.virtualModuleId ?? "virtual:ox-content-svelte/html-host/modules";
1436
- const resolvedVirtualModuleId = `\0${virtualModuleId}`;
1437
- let config;
1438
- let command = "build";
1439
- let components;
1440
- let cache;
1441
- let resolved = {
1442
- modules: [],
1443
- watchFiles: []
1444
- };
1445
- const context = () => ({
1446
- root: config?.root ?? input.root ?? process.cwd(),
1447
- mode: config?.mode ?? "production",
1448
- command
1162
+ return createHtmlHostIslandRegistry({
1163
+ ...input,
1164
+ virtualModuleId: input.virtualModuleId ?? "virtual:ox-content-svelte/html-host/modules",
1165
+ pluginName: input.pluginName ?? "ox-content:svelte-html-host-island-registry"
1449
1166
  });
1450
- const resolve = async () => {
1451
- cache ??= resolveSvelteHtmlHostIslandRegistry(input, context(), components).then((next) => {
1452
- resolved = next;
1453
- return next;
1454
- });
1455
- return cache;
1456
- };
1457
- const invalidate = () => {
1458
- cache = void 0;
1459
- };
1460
- return {
1461
- plugin: {
1462
- name: "ox-content:svelte-html-host-island-registry",
1463
- config(_config, env) {
1464
- command = env.command;
1465
- },
1466
- async configResolved(resolvedConfig) {
1467
- config = resolvedConfig;
1468
- components = input.components ? await resolveComponentsGlob(input.components, resolvedConfig.root) : {};
1469
- invalidate();
1470
- },
1471
- buildStart() {
1472
- invalidate();
1473
- },
1474
- resolveId(id) {
1475
- return id === virtualModuleId ? resolvedVirtualModuleId : null;
1476
- },
1477
- async load(id) {
1478
- if (id !== resolvedVirtualModuleId) return null;
1479
- return renderModulesVirtualModule(await resolve());
1480
- },
1481
- handleHotUpdate(ctx) {
1482
- if (!shouldInvalidate(ctx.file, context().root, input.oxContent?.srcDir, resolved.watchFiles, input.watch)) return;
1483
- invalidate();
1484
- invalidateVirtualModule(ctx.server, resolvedVirtualModuleId);
1485
- ctx.server.ws.send({ type: "full-reload" });
1486
- return [];
1487
- }
1488
- },
1489
- virtualModuleId,
1490
- resolve,
1491
- resolveClientModule(module) {
1492
- return toSvelteHtmlHostClientModuleId(module.serverModuleId, context().root);
1493
- }
1494
- };
1495
1167
  }
1496
- async function resolveSvelteHtmlHostIslandRegistry(input, context, resolvedComponents) {
1497
- const components = resolvedComponents ?? (input.components ? await resolveComponentsGlob(input.components, context.root) : {});
1498
- const documents = [...await resolveMaybe(input.documents, context) ?? [], ...await resolveInputCollectionDocuments(input, context) ?? []];
1499
- const entries = await resolveMaybe(input.entries, context);
1500
- const modules = /* @__PURE__ */ new Map();
1501
- const watchFiles = /* @__PURE__ */ new Set();
1502
- for (const file of input.watch ?? []) watchFiles.add(resolveWatchFile(file, context.root));
1503
- for (const entry of entries ?? []) {
1504
- addModule(modules, {
1505
- name: entry.name ?? path.basename(stripViteQuery(entry.moduleId), path.extname(entry.moduleId)),
1506
- moduleId: toSvelteHtmlHostClientModuleId(entry.moduleId, context.root),
1507
- exportName: entry.exportName ?? "default"
1508
- });
1509
- if (entry.documentPath) watchFiles.add(resolveWatchFile(entry.documentPath, context.root));
1510
- }
1511
- const oxContent = customHostOxContentOptions({
1512
- ...input.oxContent,
1513
- embeds: false
1514
- });
1515
- const srcDir = oxContent.srcDir ?? "content";
1516
- const contentRoot = resolveContentRootPath({
1517
- root: context.root,
1518
- srcDir
1519
- });
1520
- for (const document of documents) {
1521
- const documentPath = resolveDocumentPath(document.documentPath, context.root);
1522
- watchFiles.add(documentPath);
1523
- for (const dependency of document.dependencies ?? []) watchFiles.add(resolveWatchFile(dependency, context.root));
1524
- const materialized = await materializeDocument(document, documentPath, oxContent);
1525
- if (!materialized) continue;
1526
- const documentComponents = document.components ?? components;
1527
- const discovered = await discoverDocumentMdxIslands({
1528
- source: materialized.source,
1529
- html: materialized.html,
1530
- components: documentComponents,
1531
- imports: materialized.imports,
1532
- documentPath,
1533
- contentRoot,
1534
- srcDir,
1535
- root: context.root
1536
- });
1537
- const usedComponents = new Set(discovered.usedComponents);
1538
- if (materialized.html) for (const name of intersectHydratableComponentNames(collectMdxIslandNamesFromHtml(materialized.html), documentComponents, discovered.localBindings.keys())) usedComponents.add(name);
1539
- for (const name of usedComponents) {
1540
- const local = discovered.localBindings.get(name);
1541
- const serverModuleId = local ? local.resolvedPath : resolveComponentPath(documentComponents, name, context.root);
1542
- if (!serverModuleId) continue;
1543
- addModule(modules, {
1544
- name,
1545
- moduleId: toSvelteHtmlHostClientModuleId(serverModuleId, context.root),
1546
- exportName: local?.imported ?? "default"
1547
- });
1548
- }
1549
- }
1550
- return {
1551
- modules: [...modules.values()].sort((a, b) => `${a.moduleId}\0${a.exportName}\0${a.name}`.localeCompare(`${b.moduleId}\0${b.exportName}\0${b.name}`)),
1552
- watchFiles: [...watchFiles]
1553
- };
1554
- }
1555
- function resolveInputCollectionDocuments(input, context) {
1556
- if (!input.collectionDocuments) return void 0;
1557
- return resolveSvelteHtmlHostCollectionDocuments(input.collectionDocuments.oxContent === void 0 ? {
1558
- ...input.collectionDocuments,
1559
- oxContent: input.oxContent
1560
- } : input.collectionDocuments, context);
1561
- }
1562
- function renderModulesVirtualModule(registry) {
1563
- return [
1564
- "export const modules = {",
1565
- ...[...new Set(registry.modules.map((module) => module.moduleId))].sort().map((moduleId) => ` ${JSON.stringify(moduleId)}: () => import(${JSON.stringify(moduleId)}),`),
1566
- "};",
1567
- `export const clientModules = ${JSON.stringify(registry.modules, null, 2)};`,
1568
- "export default modules;",
1569
- ""
1570
- ].join("\n");
1571
- }
1572
- async function materializeDocument(document, documentPath, oxContent) {
1573
- const source = document.source ?? await readOptional(documentPath);
1574
- if (source === void 0 && document.html === void 0) return void 0;
1575
- if (document.imports && document.html !== void 0) return {
1576
- source: source ?? "",
1577
- html: document.html,
1578
- imports: document.imports
1579
- };
1580
- if (source === void 0) return {
1581
- source: "",
1582
- html: document.html,
1583
- imports: document.imports ?? []
1584
- };
1585
- const rendered = await renderMarkdown(source, documentPath, oxContent);
1586
- return {
1587
- source,
1588
- html: document.html ?? rendered.html,
1589
- imports: document.imports ?? rendered.imports
1590
- };
1591
- }
1592
- async function readOptional(file) {
1593
- try {
1594
- return await fs.readFile(file, "utf8");
1595
- } catch {
1596
- return;
1597
- }
1168
+ function resolveSvelteHtmlHostIslandRegistry(input, context, resolvedComponents) {
1169
+ return resolveHtmlHostIslandRegistry(input, context, resolvedComponents);
1598
1170
  }
1599
- function addModule(modules, module) {
1600
- modules.set(`${module.moduleId}\0${module.exportName}\0${module.name}`, module);
1601
- }
1602
- function resolveMaybe(value, context) {
1603
- return typeof value === "function" ? value(context) : value;
1604
- }
1605
- function resolveComponentPath(components, name, root) {
1606
- const specifier = components[name];
1607
- if (!specifier) return void 0;
1608
- if (isBareSpecifier(specifier) || specifier.startsWith("/@fs/")) return specifier;
1609
- if (specifier.startsWith("/") && !path.isAbsolute(specifier)) return specifier;
1610
- return path.isAbsolute(specifier) ? specifier : path.resolve(root, specifier);
1171
+ //#endregion
1172
+ //#region src/html-host-collection-documents.ts
1173
+ function createSvelteHtmlHostCollectionDocuments(input = {}) {
1174
+ return (context) => resolveSvelteHtmlHostCollectionDocuments(input, context);
1611
1175
  }
1612
- function invalidateVirtualModule(server, resolvedVirtualModuleId) {
1613
- const mod = server.moduleGraph.getModuleById(resolvedVirtualModuleId);
1614
- if (mod) server.moduleGraph.invalidateModule(mod);
1176
+ function resolveSvelteHtmlHostCollectionDocuments(input, context) {
1177
+ return resolveHtmlHostCollectionDocuments(input, context);
1615
1178
  }
1616
1179
  //#endregion
1617
1180
  //#region src/index.ts
@@ -1620,7 +1183,7 @@ const DEFAULT_MARKDOWN_EXTENSIONS = [
1620
1183
  ".markdown",
1621
1184
  ".mdx"
1622
1185
  ];
1623
- function normalizeMarkdownExtensions$1(extensions) {
1186
+ function normalizeMarkdownExtensions(extensions) {
1624
1187
  const values = extensions?.length ? extensions : DEFAULT_MARKDOWN_EXTENSIONS;
1625
1188
  return Array.from(new Map(values.map((extension) => {
1626
1189
  const value = extension.startsWith(".") ? extension : `.${extension}`;
@@ -1763,7 +1326,7 @@ function resolveSvelteOptions(options) {
1763
1326
  srcDir: options.srcDir ?? "docs",
1764
1327
  outDir: options.outDir ?? "dist",
1765
1328
  base: options.base ?? "/",
1766
- extensions: normalizeMarkdownExtensions$1(options.extensions),
1329
+ extensions: normalizeMarkdownExtensions(options.extensions),
1767
1330
  gfm: options.gfm ?? true,
1768
1331
  autolinks: options.autolinks ?? options.gfm ?? true,
1769
1332
  frontmatter: options.frontmatter ?? true,
@@ -1819,6 +1382,6 @@ export default components;
1819
1382
  `;
1820
1383
  }
1821
1384
  //#endregion
1822
- export { SVELTE_HTML_HOST_MODULES_VIRTUAL_ID, SvelteHtmlHostRenderError, createSvelteHtmlHostCollectionDocuments, createSvelteHtmlHostDomRenderer, createSvelteHtmlHostHydrate, createSvelteHtmlHostIslandRegistry, createSvelteHtmlHostLazyHydrate, createSvelteHtmlHostRenderer, initSvelteHtmlHost, loadSvelteHtmlHostDomRuntime, oxContent, oxContentSvelte, readSvelteHtmlHostSlot, renderHead, renderSvelteHtmlHost, resolveSvelteHtmlHostCollectionDocuments, resolveSvelteHtmlHostIslandRegistry, toSvelteHtmlHostClientModuleId };
1385
+ export { SVELTE_HTML_HOST_MODULES_VIRTUAL_ID, SvelteHtmlHostRenderError, createSvelteHtmlHostCollectionDocuments, createSvelteHtmlHostDomRenderer, createSvelteHtmlHostHydrate, createSvelteHtmlHostIslandRegistry, createSvelteHtmlHostLazyHydrate, createSvelteHtmlHostRenderer, initSvelteHtmlHost, loadSvelteHtmlHostDomRuntime, oxContent, oxContentSvelte, readSvelteHtmlHostSlot, renderHead, renderSvelteHtmlHost, resolveSvelteHtmlHostCollectionDocuments, resolveSvelteHtmlHostIslandRegistry, toHtmlHostClientModuleId as toSvelteHtmlHostClientModuleId };
1823
1386
 
1824
1387
  //# sourceMappingURL=index.mjs.map