summa-client-typescript 2.0.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.
package/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # Summa TypeScript client
2
+
3
+ Typed Node.js client for the
4
+ [Summa](https://github.com/SpaceFrontiers/summa) gRPC search server.
5
+
6
+ ## Installation
7
+
8
+ ```bash
9
+ pnpm add summa-client-typescript
10
+ ```
11
+
12
+ ## Quick start
13
+
14
+ ```typescript
15
+ import { SummaClient } from "summa-client-typescript";
16
+
17
+ const client = new SummaClient("localhost:50051");
18
+ client.connect();
19
+
20
+ try {
21
+ await client.createIndex(
22
+ "articles",
23
+ `
24
+ index articles {
25
+ field id: text<raw> [primary, stored]
26
+ field title: text<simple> [indexed, stored]
27
+ field body: text<simple> [indexed, stored]
28
+ }
29
+ `,
30
+ );
31
+
32
+ const [indexedCount, errorCount, errors] = await client.indexDocuments(
33
+ "articles",
34
+ [
35
+ { id: "1", title: "Hello", body: "First article" },
36
+ { id: "2", title: "Summa", body: "Fast search" },
37
+ ],
38
+ );
39
+ if (errorCount) throw new Error(JSON.stringify(errors));
40
+ console.log(`Indexed ${indexedCount} documents`);
41
+
42
+ await client.commit("articles");
43
+
44
+ const results = await client.search("articles", {
45
+ query: { match: { field: "title", text: "hello" } },
46
+ fieldsToLoad: ["title", "body"],
47
+ });
48
+
49
+ for (const hit of results.hits) {
50
+ console.log(hit.address, hit.score, hit.fields);
51
+ }
52
+
53
+ if (results.hits.length > 0) {
54
+ const document = await client.getDocument(
55
+ "articles",
56
+ results.hits[0].address,
57
+ );
58
+ console.log(document?.fields);
59
+ }
60
+ } finally {
61
+ client.close();
62
+ }
63
+ ```
64
+
65
+ Call `connect()` before the first RPC and `close()` when finished.
66
+
67
+ ## Index management
68
+
69
+ ```typescript
70
+ await client.listIndexes();
71
+ const info = await client.getIndexInfo("articles");
72
+ await client.reorder("articles");
73
+ await client.retrainVectorIndex("articles");
74
+ ```
75
+
76
+ `indexDocuments` returns `[indexedCount, errorCount, errors]`;
77
+ `indexDocumentsStream` takes an async iterable. Inspect errors, then `commit()`
78
+ to publish accepted work. Arrays hold repeated values; flat numeric arrays are
79
+ dense vectors. One sparse vector uses `[[[1, 0.5], [8, 0.25]]]`: the outer array
80
+ is required because `[[1, 0.5], [8, 0.25]]` means two dense vectors.
81
+
82
+ ### Delete and upsert documents
83
+
84
+ With a text primary key, delete by exact key or supply a complete replacement:
85
+
86
+ ```typescript
87
+ await client.deleteDocument("articles", "2");
88
+ await client.upsertDocument("articles", { id: "1", title: "Updated title" });
89
+ await client.commit("articles");
90
+ ```
91
+
92
+ `deleteDocuments` / `upsertDocuments` return `DocumentMutationResult` with
93
+ `acceptedCount` and `errors: [{index, error}]`. Single-item helpers throw on
94
+ rejection. Missing deletes succeed; upserts insert missing keys. Staged rows can
95
+ be replaced/deleted again before commit; the latest accepted version wins.
96
+ Optional [content hashes](../docs/content-deduplication.md) skip unchanged writes.
97
+
98
+ Limits: 100,000 deletion keys / 8 MiB key bytes; 1,000 replacements / 32 MiB
99
+ encoded protobuf, or one replacement / 200 MiB including the request envelope.
100
+ Broker commits are atomic per partition. See [mutation semantics](../docs/row-deletion.md).
101
+
102
+ ### Compact deleted rows
103
+
104
+ ```typescript
105
+ await client.forceMerge("articles"); // Retain tombstones.
106
+ await client.forceMerge("articles", undefined, true); // Physically remove deleted rows.
107
+ ```
108
+
109
+ The second argument remains the timeout in milliseconds. Compaction handles
110
+ singletons and may change addresses and BM25 scores. Index info exposes
111
+ `numDocs`, `physicalNumDocs`, `numDeletedDocs`, and `deletedRatio`.
112
+
113
+ ## Searching
114
+
115
+ `search(indexName, request)` accepts a typed `SearchRequest`. Its `query` selects
116
+ one variant: `term`, `match`, `phrase`, `boolean`, `sparseVector`, `denseVector`,
117
+ `binaryDenseVector`, `boost`, `range`, `prefix`, `all`, or `fusion`.
118
+ See [client types](src/types.ts) and the [protocol](../summa-proto/summa.proto).
119
+
120
+ ```typescript
121
+ const results = await client.search("articles", {
122
+ query: {
123
+ boolean: {
124
+ must: [{ match: { field: "title", text: "search" } }],
125
+ mustNot: [{ term: { field: "title", term: "draft" } }],
126
+ },
127
+ },
128
+ fieldsToLoad: ["title"],
129
+ });
130
+ ```
131
+
132
+ `getDocument(indexName, hit.address)` uses the full segment/document address
133
+ and returns `null` on `NOT_FOUND`. Use primary keys for durable identity.
134
+
135
+ ## Ranking diagnostics and recall traces
136
+
137
+ Search options `includeRrfScores: true` and `tracing: true` default to false.
138
+ RRF diagnostics describe organic branch nominations; traces retain bounded
139
+ candidates and query trees, including hits outside the final page. Neither
140
+ changes retrieval depth or ranking. Oversized exports fail explicitly.
141
+
142
+ For named branches, use `l1: { formula: "0.2 * title + 0.8 * body + 3 * rrf" }`.
143
+ The formula is the only L1 scoring interface; old coefficient fields are removed.
144
+ See [candidate scoring](../docs/candidate-rescoring.md) for backfill, passage
145
+ selection, expression limits, capability versions, and distributed behavior.
146
+
147
+ ## Deadlines
148
+
149
+ RPCs accept a trailing timeout in milliseconds, overriding the constructor's
150
+ `defaultTimeoutMs`. Expired calls reject with gRPC `DEADLINE_EXCEEDED`.
151
+ An expired mutation may already be staged, and an accepted commit continues
152
+ after disconnection. Resolve the outcome before retrying replacements.
153
+
154
+ ## Development
155
+
156
+ ```bash
157
+ pnpm install --frozen-lockfile
158
+ pnpm check
159
+ ```
160
+
161
+ `check` compiles strict TypeScript and runs converter tests. After
162
+ [protocol changes](../summa-proto/README.md#regeneration-and-validation), run
163
+ `pnpm generate && pnpm check` and include the generated source.
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Async Summa client implementation.
3
+ *
4
+ * Search types mirror the protobuf API. Serialization details live in
5
+ * converters.ts so this class remains focused on connection and RPC lifecycle.
6
+ */
7
+ import type { DocAddress, Document, DocumentMutationResult, IndexInfo, SearchRequest, SearchResponse } from "./types";
8
+ export interface SummaClientOptions {
9
+ /**
10
+ * Default per-RPC deadline in milliseconds, applied to every call unless
11
+ * overridden by the call's `timeoutMs` argument. Undefined means no
12
+ * deadline. Expired calls reject with gRPC DEADLINE_EXCEEDED.
13
+ */
14
+ defaultTimeoutMs?: number;
15
+ }
16
+ export declare class SummaClient {
17
+ private readonly address;
18
+ private readonly defaultTimeoutMs?;
19
+ private channel;
20
+ private indexClient;
21
+ private searchClient;
22
+ constructor(address?: string, options?: SummaClientOptions);
23
+ /** Connect to the server. */
24
+ connect(): void;
25
+ /** Close the connection. */
26
+ close(): void;
27
+ /** Per-call options with the effective deadline (call override > default). */
28
+ private callOptions;
29
+ private ensureConnected;
30
+ /** Create a new index. */
31
+ createIndex(indexName: string, schema: string, timeoutMs?: number): Promise<boolean>;
32
+ /** Delete an index. */
33
+ deleteIndex(indexName: string, timeoutMs?: number): Promise<boolean>;
34
+ /** List all indexes on the server. */
35
+ listIndexes(timeoutMs?: number): Promise<string[]>;
36
+ /** Get information about an index. */
37
+ getIndexInfo(indexName: string, timeoutMs?: number): Promise<IndexInfo>;
38
+ /** Index multiple documents. Returns [indexedCount, errorCount, errors]. */
39
+ indexDocuments(indexName: string, documents: Record<string, unknown>[], timeoutMs?: number): Promise<[number, number, Array<{
40
+ index: number;
41
+ error: string;
42
+ }>]>;
43
+ /** Index a single document. */
44
+ indexDocument(indexName: string, document: Record<string, unknown>, timeoutMs?: number): Promise<void>;
45
+ /** Stage exact-key deletions of whole documents and all their chunks.
46
+ * Missing keys are accepted. Inspect errors, then commit accepted work.
47
+ * Do not blindly retry mutations after an uncertain RPC outcome.
48
+ */
49
+ deleteDocuments(indexName: string, primaryKeys: string[], timeoutMs?: number): Promise<DocumentMutationResult>;
50
+ /** Stage one deletion; throws on rejection. Call commit to publish. */
51
+ deleteDocument(indexName: string, primaryKey: string, timeoutMs?: number): Promise<void>;
52
+ /** Stage complete replacements (inserts if absent); inspect errors, then commit.
53
+ * Each document needs its primary key; commit publishes its latest accepted
54
+ * replacement, including across calls. This is not a partial patch API.
55
+ */
56
+ upsertDocuments(indexName: string, documents: Record<string, unknown>[], timeoutMs?: number): Promise<DocumentMutationResult>;
57
+ /** Stage one complete replacement; throws on rejection. Commit to publish. */
58
+ upsertDocument(indexName: string, document: Record<string, unknown>, timeoutMs?: number): Promise<void>;
59
+ /** Stream documents for indexing. Returns number of indexed documents. */
60
+ indexDocumentsStream(indexName: string, documents: AsyncIterable<Record<string, unknown>>, timeoutMs?: number): Promise<number>;
61
+ /** Commit pending changes. Returns total number of documents. */
62
+ commit(indexName: string, timeoutMs?: number): Promise<number>;
63
+ /** Merge segments; compact=true physically removes tombstones from final outputs. */
64
+ forceMerge(indexName: string, timeoutMs?: number, compact?: boolean): Promise<number>;
65
+ /** Retrain vector index centroids/codebooks from current data. */
66
+ retrainVectorIndex(indexName: string, timeoutMs?: number): Promise<boolean>;
67
+ /** Run bounded text, Seismic, and binary ANN layout maintenance. */
68
+ reorder(indexName: string, timeoutMs?: number): Promise<number>;
69
+ /**
70
+ * Search for documents.
71
+ *
72
+ * @example
73
+ * await client.search("articles", {
74
+ * query: { match: { field: "title", text: "search engine" } },
75
+ * fieldsToLoad: ["title"],
76
+ * });
77
+ */
78
+ search(indexName: string, request: SearchRequest, timeoutMs?: number): Promise<SearchResponse>;
79
+ /** Get a document by address. Returns null if not found. */
80
+ getDocument(indexName: string, address: DocAddress, timeoutMs?: number): Promise<Document | null>;
81
+ }
82
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js ADDED
@@ -0,0 +1,312 @@
1
+ "use strict";
2
+ /**
3
+ * Async Summa client implementation.
4
+ *
5
+ * Search types mirror the protobuf API. Serialization details live in
6
+ * converters.ts so this class remains focused on connection and RPC lifecycle.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.SummaClient = void 0;
10
+ const grpc_js_1 = require("@grpc/grpc-js");
11
+ const nice_grpc_1 = require("nice-grpc");
12
+ const nice_grpc_client_middleware_deadline_1 = require("nice-grpc-client-middleware-deadline");
13
+ const converters_1 = require("./converters");
14
+ const summa_1 = require("./generated/summa");
15
+ class SummaClient {
16
+ constructor(address = "localhost:50051", options = {}) {
17
+ this.channel = null;
18
+ this.indexClient = null;
19
+ this.searchClient = null;
20
+ this.address = address;
21
+ this.defaultTimeoutMs = options.defaultTimeoutMs;
22
+ }
23
+ /** Connect to the server. */
24
+ connect() {
25
+ this.channel = (0, nice_grpc_1.createChannel)(this.address, grpc_js_1.ChannelCredentials.createInsecure(), {
26
+ // Match Python and fit bounded mutation requests and per-item errors.
27
+ "grpc.max_receive_message_length": 50 * 1024 * 1024,
28
+ "grpc.max_send_message_length": 200 * 1024 * 1024,
29
+ });
30
+ const factory = (0, nice_grpc_1.createClientFactory)().use(nice_grpc_client_middleware_deadline_1.deadlineMiddleware);
31
+ this.indexClient = factory.create(summa_1.IndexServiceDefinition, this.channel);
32
+ this.searchClient = factory.create(summa_1.SearchServiceDefinition, this.channel);
33
+ }
34
+ /** Close the connection. */
35
+ close() {
36
+ if (this.channel) {
37
+ this.channel.close();
38
+ this.channel = null;
39
+ this.indexClient = null;
40
+ this.searchClient = null;
41
+ }
42
+ }
43
+ /** Per-call options with the effective deadline (call override > default). */
44
+ callOptions(timeoutMs) {
45
+ const milliseconds = timeoutMs ?? this.defaultTimeoutMs;
46
+ return milliseconds !== undefined && milliseconds > 0
47
+ ? { deadline: new Date(Date.now() + milliseconds) }
48
+ : {};
49
+ }
50
+ ensureConnected() {
51
+ if (!this.indexClient || !this.searchClient) {
52
+ throw new Error("Client not connected. Call connect() first.");
53
+ }
54
+ }
55
+ /** Create a new index. */
56
+ async createIndex(indexName, schema, timeoutMs) {
57
+ this.ensureConnected();
58
+ const response = await this.indexClient.createIndex({ indexName, schema }, this.callOptions(timeoutMs));
59
+ return response.success;
60
+ }
61
+ /** Delete an index. */
62
+ async deleteIndex(indexName, timeoutMs) {
63
+ this.ensureConnected();
64
+ const response = await this.indexClient.deleteIndex({ indexName }, this.callOptions(timeoutMs));
65
+ return response.success;
66
+ }
67
+ /** List all indexes on the server. */
68
+ async listIndexes(timeoutMs) {
69
+ this.ensureConnected();
70
+ const response = await this.indexClient.listIndexes({}, this.callOptions(timeoutMs));
71
+ return response.indexNames;
72
+ }
73
+ /** Get information about an index. */
74
+ async getIndexInfo(indexName, timeoutMs) {
75
+ this.ensureConnected();
76
+ const response = await this.searchClient.getIndexInfo({ indexName }, this.callOptions(timeoutMs));
77
+ return {
78
+ indexName: response.indexName,
79
+ numDocs: response.numDocs,
80
+ numSegments: response.numSegments,
81
+ schema: response.schema,
82
+ physicalNumDocs: response.physicalNumDocs,
83
+ numDeletedDocs: response.numDeletedDocs,
84
+ deletedRatio: response.deletedRatio,
85
+ candidateScoringVersion: response.candidateScoringVersion,
86
+ unpreparedCandidateFields: response.unpreparedCandidateFields,
87
+ vectorStats: (response.vectorStats ?? []).map((stats) => ({
88
+ fieldName: stats.fieldName,
89
+ vectorType: stats.vectorType,
90
+ totalVectors: stats.totalVectors,
91
+ dimension: stats.dimension,
92
+ })),
93
+ };
94
+ }
95
+ /** Index multiple documents. Returns [indexedCount, errorCount, errors]. */
96
+ async indexDocuments(indexName, documents, timeoutMs) {
97
+ this.ensureConnected();
98
+ const response = await this.indexClient.batchIndexDocuments({
99
+ indexName,
100
+ documents: documents.map((document) => ({
101
+ fields: (0, converters_1.toFieldEntries)(document),
102
+ })),
103
+ }, this.callOptions(timeoutMs));
104
+ const errors = (response.errors ?? []).map((error) => ({
105
+ index: error.index,
106
+ error: error.error,
107
+ }));
108
+ return [response.indexedCount, response.errorCount, errors];
109
+ }
110
+ /** Index a single document. */
111
+ async indexDocument(indexName, document, timeoutMs) {
112
+ await this.indexDocuments(indexName, [document], timeoutMs);
113
+ }
114
+ /** Stage exact-key deletions of whole documents and all their chunks.
115
+ * Missing keys are accepted. Inspect errors, then commit accepted work.
116
+ * Do not blindly retry mutations after an uncertain RPC outcome.
117
+ */
118
+ async deleteDocuments(indexName, primaryKeys, timeoutMs) {
119
+ this.ensureConnected();
120
+ if (primaryKeys.length > 100000 ||
121
+ primaryKeys.reduce((sum, key) => sum + Buffer.byteLength(key, "utf8"), 0) > 8 * 1024 * 1024) {
122
+ throw new Error("deletion request exceeds 100000 keys or 8 MiB of key bytes");
123
+ }
124
+ return this.indexClient.deleteDocuments({ indexName, primaryKeys }, this.callOptions(timeoutMs));
125
+ }
126
+ /** Stage one deletion; throws on rejection. Call commit to publish. */
127
+ async deleteDocument(indexName, primaryKey, timeoutMs) {
128
+ const result = await this.deleteDocuments(indexName, [primaryKey], timeoutMs);
129
+ if (result.errors.length || result.acceptedCount !== 1) {
130
+ throw new Error(result.errors[0]?.error ?? "deletion was not accepted");
131
+ }
132
+ }
133
+ /** Stage complete replacements (inserts if absent); inspect errors, then commit.
134
+ * Each document needs its primary key; commit publishes its latest accepted
135
+ * replacement, including across calls. This is not a partial patch API.
136
+ */
137
+ async upsertDocuments(indexName, documents, timeoutMs) {
138
+ this.ensureConnected();
139
+ if (documents.length > 1000) {
140
+ throw new Error("upsert request exceeds 1000 documents");
141
+ }
142
+ return this.indexClient.upsertDocuments({
143
+ indexName,
144
+ documents: documents.map((document) => ({ fields: (0, converters_1.toFieldEntries)(document) })),
145
+ }, this.callOptions(timeoutMs));
146
+ }
147
+ /** Stage one complete replacement; throws on rejection. Commit to publish. */
148
+ async upsertDocument(indexName, document, timeoutMs) {
149
+ const result = await this.upsertDocuments(indexName, [document], timeoutMs);
150
+ if (result.errors.length || result.acceptedCount !== 1) {
151
+ throw new Error(result.errors[0]?.error ?? "upsert was not accepted");
152
+ }
153
+ }
154
+ /** Stream documents for indexing. Returns number of indexed documents. */
155
+ async indexDocumentsStream(indexName, documents, timeoutMs) {
156
+ this.ensureConnected();
157
+ async function* requestIterator() {
158
+ for await (const document of documents) {
159
+ yield {
160
+ indexName,
161
+ fields: (0, converters_1.toFieldEntries)(document),
162
+ };
163
+ }
164
+ }
165
+ const response = await this.indexClient.indexDocuments(requestIterator(), this.callOptions(timeoutMs));
166
+ return response.indexedCount;
167
+ }
168
+ /** Commit pending changes. Returns total number of documents. */
169
+ async commit(indexName, timeoutMs) {
170
+ this.ensureConnected();
171
+ const response = await this.indexClient.commit({ indexName }, this.callOptions(timeoutMs));
172
+ return response.numDocs;
173
+ }
174
+ /** Merge segments; compact=true physically removes tombstones from final outputs. */
175
+ async forceMerge(indexName, timeoutMs, compact = false) {
176
+ this.ensureConnected();
177
+ const response = await this.indexClient.forceMerge({ indexName, compact }, this.callOptions(timeoutMs));
178
+ return response.numSegments;
179
+ }
180
+ /** Retrain vector index centroids/codebooks from current data. */
181
+ async retrainVectorIndex(indexName, timeoutMs) {
182
+ this.ensureConnected();
183
+ const response = await this.indexClient.retrainVectorIndex({ indexName }, this.callOptions(timeoutMs));
184
+ return response.success;
185
+ }
186
+ /** Run bounded text, Seismic, and binary ANN layout maintenance. */
187
+ async reorder(indexName, timeoutMs) {
188
+ this.ensureConnected();
189
+ const response = await this.indexClient.reorder({ indexName }, this.callOptions(timeoutMs));
190
+ return response.numSegments;
191
+ }
192
+ /**
193
+ * Search for documents.
194
+ *
195
+ * @example
196
+ * await client.search("articles", {
197
+ * query: { match: { field: "title", text: "search engine" } },
198
+ * fieldsToLoad: ["title"],
199
+ * });
200
+ */
201
+ async search(indexName, request, timeoutMs) {
202
+ if (request.l1 && Object.keys(request.l1).some(key => !["formula", "backfill", "missingValues"].includes(key))) {
203
+ throw new Error("L1 accepts only formula, backfill and missingValues; put coefficients in formula");
204
+ }
205
+ this.ensureConnected();
206
+ const response = await this.searchClient.search({
207
+ indexName,
208
+ query: (0, converters_1.buildQuery)(request.query),
209
+ limit: request.limit ?? 10,
210
+ offset: request.offset ?? 0,
211
+ fieldsToLoad: request.fieldsToLoad ?? [],
212
+ reranker: request.reranker
213
+ ? (0, converters_1.buildReranker)(request.reranker)
214
+ : undefined,
215
+ candidateLimit: request.candidateLimit ?? 0,
216
+ timeBudgetMs: request.timeBudgetMs ?? 0,
217
+ textStats: undefined,
218
+ includeRrfScores: request.includeRrfScores ?? false,
219
+ tracing: request.tracing ?? false,
220
+ l1: request.l1 ? {
221
+ formula: request.l1.formula,
222
+ backfill: request.l1.backfill,
223
+ missingValues: request.l1.missingValues ?? {},
224
+ } : undefined,
225
+ scoreExport: request.scoreExport ? { passagesPerDocument: request.scoreExport.passagesPerDocument ?? 0, allPassages: request.scoreExport.allPassages ?? false, seedDocumentPassages: request.scoreExport.seedDocumentPassages ?? false } : undefined,
226
+ }, this.callOptions(timeoutMs));
227
+ const expectedL1 = "formula_v1";
228
+ if (request.scoreExport?.seedDocumentPassages && !response.seededDocumentPassages) {
229
+ throw new Error("Backend did not acknowledge document passage seeding; upgrade the broker and all backends");
230
+ }
231
+ if (request.l1 && response.rankingMethod !== expectedL1) {
232
+ throw new Error(`L1 requires a backend with ${expectedL1} ranking semantics; received ${JSON.stringify(response.rankingMethod)}`);
233
+ }
234
+ if (request.tracing && !response.trace) {
235
+ throw new Error("Backend omitted requested search trace; upgrade Summa");
236
+ }
237
+ if (request.includeRrfScores && response.hits.some((hit) => hit.rrfScore === undefined)) {
238
+ throw new Error("Backend omitted requested RRF diagnostics; upgrade Summa");
239
+ }
240
+ const hits = response.hits.map((hit) => ({
241
+ address: {
242
+ segmentId: hit.address?.segmentId ?? "",
243
+ docId: hit.address?.docId ?? 0,
244
+ },
245
+ score: hit.score,
246
+ candidateScores: hit.candidateScores,
247
+ rrfScore: hit.rrfScore,
248
+ rrfContributions: hit.rrfContributions,
249
+ fields: Object.fromEntries(Object.entries(hit.fields).map(([name, value]) => [
250
+ name,
251
+ (0, converters_1.fromFieldValueList)(value),
252
+ ])),
253
+ ordinalScores: (hit.ordinalScores ?? []).map((score) => ({
254
+ ordinal: score.ordinal,
255
+ score: score.score,
256
+ })),
257
+ }));
258
+ const timings = response.timings
259
+ ? {
260
+ searchUs: Number(response.timings.searchUs),
261
+ rerankUs: Number(response.timings.rerankUs),
262
+ loadUs: Number(response.timings.loadUs),
263
+ totalUs: Number(response.timings.totalUs),
264
+ candidateScoringUs: Number(response.timings.candidateScoringUs),
265
+ }
266
+ : undefined;
267
+ return {
268
+ hits,
269
+ totalHits: response.totalHits,
270
+ trace: response.trace,
271
+ rankingMethod: response.rankingMethod,
272
+ seededDocumentPassages: response.seededDocumentPassages,
273
+ fusionCandidates: response.fusionCandidates.map(branch => ({ queryIndex: branch.queryIndex,
274
+ candidates: branch.candidates.map(hit => ({ address: { segmentId: hit.address?.segmentId ?? "", docId: hit.address?.docId ?? 0 },
275
+ score: hit.score, ordinalScores: hit.ordinalScores })) })),
276
+ truncated: response.truncated,
277
+ tookMs: response.tookMs,
278
+ timings,
279
+ };
280
+ }
281
+ /** Get a document by address. Returns null if not found. */
282
+ async getDocument(indexName, address, timeoutMs) {
283
+ this.ensureConnected();
284
+ try {
285
+ const response = await this.searchClient.getDocument({
286
+ indexName,
287
+ address: {
288
+ segmentId: address.segmentId,
289
+ docId: address.docId,
290
+ },
291
+ }, this.callOptions(timeoutMs));
292
+ return {
293
+ fields: Object.fromEntries(Object.entries(response.fields).map(([name, value]) => [
294
+ name,
295
+ (0, converters_1.fromFieldValueList)(value),
296
+ ])),
297
+ };
298
+ }
299
+ catch (error) {
300
+ // gRPC NOT_FOUND status code.
301
+ if (typeof error === "object" &&
302
+ error !== null &&
303
+ "code" in error &&
304
+ error.code === 5) {
305
+ return null;
306
+ }
307
+ throw error;
308
+ }
309
+ }
310
+ }
311
+ exports.SummaClient = SummaClient;
312
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Pure conversion helpers between the ergonomic client API and generated
3
+ * protobuf types. Keeping them free of channel state makes them easy to test
4
+ * and keeps SummaClient focused on RPC orchestration.
5
+ */
6
+ import { FieldEntry as PbFieldEntry, FieldValueList as PbFieldValueList, Query as PbQuery, Reranker as PbReranker } from "./generated/summa";
7
+ import type { Query, Reranker } from "./types";
8
+ export declare function buildQuery(q: Query): PbQuery;
9
+ export declare function buildReranker(reranker: Reranker): PbReranker;
10
+ export declare function toFieldEntries(document: Record<string, unknown>): PbFieldEntry[];
11
+ export declare function fromFieldValueList(valueList: PbFieldValueList): unknown;
12
+ //# sourceMappingURL=converters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../src/converters.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEL,UAAU,IAAI,YAAY,EAE1B,cAAc,IAAI,gBAAgB,EAIlC,KAAK,IAAI,OAAO,EAChB,QAAQ,IAAI,UAAU,EAEvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAY,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAiBzD,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,GAAG,OAAO,CAgK5C;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAY5D;AA+CD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,YAAY,EAAE,CAgChB;AA0DD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAGvE"}