@delali/narsil 0.2.4-next.50 → 0.2.4-next.52
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 +27 -25
- package/dist/{capabilities-JrVQOwi4.d.ts → capabilities-CuTSXvbN.d.ts} +2 -2
- package/dist/{chunk-BEIK3EOZ.mjs → chunk-2FO7KZ6K.mjs} +5468 -3837
- package/dist/{chunk-XE6XR2OE.mjs → chunk-3GWP2TO6.mjs} +1 -1
- package/dist/{chunk-KMMJMDUA.mjs → chunk-3L4U6EJQ.mjs} +15 -10
- package/dist/{chunk-MHE7YWAU.mjs → chunk-72AXTIBW.mjs} +2 -2
- package/dist/{chunk-CV5H7XL7.mjs → chunk-EY2ULUMT.mjs} +30 -7
- package/dist/chunk-IFBKLBGB.mjs +7 -0
- package/dist/{chunk-WYJXSLER.mjs → chunk-POWOTUKJ.mjs} +7 -1
- package/dist/chunk-T62YOSGS.mjs +4280 -0
- package/dist/chunk-U36IDJN7.mjs +366 -0
- package/dist/{chunk-ND34I3SV.mjs → chunk-ULJ36FK4.mjs} +3502 -2383
- package/dist/{chunk-RP23PWMV.mjs → chunk-WFKIGEBY.mjs} +3 -3
- package/dist/{chunk-CMVG2UEF.mjs → chunk-WM7IS45M.mjs} +55 -517
- package/dist/chunk-Y3L5MDRV.mjs +96 -0
- package/dist/{chunk-ZHUQKZBE.mjs → chunk-YPYULM5E.mjs} +20 -4
- package/dist/chunk-ZJ4CSAB2.mjs +13 -0
- package/dist/chunk-ZT5BRDFW.mjs +513 -0
- package/dist/{client-CBOVHdjp.d.ts → client-BMJWVxOP.d.ts} +5 -5
- package/dist/client.d.ts +8 -8
- package/dist/{config-OON7IJ_B.d.ts → config-BcYZkdMw.d.ts} +2 -2
- package/dist/{config-Czh2YNDi.d.ts → config-qMLpi5T4.d.ts} +2 -2
- package/dist/direct-executor-UJC36S2D.mjs +12 -0
- package/dist/distribution/coordinator/etcd.d.ts +2 -2
- package/dist/distribution/coordinator/in-memory.d.ts +2 -2
- package/dist/distribution.d.ts +8 -8
- package/dist/distribution.mjs +30 -15
- package/dist/{engine-9PtFY50q.d.ts → engine-zhms1qId.d.ts} +2 -2
- package/dist/index.browser.mjs +12845 -7766
- package/dist/index.d.ts +9 -21
- package/dist/index.mjs +13 -12
- package/dist/{memory-Bzd5xcEW.d.ts → memory-OmgkX_Z2.d.ts} +11 -1
- package/dist/persistence/durability/checkpoint-worker.d.ts +138 -3
- package/dist/persistence/durability/checkpoint-worker.mjs +31 -17
- package/dist/react.d.ts +6 -6
- package/dist/{schema-BqRx9t4E.d.ts → schema-OSWaaZzx.d.ts} +30 -6
- package/dist/serialization/crc32-worker.mjs +2 -1
- package/dist/server.d.ts +10 -10
- package/dist/server.mjs +80 -36
- package/dist/simd-DW5AtJ6B.d.ts +41 -0
- package/dist/{tasks-Bn4R1NPN.d.ts → tasks-DiF1c9v2.d.ts} +20 -1
- package/dist/{thread-PZLEO6JL.mjs → thread-TLCX43WV.mjs} +129 -41
- package/dist/{types-DXPxaXPO.d.ts → types-LEzMyjVX.d.ts} +1 -1
- package/dist/vector/search-worker.d.ts +292 -128
- package/dist/vector/search-worker.mjs +70 -54
- package/dist/workers/entry.mjs +10 -7
- package/package.json +52 -31
- package/dist/brute-force-DbHYCTc3.d.ts +0 -8
- package/dist/chunk-CBLS46IE.mjs +0 -10
- package/dist/chunk-PIWKZPP7.mjs +0 -64
- package/dist/chunk-PMBHH44R.mjs +0 -492
- package/dist/chunk-X6YZO4MQ.mjs +0 -1572
- package/dist/direct-executor-OREXU72C.mjs +0 -12
- package/dist/vector/hnsw-build-worker.d.ts +0 -105
- package/dist/vector/hnsw-build-worker.mjs +0 -123
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reports whether the runtime loaded the SIMD module that speeds up vector
|
|
3
|
+
* distance work.
|
|
4
|
+
*
|
|
5
|
+
* Vector search works either way, so read this to explain a difference in
|
|
6
|
+
* search latency between two hosts rather than to decide whether to search.
|
|
7
|
+
*
|
|
8
|
+
* @returns True once the SIMD module has loaded.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
declare function isSimdAvailable(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* The distance kernels bound to one memory, which read their operands at byte
|
|
15
|
+
* offsets inside that memory so that a caller measures against a vector where
|
|
16
|
+
* it already lies.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
interface ArenaSimd {
|
|
21
|
+
/** The kernels read every operand out of this memory. */
|
|
22
|
+
memory: WebAssembly.Memory;
|
|
23
|
+
/** Returns the dot product of two float32 vectors at the given byte offsets. */
|
|
24
|
+
dot_product: (ptrA: number, ptrB: number, len: number) => number;
|
|
25
|
+
/** Returns the length of the float32 vector at the given byte offset. */
|
|
26
|
+
magnitude: (ptr: number, len: number) => number;
|
|
27
|
+
/** Returns the squared euclidean distance between two float32 vectors at the given byte offsets. */
|
|
28
|
+
squared_euclidean_distance: (ptrA: number, ptrB: number, len: number) => number;
|
|
29
|
+
/** Returns the integer dot product of two byte code vectors at the given byte offsets. */
|
|
30
|
+
dot_u8: (ptrA: number, ptrB: number, len: number) => number;
|
|
31
|
+
/** Returns the integer squared distance between two byte code vectors at the given byte offsets. */
|
|
32
|
+
sqdist_u8: (ptrA: number, ptrB: number, len: number) => number;
|
|
33
|
+
/** Returns the sum of level products of two 4-bit codes at the given byte offsets, each holding two levels per byte. */
|
|
34
|
+
osq_dot_nibbles_4x4: (ptrA: number, ptrB: number, bytes: number) => number;
|
|
35
|
+
/** Returns the sum of level products of a 1-bit or 2-bit code and a query staged as four bit planes. Each plane spans `planeBytes`, with one bit for each of the code's lowest level bits. */
|
|
36
|
+
osq_dot_bits: (ptrDoc: number, ptrPlanes: number, planeBytes: number, docBits: number) => number;
|
|
37
|
+
/** Returns the sum of level products of two 1-bit codes or two 2-bit codes at the given byte offsets. */
|
|
38
|
+
osq_dot_bits_pair: (ptrA: number, ptrB: number, bytes: number, bits: number) => number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { type ArenaSimd as A, isSimdAvailable as i };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { M as MemoryStats } from './memory-OmgkX_Z2.js';
|
|
2
|
+
|
|
1
3
|
/** Declarative index configuration accepted over HTTP. Function-valued engine
|
|
2
4
|
* options (custom tokenizer, stopWords-as-function, group reducer, embedding
|
|
3
5
|
* adapter object) are not representable here; the embedding adapter is named
|
|
@@ -115,6 +117,23 @@ interface CapabilitiesResponse {
|
|
|
115
117
|
/** Each name marks one capability this server serves. */
|
|
116
118
|
capabilities: string[];
|
|
117
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* The body `GET /stats/memory` answers with, which is the engine's {@link MemoryStats}
|
|
122
|
+
* plus the number of worker threads the server receives requests on. Only the
|
|
123
|
+
* server can report that count, because it starts those threads.
|
|
124
|
+
*
|
|
125
|
+
* @public
|
|
126
|
+
*/
|
|
127
|
+
interface MemoryStatsResponse extends MemoryStats {
|
|
128
|
+
/**
|
|
129
|
+
* This many worker threads receive requests and answer searches from the
|
|
130
|
+
* copies they hold. The count is zero where the main thread answers everything
|
|
131
|
+
* itself, which happens under `workers.enabled: false`, on a runtime without
|
|
132
|
+
* worker threads, and on a cluster node's engine. See
|
|
133
|
+
* {@link NarsilServer.requestThreadCount}.
|
|
134
|
+
*/
|
|
135
|
+
requestThreads: number;
|
|
136
|
+
}
|
|
118
137
|
|
|
119
138
|
/**
|
|
120
139
|
* Which long-running operation a task record tracks.
|
|
@@ -271,4 +290,4 @@ interface TaskStore {
|
|
|
271
290
|
shutdown?(): Promise<void>;
|
|
272
291
|
}
|
|
273
292
|
|
|
274
|
-
export type { CapabilitiesResponse as C, HttpIndexConfig as H, ImportError as I, TaskListPage as T, CreateIndexEmbedding as a, ImportResult as b, TaskListQuery as c, TaskProgress as d, TaskRecord as e, TaskStatus as f, TaskType as g, TaskStore as h, CreateIndexRequest as i };
|
|
293
|
+
export type { CapabilitiesResponse as C, HttpIndexConfig as H, ImportError as I, MemoryStatsResponse as M, TaskListPage as T, CreateIndexEmbedding as a, ImportResult as b, TaskListQuery as c, TaskProgress as d, TaskRecord as e, TaskStatus as f, TaskType as g, TaskStore as h, CreateIndexRequest as i };
|
|
@@ -1,15 +1,56 @@
|
|
|
1
|
-
import { loadUWebSockets, childAppOf, createRouteRunner, corsWriter, createSharedRequestGate, registerServerRoutes, sendRelayed, createDocumentReadHandlers, respondJson, SERVER_CAPABILITIES, sendError, serverRoutes, parseJson, validateSuggest, rejectInvalid, respondError, validateQuery } from './chunk-
|
|
2
|
-
import { executeListDocuments, executeSuggest, executePreflight, queryBindingOf, executeQuery } from './chunk-
|
|
3
|
-
import './chunk-
|
|
4
|
-
import {
|
|
5
|
-
import './chunk-
|
|
6
|
-
import './chunk-
|
|
1
|
+
import { loadUWebSockets, childAppOf, createRouteRunner, corsWriter, createSharedRequestGate, registerServerRoutes, sendRelayed, createDocumentReadHandlers, respondJson, SERVER_CAPABILITIES, sendError, serverRoutes, parseJson, validateSuggest, rejectInvalid, respondError, validateQuery } from './chunk-EY2ULUMT.mjs';
|
|
2
|
+
import { executeListDocuments, executeSuggest, executePreflight, queryBindingOf, executeQuery } from './chunk-YPYULM5E.mjs';
|
|
3
|
+
import './chunk-3GWP2TO6.mjs';
|
|
4
|
+
import { resolveProjection, projectionKeepsField, setNestedValue } from './chunk-WM7IS45M.mjs';
|
|
5
|
+
import { extractVectorFieldsFromSchema } from './chunk-ZT5BRDFW.mjs';
|
|
6
|
+
import './chunk-ZJ4CSAB2.mjs';
|
|
7
|
+
import './chunk-WFKIGEBY.mjs';
|
|
7
8
|
import './chunk-2GWVQWGA.mjs';
|
|
8
9
|
import { ServerErrorCodes, NarsilError, ErrorCodes } from './chunk-P4ELXVJQ.mjs';
|
|
9
10
|
|
|
11
|
+
// src/server/request-threads/held-vectors.ts
|
|
12
|
+
function managerWithHeldVectors(manager, fieldPaths, vectorOf) {
|
|
13
|
+
function get(docId, projection) {
|
|
14
|
+
const document = manager.get(docId, projection);
|
|
15
|
+
if (document === void 0) return void 0;
|
|
16
|
+
for (const fieldPath of fieldPaths) {
|
|
17
|
+
if (projection !== void 0 && !projectionKeepsField(projection, fieldPath)) continue;
|
|
18
|
+
const vector = vectorOf(fieldPath, docId);
|
|
19
|
+
if (vector !== void 0)
|
|
20
|
+
setNestedValue(document, fieldPath, Float32Array.from(vector));
|
|
21
|
+
}
|
|
22
|
+
return document;
|
|
23
|
+
}
|
|
24
|
+
const reader = Object.create(manager);
|
|
25
|
+
reader.get = get;
|
|
26
|
+
return reader;
|
|
27
|
+
}
|
|
28
|
+
|
|
10
29
|
// src/server/request-threads/read-engine.ts
|
|
11
30
|
function createThreadReadEngine(options) {
|
|
12
31
|
const { executor, relay, searchHooks } = options;
|
|
32
|
+
function vectorFieldsOf(context) {
|
|
33
|
+
return [...extractVectorFieldsFromSchema(context.config.schema).keys()];
|
|
34
|
+
}
|
|
35
|
+
function holdsEveryVectorField(indexName, context) {
|
|
36
|
+
return vectorFieldsOf(context).every((fieldPath) => executor.holdsVectorField(indexName, fieldPath));
|
|
37
|
+
}
|
|
38
|
+
function holdsEveryVectorFieldRead(indexName, context, params) {
|
|
39
|
+
if (params.document === false) return true;
|
|
40
|
+
const projection = resolveProjection(params.document === true ? void 0 : params.document);
|
|
41
|
+
return vectorFieldsOf(context).every(
|
|
42
|
+
(fieldPath) => !projectionKeepsField(projection, fieldPath) || executor.holdsVectorField(indexName, fieldPath)
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
function managerOf(indexName, context) {
|
|
46
|
+
const fieldPaths = vectorFieldsOf(context);
|
|
47
|
+
if (fieldPaths.length === 0) return context.manager;
|
|
48
|
+
return managerWithHeldVectors(
|
|
49
|
+
context.manager,
|
|
50
|
+
fieldPaths,
|
|
51
|
+
(fieldPath, docId) => executor.heldVectorOf(indexName, fieldPath, docId)
|
|
52
|
+
);
|
|
53
|
+
}
|
|
13
54
|
function requireContext(indexName) {
|
|
14
55
|
const context = executor.queryContextOf(indexName);
|
|
15
56
|
if (context === void 0) {
|
|
@@ -20,29 +61,51 @@ function createThreadReadEngine(options) {
|
|
|
20
61
|
relay.touch(indexName);
|
|
21
62
|
return context;
|
|
22
63
|
}
|
|
64
|
+
function requireWholeDocuments(indexName) {
|
|
65
|
+
const context = requireContext(indexName);
|
|
66
|
+
if (!holdsEveryVectorField(indexName, context)) {
|
|
67
|
+
throw new NarsilError(ErrorCodes.INDEX_NOT_FOUND, `This thread holds no vectors of index "${indexName}" yet`, {
|
|
68
|
+
indexName
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return { context, manager: managerOf(indexName, context) };
|
|
72
|
+
}
|
|
23
73
|
async function resolvedParams(indexName, params) {
|
|
24
74
|
if (params.vector?.text === void 0) return params;
|
|
25
75
|
const value = await relay.embed(indexName, params.vector);
|
|
26
76
|
const { text: _text, ...vector } = params.vector;
|
|
27
77
|
return { ...params, vector: { ...vector, value } };
|
|
28
78
|
}
|
|
29
|
-
function
|
|
30
|
-
if (searchHooks) return false;
|
|
79
|
+
function holdsDocumentsOf(indexName) {
|
|
31
80
|
const context = executor.queryContextOf(indexName);
|
|
32
|
-
|
|
81
|
+
return context !== void 0 && holdsEveryVectorField(indexName, context);
|
|
82
|
+
}
|
|
83
|
+
function searchableContext(indexName, params) {
|
|
84
|
+
if (searchHooks) return null;
|
|
85
|
+
const context = executor.queryContextOf(indexName);
|
|
86
|
+
if (context === void 0) return null;
|
|
33
87
|
const field = params.vector?.field;
|
|
34
|
-
if (field === void 0) return
|
|
88
|
+
if (field === void 0) return context;
|
|
35
89
|
const vectorFields = extractVectorFieldsFromSchema(context.config.schema);
|
|
36
|
-
if (!vectorFields.has(field)) return
|
|
37
|
-
return context.vectorSearchers.has(field);
|
|
90
|
+
if (!vectorFields.has(field)) return context;
|
|
91
|
+
return context.vectorSearchers.has(field) ? context : null;
|
|
92
|
+
}
|
|
93
|
+
function canAnswer(indexName, params) {
|
|
94
|
+
const context = searchableContext(indexName, params);
|
|
95
|
+
return context !== null && holdsEveryVectorFieldRead(indexName, context, params);
|
|
96
|
+
}
|
|
97
|
+
function canCount(indexName, params) {
|
|
98
|
+
return searchableContext(indexName, params) !== null;
|
|
38
99
|
}
|
|
39
100
|
return {
|
|
40
101
|
holdsCopyOf: (indexName) => executor.queryContextOf(indexName) !== void 0,
|
|
102
|
+
holdsDocumentsOf,
|
|
41
103
|
canAnswer,
|
|
104
|
+
canCount,
|
|
42
105
|
async query(indexName, params) {
|
|
43
|
-
const context =
|
|
106
|
+
const { context, manager } = requireWholeDocuments(indexName);
|
|
44
107
|
const result = await executeQuery(await resolvedParams(indexName, params), {
|
|
45
|
-
manager
|
|
108
|
+
manager,
|
|
46
109
|
language: context.language,
|
|
47
110
|
config: context.config,
|
|
48
111
|
indexName,
|
|
@@ -72,10 +135,10 @@ function createThreadReadEngine(options) {
|
|
|
72
135
|
return result;
|
|
73
136
|
},
|
|
74
137
|
async get(indexName, docId) {
|
|
75
|
-
return
|
|
138
|
+
return requireWholeDocuments(indexName).manager.get(docId);
|
|
76
139
|
},
|
|
77
140
|
async getMultiple(indexName, docIds) {
|
|
78
|
-
const { manager } =
|
|
141
|
+
const { manager } = requireWholeDocuments(indexName);
|
|
79
142
|
const found = /* @__PURE__ */ new Map();
|
|
80
143
|
for (const docId of docIds) {
|
|
81
144
|
const document = manager.get(docId);
|
|
@@ -90,8 +153,8 @@ function createThreadReadEngine(options) {
|
|
|
90
153
|
return requireContext(indexName).manager.countDocuments();
|
|
91
154
|
},
|
|
92
155
|
async listDocuments(indexName, params) {
|
|
93
|
-
const context =
|
|
94
|
-
return executeListDocuments(params ?? {}, { manager
|
|
156
|
+
const { context, manager } = requireWholeDocuments(indexName);
|
|
157
|
+
return executeListDocuments(params ?? {}, { manager, schema: context.config.schema });
|
|
95
158
|
}
|
|
96
159
|
};
|
|
97
160
|
}
|
|
@@ -113,6 +176,13 @@ var SHUTTING_DOWN_DENIAL = {
|
|
|
113
176
|
allowed: false,
|
|
114
177
|
denial: { status: 503, code: ServerErrorCodes.INTERNAL_ERROR, message: "The server is shutting down" }
|
|
115
178
|
};
|
|
179
|
+
function relayedBody(rawBody) {
|
|
180
|
+
if (rawBody === null) return { bytes: null, moved: [] };
|
|
181
|
+
const memory = rawBody.buffer;
|
|
182
|
+
const ownsItsMemory = memory instanceof ArrayBuffer && rawBody.byteOffset === 0 && rawBody.byteLength === memory.byteLength;
|
|
183
|
+
if (!ownsItsMemory) return { bytes: new Uint8Array(rawBody), moved: [] };
|
|
184
|
+
return { bytes: new Uint8Array(memory), moved: [memory] };
|
|
185
|
+
}
|
|
116
186
|
function sendUnavailable(res) {
|
|
117
187
|
sendError(res, 503, ServerErrorCodes.INTERNAL_ERROR, "The server is shutting down");
|
|
118
188
|
}
|
|
@@ -135,13 +205,18 @@ function createRelayClient(port, touchIntervalMs) {
|
|
|
135
205
|
waiting.resolve(message);
|
|
136
206
|
});
|
|
137
207
|
port.on("close", failAll);
|
|
138
|
-
function send(build) {
|
|
208
|
+
function send(build, moved = []) {
|
|
139
209
|
if (closed) return Promise.reject(portClosedError());
|
|
140
210
|
nextRequestId += 1;
|
|
141
211
|
const requestId = nextRequestId;
|
|
142
212
|
return new Promise((resolve, reject) => {
|
|
143
213
|
pending.set(requestId, { resolve, reject });
|
|
144
|
-
|
|
214
|
+
try {
|
|
215
|
+
port.postMessage(build(requestId), moved);
|
|
216
|
+
} catch (err) {
|
|
217
|
+
pending.delete(requestId);
|
|
218
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
219
|
+
}
|
|
145
220
|
});
|
|
146
221
|
}
|
|
147
222
|
return {
|
|
@@ -159,17 +234,21 @@ function createRelayClient(port, touchIntervalMs) {
|
|
|
159
234
|
},
|
|
160
235
|
async request(route, ctx) {
|
|
161
236
|
let reply;
|
|
237
|
+
const body = relayedBody(ctx.rawBody);
|
|
162
238
|
try {
|
|
163
|
-
reply = await send(
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
239
|
+
reply = await send(
|
|
240
|
+
(requestId) => ({
|
|
241
|
+
type: "request",
|
|
242
|
+
requestId,
|
|
243
|
+
route,
|
|
244
|
+
params: ctx.params,
|
|
245
|
+
query: ctx.query.toString(),
|
|
246
|
+
contentType: ctx.contentType,
|
|
247
|
+
rawBody: body.bytes,
|
|
248
|
+
hookContext: ctx.hookContext
|
|
249
|
+
}),
|
|
250
|
+
body.moved
|
|
251
|
+
);
|
|
173
252
|
} catch {
|
|
174
253
|
if (!ctx.abort.aborted) sendUnavailable(ctx.res);
|
|
175
254
|
return;
|
|
@@ -207,7 +286,11 @@ function relayed(relay, route) {
|
|
|
207
286
|
function onHeldIndex(local, handler, fallback) {
|
|
208
287
|
return (ctx) => local.holdsCopyOf(ctx.params[0]) ? handler(ctx) : fallback(ctx);
|
|
209
288
|
}
|
|
210
|
-
function
|
|
289
|
+
function onWholeDocuments(local, handler, fallback) {
|
|
290
|
+
return (ctx) => local.holdsDocumentsOf(ctx.params[0]) ? handler(ctx) : fallback(ctx);
|
|
291
|
+
}
|
|
292
|
+
function searchHandler(options) {
|
|
293
|
+
const { fallback, maxResultWindow, staysOnThread, answer } = options;
|
|
211
294
|
return async (ctx) => {
|
|
212
295
|
const params = parseJson(ctx);
|
|
213
296
|
if (!params) return;
|
|
@@ -216,7 +299,7 @@ function searchHandler(local, fallback, maxResultWindow, answer) {
|
|
|
216
299
|
rejectInvalid(ctx, failure);
|
|
217
300
|
return;
|
|
218
301
|
}
|
|
219
|
-
if (!
|
|
302
|
+
if (!staysOnThread(ctx.params[0], params)) {
|
|
220
303
|
await fallback(ctx);
|
|
221
304
|
return;
|
|
222
305
|
}
|
|
@@ -267,19 +350,24 @@ function threadHandlers(local, relay, settings) {
|
|
|
267
350
|
livez: (ctx) => respondJson(ctx, { status: "ok" }),
|
|
268
351
|
version: (ctx) => respondJson(ctx, { name: "narsil", ...settings.build }),
|
|
269
352
|
capabilities: (ctx) => respondJson(ctx, { capabilities: [...SERVER_CAPABILITIES] }),
|
|
270
|
-
search: searchHandler(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
353
|
+
search: searchHandler({
|
|
354
|
+
fallback: forwarded.search,
|
|
355
|
+
maxResultWindow,
|
|
356
|
+
staysOnThread: (name, params) => local.canAnswer(name, params),
|
|
357
|
+
answer: (name, params) => local.query(name, params)
|
|
358
|
+
}),
|
|
359
|
+
preflight: searchHandler({
|
|
360
|
+
fallback: forwarded.preflight,
|
|
274
361
|
maxResultWindow,
|
|
275
|
-
(name, params) => local.
|
|
276
|
-
|
|
362
|
+
staysOnThread: (name, params) => local.canCount(name, params),
|
|
363
|
+
answer: (name, params) => local.preflight(name, params)
|
|
364
|
+
}),
|
|
277
365
|
suggest: suggestHandler(local, forwarded.suggest),
|
|
278
|
-
get:
|
|
366
|
+
get: onWholeDocuments(local, reads.get, forwarded.get),
|
|
279
367
|
exists: onHeldIndex(local, reads.exists, forwarded.exists),
|
|
280
368
|
count: onHeldIndex(local, reads.count, forwarded.count),
|
|
281
|
-
list:
|
|
282
|
-
multiGet:
|
|
369
|
+
list: onWholeDocuments(local, reads.list, forwarded.list),
|
|
370
|
+
multiGet: onWholeDocuments(local, reads.multiGet, forwarded.multiGet)
|
|
283
371
|
};
|
|
284
372
|
}
|
|
285
373
|
async function serveRequests(executor, settings) {
|