fix(rvf-sdk): ergonomic query count arg + clear create-on-existing error (#657, #658)#696
fix(rvf-sdk): ergonomic query count arg + clear create-on-existing error (#657, #658)#696ohdearquant wants to merge 1 commit into
Conversation
…ror (ruvnet#657, ruvnet#658) ruvnet#657: RvfDatabase.query() accepted only a positional numeric count; passing an options object ({k}/{topK}/{limit}) put the object in the count slot and leaked a low-level "Failed to convert napi value Object into rust type u32" error. query() now accepts both forms and validates the count, throwing a clear InvalidArgument (new SDK code) for a missing/non-positive-integer count before crossing N-API. ruvnet#658: NodeBackend.create() on a path that already held a file surfaced the native FsyncFailed durability error, sending debugging the wrong way. It now checks for an existing file first and throws a clear FileExists (new SDK code) pointing at open() or { overwrite: true }; overwrite removes the old file and its .idmap.json sidecar before creating. dist/ regenerated via tsc. scripts/smoke-query-create.mjs verifies both against the built output (11 checks, no native addon required for ruvnet#657). Co-Authored-By: Leo <noreply@khive.ai>
|
Reviewed this (independently, not just the PR description — checked out the diff and traced the actual code paths). Found a blocker that needs a rebase before this can merge: Hard error-code collision. This PR adds Suggest rebasing onto current main and moving Two non-blocking things worth a look while rebasing:
Happy to help rebase this if useful — just didn't want to push to your branch without asking first. |
Fixes #657 and #658 — two
@ruvector/rvfJS SDK papercuts where a mistaken callform leaked a misleading low-level error instead of a clear, actionable one. Both
fixes live in the SDK layer (
database.ts/backend.ts); no native rebuild.#657 —
query()options-object formRvfDatabase.query(vector, k, options)accepted only a positional numerick.Passing an options object (
query(vec, { k: 2 }), or{topK}/{limit}, as mostvector-DB JS APIs allow) put the object in the
kslot, which crossed N-API andthrew
Failed to convert napi value Object into rust type u32.Now
query()accepts both forms and validates before dispatch:query(vec, 10)— positional (unchanged).query(vec, { k: 10, efSearch: 200 })— object form;topKandlimitareaccepted as aliases for
k; the remaining fields pass through as query options.RvfErrorwith the newRvfErrorCode.InvalidArgumentinstead of the N-API error.#658 —
create()on an existing pathcreate()on a path that already held a valid.rvfsurfaced the nativeFsyncFailed(durability) error — implying a disk/OS fault when the real cause wasjust "the file already exists."
NodeBackend.create()now checks first and throws aclear
RvfErrorwith the newRvfErrorCode.FileExists, pointing atopen()or a new{ overwrite: true }option.overwriteremoves the old file and its.idmap.jsonsidecar before creating, so no stale string-id map leaks in.Additive / compatible
0xFF__) error codes:FileExists = 0xff04,InvalidArgument = 0xff05. No existing code changed.RvfOptions.overwrite(defaultfalse= current behavior).query()'s positional-number form is unchanged; the object form is new surface.dist/regenerated withtsc(this package commits its build output;filespublishes
dist/only). Stalesrc/*.jsartifacts are not referenced bypackage.jsonand were left untouched.Verification
scripts/smoke-query-create.mjs(alsonpm run smoke) exercises both fixes againstthe built
dist/. #657 runs with no native addon (mock backend viafromBackend);#658 runs when a native/stub addon is resolvable.
tsc --noEmit(strict) is clean. Note:#659(ingestBatch metadata) is a related butseparate change touching the native ingest/query path — not included here.