@outfitter/index 0.1.0-rc.1 → 0.1.0-rc.3

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/dist/index.d.ts CHANGED
@@ -1,304 +1,5 @@
1
- import { Database } from "bun:sqlite";
2
- import { StorageError } from "@outfitter/contracts";
3
- import { Result } from "@outfitter/contracts";
4
- interface MigrationRegistry<TContext> {
5
- register(fromVersion: number, toVersion: number, migrate: (context: TContext) => Result<void, StorageError>): void;
6
- migrate(context: TContext, fromVersion: number, toVersion: number): Result<void, StorageError>;
7
- }
8
- interface IndexMigrationContext {
9
- readonly db: Database;
10
- }
11
- type IndexMigrationRegistry = MigrationRegistry<IndexMigrationContext>;
12
- declare function createMigrationRegistry<TContext>(): MigrationRegistry<TContext>;
13
- import { Result as Result2, StorageError as StorageError2 } from "@outfitter/contracts";
14
- /**
15
- * FTS5 tokenizer options for text analysis.
16
- *
17
- * - `unicode61`: Default tokenizer with Unicode support (recommended for most use cases)
18
- * - `porter`: Applies Porter stemming algorithm for English text (finds related word forms)
19
- * - `trigram`: Splits text into 3-character sequences (good for substring matching)
20
- */
21
- type TokenizerType = "unicode61" | "porter" | "trigram";
22
- /**
23
- * Options for creating an FTS5 index.
24
- *
25
- * @example
26
- * ```typescript
27
- * const options: IndexOptions = {
28
- * path: "/path/to/index.db",
29
- * tableName: "documents",
30
- * tokenizer: "porter",
31
- * };
32
- *
33
- * const index = createIndex(options);
34
- * ```
35
- */
36
- interface IndexOptions {
37
- /**
38
- * Absolute path to the SQLite database file.
39
- * The file will be created if it does not exist.
40
- */
41
- path: string;
42
- /**
43
- * Name of the FTS5 virtual table.
44
- * @defaultValue "documents"
45
- */
46
- tableName?: string;
47
- /**
48
- * FTS5 tokenizer for text analysis.
49
- * @defaultValue "unicode61"
50
- */
51
- tokenizer?: TokenizerType;
52
- /**
53
- * Optional tool identifier recorded in index metadata.
54
- */
55
- tool?: string;
56
- /**
57
- * Optional tool version recorded in index metadata.
58
- */
59
- toolVersion?: string;
60
- /**
61
- * Optional migration registry for upgrading older index versions.
62
- */
63
- migrations?: IndexMigrationRegistry;
64
- }
65
- /**
66
- * Metadata stored alongside the index to track version and provenance.
67
- */
68
- interface IndexMetadata {
69
- /** File format version */
70
- version: number;
71
- /** When this index was created */
72
- created: string;
73
- /** Tool that created the index */
74
- tool: string;
75
- /** Tool version that created the index */
76
- toolVersion: string;
77
- }
78
- /**
79
- * A document to be indexed in the FTS5 index.
80
- *
81
- * Documents have a unique ID, searchable content, and optional metadata.
82
- * The metadata is stored as JSON and can be used to attach additional
83
- * information that is returned with search results.
84
- *
85
- * @example
86
- * ```typescript
87
- * const doc: IndexDocument = {
88
- * id: "note-123",
89
- * content: "This is the searchable text content",
90
- * metadata: { title: "My Note", createdAt: Date.now() },
91
- * };
92
- * ```
93
- */
94
- interface IndexDocument {
95
- /** Unique identifier for this document */
96
- id: string;
97
- /** Searchable text content */
98
- content: string;
99
- /**
100
- * Optional metadata associated with the document.
101
- * Stored as JSON and returned with search results.
102
- */
103
- metadata?: Record<string, unknown>;
104
- }
105
- /**
106
- * Query parameters for searching the FTS5 index.
107
- *
108
- * Uses FTS5 query syntax which supports:
109
- * - Simple terms: `search term`
110
- * - Phrases: `"exact phrase"`
111
- * - Boolean operators: `term1 AND term2`, `term1 OR term2`, `NOT term`
112
- * - Prefix matching: `term*`
113
- * - Grouping: `(term1 OR term2) AND term3`
114
- *
115
- * @example
116
- * ```typescript
117
- * // Simple search
118
- * const query1: SearchQuery = { query: "typescript" };
119
- *
120
- * // Phrase search with pagination
121
- * const query2: SearchQuery = {
122
- * query: '"error handling"',
123
- * limit: 10,
124
- * offset: 20,
125
- * };
126
- * ```
127
- */
128
- interface SearchQuery {
129
- /** FTS5 query string */
130
- query: string;
131
- /**
132
- * Maximum number of results to return.
133
- * @defaultValue 25
134
- */
135
- limit?: number;
136
- /**
137
- * Number of results to skip (for pagination).
138
- * @defaultValue 0
139
- */
140
- offset?: number;
141
- }
142
- /**
143
- * A single search result from an FTS5 query.
144
- *
145
- * Results include the document ID, BM25 relevance score, content,
146
- * and any associated metadata. Optional highlights show matching
147
- * snippets from the content.
148
- *
149
- * @typeParam T - Type of the metadata (defaults to `unknown`)
150
- *
151
- * @example
152
- * ```typescript
153
- * interface NoteMetadata {
154
- * title: string;
155
- * tags: string[];
156
- * }
157
- *
158
- * const result: SearchResult<NoteMetadata> = {
159
- * id: "note-123",
160
- * score: 0.85,
161
- * content: "Full document content...",
162
- * metadata: { title: "My Note", tags: ["typescript"] },
163
- * highlights: ["...matching <b>snippet</b>..."],
164
- * };
165
- * ```
166
- */
167
- interface SearchResult<T = unknown> {
168
- /** Document ID */
169
- id: string;
170
- /**
171
- * BM25 relevance ranking score.
172
- * Higher scores indicate better matches.
173
- * Note: FTS5 BM25 returns negative values (closer to 0 = better match).
174
- */
175
- score: number;
176
- /** Full document content */
177
- content: string;
178
- /** Document metadata (if present) */
179
- metadata?: T;
180
- /**
181
- * Matching snippets from the content.
182
- * Uses FTS5 snippet() function for context-aware highlights.
183
- */
184
- highlights?: string[];
185
- }
186
- /**
187
- * The FTS5 index interface for full-text search operations.
188
- *
189
- * Provides methods for adding, searching, and removing documents
190
- * from an SQLite FTS5 index. All operations return `Result` types
191
- * for explicit error handling.
192
- *
193
- * @typeParam T - Type of document metadata (defaults to `unknown`)
194
- *
195
- * @example
196
- * ```typescript
197
- * const index = createIndex<NoteMetadata>({ path: "./index.db" });
198
- *
199
- * // Add documents
200
- * await index.add({ id: "1", content: "Hello world", metadata: { title: "Greeting" } });
201
- *
202
- * // Search
203
- * const results = await index.search({ query: "hello" });
204
- * if (results.isOk()) {
205
- * for (const result of results.value) {
206
- * console.log(result.id, result.score);
207
- * }
208
- * }
209
- *
210
- * // Cleanup
211
- * index.close();
212
- * ```
213
- */
214
- interface Index<T = unknown> {
215
- /**
216
- * Add a single document to the index.
217
- * If a document with the same ID exists, it will be replaced.
218
- *
219
- * @param doc - Document to add
220
- * @returns Result indicating success or StorageError
221
- */
222
- add(doc: IndexDocument): Promise<Result2<void, StorageError2>>;
223
- /**
224
- * Add multiple documents to the index in a single transaction.
225
- * More efficient than calling add() multiple times.
226
- * If a document with the same ID exists, it will be replaced.
227
- *
228
- * @param docs - Array of documents to add
229
- * @returns Result indicating success or StorageError
230
- */
231
- addMany(docs: IndexDocument[]): Promise<Result2<void, StorageError2>>;
232
- /**
233
- * Search the index using FTS5 query syntax.
234
- * Returns results ranked by BM25 relevance score.
235
- *
236
- * @param query - Search query parameters
237
- * @returns Result containing array of search results or StorageError
238
- */
239
- search(query: SearchQuery): Promise<Result2<SearchResult<T>[], StorageError2>>;
240
- /**
241
- * Remove a document from the index by ID.
242
- * No error is returned if the document does not exist.
243
- *
244
- * @param id - Document ID to remove
245
- * @returns Result indicating success or StorageError
246
- */
247
- remove(id: string): Promise<Result2<void, StorageError2>>;
248
- /**
249
- * Remove all documents from the index.
250
- *
251
- * @returns Result indicating success or StorageError
252
- */
253
- clear(): Promise<Result2<void, StorageError2>>;
254
- /**
255
- * Close the index and release resources.
256
- * The index should not be used after calling close().
257
- */
258
- close(): void;
259
- }
260
- /**
261
- * Creates an FTS5 full-text search index.
262
- *
263
- * Uses SQLite FTS5 virtual table for fast full-text search with BM25 ranking.
264
- * The database is configured with WAL mode for better concurrency.
265
- *
266
- * @typeParam T - Type of document metadata (defaults to `unknown`)
267
- * @param options - Index options including database path and table configuration
268
- * @returns An Index instance for managing documents and searching
269
- *
270
- * @example
271
- * ```typescript
272
- * // Create an index with default settings
273
- * const index = createIndex({ path: "./data/index.db" });
274
- *
275
- * // Add documents
276
- * await index.add({
277
- * id: "doc-1",
278
- * content: "Hello world",
279
- * metadata: { title: "Greeting" },
280
- * });
281
- *
282
- * // Search
283
- * const results = await index.search({ query: "hello" });
284
- *
285
- * // Cleanup
286
- * index.close();
287
- * ```
288
- *
289
- * @example
290
- * ```typescript
291
- * // Create an index with Porter stemmer for English text
292
- * const index = createIndex({
293
- * path: "./data/notes.db",
294
- * tableName: "notes_fts",
295
- * tokenizer: "porter",
296
- * });
297
- * ```
298
- */
299
- declare function createIndex<T = unknown>(options: IndexOptions): Index<T>;
300
- /**
301
- * @outfitter/index - Versioning constants
302
- */
303
- declare const INDEX_VERSION = 1;
1
+ import { createIndex } from "./shared/@outfitter/index-ewvzd5f9";
2
+ import { INDEX_VERSION } from "./shared/@outfitter/index-3xe3cd6r";
3
+ import { Index, IndexDocument, IndexMetadata, IndexOptions, SearchQuery, SearchResult, TokenizerType } from "./shared/@outfitter/index-m0h11hv5";
4
+ import { IndexMigrationRegistry, createMigrationRegistry } from "./shared/@outfitter/index-mmgx1j0h";
304
5
  export { createMigrationRegistry, createIndex, TokenizerType, SearchResult, SearchQuery, IndexOptions, IndexMigrationRegistry, IndexMetadata, IndexDocument, Index, INDEX_VERSION };
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
1
  // @bun
2
- import {
3
- createMigrationRegistry
4
- } from "./migrations.js";
5
- import"./types.js";
6
2
  import {
7
3
  createIndex
8
- } from "./fts5.js";
4
+ } from "./shared/@outfitter/index-gf30ny51.js";
5
+ import {
6
+ createMigrationRegistry
7
+ } from "./shared/@outfitter/index-1me624ny.js";
9
8
  import {
10
9
  INDEX_VERSION
11
- } from "./version.js";
10
+ } from "./shared/@outfitter/index-bbzmc40h.js";
11
+ import"./shared/@outfitter/index-8fwmfq7d.js";
12
12
  export {
13
13
  createMigrationRegistry,
14
14
  createIndex,
@@ -1,13 +1,2 @@
1
- import { Database } from "bun:sqlite";
2
- import { StorageError } from "@outfitter/contracts";
3
- import { Result } from "@outfitter/contracts";
4
- interface MigrationRegistry<TContext> {
5
- register(fromVersion: number, toVersion: number, migrate: (context: TContext) => Result<void, StorageError>): void;
6
- migrate(context: TContext, fromVersion: number, toVersion: number): Result<void, StorageError>;
7
- }
8
- interface IndexMigrationContext {
9
- readonly db: Database;
10
- }
11
- type IndexMigrationRegistry = MigrationRegistry<IndexMigrationContext>;
12
- declare function createMigrationRegistry<TContext>(): MigrationRegistry<TContext>;
1
+ import { IndexMigrationContext, IndexMigrationRegistry, MigrationRegistry, createMigrationRegistry } from "./shared/@outfitter/index-mmgx1j0h";
13
2
  export { createMigrationRegistry, MigrationRegistry, IndexMigrationRegistry, IndexMigrationContext };
@@ -1,47 +1,7 @@
1
1
  // @bun
2
- // packages/index/src/migrations.ts
3
- import { Result } from "@outfitter/contracts";
4
- function createStorageError(message, cause) {
5
- return {
6
- _tag: "StorageError",
7
- message,
8
- cause
9
- };
10
- }
11
- function createMigrationRegistry() {
12
- const steps = new Map;
13
- return {
14
- register(fromVersion, toVersion, migrate) {
15
- steps.set(fromVersion, { to: toVersion, migrate });
16
- },
17
- migrate(context, fromVersion, toVersion) {
18
- if (fromVersion === toVersion) {
19
- return Result.ok(undefined);
20
- }
21
- let current = fromVersion;
22
- const visited = new Set;
23
- while (current < toVersion) {
24
- if (visited.has(current)) {
25
- return Result.err(createStorageError(`Detected migration loop at version ${current}`));
26
- }
27
- visited.add(current);
28
- const step = steps.get(current);
29
- if (!step) {
30
- return Result.err(createStorageError(`No migration registered from version ${current}`));
31
- }
32
- const result = step.migrate(context);
33
- if (result.isErr()) {
34
- return result;
35
- }
36
- current = step.to;
37
- }
38
- if (current !== toVersion) {
39
- return Result.err(createStorageError(`Migration ended at version ${current} instead of ${toVersion}`));
40
- }
41
- return Result.ok(undefined);
42
- }
43
- };
44
- }
2
+ import {
3
+ createMigrationRegistry
4
+ } from "./shared/@outfitter/index-1me624ny.js";
45
5
  export {
46
6
  createMigrationRegistry
47
7
  };
@@ -0,0 +1,46 @@
1
+ // @bun
2
+ // packages/index/src/migrations.ts
3
+ import { Result } from "@outfitter/contracts";
4
+ function createStorageError(message, cause) {
5
+ return {
6
+ _tag: "StorageError",
7
+ message,
8
+ cause
9
+ };
10
+ }
11
+ function createMigrationRegistry() {
12
+ const steps = new Map;
13
+ return {
14
+ register(fromVersion, toVersion, migrate) {
15
+ steps.set(fromVersion, { to: toVersion, migrate });
16
+ },
17
+ migrate(context, fromVersion, toVersion) {
18
+ if (fromVersion === toVersion) {
19
+ return Result.ok(undefined);
20
+ }
21
+ let current = fromVersion;
22
+ const visited = new Set;
23
+ while (current < toVersion) {
24
+ if (visited.has(current)) {
25
+ return Result.err(createStorageError(`Detected migration loop at version ${current}`));
26
+ }
27
+ visited.add(current);
28
+ const step = steps.get(current);
29
+ if (!step) {
30
+ return Result.err(createStorageError(`No migration registered from version ${current}`));
31
+ }
32
+ const result = step.migrate(context);
33
+ if (result.isErr()) {
34
+ return result;
35
+ }
36
+ current = step.to;
37
+ }
38
+ if (current !== toVersion) {
39
+ return Result.err(createStorageError(`Migration ended at version ${current} instead of ${toVersion}`));
40
+ }
41
+ return Result.ok(undefined);
42
+ }
43
+ };
44
+ }
45
+
46
+ export { createMigrationRegistry };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @outfitter/index - Versioning constants
3
+ */
4
+ declare const INDEX_VERSION = 1;
5
+ declare const INDEX_META_TABLE = "__outfitter_index_meta";
6
+ declare const INDEX_META_KEY = "header";
7
+ export { INDEX_VERSION, INDEX_META_TABLE, INDEX_META_KEY };
@@ -0,0 +1 @@
1
+ // @bun
@@ -0,0 +1,7 @@
1
+ // @bun
2
+ // packages/index/src/version.ts
3
+ var INDEX_VERSION = 1;
4
+ var INDEX_META_TABLE = "__outfitter_index_meta";
5
+ var INDEX_META_KEY = "header";
6
+
7
+ export { INDEX_VERSION, INDEX_META_TABLE, INDEX_META_KEY };
@@ -0,0 +1,42 @@
1
+ import { Index, IndexOptions } from "./index-m0h11hv5";
2
+ /**
3
+ * Creates an FTS5 full-text search index.
4
+ *
5
+ * Uses SQLite FTS5 virtual table for fast full-text search with BM25 ranking.
6
+ * The database is configured with WAL mode for better concurrency.
7
+ *
8
+ * @typeParam T - Type of document metadata (defaults to `unknown`)
9
+ * @param options - Index options including database path and table configuration
10
+ * @returns An Index instance for managing documents and searching
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Create an index with default settings
15
+ * const index = createIndex({ path: "./data/index.db" });
16
+ *
17
+ * // Add documents
18
+ * await index.add({
19
+ * id: "doc-1",
20
+ * content: "Hello world",
21
+ * metadata: { title: "Greeting" },
22
+ * });
23
+ *
24
+ * // Search
25
+ * const results = await index.search({ query: "hello" });
26
+ *
27
+ * // Cleanup
28
+ * index.close();
29
+ * ```
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // Create an index with Porter stemmer for English text
34
+ * const index = createIndex({
35
+ * path: "./data/notes.db",
36
+ * tableName: "notes_fts",
37
+ * tokenizer: "porter",
38
+ * });
39
+ * ```
40
+ */
41
+ declare function createIndex<T = unknown>(options: IndexOptions): Index<T>;
42
+ export { createIndex };