@delali/narsil 0.2.4-next.48 → 0.2.4-next.50
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 +2 -2
- package/dist/adapters/indexeddb.mjs +15 -10
- package/dist/{options-BC68VPoE.d.ts → capabilities-JrVQOwi4.d.ts} +55 -47
- package/dist/{chunk-BFIH7OV5.mjs → chunk-2GWVQWGA.mjs} +3 -1
- package/dist/chunk-AV4IJKD2.mjs +35 -0
- package/dist/{chunk-EV45L35L.mjs → chunk-BEIK3EOZ.mjs} +845 -2407
- package/dist/chunk-CBLS46IE.mjs +10 -0
- package/dist/chunk-CMVG2UEF.mjs +2038 -0
- package/dist/chunk-CV5H7XL7.mjs +876 -0
- package/dist/{chunk-JQUL2T6I.mjs → chunk-GCM3JFVA.mjs} +1 -2
- package/dist/{chunk-XWICBGYT.mjs → chunk-MHE7YWAU.mjs} +3 -5
- package/dist/{chunk-UZTT2BKQ.mjs → chunk-ND34I3SV.mjs} +1202 -1881
- package/dist/{chunk-PM52SMBT.mjs → chunk-OOSIDHA3.mjs} +2 -1
- package/dist/chunk-ORBLD3EL.mjs +6 -0
- package/dist/chunk-PIWKZPP7.mjs +64 -0
- package/dist/{chunk-4COAUBLJ.mjs → chunk-PMBHH44R.mjs} +124 -8
- package/dist/chunk-RP23PWMV.mjs +11 -0
- package/dist/chunk-UNEEFTEU.mjs +7 -0
- package/dist/{chunk-WTONLDU3.mjs → chunk-WYJXSLER.mjs} +9 -19
- package/dist/{chunk-DFZDV5FV.mjs → chunk-X6YZO4MQ.mjs} +19 -15
- package/dist/chunk-XE6XR2OE.mjs +23 -0
- package/dist/chunk-YEO6G2NG.mjs +6 -0
- package/dist/chunk-ZHUQKZBE.mjs +1292 -0
- package/dist/{client-C5BkUqB8.d.ts → client-CBOVHdjp.d.ts} +31 -7
- package/dist/client.d.ts +7 -7
- package/dist/client.mjs +250 -232
- package/dist/{config-B-ZI-ft5.d.ts → config-Czh2YNDi.d.ts} +2 -2
- package/dist/{config-BZRExglL.d.ts → config-OON7IJ_B.d.ts} +50 -13
- package/dist/direct-executor-OREXU72C.mjs +12 -0
- package/dist/distribution/coordinator/etcd.d.ts +2 -2
- package/dist/distribution/coordinator/etcd.mjs +2 -3
- package/dist/distribution/coordinator/in-memory.d.ts +2 -2
- package/dist/distribution/coordinator/in-memory.mjs +2 -2
- package/dist/distribution/transport/grpc.mjs +7 -9
- package/dist/distribution/transport/in-memory.mjs +2 -1
- package/dist/distribution/transport/tcp.mjs +3 -2
- package/dist/distribution.d.ts +8 -8
- package/dist/distribution.mjs +142 -101
- package/dist/embeddings/openai.mjs +5 -3
- package/dist/{engine-Cjr1uBLa.d.ts → engine-9PtFY50q.d.ts} +125 -69
- package/dist/index.browser.mjs +4689 -3330
- package/dist/index.d.ts +7 -7
- package/dist/index.mjs +14 -8
- package/dist/invalidation/broadcast-channel.mjs +2 -1
- package/dist/invalidation/filesystem.mjs +3 -4
- package/dist/{search-DDHjfXhJ.d.ts → memory-Bzd5xcEW.d.ts} +89 -63
- package/dist/persistence/durability/checkpoint-worker.d.ts +1 -1
- package/dist/persistence/durability/checkpoint-worker.mjs +14 -8
- package/dist/react.d.ts +4 -4
- package/dist/react.mjs +7 -5
- package/dist/{schema-B7juWg8Q.d.ts → schema-BqRx9t4E.d.ts} +22 -3
- package/dist/server.d.ts +47 -42
- package/dist/server.mjs +338 -821
- package/dist/thread-PZLEO6JL.mjs +310 -0
- package/dist/{types-DsSSjY4d.d.ts → types-DXPxaXPO.d.ts} +1 -1
- package/dist/vector/hnsw-build-worker.mjs +3 -4
- package/dist/vector/search-worker.mjs +4 -123
- package/dist/workers/entry.mjs +47 -3
- package/package.json +5 -1
- package/dist/direct-executor-EOTFGXTO.mjs +0 -8
package/README.md
CHANGED
|
@@ -91,7 +91,7 @@ Every hit holds the document, its id, and its BM25 score. `results.count` report
|
|
|
91
91
|
|
|
92
92
|
**Storage.** [Persistence adapters](https://github.com/assetcorp/narsil/blob/main/docs/persistence-and-durability.md) plug in filesystem, IndexedDB, memory, or custom backends. Durability adds a write-ahead log with periodic checkpoints and automatic recovery, and snapshots capture a whole index as one portable byte array.
|
|
93
93
|
|
|
94
|
-
**Scale.** [Partitioned indexes](https://github.com/assetcorp/narsil/blob/main/docs/partitions-and-workers.md) route documents by deterministic hash and reshape online through `rebalance()`, with writes buffering in a write-ahead queue during the reshape. Worker
|
|
94
|
+
**Scale.** [Partitioned indexes](https://github.com/assetcorp/narsil/blob/main/docs/partitions-and-workers.md) route documents by deterministic hash and reshape online through `rebalance()`, with writes buffering in a write-ahead queue during the reshape. Worker copies answer keyword queries on half the worker threads once an index holds 1,000 documents, and the HTTP server receives requests on the threads that hold them.
|
|
95
95
|
|
|
96
96
|
**Operations.** The [HTTP server](https://github.com/assetcorp/narsil/blob/main/docs/http-server.md) subpath wraps an engine in a REST API with health probes, bulk NDJSON import, snapshot and restore endpoints, and task-based long operations. The [client](https://github.com/assetcorp/narsil/blob/main/docs/client.md) subpath reaches every one of those routes from a browser or from Node under the engine's own method names, and the [React](https://github.com/assetcorp/narsil/blob/main/docs/react.md) subpath gives those methods to components as hooks. [Events, plugins, and memory reporting](https://github.com/assetcorp/narsil/blob/main/docs/observability.md) cover observability, and [language modules](https://github.com/assetcorp/narsil/blob/main/docs/language-support.md) cover 107 languages as separate entry points, 20 of them African.
|
|
97
97
|
|
|
@@ -108,7 +108,7 @@ Every hit holds the document, its id, and its BM25 score. `results.count` report
|
|
|
108
108
|
| [Geosearch](../../docs/geosearch.md) | Radius and polygon filters, and the two distance formulas |
|
|
109
109
|
| [Embedding adapters](../../docs/embedding-adapters.md) | Automatic embedding on insert and query, named adapters, the bundled ones, and custom ones |
|
|
110
110
|
| [Persistence and durability](../../docs/persistence-and-durability.md) | Storage backends, the write-ahead log, checkpoints, recovery, and snapshots |
|
|
111
|
-
| [Partitions and workers](../../docs/partitions-and-workers.md) | Partition routing, online rebalancing, worker
|
|
111
|
+
| [Partitions and workers](../../docs/partitions-and-workers.md) | Partition routing, online rebalancing, worker copies, and multi-instance invalidation |
|
|
112
112
|
| [Language support](../../docs/language-support.md) | The 107 language modules, analysis revisions and rebuilds, and named tokenizers and stop words |
|
|
113
113
|
| [HTTP server](../../docs/http-server.md) | Wrapping an engine in a REST API, every route it serves, and long-running tasks |
|
|
114
114
|
| [Cluster mode](../../docs/cluster.md) | Multi-node indexes: nodes and roles, replication, routed writes, distributed searches and reads, and what a cluster refuses |
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import { NarsilError, ErrorCodes } from '../chunk-P4ELXVJQ.mjs';
|
|
2
2
|
|
|
3
|
+
// src/persistence/constants.ts
|
|
4
|
+
var DEFAULT_INDEXEDDB_NAME = "narsil";
|
|
5
|
+
var DEFAULT_INDEXEDDB_STORE_NAME = "partitions";
|
|
6
|
+
var MAX_PERSISTENCE_KEY_LENGTH = 1024;
|
|
7
|
+
var INDEXEDDB_BLOCKED_TIMEOUT_MS = 5e3;
|
|
8
|
+
|
|
3
9
|
// src/persistence/indexeddb.ts
|
|
4
|
-
var DEFAULT_DB_NAME = "narsil";
|
|
5
|
-
var DEFAULT_STORE_NAME = "partitions";
|
|
6
|
-
var MAX_KEY_LENGTH = 1024;
|
|
7
|
-
var BLOCKED_TIMEOUT_MS = 5e3;
|
|
8
10
|
function validateKey(key) {
|
|
9
11
|
if (!key || key.length === 0) {
|
|
10
12
|
throw new NarsilError(ErrorCodes.PERSISTENCE_SAVE_FAILED, "Key must be a non-empty string");
|
|
11
13
|
}
|
|
12
|
-
if (key.length >
|
|
14
|
+
if (key.length > MAX_PERSISTENCE_KEY_LENGTH) {
|
|
13
15
|
throw new NarsilError(
|
|
14
16
|
ErrorCodes.PERSISTENCE_SAVE_FAILED,
|
|
15
|
-
`Key length ${key.length} exceeds maximum of ${
|
|
17
|
+
`Key length ${key.length} exceeds maximum of ${MAX_PERSISTENCE_KEY_LENGTH}`
|
|
16
18
|
);
|
|
17
19
|
}
|
|
18
20
|
}
|
|
@@ -23,8 +25,8 @@ function createIndexedDBPersistence(config) {
|
|
|
23
25
|
"IndexedDB is not available in this environment. Use createMemoryPersistence() or createFilesystemPersistence() instead."
|
|
24
26
|
);
|
|
25
27
|
}
|
|
26
|
-
const dbName = config?.dbName ??
|
|
27
|
-
const storeName = config?.storeName ??
|
|
28
|
+
const dbName = config?.dbName ?? DEFAULT_INDEXEDDB_NAME;
|
|
29
|
+
const storeName = config?.storeName ?? DEFAULT_INDEXEDDB_STORE_NAME;
|
|
28
30
|
let cachedDb = null;
|
|
29
31
|
function openDatabase() {
|
|
30
32
|
if (cachedDb !== null) {
|
|
@@ -36,9 +38,12 @@ function createIndexedDBPersistence(config) {
|
|
|
36
38
|
request.onblocked = () => {
|
|
37
39
|
blockedTimer = setTimeout(() => {
|
|
38
40
|
reject(
|
|
39
|
-
new NarsilError(
|
|
41
|
+
new NarsilError(
|
|
42
|
+
ErrorCodes.PERSISTENCE_SAVE_FAILED,
|
|
43
|
+
`IndexedDB open blocked for ${INDEXEDDB_BLOCKED_TIMEOUT_MS}ms`
|
|
44
|
+
)
|
|
40
45
|
);
|
|
41
|
-
},
|
|
46
|
+
}, INDEXEDDB_BLOCKED_TIMEOUT_MS);
|
|
42
47
|
};
|
|
43
48
|
request.onupgradeneeded = () => {
|
|
44
49
|
const db = request.result;
|
|
@@ -1,52 +1,7 @@
|
|
|
1
|
-
import { C as ClusterNamespace } from './config-B-ZI-ft5.js';
|
|
2
1
|
import { E as EmbeddingAdapter } from './adapters-79OIa4xm.js';
|
|
2
|
+
import { C as ClusterNamespace } from './config-Czh2YNDi.js';
|
|
3
3
|
import { h as TaskStore } from './tasks-Bn4R1NPN.js';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Marks that `POST /indexes/{name}/documents/_import` accepts `?async=true` and
|
|
7
|
-
* answers with a task record.
|
|
8
|
-
*
|
|
9
|
-
* @public
|
|
10
|
-
*/
|
|
11
|
-
declare const ASYNC_IMPORT_CAPABILITY = "documents.import.async";
|
|
12
|
-
/**
|
|
13
|
-
* Marks that `POST /tasks/{id}/_cancel` asks a running task to stop.
|
|
14
|
-
*
|
|
15
|
-
* @public
|
|
16
|
-
*/
|
|
17
|
-
declare const TASK_CANCEL_CAPABILITY = "tasks.cancel";
|
|
18
|
-
/**
|
|
19
|
-
* Marks that `GET /tasks` filters by index, type, and status, and pages through
|
|
20
|
-
* `from` and `limit`.
|
|
21
|
-
*
|
|
22
|
-
* @public
|
|
23
|
-
*/
|
|
24
|
-
declare const TASK_FILTER_CAPABILITY = "tasks.filter";
|
|
25
|
-
/**
|
|
26
|
-
* Marks that `POST /indexes/{name}/_rebuild-analysis` reanalyses an index whose
|
|
27
|
-
* language module moved on.
|
|
28
|
-
*
|
|
29
|
-
* @public
|
|
30
|
-
*/
|
|
31
|
-
declare const REBUILD_ANALYSIS_CAPABILITY = "indexes.rebuildAnalysis";
|
|
32
|
-
/**
|
|
33
|
-
* Marks that `POST /indexes/{name}/_open` and `POST /indexes/{name}/_close`
|
|
34
|
-
* load and release an index's server memory.
|
|
35
|
-
*
|
|
36
|
-
* @public
|
|
37
|
-
*/
|
|
38
|
-
declare const INDEX_LIFECYCLE_CAPABILITY = "indexes.lifecycle";
|
|
39
|
-
/**
|
|
40
|
-
* Every capability this server announces at `/capabilities`.
|
|
41
|
-
*
|
|
42
|
-
* A client reads this list to find out whether an optional route or mode is
|
|
43
|
-
* available before it sends a request, because a server that predates one of
|
|
44
|
-
* them answers 404 rather than explaining itself.
|
|
45
|
-
*
|
|
46
|
-
* @public
|
|
47
|
-
*/
|
|
48
|
-
declare const SERVER_CAPABILITIES: readonly string[];
|
|
49
|
-
|
|
50
5
|
/**
|
|
51
6
|
* Context handed to {@link OnRequestHook} for every inbound request, captured
|
|
52
7
|
* synchronously before any body is read. `remoteAddress` is the peer address
|
|
@@ -121,7 +76,7 @@ interface ServerLimits {
|
|
|
121
76
|
maxLineBytes?: number;
|
|
122
77
|
/** Documents handed to the engine per batch during NDJSON import; the loop yields between batches. */
|
|
123
78
|
importBatchSize?: number;
|
|
124
|
-
/** Maximum requests executing engine work at once; excess is shed with 429. Omit or 0 to disable. */
|
|
79
|
+
/** Maximum requests executing engine work at once, counted across every request thread; excess is shed with 429. Omit or 0 to disable. */
|
|
125
80
|
maxConcurrentRequests?: number;
|
|
126
81
|
/** Ceiling for a search's `limit`, `offset`, and `group.maxPerGroup`, so one
|
|
127
82
|
* request cannot ask for an unbounded result set. Excess → 400. Defaults to
|
|
@@ -228,6 +183,14 @@ interface NarsilServer {
|
|
|
228
183
|
close(): Promise<void>;
|
|
229
184
|
/** The server bound to this port, which is what you read after binding to port 0. */
|
|
230
185
|
readonly listeningPort: number;
|
|
186
|
+
/**
|
|
187
|
+
* How many request threads receive connections, which is the engine's
|
|
188
|
+
* worker count on a machine with three cores or more and one below that.
|
|
189
|
+
* It reads zero while the main thread answers every request itself, which
|
|
190
|
+
* happens on a runtime without worker threads, on an engine created with
|
|
191
|
+
* `workers.enabled: false`, and on a cluster node's engine.
|
|
192
|
+
*/
|
|
193
|
+
readonly requestThreadCount: number;
|
|
231
194
|
}
|
|
232
195
|
/**
|
|
233
196
|
* The body every failed response carries, which is what an HTTP client parses
|
|
@@ -247,4 +210,49 @@ interface ErrorEnvelope {
|
|
|
247
210
|
};
|
|
248
211
|
}
|
|
249
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Marks that `POST /indexes/{name}/documents/_import` accepts `?async=true` and
|
|
215
|
+
* answers with a task record.
|
|
216
|
+
*
|
|
217
|
+
* @public
|
|
218
|
+
*/
|
|
219
|
+
declare const ASYNC_IMPORT_CAPABILITY = "documents.import.async";
|
|
220
|
+
/**
|
|
221
|
+
* Marks that `POST /tasks/{id}/_cancel` asks a running task to stop.
|
|
222
|
+
*
|
|
223
|
+
* @public
|
|
224
|
+
*/
|
|
225
|
+
declare const TASK_CANCEL_CAPABILITY = "tasks.cancel";
|
|
226
|
+
/**
|
|
227
|
+
* Marks that `GET /tasks` filters by index, type, and status, and pages through
|
|
228
|
+
* `from` and `limit`.
|
|
229
|
+
*
|
|
230
|
+
* @public
|
|
231
|
+
*/
|
|
232
|
+
declare const TASK_FILTER_CAPABILITY = "tasks.filter";
|
|
233
|
+
/**
|
|
234
|
+
* Marks that `POST /indexes/{name}/_rebuild-analysis` reanalyses an index whose
|
|
235
|
+
* language module moved on.
|
|
236
|
+
*
|
|
237
|
+
* @public
|
|
238
|
+
*/
|
|
239
|
+
declare const REBUILD_ANALYSIS_CAPABILITY = "indexes.rebuildAnalysis";
|
|
240
|
+
/**
|
|
241
|
+
* Marks that `POST /indexes/{name}/_open` and `POST /indexes/{name}/_close`
|
|
242
|
+
* load and release an index's server memory.
|
|
243
|
+
*
|
|
244
|
+
* @public
|
|
245
|
+
*/
|
|
246
|
+
declare const INDEX_LIFECYCLE_CAPABILITY = "indexes.lifecycle";
|
|
247
|
+
/**
|
|
248
|
+
* Every capability this server announces at `/capabilities`.
|
|
249
|
+
*
|
|
250
|
+
* A client reads this list to find out whether an optional route or mode is
|
|
251
|
+
* available before it sends a request, because a server that predates one of
|
|
252
|
+
* them answers 404 rather than explaining itself.
|
|
253
|
+
*
|
|
254
|
+
* @public
|
|
255
|
+
*/
|
|
256
|
+
declare const SERVER_CAPABILITIES: readonly string[];
|
|
257
|
+
|
|
250
258
|
export { ASYNC_IMPORT_CAPABILITY as A, type CorsOptions as C, type ErrorEnvelope as E, INDEX_LIFECYCLE_CAPABILITY as I, type NarsilServer as N, type OnRequestHook as O, REBUILD_ANALYSIS_CAPABILITY as R, SERVER_CAPABILITIES as S, TASK_CANCEL_CAPABILITY as T, TASK_FILTER_CAPABILITY as a, type ServerOptions as b, type RequestContext as c, type RequestDenial as d, type ServerLimits as e };
|
|
@@ -108,8 +108,10 @@ function compareSortStrings(a, b) {
|
|
|
108
108
|
return compareCodePoints(a, b);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
// src/core/ordering/
|
|
111
|
+
// src/core/ordering/constants.ts
|
|
112
112
|
var SORT_VALUE_MAX_CODE_POINTS = 512;
|
|
113
|
+
|
|
114
|
+
// src/core/ordering/sort-values.ts
|
|
113
115
|
function truncateSortString(value) {
|
|
114
116
|
if (value.length <= SORT_VALUE_MAX_CODE_POINTS) return value;
|
|
115
117
|
let index = 0;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/runtime/detect.ts
|
|
2
|
+
function detectRuntimeName() {
|
|
3
|
+
if ("Bun" in globalThis) {
|
|
4
|
+
return "bun";
|
|
5
|
+
}
|
|
6
|
+
if ("Deno" in globalThis) {
|
|
7
|
+
return "deno";
|
|
8
|
+
}
|
|
9
|
+
const proc = globalThis.process;
|
|
10
|
+
if (typeof proc === "object" && proc !== null && typeof proc.versions === "object" && typeof proc.versions?.node === "string") {
|
|
11
|
+
return "node";
|
|
12
|
+
}
|
|
13
|
+
return "browser";
|
|
14
|
+
}
|
|
15
|
+
function getCpuCount() {
|
|
16
|
+
const nav = globalThis.navigator;
|
|
17
|
+
if (nav && typeof nav.hardwareConcurrency === "number" && nav.hardwareConcurrency >= 1) {
|
|
18
|
+
return nav.hardwareConcurrency;
|
|
19
|
+
}
|
|
20
|
+
return 1;
|
|
21
|
+
}
|
|
22
|
+
function detectRuntime() {
|
|
23
|
+
const runtime = detectRuntimeName();
|
|
24
|
+
return {
|
|
25
|
+
runtime,
|
|
26
|
+
cpuCount: getCpuCount(),
|
|
27
|
+
supportsWorkerThreads: runtime === "node" || runtime === "bun",
|
|
28
|
+
supportsWebWorkers: runtime === "browser" || runtime === "deno" || runtime === "bun",
|
|
29
|
+
supportsFileSystem: runtime === "node" || runtime === "bun" || runtime === "deno",
|
|
30
|
+
supportsIndexedDB: runtime === "browser" || "indexedDB" in globalThis,
|
|
31
|
+
supportsBroadcastChannel: "BroadcastChannel" in globalThis
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { detectRuntime };
|