@hraness/wordcell 0.22.3 → 0.22.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.
Files changed (53) hide show
  1. package/README.md +20 -17
  2. package/dist/authoring.js +2 -2
  3. package/dist/{authority-06eqhqam.js → authority-3ga47syb.js} +2 -2
  4. package/dist/benchmark.js +3 -3
  5. package/dist/cli.js +16 -16
  6. package/dist/evaluation-builder.js +10 -10
  7. package/dist/evaluation-kb.js +10 -10
  8. package/dist/graph-authority.js +4 -4
  9. package/dist/graph-percolation.js +6 -6
  10. package/dist/graph.js +3 -1
  11. package/dist/{index-1k595z6v.js → index-1r5rnkfr.js} +2 -2
  12. package/dist/{index-3agn8scn.js → index-23m6bbjt.js} +47 -11
  13. package/dist/{index-q7tbg07z.js → index-42tb8qqp.js} +7 -7
  14. package/dist/{index-yx6p1vzc.js → index-8bgnhjgq.js} +17 -16
  15. package/dist/{index-233z9wmn.js → index-8v6k9h4r.js} +13 -5
  16. package/dist/{index-vnybgywh.js → index-aer0jdrq.js} +1 -1
  17. package/dist/{index-xv80vzfp.js → index-f75zmmdr.js} +4 -4
  18. package/dist/{index-ecqpgr5y.js → index-f7fnww7a.js} +1 -1
  19. package/dist/{index-djrcc1yf.js → index-gtwqye5a.js} +4 -4
  20. package/dist/{index-bqtqeak3.js → index-h2qn3y3f.js} +4 -4
  21. package/dist/{index-rr9kzq4n.js → index-n57tewfr.js} +2 -2
  22. package/dist/{index-76dbn6pe.js → index-n9kwenpt.js} +1 -1
  23. package/dist/{index-n386evxj.js → index-p96kb6t2.js} +1 -1
  24. package/dist/{index-tf4wzjew.js → index-pz2b2x0y.js} +1 -1
  25. package/dist/{index-jk1sgx36.js → index-qdb8f8va.js} +1 -1
  26. package/dist/{index-a3j61wz9.js → index-xzvcw9ga.js} +201 -131
  27. package/dist/{index-qbssx940.js → index-zy7an84p.js} +223 -8
  28. package/dist/index.js +21 -15
  29. package/dist/percolate.js +2 -2
  30. package/dist/portfolio.js +10 -10
  31. package/dist/publish-reader/reader.js +48 -12
  32. package/dist/publish-search.js +1 -1
  33. package/dist/publish.js +4 -4
  34. package/dist/sdk.js +9 -9
  35. package/dist/search.js +2 -2
  36. package/dist/semantic.js +4 -4
  37. package/dist/{support-vm8fw4yc.js → support-jf9v10j7.js} +15 -15
  38. package/dist/workflows/decision-context.js +10 -10
  39. package/dist/workflows/index.js +10 -10
  40. package/package.json +5 -4
  41. package/skills/wordcell/SKILL.md +1 -1
  42. package/skills/wordcell/references/plan-structure.md +1 -1
  43. package/skills/wordcell/references/url-platforms.md +1 -1
  44. package/src/cli-program.ts +4 -2
  45. package/src/graph.ts +79 -9
  46. package/src/mention-index.ts +194 -0
  47. package/src/publish-index.ts +3 -2
  48. package/src/publish-markdown.ts +55 -0
  49. package/src/publish-model.ts +2 -2
  50. package/src/publish-reader/reader.ts +3 -1
  51. package/src/publish-search.ts +44 -13
  52. package/src/publish.ts +4 -1
  53. package/src/vault.ts +26 -2
@@ -7,7 +7,7 @@ import {
7
7
  } from "./index-48pz4jpc.js";
8
8
  import {
9
9
  lookupNote
10
- } from "./index-qbssx940.js";
10
+ } from "./index-zy7an84p.js";
11
11
 
12
12
  // src/search.ts
13
13
  var MAX_EXACT_RESULTS = 500;
@@ -3,10 +3,10 @@ import {
3
3
  GRAPH_LIMITS,
4
4
  GraphAuthorityError,
5
5
  validateGraphQueryRequest
6
- } from "./index-tf4wzjew.js";
6
+ } from "./index-pz2b2x0y.js";
7
7
  import {
8
8
  scanVault
9
- } from "./index-233z9wmn.js";
9
+ } from "./index-8v6k9h4r.js";
10
10
  import {
11
11
  analyzeAuthoredRepositoryScopes
12
12
  } from "./index-06c9ctr6.js";
@@ -19,7 +19,7 @@ import {
19
19
  documentIdState,
20
20
  isCanonicalNoteId,
21
21
  parseNote
22
- } from "./index-qbssx940.js";
22
+ } from "./index-zy7an84p.js";
23
23
  import {
24
24
  __require
25
25
  } from "./index-z1w83f81.js";
@@ -231,7 +231,7 @@ import { lstat, open } from "fs/promises";
231
231
  var graphCacheFileSystem = { lstat, open };
232
232
 
233
233
  // src/graph-authority.ts
234
- var openOhGraphAdapter = async (...args) => await (await import("./authority-06eqhqam.js")).openOhGraphAdapter(...args);
234
+ var openOhGraphAdapter = async (...args) => await (await import("./authority-3ga47syb.js")).openOhGraphAdapter(...args);
235
235
  var MAX_CACHE_BYTES = 67108864;
236
236
  var ignoredCache = `# Disposable Wordcell graph state. Rebuild from Markdown.
237
237
  *
@@ -7,7 +7,7 @@ import {
7
7
  isCanonicalRelationPredicate,
8
8
  parseDocumentId,
9
9
  parseQualifiedDocumentUri
10
- } from "./index-qbssx940.js";
10
+ } from "./index-zy7an84p.js";
11
11
 
12
12
  // src/authoring-model.ts
13
13
  import { createHash } from "crypto";
@@ -1,20 +1,20 @@
1
1
  // @bun
2
2
  import {
3
3
  percolateVault
4
- } from "./index-jk1sgx36.js";
4
+ } from "./index-qdb8f8va.js";
5
5
  import {
6
6
  createGraphSnapshot,
7
7
  openGraphAuthority
8
- } from "./index-xv80vzfp.js";
8
+ } from "./index-f75zmmdr.js";
9
9
  import {
10
10
  GraphAuthorityError,
11
11
  validateGraphPercolationOptions
12
- } from "./index-tf4wzjew.js";
12
+ } from "./index-pz2b2x0y.js";
13
13
  import {
14
14
  analyzeVault,
15
15
  lookupNote,
16
16
  parseNote
17
- } from "./index-qbssx940.js";
17
+ } from "./index-zy7an84p.js";
18
18
 
19
19
  // src/graph-percolation.ts
20
20
  async function percolateWithGraph(snapshot, options) {
@@ -5,7 +5,7 @@ import {
5
5
  MAX_SEARCH_RESULTS,
6
6
  openKnowledgeBase,
7
7
  validateKnowledgeBaseSearchHistory
8
- } from "./index-q7tbg07z.js";
8
+ } from "./index-42tb8qqp.js";
9
9
  import {
10
10
  expandSearchRequest,
11
11
  parseSearchRules
@@ -15,10 +15,10 @@ import {
15
15
  } from "./index-1gwbassd.js";
16
16
  import {
17
17
  validateSearchQuery
18
- } from "./index-vnybgywh.js";
18
+ } from "./index-aer0jdrq.js";
19
19
  import {
20
20
  scanVault
21
- } from "./index-233z9wmn.js";
21
+ } from "./index-8v6k9h4r.js";
22
22
  import {
23
23
  validateQueryOptions
24
24
  } from "./index-48pz4jpc.js";
@@ -32,7 +32,7 @@ import {
32
32
  parseVaultKey,
33
33
  portfolioDocumentIdentity,
34
34
  portfolioVaultIdentity
35
- } from "./index-qbssx940.js";
35
+ } from "./index-zy7an84p.js";
36
36
 
37
37
  // src/portfolio.ts
38
38
  import { createHash as createHash2 } from "crypto";
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  fuseRankedCandidates,
4
4
  validateSearchQuery
5
- } from "./index-vnybgywh.js";
5
+ } from "./index-aer0jdrq.js";
6
6
  import {
7
7
  MAX_NOTE_UTF8_BYTES,
8
8
  MAX_SCANNED_NOTES,
9
9
  MAX_VAULT_UTF8_BYTES,
10
10
  VaultScanBudgetError,
11
11
  scanVault
12
- } from "./index-233z9wmn.js";
12
+ } from "./index-8v6k9h4r.js";
13
13
 
14
14
  // src/semantic.ts
15
15
  import { createHash as createHash2 } from "crypto";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./index-h170byqw.js";
5
5
  import {
6
6
  packUntrustedSearchContext
7
- } from "./index-q7tbg07z.js";
7
+ } from "./index-42tb8qqp.js";
8
8
 
9
9
  // src/workflows/decision-context.ts
10
10
  var decisionContextWorkflow = defineWorkflow({
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  fuseRankedCandidates
4
- } from "./index-vnybgywh.js";
4
+ } from "./index-aer0jdrq.js";
5
5
 
6
6
  // src/benchmark.ts
7
7
  var MAX_BENCHMARK_CASES = 500;
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  isCanonicalNoteId,
7
7
  isCanonicalRelationPredicate
8
- } from "./index-qbssx940.js";
8
+ } from "./index-zy7an84p.js";
9
9
 
10
10
  // src/graph-authority-model.ts
11
11
  var GRAPH_LIMITS = Object.freeze({
@@ -5,7 +5,7 @@ import {
5
5
  isCanonicalNoteId,
6
6
  isCanonicalRelationPredicate,
7
7
  lookupNote
8
- } from "./index-qbssx940.js";
8
+ } from "./index-zy7an84p.js";
9
9
 
10
10
  // src/percolate.ts
11
11
  import { createHash } from "crypto";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  scanVault
4
- } from "./index-233z9wmn.js";
4
+ } from "./index-8v6k9h4r.js";
5
5
  import {
6
6
  navigateLinks
7
7
  } from "./index-d13v9ckt.js";
@@ -31,7 +31,7 @@ import {
31
31
  import {
32
32
  publishNormalize,
33
33
  publishShardName
34
- } from "./index-3agn8scn.js";
34
+ } from "./index-23m6bbjt.js";
35
35
  import {
36
36
  parseLocalAttachmentReferences,
37
37
  validateMarkdownAttachments
@@ -39,7 +39,7 @@ import {
39
39
  import {
40
40
  lookupNote,
41
41
  normalizeVaultPath
42
- } from "./index-qbssx940.js";
42
+ } from "./index-zy7an84p.js";
43
43
 
44
44
  // src/publish.ts
45
45
  import { createHash } from "crypto";
@@ -49,133 +49,6 @@ import { canonicalJson as canonicalJson2, canonicalSha256 } from "@hraness/oh";
49
49
 
50
50
  // src/publish-index.ts
51
51
  import { canonicalJson } from "@hraness/oh";
52
- var TERM_PATTERN = /[\p{L}\p{N}][\p{L}\p{N}._/-]*/gu;
53
- function bounded(value, maximumBytes) {
54
- if (Buffer.byteLength(value, "utf8") <= maximumBytes)
55
- return { text: value, truncated: false };
56
- const bytes = Buffer.from(value, "utf8");
57
- let end = maximumBytes;
58
- while (end > 0 && ((bytes[end] ?? 0) & 192) === 128)
59
- end -= 1;
60
- return { text: bytes.subarray(0, end).toString("utf8"), truncated: true };
61
- }
62
- function previewText(note) {
63
- const basis = note.summary !== "" ? note.summary : note.searchableText;
64
- const collapsed = basis.replace(/\s+/gu, " ").trim();
65
- return bounded(collapsed, WORDCELL_SITE_LIMITS_V1.docPreviewBytes).text;
66
- }
67
- function indexableTerms(text) {
68
- const terms = new Set;
69
- for (const match of text.matchAll(TERM_PATTERN))
70
- terms.add(match[0]);
71
- return [...terms];
72
- }
73
- function buildSiteIndex(notes, slugById, options = {}) {
74
- const indexContent = options.indexContent !== false;
75
- const fields = [];
76
- const inlineTexts = [];
77
- let textTruncated = false;
78
- let inlineTotal = 0;
79
- for (const note of notes) {
80
- const title = bounded(publishNormalize(note.title), WORDCELL_SITE_LIMITS_V1.fieldTextBytes);
81
- const aliases = bounded(note.aliases.map(publishNormalize).join(`
82
- `), WORDCELL_SITE_LIMITS_V1.fieldTextBytes);
83
- const path = bounded(`${publishNormalize(note.path)}
84
- ${publishNormalize(note.id)}`, WORDCELL_SITE_LIMITS_V1.fieldTextBytes);
85
- const tags = bounded(note.tags.map(publishNormalize).join(`
86
- `), WORDCELL_SITE_LIMITS_V1.fieldTextBytes);
87
- const metadata = bounded(publishNormalize(canonicalJson(note.metadata)), WORDCELL_SITE_LIMITS_V1.fieldTextBytes);
88
- textTruncated ||= title.truncated || aliases.truncated || path.truncated || tags.truncated || metadata.truncated;
89
- fields.push({ t: title.text, a: aliases.text, p: path.text, g: tags.text, m: metadata.text });
90
- if (indexContent) {
91
- const inline = bounded(publishNormalize(note.searchableText), WORDCELL_SITE_LIMITS_V1.inlineTextBytes);
92
- textTruncated ||= inline.truncated;
93
- inlineTexts.push(inline.text);
94
- inlineTotal += Buffer.byteLength(inline.text, "utf8");
95
- }
96
- }
97
- const mode = !indexContent ? "none" : inlineTotal <= WORDCELL_SITE_LIMITS_V1.inlineTotalBytes ? "inline" : "shards";
98
- const allTerms = new Set;
99
- const contentPostings = new Map;
100
- const docs = [];
101
- for (const [index, note] of notes.entries()) {
102
- const slug = slugById.get(note.id);
103
- if (slug === undefined)
104
- throw new Error(`Missing published slug for ${note.id}.`);
105
- const field = fields[index];
106
- if (field === undefined)
107
- throw new Error(`Missing indexed fields for ${note.id}.`);
108
- const inline = mode === "inline" ? inlineTexts[index] : undefined;
109
- const fieldTerms = indexableTerms(`${field.t}
110
- ${field.a}
111
- ${field.p}
112
- ${field.g}
113
- ${field.m}`);
114
- for (const term of fieldTerms)
115
- allTerms.add(term);
116
- if (mode !== "none") {
117
- const content = inlineTexts[index] ?? "";
118
- for (const term of indexableTerms(content)) {
119
- allTerms.add(term);
120
- if (mode === "shards") {
121
- const list = contentPostings.get(term) ?? [];
122
- list.push(index);
123
- contentPostings.set(term, list);
124
- }
125
- }
126
- }
127
- docs.push({
128
- i: index,
129
- s: slug,
130
- t: note.title,
131
- p: previewText(note),
132
- f: field,
133
- ...inline === undefined ? {} : { x: inline }
134
- });
135
- }
136
- let termsTruncated = false;
137
- let sortedTerms = [...allTerms].toSorted((left, right) => left.localeCompare(right));
138
- if (sortedTerms.length > WORDCELL_SITE_LIMITS_V1.indexTerms) {
139
- sortedTerms = sortedTerms.slice(0, WORDCELL_SITE_LIMITS_V1.indexTerms);
140
- termsTruncated = true;
141
- }
142
- const admitted = new Set(sortedTerms);
143
- const postings = new Map;
144
- if (mode === "shards") {
145
- const grouped = new Map;
146
- for (const [term, docIds] of [...contentPostings.entries()].toSorted(([a], [b]) => a.localeCompare(b))) {
147
- if (!admitted.has(term))
148
- continue;
149
- const shard = publishShardName(term);
150
- const bucket = grouped.get(shard) ?? Object.create(null);
151
- bucket[term] = docIds;
152
- grouped.set(shard, bucket);
153
- }
154
- for (const [shard, bucket] of [...grouped.entries()].toSorted(([a], [b]) => a.localeCompare(b))) {
155
- postings.set(shard, {
156
- format: WORDCELL_SITE_POSTINGS_FORMAT_V1,
157
- shard,
158
- postings: Object.freeze(bucket)
159
- });
160
- }
161
- }
162
- return {
163
- docs: {
164
- format: WORDCELL_SITE_DOCS_FORMAT_V1,
165
- content: mode,
166
- docs
167
- },
168
- terms: {
169
- format: WORDCELL_SITE_TERMS_FORMAT_V1,
170
- terms: sortedTerms
171
- },
172
- postings,
173
- termsCount: sortedTerms.length,
174
- termsTruncated,
175
- textTruncated,
176
- mode
177
- };
178
- }
179
52
 
180
53
  // src/publish-markdown.ts
181
54
  var VOID_SLUG = /[^\p{L}\p{N}._~-]+/gu;
@@ -257,6 +130,8 @@ function renderFootnoteReference(raw, label, footnotes) {
257
130
  const id = `wordcell:footnote-ref:${number}:${note.references.length + 1}`;
258
131
  note.references.push(id);
259
132
  footnotes.references += 1;
133
+ if (footnotes.plain)
134
+ return "";
260
135
  return `<sup><a id="${id}" href="#wordcell:footnote:${number}" role="doc-noteref" aria-label="Footnote ${number}">${number}</a></sup>`;
261
136
  }
262
137
  function renderInline(text, ctx, footnotes) {
@@ -904,6 +779,72 @@ function renderMarkdownToHtml(content, ctx) {
904
779
  ${notes}
905
780
  </ol></section>`;
906
781
  }
782
+ function projectMarkdownText(content, description) {
783
+ const footnotes = { byLabel: new Map, numbered: [], definitions: 0, references: 0, disabled: false, plain: true };
784
+ const blocks = parseMarkdownBlocks(content, footnotes, true);
785
+ const context = {
786
+ source: "",
787
+ resolveNote: () => {
788
+ return;
789
+ },
790
+ resolveAsset: () => {
791
+ return;
792
+ },
793
+ noteHref: () => ""
794
+ };
795
+ const inline = (text2, state) => stripMarkup(renderInline(text2, context, state));
796
+ const parts = (items, state) => items.map((block) => {
797
+ switch (block.type) {
798
+ case "paragraph":
799
+ case "heading":
800
+ return inline(block.text, state);
801
+ case "literal":
802
+ case "code":
803
+ return block.text;
804
+ case "break":
805
+ return "";
806
+ case "quote":
807
+ return parts(block.blocks, state).join(`
808
+
809
+ `);
810
+ case "table":
811
+ return [block.header, ...block.rows].map((row) => row.map((cell) => inline(cell, state)).join(" ")).join(`
812
+ `);
813
+ case "list":
814
+ return block.parts.map((part) => part.type === "item" || part.type === "continuation" ? inline(part.text, state) : "").filter(Boolean).join(`
815
+ `);
816
+ case "footnote":
817
+ return state.disabled || block.note.invalid ? block.note.authored : "";
818
+ }
819
+ });
820
+ const rendered = parts(blocks, footnotes);
821
+ if (!footnotes.disabled)
822
+ for (const note of footnotes.byLabel.values()) {
823
+ if (note !== null && !note.invalid)
824
+ footnoteNumber(note, footnotes);
825
+ }
826
+ const text = [...rendered, ...footnotes.numbered.map((note) => inline(note.body.replaceAll(`
827
+ `, " ")))].filter(Boolean).join(`
828
+
829
+ `);
830
+ let preview = rendered.find((value, index) => blocks[index]?.type === "paragraph" && value.trim() !== "") ?? text;
831
+ if (description !== undefined && description.trim() !== "") {
832
+ const state = {
833
+ byLabel: new Map([...footnotes.byLabel].map(([label, note]) => [label, note === null ? null : { body: note.body, authored: note.authored, invalid: note.invalid, references: [] }])),
834
+ numbered: [],
835
+ definitions: footnotes.definitions,
836
+ references: 0,
837
+ disabled: footnotes.disabled,
838
+ plain: true
839
+ };
840
+ const authored = parts(parseMarkdownBlocks(description, state, false), state).filter(Boolean).join(`
841
+
842
+ `);
843
+ if (authored.trim() !== "")
844
+ preview = authored;
845
+ }
846
+ return { text, preview };
847
+ }
907
848
  function stripMarkup(html) {
908
849
  let stripped = "";
909
850
  let inTag = false;
@@ -918,6 +859,135 @@ function stripMarkup(html) {
918
859
  return stripped.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&quot;", '"').replaceAll("&#39;", "'").replaceAll("&amp;", "&");
919
860
  }
920
861
 
862
+ // src/publish-index.ts
863
+ var TERM_PATTERN = /[\p{L}\p{N}][\p{L}\p{N}._/-]*/gu;
864
+ function bounded(value, maximumBytes) {
865
+ if (Buffer.byteLength(value, "utf8") <= maximumBytes)
866
+ return { text: value, truncated: false };
867
+ const bytes = Buffer.from(value, "utf8");
868
+ let end = maximumBytes;
869
+ while (end > 0 && ((bytes[end] ?? 0) & 192) === 128)
870
+ end -= 1;
871
+ return { text: bytes.subarray(0, end).toString("utf8"), truncated: true };
872
+ }
873
+ function previewText(note) {
874
+ const display = projectMarkdownText(note.content, note.properties["description"]);
875
+ const collapsed = display.preview.replace(/\s+/gu, " ").trim();
876
+ return bounded(collapsed, WORDCELL_SITE_LIMITS_V1.docPreviewBytes).text;
877
+ }
878
+ function indexableTerms(text) {
879
+ const terms = new Set;
880
+ for (const match of text.matchAll(TERM_PATTERN))
881
+ terms.add(match[0]);
882
+ return [...terms];
883
+ }
884
+ function buildSiteIndex(notes, slugById, options = {}) {
885
+ const indexContent = options.indexContent !== false;
886
+ const fields = [];
887
+ const inlineTexts = [];
888
+ let textTruncated = false;
889
+ let inlineTotal = 0;
890
+ for (const note of notes) {
891
+ const title = bounded(publishNormalize(note.title), WORDCELL_SITE_LIMITS_V1.fieldTextBytes);
892
+ const aliases = bounded(note.aliases.map(publishNormalize).join(`
893
+ `), WORDCELL_SITE_LIMITS_V1.fieldTextBytes);
894
+ const path = bounded(`${publishNormalize(note.path)}
895
+ ${publishNormalize(note.id)}`, WORDCELL_SITE_LIMITS_V1.fieldTextBytes);
896
+ const tags = bounded(note.tags.map(publishNormalize).join(`
897
+ `), WORDCELL_SITE_LIMITS_V1.fieldTextBytes);
898
+ const metadata = bounded(publishNormalize(canonicalJson(note.metadata)), WORDCELL_SITE_LIMITS_V1.fieldTextBytes);
899
+ textTruncated ||= title.truncated || aliases.truncated || path.truncated || tags.truncated || metadata.truncated;
900
+ fields.push({ t: title.text, a: aliases.text, p: path.text, g: tags.text, m: metadata.text });
901
+ if (indexContent) {
902
+ const inline = bounded(publishNormalize(note.searchableText), WORDCELL_SITE_LIMITS_V1.inlineTextBytes);
903
+ textTruncated ||= inline.truncated;
904
+ inlineTexts.push(inline.text);
905
+ inlineTotal += Buffer.byteLength(inline.text, "utf8");
906
+ }
907
+ }
908
+ const mode = !indexContent ? "none" : inlineTotal <= WORDCELL_SITE_LIMITS_V1.inlineTotalBytes ? "inline" : "shards";
909
+ const allTerms = new Set;
910
+ const contentPostings = new Map;
911
+ const docs = [];
912
+ for (const [index, note] of notes.entries()) {
913
+ const slug = slugById.get(note.id);
914
+ if (slug === undefined)
915
+ throw new Error(`Missing published slug for ${note.id}.`);
916
+ const field = fields[index];
917
+ if (field === undefined)
918
+ throw new Error(`Missing indexed fields for ${note.id}.`);
919
+ const inline = mode === "inline" ? inlineTexts[index] : undefined;
920
+ const fieldTerms = indexableTerms(`${field.t}
921
+ ${field.a}
922
+ ${field.p}
923
+ ${field.g}
924
+ ${field.m}`);
925
+ for (const term of fieldTerms)
926
+ allTerms.add(term);
927
+ if (mode !== "none") {
928
+ const content = inlineTexts[index] ?? "";
929
+ for (const term of indexableTerms(content)) {
930
+ allTerms.add(term);
931
+ if (mode === "shards") {
932
+ const list = contentPostings.get(term) ?? [];
933
+ list.push(index);
934
+ contentPostings.set(term, list);
935
+ }
936
+ }
937
+ }
938
+ docs.push({
939
+ i: index,
940
+ s: slug,
941
+ t: note.title,
942
+ p: previewText(note),
943
+ f: field,
944
+ ...inline === undefined ? {} : { x: inline }
945
+ });
946
+ }
947
+ let termsTruncated = false;
948
+ let sortedTerms = [...allTerms].toSorted((left, right) => left.localeCompare(right));
949
+ if (sortedTerms.length > WORDCELL_SITE_LIMITS_V1.indexTerms) {
950
+ sortedTerms = sortedTerms.slice(0, WORDCELL_SITE_LIMITS_V1.indexTerms);
951
+ termsTruncated = true;
952
+ }
953
+ const admitted = new Set(sortedTerms);
954
+ const postings = new Map;
955
+ if (mode === "shards") {
956
+ const grouped = new Map;
957
+ for (const [term, docIds] of [...contentPostings.entries()].toSorted(([a], [b]) => a.localeCompare(b))) {
958
+ if (!admitted.has(term))
959
+ continue;
960
+ const shard = publishShardName(term);
961
+ const bucket = grouped.get(shard) ?? Object.create(null);
962
+ bucket[term] = docIds;
963
+ grouped.set(shard, bucket);
964
+ }
965
+ for (const [shard, bucket] of [...grouped.entries()].toSorted(([a], [b]) => a.localeCompare(b))) {
966
+ postings.set(shard, {
967
+ format: WORDCELL_SITE_POSTINGS_FORMAT_V1,
968
+ shard,
969
+ postings: Object.freeze(bucket)
970
+ });
971
+ }
972
+ }
973
+ return {
974
+ docs: {
975
+ format: WORDCELL_SITE_DOCS_FORMAT_V1,
976
+ content: mode,
977
+ docs
978
+ },
979
+ terms: {
980
+ format: WORDCELL_SITE_TERMS_FORMAT_V1,
981
+ terms: sortedTerms
982
+ },
983
+ postings,
984
+ termsCount: sortedTerms.length,
985
+ termsTruncated,
986
+ textTruncated,
987
+ mode
988
+ };
989
+ }
990
+
921
991
  // src/publish-nav.ts
922
992
  var SITE_NAV_GROUP_LIMIT = 96;
923
993
  var SITE_NAV_NODE_BUDGET = 768;
@@ -1709,7 +1779,7 @@ async function projectVault(snapshot, options, io) {
1709
1779
  let anyTextTruncated = false;
1710
1780
  for (const note of selection.notes) {
1711
1781
  const slug = slugFor(note.id);
1712
- const text = boundedNormalized(note.searchableText, WORDCELL_SITE_LIMITS_V1.noteTextBytes);
1782
+ const text = boundedNormalized(projectMarkdownText(note.content).text, WORDCELL_SITE_LIMITS_V1.noteTextBytes);
1713
1783
  anyTextTruncated ||= text.truncated;
1714
1784
  const payload = {
1715
1785
  format: WORDCELL_SITE_NOTE_FORMAT_V1,