baraqex 1.0.17 → 1.0.19

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.
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * Server-side Go WASM integration for Node.js
3
+ * Uses the standard Go WASM runtime (wasm_exec.js)
3
4
  */
4
5
  import fs from 'fs/promises';
6
+ import path from 'path';
7
+ import { pathToFileURL } from 'url';
5
8
  // Global flag to ensure we only initialize WASM once
6
9
  let initialized = false;
7
10
  /**
@@ -11,14 +14,6 @@ export async function initNodeWasm() {
11
14
  if (initialized)
12
15
  return;
13
16
  try {
14
- // Check if node requires WASM flags
15
- const nodeVersion = process.version;
16
- const majorVersion = parseInt(nodeVersion.slice(1).split('.')[0], 10);
17
- // Node.js version check for WASM flags requirement
18
- if (majorVersion < 16) {
19
- console.warn('[WASM] Note: Node.js version < 16 detected. ' +
20
- 'You may need --experimental-wasm-bigint flag for Go WASM modules.');
21
- }
22
17
  // Global WASM environment setup for Node.js
23
18
  globalThis.TextEncoder = globalThis.TextEncoder || TextEncoder;
24
19
  globalThis.TextDecoder = globalThis.TextDecoder || TextDecoder;
@@ -31,443 +26,127 @@ export async function initNodeWasm() {
31
26
  }
32
27
  }
33
28
  /**
34
- * Load a Go WASM module from a file path for server-side usage
29
+ * Load Go WASM runtime from wasm_exec.js file
35
30
  */
36
- export async function loadGoWasmFromFile(wasmFilePath, options = {}) {
37
- try {
38
- // Initialize Node.js WASM environment
39
- await initNodeWasm();
40
- // Create a proper Go runtime that matches what Go WASM expects
41
- const Go = class {
42
- constructor() {
43
- this.importObject = {
44
- gojs: {
45
- // Memory management
46
- 'runtime.wasmExit': (sp) => {
47
- const code = new DataView(this.mem.buffer).getInt32(sp + 8, true);
48
- process.exit(code);
49
- },
50
- 'runtime.wasmWrite': (sp) => {
51
- const fd = new DataView(this.mem.buffer).getInt32(sp + 8, true);
52
- const p = new DataView(this.mem.buffer).getInt32(sp + 16, true);
53
- const n = new DataView(this.mem.buffer).getInt32(sp + 24, true);
54
- if (fd === 1) { // stdout
55
- process.stdout.write(new Uint8Array(this.mem.buffer, p, n));
56
- }
57
- else if (fd === 2) { // stderr
58
- process.stderr.write(new Uint8Array(this.mem.buffer, p, n));
59
- }
60
- },
61
- 'runtime.resetMemoryDataView': () => {
62
- this.mem = this.inst?.exports.mem;
63
- },
64
- 'runtime.nanotime1': (sp) => {
65
- const nsec = Date.now() * 1000000;
66
- new DataView(this.mem.buffer).setBigInt64(sp + 8, BigInt(nsec), true);
67
- },
68
- 'runtime.walltime': (sp) => {
69
- const msec = Date.now();
70
- const sec = Math.floor(msec / 1000);
71
- const nsec = (msec % 1000) * 1000000;
72
- new DataView(this.mem.buffer).setBigInt64(sp + 8, BigInt(sec), true);
73
- new DataView(this.mem.buffer).setInt32(sp + 16, nsec, true);
74
- },
75
- 'runtime.scheduleTimeoutEvent': (sp) => {
76
- const id = this._nextCallbackTimeoutID++;
77
- const delay = new DataView(this.mem.buffer).getBigInt64(sp + 8, true);
78
- setTimeout(() => {
79
- this._resume();
80
- }, Number(delay));
81
- new DataView(this.mem.buffer).setInt32(sp + 16, id, true);
82
- },
83
- 'runtime.clearTimeoutEvent': (sp) => {
84
- // Simplified implementation
85
- },
86
- 'runtime.getRandomData': (sp) => {
87
- const buf = new DataView(this.mem.buffer).getInt32(sp + 8, true);
88
- const len = new DataView(this.mem.buffer).getInt32(sp + 16, true);
89
- crypto.getRandomValues(new Uint8Array(this.mem.buffer, buf, len));
90
- },
91
- // JavaScript interop
92
- 'syscall/js.finalizeRef': () => { },
93
- 'syscall/js.stringVal': (sp) => {
94
- const s = this._loadString(new DataView(this.mem.buffer).getInt32(sp + 8, true));
95
- this._storeValue(sp + 16, s);
96
- },
97
- 'syscall/js.valueGet': (sp) => {
98
- try {
99
- const v = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
100
- const p = this._loadString(new DataView(this.mem.buffer).getInt32(sp + 16, true));
101
- // Ensure v is a valid object before using Reflect.get
102
- if (v === null || v === undefined) {
103
- console.warn(`[WASM] valueGet called on null/undefined object for property: ${p}`);
104
- this._storeValue(sp + 24, undefined);
105
- return;
106
- }
107
- if (typeof v !== 'object' && typeof v !== 'function') {
108
- console.warn(`[WASM] valueGet called on non-object (${typeof v}) for property: ${p}`);
109
- this._storeValue(sp + 24, undefined);
110
- return;
111
- }
112
- const result = Reflect.get(v, p);
113
- this._storeValue(sp + 24, result);
114
- }
115
- catch (error) {
116
- console.warn(`[WASM] Error in valueGet:`, error);
117
- this._storeValue(sp + 24, undefined);
118
- }
119
- },
120
- 'syscall/js.valueSet': (sp) => {
121
- const v = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
122
- const p = this._loadString(new DataView(this.mem.buffer).getInt32(sp + 16, true));
123
- const x = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 24, true));
124
- Reflect.set(v, p, x);
125
- },
126
- 'syscall/js.valueDelete': (sp) => {
127
- const v = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
128
- const p = this._loadString(new DataView(this.mem.buffer).getInt32(sp + 16, true));
129
- Reflect.deleteProperty(v, p);
130
- },
131
- 'syscall/js.valueIndex': (sp) => {
132
- const v = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
133
- const i = new DataView(this.mem.buffer).getInt32(sp + 16, true);
134
- this._storeValue(sp + 20, Reflect.get(v, i));
135
- },
136
- 'syscall/js.valueSetIndex': (sp) => {
137
- const v = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
138
- const i = new DataView(this.mem.buffer).getInt32(sp + 16, true);
139
- const x = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 20, true));
140
- Reflect.set(v, i, x);
141
- },
142
- 'syscall/js.valueCall': (sp) => {
143
- try {
144
- const v = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
145
- const m = this._loadString(new DataView(this.mem.buffer).getInt32(sp + 16, true));
146
- const args = this._loadSliceOfValues(new DataView(this.mem.buffer).getInt32(sp + 24, true));
147
- const result = Reflect.apply(v[m], v, args);
148
- this._storeValue(sp + 40, result);
149
- new DataView(this.mem.buffer).setUint8(sp + 48, 1);
150
- }
151
- catch (err) {
152
- this._storeValue(sp + 40, err);
153
- new DataView(this.mem.buffer).setUint8(sp + 48, 0);
154
- }
155
- },
156
- 'syscall/js.valueInvoke': (sp) => {
157
- try {
158
- const v = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
159
- const args = this._loadSliceOfValues(new DataView(this.mem.buffer).getInt32(sp + 16, true));
160
- const result = Reflect.apply(v, undefined, args);
161
- this._storeValue(sp + 32, result);
162
- new DataView(this.mem.buffer).setUint8(sp + 40, 1);
163
- }
164
- catch (err) {
165
- this._storeValue(sp + 32, err);
166
- new DataView(this.mem.buffer).setUint8(sp + 40, 0);
167
- }
168
- },
169
- 'syscall/js.valueNew': (sp) => {
170
- try {
171
- const v = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
172
- const args = this._loadSliceOfValues(new DataView(this.mem.buffer).getInt32(sp + 16, true));
173
- const result = Reflect.construct(v, args);
174
- this._storeValue(sp + 32, result);
175
- new DataView(this.mem.buffer).setUint8(sp + 40, 1);
176
- }
177
- catch (err) {
178
- this._storeValue(sp + 32, err);
179
- new DataView(this.mem.buffer).setUint8(sp + 40, 0);
180
- }
181
- },
182
- 'syscall/js.valueLength': (sp) => {
183
- const v = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
184
- new DataView(this.mem.buffer).setInt32(sp + 16, parseInt(v.length), true);
185
- },
186
- 'syscall/js.valuePrepareString': (sp) => {
187
- const s = String(this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true)));
188
- const str = new TextEncoder().encode(s);
189
- this._storeValue(sp + 16, str);
190
- new DataView(this.mem.buffer).setInt32(sp + 24, str.length, true);
191
- },
192
- 'syscall/js.valueLoadString': (sp) => {
193
- const str = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
194
- new Uint8Array(this.mem.buffer, new DataView(this.mem.buffer).getInt32(sp + 16, true)).set(str);
195
- },
196
- 'syscall/js.valueInstanceOf': (sp) => {
197
- const v = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
198
- const t = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 16, true));
199
- new DataView(this.mem.buffer).setUint8(sp + 24, v instanceof t ? 1 : 0);
200
- },
201
- 'syscall/js.copyBytesToGo': (sp) => {
202
- const dst = new DataView(this.mem.buffer).getInt32(sp + 8, true);
203
- const src = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 16, true));
204
- new Uint8Array(this.mem.buffer, dst).set(src);
205
- new DataView(this.mem.buffer).setInt32(sp + 24, src.length, true);
206
- },
207
- 'syscall/js.copyBytesToJS': (sp) => {
208
- const dst = this._loadValue(new DataView(this.mem.buffer).getInt32(sp + 8, true));
209
- const src = new DataView(this.mem.buffer).getInt32(sp + 16, true);
210
- const len = new DataView(this.mem.buffer).getInt32(sp + 24, true);
211
- dst.set(new Uint8Array(this.mem.buffer, src, len));
212
- new DataView(this.mem.buffer).setInt32(sp + 32, len, true);
213
- },
214
- // Debug functions
215
- 'debug': (value) => {
216
- console.log('[Go WASM Debug]:', value);
217
- }
218
- }
219
- };
220
- this._nextCallbackTimeoutID = 1;
221
- this._values = [NaN, 0, null, true, false, global, this];
222
- this._goRefCounts = [];
223
- this._ids = new Map();
224
- this._idPool = [];
225
- }
226
- _storeValue(addr, v) {
227
- const nanHead = 0x7FF80000;
228
- if (typeof v === "number" && v !== 0) {
229
- if (isNaN(v)) {
230
- new DataView(this.mem.buffer).setUint32(addr + 4, nanHead, true);
231
- new DataView(this.mem.buffer).setUint32(addr, 0, true);
232
- return;
233
- }
234
- new DataView(this.mem.buffer).setFloat64(addr, v, true);
235
- return;
236
- }
237
- if (v === undefined) {
238
- new DataView(this.mem.buffer).setFloat64(addr, 0, true);
239
- return;
240
- }
241
- let id = this._ids.get(v);
242
- if (id === undefined) {
243
- id = this._idPool.pop();
244
- if (id === undefined) {
245
- id = this._values.length;
246
- }
247
- this._values[id] = v;
248
- this._goRefCounts[id] = 0;
249
- this._ids.set(v, id);
250
- }
251
- this._goRefCounts[id]++;
252
- let typeFlag = 0;
253
- switch (typeof v) {
254
- case "object":
255
- if (v !== null) {
256
- typeFlag = 1;
257
- }
258
- break;
259
- case "string":
260
- typeFlag = 2;
261
- break;
262
- case "symbol":
263
- typeFlag = 3;
264
- break;
265
- case "function":
266
- typeFlag = 4;
267
- break;
31
+ async function loadGoRuntime(goWasmPath) {
32
+ if (typeof global.Go === 'function') {
33
+ return global.Go;
34
+ }
35
+ // Try to find wasm_exec.js or wasm_exec.cjs
36
+ const possiblePaths = [
37
+ goWasmPath,
38
+ './wasm_exec.cjs',
39
+ './wasm_exec.js',
40
+ './public/wasm_exec.cjs',
41
+ './public/wasm_exec.js',
42
+ './src/wasm_exec.cjs',
43
+ './src/wasm_exec.js',
44
+ path.join(process.cwd(), 'wasm_exec.cjs'),
45
+ path.join(process.cwd(), 'wasm_exec.js'),
46
+ path.join(process.cwd(), 'public', 'wasm_exec.cjs'),
47
+ path.join(process.cwd(), 'public', 'wasm_exec.js'),
48
+ path.join(process.cwd(), 'src', 'wasm_exec.cjs'),
49
+ path.join(process.cwd(), 'src', 'wasm_exec.js')
50
+ ].filter(Boolean);
51
+ for (const wasmExecPath of possiblePaths) {
52
+ try {
53
+ const resolvedPath = path.resolve(wasmExecPath);
54
+ // Check if file exists using fs.stat instead of fs.access
55
+ try {
56
+ const stats = await fs.stat(resolvedPath);
57
+ if (!stats.isFile()) {
58
+ continue;
268
59
  }
269
- new DataView(this.mem.buffer).setUint32(addr + 4, nanHead | typeFlag, true);
270
- new DataView(this.mem.buffer).setUint32(addr, id, true);
271
60
  }
272
- _loadValue(addr) {
273
- try {
274
- // Validate address bounds
275
- if (addr < 0 || addr >= this.mem.buffer.byteLength - 8) {
276
- console.warn(`[WASM] Invalid _loadValue address: ${addr}`);
277
- return undefined;
278
- }
279
- const f = new DataView(this.mem.buffer).getFloat64(addr, true);
280
- if (f === 0) {
281
- return undefined;
282
- }
283
- if (!isNaN(f)) {
284
- return f;
285
- }
286
- const id = new DataView(this.mem.buffer).getUint32(addr, true);
287
- // Validate the ID is within bounds
288
- if (id < 0 || id >= this._values.length) {
289
- console.warn(`[WASM] Invalid value ID: ${id}, values length: ${this._values.length}`);
290
- return undefined;
291
- }
292
- return this._values[id];
293
- }
294
- catch (error) {
295
- console.warn(`[WASM] Error loading value at ${addr}:`, error);
296
- return undefined;
297
- }
61
+ catch (statError) {
62
+ continue; // File doesn't exist, try next path
298
63
  }
299
- _loadString(addr) {
300
- try {
301
- // Validate the address is within bounds
302
- if (addr < 0 || addr >= this.mem.buffer.byteLength - 8) {
303
- console.warn(`[WASM] Invalid string address: ${addr}, buffer size: ${this.mem.buffer.byteLength}`);
304
- return '';
305
- }
306
- const saddr = new DataView(this.mem.buffer).getInt32(addr + 0, true);
307
- const len = new DataView(this.mem.buffer).getInt32(addr + 8, true);
308
- // Validate string data address and length
309
- if (saddr < 0 || len < 0 || saddr + len > this.mem.buffer.byteLength) {
310
- console.warn(`[WASM] Invalid string data - addr: ${saddr}, len: ${len}, buffer size: ${this.mem.buffer.byteLength}`);
311
- return '';
312
- }
313
- return new TextDecoder("utf-8").decode(new DataView(this.mem.buffer, saddr, len));
314
- }
315
- catch (error) {
316
- console.warn(`[WASM] Error loading string at ${addr}:`, error);
317
- return '';
318
- }
64
+ // Load the Go runtime using dynamic import with file:// URL
65
+ const wasmExecUrl = pathToFileURL(resolvedPath).href;
66
+ // Clear global.Go to ensure fresh import
67
+ if (global.Go) {
68
+ delete global.Go;
319
69
  }
320
- _loadSliceOfValues(addr) {
321
- try {
322
- // Validate the address is within bounds
323
- if (addr < 0 || addr >= this.mem.buffer.byteLength - 16) {
324
- console.warn(`[WASM] Invalid slice address: ${addr}`);
325
- return [];
326
- }
327
- const array = new DataView(this.mem.buffer).getInt32(addr + 0, true);
328
- const len = new DataView(this.mem.buffer).getInt32(addr + 8, true);
329
- // Validate array parameters
330
- if (len < 0 || len > 1000) { // Reasonable limit
331
- console.warn(`[WASM] Invalid slice length: ${len}`);
332
- return [];
333
- }
334
- if (array < 0 || array + (len * 8) > this.mem.buffer.byteLength) {
335
- console.warn(`[WASM] Invalid slice data - addr: ${array}, len: ${len}`);
336
- return [];
337
- }
338
- const a = new Array(len);
339
- for (let i = 0; i < len; i++) {
340
- a[i] = this._loadValue(array + i * 8);
341
- }
342
- return a;
343
- }
344
- catch (error) {
345
- console.warn(`[WASM] Error loading slice at ${addr}:`, error);
346
- return [];
347
- }
70
+ // Import the module
71
+ await import(wasmExecUrl);
72
+ if (typeof global.Go === 'function') {
73
+ console.log(`[WASM] Loaded Go runtime from: ${resolvedPath}`);
74
+ return global.Go;
348
75
  }
349
- _resume() {
350
- if (this.inst && this.inst.exports.resume) {
351
- try {
352
- this.inst.exports.resume();
353
- }
354
- catch (error) {
355
- console.warn('[WASM] Error resuming:', error);
356
- }
357
- }
76
+ else {
77
+ console.warn(`[WASM] File found but Go class not exported: ${resolvedPath}`);
358
78
  }
359
- run(instance) {
360
- this.inst = instance;
361
- this.mem = instance.exports.mem;
362
- // Set up the global object with common browser APIs
363
- global.global = global;
364
- global.Object = Object;
365
- global.Array = Array;
366
- global.console = console;
367
- global.document = {
368
- createElement: (tag) => ({ tagName: tag, innerHTML: '', style: {} }),
369
- getElementById: () => null,
370
- querySelector: () => null
371
- };
372
- global.window = global;
373
- // Add required crypto for Go WASM
374
- if (!global.crypto) {
375
- global.crypto = {
376
- getRandomValues: (array) => {
377
- if (array && array instanceof Uint8Array) {
378
- for (let i = 0; i < array.length; i++) {
379
- array[i] = Math.floor(Math.random() * 256);
380
- }
381
- }
382
- return array;
383
- },
384
- subtle: {},
385
- randomUUID: () => {
386
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
387
- const r = Math.random() * 16 | 0;
388
- const v = c === 'x' ? r : (r & 0x3 | 0x8);
389
- return v.toString(16);
390
- });
391
- }
392
- };
393
- }
394
- if (options.debug) {
395
- console.log('[WASM] Go runtime initialized with proper imports');
396
- console.log('[WASM] Memory size:', this.mem.buffer.byteLength, 'bytes');
397
- }
398
- // Run the Go program with error handling
399
- try {
400
- if (instance.exports.run) {
401
- instance.exports.run();
402
- }
403
- }
404
- catch (error) {
405
- console.error('[WASM] Error running Go program:', error);
406
- throw error;
407
- }
408
- }
409
- };
79
+ }
80
+ catch (error) {
81
+ console.warn(`[WASM] Error loading from ${wasmExecPath}:`, error.message);
82
+ continue;
83
+ }
84
+ }
85
+ throw new Error('[WASM] Could not find wasm_exec.js. Please ensure you have the Go WASM runtime file available.\n' +
86
+ 'You can get it from: https://github.com/golang/go/blob/master/misc/wasm/wasm_exec.js\n' +
87
+ `Searched paths: ${possiblePaths.join(', ')}`);
88
+ }
89
+ /**
90
+ * Load a Go WASM module from a file path for server-side usage
91
+ */
92
+ export async function loadGoWasmFromFile(wasmFilePath, options = {}) {
93
+ try {
94
+ // Initialize Node.js WASM environment
95
+ await initNodeWasm();
96
+ if (options.debug) {
97
+ console.log('[WASM] Loading WASM from file:', wasmFilePath);
98
+ }
99
+ // Load the standard Go runtime
100
+ const GoRuntime = await loadGoRuntime(options.goWasmPath);
101
+ const go = new GoRuntime();
410
102
  // Load WASM binary
411
103
  const wasmBuffer = await fs.readFile(wasmFilePath);
412
104
  const wasmModule = await WebAssembly.compile(wasmBuffer);
413
- // Create Go instance
414
- const go = new Go();
415
- // Create imports object
105
+ // The standard wasm_exec.js provides imports under 'go' but some Go WASM modules expect 'gojs'
106
+ // Create imports object with both possible structures
107
+ const baseImports = go.importObject;
416
108
  const finalImportObject = {
417
- ...go.importObject,
109
+ ...baseImports,
110
+ // Add gojs mapping for compatibility
111
+ gojs: baseImports.go || {},
418
112
  ...options.importObject
419
113
  };
114
+ if (options.debug) {
115
+ console.log('[WASM] Available import modules:', Object.keys(finalImportObject));
116
+ console.log('[WASM] Go import functions:', Object.keys(finalImportObject.go || {}));
117
+ console.log('[WASM] Gojs import functions:', Object.keys(finalImportObject.gojs || {}));
118
+ }
420
119
  // Instantiate the WASM module
421
120
  const instance = await WebAssembly.instantiate(wasmModule, finalImportObject);
422
- // Initialize Go runtime
423
- go.run(instance);
424
- // Give the Go module more time to register global functions and handle initialization
121
+ // Initialize Go runtime (exactly like browser)
122
+ await go.run(instance);
123
+ // Give Go runtime time to initialize and register functions (like browser version)
425
124
  await new Promise(resolve => setTimeout(resolve, 1000));
426
- // Extract exported functions
427
- const exports = instance.exports;
125
+ // Extract exported functions from global scope (like browser version)
428
126
  const functions = {};
429
- // Generate wrapper functions for all exports that are functions
430
- for (const key in exports) {
431
- if (typeof exports[key] === 'function') {
432
- const exportedFunc = exports[key];
433
- functions[key] = (...args) => exportedFunc(...args);
434
- if (options.debug) {
435
- const originalFn = functions[key];
436
- functions[key] = (...args) => {
437
- console.log(`[WASM] Calling ${key}(${args.join(', ')})`);
438
- const result = originalFn(...args);
439
- console.log(`[WASM] ${key} returned:`, result);
440
- return result;
441
- };
442
- }
443
- }
444
- }
445
- // Also capture global functions exported by Go
446
- for (const key in global) {
447
- if (key.startsWith('go') && typeof global[key] === 'function') {
448
- const globalFunc = global[key];
449
- functions[key] = (...args) => globalFunc(...args);
127
+ // Look for Go functions in global scope
128
+ const globalObj = global;
129
+ for (const key in globalObj) {
130
+ if (typeof globalObj[key] === 'function' && key.startsWith('go')) {
131
+ functions[key] = globalObj[key];
450
132
  if (options.debug) {
451
- const originalFn = functions[key];
452
- functions[key] = (...args) => {
453
- console.log(`[WASM] Calling global ${key}(${args.join(', ')})`);
454
- const result = originalFn(...args);
455
- console.log(`[WASM] ${key} returned:`, result);
456
- return result;
457
- };
133
+ console.log(`[WASM] Found function: ${key}`);
458
134
  }
459
135
  }
460
136
  }
461
137
  const wasmInstance = {
462
138
  instance,
463
139
  module: wasmModule,
464
- exports,
140
+ exports: instance.exports,
465
141
  functions
466
142
  };
467
143
  // Run onLoad callback if provided
468
144
  if (options.onLoad) {
469
145
  options.onLoad(wasmInstance);
470
146
  }
147
+ if (options.debug) {
148
+ console.log(`[WASM] Module loaded successfully with ${Object.keys(functions).length} functions`);
149
+ }
471
150
  return wasmInstance;
472
151
  }
473
152
  catch (error) {
@@ -475,4 +154,28 @@ export async function loadGoWasmFromFile(wasmFilePath, options = {}) {
475
154
  throw error;
476
155
  }
477
156
  }
157
+ /**
158
+ * Call a Go WASM function in Node.js environment
159
+ */
160
+ export function callWasmFunction(funcName, ...args) {
161
+ const func = global[funcName];
162
+ if (typeof func !== 'function') {
163
+ throw new Error(`Function ${funcName} not found. Make sure the WASM module is loaded.`);
164
+ }
165
+ return func(...args);
166
+ }
167
+ /**
168
+ * Check if Go WASM is ready in Node.js
169
+ */
170
+ export function isWasmReady() {
171
+ const globalObj = global;
172
+ return Object.keys(globalObj).some(key => key.startsWith('go') && typeof globalObj[key] === 'function');
173
+ }
174
+ /**
175
+ * Get all available Go WASM functions in Node.js
176
+ */
177
+ export function getWasmFunctions() {
178
+ const globalObj = global;
179
+ return Object.keys(globalObj).filter(key => key.startsWith('go') && typeof globalObj[key] === 'function');
180
+ }
478
181
  //# sourceMappingURL=wasm.js.map