model-explorer / docs /API.md
mr4's picture
Upload 71 files
9bd422a verified
# ONNX Model Explorer β€” API Reference
All modules are loaded as plain `<script>` tags and exposed on `window`. No import/export syntax is used at runtime.
---
## ModelLoader
**File:** `js/core/modelLoader.js`
**Global:** `window.ModelLoader`
Loads the model registry from `models/models.json` and fetches individual `.onnx` files. Also handles file uploads from the user.
### Constructor
```js
const loader = new ModelLoader();
```
### Methods
#### `loadModelList(configPath?)`
Fetches and parses `models/models.json`. Results are cached in memory after the first call.
| Parameter | Type | Default | Description |
|---|---|---|---|
| `configPath` | `string` | `CONFIG.MODELS_CONFIG_FILE` | Path to the JSON registry file |
**Returns:** `Promise<ModelInfo[]>`
```js
const models = await loader.loadModelList();
// [{ id, name, description, path, category, version, size, labelsFile }, ...]
```
On error (network failure, invalid JSON), logs to console and returns `[]`.
---
#### `loadModelFile(filePath)`
Fetches a `.onnx` file and returns its raw bytes.
| Parameter | Type | Description |
|---|---|---|
| `filePath` | `string` | Relative or absolute URL to the `.onnx` file |
**Returns:** `Promise<ArrayBuffer>`
**Throws:** `Error` if the HTTP request fails.
```js
const buffer = await loader.loadModelFile('models/ppe/model.onnx');
```
---
#### `handleFileUpload(file)`
Validates and reads a `File` object (from `<input type="file">` or drag-and-drop).
| Parameter | Type | Description |
|---|---|---|
| `file` | `File` | Browser `File` object |
**Returns:** `Promise<{ success: boolean, data?: ArrayBuffer, error?: string }>`
```js
const result = await loader.handleFileUpload(file);
if (result.success) {
// result.data is an ArrayBuffer
} else {
console.error(result.error);
}
```
Validation rules (from `CONFIG.FILE`):
- Extension must be `.onnx`
- File size must not exceed `CONFIG.FILE.MAX_FILE_SIZE`
---
### Types
```ts
interface ModelInfo {
id: string;
name: string;
description: string;
path: string;
category: string;
version: string;
size: number;
labelsFile: string | null;
}
```
---
## ONNXParser
**File:** `js/core/onnxParser.js`
**Global:** `window.ONNXParser`
Parses an ONNX model `ArrayBuffer` using the ONNX.js library (must be loaded from CDN before use).
### Constructor
```js
const parser = new ONNXParser();
```
### Methods
#### `parseModel(modelBuffer, options?)`
Decodes the protobuf and extracts all model information.
| Parameter | Type | Description |
|---|---|---|
| `modelBuffer` | `ArrayBuffer` | Raw bytes of the `.onnx` file |
| `options` | `object` | Optional overrides (e.g. `{ fileName, fileSize }`) |
**Returns:** `Promise<ParsedModel>`
**Throws:** `Error` if ONNX.js is not loaded, the buffer is empty, or parsing fails.
```js
const parsed = await parser.parseModel(buffer, { fileName: 'model.onnx' });
```
---
### Types
```ts
interface ParsedModel {
metadata: ModelMetadata;
graph: GraphStructure;
inputs: TensorInfo[];
outputs: TensorInfo[];
initializers: InitializerInfo[];
}
interface ModelMetadata {
producerName: string;
producerVersion: string;
opsetVersion: number;
irVersion: number;
customAttributes: Record<string, any>;
fileName: string;
fileSize: number;
loadedAt: number; // Unix timestamp (ms)
}
interface GraphStructure {
name: string;
nodes: NodeInfo[];
edges: EdgeInfo[];
initializers: InitializerInfo[];
}
interface NodeInfo {
id: string;
name: string;
opType: string;
attributes: Record<string, any>;
inputs: string[];
outputs: string[];
domain: string;
}
interface EdgeInfo {
source: string; // node id
target: string; // node id
label: string; // tensor name
}
interface TensorInfo {
name: string;
shape: (number | string)[];
dataType: string;
description?: string;
isOptional?: boolean;
}
interface InitializerInfo {
name: string;
shape: number[];
dataType: string;
size: number; // bytes
elementCount: number;
}
```
---
## GraphProcessor
**File:** `js/core/graphProcessor.js`
**Global:** `window.GraphProcessor`
Converts a `ParsedModel` into Cytoscape.js element descriptors. Automatically clusters nodes by `opType` when the graph exceeds `CONFIG.PERFORMANCE.LAZY_LOAD_THRESHOLD` nodes.
### Constructor
```js
const processor = new GraphProcessor();
```
### Methods
#### `processGraph(parsedModel)`
Builds the full list of Cytoscape elements (nodes + edges) from a parsed model.
| Parameter | Type | Description |
|---|---|---|
| `parsedModel` | `ParsedModel` | Output of `ONNXParser.parseModel()` |
**Returns:** `{ elements: CytoscapeElement[], stats: GraphStats }`
```js
const { elements, stats } = processor.processGraph(parsedModel);
// Pass elements directly to cytoscape({ elements })
```
Node classes assigned:
- `input-node` β€” model input tensors
- `output-node` β€” model output tensors
- `initializer-node` β€” constant weight tensors
- `op-node` β€” computation operators
- `op-node cluster-node` β€” clustered operators (large graphs)
---
### Types
```ts
interface GraphStats {
nodeCount: number;
edgeCount: number;
initializerCount: number;
inputCount: number;
outputCount: number;
clusterCount?: number; // present when isClustered is true
isClustered?: boolean;
}
```
---
## StateManager
**File:** `js/state/stateManager.js`
**Global:** `window.StateManager`
Singleton that holds all application state. Components read state via getters and react to changes via subscriptions.
### State Shape
```ts
interface AppState {
currentModel: ParsedModel | null;
modelList: ModelInfo[];
selectedNodeId: string | null;
zoomLevel: number;
viewMode: 'single' | 'comparison';
comparisonModel: ParsedModel | null;
searchQuery: string;
filteredModelList: ModelInfo[];
error: { message: string; type: 'error' | 'warning' | 'info'; timestamp: number } | null;
isLoading: boolean;
loadingProgress: number; // 0–100
}
```
### Getters
| Method | Returns | Description |
|---|---|---|
| `getState()` | `AppState` | Shallow copy of the full state |
| `getCurrentModel()` | `ParsedModel\|null` | Currently loaded model |
| `getModelList()` | `ModelInfo[]` | Full model registry |
| `getFilteredModelList()` | `ModelInfo[]` | Search-filtered model list |
| `getSearchQuery()` | `string` | Current search string |
| `getSelectedNodeId()` | `string\|null` | Selected graph node id |
| `getZoomLevel()` | `number` | Current zoom level |
| `getViewMode()` | `'single'\|'comparison'` | Current view mode |
| `getComparisonModel()` | `ParsedModel\|null` | Second model in comparison mode |
| `getError()` | `ErrorState\|null` | Current error, or null |
| `isLoading()` | `boolean` | Whether a load is in progress |
| `getLoadingProgress()` | `number` | Load progress 0–100 |
### Setters
Each setter updates the corresponding state key and notifies subscribers.
| Method | Parameter | Description |
|---|---|---|
| `setCurrentModel(model)` | `ParsedModel\|null` | Set current model; persists id to `localStorage` |
| `setModelList(list)` | `ModelInfo[]` | Replace the full model list |
| `setFilteredModelList(list)` | `ModelInfo[]` | Replace the filtered list |
| `setSearchQuery(query)` | `string` | Update search query |
| `setSelectedNodeId(id)` | `string\|null` | Update selected node |
| `setZoomLevel(level)` | `number` | Update zoom level |
| `setViewMode(mode)` | `'single'\|'comparison'` | Switch view mode |
| `setComparisonModel(model)` | `ParsedModel\|null` | Set comparison model |
| `setError(message, type?)` | `string, string` | Set error state (`type` defaults to `'error'`) |
| `clearError()` | β€” | Clear current error |
| `setLoading(loading)` | `boolean` | Toggle loading state |
| `setLoadingProgress(n)` | `number` | Update progress 0–100 |
### Subscription
#### `subscribe(key, callback)`
Subscribe to changes on a specific state key. Use `'*'` to receive all changes.
| Parameter | Type | Description |
|---|---|---|
| `key` | `string` | State key name, or `'*'` for all |
| `callback` | `(newValue, oldValue, key) => void` | Called on every change |
**Returns:** `Function` β€” call it to unsubscribe.
```js
const unsub = StateManager.subscribe('currentModel', (model) => {
console.log('Model changed:', model);
});
// Later:
unsub();
```
#### `unsubscribe(key, callback)`
Remove a specific callback without using the returned unsubscribe function.
#### `reset()`
Resets all state to initial values. Primarily used in tests.
#### `getPersistedSelectedModelId()`
Returns the model id stored in `localStorage` from the previous session, or `null`.
---
## EventBus
**File:** `js/core/eventBus.js`
**Global:** `window.EventBus`
Singleton pub/sub event bus for decoupled communication between components.
### Methods
#### `on(eventName, callback)`
Subscribe to an event.
| Parameter | Type | Description |
|---|---|---|
| `eventName` | `string` | Event name |
| `callback` | `(data: any) => void` | Handler |
**Returns:** `Function` β€” unsubscribe function.
```js
const off = EventBus.on('model:loaded', (model) => {
console.log('Loaded:', model.metadata.fileName);
});
```
#### `off(eventName, callback)`
Remove a specific handler.
#### `emit(eventName, data?)`
Emit an event to all subscribers. Errors thrown inside handlers are caught and logged.
```js
EventBus.emit('model:selected', { id: 'ppe' });
```
#### `once(eventName, callback)`
Subscribe for a single invocation, then auto-unsubscribe.
#### `clear(eventName?)`
Remove all listeners for `eventName`, or all listeners if omitted.
#### `listenerCount(eventName)`
Returns the number of active listeners for an event (useful for debugging).
### Standard Events
| Event | Payload | Description |
|---|---|---|
| `model:loaded` | `ParsedModel` | A model was successfully parsed |
| `model:selected` | `ModelInfo` | User selected a model from the list |
| `node:selected` | `string` (node id) | User clicked a graph node |
| `search:updated` | `string` (query) | Search field changed |
| `error:occurred` | `{ message, type }` | An error was raised |
| `export:requested` | `ParsedModel` | User clicked Export |
| `comparison:started` | `ParsedModel` | Comparison mode activated |
| `comparison:ended` | β€” | Comparison mode exited |