diff --git a/javascript/lib.cpp b/javascript/lib.cpp index b259f0b0..81f5c2d7 100644 --- a/javascript/lib.cpp +++ b/javascript/lib.cpp @@ -44,6 +44,7 @@ class CompiledIndex : public Napi::ObjectWrap { Napi::Value Count(Napi::CallbackInfo const& ctx); std::unique_ptr native_; + std::mutex mtx; }; Napi::Object CompiledIndex::Init(Napi::Env env, Napi::Object exports) { @@ -165,13 +166,23 @@ void CompiledIndex::Add(Napi::CallbackInfo const& ctx) { // Create an instance of the executor with the default number of threads auto run_parallel = [&](auto vectors) { + std::string error = ""; executor_stl_t executor; executor.fixed(tasks, [&](std::size_t /*thread_idx*/, std::size_t task_idx) { add_result_t result = native_->add(static_cast(keys[task_idx]), vectors + task_idx * native_->dimensions()); - if (!result) - Napi::Error::New(ctx.Env(), result.error.release()).ThrowAsJavaScriptException(); + if (!result) { + std::lock_guard lock(mtx); + error + .append(""); + } }); + if (error.size() > 0) + Napi::Error::New(ctx.Env(), error).ThrowAsJavaScriptException(); }; Napi::TypedArray vectors = ctx[1].As(); diff --git a/javascript/usearch.test.js b/javascript/usearch.test.js index 5210a2bd..482c994f 100644 --- a/javascript/usearch.test.js +++ b/javascript/usearch.test.js @@ -166,7 +166,28 @@ test('Invalid operations', async (t) => { () => index.add(42n, new Float32Array([0.2, 0.6, 0.4])), { name: 'Error', - message: 'Duplicate keys not allowed in high-level wrappers' + message: '' + } + ); + }); + + await t.test('Batch add containing the same key', () => { + const index = new usearch.Index({ + metric: "l2sq", + connectivity: 16, + dimensions: 3, + }); + index.add(42n, new Float32Array([0.2, 0.6, 0.4])); + assert.throws( + () => { + index.add( + [41n, 42n, 43n], + [[0.1, 0.6, 0.4], [0.2, 0.6, 0.4], [0.3, 0.6, 0.4]] + ); + }, + { + name: 'Error', + message: '' } ); }); @@ -232,7 +253,7 @@ test('Serialization', async (t) => { () => index.add(43n, new Float32Array([0.2, 0.6, 0.4])), { name: 'Error', - message: "Can't add to an immutable index" + message: "" } ); });