Title here
Summary here
import { useState } from 'react';
import { parseModel } from '@wetron/core';
import type { ModelGraph } from '@wetron/core';
import { ModelGraphView, NodePropertyPanel } from '@wetron/react';
import type { PanelTarget } from '@wetron/react';
import '@wetron/react/styles.css';
export default function App() {
const [graph, setGraph] = useState<ModelGraph | null>(null);
const [selected, setSelected] = useState<PanelTarget | null>(null);
async function handleFile(e: React.ChangeEvent<HTMLInputElement>) {
const file = e.target.files?.[0];
if (!file) return;
const bytes = new Uint8Array(await file.arrayBuffer());
setGraph(await parseModel(bytes, file.name));
}
return (
<>
<input type="file" accept=".onnx,.tflite,.keras,.gguf,.pt,.pte,.pb" onChange={handleFile} />
{graph && <ModelGraphView graph={graph} onTargetClick={setSelected} colorMode="system" />}
<NodePropertyPanel
target={selected}
colorMode="system"
opsets={graph?.opsets}
tensorShapes={graph?.tensorShapes}
onClose={() => setSelected(null)}
/>
</>
);
}<script>
import { parseModel } from '@wetron/core';
import { ModelGraphView, NodePropertyPanel } from '@wetron/svelte';
let graph = $state(null);
let selected = $state(null);
async function handleFile(e) {
const file = e.target.files[0];
const bytes = new Uint8Array(await file.arrayBuffer());
graph = await parseModel(bytes, file.name);
}
</script>
<input type="file" accept=".onnx,.tflite,.keras,.gguf,.pt,.pte,.pb" onchange={handleFile} />
{#if graph}
<ModelGraphView {graph} onTargetClick={(t) => (selected = t)} colorMode="system" />
{/if}
<NodePropertyPanel target={selected} colorMode="system" />All parsers throw ParseError on failure. Partial successes attach non-fatal issues as warnings on the returned graph:
import { ParseError } from '@wetron/core';
try {
const graph = await parseModel(bytes, file.name);
if (graph.warnings?.length) {
console.warn('Parse warnings:', graph.warnings);
}
} catch (e) {
if (e instanceof ParseError) {
console.error(`[${e.format}] ${e.context}`);
}
}import { detectFormat } from '@wetron/core';
const format = detectFormat(bytes, file.name);
// "onnx" | "tflite" | "keras" | "gguf" | "torchscript" | "executorch" | "savedmodel" | "unknown"
// never throws
ONNX, TFLite, and GGUF expose initializer bytes via graph.weights. Decode the first few thousand supported values for a preview and feed them to computeStats for the property panel’s histogram and heatmap.
import { decodeFirstN, numericView, computeStats } from '@wetron/core';
const bytes = graph.weights?.kind === 'available' ? graph.weights.source.get('conv1.weight') : undefined;
if (bytes) {
const preview = decodeFirstN(bytes, 'float32', 4096);
if (preview instanceof Float64Array) {
const stats = computeStats(numericView(preview));
// stats.min, stats.max, stats.mean, stats.std,
// stats.histogram (12 bins), stats.heatmap (16x8)
}
}For TF2 SavedModel, load the checkpoint pair separately:
import { loadSavedModelWeights, attachCheckpointToGraph } from '@wetron/savedmodel';
if (graph.weights?.kind === 'external' && graph.weights.format === 'savedmodel') {
const loaded = await loadSavedModelWeights(indexFile, dataFile);
const withWeights = attachCheckpointToGraph(graph, loaded);
// withWeights.weights.source.get(nodeName) -> Uint8Array | undefined
}