Skip to content

comonoid/agdelte

Repository files navigation

Agdelte

Reactive UI framework with dependent types. No Virtual DOM.

Svelte showed the way: compile-time reactivity beats runtime diffing. But Svelte's compiler magic is opaque — TypeScript doesn't truly understand it.

Agdelte brings Svelte's key insight to a language with a real type system:

  • Direct DOM updates via reactive bindings (no Virtual DOM diffing)
  • Declarative templates with bind points that auto-update
  • Static verification of initial structure + dynamic flexibility via lenses

Core Idea

Agdelte uses reactive bindings — like Svelte, but with dependent types:

-- Reactive template with bindings (like Svelte)
counterTemplate : Node Model Msg
counterTemplate =
  div [ class "counter" ]
    ( button [ onClick Dec ] [ text "-" ]
    ∷ span [ class "count" ] [ bindF show ]   -- auto-updates on model change!
    ∷ button [ onClick Inc ] [ text "+" ]
    ∷ [] )

-- App with reactive template
record ReactiveApp (Model Msg : Set) : Set₁ where
  field
    init     : Model
    update   : Msg  Model  Model
    template : Node Model Msg    -- NOT a function! Structure with bindings

Key insight: reactive bindings instead of Virtual DOM:

  • bind points track which DOM nodes depend on model
  • When model changes, only affected bindings update
  • No tree diffing, no re-rendering — direct DOM mutations
-- Binding: reactive connection from Model to DOM
record Binding (Model : Set) (A : Set) : Set where
  field
    extract : Model  A           -- get value from model
    equals  : A  A  Bool        -- detect changes

How It Works (Svelte-style)

1. FIRST RENDER:
   - Walk the Node tree, create real DOM
   - For each `bind`, remember (DOMNode, Binding)

2. ON MODEL CHANGE:
   - For each binding: extract(oldModel) vs extract(newModel)
   - If changed: update that DOM node directly
   - NO tree diffing! Direct updates to tracked nodes.

This is exactly what Svelte does at compile time, but we do it with explicit bindings that the type system can verify.

Theoretical Foundation

The Theory/ module (isolated, optional) establishes correspondence with Polynomial Functors (Spivak, Niu):

  • Reactive bindings as lens-like structures
  • Widget networks as polynomial machines
  • Composition via polynomial operations (⊗, ⊕)

Multi-level architecture:

Level 3: Declarative DSL    — button [ onClick Dec ] [ bindF show ]
Level 2: Lenses             — navigation, modification, composition
Level 1: Polynomials        — mathematical foundation

Quick Example

-- Reactive Counter (like Svelte)
module ReactiveCounter where

open import Agdelte.Reactive.Node

-- Model & Messages
Model =data Msg : Set where
  Inc Dec : Msg

-- Pure update
update : Msg  Model  Model
update Inc n = suc n
update Dec zero = zero
update Dec (suc n) = n

-- Declarative template with reactive binding
template : Node Model Msg
template =
  div [ class "counter" ]
    ( button [ onClick Dec ] [ text "-" ]
    ∷ span [ class "count" ] [ bindF show ]   -- bindF show = auto-update!
    ∷ button [ onClick Inc ] [ text "+" ]
    ∷ [] )

-- App
app : ReactiveApp Model Msg
app = mkReactiveApp 0 update template

Compare to Svelte:

<script>
  let count = 0;
</script>

<div class="counter">
  <button on:click={() => count--}>-</button>
  <span class="count">{count}</span>
  <button on:click={() => count++}>+</button>
</div>

Same declarative style, but with dependent types and no compiler magic.

Why Agdelte?

Svelte 5 Virtual DOM (React/Elm) Agdelte
DOM updates Direct (compiled) Diff tree, patch Direct (bindings)
Performance Fast Overhead from diffing Fast
Reactivity Compiler magic Runtime diffing Explicit bindings
Type safety TypeScript Varies Dependent types
Impossible states Runtime Runtime Compile-time

Key advantage over Virtual DOM: No tree reconstruction, no diffing algorithm. When model changes, only the bound DOM nodes update — exactly like Svelte.

Runtime Performance

Beyond Svelte-style bindings, Agdelte includes production-grade optimizations:

┌─────────────────────────────────────────────────────────────┐
│  P0 Immediate    │ keyboard, focus → sync dispatch          │
├───────────────────────────────────────────────────────────── │
│  P1 Normal       │ clicks, input → rAF batching             │
├───────────────────────────────────────────────────────────── │
│  P2 Background   │ data fetches → requestIdleCallback       │
└─────────────────────────────────────────────────────────────┘
  • Priority Scheduling: Keyboard input processes instantly (P0), UI clicks batch per frame (P1), data loads run in idle time (P2)
  • Time-Slicing: Large DOM updates (1000+ bindings) split across frames with 8ms budget — maintains 60fps
  • Web Worker: Heavy update computations offloaded to worker thread
  • Buffer Registry: SharedArrayBuffer for large binary data (images, WebGL textures) — model stores only lightweight handles
  • Slot Tracking: Skip unchanged bindings via model slot detection (O(changed) not O(bindings))

Architecture

┌─────────────────────────────────────────────────────────────┐
│  Level 3: Declarative DSL                                   │
│  button [ onClick Dec ] [ bindF show ]                     │
│  Aesthetic, readable, statically verified                   │
├─────────────────────────────────────────────────────────────┤
│  Level 2: Lenses                                            │
│  Navigation, modification, composition                      │
│  Dynamic flexibility at runtime                             │
├─────────────────────────────────────────────────────────────┤
│  Level 1: Polynomials                                       │
│  Mathematical foundation (Spivak, Niu)                      │
└─────────────────────────────────────────────────────────────┘

ReactiveApp Structure

record ReactiveApp (Model Msg : Set) : Set₁ where
  field
    init     : Model                    -- initial state
    update   : Msg  Model  Model      -- pure state transition
    template : Node Model Msg           -- reactive template (NOT a function!)
  • init — initial state
  • update — pure function: Msg → Model → Model
  • template — declarative structure with bindings (like Svelte template)

Node — Reactive Template

data Node (Model Msg : Set) : Set₁ where
  text : String  Node Model Msg                           -- static text
  bind : Binding Model String  Node Model Msg             -- reactive binding!
  elem : String  List (Attr Model Msg)  List (Node Model Msg)  Node Model Msg

The key difference from Virtual DOM: template is data, not a function. Bindings track exactly which DOM nodes need updating.

Documentation

Document Description
doc/ Main documentation index
doc/guide/architecture.md Core architecture and design
doc/guide/examples.md Guide to all examples
doc/guide/getting-started.md Prerequisites, build, run

API Reference

Document Description
doc/api/node.md ReactiveApp, Node, Attr, Binding, zoomNode, Lens
doc/api/event.md Subscriptions: interval, keyboard, WebSocket, workers
doc/api/cmd.md Commands: HTTP, DOM, clipboard, storage, routing
doc/api/task.md Monadic chains: sequential HTTP, do-notation
doc/api/optic.md Lens, Prism, Affine, Traversal, Optic, ProcessOptic, RemoteOptic
doc/api/agent.md Agent coalgebra, Wiring, SharedAgent, Diagram
doc/api/signal.md Synchronous streams: const, map, delay, fold
doc/api/session.md Session types: send/recv, dual, offer/choose
doc/api/css.md Typed CSS: Decl, Length, Color, Layout, Stylesheet
doc/api/svg.md Typed SVG: Elements, Path, Transform, SMIL, Events
doc/api/anim.md Model-driven animations: Tween, Spring
doc/api/webgl.md WebGL scene graphs: Camera, Light, Material, SceneNode, Scene
doc/api/webgl-controls.md WebGL 3D UI controls: buttons, sliders, charts, gizmos
doc/api/html-controls.md HTML UI widgets: TabBar, Modal, DataGrid, Dropdown, Video Player, etc.
doc/api/auth.md JWT, Middleware, Client-side token management
doc/api/storage.md WAL persistence, snapshots, AppStore
doc/api/ffi.md Browser/Server postulates, Serialize

Additional Documents

Document Description
doc/internals/runtime.md JavaScript runtime implementation
doc/theory/combinators.md All combinators with types
doc/theory/time-model.md Time model: ticks, dt
doc/theory/polynomials.md Polynomial functors: theory
doc/comparison/vs-svelte.md Comparison with Svelte 5
doc/comparison/vs-vue3.md Comparison with Vue 3

Project Structure

src/
  Agdelte/
    ├── App.agda                 -- Top-level app module
    │
    ├── Reactive/                -- Reactive templates (Svelte-style)
    │   ├── Node.agda            -- Node, Binding, ReactiveApp
    │   ├── Lens.agda            -- Lens, fstLens, sndLens
    │   ├── Optic.agda           -- Prism, Traversal, Affine, Optic, routeMsg
    │   ├── BigLens.agda         -- Big Lens across processes/hosts
    │   ├── Diagram.agda         -- Wiring diagrams
    │   ├── Inspector.agda       -- Runtime inspector
    │   ├── ProcessOptic.agda    -- Cross-process optics
    │   ├── RemoteOptic.agda     -- Cross-host optics
    │   └── TimeTravel.agda      -- Time-travel debugging
    │
    ├── Core/                    -- Effects
    │   ├── Signal.agda          -- Coinductive stream
    │   ├── Event.agda           -- Event — subscriptions (interval, keyboard)
    │   ├── Cmd.agda             -- Cmd — commands (httpGet, httpPost)
    │   ├── Task.agda            -- Task — monadic chains (do-notation)
    │   └── Result.agda          -- Result type for error handling
    │
    ├── Concurrent/              -- Concurrency & session types
    │   ├── Agent.agda           -- Agent coalgebra
    │   ├── CoSession.agda       -- Co-session types
    │   ├── DepAgent.agda        -- Dependent agents
    │   ├── Obligation.agda      -- Linear obligations
    │   ├── ProcessOpticLinear.agda -- Linear process optics
    │   ├── Session.agda         -- Session types
    │   ├── SessionExec.agda     -- Session execution
    │   ├── SessionForm.agda     -- Session formulas
    │   ├── SharedAgent.agda     -- Shared agent state
    │   └── Wiring.agda          -- Agent wiring
    │
    ├── Html/                    -- HTML DSL
    │   ├── Attributes.agda      -- HTML attributes
    │   ├── Elements.agda        -- HTML elements
    │   ├── Events.agda          -- DOM events
    │   ├── Navigation.agda      -- Navigation helpers
    │   ├── Types.agda           -- HTML types
    │   └── Controls/            -- UI widget library
    │       ├── Video/           -- MediaSource video player
    │       │   ├── Player.agda  -- State machine, public API
    │       │   ├── Controls.agda -- UI overlay (play, seek, volume)
    │       │   ├── Source.agda  -- MediaSource management
    │       │   ├── SegmentLoader.agda -- Segment fetch pipeline
    │       │   ├── Types.agda   -- PlayerState, VideoModel, VideoMsg
    │       │   └── Util.agda    -- Time formatting, manifest parsing
    │
    ├── FFI/                     -- Foreign function interface
    │   ├── Browser.agda         -- Browser postulates
    │   ├── Crypto.agda          -- HMAC-SHA256, bcrypt, base64, random
    │   ├── FileSystem.agda      -- File I/O (read, write, append, mkdir)
    │   ├── Server.agda          -- Server postulates
    │   └── Shared.agda          -- Shared FFI types
    │
    ├── Auth/                    -- Authentication
    │   ├── JWT.agda             -- JWT sign/verify (HS256)
    │   ├── Handler.agda         -- Register/login handlers
    │   ├── Client.agda          -- Client-side token management
    │   └── Middleware.agda      -- Bearer auth middleware, CORS
    │
    ├── Storage/                 -- Persistence
    │   ├── WAL.agda             -- Write-ahead log with snapshots
    │   └── AppStore.agda        -- Domain state + WAL config
    │
    ├── Lens/                    -- Lens utilities
    │   └── Widget.agda          -- Widget lenses
    │
    ├── Primitive/               -- Primitive event sources
    │   ├── AnimationFrame.agda  -- requestAnimationFrame
    │   ├── Interval.agda        -- setInterval
    │   ├── Keyboard.agda        -- Keyboard events
    │   ├── Mouse.agda           -- Mouse events
    │   ├── Request.agda         -- HTTP requests
    │   └── Time.agda            -- Time primitives
    │
    ├── Css/                     -- CSS DSL
    │   ├── Decl.agda            -- CSS declarations
    │   ├── Length.agda          -- Length units (px, em, rem, %)
    │   ├── Color.agda           -- Color types (rgb, hsl, hex)
    │   ├── Layout.agda          -- Flexbox, Grid
    │   ├── Transition.agda      -- CSS transitions
    │   ├── Animation.agda       -- CSS @keyframes
    │   ├── Stylesheet.agda      -- Full stylesheet generation
    │   └── Render.agda          -- CSS rendering to String
    │
    ├── Svg/                     -- SVG DSL
    │   ├── Core.agda            -- Core types and rendering
    │   ├── Attributes.agda      -- Typed SVG attributes
    │   ├── Elements.agda        -- SVG elements (rect, circle, path, etc.)
    │   ├── Path.agda            -- Path commands (M, L, C, A, Z)
    │   ├── Transform.agda       -- Transform operations
    │   ├── Smil.agda            -- SMIL declarative animations
    │   └── Events.agda          -- SVG pointer events with coordinates
    │
    ├── Anim/                    -- Model-driven animations
    │   ├── Tween.agda           -- Tween animations with easing
    │   └── Spring.agda          -- Spring physics animations
    │
    ├── Buffer.agda              -- Buffer Registry API (SharedArrayBuffer)
    │
    ├── WebGL/                   -- WebGL 3D scene graphs
    │   ├── Types.agda           -- Camera, Light, Material, SceneNode, Scene
    │   ├── Controls.agda        -- Re-exports all 3D UI controls
    │   ├── Controls/            -- 3D UI controls library
    │   │   ├── Theme.agda       -- ControlTheme, themes
    │   │   ├── State.agda       -- ControlState
    │   │   ├── Text.agda        -- label, dynamicLabel
    │   │   ├── Buttons.agda     -- button, fabButton, iconButton
    │   │   ├── Sliders.agda     -- hslider, vslider, dial
    │   │   ├── Toggles.agda     -- toggle, checkbox, radio
    │   │   ├── Menus.agda       -- dropdown, radialMenu
    │   │   ├── Tabs.agda        -- tabBar, tabPanel
    │   │   ├── Input.agda       -- textInput, numberInput, colorPicker
    │   │   ├── Charts/          -- 3D data visualization
    │   │   │   ├── Bar3D.agda
    │   │   │   ├── Scatter3D.agda
    │   │   │   ├── Surface.agda
    │   │   │   └── Network3D.agda
    │   │   ├── Audio/           -- Audio visualization
    │   │   │   ├── Spectrum.agda
    │   │   │   └── Waveform.agda
    │   │   └── Gizmos/          -- 3D manipulation tools
    │   │       ├── Transform.agda
    │   │       ├── Selection.agda
    │   │       └── Measure.agda
    │   └── Builder/             -- Geometry composition & optimization
    │       ├── Geometry/        -- Primitives, Procedural, CSG
    │       ├── Layout/          -- Stack, Grid, Radial
    │       ├── Optimize/        -- Batching, LOD, Culling
    │       ├── Interaction/     -- NamedParts
    │       └── Import/          -- GLTF
    │
    ├── Theory/                  -- Mathematical foundation (optional)
    │   ├── Poly.agda            -- Polynomial functors, Coalg, Lens
    │   ├── PolySignal.agda      -- Signal ≅ Coalg (Mono A ⊤)
    │   ├── PolyApp.agda         -- Polynomial app structure
    │   ├── AgentCoalg.agda      -- Agent as coalgebra
    │   ├── BigLensPolyLens.agda -- BigLens ≅ Poly.Lens
    │   ├── DepPoly.agda         -- Dependent polynomials
    │   ├── LensLaws.agda        -- Lens law proofs
    │   ├── OpticPolyLens.agda   -- Optic ≅ Poly.Lens
    │   └── SessionDualProof.agda -- Session duality proof
    │
    └── Test/                    -- Tests
        ├── Interpret.agda       -- Pure event testing (SimEvent)
        └── OpticTest.agda       -- 16 optic proofs

examples/
    Counter.agda                 -- Counter with reactive bindings
    Timer.agda                   -- Stopwatch with interval
    Todo.agda                    -- TodoMVC-style app
    Keyboard.agda                -- Global keyboard events
    KeyboardDemo.agda            -- Keyboard demo (server)
    Http.agda                    -- HTTP requests
    Task.agda                    -- Task chains (do-notation)
    WebSocket.agda               -- WebSocket communication
    Router.agda                  -- SPA routing
    Composition.agda             -- App composition (zoomNode)
    Transitions.agda             -- CSS enter/leave animations (whenT)
    Combinators.agda             -- Event pipeline (foldE, mapFilterE)
    OpticDynamic.agda            -- Dynamic optics (ixList, Traversal, _∘O_)
    StressTest.agda              -- Performance benchmark
    AgentWiring.agda             -- Agent wiring example
    DepAgentDemo.agda            -- Dependent agent demo
    Parallel.agda                -- Parallel execution
    RemoteAgent.agda             -- Remote agent example
    SessionDual.agda             -- Session duality example
    SessionFormDemo.agda         -- Session form demo
    Worker.agda                  -- Web worker example
    CssDemo.agda                 -- CSS DSL demo
    CssFullDemo.agda             -- CSS full demo
    AnimDemo.agda                -- Tween/Spring animations
    SvgTest.agda                 -- Basic SVG demo
    SvgSmil.agda                 -- SMIL declarative animations
    SvgPanZoom.agda              -- Interactive pan/zoom
    SvgChart.agda                -- Data-driven bar chart
    SvgLineDraw.agda             -- Self-drawing paths
    WebGLTest.agda               -- WebGL basics (perspective, phong, animate)
    WebGLFullDemo.agda           -- WebGL full demo (all features)
    VideoDemo.agda               -- Video player integration
    ControlsDemo.agda            -- HTML controls showcase
    WebGLControlsDemo.agda       -- WebGL 3D controls demo

runtime/
    reactive.js                  -- Main runtime: priority scheduling, time-slicing
    reactive-auto.js             -- Auto-loader (data-agdelte attribute)
    reactive-gl.js               -- WebGL runtime (3D scene graph rendering)
    events.js                    -- Event interpretation with priority dispatchers
    primitives.js                -- Primitive event sources
    svg-events.js                -- SVG coordinate conversion helpers
    agda-values.js               -- Abstraction for Scott encoding
    buffer-registry.js           -- SharedArrayBuffer management
    update-worker.js             -- Web Worker for heavy update computations
    workers/
        fibonacci.js             -- Fibonacci worker example
        fibonacci-progress.js    -- Fibonacci with progress reporting

hs/
    Agdelte/
        Http.hs                  -- Warp HTTP server (request/response with headers)
        Crypto.hs                -- HMAC-SHA256, bcrypt, base64 (cryptonite)

Key Properties

No Virtual DOM. Direct DOM updates via reactive bindings — like Svelte, but explicit.

Purity. update is a pure function. Template is data, not computation.

Declarativity. Template describes structure, bindings describe what changes.

Performance. No tree diffing. O(bindings) updates, not O(tree size).

Composability. Events and bindings combine with standard operations:

-- Basic
never     : Event A                           -- nothing
merge     : Event A  Event A  Event A       -- combine streams
mapE      : (A  B)  Event A  Event B       -- transform
filterE   : (A  Bool)  Event A  Event A    -- filter

-- Sampling (Event + Signal interaction)
snapshot  : (A  B  C)  Event A  Signal B  Event C  -- sample Signal
gate      : Event A  Signal Bool  Event A   -- filter by Signal
changes   : Signal A  Event A                -- events when Signal changes

-- Time-based
debounce  : Event A  Event A             -- after N ms pause
throttle  : Event A  Event A             -- max once per N ms

-- Switching
switchE   : Event A  Event (Event A)  Event A  -- dynamic Event switching

-- Merging
mergeWith : (A  A  A)  Event A  Event A  Event A  -- merge with function
alignWith : (These A B  C)  Event A  Event B  Event C  -- align different types

-- Accumulators
accumE    : A  Event (A  A)  Event A        -- fold to Event
accumB    : A  Event (A  A)  Signal A       -- fold functions to Signal

-- Deferred
pre       : A  Signal A  Signal A            -- delay by one tick

-- Error handling
catchE    : Event (Result E A)  (E  A)  Event A  -- handle errors

-- Testing
interpret : (Event A  Event B)  List (List A)  List (List B)  -- test Event transformations

Concurrency

Heavy computations that block UI? Use workers — same Event pattern:

-- Worker is just another Event primitive
worker : WorkerFn A B  A  Event B

-- Same declarative model
events m = if m.computing
  then mapE Done (worker heavyComputation m.data)
  else never
-- Event appears → worker starts
-- Event disappears → worker cancelled (automatic cleanup)

Structured concurrency, automatic resource management, no leaks. See doc/api/event.md.

Quick Start

# Install dependencies (Agda 2.6.4+, agda-stdlib 2.0+)

# Build all examples
npm run build:all

# Start dev server
npm run dev

# Open http://localhost:8080/

See examples/README.md for details.

Features

Core

  • Reactive templates — ReactiveApp, Node, Binding (Svelte-style, no Virtual DOM)
  • Incremental updates — binding scopes, foreachKeyed (key-based list reconciliation), whenT (CSS enter/leave transitions)
  • Widget lensesLens Outer Inner, composition _∘L_, zoomNode for full component composition
  • Combinators & testingfoldE, mapFilterE, switchE, accumE, gate; pure testing via SimEvent with propositional equality proofs
  • OpticsPrism, Traversal, Affine, unified Optic with _∘O_; routeMsg, ixList, 16 equality proofs

Performance (Runtime Optimizations)

  • Priority Scheduling — P0 (keyboard: immediate), P1 (clicks: rAF batching), P2 (data: idle callback)
  • Time-Slicing — large DOM updates split across frames (8ms budget), maintains 60fps
  • Web Worker for update — offload heavy update computations to worker thread
  • Buffer RegistrySharedArrayBuffer for large binary data (images, audio) outside Agda model
  • Slot-based tracking — skip unchanged bindings via model slot detection

Concurrency & Distribution

  • Agents — polynomial coalgebras, channels, structured concurrency
  • Process/Remote Optics — same Optic interface across processes and hosts
  • Big Optic — spans local widgets, processes, and remote hosts uniformly
  • Session types — send/recv, dual, offer/choose; duality proofs; linear obligations

Developer Tools

  • DevTools via Big Optic — network inspection across processes/hosts
  • Time-travel debugging — undo/redo with history
  • Runtime inspector — live model inspection
  • Hot reload — preserve model across code changes

Formal Verification

  • Optic ≅ Poly.Lens for monomial case
  • Lens law proofs — get-put, put-get, put-put
  • ReactiveApp ↔ Coalg formal connection
  • Session duality proof

Effects

  • Signal — coinductive streams (const, map, delay, fold)
  • Event — subscriptions (interval, keyboard, WebSocket, workers)
  • Cmd — commands (HTTP, DOM, clipboard, storage, routing)
  • Task — monadic chains with do-notation
  • HTTP requests with custom headers — httpGetH, httpPostH in both Cmd and Task

DSLs

  • CSS — typed generation: Decl, Length, Color, Layout, Transitions, Animations, Stylesheet
  • SVG — namespace-aware: typed elements, Path commands, Transform, SMIL animations, pointer events
  • Animations — model-driven Tween/Spring with compile-time keyframe generation
  • WebGL — declarative 3D scene graphs: cameras, lights, materials, text3D, groups, events
  • WebGL Builder — geometry (CSG, procedural), layout (stack, grid, radial), instancing, LOD, culling
  • WebGL Controls — complete 3D UI library: buttons, sliders, toggles, menus, tabs, input fields, charts, audio visualization, gizmos

Server & Backend

  • HTTP Server — Warp via FFI.Server (listen, request/response with headers)
  • Auth — JWT signing/verification, bcrypt passwords, Bearer middleware, client-side token management (localStorage)
  • Crypto FFI — HMAC-SHA256, bcrypt, base64, random bytes (Haskell via cryptonite)
  • WAL Persistence — write-ahead log with snapshots, thread-safe MVar-based state, automatic compaction
  • File System FFI — readFile, writeFile, appendFile, exists, mkdir, rename (Haskell IO)

WebGL Controls

Complete 3D UI library for building interactive WebGL applications:

open import Agdelte.WebGL.Controls

-- 3D control panel
controlPanel : Scene Model Msg
controlPanel = mkScene camera
  ( -- Themed 3D button
    button darkTheme "Start" StartClicked t1
  ∷ -- Horizontal slider with value display
    labeledSlider darkTheme "Volume" getVolume SetVolume showPercent t2
  ∷ -- Toggle switch
    labeledToggle darkTheme "Mute" getMuted ToggleMute t3
  ∷ -- Real-time spectrum analyzer
    frequencyBars3D darkTheme spectrumConfig getFrequencies t4
  ∷ -- Transform gizmo for 3D manipulation
    translateGizmo defaultGizmoStyle UpdatePosition t5
  ∷ [] )

18 control modules:

Category Controls
Basic button, iconButton, fabButton, labeledButton
Sliders hslider, vslider, dial, labeledSlider, intSlider
Toggles toggle, checkbox, radio, rockerSwitch
Menus dropdown, radialMenu, contextMenu, selectionDropdown
Tabs tabBar, tabPanel, segmentedControl, paginationDots
Input textInput, numberInput, colorPicker
Charts barChart3D, scatterPlot3D, surfacePlot3D, networkGraph3D
Audio frequencyBars3D, circularSpectrum3D, oscilloscope3D, vuMeter3D, lissajous3D
Gizmos translateGizmo, rotateGizmo, scaleGizmo, boundingBox3D, selectionBox3D, distanceGizmo, angleGizmo, ruler3D, gridPlane

See doc/api/webgl-controls.md for full API.

Philosophy

Svelte's performance + dependent types = Agdelte

Agdelte takes Svelte's key insight — direct DOM updates without Virtual DOM — and makes it explicit and type-safe.

  • Svelte: Compiler generates direct DOM updates (magic)
  • Agdelte: Explicit bindings that the type system verifies (transparent)

Same performance characteristics, but you can see and reason about the reactive connections.

License

MIT

About

Dependent Lens FRP and concurrent model in Agda

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors