Initial iris repository structure
Some checks failed
CI / build (push) Failing after 36s

WASM reactive UI framework for Go:
- reactive/ - Signal[T], Effect, Runtime
- ui/ - Button, Text, Input, View, Canvas, SVG components
- navigation/ - Router, guards, history management
- auth/ - OIDC client for WASM applications
- host/ - Static file server

Extracted from arcadia as open-source component.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-01-08 19:23:49 +01:00
commit 00d98879d3
36 changed files with 4181 additions and 0 deletions

52
reactive/signal.go Normal file
View File

@@ -0,0 +1,52 @@
package reactive
type SignalId int
type Signal[T any] struct {
*Runtime
SignalId
}
func NewSignal[T any](initial T) Signal[T] {
rt := GetRuntime()
id := SignalId(len(rt.signalValues))
rt.signalValues = append(rt.signalValues, initial)
return Signal[T]{rt, id}
}
func NewSignalWithRuntime[T any](rt *Runtime, initial T) Signal[T] {
id := SignalId(len(rt.signalValues))
rt.signalValues = append(rt.signalValues, initial)
return Signal[T]{rt, id}
}
func (s *Signal[T]) Get() T {
val := s.Runtime.signalValues[s.SignalId]
if rt := s.Runtime; rt.runningEffect != nil {
// Check if this effect is already subscribed to this signal
subscribers := rt.signalSubscribers[s.SignalId]
alreadySubscribed := false
for _, effectId := range subscribers {
if effectId == *rt.runningEffect {
alreadySubscribed = true
break
}
}
if !alreadySubscribed {
rt.signalSubscribers[s.SignalId] = append(rt.signalSubscribers[s.SignalId], *rt.runningEffect)
}
}
return val.(T)
}
func (s *Signal[T]) Set(v T) {
s.Runtime.signalValues[s.SignalId] = v
if subscribers, ok := s.Runtime.signalSubscribers[s.SignalId]; ok {
for _, effectId := range subscribers {
runEffect(s.Runtime, effectId)
}
}
}