Module

Hylograph.Kernel.WASM.FFI

Package
purescript-hylograph-wasm-kernel
Repository
afcondon/purescript-hylograph-wasm-kernel

WASM Force Engine FFI

High-performance force simulation using Rust/WebAssembly. Provides 3-4x speedup over D3.js for large graphs (10,000+ nodes).

Usage:

import Hylograph.Kernel.WASM.FFI as WASM

main = do
  -- Initialize WASM module (once at app startup)
  WASM.initWasm "./pkg/force_kernel.js"

  -- Create simulation
  sim <- WASM.create 1000

  -- Configure forces
  WASM.configureManyBody sim { strength: -30.0, theta: 0.9, distanceMin: 1.0, distanceMax: 10000.0 }
  WASM.configureLinks sim { distance: 30.0, strength: 1.0, iterations: 1 }
  WASM.configureCenter sim { x: 0.0, y: 0.0, strength: 1.0 }

  -- Set links
  WASM.setLinks sim [0, 1, 1, 2, 2, 3]  -- [source, target, source, target, ...]

  -- Run simulation
  WASM.tick sim

  -- Get results
  positions <- WASM.getPositions sim  -- [x0, y0, x1, y1, ...]

#WASMSimulation Source

data WASMSimulation

Opaque type for WASM simulation handle

#ManyBodyConfig Source

type ManyBodyConfig = { distanceMax :: Number, distanceMin :: Number, strength :: Number, theta :: Number }

Many-body force configuration

#LinkConfig Source

type LinkConfig = { distance :: Number, iterations :: Int, strength :: Number }

Link force configuration

#CenterConfig Source

type CenterConfig = { strength :: Number, x :: Number, y :: Number }

Center force configuration

#ForceXConfig Source

type ForceXConfig = { strength :: Number, target :: Number }

ForceX configuration - pulls nodes toward an x position

#ForceYConfig Source

type ForceYConfig = { strength :: Number, target :: Number }

ForceY configuration - pulls nodes toward a y position

#CollideConfig Source

type CollideConfig = { iterations :: Int, radius :: Number, strength :: Number }

Collide force configuration - prevents node overlap

#initWasm Source

initWasm :: String -> Aff Unit

Initialize the WASM module. Call once at application startup.

The URL should point to the generated JavaScript module from wasm-pack. Example: initWasm "./pkg/force_kernel.js"

#isWasmReady Source

isWasmReady :: Effect Boolean

Check if WASM is initialized and ready

#create Source

create :: Int -> Effect WASMSimulation

Create a new WASM simulation with the given number of nodes. Nodes are initialized in a phyllotaxis (sunflower) pattern.

#free Source

free :: WASMSimulation -> Effect Unit

Free WASM simulation memory. Call when done with simulation.

#setNodeCount Source

setNodeCount :: WASMSimulation -> Int -> Effect Unit

Resize simulation to new node count

#setPosition Source

setPosition :: WASMSimulation -> Int -> Number -> Number -> Effect Unit

Set a single node's position

#setAllPositions Source

setAllPositions :: WASMSimulation -> Array Number -> Effect Unit

Set all positions from flat array [x0, y0, x1, y1, ...]

#getPositions Source

getPositions :: WASMSimulation -> Effect (Array Number)

Get all positions as flat array [x0, y0, x1, y1, ...]

#getPositionsAsObjects Source

getPositionsAsObjects :: WASMSimulation -> Effect (Array { x :: Number, y :: Number })

Get positions as array of {x, y} objects

#fixNode Source

fixNode :: WASMSimulation -> Int -> Number -> Number -> Effect Unit

Fix a node at a position (like D3's fx/fy)

#unfixNode Source

unfixNode :: WASMSimulation -> Int -> Effect Unit

Unfix a node

#setLinksFromRecords Source

setLinksFromRecords :: forall r. WASMSimulation -> Array { source :: Int, target :: Int | r } -> Effect Unit

Set links from array of records with source/target fields

#configureManyBody Source

configureManyBody :: WASMSimulation -> ManyBodyConfig -> Effect Unit

Configure many-body (charge) force

#configureCenter Source

configureCenter :: WASMSimulation -> CenterConfig -> Effect Unit

Configure center force

#configureForceX Source

configureForceX :: WASMSimulation -> ForceXConfig -> Effect Unit

Configure forceX (pull toward x position)

#configureForceY Source

configureForceY :: WASMSimulation -> ForceYConfig -> Effect Unit

Configure forceY (pull toward y position)

#configureCollide Source

configureCollide :: WASMSimulation -> CollideConfig -> Effect Unit

Configure collide force (prevent node overlap)

#enableForces Source

enableForces :: WASMSimulation -> { center :: Boolean, links :: Boolean, manyBody :: Boolean } -> Effect Unit

Enable/disable forces individually (original 3)

#enableForcesAll Source

enableForcesAll :: WASMSimulation -> { center :: Boolean, collide :: Boolean, forceX :: Boolean, forceY :: Boolean, links :: Boolean, manyBody :: Boolean } -> Effect Unit

Enable/disable all forces including new ones

#setAlpha Source

setAlpha :: WASMSimulation -> Number -> Effect Unit

Set alpha (temperature). Higher = more movement.

#getAlpha Source

getAlpha :: WASMSimulation -> Effect Number

Get current alpha

#setAlphaDecay Source

setAlphaDecay :: WASMSimulation -> Number -> Effect Unit

Set alpha decay rate

#setVelocityDecay Source

setVelocityDecay :: WASMSimulation -> Number -> Effect Unit

Set velocity decay (friction). 0.6 means 40% decay per tick.

#reheat Source

reheat :: WASMSimulation -> Effect Unit

Reheat simulation (reset alpha to 1.0)

#tick Source

tick :: WASMSimulation -> Effect Number

Run a single simulation tick. Returns new alpha value.

#tickN Source

tickN :: WASMSimulation -> Int -> Effect Number

Run multiple ticks. Stops early if alpha < alphaMin.

#isRunning Source

isRunning :: WASMSimulation -> Effect Boolean

Check if simulation is still running (alpha >= alphaMin)

#nodeCount Source

nodeCount :: WASMSimulation -> Effect Int

Get number of nodes

#linkCount Source

linkCount :: WASMSimulation -> Effect Int

Get number of links

#syncPositionsToWasm Source

syncPositionsToWasm :: forall r. WASMSimulation -> Array { x :: Number, y :: Number | r } -> Effect Unit

Copy positions from PureScript node array to WASM

#syncPositionsFromWasm Source

syncPositionsFromWasm :: forall r. WASMSimulation -> Array { vx :: Number, vy :: Number, x :: Number, y :: Number | r } -> Effect (Array { vx :: Number, vy :: Number, x :: Number, y :: Number | r })

Copy positions from WASM back to PureScript node array. Warning: This mutates the input array!