Skip to content

v0.15.0

Latest

Choose a tag to compare

@Stevenic Stevenic released this 24 May 18:09
7052e73

v0.15.0 — Performance & reliability

Non-breaking performance and bug-fix release on top of a dependency-update wave. Vectra's own API is fully backward-compatible; only direct callers of bumped SDKs (most notably openai 4 → 6) need to review their code.

Install Vectra from NPM

Highlights

  • Re-upserting unchanged documents is a no-op instead of O(chunks) embedding calls.
  • Faster transactions, faster top-K queries, faster bulk delete.
  • Fixed a long-standing bug where upsertItem left a stale precomputed norm, silently degrading cosine rankings.
  • Fixed a Windows-only FolderWatcher crash for paths under os.tmpdir() (and anywhere else 8.3 short names resolve).
  • Test coverage is up to 97.7% statements / 91.5% branches (from ~94.6% / 87.1%).

Performance

Skip-if-unchanged document upsert. LocalDocumentIndex.upsertDocument now hashes text + docType + metadata (canonicalized, SHA-256) and stores the hash on the catalog. If you re-upsert a URI with byte-identical content, the call returns the existing document handle without re-chunking or re-embedding. Measured: a 100-file no-op sync that previously took ~505s of pure re-embed overhead now finishes in under a second.

Old catalogs bootstrap on first upsert per URI, then short-circuit. No catalog version bump. Opt out with { force: true } as the 5th argument (e.g., after rotating embeddings models).

Engine improvements:

  • beginUpdate no longer deep-clones vectors — shallow array copy saves O(N·D) memory per upsert.
  • queryItems uses a bounded min-heap for top-K — O(N log K) instead of O(N log N).
  • queryItems loads external metadata in parallel.
  • deleteDocument removes all chunks in one pass via the new public LocalIndex.deleteItems(ids) helper — O(N) instead of O(N·M).

Bug fixes

Stale precomputed norm after upsertItem. Upsert previously kept the old norm when the vector changed, skewing every subsequent cosine ranking against that item. Indexes built with prior versions self-heal on the next upsert per item.

FolderWatcher Windows crash with 8.3 short-name paths. The watcher now resolves paths through fs.realpath before calling fs.watch, avoiding a libuv assertion (!_wcsnicmp in fs-event.c) on paths under os.tmpdir(). It also no longer uses fs.watch(..., { recursive: true }) — it walks the tree and watches each directory individually, adding/removing watchers as subdirs appear or disappear.

Behavior note: URIs stored in an index for paths that previously contained 8.3 short names will now be in their canonical long-name form. If you store Vectra URIs externally, paths under os.tmpdir() (or similar) may differ.

Testing & internals

  • New src/internals/transformersLoader.ts test seam — @huggingface/transformers 4.x marks its ESM exports as non-configurable, which broke the prior sinon.stub(module, 'pipeline') approach in tests. Production behavior unchanged.
  • Linux CI now correctly runs all spec files (test scripts quote the glob).

Dependency updates

Runtime — major bumps (review direct usage): openai 4.104.0 → 6.33.0, @huggingface/transformers 3.8.1 → 4.0.1, dotenv 16.5.0 → 17.4.1, protobufjs 7.5.4 → 8.0.0, uuid 11.1.0 → 13.0.0, yargs 17.7.2 → 18.0.0.

Runtime — minor/patch: wink-nlp 2.4.0, cheerio 1.2.0, turndown 7.2.4.

Dev/tooling: typescript 5.9.3, eslint 10.2.0, mocha 11.7.5, nyc 18.0.0, webpack-cli 7.0.2, @types/node 25.5.2, @types/uuid 11.0.0, @types/yargs 17.0.35.

GitHub Actions: checkout v6, setup-node v6, deploy-pages v5, upload-pages-artifact v5, configure-pages v6.

Upgrading from v0.14.x

No required code changes. Three things to watch for:

  1. Direct openai SDK usage alongside OpenAIEmbeddings — Vectra's wrapper is unchanged, but the underlying SDK jumped 4 → 6.
  2. URIs from paths under os.tmpdir() (or anywhere else 8.3 short names resolve) — now in canonical long-name form.
  3. Cosine rankings post-upsertItem in v0.14.x — self-heal on next upsert per item, or force a refresh sooner.