@delali/narsil 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Narsil
2
2
 
3
+ [![CI](https://github.com/assetcorp/narsil/actions/workflows/ci.yml/badge.svg)](https://github.com/assetcorp/narsil/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/@delali/narsil)](https://www.npmjs.com/package/@delali/narsil)
5
+ [![downloads](https://img.shields.io/npm/dw/@delali/narsil)](https://www.npmjs.com/package/@delali/narsil)
6
+ [![types](https://img.shields.io/badge/types-TypeScript-blue)](https://www.npmjs.com/package/@delali/narsil)
7
+ [![license](https://img.shields.io/npm/l/@delali/narsil)](https://github.com/assetcorp/narsil/blob/main/LICENSE)
8
+
3
9
  Distributed search, reforged.
4
10
 
5
11
  Narsil is a distributed search engine with full-text, vector, hybrid, and geosearch. It auto-partitions large indexes across workers, serializes them into a cross-language binary format (.nrsl), and merges results back into a single ranked answer. The TypeScript package is the first implementation.
@@ -140,6 +146,18 @@ const results = await narsil.query('products', {
140
146
  // hit.highlights.title.snippet => '<mark>Mechanical</mark> Keyboard'
141
147
  ```
142
148
 
149
+ ### Term suggestions
150
+
151
+ Get autocomplete suggestions from the index's term dictionary. The API tokenizes the input, extracts the last word, and matches it against stored terms across all partitions. Results are ranked by document frequency.
152
+
153
+ ```ts
154
+ const suggestions = await narsil.suggest('products', {
155
+ prefix: 'mech',
156
+ limit: 5,
157
+ })
158
+ // suggestions.terms => [{ term: 'mechan', documentFrequency: 12 }, ...]
159
+ ```
160
+
143
161
  ### Cursor-based pagination
144
162
 
145
163
  Deep pagination using `searchAfter` cursors that track position across partitions. No offset-based performance degradation for deep result sets.
@@ -204,6 +222,27 @@ import '@delali/narsil/languages/twi'
204
222
  | Vector | `mode: 'vector'` | Cosine similarity, dot product, or Euclidean distance |
205
223
  | Hybrid | `mode: 'hybrid'` | Weighted combination of BM25 + vector similarity |
206
224
 
225
+ ## Search quality
226
+
227
+ Ranking quality is measured against the [Cranfield Collection](https://ir-datasets.com/cranfield.html), the foundational information retrieval benchmark created in the 1960s. It contains 1,400 documents and 225 queries with exhaustive human relevance judgments, meaning every query-document pair was scored by domain experts. All engines in this comparison use identical stop words (Lucene English, 35 terms), Porter stemming, and default BM25 parameters.
228
+
229
+ | Engine | nDCG@10 | P@10 | MAP | MRR |
230
+ | --- | ---: | ---: | ---: | ---: |
231
+ | **Narsil 0.1.1** | **0.3739** | **0.2458** | **0.2614** | **0.5638** |
232
+ | Orama 3.1.18 | 0.2911 | 0.1836 | 0.1846 | 0.4821 |
233
+ | MiniSearch 7.2.0 | 0.0077 | 0.0067 | 0.0027 | 0.0139 |
234
+
235
+ **What these metrics mean:**
236
+
237
+ - **nDCG@10** measures whether the most relevant documents appear near the top of the results. A score of 1.0 would mean perfect ranking; 0.0 means no relevant documents in the top 10.
238
+ - **P@10** is the fraction of the top 10 results that are relevant. Narsil averages about 2.5 relevant results in every top-10 list.
239
+ - **MAP** tracks precision at every rank where a relevant document appears. Higher MAP means relevant documents cluster near the top rather than being spread through the result set.
240
+ - **MRR** measures how far a user scrolls to find the first relevant result. Narsil's 0.56 means the first relevant document typically appears at position 2.
241
+
242
+ These scores fall within the expected range for BM25 on standard IR benchmarks (published BM25 baselines on BEIR datasets range from 0.24 to 0.63 nDCG@10). Narsil also runs a [Cranfield regression test](src/__tests__/relevance/cranfield.test.ts) in CI that fails the build if ranking quality drops below calibrated thresholds.
243
+
244
+ Reproduce: `pnpm -C packages/benchmarks bench --tiers quality`
245
+
207
246
  ## Runtime support (TypeScript)
208
247
 
209
248
  | Runtime | Concurrency | Persistence | Invalidation |
@@ -1,4 +1,4 @@
1
- import { NarsilError, ErrorCodes } from '../chunk-JKIBUPAY.mjs';
1
+ import { NarsilError, ErrorCodes } from '../chunk-7GKPWGCN.mjs';
2
2
 
3
3
  // src/persistence/filesystem.ts
4
4
  var cachedFs = null;
@@ -1,4 +1,4 @@
1
- import { NarsilError, ErrorCodes } from '../chunk-JKIBUPAY.mjs';
1
+ import { NarsilError, ErrorCodes } from '../chunk-7GKPWGCN.mjs';
2
2
 
3
3
  // src/persistence/indexeddb.ts
4
4
  var DEFAULT_DB_NAME = "narsil";
@@ -26,7 +26,8 @@ var ErrorCodes = {
26
26
  SEARCH_INVALID_CURSOR: "SEARCH_INVALID_CURSOR",
27
27
  LANGUAGE_NOT_SUPPORTED: "LANGUAGE_NOT_SUPPORTED",
28
28
  ENVELOPE_VERSION_MISMATCH: "ENVELOPE_VERSION_MISMATCH",
29
- ENVELOPE_INVALID_MAGIC: "ENVELOPE_INVALID_MAGIC"
29
+ ENVELOPE_INVALID_MAGIC: "ENVELOPE_INVALID_MAGIC",
30
+ PARTITION_CAPACITY_EXCEEDED: "PARTITION_CAPACITY_EXCEEDED"
30
31
  };
31
32
  var NarsilError = class extends Error {
32
33
  code;