@wiscale/velesdb-sdk 1.13.5 → 1.13.7

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.mts CHANGED
@@ -1375,7 +1375,10 @@ declare class WasmBackend implements IVelesDBBackend {
1375
1375
  private wasmModule;
1376
1376
  private collections;
1377
1377
  private _initialized;
1378
+ private _initInFlight;
1379
+ private _initGen;
1378
1380
  init(): Promise<void>;
1381
+ private runInit;
1379
1382
  isInitialized(): boolean;
1380
1383
  close(): Promise<void>;
1381
1384
  capabilities(): Readonly<CapabilityMap>;
package/dist/index.d.ts CHANGED
@@ -1375,7 +1375,10 @@ declare class WasmBackend implements IVelesDBBackend {
1375
1375
  private wasmModule;
1376
1376
  private collections;
1377
1377
  private _initialized;
1378
+ private _initInFlight;
1379
+ private _initGen;
1378
1380
  init(): Promise<void>;
1381
+ private runInit;
1379
1382
  isInitialized(): boolean;
1380
1383
  close(): Promise<void>;
1381
1384
  capabilities(): Readonly<CapabilityMap>;
package/dist/index.js CHANGED
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
8
11
  var __export = (target, all) => {
9
12
  for (var name in all)
10
13
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -27,6 +30,50 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
30
  ));
28
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
32
 
33
+ // src/backends/wasm-node-loader.ts
34
+ var wasm_node_loader_exports = {};
35
+ __export(wasm_node_loader_exports, {
36
+ isNodeRuntime: () => isNodeRuntime,
37
+ loadWasmBytesNode: () => loadWasmBytesNode
38
+ });
39
+ function isNodeRuntime() {
40
+ return typeof process !== "undefined" && Boolean(process.versions?.node);
41
+ }
42
+ async function loadWasmBytesNode() {
43
+ const [{ createRequire }, { readFile, readdir }, path] = await Promise.all([
44
+ import("module"),
45
+ import("fs/promises"),
46
+ import("path")
47
+ ]);
48
+ const cjsFilename = typeof __filename !== "undefined" ? __filename : void 0;
49
+ const moduleId = typeof cjsFilename === "string" && cjsFilename.length > 0 ? cjsFilename : import_meta.url;
50
+ const require2 = createRequire(moduleId);
51
+ const pkgJsonPath = require2.resolve("@wiscale/velesdb-wasm/package.json");
52
+ const pkgDir = path.dirname(pkgJsonPath);
53
+ const entries = await readdir(pkgDir);
54
+ const wasmFile = pickWasmBinary(entries);
55
+ if (!wasmFile) {
56
+ throw new Error(
57
+ `Cannot locate a *.wasm binary in @wiscale/velesdb-wasm at ${pkgDir}. The Node.js path expects wasm-pack output (e.g. velesdb_wasm_bg.wasm) to be present alongside package.json.`
58
+ );
59
+ }
60
+ return readFile(path.join(pkgDir, wasmFile));
61
+ }
62
+ function pickWasmBinary(entries) {
63
+ const bg = entries.find((name) => name.endsWith("_bg.wasm"));
64
+ if (bg !== void 0) {
65
+ return bg;
66
+ }
67
+ return entries.find((name) => name.endsWith(".wasm"));
68
+ }
69
+ var import_meta;
70
+ var init_wasm_node_loader = __esm({
71
+ "src/backends/wasm-node-loader.ts"() {
72
+ "use strict";
73
+ import_meta = {};
74
+ }
75
+ });
76
+
30
77
  // src/index.ts
31
78
  var index_exports = {};
32
79
  __export(index_exports, {
@@ -953,6 +1000,17 @@ var WasmBackend = class {
953
1000
  this.wasmModule = null;
954
1001
  this.collections = /* @__PURE__ */ new Map();
955
1002
  this._initialized = false;
1003
+ // Memoized single-shot init promise. Subsequent concurrent calls to init()
1004
+ // await the same in-flight initialization instead of racing into duplicate
1005
+ // wasm-bindgen `default()` invocations. Cleared on close() so a fresh
1006
+ // backend instance can re-initialize if needed.
1007
+ this._initInFlight = null;
1008
+ // Generation token bumped by close(). runInit() captures the token at
1009
+ // entry and refuses to publish its result if close() advanced the
1010
+ // generation while the async work was in flight. Without this, calling
1011
+ // close() during an in-flight init() would let the racy completion of
1012
+ // runInit() flip _initialized back to true after close() set it false.
1013
+ this._initGen = 0;
956
1014
  }
957
1015
  // ========================================================================
958
1016
  // Lifecycle
@@ -961,9 +1019,30 @@ var WasmBackend = class {
961
1019
  if (this._initialized) {
962
1020
  return;
963
1021
  }
1022
+ if (this._initInFlight) {
1023
+ return this._initInFlight;
1024
+ }
1025
+ const gen = this._initGen;
1026
+ this._initInFlight = this.runInit(gen).finally(() => {
1027
+ if (this._initGen === gen) {
1028
+ this._initInFlight = null;
1029
+ }
1030
+ });
1031
+ return this._initInFlight;
1032
+ }
1033
+ async runInit(gen) {
964
1034
  try {
965
- this.wasmModule = await import("@wiscale/velesdb-wasm");
966
- await this.wasmModule.default();
1035
+ const mod = await import("@wiscale/velesdb-wasm");
1036
+ const nodeLoader = await Promise.resolve().then(() => (init_wasm_node_loader(), wasm_node_loader_exports));
1037
+ if (nodeLoader.isNodeRuntime()) {
1038
+ await mod.default(await nodeLoader.loadWasmBytesNode());
1039
+ } else {
1040
+ await mod.default();
1041
+ }
1042
+ if (this._initGen !== gen) {
1043
+ return;
1044
+ }
1045
+ this.wasmModule = mod;
967
1046
  this._initialized = true;
968
1047
  } catch (error) {
969
1048
  throw new ConnectionError(
@@ -981,6 +1060,9 @@ var WasmBackend = class {
981
1060
  }
982
1061
  this.collections.clear();
983
1062
  this._initialized = false;
1063
+ this._initInFlight = null;
1064
+ this.wasmModule = null;
1065
+ this._initGen += 1;
984
1066
  }
985
1067
  capabilities() {
986
1068
  return WASM_CAPABILITIES;
package/dist/index.mjs CHANGED
@@ -862,6 +862,17 @@ var WasmBackend = class {
862
862
  this.wasmModule = null;
863
863
  this.collections = /* @__PURE__ */ new Map();
864
864
  this._initialized = false;
865
+ // Memoized single-shot init promise. Subsequent concurrent calls to init()
866
+ // await the same in-flight initialization instead of racing into duplicate
867
+ // wasm-bindgen `default()` invocations. Cleared on close() so a fresh
868
+ // backend instance can re-initialize if needed.
869
+ this._initInFlight = null;
870
+ // Generation token bumped by close(). runInit() captures the token at
871
+ // entry and refuses to publish its result if close() advanced the
872
+ // generation while the async work was in flight. Without this, calling
873
+ // close() during an in-flight init() would let the racy completion of
874
+ // runInit() flip _initialized back to true after close() set it false.
875
+ this._initGen = 0;
865
876
  }
866
877
  // ========================================================================
867
878
  // Lifecycle
@@ -870,9 +881,30 @@ var WasmBackend = class {
870
881
  if (this._initialized) {
871
882
  return;
872
883
  }
884
+ if (this._initInFlight) {
885
+ return this._initInFlight;
886
+ }
887
+ const gen = this._initGen;
888
+ this._initInFlight = this.runInit(gen).finally(() => {
889
+ if (this._initGen === gen) {
890
+ this._initInFlight = null;
891
+ }
892
+ });
893
+ return this._initInFlight;
894
+ }
895
+ async runInit(gen) {
873
896
  try {
874
- this.wasmModule = await import("@wiscale/velesdb-wasm");
875
- await this.wasmModule.default();
897
+ const mod = await import("@wiscale/velesdb-wasm");
898
+ const nodeLoader = await import("./wasm-node-loader-7G6P7L2Z.mjs");
899
+ if (nodeLoader.isNodeRuntime()) {
900
+ await mod.default(await nodeLoader.loadWasmBytesNode());
901
+ } else {
902
+ await mod.default();
903
+ }
904
+ if (this._initGen !== gen) {
905
+ return;
906
+ }
907
+ this.wasmModule = mod;
876
908
  this._initialized = true;
877
909
  } catch (error) {
878
910
  throw new ConnectionError(
@@ -890,6 +922,9 @@ var WasmBackend = class {
890
922
  }
891
923
  this.collections.clear();
892
924
  this._initialized = false;
925
+ this._initInFlight = null;
926
+ this.wasmModule = null;
927
+ this._initGen += 1;
893
928
  }
894
929
  capabilities() {
895
930
  return WASM_CAPABILITIES;
@@ -0,0 +1,35 @@
1
+ // src/backends/wasm-node-loader.ts
2
+ function isNodeRuntime() {
3
+ return typeof process !== "undefined" && Boolean(process.versions?.node);
4
+ }
5
+ async function loadWasmBytesNode() {
6
+ const [{ createRequire }, { readFile, readdir }, path] = await Promise.all([
7
+ import("module"),
8
+ import("fs/promises"),
9
+ import("path")
10
+ ]);
11
+ const cjsFilename = typeof __filename !== "undefined" ? __filename : void 0;
12
+ const moduleId = typeof cjsFilename === "string" && cjsFilename.length > 0 ? cjsFilename : import.meta.url;
13
+ const require2 = createRequire(moduleId);
14
+ const pkgJsonPath = require2.resolve("@wiscale/velesdb-wasm/package.json");
15
+ const pkgDir = path.dirname(pkgJsonPath);
16
+ const entries = await readdir(pkgDir);
17
+ const wasmFile = pickWasmBinary(entries);
18
+ if (!wasmFile) {
19
+ throw new Error(
20
+ `Cannot locate a *.wasm binary in @wiscale/velesdb-wasm at ${pkgDir}. The Node.js path expects wasm-pack output (e.g. velesdb_wasm_bg.wasm) to be present alongside package.json.`
21
+ );
22
+ }
23
+ return readFile(path.join(pkgDir, wasmFile));
24
+ }
25
+ function pickWasmBinary(entries) {
26
+ const bg = entries.find((name) => name.endsWith("_bg.wasm"));
27
+ if (bg !== void 0) {
28
+ return bg;
29
+ }
30
+ return entries.find((name) => name.endsWith(".wasm"));
31
+ }
32
+ export {
33
+ isNodeRuntime,
34
+ loadWasmBytesNode
35
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wiscale/velesdb-sdk",
3
- "version": "1.13.5",
3
+ "version": "1.13.7",
4
4
  "description": "VelesDB TypeScript SDK: The Local Vector Database for AI & RAG. Microsecond semantic search in Browser & Node.js.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",