@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 +33 -304
- package/infino/index.d.ts +23 -0
- package/infino/index.js +11 -0
- package/infino/native.d.ts +24 -0
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# infino
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@infino-ai/infino)
|
|
4
|
+
[](https://www.npmjs.com/package/@infino-ai/infino)
|
|
5
|
+
[](https://www.npmjs.com/package/@infino-ai/infino)
|
|
6
|
+
[](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
|
|
13
|
-
|
|
14
|
-
**SQL** query engine in one library
|
|
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
|
|
37
|
-
`Table`s, or `{ arrow: true }` results).
|
|
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
|
-
//
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
const
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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/)
|
|
336
|
-
toolchain
|
|
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 {
|
package/infino/native.d.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
86
|
-
"infx-darwin-arm64": "0.1.
|
|
87
|
-
"infx-linux-x64-gnu": "0.1.
|
|
88
|
-
"infx-linux-arm64-gnu": "0.1.
|
|
89
|
-
"infx-linux-x64-musl": "0.1.
|
|
90
|
-
"infx-linux-arm64-musl": "0.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",
|