sagedesk 2.0.0 → 2.1.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.
@@ -94,17 +94,33 @@ function dotProduct(a, b) {
94
94
  for (let i = 0; i < a.length; i++) dot += a[i] * b[i];
95
95
  return dot;
96
96
  }
97
+ function insertSorted(arr, item, maxLen) {
98
+ arr.push(item);
99
+ let i = arr.length - 1;
100
+ while (i > 0 && arr[i - 1].score < arr[i].score) {
101
+ const tmp = arr[i - 1];
102
+ arr[i - 1] = arr[i];
103
+ arr[i] = tmp;
104
+ i--;
105
+ }
106
+ if (arr.length > maxLen) arr.pop();
107
+ }
97
108
  function search(queryVector, index, topK = 3, minScore = 0.42) {
98
109
  const results = [];
99
110
  for (const chunk of index) {
100
111
  const score = dotProduct(queryVector, chunk.vector384);
101
112
  if (score < minScore) continue;
102
113
  if (results.length < topK) {
103
- results.push({ chunk, score });
104
- results.sort((a, b) => b.score - a.score);
114
+ insertSorted(results, { chunk, score }, topK);
105
115
  } else if (score > results[topK - 1].score) {
106
116
  results[topK - 1] = { chunk, score };
107
- results.sort((a, b) => b.score - a.score);
117
+ let i = topK - 1;
118
+ while (i > 0 && results[i - 1].score < results[i].score) {
119
+ const tmp = results[i - 1];
120
+ results[i - 1] = results[i];
121
+ results[i] = tmp;
122
+ i--;
123
+ }
108
124
  }
109
125
  }
110
126
  return results;
@@ -115,15 +131,23 @@ function keywordSearch(query, index, topK = 3) {
115
131
  const results = [];
116
132
  for (const chunk of index) {
117
133
  const chunkLower = chunk.textLower || chunk.text.toLowerCase();
118
- const matchCount = terms.filter((t) => chunkLower.includes(t)).length;
134
+ let matchCount = 0;
135
+ for (const t of terms) {
136
+ if (chunkLower.includes(t)) matchCount++;
137
+ }
119
138
  const score = matchCount / terms.length;
120
139
  if (score <= 0) continue;
121
140
  if (results.length < topK) {
122
- results.push({ chunk, score });
123
- results.sort((a, b) => b.score - a.score);
141
+ insertSorted(results, { chunk, score }, topK);
124
142
  } else if (score > results[topK - 1].score) {
125
143
  results[topK - 1] = { chunk, score };
126
- results.sort((a, b) => b.score - a.score);
144
+ let i = topK - 1;
145
+ while (i > 0 && results[i - 1].score < results[i].score) {
146
+ const tmp = results[i - 1];
147
+ results[i - 1] = results[i];
148
+ results[i] = tmp;
149
+ i--;
150
+ }
127
151
  }
128
152
  }
129
153
  return results;
@@ -479,13 +503,10 @@ var PURIFY_CONFIG = {
479
503
  ALLOWED_ATTR: ["href", "title", "target", "rel"],
480
504
  ALLOW_DATA_ATTR: false
481
505
  };
482
- var HOOK_ALLOWLIST = ["a"];
483
506
  DOMPurify.addHook("afterSanitizeAttributes", (node) => {
484
- if (HOOK_ALLOWLIST.includes(node.tagName.toLowerCase())) {
485
- if (node.tagName.toLowerCase() === "a") {
486
- node.setAttribute("target", "_blank");
487
- node.setAttribute("rel", "noopener noreferrer");
488
- }
507
+ if (node.tagName.toLowerCase() === "a") {
508
+ node.setAttribute("target", "_blank");
509
+ node.setAttribute("rel", "noopener noreferrer");
489
510
  }
490
511
  });
491
512
  function parseMarkdown(markdown) {