@hraness/wordcell 0.22.2 → 0.22.4

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.js CHANGED
@@ -167,7 +167,7 @@ import {
167
167
  publishVault,
168
168
  renderPublishReportText,
169
169
  serializeSiteFile
170
- } from "./index-hmw17zaa.js";
170
+ } from "./index-pnt9wr59.js";
171
171
  import {
172
172
  MAX_NOTE_UTF8_BYTES,
173
173
  MAX_SCANNED_NOTES,
@@ -245,7 +245,7 @@ import {
245
245
  parseSitePostingsV1,
246
246
  parseSiteTermsV1
247
247
  } from "./index-66pshdtx.js";
248
- import"./index-3agn8scn.js";
248
+ import"./index-23m6bbjt.js";
249
249
  import {
250
250
  auditAgentGuideRepository,
251
251
  auditAgentGuideSource,
@@ -757,22 +757,58 @@ function comparePublishScores(left, right) {
757
757
  return Number(right.identity) - Number(left.identity) || right.score - left.score || left.i - right.i;
758
758
  }
759
759
  function publishSnippet(text, query, fallback, windowBytes = 160) {
760
- const normalized = publishNormalize(text);
761
- let offset = query.normalized === "" ? -1 : normalized.indexOf(query.normalized);
762
- if (offset < 0) {
760
+ if (!Number.isSafeInteger(windowBytes) || windowBytes < 0)
761
+ throw new RangeError("Snippet window must be a nonnegative safe byte count.");
762
+ const display = text.normalize("NFC");
763
+ const normalized = publishNormalize(display);
764
+ let match = query.normalized === "" ? -1 : normalized.indexOf(query.normalized);
765
+ if (match < 0) {
763
766
  for (const term of query.terms) {
764
- offset = normalized.indexOf(term);
765
- if (offset >= 0)
767
+ match = normalized.indexOf(term);
768
+ if (match >= 0)
766
769
  break;
767
770
  }
768
771
  }
769
- if (offset < 0)
772
+ if (match < 0)
770
773
  return fallback;
771
- const half = Math.floor(windowBytes / 2);
772
- const start = Math.max(0, offset - half);
773
- const end = Math.min(text.length, offset + half);
774
- const snippet = text.slice(start, end).replace(/\s+/gu, " ").trim();
775
- return `${start > 0 ? "…" : ""}${snippet}${end < text.length ? "…" : ""}`;
774
+ let offset = 0, normalizedOffset = 0;
775
+ for (const character of display) {
776
+ const width = character.toLocaleLowerCase("en-US").length;
777
+ if (normalizedOffset + width > match)
778
+ break;
779
+ normalizedOffset += width;
780
+ offset += character.length;
781
+ }
782
+ const edge = windowBytes >= 6 ? "…" : "";
783
+ const budget = windowBytes - 2 * publishUtf8Bytes(edge);
784
+ const previous = (end2) => {
785
+ const last = display.charCodeAt(end2 - 1);
786
+ return end2 > 1 && last >= 56320 && last <= 57343 && display.charCodeAt(end2 - 2) >= 55296 && display.charCodeAt(end2 - 2) <= 56319 ? end2 - 2 : end2 - 1;
787
+ };
788
+ let start = offset, end = offset, used = 0;
789
+ while (start > 0) {
790
+ const before = previous(start), bytes = publishUtf8Bytes(display.slice(before, start));
791
+ if (used + bytes > Math.floor(budget / 2))
792
+ break;
793
+ start = before;
794
+ used += bytes;
795
+ }
796
+ while (end < display.length) {
797
+ const character = String.fromCodePoint(display.codePointAt(end) ?? 0), bytes = publishUtf8Bytes(character);
798
+ if (used + bytes > budget)
799
+ break;
800
+ end += character.length;
801
+ used += bytes;
802
+ }
803
+ while (start > 0) {
804
+ const before = previous(start), bytes = publishUtf8Bytes(display.slice(before, start));
805
+ if (used + bytes > budget)
806
+ break;
807
+ start = before;
808
+ used += bytes;
809
+ }
810
+ const snippet = display.slice(start, end).replace(/\s+/gu, " ").trim();
811
+ return `${start > 0 ? edge : ""}${snippet}${end < display.length ? edge : ""}`;
776
812
  }
777
813
 
778
814
  // src/publish-theme.ts
@@ -924,7 +960,7 @@ function resultHref(base, slug) {
924
960
  }
925
961
  function snippetFor(index, doc, query) {
926
962
  const hydrated = index.notes.get(doc.s);
927
- const text = hydrated?.text ?? doc.x;
963
+ const text = hydrated?.text;
928
964
  return text === undefined ? doc.p : publishSnippet(text, query, doc.p);
929
965
  }
930
966
  function appendMarked(parent, text, terms) {
@@ -23,7 +23,7 @@ import {
23
23
  publishSnippet,
24
24
  publishUtf8Bytes,
25
25
  scorePublishDocument
26
- } from "./index-3agn8scn.js";
26
+ } from "./index-23m6bbjt.js";
27
27
  import"./index-z1w83f81.js";
28
28
  export {
29
29
  scorePublishDocument,
package/dist/publish.js CHANGED
@@ -10,14 +10,14 @@ import {
10
10
  publishVault,
11
11
  renderPublishReportText,
12
12
  serializeSiteFile
13
- } from "./index-hmw17zaa.js";
13
+ } from "./index-pnt9wr59.js";
14
14
  import"./index-233z9wmn.js";
15
15
  import"./index-d13v9ckt.js";
16
16
  import"./index-48pz4jpc.js";
17
17
  import"./index-06c9ctr6.js";
18
18
  import"./index-4knsp9qj.js";
19
19
  import"./index-66pshdtx.js";
20
- import"./index-3agn8scn.js";
20
+ import"./index-23m6bbjt.js";
21
21
  import"./index-5vwpzb5a.js";
22
22
  import"./index-x3fthpsc.js";
23
23
  import"./index-qbssx940.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  parseArguments as parseArguments2,
4
4
  parseUrlMetadataArguments
5
- } from "./index-bw2r37z9.js";
5
+ } from "./index-9h7zh0wt.js";
6
6
  import"./index-bcknqxrq.js";
7
7
  import {
8
8
  parsePdfArguments
@@ -42,14 +42,14 @@ import"./index-tf4wzjew.js";
42
42
  import"./index-1gwbassd.js";
43
43
  import"./index-vnybgywh.js";
44
44
  import"./index-1xxnjn0d.js";
45
- import"./index-hmw17zaa.js";
45
+ import"./index-pnt9wr59.js";
46
46
  import"./index-233z9wmn.js";
47
47
  import"./index-d13v9ckt.js";
48
48
  import"./index-48pz4jpc.js";
49
49
  import"./index-06c9ctr6.js";
50
50
  import"./index-4knsp9qj.js";
51
51
  import"./index-66pshdtx.js";
52
- import"./index-3agn8scn.js";
52
+ import"./index-23m6bbjt.js";
53
53
  import"./index-hya40gb2.js";
54
54
  import"./index-5vwpzb5a.js";
55
55
  import"./index-x3fthpsc.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hraness/wordcell",
3
- "version": "0.22.2",
3
+ "version": "0.22.4",
4
4
  "description": "A local Markdown knowledge base with superpowers. Save decisions, sources, and plans as files you own, then recover them through exact and semantic search, typed relationships, backlinks, and Git history.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -479,8 +479,8 @@
479
479
  "check": "bun run check:worker && bun run check:effect && bun run check:workflows && bun run check:portfolio-inventory && bun run check:installed-command-docs && bun run typecheck && bun run build && bun run test:package && bun run test && bun run url-metadata:tool:check",
480
480
  "prepack": "bun run check",
481
481
  "check:effect": "bun run scripts/check-effect-policy.ts",
482
- "kb:search": "bunx --bun --package https://github.com/hraness/wordcell/releases/download/v0.22.1/hraness-wordcell-0.22.1.tgz wordcell search --root kb --mode exact --rerank typesafe --rerank-limit 25",
483
- "kb:search:local": "bunx --bun --package https://github.com/hraness/wordcell/releases/download/v0.22.1/hraness-wordcell-0.22.1.tgz wordcell search --root kb --mode exact",
482
+ "kb:search": "bunx --bun --package https://github.com/hraness/wordcell/releases/download/v0.22.3/hraness-wordcell-0.22.3.tgz wordcell search --root kb --mode exact --rerank typesafe --rerank-limit 25",
483
+ "kb:search:local": "bunx --bun --package https://github.com/hraness/wordcell/releases/download/v0.22.3/hraness-wordcell-0.22.3.tgz wordcell search --root kb --mode exact",
484
484
  "check:worker": "tsc -p worker/tsconfig.json --noEmit"
485
485
  },
486
486
  "dependencies": {
@@ -56,7 +56,7 @@ missing:
56
56
  ```sh
57
57
  command -v wordcell >/dev/null 2>&1 || {
58
58
  command -v bun >/dev/null 2>&1 || exit 1
59
- bun add --global --ignore-scripts https://github.com/hraness/wordcell/releases/download/v0.22.2/hraness-wordcell-0.22.2.tgz
59
+ bun add --global --ignore-scripts https://github.com/hraness/wordcell/releases/download/v0.22.4/hraness-wordcell-0.22.4.tgz
60
60
  }
61
61
  wordcell --help
62
62
  ```
@@ -1,6 +1,7 @@
1
1
  import { canonicalJson } from "@hraness/oh";
2
2
 
3
3
  import type { Note } from "./graph.js";
4
+ import { projectMarkdownText } from "./publish-markdown.js";
4
5
  import {
5
6
  WORDCELL_SITE_DOCS_FORMAT_V1,
6
7
  WORDCELL_SITE_LIMITS_V1,
@@ -38,8 +39,8 @@ function bounded(value: string, maximumBytes: number): { text: string; truncated
38
39
  }
39
40
 
40
41
  function previewText(note: Note): string {
41
- const basis = note.summary !== "" ? note.summary : note.searchableText;
42
- const collapsed = basis.replace(/\s+/gu, " ").trim();
42
+ const display = projectMarkdownText(note.content, note.properties["description"]);
43
+ const collapsed = display.preview.replace(/\s+/gu, " ").trim();
43
44
  return bounded(collapsed, WORDCELL_SITE_LIMITS_V1.docPreviewBytes).text;
44
45
  }
45
46