@ox-content/vite-plugin 2.26.0 → 2.27.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
@@ -1697,16 +1697,53 @@ function convertNavGroupsForRust(navGroups) {
1697
1697
  return converted;
1698
1698
  }
1699
1699
  /**
1700
- * Generates HTML page with navigation using Rust NAPI bindings.
1700
+ * Converts a `TocEntry` tree into the plain shape the Rust binding expects.
1701
+ * Hoisted to module scope so it isn't reallocated for every page; the
1702
+ * per-page `.map` over `pageData.toc` still runs since the TOC is page-specific.
1701
1703
  */
1702
- async function generateHtmlPage(pageData, navGroups, siteName, base, ogImage, theme, locale, availableLocales) {
1703
- const mod = await require_napi.importNapiModule();
1704
- const toRustTocEntry = (entry) => ({
1704
+ function toRustTocEntry(entry) {
1705
+ return {
1705
1706
  depth: entry.depth,
1706
1707
  text: entry.text,
1707
1708
  slug: entry.slug,
1708
1709
  children: entry.children?.map(toRustTocEntry) ?? []
1709
- });
1710
+ };
1711
+ }
1712
+ /**
1713
+ * Per-build cache for the Rust-facing locale list. `i18n.locales` is the same
1714
+ * reference for every page in a build, so this mapping (and the `?? "ltr"`
1715
+ * default) only runs once per build instead of once per page.
1716
+ */
1717
+ const rustLocalesCache = /* @__PURE__ */ new WeakMap();
1718
+ function toRustLocales(locales) {
1719
+ const cached = rustLocalesCache.get(locales);
1720
+ if (cached) return cached;
1721
+ const converted = locales.map((locale) => ({
1722
+ code: locale.code,
1723
+ name: locale.name,
1724
+ dir: locale.dir ?? "ltr"
1725
+ }));
1726
+ rustLocalesCache.set(locales, converted);
1727
+ return converted;
1728
+ }
1729
+ /**
1730
+ * Per-build cache for the locale-code list passed to `getSsgPageLocale`. The
1731
+ * `i18n.locales` reference is stable across a build, so the `.map` to codes
1732
+ * runs once instead of once per page.
1733
+ */
1734
+ const localeCodesCache = /* @__PURE__ */ new WeakMap();
1735
+ function localeCodesFor(locales) {
1736
+ const cached = localeCodesCache.get(locales);
1737
+ if (cached) return cached;
1738
+ const codes = locales.map((locale) => locale.code);
1739
+ localeCodesCache.set(locales, codes);
1740
+ return codes;
1741
+ }
1742
+ /**
1743
+ * Generates HTML page with navigation using Rust NAPI bindings.
1744
+ */
1745
+ async function generateHtmlPage(pageData, navGroups, siteName, base, ogImage, theme, locale, availableLocales) {
1746
+ const mod = await require_napi.importNapiModule();
1710
1747
  const tocForRust = pageData.toc.map(toRustTocEntry);
1711
1748
  const navGroupsForRust = convertNavGroupsForRust(navGroups);
1712
1749
  const themeForRust = theme ? require_vitepress.themeToNapi(theme) : void 0;
@@ -1755,11 +1792,7 @@ async function generateHtmlPage(pageData, navGroups, siteName, base, ogImage, th
1755
1792
  ogImage,
1756
1793
  theme: themeForRust,
1757
1794
  locale,
1758
- availableLocales: availableLocales?.map((l) => ({
1759
- code: l.code,
1760
- name: l.name,
1761
- dir: l.dir ?? "ltr"
1762
- }))
1795
+ availableLocales: availableLocales ? toRustLocales(availableLocales) : void 0
1763
1796
  });
1764
1797
  }
1765
1798
  async function externalizeSharedPageAssets(pages, outDir, base) {
@@ -1788,7 +1821,7 @@ function resolveNavigationGroups(navigation, base, extension) {
1788
1821
  }
1789
1822
  function getPageLocale(urlPath, i18n) {
1790
1823
  if (!i18n) return void 0;
1791
- return require_napi.importNapiModuleSync().getSsgPageLocale(urlPath, i18n.defaultLocale, i18n.locales.map((locale) => locale.code)) ?? void 0;
1824
+ return require_napi.importNapiModuleSync().getSsgPageLocale(urlPath, i18n.defaultLocale, localeCodesFor(i18n.locales)) ?? void 0;
1792
1825
  }
1793
1826
  function getRoutePaths(inputPath, srcDir, outDir, base, extension, siteUrl) {
1794
1827
  return require_napi.importNapiModuleSync().resolveSsgRoutePaths(inputPath, srcDir, outDir, base, extension, siteUrl);
@@ -2908,12 +2941,15 @@ async function runStandardSpellcheckDocuments(maskedDocuments, options) {
2908
2941
  };
2909
2942
  return Promise.all(maskedDocuments.map(async (maskedDocument, index) => {
2910
2943
  if (maskedDocument.trim().length === 0) return [];
2911
- return (await spellCheckDocument({
2944
+ const result = await spellCheckDocument({
2912
2945
  languageId: "plaintext",
2913
2946
  locale,
2914
2947
  text: maskedDocument,
2915
2948
  uri: `file:///ox-content-lint-${index}.md`
2916
- }, spellCheckOptions, settings)).issues.map((issue) => mapStandardIssueToDiagnostic(issue, standard.languages, maskedDocument));
2949
+ }, spellCheckOptions, settings);
2950
+ const newlineOffsets = [];
2951
+ for (let i = 0; i < maskedDocument.length; i++) if (maskedDocument.charCodeAt(i) === 10) newlineOffsets.push(i);
2952
+ return result.issues.map((issue) => mapStandardIssueToDiagnostic(issue, standard.languages, newlineOffsets));
2917
2953
  }));
2918
2954
  } catch (error) {
2919
2955
  const imports = standard.imports.join(", ");
@@ -2934,8 +2970,8 @@ async function loadCspellLib() {
2934
2970
  cspellLibPromise ??= import("cspell-lib");
2935
2971
  return cspellLibPromise;
2936
2972
  }
2937
- function mapStandardIssueToDiagnostic(issue, languages, documentText) {
2938
- const line = getLineNumberAtOffset(documentText, issue.line.offset);
2973
+ function mapStandardIssueToDiagnostic(issue, languages, newlineOffsets) {
2974
+ const line = getLineNumberAtOffset(newlineOffsets, issue.line.offset);
2939
2975
  const column = issue.offset - issue.line.offset + 1;
2940
2976
  return {
2941
2977
  column,
@@ -2949,10 +2985,15 @@ function mapStandardIssueToDiagnostic(issue, languages, documentText) {
2949
2985
  suggestions: issue.suggestions?.slice(0, 3)
2950
2986
  };
2951
2987
  }
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;
2988
+ function getLineNumberAtOffset(newlineOffsets, offset) {
2989
+ let lo = 0;
2990
+ let hi = newlineOffsets.length;
2991
+ while (lo < hi) {
2992
+ const mid = lo + hi >>> 1;
2993
+ if (newlineOffsets[mid] < offset) lo = mid + 1;
2994
+ else hi = mid;
2995
+ }
2996
+ return lo + 1;
2956
2997
  }
2957
2998
  function inferStandardIssueLanguage(word, languages) {
2958
2999
  if (/[\p{Script=Hiragana}\p{Script=Katakana}]/u.test(word) && languages.includes("ja")) return "ja";