'use client'; import type { UserProfile, SPFPassport } from './auth/types'; /** * WASM module interface with proper TypeScript typing */ interface PassportWASM { parse_spf_file(data: Uint8Array, password: string): Promise; get_profiles_from_passport(data: Uint8Array, password: string): Promise; validate_spf_signature(data: Uint8Array, signature: Uint8Array): Promise; } /** * WASM loader class for managing the WASM module */ export class PassportWASMLoader { private module: PassportWASM | null = null; private isLoading: boolean = false; private loadPromise: Promise | null = null; /** * Initialize the WASM module */ async init(): Promise { if (this.module) { return this.module; } if (this.loadPromise) { return this.loadPromise; } this.isLoading = true; this.loadPromise = this.loadWASMModule(); try { this.module = await this.loadPromise; return this.module; } catch (error) { this.loadPromise = null; this.isLoading = false; throw error; } } /** * Load the WASM module dynamically */ private async loadWASMModule(): Promise { if (typeof window === 'undefined') { throw new Error('WASM module can only be loaded in browser environment'); } try { // Dynamically import the WASM bindings // With bundler target, the module is automatically initialized on import // but we need to ensure the WASM memory is ready before calling functions const wasmModule = await import('./wasm-pkg/sharenet_passport_wasm'); // Test that the WASM module is properly initialized by checking if // the wasm memory is accessible through a simple property access // This ensures the WASM module is fully loaded before we use it if (!wasmModule || typeof wasmModule.parse_spf_file !== 'function') { throw new Error('WASM module exports not properly loaded'); } // Create wrapper functions with proper typing const wasmWrapper: PassportWASM = { parse_spf_file: async (data: Uint8Array, password: string): Promise => { const result = wasmModule.parse_spf_file(data, password); // The WASM function returns a JsValue that we need to convert // For now, we'll assume it returns the correct structure return result as unknown as SPFPassport; }, get_profiles_from_passport: async (data: Uint8Array, password: string): Promise => { const result = wasmModule.get_profiles_from_passport(data, password); return result as unknown as UserProfile[]; }, validate_spf_signature: async (data: Uint8Array, signature: Uint8Array): Promise => { return wasmModule.validate_spf_signature(data, signature); }, }; return wasmWrapper; } catch (error) { console.error('Failed to load WASM module:', error); throw new Error(`Failed to load WASM module: ${error instanceof Error ? error.message : 'Unknown error'}`); } } /** * Check if the module is loaded */ isLoaded(): boolean { return this.module !== null; } /** * Check if the module is currently loading */ getIsLoading(): boolean { return this.isLoading; } /** * Get the loaded module (throws if not loaded) */ getModule(): PassportWASM { if (!this.module) { throw new Error('WASM module not loaded. Call init() first.'); } return this.module; } } // Create a singleton instance export const passportWASM = new PassportWASMLoader();