@duckedup/nidus 0.1.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.
@@ -0,0 +1,285 @@
1
+ /**
2
+ * A typed attribute value, externally tagged exactly as `nidus` serde-encodes
3
+ * `Value` on the wire: `{ Str }`, `{ Int }`, `{ Bool }`, `{ List }`, or the bare
4
+ * string `"Null"`.
5
+ *
6
+ * `Null` is distinct from an absent key: absence means "not set / not indexed",
7
+ * `Null` means "set, and empty/none".
8
+ */
9
+ type Value = {
10
+ Str: string;
11
+ } | {
12
+ Int: number;
13
+ } | {
14
+ Bool: boolean;
15
+ } | {
16
+ List: string[];
17
+ } | "Null";
18
+ /**
19
+ * What callers may pass anywhere a {@link Value} is expected: either an
20
+ * explicitly-tagged `Value` (from the `v.*` helpers) or a plain JS scalar that
21
+ * the SDK normalizes — `string → Str`, `boolean → Bool`, integer `number → Int`,
22
+ * `string[] → List`, `null → Null`. A non-integer number throws (the store has no
23
+ * float attribute type; floats belong in the vector, not in attrs).
24
+ */
25
+ type AttrInput = Value | string | number | boolean | string[] | null;
26
+ /** A document: caller-supplied `id`, an optional embedding, and typed metadata. */
27
+ interface NidusRecord {
28
+ id: string;
29
+ /** Omit for a text-only doc (indexed by FTS/metadata only, never by vector search). */
30
+ vector?: number[];
31
+ attrs: Record<string, Value>;
32
+ }
33
+ /** Like {@link NidusRecord} but accepts plain JS values in `attrs` (auto-normalized). */
34
+ interface RecordInput {
35
+ id: string;
36
+ vector?: number[];
37
+ attrs: Record<string, AttrInput>;
38
+ }
39
+ /** A record read back from the server, with `attrs` decoded to plain JS values. */
40
+ interface DecodedRecord {
41
+ id: string;
42
+ vector?: number[];
43
+ attrs: Record<string, DecodedValue>;
44
+ }
45
+ /** A single attribute predicate, externally tagged as `nidus` encodes `Predicate`. */
46
+ type Predicate = {
47
+ Eq: [string, Value];
48
+ } | {
49
+ Ne: [string, Value];
50
+ } | {
51
+ Glob: [string, string];
52
+ } | {
53
+ In: [string, Value[]];
54
+ } | {
55
+ NotIn: [string, Value[]];
56
+ } | {
57
+ Lt: [string, Value];
58
+ } | {
59
+ Le: [string, Value];
60
+ } | {
61
+ Gt: [string, Value];
62
+ } | {
63
+ Ge: [string, Value];
64
+ };
65
+ /**
66
+ * A conjunction (AND) of predicates. On the wire `Filter` is a newtype over
67
+ * `Vec<Predicate>`, so it serializes as a bare array — an empty array matches
68
+ * everything.
69
+ */
70
+ type Filter = Predicate[];
71
+ /** A search/list result row, decoded so `attrs` holds plain JS values. */
72
+ interface Hit {
73
+ collection: string;
74
+ id: string;
75
+ score: number;
76
+ attrs: Record<string, DecodedValue>;
77
+ }
78
+ /** A {@link Value} decoded back to a plain JS value. */
79
+ type DecodedValue = string | number | boolean | string[] | null;
80
+ /** On-disk footprint, mirroring `FootprintDto`. */
81
+ interface Footprint {
82
+ rows: number;
83
+ dead_rows: number;
84
+ dimension: number;
85
+ vector_bytes: number;
86
+ doc_count: number;
87
+ }
88
+ /** Active ANN-index configuration, mirroring `AnnDto` (`null` when exact search). */
89
+ interface AnnInfo {
90
+ kind: string;
91
+ overscan: number;
92
+ seed: number;
93
+ m?: number;
94
+ ef_construction?: number;
95
+ ef_search?: number;
96
+ n_lists?: number;
97
+ n_probe?: number;
98
+ }
99
+ /** Store-wide introspection, mirroring the `/stats` response. */
100
+ interface Stats {
101
+ dimension: number;
102
+ distance: string;
103
+ ann: AnnInfo | null;
104
+ collections: string[];
105
+ footprint: Footprint;
106
+ }
107
+ /** Options for {@link NidusClient.search}. An empty/omitted `scope` searches every collection. */
108
+ interface SearchOptions {
109
+ query: number[];
110
+ scope?: string[];
111
+ topK?: number;
112
+ minScore?: number;
113
+ filter?: Filter;
114
+ }
115
+ /** Options for {@link NidusClient.textSearch} (BM25). */
116
+ interface TextSearchOptions {
117
+ field: string;
118
+ query: string;
119
+ scope?: string[];
120
+ topK?: number;
121
+ /** A raw BM25 score floor (not cosine). */
122
+ minScore?: number;
123
+ filter?: Filter;
124
+ }
125
+ /** Options for {@link NidusClient.hybridSearch} (vector + BM25 fused via RRF). */
126
+ interface HybridSearchOptions {
127
+ vector: number[];
128
+ field: string;
129
+ text: string;
130
+ scope?: string[];
131
+ topK?: number;
132
+ filter?: Filter;
133
+ rrfK?: number;
134
+ candidates?: number;
135
+ }
136
+ /** Options for {@link NidusClient.list} (metadata-only, paginated). */
137
+ interface ListOptions {
138
+ scope?: string[];
139
+ offset?: number;
140
+ limit?: number;
141
+ filter?: Filter;
142
+ }
143
+
144
+ /** Minimal `fetch` signature the client needs — satisfied by the platform global. */
145
+ type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
146
+ /** Construction options for {@link NidusClient}. */
147
+ interface NidusClientOptions {
148
+ /** Base URL of the server, e.g. `http://127.0.0.1:7700`. Trailing slash optional. */
149
+ baseUrl: string;
150
+ /** Bearer token, when the server was started with `--token`. */
151
+ token?: string;
152
+ /** Override the `fetch` implementation (defaults to `globalThis.fetch`). */
153
+ fetch?: FetchLike;
154
+ /** Per-request timeout in milliseconds. Omit (or `0`) to disable. */
155
+ timeoutMs?: number;
156
+ /** Extra headers sent on every request. */
157
+ headers?: Record<string, string>;
158
+ }
159
+ declare class NidusClient {
160
+ private readonly baseUrl;
161
+ private readonly token?;
162
+ private readonly doFetch;
163
+ private readonly timeoutMs;
164
+ private readonly extraHeaders;
165
+ constructor(options: NidusClientOptions);
166
+ /** Liveness check. Returns `true` when the server answers `/health`. */
167
+ health(): Promise<boolean>;
168
+ /** Store-wide introspection: dimension, distance, ANN config, collections, footprint. */
169
+ stats(): Promise<Stats>;
170
+ /** List every collection name. */
171
+ collections(): Promise<string[]>;
172
+ /** Create a collection. Idempotent on the server side. */
173
+ createCollection(name: string): Promise<void>;
174
+ /** Drop a collection and all its records. */
175
+ dropCollection(name: string): Promise<void>;
176
+ /** Read a collection's free-form string metadata. */
177
+ getMeta(name: string): Promise<Record<string, string>>;
178
+ /** Replace a collection's free-form string metadata. */
179
+ setMeta(name: string, meta: Record<string, string>): Promise<void>;
180
+ /**
181
+ * Insert or replace records (idempotent on `id` within the collection).
182
+ * `attrs` accept plain JS values or `v.*` helpers; they are normalized for you.
183
+ * Returns the number of records upserted.
184
+ */
185
+ upsert(name: string, records: RecordInput[]): Promise<number>;
186
+ /** Delete records by id. Returns the number deleted. */
187
+ delete(name: string, opts: {
188
+ ids: string[];
189
+ }): Promise<number>;
190
+ /** Delete every record matching `filter`. Returns the number deleted. */
191
+ deleteWhere(name: string, filter: Filter): Promise<number>;
192
+ /** Fetch every record in a collection (attrs decoded to plain JS values). */
193
+ records(name: string): Promise<DecodedRecord[]>;
194
+ /** Declare the full-text-indexed attribute fields for a collection. */
195
+ setFtsSchema(name: string, fields: string[]): Promise<void>;
196
+ /** Vector (cosine) nearest-neighbour search. Empty `scope` searches all collections. */
197
+ search(opts: SearchOptions): Promise<Hit[]>;
198
+ /** BM25 full-text search over one indexed field. */
199
+ textSearch(opts: TextSearchOptions): Promise<Hit[]>;
200
+ /** Hybrid search: fuse a vector query and a BM25 text query via RRF. */
201
+ hybridSearch(opts: HybridSearchOptions): Promise<Hit[]>;
202
+ /** Metadata-only listing (no vector), paginated by `offset`/`limit`. */
203
+ list(opts?: ListOptions): Promise<Hit[]>;
204
+ /** Force a durability flush. */
205
+ flush(): Promise<void>;
206
+ /** Compact the store (reclaim space from deleted/overwritten rows). */
207
+ compact(): Promise<void>;
208
+ /** Run a search-family request and decode the resulting hits' attrs. */
209
+ private searchRequest;
210
+ /** Issue a request and parse a JSON body, mapping a non-2xx to {@link NidusError}. */
211
+ private request;
212
+ /** The bare transport: headers, auth, timeout, and transport-error mapping. */
213
+ private raw;
214
+ }
215
+
216
+ /** An error returned by a `nidus` server, or a transport failure reaching it. */
217
+ declare class NidusError extends Error {
218
+ /** The HTTP status code, or `0` for a transport/timeout failure (no response). */
219
+ readonly status: number;
220
+ constructor(message: string, status: number);
221
+ /** A malformed request the server rejected (HTTP 400). */
222
+ get isBadRequest(): boolean;
223
+ /** The store is read-only (HTTP 403). */
224
+ get isReadOnly(): boolean;
225
+ /** The writer lock is held by another process (HTTP 409). */
226
+ get isLocked(): boolean;
227
+ /** Out of capacity: `max_vector_bytes` exceeded or OOM (HTTP 507). */
228
+ get isOutOfCapacity(): boolean;
229
+ }
230
+
231
+ /**
232
+ * Predicate constructors. Each accepts a plain JS value (auto-normalized) or an
233
+ * explicit `v.*` {@link Value}. Combine results into a {@link Filter} array, or
234
+ * use {@link f.and} for readability.
235
+ */
236
+ declare const f: {
237
+ /** `attrs[key] === value`. */
238
+ readonly eq: (key: string, value: AttrInput) => Predicate;
239
+ /** `attrs[key]` is present and `!== value`. */
240
+ readonly ne: (key: string, value: AttrInput) => Predicate;
241
+ /** `attrs[key]` is a `Str` matching the glob pattern (`*`, `?`, `[..]`). */
242
+ readonly glob: (key: string, pattern: string) => Predicate;
243
+ /** `attrs[key]` equals one of `values`. */
244
+ readonly in: (key: string, values: AttrInput[]) => Predicate;
245
+ /** `attrs[key]` is present and equals none of `values`. */
246
+ readonly notIn: (key: string, values: AttrInput[]) => Predicate;
247
+ /** `attrs[key] < value` (same-type, orderable). */
248
+ readonly lt: (key: string, value: AttrInput) => Predicate;
249
+ /** `attrs[key] <= value` (same-type, orderable). */
250
+ readonly le: (key: string, value: AttrInput) => Predicate;
251
+ /** `attrs[key] > value` (same-type, orderable). */
252
+ readonly gt: (key: string, value: AttrInput) => Predicate;
253
+ /** `attrs[key] >= value` (same-type, orderable). */
254
+ readonly ge: (key: string, value: AttrInput) => Predicate;
255
+ /** Collect predicates into a {@link Filter} (purely sugar — they already AND). */
256
+ readonly and: (...preds: Predicate[]) => Filter;
257
+ };
258
+
259
+ /**
260
+ * Value constructors mirroring the `Value` variants. `v.int` requires a safe
261
+ * integer (the store's attribute integer is an `i64`; a non-integer would be a
262
+ * silent type error since there is no float attribute).
263
+ */
264
+ declare const v: {
265
+ readonly str: (s: string) => Value;
266
+ readonly int: (n: number) => Value;
267
+ readonly bool: (b: boolean) => Value;
268
+ readonly list: (items: string[]) => Value;
269
+ /** The explicit `Null` value — set-but-empty, distinct from an absent key. */
270
+ readonly nil: () => Value;
271
+ };
272
+ /**
273
+ * Normalize a caller-supplied {@link AttrInput} into the wire {@link Value} shape.
274
+ * Plain scalars map by type; an already-tagged `Value` passes through unchanged.
275
+ * Throws on a non-integer number or a non-string list element.
276
+ */
277
+ declare function encodeValue(input: AttrInput): Value;
278
+ /** Normalize a whole `attrs` map of {@link AttrInput} into wire {@link Value}s. */
279
+ declare function encodeAttrs(attrs: Record<string, AttrInput>): Record<string, Value>;
280
+ /** Decode a wire {@link Value} back to a plain JS value. */
281
+ declare function decodeValue(value: Value): DecodedValue;
282
+ /** Decode a whole wire `attrs` map back to plain JS values. */
283
+ declare function decodeAttrs(attrs: Record<string, Value>): Record<string, DecodedValue>;
284
+
285
+ export { type AnnInfo, type AttrInput, type DecodedRecord, type DecodedValue, type FetchLike, type Filter, type Footprint, type Hit, type HybridSearchOptions, type ListOptions, NidusClient, type NidusClientOptions, NidusError, type NidusRecord, type Predicate, type RecordInput, type SearchOptions, type Stats, type TextSearchOptions, type Value, decodeAttrs, decodeValue, encodeAttrs, encodeValue, f, v };
@@ -0,0 +1,285 @@
1
+ /**
2
+ * A typed attribute value, externally tagged exactly as `nidus` serde-encodes
3
+ * `Value` on the wire: `{ Str }`, `{ Int }`, `{ Bool }`, `{ List }`, or the bare
4
+ * string `"Null"`.
5
+ *
6
+ * `Null` is distinct from an absent key: absence means "not set / not indexed",
7
+ * `Null` means "set, and empty/none".
8
+ */
9
+ type Value = {
10
+ Str: string;
11
+ } | {
12
+ Int: number;
13
+ } | {
14
+ Bool: boolean;
15
+ } | {
16
+ List: string[];
17
+ } | "Null";
18
+ /**
19
+ * What callers may pass anywhere a {@link Value} is expected: either an
20
+ * explicitly-tagged `Value` (from the `v.*` helpers) or a plain JS scalar that
21
+ * the SDK normalizes — `string → Str`, `boolean → Bool`, integer `number → Int`,
22
+ * `string[] → List`, `null → Null`. A non-integer number throws (the store has no
23
+ * float attribute type; floats belong in the vector, not in attrs).
24
+ */
25
+ type AttrInput = Value | string | number | boolean | string[] | null;
26
+ /** A document: caller-supplied `id`, an optional embedding, and typed metadata. */
27
+ interface NidusRecord {
28
+ id: string;
29
+ /** Omit for a text-only doc (indexed by FTS/metadata only, never by vector search). */
30
+ vector?: number[];
31
+ attrs: Record<string, Value>;
32
+ }
33
+ /** Like {@link NidusRecord} but accepts plain JS values in `attrs` (auto-normalized). */
34
+ interface RecordInput {
35
+ id: string;
36
+ vector?: number[];
37
+ attrs: Record<string, AttrInput>;
38
+ }
39
+ /** A record read back from the server, with `attrs` decoded to plain JS values. */
40
+ interface DecodedRecord {
41
+ id: string;
42
+ vector?: number[];
43
+ attrs: Record<string, DecodedValue>;
44
+ }
45
+ /** A single attribute predicate, externally tagged as `nidus` encodes `Predicate`. */
46
+ type Predicate = {
47
+ Eq: [string, Value];
48
+ } | {
49
+ Ne: [string, Value];
50
+ } | {
51
+ Glob: [string, string];
52
+ } | {
53
+ In: [string, Value[]];
54
+ } | {
55
+ NotIn: [string, Value[]];
56
+ } | {
57
+ Lt: [string, Value];
58
+ } | {
59
+ Le: [string, Value];
60
+ } | {
61
+ Gt: [string, Value];
62
+ } | {
63
+ Ge: [string, Value];
64
+ };
65
+ /**
66
+ * A conjunction (AND) of predicates. On the wire `Filter` is a newtype over
67
+ * `Vec<Predicate>`, so it serializes as a bare array — an empty array matches
68
+ * everything.
69
+ */
70
+ type Filter = Predicate[];
71
+ /** A search/list result row, decoded so `attrs` holds plain JS values. */
72
+ interface Hit {
73
+ collection: string;
74
+ id: string;
75
+ score: number;
76
+ attrs: Record<string, DecodedValue>;
77
+ }
78
+ /** A {@link Value} decoded back to a plain JS value. */
79
+ type DecodedValue = string | number | boolean | string[] | null;
80
+ /** On-disk footprint, mirroring `FootprintDto`. */
81
+ interface Footprint {
82
+ rows: number;
83
+ dead_rows: number;
84
+ dimension: number;
85
+ vector_bytes: number;
86
+ doc_count: number;
87
+ }
88
+ /** Active ANN-index configuration, mirroring `AnnDto` (`null` when exact search). */
89
+ interface AnnInfo {
90
+ kind: string;
91
+ overscan: number;
92
+ seed: number;
93
+ m?: number;
94
+ ef_construction?: number;
95
+ ef_search?: number;
96
+ n_lists?: number;
97
+ n_probe?: number;
98
+ }
99
+ /** Store-wide introspection, mirroring the `/stats` response. */
100
+ interface Stats {
101
+ dimension: number;
102
+ distance: string;
103
+ ann: AnnInfo | null;
104
+ collections: string[];
105
+ footprint: Footprint;
106
+ }
107
+ /** Options for {@link NidusClient.search}. An empty/omitted `scope` searches every collection. */
108
+ interface SearchOptions {
109
+ query: number[];
110
+ scope?: string[];
111
+ topK?: number;
112
+ minScore?: number;
113
+ filter?: Filter;
114
+ }
115
+ /** Options for {@link NidusClient.textSearch} (BM25). */
116
+ interface TextSearchOptions {
117
+ field: string;
118
+ query: string;
119
+ scope?: string[];
120
+ topK?: number;
121
+ /** A raw BM25 score floor (not cosine). */
122
+ minScore?: number;
123
+ filter?: Filter;
124
+ }
125
+ /** Options for {@link NidusClient.hybridSearch} (vector + BM25 fused via RRF). */
126
+ interface HybridSearchOptions {
127
+ vector: number[];
128
+ field: string;
129
+ text: string;
130
+ scope?: string[];
131
+ topK?: number;
132
+ filter?: Filter;
133
+ rrfK?: number;
134
+ candidates?: number;
135
+ }
136
+ /** Options for {@link NidusClient.list} (metadata-only, paginated). */
137
+ interface ListOptions {
138
+ scope?: string[];
139
+ offset?: number;
140
+ limit?: number;
141
+ filter?: Filter;
142
+ }
143
+
144
+ /** Minimal `fetch` signature the client needs — satisfied by the platform global. */
145
+ type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
146
+ /** Construction options for {@link NidusClient}. */
147
+ interface NidusClientOptions {
148
+ /** Base URL of the server, e.g. `http://127.0.0.1:7700`. Trailing slash optional. */
149
+ baseUrl: string;
150
+ /** Bearer token, when the server was started with `--token`. */
151
+ token?: string;
152
+ /** Override the `fetch` implementation (defaults to `globalThis.fetch`). */
153
+ fetch?: FetchLike;
154
+ /** Per-request timeout in milliseconds. Omit (or `0`) to disable. */
155
+ timeoutMs?: number;
156
+ /** Extra headers sent on every request. */
157
+ headers?: Record<string, string>;
158
+ }
159
+ declare class NidusClient {
160
+ private readonly baseUrl;
161
+ private readonly token?;
162
+ private readonly doFetch;
163
+ private readonly timeoutMs;
164
+ private readonly extraHeaders;
165
+ constructor(options: NidusClientOptions);
166
+ /** Liveness check. Returns `true` when the server answers `/health`. */
167
+ health(): Promise<boolean>;
168
+ /** Store-wide introspection: dimension, distance, ANN config, collections, footprint. */
169
+ stats(): Promise<Stats>;
170
+ /** List every collection name. */
171
+ collections(): Promise<string[]>;
172
+ /** Create a collection. Idempotent on the server side. */
173
+ createCollection(name: string): Promise<void>;
174
+ /** Drop a collection and all its records. */
175
+ dropCollection(name: string): Promise<void>;
176
+ /** Read a collection's free-form string metadata. */
177
+ getMeta(name: string): Promise<Record<string, string>>;
178
+ /** Replace a collection's free-form string metadata. */
179
+ setMeta(name: string, meta: Record<string, string>): Promise<void>;
180
+ /**
181
+ * Insert or replace records (idempotent on `id` within the collection).
182
+ * `attrs` accept plain JS values or `v.*` helpers; they are normalized for you.
183
+ * Returns the number of records upserted.
184
+ */
185
+ upsert(name: string, records: RecordInput[]): Promise<number>;
186
+ /** Delete records by id. Returns the number deleted. */
187
+ delete(name: string, opts: {
188
+ ids: string[];
189
+ }): Promise<number>;
190
+ /** Delete every record matching `filter`. Returns the number deleted. */
191
+ deleteWhere(name: string, filter: Filter): Promise<number>;
192
+ /** Fetch every record in a collection (attrs decoded to plain JS values). */
193
+ records(name: string): Promise<DecodedRecord[]>;
194
+ /** Declare the full-text-indexed attribute fields for a collection. */
195
+ setFtsSchema(name: string, fields: string[]): Promise<void>;
196
+ /** Vector (cosine) nearest-neighbour search. Empty `scope` searches all collections. */
197
+ search(opts: SearchOptions): Promise<Hit[]>;
198
+ /** BM25 full-text search over one indexed field. */
199
+ textSearch(opts: TextSearchOptions): Promise<Hit[]>;
200
+ /** Hybrid search: fuse a vector query and a BM25 text query via RRF. */
201
+ hybridSearch(opts: HybridSearchOptions): Promise<Hit[]>;
202
+ /** Metadata-only listing (no vector), paginated by `offset`/`limit`. */
203
+ list(opts?: ListOptions): Promise<Hit[]>;
204
+ /** Force a durability flush. */
205
+ flush(): Promise<void>;
206
+ /** Compact the store (reclaim space from deleted/overwritten rows). */
207
+ compact(): Promise<void>;
208
+ /** Run a search-family request and decode the resulting hits' attrs. */
209
+ private searchRequest;
210
+ /** Issue a request and parse a JSON body, mapping a non-2xx to {@link NidusError}. */
211
+ private request;
212
+ /** The bare transport: headers, auth, timeout, and transport-error mapping. */
213
+ private raw;
214
+ }
215
+
216
+ /** An error returned by a `nidus` server, or a transport failure reaching it. */
217
+ declare class NidusError extends Error {
218
+ /** The HTTP status code, or `0` for a transport/timeout failure (no response). */
219
+ readonly status: number;
220
+ constructor(message: string, status: number);
221
+ /** A malformed request the server rejected (HTTP 400). */
222
+ get isBadRequest(): boolean;
223
+ /** The store is read-only (HTTP 403). */
224
+ get isReadOnly(): boolean;
225
+ /** The writer lock is held by another process (HTTP 409). */
226
+ get isLocked(): boolean;
227
+ /** Out of capacity: `max_vector_bytes` exceeded or OOM (HTTP 507). */
228
+ get isOutOfCapacity(): boolean;
229
+ }
230
+
231
+ /**
232
+ * Predicate constructors. Each accepts a plain JS value (auto-normalized) or an
233
+ * explicit `v.*` {@link Value}. Combine results into a {@link Filter} array, or
234
+ * use {@link f.and} for readability.
235
+ */
236
+ declare const f: {
237
+ /** `attrs[key] === value`. */
238
+ readonly eq: (key: string, value: AttrInput) => Predicate;
239
+ /** `attrs[key]` is present and `!== value`. */
240
+ readonly ne: (key: string, value: AttrInput) => Predicate;
241
+ /** `attrs[key]` is a `Str` matching the glob pattern (`*`, `?`, `[..]`). */
242
+ readonly glob: (key: string, pattern: string) => Predicate;
243
+ /** `attrs[key]` equals one of `values`. */
244
+ readonly in: (key: string, values: AttrInput[]) => Predicate;
245
+ /** `attrs[key]` is present and equals none of `values`. */
246
+ readonly notIn: (key: string, values: AttrInput[]) => Predicate;
247
+ /** `attrs[key] < value` (same-type, orderable). */
248
+ readonly lt: (key: string, value: AttrInput) => Predicate;
249
+ /** `attrs[key] <= value` (same-type, orderable). */
250
+ readonly le: (key: string, value: AttrInput) => Predicate;
251
+ /** `attrs[key] > value` (same-type, orderable). */
252
+ readonly gt: (key: string, value: AttrInput) => Predicate;
253
+ /** `attrs[key] >= value` (same-type, orderable). */
254
+ readonly ge: (key: string, value: AttrInput) => Predicate;
255
+ /** Collect predicates into a {@link Filter} (purely sugar — they already AND). */
256
+ readonly and: (...preds: Predicate[]) => Filter;
257
+ };
258
+
259
+ /**
260
+ * Value constructors mirroring the `Value` variants. `v.int` requires a safe
261
+ * integer (the store's attribute integer is an `i64`; a non-integer would be a
262
+ * silent type error since there is no float attribute).
263
+ */
264
+ declare const v: {
265
+ readonly str: (s: string) => Value;
266
+ readonly int: (n: number) => Value;
267
+ readonly bool: (b: boolean) => Value;
268
+ readonly list: (items: string[]) => Value;
269
+ /** The explicit `Null` value — set-but-empty, distinct from an absent key. */
270
+ readonly nil: () => Value;
271
+ };
272
+ /**
273
+ * Normalize a caller-supplied {@link AttrInput} into the wire {@link Value} shape.
274
+ * Plain scalars map by type; an already-tagged `Value` passes through unchanged.
275
+ * Throws on a non-integer number or a non-string list element.
276
+ */
277
+ declare function encodeValue(input: AttrInput): Value;
278
+ /** Normalize a whole `attrs` map of {@link AttrInput} into wire {@link Value}s. */
279
+ declare function encodeAttrs(attrs: Record<string, AttrInput>): Record<string, Value>;
280
+ /** Decode a wire {@link Value} back to a plain JS value. */
281
+ declare function decodeValue(value: Value): DecodedValue;
282
+ /** Decode a whole wire `attrs` map back to plain JS values. */
283
+ declare function decodeAttrs(attrs: Record<string, Value>): Record<string, DecodedValue>;
284
+
285
+ export { type AnnInfo, type AttrInput, type DecodedRecord, type DecodedValue, type FetchLike, type Filter, type Footprint, type Hit, type HybridSearchOptions, type ListOptions, NidusClient, type NidusClientOptions, NidusError, type NidusRecord, type Predicate, type RecordInput, type SearchOptions, type Stats, type TextSearchOptions, type Value, decodeAttrs, decodeValue, encodeAttrs, encodeValue, f, v };