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>
53 lines
1.2 KiB
Go
53 lines
1.2 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|