hermes-wasm 1.8.145 → 1.8.146
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 +92 -325
- package/hermes_wasm.js +4 -4
- package/hermes_wasm_bg.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,70 +1,38 @@
|
|
|
1
1
|
# hermes-wasm
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Browser search and indexing through the shared Rust engine. `LocalIndex` is
|
|
4
|
+
writable; `RemoteIndex` (HTTP) and `IpfsIndex` (fetch callbacks) are read-only.
|
|
5
|
+
Remote readers cache slices in memory and optionally IndexedDB.
|
|
4
6
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
- **Local indexing** — create indexes, add documents, commit, and search entirely in WASM
|
|
8
|
-
- **Pluggable persistence** — bring your own storage (IDB, encrypted, OPFS) via simple JS interface
|
|
9
|
-
- **Remote search** — load pre-built indexes over HTTP with slice caching
|
|
10
|
-
- **IPFS support** — load indexes from IPFS via JavaScript fetch callbacks
|
|
11
|
-
- **Language-aware tokenizers** — English, German, French, Spanish, Russian, Arabic, and more
|
|
12
|
-
- **Query language** — `field:term`, `AND`, `OR`, `NOT`, grouping with parentheses
|
|
13
|
-
- **Static deployment** — host the generated JS/WASM and index files over HTTP
|
|
14
|
-
|
|
15
|
-
## Quick Start
|
|
7
|
+
## Quick start
|
|
16
8
|
|
|
17
9
|
```bash
|
|
18
10
|
npm install hermes-wasm
|
|
19
11
|
```
|
|
20
12
|
|
|
21
|
-
### In-Memory Index
|
|
22
|
-
|
|
23
13
|
```js
|
|
24
14
|
import init, { LocalIndex } from "hermes-wasm";
|
|
25
15
|
|
|
26
16
|
await init();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
field body: text<en_stem> [indexed, stored]
|
|
33
|
-
field views: u64 [indexed, stored]
|
|
34
|
-
}
|
|
35
|
-
`);
|
|
36
|
-
|
|
37
|
-
// Add documents
|
|
38
|
-
await index.addDocuments([
|
|
39
|
-
{
|
|
40
|
-
title: "Rust Programming",
|
|
41
|
-
body: "Rust is a systems language.",
|
|
42
|
-
views: 1500,
|
|
43
|
-
},
|
|
44
|
-
{ title: "Search Engines", body: "BM25 is a ranking function.", views: 800 },
|
|
45
|
-
]);
|
|
46
|
-
|
|
47
|
-
// Commit (builds the segment)
|
|
17
|
+
const index = await LocalIndex.create(`index articles {
|
|
18
|
+
field id: text<raw> [primary, stored]
|
|
19
|
+
field title: text<en_stem> [indexed, stored]
|
|
20
|
+
}`);
|
|
21
|
+
await index.addDocument({ id: "1", title: "Search with Rust" });
|
|
48
22
|
await index.commit();
|
|
49
|
-
|
|
50
|
-
// Search
|
|
51
23
|
const results = await index.search("rust", 10);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// Get document
|
|
55
|
-
const doc = await index.getDocument(
|
|
56
|
-
results.hits[0].address.segment_id,
|
|
57
|
-
results.hits[0].address.doc_id,
|
|
58
|
-
);
|
|
59
|
-
// { title: "Rust Programming", body: "Rust is a systems language.", views: 1500 }
|
|
24
|
+
const { segment_id, doc_id } = results.hits[0].address;
|
|
25
|
+
const doc = await index.getDocument(segment_id, doc_id);
|
|
60
26
|
```
|
|
61
27
|
|
|
62
|
-
|
|
28
|
+
See [SDL](../docs/schema.md) and [query syntax](../docs/query-language.md).
|
|
29
|
+
|
|
30
|
+
## Persistent local indexes
|
|
63
31
|
|
|
64
|
-
|
|
32
|
+
`LocalIndex.withStorage(storage, sdl)` creates or reopens an index and saves
|
|
33
|
+
changed files on commit. Supply this interface:
|
|
65
34
|
|
|
66
35
|
```ts
|
|
67
|
-
// Your storage must implement this interface:
|
|
68
36
|
interface IFilesStorage {
|
|
69
37
|
write(name: string, buffer: ArrayBuffer): Promise<void>;
|
|
70
38
|
get(name: string): Promise<ArrayBuffer | null>;
|
|
@@ -73,320 +41,119 @@ interface IFilesStorage {
|
|
|
73
41
|
}
|
|
74
42
|
```
|
|
75
43
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const index = await LocalIndex.withStorage(myStorage, schema);
|
|
79
|
-
await index.addDocuments(docs);
|
|
80
|
-
await index.commit(); // only new segment files written to storage
|
|
81
|
-
|
|
82
|
-
// Later (page reload) — same call reopens if storage has files
|
|
83
|
-
const index = await LocalIndex.withStorage(myStorage, schema);
|
|
84
|
-
const results = await index.search("rust", 10); // works immediately
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
A simple IndexedDB implementation:
|
|
44
|
+
Use one writable index per storage namespace and atomic per-file replacement.
|
|
45
|
+
IndexedDB, OPFS, and encryption are storage-adapter choices.
|
|
88
46
|
|
|
89
|
-
|
|
90
|
-
class IdbStorage {
|
|
91
|
-
constructor(name) {
|
|
92
|
-
this.prefix = `idx:${name}:`;
|
|
93
|
-
}
|
|
94
|
-
async write(name, buffer) {
|
|
95
|
-
/* idb put this.prefix + name → buffer */
|
|
96
|
-
}
|
|
97
|
-
async get(name) {
|
|
98
|
-
/* idb get this.prefix + name */
|
|
99
|
-
}
|
|
100
|
-
async delete(names) {
|
|
101
|
-
/* idb delete each this.prefix + name */
|
|
102
|
-
}
|
|
103
|
-
async list() {
|
|
104
|
-
/* idb getAllKeys matching this.prefix, strip prefix */
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const index = await LocalIndex.withStorage(new IdbStorage("articles"), schema);
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### Remote Index (HTTP)
|
|
47
|
+
## Remote indexes
|
|
112
48
|
|
|
113
49
|
```js
|
|
114
|
-
import init, { RemoteIndex } from "hermes-wasm";
|
|
50
|
+
import init, { RemoteIndex, IpfsIndex } from "hermes-wasm";
|
|
115
51
|
|
|
116
52
|
await init();
|
|
117
|
-
|
|
118
53
|
const index = new RemoteIndex("https://example.com/my-index/");
|
|
119
|
-
await index.load_with_idb_cache(); //
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
// Fetch a document
|
|
124
|
-
const doc = await index.get_document(
|
|
125
|
-
results.hits[0].address.segment_id,
|
|
126
|
-
results.hits[0].address.doc_id,
|
|
127
|
-
);
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
## API Reference
|
|
131
|
-
|
|
132
|
-
### `LocalIndex`
|
|
133
|
-
|
|
134
|
-
| Method | Description |
|
|
135
|
-
| ------------------------------------------------------- | -------------------------------------------------- |
|
|
136
|
-
| `LocalIndex.create(sdl)` | Create in-memory index from SDL schema |
|
|
137
|
-
| `LocalIndex.withStorage(storage, sdl)` | Create or open index with pluggable storage |
|
|
138
|
-
| `index.addDocument(json)` | Add a single document |
|
|
139
|
-
| `index.addDocuments(jsonArray)` | Add multiple documents, returns count |
|
|
140
|
-
| `index.commit()` | Commit pending docs, sync to storage if configured |
|
|
141
|
-
| `index.search(query, limit)` | Search with BM25 ranking |
|
|
142
|
-
| `index.searchOffset(query, limit, offset)` | Search with pagination |
|
|
143
|
-
| `index.searchStructured(request)` | Structured query with inline doc retrieval |
|
|
144
|
-
| `index.getDocument(segmentId, docId)` | Retrieve stored document |
|
|
145
|
-
| `index.getDocumentWithFields(segmentId, docId, fields)` | Retrieve only specified fields |
|
|
146
|
-
| `index.numDocs()` | Count of committed documents |
|
|
147
|
-
| `index.pendingDocs()` | Count of uncommitted documents |
|
|
148
|
-
| `index.fieldNames()` | List of field names |
|
|
149
|
-
|
|
150
|
-
### `RemoteIndex`
|
|
151
|
-
|
|
152
|
-
| Method | Description |
|
|
153
|
-
| ---------------------------------------------------------- | ----------------------------------- |
|
|
154
|
-
| `new RemoteIndex(url)` | Create remote index pointing to URL |
|
|
155
|
-
| `RemoteIndex.with_cache_size(url, bytes)` | Create with custom cache size |
|
|
156
|
-
| `index.load()` | Load index metadata and segments |
|
|
157
|
-
| `index.load_with_idb_cache()` | Load with IndexedDB cache pre-fill |
|
|
158
|
-
| `index.search(query, limit)` | Search |
|
|
159
|
-
| `index.search_offset(query, limit, offset)` | Search with pagination |
|
|
160
|
-
| `index.searchStructured(request)` | Structured query with inline docs |
|
|
161
|
-
| `index.get_document(segmentId, docId)` | Retrieve document |
|
|
162
|
-
| `index.get_document_with_fields(segmentId, docId, fields)` | Retrieve only specified fields |
|
|
163
|
-
| `index.num_docs()` | Document count |
|
|
164
|
-
| `index.num_segments()` | Segment count |
|
|
165
|
-
| `index.field_names()` | Field names |
|
|
166
|
-
| `index.default_fields()` | Default search fields |
|
|
167
|
-
| `index.export_cache()` | Export slice cache as `Uint8Array` |
|
|
168
|
-
| `index.import_cache(data)` | Import previously exported cache |
|
|
169
|
-
| `index.save_cache_to_idb()` | Persist slice cache to IndexedDB |
|
|
170
|
-
| `index.load_cache_from_idb()` | Restore cache from IndexedDB |
|
|
171
|
-
| `index.clear_idb_cache()` | Remove persisted cache |
|
|
172
|
-
| `index.cache_stats()` | Cache utilization info |
|
|
173
|
-
| `index.network_stats()` | HTTP request statistics |
|
|
174
|
-
| `index.reset_network_stats()` | Clear network statistics |
|
|
175
|
-
|
|
176
|
-
### `IpfsIndex`
|
|
177
|
-
|
|
178
|
-
Same API as `RemoteIndex` but loaded via JavaScript callbacks instead of HTTP:
|
|
179
|
-
|
|
180
|
-
| Method | Description |
|
|
181
|
-
| -------------------------------------------- | ---------------------------------------- |
|
|
182
|
-
| `new IpfsIndex(basePath)` | Create with IPFS path (e.g. `/ipfs/Qm…`) |
|
|
183
|
-
| `IpfsIndex.with_cache_size(path, bytes)` | Create with custom cache size |
|
|
184
|
-
| `index.load(fetchFn, sizeFn)` | Load using JS callbacks |
|
|
185
|
-
| `index.load_with_idb_cache(fetchFn, sizeFn)` | Load with IDB cache + JS callbacks |
|
|
186
|
-
|
|
187
|
-
`fetchFn`: `(path: string, rangeStart?: number, rangeEnd?: number) => Promise<Uint8Array>`
|
|
188
|
-
`sizeFn`: `(path: string) => Promise<number>`
|
|
189
|
-
|
|
190
|
-
All other methods (`search`, `get_document`, `cache_stats`, etc.) are identical to `RemoteIndex`.
|
|
191
|
-
|
|
192
|
-
### Logging
|
|
193
|
-
|
|
194
|
-
Debug output is off by default (level: `warn`). Enable verbose logging for diagnostics:
|
|
195
|
-
|
|
196
|
-
```js
|
|
197
|
-
import { set_log_level } from "hermes-wasm";
|
|
54
|
+
await index.load_with_idb_cache(); // Use load() to skip persistent cache restore.
|
|
55
|
+
const results = await index.search("rust", 10);
|
|
56
|
+
await index.save_cache_to_idb();
|
|
198
57
|
|
|
199
|
-
|
|
58
|
+
const ipfs = new IpfsIndex("/ipfs/YOUR_CID");
|
|
59
|
+
await ipfs.load(fetchFn, sizeFn);
|
|
200
60
|
```
|
|
201
61
|
|
|
202
|
-
|
|
62
|
+
HTTP hosting must support range requests and cross-origin access when needed.
|
|
63
|
+
IPFS callbacks:
|
|
203
64
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
| `registry.list()` | List index names |
|
|
212
|
-
| `registry.search(name, query, limit)` | Search a specific index |
|
|
213
|
-
|
|
214
|
-
### Schema Definition Language (SDL)
|
|
215
|
-
|
|
216
|
-
```
|
|
217
|
-
index <name> {
|
|
218
|
-
field <name>: <type> [attributes]
|
|
219
|
-
}
|
|
65
|
+
```ts
|
|
66
|
+
type FetchFn = (
|
|
67
|
+
path: string,
|
|
68
|
+
start?: number,
|
|
69
|
+
end?: number,
|
|
70
|
+
) => Promise<Uint8Array>;
|
|
71
|
+
type SizeFn = (path: string) => Promise<number>;
|
|
220
72
|
```
|
|
221
73
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
**Tokenizers:** `text<en_stem>`, `text<de_stem>`, `text<fr_stem>`, `text<es_stem>`, `text<it_stem>`, `text<pt_stem>`, `text<ru_stem>`, `text<ar_stem>`, `text<simple>`, etc.
|
|
74
|
+
## API reference
|
|
225
75
|
|
|
226
|
-
|
|
76
|
+
All three indexes support `search(query, limit)` and `searchStructured(request)`.
|
|
77
|
+
Other method names differ:
|
|
227
78
|
|
|
228
|
-
|
|
79
|
+
| Operation | LocalIndex | RemoteIndex / IpfsIndex |
|
|
80
|
+
| ------------------------------ | ------------------------------------------------- | ------------------------------------------------------------------- |
|
|
81
|
+
| Paginated search | `searchOffset(query, limit, offset)` | `search_offset(query, limit, offset)` |
|
|
82
|
+
| Stored document | `getDocument(segmentId, docId)` | `get_document(segmentId, docId)` |
|
|
83
|
+
| Selected fields | `getDocumentWithFields(segmentId, docId, fields)` | `getDocumentWithFields(segmentId, docId, fields)` |
|
|
84
|
+
| Counts / fields | `numDocs()`, `pendingDocs()`, `fieldNames()` | `num_docs()`, `num_segments()`, `field_names()`, `default_fields()` |
|
|
85
|
+
| Ingest | `addDocument(doc)`, `addDocuments(docs)` | — |
|
|
86
|
+
| Publish / discard pending work | `commit()`, `abort()` | — |
|
|
229
87
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
| AND | `rust AND web` | Both terms required |
|
|
235
|
-
| OR | `rust OR python` | Either term |
|
|
236
|
-
| NOT | `rust NOT unsafe` | Exclude term |
|
|
237
|
-
| Group | `(rust OR go) AND web` | Grouping |
|
|
238
|
-
| Phrase | `"search engine"` | Exact phrase |
|
|
88
|
+
Remote indexes also expose `with_cache_size`, `cache_stats`, `network_stats`,
|
|
89
|
+
`reset_network_stats`, `export_cache`, `import_cache`, `save_cache_to_idb`,
|
|
90
|
+
`load_cache_from_idb`, and `clear_idb_cache`. `IndexRegistry` manages named HTTP
|
|
91
|
+
indexes with `add_remote`, `remove`, `list`, and `search`.
|
|
239
92
|
|
|
240
|
-
|
|
93
|
+
For exact signatures, use the generated `pkg/hermes_wasm.d.ts` after building.
|
|
94
|
+
Set diagnostics with `set_log_level("debug")`; the default is `warn`.
|
|
241
95
|
|
|
242
|
-
|
|
96
|
+
## Structured query API
|
|
243
97
|
|
|
244
98
|
```js
|
|
245
99
|
const results = await index.searchStructured({
|
|
246
|
-
query: {
|
|
100
|
+
query: { match: { field: "title", text: "rust search" } },
|
|
247
101
|
limit: 10,
|
|
248
|
-
|
|
249
|
-
fieldsToLoad: ["title", "body"],
|
|
102
|
+
fieldsToLoad: ["title"],
|
|
250
103
|
});
|
|
251
|
-
// { hits: [{ address, score, doc: { title: "..."
|
|
104
|
+
// { hits: [{ address, score, doc: { title: "..." } }], total_hits }
|
|
252
105
|
```
|
|
253
106
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
107
|
+
Requests use camelCase; responses use snake_case. Supported variants are
|
|
108
|
+
`term`, `match`, `phrase`, `boolean`, `prefix`, `sparseVector`, `denseVector`,
|
|
109
|
+
and top-level `fusion`. Term/prefix payloads use `value`, while match/phrase
|
|
110
|
+
use `text`. Fusion supports `rrf` and `normalizedWeightedSum`.
|
|
111
|
+
See the [request definitions](src/query.rs); server L1 and reranker options
|
|
112
|
+
are not exposed by this adapter.
|
|
259
113
|
|
|
260
|
-
|
|
261
|
-
{ match: { field: "body", text: "search engine" } }
|
|
262
|
-
|
|
263
|
-
// Boolean query (recursive composition)
|
|
264
|
-
{ boolean: {
|
|
265
|
-
must: [{ term: { field: "title", value: "rust" } }],
|
|
266
|
-
should: [{ match: { field: "body", text: "fast" } }],
|
|
267
|
-
mustNot: [{ term: { field: "title", value: "python" } }],
|
|
268
|
-
} }
|
|
269
|
-
|
|
270
|
-
// Prefix query
|
|
271
|
-
{ prefix: { field: "title", value: "rus" } }
|
|
114
|
+
## Structured search diagnostics
|
|
272
115
|
|
|
273
|
-
|
|
274
|
-
|
|
116
|
+
`includeRrfScores: true` adds fusion attribution; `tracing: true` captures bounded
|
|
117
|
+
branch nominations and selected addresses without changing retrieval depth or
|
|
118
|
+
ranking. Discarded candidates have no stored fields. Traces contain one local
|
|
119
|
+
shard. The diagnostic window is capped at 10,000 and JSON responses at 64 MiB;
|
|
120
|
+
oversized exports fail. See [candidate diagnostics](../docs/candidate-rescoring.md).
|
|
275
121
|
|
|
276
|
-
|
|
277
|
-
{ denseVector: { field: "emb", vector: [0.1, 0.2, 0.3], nprobe: 32 } }
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
## Building
|
|
122
|
+
## Delete and upsert local documents
|
|
281
123
|
|
|
282
|
-
|
|
124
|
+
A text primary key enables whole-document deletion and full replacement,
|
|
125
|
+
including all chunks and indexed-only values:
|
|
283
126
|
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
127
|
+
```js
|
|
128
|
+
await index.upsertDocument({ id: "1", title: "Updated title" });
|
|
129
|
+
await index.upsertDocument({ id: "1", title: "Latest title" });
|
|
130
|
+
await index.commit();
|
|
131
|
+
index.deleteDocument("1");
|
|
132
|
+
await index.commit();
|
|
289
133
|
```
|
|
290
134
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
135
|
+
Staged rows may be replaced/deleted before commit; the latest accepted version
|
|
136
|
+
wins. Optional [content hashes](../docs/content-deduplication.md) skip unchanged
|
|
137
|
+
upserts. `deleteDocuments(keys)` and `await upsertDocuments(docs)` return
|
|
138
|
+
`{ acceptedCount, errors: [{ index, error }] }`; inspect errors and commit accepted
|
|
139
|
+
work. `abort()` discards the entire pending transaction.
|
|
294
140
|
|
|
295
|
-
|
|
141
|
+
A failed builder requires abort. A failed storage commit can be retried without
|
|
142
|
+
replaying mutations. Batches allow 100,000 deletion keys / 8 MiB key bytes or
|
|
143
|
+
1,000 replacements / 32 MiB JSON. Physical compaction uses native core, CLI, or
|
|
144
|
+
the server. See [row deletion](../docs/row-deletion.md).
|
|
296
145
|
|
|
297
|
-
|
|
146
|
+
## Building
|
|
298
147
|
|
|
299
|
-
|
|
148
|
+
From the repository root, with `wasm-pack`, LLVM, and Node.js 22.12+:
|
|
300
149
|
|
|
301
150
|
```bash
|
|
302
151
|
cd hermes-wasm
|
|
303
152
|
bash build.sh
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
# Open http://localhost:8080
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
## Architecture
|
|
310
|
-
|
|
311
|
-
```
|
|
312
|
-
Browser JS
|
|
313
|
-
│
|
|
314
|
-
├── LocalIndex (create/index/search in WASM)
|
|
315
|
-
│ └── WasmIndexWriter → SegmentBuilder → RamDirectory
|
|
316
|
-
│ │
|
|
317
|
-
│ [pluggable IFilesStorage]
|
|
318
|
-
│ (IDB, encrypted, OPFS, ...)
|
|
319
|
-
│
|
|
320
|
-
├── RemoteIndex (HTTP range requests)
|
|
321
|
-
│ └── Searcher → SliceCachingDirectory → HttpDirectory
|
|
322
|
-
│
|
|
323
|
-
├── IpfsIndex (JS fetch callbacks)
|
|
324
|
-
│ └── Searcher → SliceCachingDirectory → JsFetchDirectory
|
|
325
|
-
│
|
|
326
|
-
└── IndexRegistry (multi-index management)
|
|
327
|
-
└── Map<name, RemoteIndex>
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
## Structured search diagnostics
|
|
331
|
-
|
|
332
|
-
`searchStructured` accepts `includeRrfScores` for fusion queries and `tracing`
|
|
333
|
-
for any supported structured query. Both default to false:
|
|
334
|
-
|
|
335
|
-
```js
|
|
336
|
-
const response = await index.searchStructured({
|
|
337
|
-
query: {
|
|
338
|
-
fusion: {
|
|
339
|
-
queries: [
|
|
340
|
-
{ name: "title", query: { match: { field: "title", text: "rust" } } },
|
|
341
|
-
{ name: "body", query: { match: { field: "body", text: "rust" } } },
|
|
342
|
-
],
|
|
343
|
-
},
|
|
344
|
-
},
|
|
345
|
-
limit: 10,
|
|
346
|
-
includeRrfScores: true,
|
|
347
|
-
tracing: true,
|
|
348
|
-
});
|
|
349
|
-
console.log(response.hits[0].rrf_score, response.hits[0].rrf_contributions);
|
|
350
|
-
console.log(response.trace.shards[0].queries);
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
Responses use snake_case, matching other WASM search results. RRF attribution
|
|
354
|
-
uses complete bounded branch lists before pagination and leaves `score`
|
|
355
|
-
unchanged. The local trace includes each branch's query tree, raw candidate
|
|
356
|
-
scores/ordinals and selected addresses, without hydrating discarded documents.
|
|
357
|
-
It contains one local shard with empty broker/backend IDs. The trace observes
|
|
358
|
-
the configured retrieval depth and does not run Boolean clauses independently.
|
|
359
|
-
The diagnostic window is capped at 10,000; candidate/ordinal bounds and a 64 MiB
|
|
360
|
-
JSON response limit reject oversized exports. WASM supports its existing RRF and
|
|
361
|
-
weighted-sum fusion modes; server L1/reranker features remain server APIs.
|
|
362
|
-
|
|
363
|
-
## Delete and upsert local documents
|
|
364
|
-
|
|
365
|
-
LocalIndex supports primary-key schemas and enforces uniqueness on insert and
|
|
366
|
-
reopen. Delete removes the document and every chunk, including indexed-only data.
|
|
367
|
-
Upserts are complete replacements; an absent key is inserted.
|
|
368
|
-
|
|
369
|
-
```javascript
|
|
370
|
-
const index = await LocalIndex.create(`index documents {
|
|
371
|
-
field id: text<raw> [primary, indexed, stored]
|
|
372
|
-
field body: text<simple> [indexed<chunked>]
|
|
373
|
-
}`);
|
|
374
|
-
await index.addDocument({ id: "a", body: ["first chunk", "second chunk"] });
|
|
375
|
-
await index.commit();
|
|
376
|
-
await index.upsertDocument({ id: "a", body: ["replacement"] });
|
|
377
|
-
await index.commit();
|
|
378
|
-
index.deleteDocument("a");
|
|
379
|
-
await index.commit();
|
|
153
|
+
npm ci
|
|
154
|
+
npm test -- --run
|
|
380
155
|
```
|
|
381
156
|
|
|
382
|
-
`
|
|
383
|
-
`
|
|
384
|
-
|
|
385
|
-
of the same key. `await index.abort()` discards the entire pending transaction.
|
|
386
|
-
A failed builder requires abort; a failed storage commit can be retried without
|
|
387
|
-
replaying mutations. RemoteIndex and IpfsIndex remain read-only.
|
|
388
|
-
|
|
389
|
-
Deletion batches allow 100,000 keys / 8 MiB key bytes; replacement batches allow
|
|
390
|
-
1,000 documents / 32 MiB JSON. Keep one writable LocalIndex per storage namespace,
|
|
391
|
-
and implement atomic per-file replacement in the storage adapter. Physical
|
|
392
|
-
compaction is available through native core, CLI, and the server ForceMerge API.
|
|
157
|
+
`build.sh` selects available LLVM tools for zstd cross-compilation and generates
|
|
158
|
+
`pkg/`. The root `package.json` is the private test harness; `pkg/` is the
|
|
159
|
+
publishable package. For a browser UI, see [hermes-web](../hermes-web/README.md).
|
package/hermes_wasm.js
CHANGED
|
@@ -1401,22 +1401,22 @@ function __wbg_get_imports() {
|
|
|
1401
1401
|
console.warn(arg0);
|
|
1402
1402
|
},
|
|
1403
1403
|
__wbindgen_generic_0000000000000001: function(arg0, arg1) {
|
|
1404
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx:
|
|
1404
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 2313, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
|
1405
1405
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen_a18550ed2d60b1cd___convert__closures_____invoke___wasm_bindgen_a18550ed2d60b1cd___JsValue__core_ed718c3d60ebd546___result__Result_____wasm_bindgen_a18550ed2d60b1cd___JsError___true_);
|
|
1406
1406
|
return ret;
|
|
1407
1407
|
},
|
|
1408
1408
|
__wbindgen_generic_0000000000000002: function(arg0, arg1) {
|
|
1409
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx:
|
|
1409
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 404, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
1410
1410
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen_a18550ed2d60b1cd___convert__closures_____invoke___web_sys_4cee5da1ec2af191___features__gen_IdbVersionChangeEvent__IdbVersionChangeEvent______true_);
|
|
1411
1411
|
return ret;
|
|
1412
1412
|
},
|
|
1413
1413
|
__wbindgen_generic_0000000000000003: function(arg0, arg1) {
|
|
1414
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("IDBVersionChangeEvent")], shim_idx:
|
|
1414
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("IDBVersionChangeEvent")], shim_idx: 404, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
1415
1415
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen_a18550ed2d60b1cd___convert__closures_____invoke___web_sys_4cee5da1ec2af191___features__gen_IdbVersionChangeEvent__IdbVersionChangeEvent______true__71);
|
|
1416
1416
|
return ret;
|
|
1417
1417
|
},
|
|
1418
1418
|
__wbindgen_generic_0000000000000004: function(arg0, arg1) {
|
|
1419
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx:
|
|
1419
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1445, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
1420
1420
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen_a18550ed2d60b1cd___convert__closures_____invoke_______true_);
|
|
1421
1421
|
return ret;
|
|
1422
1422
|
},
|
package/hermes_wasm_bg.wasm
CHANGED
|
Binary file
|