@mirk/store 0.4.2 → 0.6.1
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 +42 -8
- package/dist/adapters/sqlite.d.ts +6 -3
- package/dist/adapters/sqlite.js +265 -69
- package/dist/chunk-77IIKHQW.js +120 -0
- package/dist/{chunk-ZI4JA6IU.js → chunk-DKCPULXT.js} +17 -0
- package/dist/chunk-DP4D7CJY.js +59 -0
- package/dist/chunk-KPMRRYTL.js +14 -0
- package/dist/chunk-N27Y55CA.js +67 -0
- package/dist/{chunk-EDVHBRXG.js → chunk-OUY3D4RT.js} +45 -1
- package/dist/filter-B9hP-TKF.d.ts +8 -0
- package/dist/graph.d.ts +98 -0
- package/dist/graph.js +161 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +19 -3
- package/dist/kv.d.ts +6 -4
- package/dist/kv.js +1 -1
- package/dist/search.d.ts +26 -0
- package/dist/search.js +16 -0
- package/dist/sql.d.ts +27 -0
- package/dist/sql.js +14 -0
- package/dist/{types-BqSZEMAB.d.ts → types-B0XrD10b.d.ts} +28 -2
- package/dist/types-BLZTMsQO.d.ts +69 -0
- package/dist/{types-DyQLNtxa.d.ts → types-DHLdLZ_W.d.ts} +12 -1
- package/dist/vector.d.ts +8 -2
- package/dist/vector.js +8 -2
- package/package.json +16 -4
package/dist/sql.js
ADDED
|
@@ -32,6 +32,13 @@ interface VectorSearchOptions {
|
|
|
32
32
|
topK?: number;
|
|
33
33
|
/** Minimum cosine similarity; results below are excluded. Default: no floor. */
|
|
34
34
|
minScore?: number;
|
|
35
|
+
/** Pre-KNN filter: only consider documents whose metadata satisfies ALL of these
|
|
36
|
+
* exact-match conditions. Applied before scoring, so topK is out of the passing
|
|
37
|
+
* set only. `where` and `whereNot` are independent — both may be provided. */
|
|
38
|
+
where?: Record<string, unknown>;
|
|
39
|
+
/** Pre-KNN filter: exclude documents whose metadata satisfies ANY of these
|
|
40
|
+
* exact-match conditions. Applied before scoring. */
|
|
41
|
+
whereNot?: Record<string, unknown>;
|
|
35
42
|
}
|
|
36
43
|
/** A synchronous vector similarity store with per-collection documents.
|
|
37
44
|
*
|
|
@@ -46,12 +53,31 @@ interface VectorStore {
|
|
|
46
53
|
upsertMany<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, docs: ReadonlyArray<VectorDocument<M>>): void;
|
|
47
54
|
/** Fetch a document by id, or null. */
|
|
48
55
|
get<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, id: string): VectorDocument<M> | null;
|
|
56
|
+
/** Check whether a document exists by (collection, id). */
|
|
57
|
+
has(collection: string, id: string): boolean;
|
|
49
58
|
/** Remove a document by id. Returns true if it existed. */
|
|
50
59
|
remove(collection: string, id: string): boolean;
|
|
51
60
|
/** Number of documents in a collection. */
|
|
52
61
|
count(collection: string): number;
|
|
53
|
-
/** k-nearest-neighbour search by cosine similarity, highest score first.
|
|
62
|
+
/** k-nearest-neighbour search by cosine similarity, highest score first.
|
|
63
|
+
* Supports pre-KNN filtering via opts.where / opts.whereNot. */
|
|
54
64
|
search<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, query: Vector, opts?: VectorSearchOptions): VectorSearchResult<M>[];
|
|
55
65
|
}
|
|
66
|
+
/** The async face of the same vector store. Remote backends (e.g. Qdrant) implement
|
|
67
|
+
* this natively; sync backends reach it via {@link toAsyncVector}.
|
|
68
|
+
*
|
|
69
|
+
* Hand-written rather than derived from VectorStore via a mapped type: per-method
|
|
70
|
+
* generics (`get<M>`, `search<M>`, …) collapse to `unknown` under inference — same
|
|
71
|
+
* constraint as the KV AsyncStore twin in src/types.ts. */
|
|
72
|
+
interface AsyncVectorStore {
|
|
73
|
+
readonly meta: VectorStoreMeta;
|
|
74
|
+
upsert<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, doc: VectorDocument<M>): Promise<void>;
|
|
75
|
+
upsertMany<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, docs: ReadonlyArray<VectorDocument<M>>): Promise<void>;
|
|
76
|
+
get<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, id: string): Promise<VectorDocument<M> | null>;
|
|
77
|
+
has(collection: string, id: string): Promise<boolean>;
|
|
78
|
+
remove(collection: string, id: string): Promise<boolean>;
|
|
79
|
+
count(collection: string): Promise<number>;
|
|
80
|
+
search<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, query: Vector, opts?: VectorSearchOptions): Promise<VectorSearchResult<M>[]>;
|
|
81
|
+
}
|
|
56
82
|
|
|
57
|
-
export type { Vector as V, VectorDocument as a, VectorSearchOptions as b, VectorSearchResult as c, VectorStore as d, VectorStoreMeta as e };
|
|
83
|
+
export type { AsyncVectorStore as A, Vector as V, VectorDocument as a, VectorSearchOptions as b, VectorSearchResult as c, VectorStore as d, VectorStoreMeta as e };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { S as StoreFilter } from './types-DHLdLZ_W.js';
|
|
2
|
+
|
|
3
|
+
/** A document to be full-text indexed. `meta` is an exact-match-filterable
|
|
4
|
+
* payload persisted as JSON by disk-backed backends, so it must be JSON-
|
|
5
|
+
* serializable; values JSON can't represent (`undefined`, functions) are dropped
|
|
6
|
+
* on persistence — don't rely on them. */
|
|
7
|
+
interface SearchTextDocument<M = Record<string, unknown>> {
|
|
8
|
+
/** Unique id within the collection. */
|
|
9
|
+
id: string;
|
|
10
|
+
/** Single-field text to tokenize and index. Back-compat shorthand for
|
|
11
|
+
* `fields: { text }`. */
|
|
12
|
+
text: string;
|
|
13
|
+
/** Provide either `text` or `fields`, not both. */
|
|
14
|
+
fields?: never;
|
|
15
|
+
/** Typed context stored alongside the text. */
|
|
16
|
+
meta?: M;
|
|
17
|
+
}
|
|
18
|
+
interface SearchFieldDocument<M = Record<string, unknown>> {
|
|
19
|
+
/** Unique id within the collection. */
|
|
20
|
+
id: string;
|
|
21
|
+
/** Named text fields to tokenize and index with optional query-time weights
|
|
22
|
+
* (for example `{ title, body }`). All documents in a collection must use the
|
|
23
|
+
* same field names. */
|
|
24
|
+
fields: Record<string, string>;
|
|
25
|
+
/** Provide either `text` or `fields`, not both. */
|
|
26
|
+
text?: never;
|
|
27
|
+
/** Typed context stored alongside the text. */
|
|
28
|
+
meta?: M;
|
|
29
|
+
}
|
|
30
|
+
type SearchDocument<M = Record<string, unknown>> = SearchTextDocument<M> | SearchFieldDocument<M>;
|
|
31
|
+
interface SearchOptions {
|
|
32
|
+
/** Maximum results to return. Default: 10. */
|
|
33
|
+
limit?: number;
|
|
34
|
+
/** Exact-match filter on document `meta` (uses `filter.where`, evaluated with
|
|
35
|
+
* the shared `matchesWhere`). Applied before limit, after the FTS MATCH. */
|
|
36
|
+
filter?: StoreFilter;
|
|
37
|
+
/** Per-field bm25 weights. Fields not listed default to 1. Higher means more
|
|
38
|
+
* important; e.g. `{ title: 4, body: 1 }` boosts title matches. */
|
|
39
|
+
fieldWeights?: Record<string, number>;
|
|
40
|
+
}
|
|
41
|
+
/** A ranked search hit. `score` is the bm25 relevance — higher is more relevant. */
|
|
42
|
+
interface SearchResult<M = Record<string, unknown>> {
|
|
43
|
+
id: string;
|
|
44
|
+
/** bm25 relevance. Higher = more relevant. (sqlite exposes `-bm25(fts)`; the
|
|
45
|
+
* in-memory reference computes the same quantity directly.) */
|
|
46
|
+
score: number;
|
|
47
|
+
/** The document's `meta`, or `{}` when none was indexed. */
|
|
48
|
+
meta: M;
|
|
49
|
+
}
|
|
50
|
+
/** A synchronous full-text search store with per-collection documents.
|
|
51
|
+
*
|
|
52
|
+
* Ranking is bm25 with the FTS5 default parameters (k1 = 1.2, b = 0.75), plus
|
|
53
|
+
* optional query-time per-field weights. The in-memory reference and the sqlite
|
|
54
|
+
* `.search` facet produce the same RANKING on clear relevance differences;
|
|
55
|
+
* exact float scores need not match across backends (the same parity caveat as
|
|
56
|
+
* /vector). */
|
|
57
|
+
interface SearchStore {
|
|
58
|
+
/** Insert or replace a document by (collection, id). */
|
|
59
|
+
index<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, doc: SearchDocument<M>): void;
|
|
60
|
+
/** Insert or replace many documents in one collection. */
|
|
61
|
+
indexMany<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, docs: ReadonlyArray<SearchDocument<M>>): void;
|
|
62
|
+
/** Remove a document by id. Returns true if it existed. */
|
|
63
|
+
remove(collection: string, id: string): boolean;
|
|
64
|
+
/** bm25-ranked keyword search, highest score first. Supports an exact-match
|
|
65
|
+
* meta `filter`. An empty/whitespace query returns `[]`. */
|
|
66
|
+
search<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, query: string, opts?: SearchOptions): SearchResult<M>[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type { SearchDocument as S, SearchOptions as a, SearchResult as b, SearchStore as c, SearchFieldDocument as d, SearchTextDocument as e };
|
|
@@ -20,6 +20,17 @@ interface StoreFilter {
|
|
|
20
20
|
/** Number of results to skip. */
|
|
21
21
|
offset?: number;
|
|
22
22
|
}
|
|
23
|
+
/** Optional collection capability for adapters that can push `field IN (...)`
|
|
24
|
+
* down to the backing store while preserving the normal StoreFilter semantics.
|
|
25
|
+
* Graph frontier traversal uses this when present and falls back to plain
|
|
26
|
+
* `list()` when absent. */
|
|
27
|
+
interface SyncStoreInQuery {
|
|
28
|
+
listWhereIn<T>(collection: string, field: string, values: readonly unknown[], filter?: StoreFilter): T[];
|
|
29
|
+
}
|
|
30
|
+
/** Async twin of SyncStoreInQuery for remote-capable stores. */
|
|
31
|
+
interface AsyncStoreInQuery {
|
|
32
|
+
listWhereIn<T>(collection: string, field: string, values: readonly unknown[], filter?: StoreFilter): Promise<T[]>;
|
|
33
|
+
}
|
|
23
34
|
/**
|
|
24
35
|
* A typed key-value + collection store. **Synchronous.**
|
|
25
36
|
*
|
|
@@ -80,4 +91,4 @@ interface AsyncStore {
|
|
|
80
91
|
count(collection: string, filter?: StoreFilter): Promise<number>;
|
|
81
92
|
}
|
|
82
93
|
|
|
83
|
-
export type { AsyncStore as A, StoreFilter as S,
|
|
94
|
+
export type { AsyncStore as A, StoreFilter as S, AsyncStoreInQuery as a, StoreMeta as b, SyncStore as c, SyncStoreInQuery as d };
|
package/dist/vector.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { V as Vector, d as VectorStore, e as VectorStoreMeta, a as VectorDocument, b as VectorSearchOptions, c as VectorSearchResult } from './types-
|
|
1
|
+
import { V as Vector, d as VectorStore, e as VectorStoreMeta, a as VectorDocument, b as VectorSearchOptions, c as VectorSearchResult, A as AsyncVectorStore } from './types-B0XrD10b.js';
|
|
2
|
+
export { m as matchesWhere } from './filter-B9hP-TKF.js';
|
|
2
3
|
|
|
3
4
|
/** Cosine similarity in [-1, 1]. Exact. Shared by the in-memory backend and the
|
|
4
5
|
* sqlite backend's search path. Returns 0 for length mismatch or a zero vector
|
|
@@ -32,10 +33,15 @@ declare class InMemoryVectorStore implements VectorStore {
|
|
|
32
33
|
upsert<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, doc: VectorDocument<M>): void;
|
|
33
34
|
upsertMany<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, docs: ReadonlyArray<VectorDocument<M>>): void;
|
|
34
35
|
get<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, id: string): VectorDocument<M> | null;
|
|
36
|
+
has(collection: string, id: string): boolean;
|
|
35
37
|
remove(collection: string, id: string): boolean;
|
|
36
38
|
count(collection: string): number;
|
|
37
39
|
search<M extends Record<string, unknown> = Record<string, unknown>>(collection: string, query: Vector, opts?: VectorSearchOptions): VectorSearchResult<M>[];
|
|
38
40
|
private collectionFor;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
/** Lift a synchronous VectorStore to the {@link AsyncVectorStore} interface. The
|
|
44
|
+
* bridge only goes this direction — sync ⊂ async. */
|
|
45
|
+
declare function toAsyncVector(store: VectorStore): AsyncVectorStore;
|
|
46
|
+
|
|
47
|
+
export { AsyncVectorStore, InMemoryVectorStore, Vector, VectorDocument, VectorSearchOptions, VectorSearchResult, VectorStore, VectorStoreMeta, assertDimensions, bufferToVector, cosineSimilarity, isUsableVector, toAsyncVector, vectorToBuffer };
|
package/dist/vector.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
InMemoryVectorStore
|
|
3
|
-
|
|
2
|
+
InMemoryVectorStore,
|
|
3
|
+
toAsyncVector
|
|
4
|
+
} from "./chunk-OUY3D4RT.js";
|
|
4
5
|
import {
|
|
5
6
|
assertDimensions,
|
|
6
7
|
bufferToVector,
|
|
@@ -8,11 +9,16 @@ import {
|
|
|
8
9
|
isUsableVector,
|
|
9
10
|
vectorToBuffer
|
|
10
11
|
} from "./chunk-BXM3YDOC.js";
|
|
12
|
+
import {
|
|
13
|
+
matchesWhere
|
|
14
|
+
} from "./chunk-KPMRRYTL.js";
|
|
11
15
|
export {
|
|
12
16
|
InMemoryVectorStore,
|
|
13
17
|
assertDimensions,
|
|
14
18
|
bufferToVector,
|
|
15
19
|
cosineSimilarity,
|
|
16
20
|
isUsableVector,
|
|
21
|
+
matchesWhere,
|
|
22
|
+
toAsyncVector,
|
|
17
23
|
vectorToBuffer
|
|
18
24
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mirk/store",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Code-split storage ports + source adapters under one namespace. KV + collection store and vector similarity store as interface subpaths; the sqlite source-adapter implements both over one connection.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"homepage": "https://github.com/nightwork-dev/mirk/tree/main/packages/store#readme",
|
|
26
26
|
"bugs": "https://github.com/nightwork-dev/mirk/issues",
|
|
27
27
|
"main": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
28
29
|
"exports": {
|
|
29
30
|
".": {
|
|
30
31
|
"import": "./dist/index.js",
|
|
@@ -38,6 +39,18 @@
|
|
|
38
39
|
"import": "./dist/vector.js",
|
|
39
40
|
"types": "./dist/vector.d.ts"
|
|
40
41
|
},
|
|
42
|
+
"./search": {
|
|
43
|
+
"import": "./dist/search.js",
|
|
44
|
+
"types": "./dist/search.d.ts"
|
|
45
|
+
},
|
|
46
|
+
"./graph": {
|
|
47
|
+
"import": "./dist/graph.js",
|
|
48
|
+
"types": "./dist/graph.d.ts"
|
|
49
|
+
},
|
|
50
|
+
"./sql": {
|
|
51
|
+
"import": "./dist/sql.js",
|
|
52
|
+
"types": "./dist/sql.d.ts"
|
|
53
|
+
},
|
|
41
54
|
"./sqlite": {
|
|
42
55
|
"import": "./dist/adapters/sqlite.js",
|
|
43
56
|
"types": "./dist/adapters/sqlite.d.ts"
|
|
@@ -74,7 +87,6 @@
|
|
|
74
87
|
"test": "vitest run",
|
|
75
88
|
"test:watch": "vitest",
|
|
76
89
|
"typecheck": "tsc --noEmit",
|
|
77
|
-
"build": "rm -rf dist && tsup src/index.ts src/kv.ts src/vector.ts src/adapters/sqlite.ts --format esm --dts --external better-sqlite3 --external sqlite-vec"
|
|
78
|
-
}
|
|
79
|
-
"types": "./dist/index.d.ts"
|
|
90
|
+
"build": "rm -rf dist && tsup src/index.ts src/kv.ts src/vector.ts src/search.ts src/graph.ts src/sql.ts src/adapters/sqlite.ts --format esm --dts --external better-sqlite3 --external sqlite-vec"
|
|
91
|
+
}
|
|
80
92
|
}
|