@infino-ai/infino 0.1.1 → 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.
package/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # infino
2
2
 
3
+ [![npm](https://img.shields.io/npm/v/@infino-ai/infino.svg)](https://www.npmjs.com/package/@infino-ai/infino)
4
+ [![Node](https://img.shields.io/node/v/@infino-ai/infino.svg)](https://www.npmjs.com/package/@infino-ai/infino)
5
+ [![Downloads](https://img.shields.io/npm/dm/@infino-ai/infino.svg)](https://www.npmjs.com/package/@infino-ai/infino)
6
+ [![License](https://img.shields.io/npm/l/@infino-ai/infino.svg)](https://www.apache.org/licenses/LICENSE-2.0)
7
+
3
8
  **SQL, full-text, and vector search over your data on object storage — one engine, no server to run.**
4
9
 
5
10
  Infino keeps your data in Apache Parquet on object storage (local disk, Amazon
@@ -9,14 +14,9 @@ and vector indexes embedded directly inside it; a table composes many such files
9
14
  with snapshot-isolated reads, append-only writes, and atomic commits. It runs in
10
15
  your process — there is no daemon, no cluster, and no managed service to operate.
11
16
 
12
- Use it for **RAG**, **agent memory**, **hybrid search**, and **semantic search**:
13
- it's an embedded **vector database**, **full-text (BM25)** search engine, and
14
- **SQL** query engine in one library — no separate vector database or search
15
- server to run.
16
-
17
- Synchronous, Arrow at the boundary: pass arrays of objects (or apache-arrow
18
- `Table`s) in, get plain records out; pass `{ arrow: true }` to a search or query
19
- for an apache-arrow `Table` instead.
17
+ Use it for **RAG**, **agent memory**, **hybrid search**, and **semantic
18
+ search**: an embedded **vector database**, **full-text (BM25)** search engine,
19
+ and **SQL** query engine in one library.
20
20
 
21
21
  ## Install
22
22
 
@@ -33,8 +33,8 @@ toolchain required. Supported platforms:
33
33
  | Linux (glibc) | x64, arm64 |
34
34
  | Linux (musl / Alpine) | x64, arm64 |
35
35
 
36
- `apache-arrow` is installed as a dependency and used at the boundary (passing in
37
- `Table`s, or `{ arrow: true }` results). Requires Node.js >= 18.
36
+ Requires Node.js >= 18. `apache-arrow` is installed as a dependency and used at
37
+ the boundary (passing in `Table`s, or `{ arrow: true }` results).
38
38
 
39
39
  ## Quickstart
40
40
 
@@ -64,316 +64,45 @@ docs.append([
64
64
  { source: "blog", body: "Enable dark mode under Settings then Appearance.", embedding: embed(1) },
65
65
  ]);
66
66
 
67
- // Three ways to retrieve context to ground an agent's next answer:
68
- const keyword = docs.bm25Search("body", "cancel subscription", 5); // BM25
69
- const semantic = docs.vectorSearch("embedding", embed(0), 5); // vector kNN
70
- const billing = db.querySql("SELECT body FROM docs WHERE source = 'help-center'"); // SQL filter
67
+ // Retrieve context to ground an agent's next answer — keyword, vector,
68
+ // hybrid (BM25 + vector fused in one pass), or SQL:
69
+ const keyword = docs.bm25Search("body", "cancel subscription", 5); // BM25
70
+ const semantic = docs.vectorSearch("embedding", embed(0), 5); // vector kNN
71
+ const hybrid = docs.hybridSearch("body", "cancel subscription", "embedding", embed(0), 5); // fused
72
+ const billing = db.querySql("SELECT body FROM docs WHERE source = 'help-center'"); // SQL filter
71
73
  ```
72
74
 
73
75
  CommonJS works too — `const { connect, IndexSpec } = require("@infino-ai/infino");`.
74
76
 
75
- ## Examples
76
-
77
- Runnable, end-to-end examples in [`examples/`](examples) (each its own folder
78
- with a README; build the addon first, then `npm install && node index.mjs`):
79
-
80
- - [`agent-memory/`](examples/agent-memory) — infino as an AI agent's long-term
81
- memory: load a real multi-session conversation, then recall it with hybrid
82
- search, query it with SQL (`GROUP BY`, filters), and forget parts of it.
83
- - [`hybrid-search-api/`](examples/hybrid-search-api) — an embedded HTTP search
84
- service over a real product catalog, ranked by native `hybrid_search` — with
85
- no separate search server to run.
86
-
87
- ## Core concepts
88
-
89
- - **Connection** — a handle to a catalog (a set of tables under one URI). Open
90
- it with `connect(uri)`.
91
- - **Table** — an append-only, snapshot-isolated collection of rows. Each table
92
- carries an auto-generated `_id` column.
93
- - **IndexSpec** — declares which columns are full-text (BM25) and which are
94
- vector indexed. Columns without an index are still stored, filterable in SQL,
95
- and returnable via projection.
96
- - **Commits** — every `append`, `update`, and `delete` is a single atomic
97
- commit. Readers see a consistent snapshot and are never torn by a concurrent
98
- write.
99
- - **Arrow at the boundary** — searches return plain records (or an apache-arrow
100
- `Table` with `{ arrow: true }`); `append` and `update` accept an array of
101
- objects or an apache-arrow `Table` / `RecordBatch`.
102
-
103
- ## Full-text search
104
-
105
- ```javascript
106
- const docs = db.createTable("docs", { title: "large_utf8" }, new IndexSpec().fts("title"));
107
- docs.append([{ title: "the quick brown fox" }, { title: "a lazy dog" }]);
108
-
109
- // Ranked BM25 — higher score is a better match.
110
- docs.bm25Search("title", "quick fox", 10); // OR by default
111
- docs.bm25Search("title", "quick fox", 10, { mode: "and" }); // require all terms
112
-
113
- // Unranked matching (score is 0): every row containing the term(s),
114
- // or an exact whole-value match.
115
- docs.tokenMatch("title", "fox");
116
- docs.exactMatch("title", "the quick brown fox");
117
- ```
118
-
119
- ## Vector search
120
-
121
- Vector columns are `FixedSizeList<Float32, dim>` with `dim` in `[16, 4096]`. The
122
- distance metric is fixed when you declare the index (`"cosine"`, `"l2sq"`, or
123
- `"negdot"`); for vector results a smaller score is nearer. The query vector is a
124
- `number[]` or `Float32Array`.
125
-
126
- ```javascript
127
- const spec = new IndexSpec().vector("emb", 384, 256, "cosine"); // (column, dim, nCent, metric)
128
- const vecs = db.createTable("vecs", { emb: { vector: 384 } }, spec);
129
-
130
- vecs.vectorSearch("emb", queryVector, 10); // top-10 nearest
131
- vecs.vectorSearch("emb", queryVector, 10, { nprobe: 32 }); // probe more partitions (recall)
132
- vecs.vectorSearch("emb", queryVector, 10, { rerankMult: 4 }); // wider exact-rerank pool (recall)
133
- ```
134
-
135
- **Filtered vector search.** Restrict the kNN to rows matching a text predicate —
136
- a pushdown *pre-filter*, so you get the nearest *matching* rows (not a
137
- post-filter over the global top-k). The filter `column` must be FTS-indexed.
138
-
139
- ```javascript
140
- vecs.vectorSearch("emb", queryVector, 10, {
141
- filter: { column: "title", query: "billing", mode: "or" },
142
- });
143
- ```
144
-
145
- ## Hybrid search
146
-
147
- Combine BM25 and vector search in **one call** — a single pass over both
148
- indexes, fused inside the engine with reciprocal-rank fusion (no separate
149
- reranker service, no two round-trips). Keyword-only search misses paraphrases;
150
- vector-only search misses exact terms — hybrid gets both. Results come back
151
- best-first with a fused `score` (higher is better).
77
+ > The API is synchronous. In a long-running server, run calls in a
78
+ > [`worker_thread`](https://nodejs.org/api/worker_threads.html) so a query
79
+ > doesn't block the event loop.
152
80
 
153
- ```javascript
154
- const spec = new IndexSpec().fts("body").vector("emb", 384, 256, "cosine");
155
- const docs = db.createTable("docs", { body: "large_utf8", emb: { vector: 384 } }, spec);
156
- docs.append([{ body: "To cancel a subscription, open Settings then Billing.", emb: embed(/* … */) }]);
81
+ ## Documentation
157
82
 
158
- // hybridSearch(textColumn, textQuery, vectorColumn, vectorQuery, k, opts?)
159
- docs.hybridSearch("body", "cancel subscription", "emb", embed("how do I stop my plan?"), 10);
160
- // opts: { mode } tunes the BM25 side, { nprobe } the vector side.
83
+ Full docs, guides, and the API reference live at **[docs.infino.ai](https://docs.infino.ai)**:
161
84
 
162
- // The same fusion is also a SQL table function, so it composes in a query:
163
- const qvec = embed("how do I stop my plan?").join(",");
164
- db.querySql(
165
- `SELECT _id, score FROM hybrid_search('docs', 'body', 'cancel subscription', 'emb', '${qvec}', 10)`,
166
- );
167
- ```
168
-
169
- For a complete, runnable hybrid search service see the
170
- [`hybrid-search-api` example](examples/hybrid-search-api).
171
-
172
- ## SQL
173
-
174
- Run SQL across the catalog's tables for analytics and filtering; the search
175
- functions are also available as SQL table functions. Results come back as plain
176
- records (or an apache-arrow `Table` with `{ arrow: true }`).
177
-
178
- ```javascript
179
- db.querySql("SELECT COUNT(*) AS n FROM docs");
180
- db.querySql("SELECT title FROM docs WHERE title = 'a lazy dog'");
181
-
182
- // The search methods are also SQL table functions — bm25_search, vector_search,
183
- // and hybrid_search (see "Hybrid search" above) — so you can filter, join, and
184
- // aggregate over search results.
185
- db.querySql("SELECT _id, score FROM bm25_search('docs', 'title', 'fox', 10)");
186
- ```
187
-
188
- ## Projections
189
-
190
- By default a search returns just `_id` and `score` — no row data is decoded.
191
- Name the columns you want to materialize:
192
-
193
- ```javascript
194
- docs.bm25Search("title", "fox", 10); // _id + score only
195
- docs.bm25Search("title", "fox", 10, { projection: ["_id", "title", "score"] });
196
- ```
197
-
198
- ## Updates and deletes
199
-
200
- Mutations require durable storage (a local path or object store, not
201
- `memory://`). The predicate is a SQL boolean expression — the same thing you'd
202
- write after `WHERE` — evaluated against the table's columns.
203
-
204
- ```javascript
205
- docs.append([{ title: "draft post" }, { title: "spam" }]);
206
-
207
- // Delete every row matching the predicate.
208
- docs.delete("title = 'spam'");
209
-
210
- // Replace matched rows 1:1 with new rows (same input shapes as append).
211
- const stats = docs.update("title = 'draft post'", [{ title: "published post" }]);
212
- console.log(stats.matched, stats.nTombstoned, stats.nNotFound);
213
- ```
214
-
215
- `update` is a one-to-one replacement: the number of matched rows must equal the
216
- number you supply, otherwise it throws. Both methods return `{ matched,
217
- nTombstoned, nNotFound }`.
218
-
219
- ## Optimize
220
-
221
- Many small appends produce many small files. `optimize` compacts them —
222
- merging small or underfilled files into larger ones — which keeps reads efficient.
223
-
224
- ```javascript
225
- docs.optimize(); // engine defaults
226
- docs.optimize({ targetSuperfileSizeMb: 256, minFillPercent: 50 });
227
- ```
228
-
229
- ## Storage backends
230
-
231
- `connect` selects the backend from the URI:
232
-
233
- | URI | Backend |
234
- | ------------------------ | ---------------------------------------- |
235
- | `./data`, `/abs/path` | Local filesystem |
236
- | `s3://bucket/prefix` | Amazon S3 / S3-compatible object storage |
237
- | `az://container/prefix` | Azure Blob Storage |
238
- | `memory://` | In-process, ephemeral (testing) |
239
-
240
- Credentials go in `storageOptions`, keyed by the standard `object_store` config
241
- strings (`aws_*` / `azure_*` — the same names the AWS and Azure SDKs use). Omit
242
- them to use ambient cloud identity (IAM instance role / managed identity);
243
- infino reads no credentials from the environment.
244
-
245
- ```javascript
246
- // S3
247
- const db = connect("s3://bucket/prefix", {
248
- storageOptions: {
249
- aws_access_key_id: "…",
250
- aws_secret_access_key: "…",
251
- aws_region: "us-east-1",
252
- },
253
- });
254
-
255
- // Azure
256
- const db = connect("az://container/prefix", {
257
- storageOptions: {
258
- azure_storage_account_name: "…",
259
- azure_storage_account_key: "…",
260
- },
261
- });
262
- ```
263
-
264
- Common keys:
265
-
266
- | Backend | Keys |
267
- | ------- | ---- |
268
- | S3 | `aws_access_key_id`, `aws_secret_access_key`, `aws_region`, `aws_session_token`, `aws_endpoint` |
269
- | Azure | `azure_storage_account_name`, `azure_storage_account_key`, `azure_storage_sas_key`, `azure_storage_client_id`, `azure_storage_client_secret`, `azure_storage_tenant_id` |
270
-
271
- The full set is whatever `object_store` accepts for the backend; an unknown key
272
- is rejected at `connect`. Pass `validate: true` to probe the backend at
273
- `connect`, so wrong credentials or an unreachable bucket throw there instead of
274
- on the first query. For an S3-compatible endpoint (MinIO / R2 / Ceph), set
275
- `aws_endpoint` (with `aws_allow_http: "true"` for plain HTTP) alongside the
276
- credentials.
277
-
278
- ### Local disk cache
279
-
280
- For object-storage-backed catalogs, a local disk cache keeps hot data on fast
281
- local storage. `coldFetchMode` controls how cache misses are served:
282
- `"hybrid_with_prefetch"`, `"range_only"`, or
283
- `"lazy_foreground_with_background_fill"`.
284
-
285
- ```javascript
286
- const db = connect("s3://bucket/prefix", {
287
- cacheDir: "/mnt/nvme/infino-cache",
288
- cacheBudgetBytes: 64 * 1024 ** 3,
289
- coldFetchMode: "lazy_foreground_with_background_fill",
290
- });
291
- ```
292
-
293
- ## Schema and type requirements
294
-
295
- - Full-text columns must be Arrow `LargeUtf8` (`"large_utf8"` in a descriptor).
296
- - Vector columns must be `FixedSizeList<Float32, dim>` (`{ vector: dim }`) with
297
- `dim` in `[16, 4096]`.
298
- - The `_id` column is generated by the engine; do not declare it. It comes back
299
- as a JavaScript `bigint`.
300
- - `createTable` accepts an apache-arrow `Schema` or a plain `{ column: type }`
301
- descriptor; `append` / `update` accept an array of objects or an apache-arrow
302
- `Table` / `RecordBatch`, coerced against the table's declared schema.
303
-
304
- ## API reference
305
-
306
- - `connect(uri, options?)` — backend from the URI scheme. `options`:
307
- `storageOptions` (credentials, keyed by `object_store`'s `aws_*` / `azure_*`
308
- strings), `validate`, and a local disk cache (`cacheDir`, `cacheBudgetBytes`,
309
- `coldFetchMode`).
310
- - `Connection`
311
- - `createTable(name, schema, IndexSpec)` / `openTable(name)` /
312
- `dropTable(name, purge?)` (`purge = true` also deletes the data) /
313
- `listTables()` / `querySql(sql, { arrow? })`.
314
- - `Table`
315
- - `append(data)` — one `append` is one commit.
316
- - `bm25Search(col, q, k, { mode?, projection?, arrow? })` — ranked BM25.
317
- - `vectorSearch(col, query, k, { nprobe?, rerankMult?, filter?, projection?, arrow? })`
318
- — ranked kNN; `filter` (`{ column, query, mode? }`, `column` FTS-indexed) is
319
- a pushdown pre-filter.
320
- - `tokenMatch(col, q, { mode?, projection?, arrow? })` /
321
- `exactMatch(col, value, { projection?, arrow? })` — unranked (`score` is `0`).
322
- - `update(predicate, data)` / `delete(predicate)` — mutate rows matching a SQL
323
- predicate; return `{ matched, nTombstoned, nNotFound }`; require durable
324
- storage.
325
- - `optimize({ maxMemoryMb?, minFillPercent?, targetSuperfileSizeMb? })`.
326
- - `schema()` — the table's apache-arrow `Schema`.
327
- - `IndexSpec().fts(col).vector(col, dim, nCent, metric)`.
328
- - `BUILDER_ID` (named export) — the engine's build identifier string.
329
-
330
- Search results default to `_id` + `score`; name columns in `projection` to
331
- materialize row data.
85
+ - [Quickstart](https://docs.infino.ai/quickstart) install to first query
86
+ - [Core concepts](https://docs.infino.ai/core-concepts) superfiles, commits, and indexes
87
+ - Guides — [Tables & indexing](https://docs.infino.ai/guides/tables) ·
88
+ [Search: BM25, vector, hybrid](https://docs.infino.ai/guides/search) ·
89
+ [Embeddings](https://docs.infino.ai/guides/embeddings) ·
90
+ [Storage & credentials](https://docs.infino.ai/guides/storage)
91
+ - [SQL reference](https://docs.infino.ai/sql-reference) — query tables and the search table-valued functions
92
+ - [API reference](https://docs.infino.ai/api-reference) the full Node surface, generated from the package
93
+ - [Integrations](https://docs.infino.ai/integrations) — LangChain, CrewAI, Vercel AI SDK, MCP
94
+ - [Examples](examples) — runnable agent-memory and hybrid-search-service demos
332
95
 
333
96
  ## Building from source
334
97
 
335
- The binding is built with [napi-rs](https://napi.rs/). Building requires a Rust
336
- toolchain and access to crates.io.
98
+ The binding is built with [napi-rs](https://napi.rs/) and requires a Rust
99
+ toolchain.
337
100
 
338
101
  ```sh
339
102
  cd infino-node
340
103
  npm install && npm run build && npm test
341
104
  ```
342
105
 
343
- ## Notes
344
-
345
- - The API is **synchronous**. In a long-running server, run calls in a
346
- `worker_thread` so a query doesn't block the event loop.
347
-
348
- ## FAQ
349
-
350
- **Is infino a vector database?** It does vector search, but it's more than that —
351
- an embedded engine that runs vector search *and* full-text (BM25) *and* SQL over
352
- one copy of your data. Reach for it wherever you'd use a vector database, plus the
353
- cases a vector store alone can't cover: keyword search, filtering, joins, and
354
- aggregates.
355
-
356
- **Does it need a server?** No. It runs in your Node.js process — no daemon, no
357
- cluster, no managed service. Your data is Parquet on local disk or S3.
358
-
359
- **Can it do hybrid (keyword + vector) search?** Yes, natively — BM25 and vector
360
- fused in a single pass via `hybrid_search` (see [Hybrid search](#hybrid-search)),
361
- not a client-side rerank.
362
-
363
- **Where is my data stored?** As Apache Parquet files on local disk or any
364
- S3-compatible object store; each file embeds its own BM25 and vector indexes.
365
-
366
- **Does it work with TypeScript?** Yes — the package ships type definitions and the
367
- API is identical from JavaScript and TypeScript. Both ESM `import` and CommonJS
368
- `require` work.
369
-
370
- **Do I need a Rust toolchain to install it?** No — a prebuilt native binary is
371
- selected automatically at install (macOS and Linux, x64 and arm64).
372
-
373
- **Is it a good fit for RAG or agent memory?** Yes, that's a primary use case:
374
- store documents or conversation history once, retrieve with hybrid search, and
375
- filter/aggregate with SQL. See the runnable [examples](examples).
376
-
377
106
  ## License
378
107
 
379
108
  Apache-2.0.
package/infino/index.d.ts CHANGED
@@ -44,6 +44,19 @@ export interface MutationStats {
44
44
  /** Matched rows not found in any live segment. */
45
45
  nNotFound: number;
46
46
  }
47
+ /** Counts from a `gc` sweep. */
48
+ export interface GcReport {
49
+ /** Bytes reclaimed by deleting orphaned objects. */
50
+ bytesFreed: number;
51
+ /** Orphaned objects deleted. */
52
+ objectsDeleted: number;
53
+ /** Objects kept because they are still referenced by the live set. */
54
+ objectsSkippedLive: number;
55
+ /** Objects kept because they are younger than the grace period. */
56
+ objectsSkippedTooNew: number;
57
+ /** Objects that failed to delete (left for the next sweep). */
58
+ deleteErrors: number;
59
+ }
47
60
  /** Tuning for `optimize`; all fields optional (omitted ⇒ engine default). */
48
61
  export interface OptimizeOptions {
49
62
  /** Build-time memory budget, in MB. */
@@ -99,6 +112,9 @@ export interface MatchOptions {
99
112
  projection?: string[];
100
113
  arrow?: boolean;
101
114
  }
115
+ export interface CountOptions {
116
+ mode?: BoolMode;
117
+ }
102
118
  export interface QueryOptions {
103
119
  arrow?: boolean;
104
120
  }
@@ -140,6 +156,9 @@ export declare class Table {
140
156
  arrow: true;
141
157
  }): arrow.Table;
142
158
  exactMatch(column: string, value: string, opts?: MatchOptions): RowRecord[];
159
+ /** Count rows matching a BM25 keyword `query` over `column`, without
160
+ * fetching them. `mode` is `"or"` (default) or `"and"`. */
161
+ count(column: string, query: string, opts?: CountOptions): number;
143
162
  /** Replace rows matching a SQL predicate (e.g. `"status = 'spam'"`) with
144
163
  * `data` (same shapes as `append`), 1:1 — the matched count must equal the
145
164
  * replacement-row count. Requires durable storage (not `memory://`). */
@@ -150,6 +169,10 @@ export declare class Table {
150
169
  /** Merge small / underfilled superfiles into larger ones (omit `settings`
151
170
  * for engine defaults). */
152
171
  optimize(settings?: OptimizeOptions): void;
172
+ /** Delete orphaned storage objects left by compaction or interrupted writes.
173
+ * Only objects older than `graceSecs` (a safety window against racing
174
+ * readers/writers) are removed. Requires durable storage (not `memory://`). */
175
+ gc(graceSecs: number): GcReport;
153
176
  }
154
177
  export declare class Connection {
155
178
  private inner;
package/infino/index.js CHANGED
@@ -229,6 +229,11 @@ class Table {
229
229
  const buf = this.inner.exactMatch(column, value, opts.projection);
230
230
  return decode(buf, opts.arrow);
231
231
  }
232
+ /** Count rows matching a BM25 keyword `query` over `column`, without
233
+ * fetching them. `mode` is `"or"` (default) or `"and"`. */
234
+ count(column, query, opts = {}) {
235
+ return this.inner.count(column, query, opts.mode);
236
+ }
232
237
  /** Replace rows matching a SQL predicate (e.g. `"status = 'spam'"`) with
233
238
  * `data` (same shapes as `append`), 1:1 — the matched count must equal the
234
239
  * replacement-row count. Requires durable storage (not `memory://`). */
@@ -245,6 +250,12 @@ class Table {
245
250
  optimize(settings) {
246
251
  this.inner.optimize(settings);
247
252
  }
253
+ /** Delete orphaned storage objects left by compaction or interrupted writes.
254
+ * Only objects older than `graceSecs` (a safety window against racing
255
+ * readers/writers) are removed. Requires durable storage (not `memory://`). */
256
+ gc(graceSecs) {
257
+ return this.inner.gc(graceSecs);
258
+ }
248
259
  }
249
260
  exports.Table = Table;
250
261
  class Connection {
@@ -48,6 +48,19 @@ export interface MutationStats {
48
48
  /** Matched rows that were not found in any live segment. */
49
49
  nNotFound: number
50
50
  }
51
+ /** Counts from a `gc` sweep. */
52
+ export interface GcReport {
53
+ /** Bytes reclaimed by deleting orphaned objects. */
54
+ bytesFreed: number
55
+ /** Orphaned objects deleted. */
56
+ objectsDeleted: number
57
+ /** Objects kept because they are still referenced by the live set. */
58
+ objectsSkippedLive: number
59
+ /** Objects kept because they are younger than the grace period. */
60
+ objectsSkippedTooNew: number
61
+ /** Objects that failed to delete (left for the next sweep). */
62
+ deleteErrors: number
63
+ }
51
64
  /**
52
65
  * Text-predicate filter for `vectorSearch` — a pushdown pre-filter, not a
53
66
  * post-filter: kNN ranks only among rows whose FTS-indexed `column` matches
@@ -149,6 +162,11 @@ export declare class Table {
149
162
  * columns (omit for full rows).
150
163
  */
151
164
  exactMatch(column: string, value: string, projection?: Array<string> | undefined | null): Buffer
165
+ /**
166
+ * Count rows matching a BM25 keyword `query` over `column`, without
167
+ * fetching them. `mode` is `"or"` (default) or `"and"`.
168
+ */
169
+ count(column: string, query: string, mode?: string | undefined | null): number
152
170
  /**
153
171
  * Hybrid BM25 + vector search fused with reciprocal-rank fusion.
154
172
  * `text_column`/`text_query` (under `mode`) drive BM25; `vector_column`/
@@ -175,6 +193,12 @@ export declare class Table {
175
193
  * defaults).
176
194
  */
177
195
  optimize(settings?: OptimizeOptions | undefined | null): void
196
+ /**
197
+ * Delete orphaned storage objects left by compaction or interrupted
198
+ * writes. Only objects older than `graceSecs` (a safety window against
199
+ * racing readers/writers) are removed. Requires durable storage.
200
+ */
201
+ gc(graceSecs: number): GcReport
178
202
  /**
179
203
  * The user-facing Arrow schema, as an Arrow IPC `Buffer` (an empty
180
204
  * table carrying the schema; read with `tableFromIPC`).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@infino-ai/infino",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Fast search on object storage — SQL, full-text, and vector search.",
5
5
  "license": "Apache-2.0",
6
6
  "publishConfig": {
@@ -82,12 +82,12 @@
82
82
  "apache-arrow": "^17"
83
83
  },
84
84
  "optionalDependencies": {
85
- "infx-darwin-x64": "0.1.1",
86
- "infx-darwin-arm64": "0.1.1",
87
- "infx-linux-x64-gnu": "0.1.1",
88
- "infx-linux-arm64-gnu": "0.1.1",
89
- "infx-linux-x64-musl": "0.1.1",
90
- "infx-linux-arm64-musl": "0.1.1"
85
+ "infx-darwin-x64": "0.1.2",
86
+ "infx-darwin-arm64": "0.1.2",
87
+ "infx-linux-x64-gnu": "0.1.2",
88
+ "infx-linux-arm64-gnu": "0.1.2",
89
+ "infx-linux-x64-musl": "0.1.2",
90
+ "infx-linux-arm64-musl": "0.1.2"
91
91
  },
92
92
  "devDependencies": {
93
93
  "@napi-rs/cli": "^2.18.0",