@context-vault/core 3.0.0 → 3.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@context-vault/core",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "type": "module",
5
5
  "description": "Pure local engine: capture, index, search, and utilities for context-vault",
6
6
  "main": "dist/main.js",
package/src/capture.ts CHANGED
@@ -266,7 +266,7 @@ export function updateEntryFile(
266
266
  };
267
267
  }
268
268
 
269
- export async function captureAndIndex(ctx: BaseCtx, data: CaptureInput): Promise<CaptureResult> {
269
+ export async function captureAndIndex(ctx: BaseCtx, data: CaptureInput, precomputedEmbedding?: Float32Array | null): Promise<CaptureResult> {
270
270
  let previousContent: string | null = null;
271
271
  if (categoryFor(data.kind) === "entity" && data.identity_key) {
272
272
  const identitySlug = slugify(data.identity_key);
@@ -279,7 +279,7 @@ export async function captureAndIndex(ctx: BaseCtx, data: CaptureInput): Promise
279
279
 
280
280
  const entry = writeEntry(ctx, data);
281
281
  try {
282
- await indexEntry(ctx, entry);
282
+ await indexEntry(ctx, entry, precomputedEmbedding);
283
283
  if (entry.supersedes?.length && ctx.stmts.updateSupersededBy) {
284
284
  for (const supersededId of entry.supersedes) {
285
285
  if (typeof supersededId === "string" && supersededId.trim()) {
package/src/db.ts CHANGED
@@ -107,6 +107,7 @@ export async function initDatabase(dbPath: string): Promise<DatabaseSync> {
107
107
  const db = new DatabaseSync(path, { allowExtension: true });
108
108
  db.exec("PRAGMA journal_mode = WAL");
109
109
  db.exec("PRAGMA foreign_keys = ON");
110
+ db.exec("PRAGMA busy_timeout = 3000");
110
111
  try {
111
112
  sqliteVec.load(db);
112
113
  } catch (e) {
@@ -124,6 +125,7 @@ export async function initDatabase(dbPath: string): Promise<DatabaseSync> {
124
125
  );
125
126
 
126
127
  const backupPath = `${dbPath}.v${version}.backup`;
128
+ let backupSucceeded = false;
127
129
  try {
128
130
  db.close();
129
131
  if (existsSync(dbPath)) {
@@ -131,6 +133,9 @@ export async function initDatabase(dbPath: string): Promise<DatabaseSync> {
131
133
  console.error(
132
134
  `[context-vault] Backed up old database to: ${backupPath}`,
133
135
  );
136
+ backupSucceeded = true;
137
+ } else {
138
+ backupSucceeded = true;
134
139
  }
135
140
  } catch (backupErr) {
136
141
  console.error(
@@ -138,6 +143,13 @@ export async function initDatabase(dbPath: string): Promise<DatabaseSync> {
138
143
  );
139
144
  }
140
145
 
146
+ if (!backupSucceeded) {
147
+ throw new Error(
148
+ `[context-vault] Aborting schema migration: backup failed for ${dbPath}. ` +
149
+ `Fix the backup issue or manually back up the file before upgrading.`,
150
+ );
151
+ }
152
+
141
153
  unlinkSync(dbPath);
142
154
  try { unlinkSync(dbPath + "-wal"); } catch {}
143
155
  try { unlinkSync(dbPath + "-shm"); } catch {}
package/src/index.ts CHANGED
@@ -13,6 +13,7 @@ const EMBED_BATCH_SIZE = 32;
13
13
  export async function indexEntry(
14
14
  ctx: BaseCtx,
15
15
  entry: IndexEntryInput & { supersedes?: string[] | null; related_to?: string[] | null },
16
+ precomputedEmbedding?: Float32Array | null,
16
17
  ): Promise<void> {
17
18
  const {
18
19
  id, kind, category, title, body, meta, tags, source,
@@ -92,8 +93,16 @@ export async function indexEntry(
92
93
  }
93
94
 
94
95
  if (cat !== "event") {
95
- const embeddingText = [title, body].filter(Boolean).join(" ");
96
- const embedding = await ctx.embed(embeddingText);
96
+ let embedding: Float32Array | null = null;
97
+ if (precomputedEmbedding !== undefined) {
98
+ embedding = precomputedEmbedding;
99
+ } else {
100
+ try {
101
+ embedding = await ctx.embed([title, body].filter(Boolean).join(" "));
102
+ } catch (embedErr) {
103
+ console.warn(`[context-vault] embed() failed for entry ${id} — skipping vec insert: ${(embedErr as Error).message}`);
104
+ }
105
+ }
97
106
 
98
107
  if (embedding) {
99
108
  try { ctx.deleteVec(rowid); } catch { /* no-op */ }