Skip to content

Config Module Architecture

Goals

The Config module provides flexible ONNX Runtime configuration to solve: 1. Hard-coded paths – avoid baking WASM locations into source files. 2. Timing issues – handle cases where ORT loads before or after configuration. 3. Adaptability – support single or multiple fallback paths.

Design

Module structure

Config module
├─ Path storage (module-level state)
├─ Initialiser (initOrtEnvironment)
├─ Path setters/getters
└─ Utility helpers (delayed application, validation)

Configuration Flow

  1. Application bootstraps – App module calls initOrtEnvironment() during App.init()
  2. Path configuration – Paths are set via setOrtWasmPaths() or passed directly to initOrtEnvironment()
  3. ORT availability check – Check whether ORT is already loaded:
  4. Yes → Apply configuration immediately via ort.env.wasm.wasmPaths
  5. No → Start polling mechanism to apply configuration when ORT loads
  6. Configuration applied – Logs confirmation when paths are successfully set

Delayed Configuration

If ORT is not present when configuration runs, the module polls until it loads: - Poll interval: 50 ms. - As soon as window.ort becomes available, paths are applied and polling stops. - Avoids blocking the main thread.

Polling Strategy: - Poll interval: 50ms (non-blocking) - Polling function: applyConfigWhenReady() checks for window.ort availability - Automatic application: As soon as window.ort becomes available, paths are applied and polling stops - Non-blocking: Uses setTimeout to avoid blocking the main thread

Implementation:

const applyConfigWhenReady = () => {
  if ((window as any).ort) {
    const ort = (window as any).ort;
    ort.env.wasm.wasmPaths = getOrtWasmPaths();
    console.log(`[Visionary] ONNX Runtime WASM paths configured (delayed): ${getOrtWasmPaths()}`);
  } else {
    // Continue polling if ORT not yet available
    setTimeout(applyConfigWhenReady, 50);
  }
};

Benefits: - Works regardless of ORT loading order - No blocking operations - Automatic retry until ORT is available - Clear logging for debugging

Path Configuration

Path Format

  • Single path: '/src/ort/' → stored as-is
  • Multiple paths: ['/path1/', '/path2/'] → stored as '/path1/,/path2/' (comma-separated)

Path Application

The final value is set in ort.env.wasm.wasmPaths. ORT tries each location in order until files resolve:

  1. First path is tried
  2. If files not found, second path is tried
  3. Continues until files are found or all paths exhausted

Default Path

The module provides a default path: /src/ort/

This is used when: - initOrtEnvironment() is called without arguments - getDefaultOrtWasmPaths() is called explicitly

Path Storage

Paths are stored in module-level state:

let ortWasmPaths: string = '/src/ort/';

This ensures: - Configuration persists across function calls - Can be set before ORT is available - Can be retrieved at any time via getOrtWasmPaths()

Error Handling

The Config module uses a graceful error handling approach:

Warnings (Non-Fatal)

  • ORT not available: Logs a warning but does not throw:
    console.warn('[Visionary] ONNX Runtime not available, configuration will be applied when ort is loaded');
    
  • Delayed application: Starts polling mechanism automatically

Success Logging

  • Immediate application: Logs when ORT is already loaded:
    console.log(`[Visionary] ONNX Runtime WASM paths configured: ${getOrtWasmPaths()}`);
    
  • Delayed application: Logs when configuration is applied after polling:
    console.log(`[Visionary] ONNX Runtime WASM paths configured (delayed): ${getOrtWasmPaths()}`);
    

Configuration Verification

Use isOrtConfigured() to verify configuration state:

if (isOrtConfigured()) {
  console.log('ORT is ready and configured');
} else {
  console.warn('ORT configuration pending...');
}

Usage Patterns

Used by App module during initialization:

import { initOrtEnvironment, getDefaultOrtWasmPaths } from 'src/config';

// In App.init()
const wasmPaths = getDefaultOrtWasmPaths();
initOrtEnvironment(wasmPaths);

2. Configure with Custom Paths

Set paths explicitly before initialization:

import { setOrtWasmPaths, initOrtEnvironment } from 'src/config';

setOrtWasmPaths('/custom/ort/path/');
initOrtEnvironment();

3. Multiple Fallback Paths

Provide multiple paths for redundancy:

setOrtWasmPaths([
  'https://cdn.example.com/ort/',  // Try CDN first
  '/local/cache/ort/',              // Fallback to local cache
  '/src/ort/'                       // Final fallback
]);
initOrtEnvironment();

4. Check Configuration State

Verify ORT is ready before loading models:

import { isOrtConfigured, initOrtEnvironment } from 'src/config';

if (!isOrtConfigured()) {
  initOrtEnvironment();
  // Wait a bit for delayed configuration
  setTimeout(() => {
    if (isOrtConfigured()) {
      console.log('ORT ready');
    }
  }, 100);
}

5. Runtime Path Updates

Update paths dynamically (rare use case):

// Get current paths
const currentPaths = getOrtWasmPaths();

// Update with new paths
setOrtWasmPaths(['/new/path/']);
initOrtEnvironment();

Integration Points

App Module Integration

The App module automatically initializes ORT configuration:

// In App.init() - line 110-113
const wasmPaths = getDefaultOrtWasmPaths();
initOrtEnvironment(wasmPaths);
console.log(`[App] Initialized ORT environment with paths: ${wasmPaths}`);

Timing: 1. ORT configuration happens first (before WebGPU initialization) 2. WebGPU initialization may share device with ORT 3. ONNX models can be loaded after configuration

ONNX Module Dependency

The ONNX module relies on Config module to ensure: - ORT environment is properly configured - WASM paths are set before model loading - GPU device sharing works correctly

WebGPU Context Integration

The initWebGPU_onnx() function benefits from ORT configuration: - Shared device creation requires ORT to be configured - WASM paths must be set for ORT to function - Configuration ensures compatibility between ORT and WebGPU

Module State

The Config module maintains internal state:

let ortWasmPaths: string = '/src/ort/';

State Management: - Module-level storage – Persists across function calls - No public state object – Encapsulated for safety - Getter functiongetOrtWasmPaths() provides read access - Setter functionsetOrtWasmPaths() provides write access