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

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,72 @@ 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 {
1101
+ html: rendered.html ?? rendered.body ?? "",
1102
+ head: rendered.head
1103
+ };
1254
1104
  }
1255
- function hasAttr(openTag, name) {
1256
- return new RegExp(`\\s${name}(?:\\s*=|\\s|>|$)`, "i").test(openTag);
1105
+ function resolveSvelteRuntime(server, shared) {
1106
+ return {
1107
+ render: runtimeFunction(server, "render", "svelte/server"),
1108
+ createRawSnippet: runtimeFunction(shared, "createRawSnippet", "svelte")
1109
+ };
1257
1110
  }
1258
- function errorMessage(error) {
1259
- return error instanceof Error ? error.message : String(error);
1111
+ function runtimeFunction(module, name, moduleId) {
1112
+ const value = module && typeof module === "object" ? module[name] : void 0;
1113
+ if (typeof value !== "function") throw new Error(`Svelte HTML host renderer could not load ${moduleId}.${name}.`);
1114
+ return value;
1260
1115
  }
1261
1116
  //#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
- }
1117
+ //#region src/html-host.ts
1118
+ async function renderSvelteHtmlHost(input) {
1119
+ const resolveClientModule = input.resolveClientModule;
1120
+ return await renderHtmlHost({
1121
+ ...input,
1122
+ frameworkName: "Svelte",
1123
+ renderComponent: input.renderComponent ?? defaultRenderSvelteHtmlComponent,
1124
+ resolveClientModule
1125
+ });
1306
1126
  }
1307
- function toPosixPath(file) {
1308
- return file.replace(/\\/g, "/");
1127
+ function createSvelteHtmlHostHydrate(input) {
1128
+ return createHtmlHostHydrate(input);
1309
1129
  }
1310
1130
  //#endregion
1311
1131
  //#region src/html-host-renderer.ts
1312
1132
  var SvelteHtmlHostRenderError = class extends Error {
1313
1133
  diagnostics;
1314
1134
  constructor(diagnostics) {
1315
- super(formatSvelteHtmlHostDiagnostics(diagnostics));
1135
+ super(formatHtmlHostDiagnostics(diagnostics));
1316
1136
  this.name = "SvelteHtmlHostRenderError";
1317
1137
  this.diagnostics = [...diagnostics];
1318
1138
  }
1319
1139
  };
1320
1140
  function createSvelteHtmlHostRenderer(input) {
1321
1141
  const policy = input.diagnostics ?? "throw";
1142
+ const defaultRenderComponent = createSvelteHtmlHostComponentRenderer(input.loadModule);
1322
1143
  return async (html, context) => {
1323
1144
  const root = context.root ?? input.root;
1324
1145
  const result = await renderSvelteHtmlHost({
@@ -1330,288 +1151,33 @@ function createSvelteHtmlHostRenderer(input) {
1330
1151
  imports: context.imports,
1331
1152
  components: context.components ?? input.components,
1332
1153
  loadModule: input.loadModule,
1333
- renderComponent: context.renderComponent ?? input.renderComponent,
1334
- resolveClientModule: context.resolveClientModule ?? input.resolveClientModule ?? ((module) => toSvelteHtmlHostClientModuleId(module.serverModuleId, root))
1154
+ renderComponent: context.renderComponent ?? input.renderComponent ?? defaultRenderComponent,
1155
+ resolveClientModule: context.resolveClientModule ?? input.resolveClientModule ?? ((module) => toHtmlHostClientModuleId$1(module.serverModuleId, root))
1335
1156
  });
1336
1157
  if (policy === "throw" && result.diagnostics.length > 0) throw new SvelteHtmlHostRenderError(result.diagnostics);
1337
1158
  return result;
1338
1159
  };
1339
1160
  }
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
1161
  //#endregion
1432
1162
  //#region src/html-host-registry.ts
1433
1163
  const SVELTE_HTML_HOST_MODULES_VIRTUAL_ID = "virtual:ox-content-svelte/html-host/modules";
1434
1164
  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
1165
+ return createHtmlHostIslandRegistry({
1166
+ ...input,
1167
+ virtualModuleId: input.virtualModuleId ?? "virtual:ox-content-svelte/html-host/modules",
1168
+ pluginName: input.pluginName ?? "ox-content:svelte-html-host-island-registry"
1449
1169
  });
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
1170
  }
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
- }
1171
+ function resolveSvelteHtmlHostIslandRegistry(input, context, resolvedComponents) {
1172
+ return resolveHtmlHostIslandRegistry(input, context, resolvedComponents);
1598
1173
  }
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);
1174
+ //#endregion
1175
+ //#region src/html-host-collection-documents.ts
1176
+ function createSvelteHtmlHostCollectionDocuments(input = {}) {
1177
+ return (context) => resolveSvelteHtmlHostCollectionDocuments(input, context);
1611
1178
  }
1612
- function invalidateVirtualModule(server, resolvedVirtualModuleId) {
1613
- const mod = server.moduleGraph.getModuleById(resolvedVirtualModuleId);
1614
- if (mod) server.moduleGraph.invalidateModule(mod);
1179
+ function resolveSvelteHtmlHostCollectionDocuments(input, context) {
1180
+ return resolveHtmlHostCollectionDocuments(input, context);
1615
1181
  }
1616
1182
  //#endregion
1617
1183
  //#region src/index.ts
@@ -1620,7 +1186,7 @@ const DEFAULT_MARKDOWN_EXTENSIONS = [
1620
1186
  ".markdown",
1621
1187
  ".mdx"
1622
1188
  ];
1623
- function normalizeMarkdownExtensions$1(extensions) {
1189
+ function normalizeMarkdownExtensions(extensions) {
1624
1190
  const values = extensions?.length ? extensions : DEFAULT_MARKDOWN_EXTENSIONS;
1625
1191
  return Array.from(new Map(values.map((extension) => {
1626
1192
  const value = extension.startsWith(".") ? extension : `.${extension}`;
@@ -1763,7 +1329,7 @@ function resolveSvelteOptions(options) {
1763
1329
  srcDir: options.srcDir ?? "docs",
1764
1330
  outDir: options.outDir ?? "dist",
1765
1331
  base: options.base ?? "/",
1766
- extensions: normalizeMarkdownExtensions$1(options.extensions),
1332
+ extensions: normalizeMarkdownExtensions(options.extensions),
1767
1333
  gfm: options.gfm ?? true,
1768
1334
  autolinks: options.autolinks ?? options.gfm ?? true,
1769
1335
  frontmatter: options.frontmatter ?? true,
@@ -1819,6 +1385,6 @@ export default components;
1819
1385
  `;
1820
1386
  }
1821
1387
  //#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 };
1388
+ 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
1389
 
1824
1390
  //# sourceMappingURL=index.mjs.map