@farming-labs/docs 0.2.123 → 0.2.124

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.
Files changed (2) hide show
  1. package/dist/mcp.mjs +108 -61
  2. package/package.json +1 -1
package/dist/mcp.mjs CHANGED
@@ -5953,82 +5953,107 @@ function resolveFilesystemDocsPageSource(dir) {
5953
5953
  candidate
5954
5954
  ));
5955
5955
  }
5956
- function hasVisibleDescendantFilesystemDocsPage(dir) {
5957
- let entries;
5958
- try {
5959
- entries = fs.readdirSync(
5956
+ function normalizeFrontmatterLastmod(value) {
5957
+ if (typeof value === "string") return value;
5958
+ return value instanceof Date && Number.isFinite(value.getTime()) ? value.toISOString() : void 0;
5959
+ }
5960
+ function scanFilesystemDocsPages(contentDirAbs, entry, rootDir) {
5961
+ const pages = [];
5962
+ const directoryEntries = /* @__PURE__ */ new Map();
5963
+ const fileStats = /* @__PURE__ */ new Map();
5964
+ const documents = /* @__PURE__ */ new Map();
5965
+ const visibleDescendants = /* @__PURE__ */ new Map();
5966
+ function readDirectory(dir) {
5967
+ const cached = directoryEntries.get(dir);
5968
+ if (cached) return cached;
5969
+ const entries = fs.readdirSync(
5960
5970
  /* turbopackIgnore: true */
5961
5971
  dir
5962
- );
5963
- } catch {
5964
- return false;
5972
+ ).sort();
5973
+ directoryEntries.set(dir, entries);
5974
+ return entries;
5965
5975
  }
5966
- for (const name of entries.sort()) {
5967
- const full = path.join(
5976
+ function readStat(file) {
5977
+ const cached = fileStats.get(file);
5978
+ if (cached) return cached;
5979
+ const stat = fs.statSync(
5968
5980
  /* turbopackIgnore: true */
5969
- dir,
5970
- name
5981
+ file
5971
5982
  );
5983
+ fileStats.set(file, stat);
5984
+ return stat;
5985
+ }
5986
+ function readDocument(file) {
5987
+ const cached = documents.get(file);
5988
+ if (cached) return cached;
5989
+ const { data, content } = matter(fs.readFileSync(
5990
+ /* turbopackIgnore: true */
5991
+ file,
5992
+ "utf-8"
5993
+ ));
5994
+ const document = {
5995
+ data,
5996
+ content
5997
+ };
5998
+ documents.set(file, document);
5999
+ return document;
6000
+ }
6001
+ function hasVisibleDescendantFilesystemDocsPage(dir) {
6002
+ const cached = visibleDescendants.get(dir);
6003
+ if (cached !== void 0) return cached;
6004
+ const remember = (visible) => {
6005
+ visibleDescendants.set(dir, visible);
6006
+ return visible;
6007
+ };
6008
+ let entries;
5972
6009
  try {
5973
- if (!fs.statSync(
5974
- /* turbopackIgnore: true */
5975
- full
5976
- ).isDirectory()) continue;
6010
+ entries = readDirectory(dir);
5977
6011
  } catch {
5978
- continue;
6012
+ return false;
5979
6013
  }
5980
- const pageSource = resolveFilesystemDocsPageSource(full);
5981
- if (pageSource) try {
5982
- const data = matter(fs.readFileSync(
6014
+ for (const name of entries) {
6015
+ const full = path.join(
5983
6016
  /* turbopackIgnore: true */
5984
- pageSource,
5985
- "utf-8"
5986
- )).data;
5987
- const hiddenFolderIndex = resolvePageSidebarFolderIndexBehavior(data.sidebar) === "hidden";
5988
- if (data.hidden !== true && !hiddenFolderIndex) return true;
5989
- } catch {
5990
- return true;
6017
+ dir,
6018
+ name
6019
+ );
6020
+ try {
6021
+ if (!readStat(full).isDirectory()) continue;
6022
+ } catch {
6023
+ continue;
6024
+ }
6025
+ const pageSource = resolveFilesystemDocsPageSource(full);
6026
+ if (pageSource) try {
6027
+ const data = readDocument(pageSource).data;
6028
+ const hiddenFolderIndex = resolvePageSidebarFolderIndexBehavior(data.sidebar) === "hidden";
6029
+ if (data.hidden !== true && !hiddenFolderIndex) return remember(true);
6030
+ } catch {
6031
+ return remember(true);
6032
+ }
6033
+ if (hasVisibleDescendantFilesystemDocsPage(full)) return remember(true);
5991
6034
  }
5992
- if (hasVisibleDescendantFilesystemDocsPage(full)) return true;
6035
+ return remember(false);
5993
6036
  }
5994
- return false;
5995
- }
5996
- function normalizeFrontmatterLastmod(value) {
5997
- if (typeof value === "string") return value;
5998
- return value instanceof Date && Number.isFinite(value.getTime()) ? value.toISOString() : void 0;
5999
- }
6000
- function scanFilesystemDocsPages(contentDirAbs, entry, rootDir) {
6001
- const pages = [];
6002
6037
  function scan(dir, slugParts) {
6003
6038
  if (!fs.existsSync(
6004
6039
  /* turbopackIgnore: true */
6005
6040
  dir
6006
6041
  )) return;
6007
- const entries = fs.readdirSync(
6008
- /* turbopackIgnore: true */
6009
- dir
6010
- ).sort();
6042
+ const entries = readDirectory(dir);
6011
6043
  for (const name of entries) {
6012
6044
  const full = path.join(
6013
6045
  /* turbopackIgnore: true */
6014
6046
  dir,
6015
6047
  name
6016
6048
  );
6017
- const stat = fs.statSync(
6018
- /* turbopackIgnore: true */
6019
- full
6020
- );
6049
+ const stat = readStat(full);
6021
6050
  if (stat.isDirectory()) {
6022
6051
  scan(full, [...slugParts, name]);
6023
6052
  continue;
6024
6053
  }
6025
6054
  if (name === "agent.md") continue;
6026
6055
  if (!name.endsWith(".md") && !name.endsWith(".mdx") && !name.endsWith(".svx")) continue;
6027
- const { data, content } = matter(fs.readFileSync(
6028
- /* turbopackIgnore: true */
6029
- full,
6030
- "utf-8"
6031
- ));
6056
+ const { data, content } = readDocument(full);
6032
6057
  const baseName = name.replace(/\.(md|mdx|svx)$/, "");
6033
6058
  const isIndex = baseName === "index" || baseName === "page" || baseName === "+page";
6034
6059
  if (isIndex && resolvePageSidebarFolderIndexBehavior(data.sidebar) === "hidden" && hasVisibleDescendantFilesystemDocsPage(dir)) continue;
@@ -6104,12 +6129,42 @@ function resolveRelatedForMcpPages(pages) {
6104
6129
  function buildNavigationTreeFromPages(pages, siteTitle, ordering) {
6105
6130
  const bySlug = new Map(pages.map((page) => [page.slug, page]));
6106
6131
  const rootPage = bySlug.get("");
6132
+ const childrenBySlug = /* @__PURE__ */ new Map();
6133
+ const orderingIndexes = /* @__PURE__ */ new Map();
6134
+ function childrenOf(slug) {
6135
+ let children = childrenBySlug.get(slug);
6136
+ if (!children) {
6137
+ children = /* @__PURE__ */ new Set();
6138
+ childrenBySlug.set(slug, children);
6139
+ }
6140
+ return children;
6141
+ }
6142
+ for (const page of pages) {
6143
+ const slug = page.slug;
6144
+ let parent = "";
6145
+ let start = 0;
6146
+ while (start < slug.length) {
6147
+ const separator = slug.indexOf("/", start);
6148
+ const child = separator === -1 ? slug : slug.slice(0, separator);
6149
+ childrenOf(parent).add(child);
6150
+ if (separator === -1) break;
6151
+ childrenOf(child);
6152
+ parent = child;
6153
+ start = separator + 1;
6154
+ }
6155
+ }
6107
6156
  function childOrderFor(parentSlug) {
6108
6157
  if (!Array.isArray(ordering)) return void 0;
6109
6158
  if (!parentSlug) return ordering;
6110
6159
  let items = ordering;
6111
6160
  for (const segment of parentSlug.split("/")) {
6112
- items = (items?.find((item) => item.slug === segment))?.children;
6161
+ let index = orderingIndexes.get(items);
6162
+ if (!index) {
6163
+ index = /* @__PURE__ */ new Map();
6164
+ for (const item of items) if (!index.has(item.slug)) index.set(item.slug, item);
6165
+ orderingIndexes.set(items, index);
6166
+ }
6167
+ items = index.get(segment)?.children;
6113
6168
  if (!items) return void 0;
6114
6169
  }
6115
6170
  return items;
@@ -6118,10 +6173,11 @@ function buildNavigationTreeFromPages(pages, siteTitle, ordering) {
6118
6173
  const explicitOrder = childOrderFor(parentSlug);
6119
6174
  if (explicitOrder) {
6120
6175
  const explicit = new Set(explicitOrder.map((item) => item.slug));
6176
+ const available = new Set(childSlugs);
6121
6177
  const ordered = [];
6122
6178
  for (const item of explicitOrder) {
6123
6179
  const childSlug = parentSlug ? `${parentSlug}/${item.slug}` : item.slug;
6124
- if (childSlugs.includes(childSlug)) ordered.push(childSlug);
6180
+ if (available.has(childSlug)) ordered.push(childSlug);
6125
6181
  }
6126
6182
  for (const childSlug of childSlugs) {
6127
6183
  const segment = childSlug.split("/").pop() ?? childSlug;
@@ -6140,20 +6196,11 @@ function buildNavigationTreeFromPages(pages, siteTitle, ordering) {
6140
6196
  return [...childSlugs].sort((left, right) => left.localeCompare(right));
6141
6197
  }
6142
6198
  function buildLevel(parentSlug) {
6143
- const prefix = parentSlug ? `${parentSlug}/` : "";
6144
- const childSet = /* @__PURE__ */ new Set();
6145
- for (const page of pages) {
6146
- if (!page.slug.startsWith(prefix) || page.slug === parentSlug) continue;
6147
- const remainder = page.slug.slice(prefix.length);
6148
- if (!remainder) continue;
6149
- const [firstSegment] = remainder.split("/");
6150
- childSet.add(parentSlug ? `${parentSlug}/${firstSegment}` : firstSegment);
6151
- }
6152
- const childSlugs = sortChildSlugs([...childSet], parentSlug);
6199
+ const childSlugs = sortChildSlugs([...childrenBySlug.get(parentSlug) ?? []], parentSlug);
6153
6200
  const nodes = [];
6154
6201
  for (const childSlug of childSlugs) {
6155
6202
  const page = bySlug.get(childSlug);
6156
- const hasChildren = pages.some((candidate) => candidate.slug.startsWith(`${childSlug}/`));
6203
+ const hasChildren = childrenBySlug.has(childSlug);
6157
6204
  const segment = childSlug.split("/").pop() ?? childSlug;
6158
6205
  const name = page?.title ?? titleize(segment);
6159
6206
  const icon = page?.icon;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farming-labs/docs",
3
- "version": "0.2.123",
3
+ "version": "0.2.124",
4
4
  "description": "Modern, flexible MDX-based docs framework — core types, config, and CLI",
5
5
  "keywords": [
6
6
  "docs",