@ox-content/vite-plugin 2.26.0 → 2.28.0

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.cjs CHANGED
@@ -3,6 +3,7 @@ const require_chunk = require("./chunk.cjs");
3
3
  const require_napi = require("./napi.cjs");
4
4
  const require_mermaid = require("./mermaid.cjs");
5
5
  const require_tabs = require("./tabs.cjs");
6
+ require("./pm.cjs");
6
7
  const require_youtube = require("./youtube.cjs");
7
8
  const require_github = require("./github.cjs");
8
9
  const require_ogp = require("./ogp.cjs");
@@ -280,13 +281,17 @@ async function highlightCode(html, theme = "github-dark", langs = []) {
280
281
  * Transform all enabled plugins in HTML content.
281
282
  */
282
283
  async function transformAllPlugins(html, options = {}) {
283
- const { tabs = true, youtube = true, github = true, ogp, openGraph, mermaid = true, githubToken } = options;
284
+ const { tabs = true, pm = true, youtube = true, github = true, ogp, openGraph, mermaid = true, githubToken } = options;
284
285
  let result = html;
285
286
  const ogpOptions = openGraph ?? ogp ?? true;
286
287
  if (tabs) {
287
288
  const { transformTabs } = await Promise.resolve().then(() => require("./tabs.cjs")).then((n) => n.tabs_exports);
288
289
  result = await transformTabs(result);
289
290
  }
291
+ if (pm !== false) {
292
+ const { transformPm } = await Promise.resolve().then(() => require("./pm.cjs")).then((n) => n.pm_exports);
293
+ result = await transformPm(result, typeof pm === "object" ? pm : {});
294
+ }
290
295
  if (youtube) {
291
296
  const { transformYouTube } = await Promise.resolve().then(() => require("./youtube.cjs")).then((n) => n.youtube_exports);
292
297
  result = await transformYouTube(result);
@@ -1697,16 +1702,53 @@ function convertNavGroupsForRust(navGroups) {
1697
1702
  return converted;
1698
1703
  }
1699
1704
  /**
1700
- * Generates HTML page with navigation using Rust NAPI bindings.
1705
+ * Converts a `TocEntry` tree into the plain shape the Rust binding expects.
1706
+ * Hoisted to module scope so it isn't reallocated for every page; the
1707
+ * per-page `.map` over `pageData.toc` still runs since the TOC is page-specific.
1701
1708
  */
1702
- async function generateHtmlPage(pageData, navGroups, siteName, base, ogImage, theme, locale, availableLocales) {
1703
- const mod = await require_napi.importNapiModule();
1704
- const toRustTocEntry = (entry) => ({
1709
+ function toRustTocEntry(entry) {
1710
+ return {
1705
1711
  depth: entry.depth,
1706
1712
  text: entry.text,
1707
1713
  slug: entry.slug,
1708
1714
  children: entry.children?.map(toRustTocEntry) ?? []
1709
- });
1715
+ };
1716
+ }
1717
+ /**
1718
+ * Per-build cache for the Rust-facing locale list. `i18n.locales` is the same
1719
+ * reference for every page in a build, so this mapping (and the `?? "ltr"`
1720
+ * default) only runs once per build instead of once per page.
1721
+ */
1722
+ const rustLocalesCache = /* @__PURE__ */ new WeakMap();
1723
+ function toRustLocales(locales) {
1724
+ const cached = rustLocalesCache.get(locales);
1725
+ if (cached) return cached;
1726
+ const converted = locales.map((locale) => ({
1727
+ code: locale.code,
1728
+ name: locale.name,
1729
+ dir: locale.dir ?? "ltr"
1730
+ }));
1731
+ rustLocalesCache.set(locales, converted);
1732
+ return converted;
1733
+ }
1734
+ /**
1735
+ * Per-build cache for the locale-code list passed to `getSsgPageLocale`. The
1736
+ * `i18n.locales` reference is stable across a build, so the `.map` to codes
1737
+ * runs once instead of once per page.
1738
+ */
1739
+ const localeCodesCache = /* @__PURE__ */ new WeakMap();
1740
+ function localeCodesFor(locales) {
1741
+ const cached = localeCodesCache.get(locales);
1742
+ if (cached) return cached;
1743
+ const codes = locales.map((locale) => locale.code);
1744
+ localeCodesCache.set(locales, codes);
1745
+ return codes;
1746
+ }
1747
+ /**
1748
+ * Generates HTML page with navigation using Rust NAPI bindings.
1749
+ */
1750
+ async function generateHtmlPage(pageData, navGroups, siteName, base, ogImage, theme, locale, availableLocales) {
1751
+ const mod = await require_napi.importNapiModule();
1710
1752
  const tocForRust = pageData.toc.map(toRustTocEntry);
1711
1753
  const navGroupsForRust = convertNavGroupsForRust(navGroups);
1712
1754
  const themeForRust = theme ? require_vitepress.themeToNapi(theme) : void 0;
@@ -1755,11 +1797,7 @@ async function generateHtmlPage(pageData, navGroups, siteName, base, ogImage, th
1755
1797
  ogImage,
1756
1798
  theme: themeForRust,
1757
1799
  locale,
1758
- availableLocales: availableLocales?.map((l) => ({
1759
- code: l.code,
1760
- name: l.name,
1761
- dir: l.dir ?? "ltr"
1762
- }))
1800
+ availableLocales: availableLocales ? toRustLocales(availableLocales) : void 0
1763
1801
  });
1764
1802
  }
1765
1803
  async function externalizeSharedPageAssets(pages, outDir, base) {
@@ -1788,7 +1826,7 @@ function resolveNavigationGroups(navigation, base, extension) {
1788
1826
  }
1789
1827
  function getPageLocale(urlPath, i18n) {
1790
1828
  if (!i18n) return void 0;
1791
- return require_napi.importNapiModuleSync().getSsgPageLocale(urlPath, i18n.defaultLocale, i18n.locales.map((locale) => locale.code)) ?? void 0;
1829
+ return require_napi.importNapiModuleSync().getSsgPageLocale(urlPath, i18n.defaultLocale, localeCodesFor(i18n.locales)) ?? void 0;
1792
1830
  }
1793
1831
  function getRoutePaths(inputPath, srcDir, outDir, base, extension, siteUrl) {
1794
1832
  return require_napi.importNapiModuleSync().resolveSsgRoutePaths(inputPath, srcDir, outDir, base, extension, siteUrl);
@@ -2908,12 +2946,15 @@ async function runStandardSpellcheckDocuments(maskedDocuments, options) {
2908
2946
  };
2909
2947
  return Promise.all(maskedDocuments.map(async (maskedDocument, index) => {
2910
2948
  if (maskedDocument.trim().length === 0) return [];
2911
- return (await spellCheckDocument({
2949
+ const result = await spellCheckDocument({
2912
2950
  languageId: "plaintext",
2913
2951
  locale,
2914
2952
  text: maskedDocument,
2915
2953
  uri: `file:///ox-content-lint-${index}.md`
2916
- }, spellCheckOptions, settings)).issues.map((issue) => mapStandardIssueToDiagnostic(issue, standard.languages, maskedDocument));
2954
+ }, spellCheckOptions, settings);
2955
+ const newlineOffsets = [];
2956
+ for (let i = 0; i < maskedDocument.length; i++) if (maskedDocument.charCodeAt(i) === 10) newlineOffsets.push(i);
2957
+ return result.issues.map((issue) => mapStandardIssueToDiagnostic(issue, standard.languages, newlineOffsets));
2917
2958
  }));
2918
2959
  } catch (error) {
2919
2960
  const imports = standard.imports.join(", ");
@@ -2934,8 +2975,8 @@ async function loadCspellLib() {
2934
2975
  cspellLibPromise ??= import("cspell-lib");
2935
2976
  return cspellLibPromise;
2936
2977
  }
2937
- function mapStandardIssueToDiagnostic(issue, languages, documentText) {
2938
- const line = getLineNumberAtOffset(documentText, issue.line.offset);
2978
+ function mapStandardIssueToDiagnostic(issue, languages, newlineOffsets) {
2979
+ const line = getLineNumberAtOffset(newlineOffsets, issue.line.offset);
2939
2980
  const column = issue.offset - issue.line.offset + 1;
2940
2981
  return {
2941
2982
  column,
@@ -2949,10 +2990,15 @@ function mapStandardIssueToDiagnostic(issue, languages, documentText) {
2949
2990
  suggestions: issue.suggestions?.slice(0, 3)
2950
2991
  };
2951
2992
  }
2952
- function getLineNumberAtOffset(text, offset) {
2953
- let line = 1;
2954
- for (let index = 0; index < offset && index < text.length; index++) if (text.charCodeAt(index) === 10) line++;
2955
- return line;
2993
+ function getLineNumberAtOffset(newlineOffsets, offset) {
2994
+ let lo = 0;
2995
+ let hi = newlineOffsets.length;
2996
+ while (lo < hi) {
2997
+ const mid = lo + hi >>> 1;
2998
+ if (newlineOffsets[mid] < offset) lo = mid + 1;
2999
+ else hi = mid;
3000
+ }
3001
+ return lo + 1;
2956
3002
  }
2957
3003
  function inferStandardIssueLanguage(word, languages) {
2958
3004
  if (/[\p{Script=Hiragana}\p{Script=Katakana}]/u.test(word) && languages.includes("ja")) return "ja";