@loams/client 0.1.0 → 0.1.2

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.
Files changed (56) hide show
  1. package/README.md +104 -4
  2. package/dist/app.d.ts +149 -0
  3. package/dist/app.js +317 -0
  4. package/dist/builders/filter.d.ts +96 -0
  5. package/dist/builders/filter.js +190 -0
  6. package/dist/builders/schema.d.ts +50 -0
  7. package/dist/builders/schema.js +92 -0
  8. package/dist/builders/search.d.ts +159 -0
  9. package/dist/builders/search.js +307 -0
  10. package/dist/gen/facade.d.ts +267 -2
  11. package/dist/gen/facade.js +194 -0
  12. package/dist/handle.d.ts +67 -0
  13. package/dist/handle.js +107 -0
  14. package/dist/index.d.ts +13 -5
  15. package/dist/index.js +13 -3
  16. package/dist/loams.d.ts +78 -3
  17. package/dist/loams.js +84 -6
  18. package/dist/node.js +1 -1
  19. package/dist/runtime/batch.d.ts +29 -0
  20. package/dist/runtime/batch.js +95 -0
  21. package/dist/runtime/call.d.ts +63 -9
  22. package/dist/runtime/call.js +243 -41
  23. package/dist/runtime/consistency.d.ts +65 -11
  24. package/dist/runtime/consistency.js +212 -46
  25. package/dist/runtime/errors.d.ts +29 -2
  26. package/dist/runtime/errors.js +26 -0
  27. package/dist/runtime/machine-key.d.ts +33 -0
  28. package/dist/runtime/machine-key.js +174 -0
  29. package/dist/runtime/pagination.js +8 -2
  30. package/dist/runtime/subscribe.d.ts +37 -0
  31. package/dist/runtime/subscribe.js +128 -0
  32. package/dist/runtime/token-source.d.ts +1 -1
  33. package/dist/runtime/token-source.js +1 -1
  34. package/dist/runtime/transports.d.ts +22 -1
  35. package/dist/runtime/transports.js +28 -2
  36. package/dist/vendor/proto/collection-v1.d.ts +3 -0
  37. package/dist/vendor/proto/collection-v1.js +7 -0
  38. package/dist/vendor/proto/gen/loams/auth/v1/auth_pb.d.ts +7 -2
  39. package/dist/vendor/proto/gen/loams/auth/v1/auth_pb.js +5 -1
  40. package/dist/vendor/proto/gen/loams/collection/v1/collection_pb.d.ts +1610 -0
  41. package/dist/vendor/proto/gen/loams/collection/v1/collection_pb.js +399 -0
  42. package/dist/vendor/proto/gen/loams/collection/v1/document_pb.d.ts +1054 -0
  43. package/dist/vendor/proto/gen/loams/collection/v1/document_pb.js +327 -0
  44. package/dist/vendor/proto/gen/loams/collection/v1/query_pb.d.ts +2101 -0
  45. package/dist/vendor/proto/gen/loams/collection/v1/query_pb.js +608 -0
  46. package/dist/vendor/proto/gen/loams/graph/v1/graph_pb.d.ts +2299 -0
  47. package/dist/vendor/proto/gen/loams/graph/v1/graph_pb.js +596 -0
  48. package/dist/vendor/proto/gen/loams/instance/v1/instance_pb.d.ts +23 -7
  49. package/dist/vendor/proto/gen/loams/instance/v1/instance_pb.js +20 -5
  50. package/dist/vendor/proto/gen/loams/operations/v1/operations_pb.d.ts +399 -0
  51. package/dist/vendor/proto/gen/loams/operations/v1/operations_pb.js +118 -0
  52. package/dist/vendor/proto/gen/loams/sql/v1/sql_pb.d.ts +182 -0
  53. package/dist/vendor/proto/gen/loams/sql/v1/sql_pb.js +72 -0
  54. package/dist/vendor/proto/gen/loams/stream/v1/stream_pb.d.ts +688 -0
  55. package/dist/vendor/proto/gen/loams/stream/v1/stream_pb.js +180 -0
  56. package/package.json +2 -2
@@ -0,0 +1,96 @@
1
+ import { type JsonObject, type JsonValue } from '@bufbuild/protobuf';
2
+ import { type Query } from '../vendor/proto/gen/loams/collection/v1/query_pb.js';
3
+ /** One filter, as the proto3 JSON of a `loams.collection.v1.Query`. */
4
+ export type FilterJson = JsonObject;
5
+ /** A document id, as a filter or a document call takes it. A `number` must be
6
+ * a safe integer; pass a `bigint` above 2^53. */
7
+ export type DocId = number | bigint | string | {
8
+ uuid: string;
9
+ } | {
10
+ uint: string | number | bigint;
11
+ };
12
+ /** `{"auto": {}}` or an exact number of edits, 0 to 2. */
13
+ export type Fuzziness = 'auto' | 0 | 1 | 2;
14
+ /** A document id as the `Query.ids` `Value` spells it: `{"uint": "1"}`,
15
+ * `{"uuid": "…"}` or a bare string. */
16
+ export declare function idValue(id: DocId): JsonValue;
17
+ /** The bounds of a range: any of `gt`, `gte`, `lt`, `lte`. */
18
+ export interface Bounds {
19
+ gt?: JsonValue;
20
+ gte?: JsonValue;
21
+ lt?: JsonValue;
22
+ lte?: JsonValue;
23
+ }
24
+ /** The options of a `match`. */
25
+ export interface MatchOptions {
26
+ /** `'or'` (the default) or `'and'`. */
27
+ operator?: 'or' | 'and';
28
+ minimumShouldMatch?: string | number;
29
+ fuzziness?: Fuzziness;
30
+ analyzer?: string;
31
+ }
32
+ /** The options of a `query_string`. */
33
+ export interface QueryStringOptions {
34
+ fields?: string[];
35
+ operator?: 'or' | 'and';
36
+ }
37
+ /** The options of a `multi_match`. */
38
+ export interface MultiMatchOptions {
39
+ /** `best_fields` (the default), `most_fields`, `cross_fields`, `phrase`,
40
+ * `phrase_prefix`. */
41
+ kind?: 'best_fields' | 'most_fields' | 'cross_fields' | 'phrase' | 'phrase_prefix';
42
+ operator?: 'or' | 'and';
43
+ tieBreaker?: number;
44
+ }
45
+ /** The filter verbs. */
46
+ export declare const Filter: {
47
+ /** Every document. */
48
+ readonly all: () => FilterJson;
49
+ /** No document. */
50
+ readonly none: () => FilterJson;
51
+ /** The field equals `value` (a term query). */
52
+ readonly eq: (field: string, value: JsonValue) => FilterJson;
53
+ /** The field equals any of `values` (a terms query). */
54
+ readonly in: (field: string, values: JsonValue[]) => FilterJson;
55
+ /** The field is within the bounds; an omitted bound is open. */
56
+ readonly range: (field: string, bounds: Bounds) => FilterJson;
57
+ /** The field is present, whatever its value. */
58
+ readonly exists: (field: string) => FilterJson;
59
+ /** The field is `null` or absent. */
60
+ readonly isNull: (field: string) => FilterJson;
61
+ /** The field is an empty string, list or object. */
62
+ readonly isEmpty: (field: string) => FilterJson;
63
+ /** The field starts with `value`. */
64
+ readonly prefix: (field: string, value: string) => FilterJson;
65
+ /** The field matches a `*`/`?` pattern. */
66
+ readonly wildcard: (field: string, pattern: string) => FilterJson;
67
+ /** The field is within `fuzziness` edits of `value`. */
68
+ readonly fuzzy: (field: string, value: string, edits?: Fuzziness) => FilterJson;
69
+ /** A full-text match on one field. */
70
+ readonly match: (field: string, text: string, options?: MatchOptions) => FilterJson;
71
+ /** The words of `text`, in order, at most `slop` positions apart. */
72
+ readonly phrase: (field: string, text: string, slop?: number) => FilterJson;
73
+ /** A full-text match over several fields; `'title^2'` boosts one. */
74
+ readonly multiMatch: (fields: string[], text: string, options?: MultiMatchOptions) => FilterJson;
75
+ /** The query-string syntax, over `fields` or the collection's defaults. */
76
+ readonly queryString: (query: string, options?: QueryStringOptions) => FilterJson;
77
+ /** The documents with these ids, and no others. */
78
+ readonly ids: (...ids: DocId[]) => FilterJson;
79
+ /** Every query matches (a bool `must`). */
80
+ readonly and: (...queries: FilterJson[]) => FilterJson;
81
+ /** At least one of the queries matches (a bool `should`). */
82
+ readonly or: (...queries: FilterJson[]) => FilterJson;
83
+ /** At least `minimumShouldMatch` of the queries match: `or` with an explicit
84
+ * `minimum_should_match`. */
85
+ readonly anyOf: (queries: FilterJson[], minimumShouldMatch: number | string) => FilterJson;
86
+ /** None of the queries match (a bool `must_not`). */
87
+ readonly not: (...queries: FilterJson[]) => FilterJson;
88
+ /** Every query matches, without scoring (a bool `filter`). */
89
+ readonly filter: (...queries: FilterJson[]) => FilterJson;
90
+ /** Multiplies the query's score by `boost`. */
91
+ readonly boost: (query: FilterJson, boost: number) => FilterJson;
92
+ /** Every match of `query` scores `score`. */
93
+ readonly constantScore: (query: FilterJson, score: number) => FilterJson;
94
+ };
95
+ /** Decodes a filter into the generated `Query` message. */
96
+ export declare function toQuery(filter: FilterJson): Query;
@@ -0,0 +1,190 @@
1
+ // The filter builder (SDKP §2.4): one verb per arm of `loams.collection.v1.Query`.
2
+ //
3
+ // Filter.and(Filter.eq('tags', 'policy'), Filter.range('n', { gte: 2 }))
4
+ //
5
+ // Every verb is a pure function that returns the arm's **proto3 JSON**, which
6
+ // is also how the builder corpus (`sdks/fixtures/builders/*.json`) spells its
7
+ // expectations, so one case is one comparison. `toQuery` decodes it into the
8
+ // generated message when a caller wants the typed form; the search builder and
9
+ // the document calls do that for you.
10
+ //
11
+ // Values are JSON: a string, a number, a bool, `null`, or the IR's tagged
12
+ // objects (`{"date": "<RFC 3339>"}`, `{"uuid": "…"}`).
13
+ import { fromJson } from '@bufbuild/protobuf';
14
+ import { QuerySchema } from '../vendor/proto/gen/loams/collection/v1/query_pb.js';
15
+ function fuzziness(value) {
16
+ return value === 'auto' ? { auto: {} } : { edits: value };
17
+ }
18
+ /** A document id as the `Query.ids` `Value` spells it: `{"uint": "1"}`,
19
+ * `{"uuid": "…"}` or a bare string. */
20
+ export function idValue(id) {
21
+ if (typeof id === 'number') {
22
+ if (!Number.isSafeInteger(id) || id < 0) {
23
+ throw new RangeError(`a numeric document id must be a non-negative safe integer, not ${id}; pass a bigint`);
24
+ }
25
+ return { uint: String(id) };
26
+ }
27
+ if (typeof id === 'bigint') {
28
+ return { uint: id.toString() };
29
+ }
30
+ if (typeof id === 'string') {
31
+ return id;
32
+ }
33
+ if ('uuid' in id) {
34
+ return { uuid: id.uuid };
35
+ }
36
+ return { uint: String(id.uint) };
37
+ }
38
+ function definedBounds(bounds) {
39
+ const out = {};
40
+ for (const key of ['gt', 'gte', 'lt', 'lte']) {
41
+ if (bounds[key] !== undefined) {
42
+ out[key] = bounds[key];
43
+ }
44
+ }
45
+ return out;
46
+ }
47
+ function boolOperator(operator) {
48
+ return operator === 'and' ? 'BOOL_OPERATOR_AND' : 'BOOL_OPERATOR_OR';
49
+ }
50
+ /** A field name and an optional `^boost`, for `multi_match`. */
51
+ function multiMatchField(spec) {
52
+ const at = spec.lastIndexOf('^');
53
+ if (at > 0) {
54
+ const boost = Number(spec.slice(at + 1));
55
+ if (Number.isFinite(boost)) {
56
+ return { field: spec.slice(0, at), boost };
57
+ }
58
+ }
59
+ return { field: spec };
60
+ }
61
+ /** The filter verbs. */
62
+ export const Filter = {
63
+ /** Every document. */
64
+ all() {
65
+ return { matchAll: {} };
66
+ },
67
+ /** No document. */
68
+ none() {
69
+ return { matchNone: {} };
70
+ },
71
+ /** The field equals `value` (a term query). */
72
+ eq(field, value) {
73
+ return { term: { field, value } };
74
+ },
75
+ /** The field equals any of `values` (a terms query). */
76
+ in(field, values) {
77
+ return { terms: { field, values } };
78
+ },
79
+ /** The field is within the bounds; an omitted bound is open. */
80
+ range(field, bounds) {
81
+ return { range: { field, ...definedBounds(bounds) } };
82
+ },
83
+ /** The field is present, whatever its value. */
84
+ exists(field) {
85
+ return { exists: { field } };
86
+ },
87
+ /** The field is `null` or absent. */
88
+ isNull(field) {
89
+ return { isNull: { field } };
90
+ },
91
+ /** The field is an empty string, list or object. */
92
+ isEmpty(field) {
93
+ return { isEmpty: { field } };
94
+ },
95
+ /** The field starts with `value`. */
96
+ prefix(field, value) {
97
+ return { prefix: { field, value } };
98
+ },
99
+ /** The field matches a `*`/`?` pattern. */
100
+ wildcard(field, pattern) {
101
+ return { wildcard: { field, pattern } };
102
+ },
103
+ /** The field is within `fuzziness` edits of `value`. */
104
+ fuzzy(field, value, edits) {
105
+ return { fuzzy: { field, value, ...(edits === undefined ? {} : { fuzziness: fuzziness(edits) }) } };
106
+ },
107
+ /** A full-text match on one field. */
108
+ match(field, text, options = {}) {
109
+ const match = { field, text };
110
+ if (options.operator !== undefined) {
111
+ match.operator = options.operator;
112
+ }
113
+ if (options.minimumShouldMatch !== undefined) {
114
+ match.minimumShouldMatch = String(options.minimumShouldMatch);
115
+ }
116
+ if (options.fuzziness !== undefined) {
117
+ match.fuzziness = fuzziness(options.fuzziness);
118
+ }
119
+ if (options.analyzer !== undefined) {
120
+ match.analyzer = options.analyzer;
121
+ }
122
+ return { match };
123
+ },
124
+ /** The words of `text`, in order, at most `slop` positions apart. */
125
+ phrase(field, text, slop) {
126
+ return { matchPhrase: { field, text, ...(slop === undefined ? {} : { slop }) } };
127
+ },
128
+ /** A full-text match over several fields; `'title^2'` boosts one. */
129
+ multiMatch(fields, text, options = {}) {
130
+ const query = { fields: fields.map(multiMatchField), text };
131
+ if (options.kind !== undefined) {
132
+ query.kind = `MULTI_MATCH_KIND_${options.kind.toUpperCase()}`;
133
+ }
134
+ if (options.operator !== undefined) {
135
+ query.operator = boolOperator(options.operator);
136
+ }
137
+ if (options.tieBreaker !== undefined) {
138
+ query.tieBreaker = options.tieBreaker;
139
+ }
140
+ return { multiMatch: query };
141
+ },
142
+ /** The query-string syntax, over `fields` or the collection's defaults. */
143
+ queryString(query, options = {}) {
144
+ const out = { query };
145
+ if (options.fields !== undefined && options.fields.length > 0) {
146
+ out.defaultFields = options.fields;
147
+ }
148
+ if (options.operator !== undefined) {
149
+ out.defaultOperator = boolOperator(options.operator);
150
+ }
151
+ return { queryString: out };
152
+ },
153
+ /** The documents with these ids, and no others. */
154
+ ids(...ids) {
155
+ return { ids: ids.map(idValue) };
156
+ },
157
+ /** Every query matches (a bool `must`). */
158
+ and(...queries) {
159
+ return { bool: { must: queries } };
160
+ },
161
+ /** At least one of the queries matches (a bool `should`). */
162
+ or(...queries) {
163
+ return { bool: { should: queries } };
164
+ },
165
+ /** At least `minimumShouldMatch` of the queries match: `or` with an explicit
166
+ * `minimum_should_match`. */
167
+ anyOf(queries, minimumShouldMatch) {
168
+ return { bool: { should: queries, minimumShouldMatch: String(minimumShouldMatch) } };
169
+ },
170
+ /** None of the queries match (a bool `must_not`). */
171
+ not(...queries) {
172
+ return { bool: { mustNot: queries } };
173
+ },
174
+ /** Every query matches, without scoring (a bool `filter`). */
175
+ filter(...queries) {
176
+ return { bool: { filter: queries } };
177
+ },
178
+ /** Multiplies the query's score by `boost`. */
179
+ boost(query, boost) {
180
+ return { boost: { query, boost } };
181
+ },
182
+ /** Every match of `query` scores `score`. */
183
+ constantScore(query, score) {
184
+ return { constantScore: { query, score } };
185
+ },
186
+ };
187
+ /** Decodes a filter into the generated `Query` message. */
188
+ export function toQuery(filter) {
189
+ return fromJson(QuerySchema, filter);
190
+ }
@@ -0,0 +1,50 @@
1
+ import type { JsonObject } from '@bufbuild/protobuf';
2
+ /** What every field takes. */
3
+ export interface FieldOptions {
4
+ /** Whether the field is in the inverted index. Default `true`. */
5
+ indexed?: boolean;
6
+ /** Whether the field has a columnar copy for sorting, ranges and
7
+ * aggregations. Default `false` for text and `true` for every other kind. */
8
+ fast?: boolean;
9
+ /** Where the value comes from in `_source`. Default: the field's name. */
10
+ sourcePath?: string;
11
+ }
12
+ /** A text field's options. */
13
+ export interface TextOptions extends FieldOptions {
14
+ /** `standard` (the default), `english`, `simple`, `whitespace` or `keyword`. */
15
+ analyzer?: string;
16
+ /** Whether positions are indexed, which phrase queries need. Default `true`. */
17
+ positions?: boolean;
18
+ }
19
+ /** A dense vector's distance function. */
20
+ export type Distance = 'cosine' | 'dot' | 'euclid' | 'manhattan';
21
+ /** What a write does with a `_source` path no field maps. */
22
+ export type DynamicMapping = 'ignore' | 'strict' | 'map';
23
+ /** The schema builder. Each verb appends and returns the builder. */
24
+ export declare class Schema {
25
+ #private;
26
+ /** A full-text field. */
27
+ text(name: string, options?: TextOptions): this;
28
+ /** An exact-match string field. */
29
+ keyword(name: string, options?: FieldOptions): this;
30
+ /** A signed 64-bit integer field. */
31
+ i64(name: string, options?: FieldOptions): this;
32
+ /** A 64-bit float field. */
33
+ f64(name: string, options?: FieldOptions): this;
34
+ /** A boolean field. */
35
+ bool(name: string, options?: FieldOptions): this;
36
+ /** An RFC 3339 timestamp field (the schema's `date` kind). */
37
+ timestamp(name: string, options?: FieldOptions): this;
38
+ /** A UUID field. */
39
+ uuid(name: string, options?: FieldOptions): this;
40
+ /** A named dense vector of `dim` dimensions. */
41
+ vector(name: string, dim: number, distance?: Distance): this;
42
+ /** A named sparse vector; `idf` reweights the query by IDF at search time. */
43
+ sparseVector(name: string, modifier?: 'none' | 'idf'): this;
44
+ /** What a write does with unmapped `_source` paths. Default `ignore`. */
45
+ dynamic(mode: DynamicMapping): this;
46
+ /** The most fields, vectors and sparse vectors together. Default 1000. */
47
+ maxFields(n: number): this;
48
+ /** The schema `Struct`, as `CreateCollectionRequest.schema` takes it. */
49
+ toJson(): JsonObject;
50
+ }
@@ -0,0 +1,92 @@
1
+ // The schema builder (SDKP §2.6): `CreateCollectionRequest.schema`, a `Struct`
2
+ // in the REST route's schema JSON, without writing the JSON by hand.
3
+ //
4
+ // const schema = new Schema()
5
+ // .text('title').text('body').keyword('tags').i64('n')
6
+ // .vector('embedding', 4);
7
+ // await loams.collections.create({ name: 'notes', schema: schema.toJson() });
8
+ //
9
+ // The output is the shape `crates/loams/tests/connect_collections.rs`
10
+ // `kb_schema()` sends: every field spelled out (`name`, `source_path`, `kind`,
11
+ // `indexed`, `fast`), the vectors and sparse vectors as lists, and `dynamic`
12
+ // and `max_fields` always present, so what the builder sends is what the
13
+ // server stores and nothing rides on a server default.
14
+ /** The schema builder. Each verb appends and returns the builder. */
15
+ export class Schema {
16
+ #fields = [];
17
+ #vectors = [];
18
+ #sparse = [];
19
+ #dynamic = 'ignore';
20
+ #maxFields = 1000;
21
+ #field(name, kind, fastByDefault, options) {
22
+ this.#fields.push({
23
+ name,
24
+ source_path: options.sourcePath ?? name,
25
+ kind,
26
+ indexed: options.indexed ?? true,
27
+ fast: options.fast ?? fastByDefault,
28
+ });
29
+ return this;
30
+ }
31
+ /** A full-text field. */
32
+ text(name, options = {}) {
33
+ return this.#field(name, { text: { analyzer: options.analyzer ?? 'standard', positions: options.positions ?? true } }, false, options);
34
+ }
35
+ /** An exact-match string field. */
36
+ keyword(name, options = {}) {
37
+ return this.#field(name, 'keyword', true, options);
38
+ }
39
+ /** A signed 64-bit integer field. */
40
+ i64(name, options = {}) {
41
+ return this.#field(name, 'i64', true, options);
42
+ }
43
+ /** A 64-bit float field. */
44
+ f64(name, options = {}) {
45
+ return this.#field(name, 'f64', true, options);
46
+ }
47
+ /** A boolean field. */
48
+ bool(name, options = {}) {
49
+ return this.#field(name, 'bool', true, options);
50
+ }
51
+ /** An RFC 3339 timestamp field (the schema's `date` kind). */
52
+ timestamp(name, options = {}) {
53
+ return this.#field(name, 'date', true, options);
54
+ }
55
+ /** A UUID field. */
56
+ uuid(name, options = {}) {
57
+ return this.#field(name, 'uuid', true, options);
58
+ }
59
+ /** A named dense vector of `dim` dimensions. */
60
+ vector(name, dim, distance = 'cosine') {
61
+ if (!Number.isInteger(dim) || dim <= 0) {
62
+ throw new RangeError(`a vector's dim must be a positive integer, not ${dim}`);
63
+ }
64
+ this.#vectors.push({ name, dim, distance });
65
+ return this;
66
+ }
67
+ /** A named sparse vector; `idf` reweights the query by IDF at search time. */
68
+ sparseVector(name, modifier) {
69
+ this.#sparse.push(modifier === undefined ? { name } : { name, modifier });
70
+ return this;
71
+ }
72
+ /** What a write does with unmapped `_source` paths. Default `ignore`. */
73
+ dynamic(mode) {
74
+ this.#dynamic = mode;
75
+ return this;
76
+ }
77
+ /** The most fields, vectors and sparse vectors together. Default 1000. */
78
+ maxFields(n) {
79
+ this.#maxFields = n;
80
+ return this;
81
+ }
82
+ /** The schema `Struct`, as `CreateCollectionRequest.schema` takes it. */
83
+ toJson() {
84
+ return {
85
+ fields: this.#fields.map((field) => ({ ...field })),
86
+ vectors: this.#vectors.map((vector) => ({ ...vector })),
87
+ sparse_vectors: this.#sparse.map((sparse) => ({ ...sparse })),
88
+ dynamic: this.#dynamic,
89
+ max_fields: this.#maxFields,
90
+ };
91
+ }
92
+ }
@@ -0,0 +1,159 @@
1
+ import { type JsonObject, type JsonValue } from '@bufbuild/protobuf';
2
+ import { type Value } from '@bufbuild/protobuf/wkt';
3
+ import { type SearchRequest } from '../vendor/proto/gen/loams/collection/v1/query_pb.js';
4
+ import { ConsistencyToken } from '../runtime/consistency.js';
5
+ import { type FilterJson } from './filter.js';
6
+ /** A fusion, as the proto3 JSON of `loams.collection.v1.Fusion`. */
7
+ export type FusionJson = JsonObject;
8
+ /** Reciprocal-rank fusion; `k` absent is the engine's 60. */
9
+ export declare function rrf(k?: number): FusionJson;
10
+ /** Distance-based score fusion, with the engine's parameters. */
11
+ export declare function dbsf(): FusionJson;
12
+ /** A weighted sum, one weight per retriever in the order they were added. */
13
+ export declare function weighted(...weights: number[]): FusionJson;
14
+ /** The fusions, as one namespace. */
15
+ export declare const Fusion: {
16
+ readonly rrf: typeof rrf;
17
+ readonly dbsf: typeof dbsf;
18
+ readonly weighted: typeof weighted;
19
+ };
20
+ /** One key of the sort, as the proto3 JSON of `SortKey`. */
21
+ export type SortJson = JsonObject;
22
+ type Order = 'asc' | 'desc';
23
+ /** The sort keys. The primary key ascending always breaks ties on the server,
24
+ * but `queryAll` needs it spelled out to page. */
25
+ export declare const Sort: {
26
+ /** By score; descending unless told otherwise. */
27
+ readonly score: (direction?: Order) => SortJson;
28
+ /** By primary key; ascending unless told otherwise. */
29
+ readonly pk: (direction?: Order) => SortJson;
30
+ /** By a fast field. `missing` puts documents without it first or last. */
31
+ readonly field: (name: string, direction?: Order, missing?: "first" | "last") => SortJson;
32
+ };
33
+ /** The options of a text retriever. */
34
+ export interface TextOptions {
35
+ /** One field is a `match`; several are a `multi_match`; none is a
36
+ * `query_string` over the collection's default fields. */
37
+ fields?: string[];
38
+ /** How many candidates the retriever contributes. */
39
+ k?: number;
40
+ }
41
+ /** A vector retriever's options: the candidate count and the ANN knobs. */
42
+ export interface VectorOptions {
43
+ k?: number;
44
+ exact?: boolean;
45
+ nprobes?: number;
46
+ refineFactor?: number;
47
+ ef?: number;
48
+ oversampling?: number;
49
+ /** Overrides the schema's distance for this query. */
50
+ distance?: string;
51
+ /** A pre-filter on this retriever's candidates. */
52
+ filter?: FilterJson;
53
+ }
54
+ /** A sparse retriever's options. */
55
+ export interface SparseOptions {
56
+ k?: number;
57
+ filter?: FilterJson;
58
+ }
59
+ /** What to return of each hit. */
60
+ export interface SelectOptions {
61
+ /** `_source` paths to keep; absent keeps everything. */
62
+ include?: string[];
63
+ /** `_source` paths to drop. */
64
+ exclude?: string[];
65
+ /** `true` returns no `_source` at all. */
66
+ noSource?: boolean;
67
+ /** Vectors to return by name. */
68
+ vectors?: string[];
69
+ /** Fast fields to return by name. */
70
+ fields?: string[];
71
+ }
72
+ /** A highlighted field's options. */
73
+ export interface HighlightOptions {
74
+ pre?: string;
75
+ post?: string;
76
+ fragmentSize?: number;
77
+ fragments?: number;
78
+ }
79
+ /** A graph expansion from the top hits (design §07 §5.2). */
80
+ export interface ExpandOptions {
81
+ /** The source field holding the vertex key. */
82
+ fromField?: string;
83
+ seedLabel?: string;
84
+ seeds?: number;
85
+ hops?: number;
86
+ direction?: 'out' | 'in' | 'both';
87
+ edgeTypes?: string[];
88
+ limitPerSeed?: number;
89
+ limit?: number;
90
+ output?: 'nested' | 'flat';
91
+ }
92
+ /** How fresh the read must be. A token, or its text, is `at_least`. */
93
+ export type ConsistencyLevel = 'strong' | 'eventual' | ConsistencyToken | string;
94
+ /** The proto3 JSON of a `loams.collection.v1.Consistency`. */
95
+ export declare function consistencyJson(level: ConsistencyLevel): JsonObject;
96
+ /** A hit's sort value, as `Hit.sort_values` answers it or as JSON. */
97
+ export type SortValue = JsonValue | Value;
98
+ /** The search builder. */
99
+ export declare class Search {
100
+ #private;
101
+ private constructor();
102
+ /** A search of `collection` (a name or an alias). */
103
+ static on(collection: string, options?: {
104
+ namespace?: string;
105
+ }): Search;
106
+ /** A builder over an existing request's proto3 JSON. */
107
+ static fromJson(json: JsonObject): Search;
108
+ /** The namespace, when it is not the client's default. */
109
+ namespace(namespace: string): Search;
110
+ /** A text retriever. A string is a `match`/`multi_match`/`query_string`
111
+ * by `fields`; a `Filter` (`match`, `multiMatch`, `phrase`…) is used as is. */
112
+ text(text: string | FilterJson, options?: TextOptions): Search;
113
+ /** A dense-vector kNN retriever on `field`. */
114
+ vector(field: string, values: readonly number[], options?: VectorOptions): Search;
115
+ /** A sparse-vector retriever: `{indices, values}`, or a term-to-weight map
116
+ * whose keys are the indices. */
117
+ sparse(field: string, terms: {
118
+ indices: number[];
119
+ values: number[];
120
+ } | Record<number, number>, options?: SparseOptions): Search;
121
+ /** How the retrievers' ranked lists combine: `rrf()`, `dbsf()` or
122
+ * `weighted(…)`. */
123
+ fuse(fusion: FusionJson): Search;
124
+ /** The filter every candidate must match. */
125
+ filter(filter: FilterJson): Search;
126
+ /** The sort, replacing any earlier one. */
127
+ sort(...keys: SortJson[]): Search;
128
+ /** The window size; the engine's default is 10. */
129
+ limit(limit: number): Search;
130
+ /** How many hits to skip before the window. */
131
+ offset(offset: number): Search;
132
+ /** The page after the hit whose `sortValues` these are. */
133
+ after(sortValues: readonly SortValue[]): Search;
134
+ /** Drops hits scoring below `score`. */
135
+ minScore(score: number): Search;
136
+ /** What to return of each hit. */
137
+ select(options: SelectOptions): Search;
138
+ /** Highlights `field` in each hit; call once per field. */
139
+ highlight(field: string, options?: HighlightOptions): Search;
140
+ /** Groups the hits by `field`: `size` hits per group, `limit` groups. */
141
+ groupBy(field: string, options?: {
142
+ size?: number;
143
+ limit?: number;
144
+ }): Search;
145
+ /** Walks `graph` from the top hits and returns their neighbours. */
146
+ expand(graph: string, options?: ExpandOptions): Search;
147
+ /** How fresh the read must be. */
148
+ consistency(level: ConsistencyLevel): Search;
149
+ /** The collection searched. */
150
+ get collection(): string;
151
+ /** Whether the sort ends in a primary-key tiebreaker, which `queryAll`
152
+ * needs to page without skipping or repeating a hit. */
153
+ get hasTiebreak(): boolean;
154
+ /** The request's proto3 JSON. */
155
+ toJson(): JsonObject;
156
+ /** The request as the generated message, checked. */
157
+ build(): SearchRequest;
158
+ }
159
+ export {};