refactor folder structure

This commit is contained in:
2026-07-17 12:52:05 -04:00
parent dda0e738d4
commit 85d07f069e
80 changed files with 93 additions and 85 deletions

View File

@@ -0,0 +1,81 @@
package vdom
import "encoding/json"
// Schedule is installed by the wasm runtime at startup; a signal write
// triggers a re-render. On the server it is nil (renders are one-shot).
var Schedule func()
// Signal holds state. On the client, writing it schedules a re-render.
type Signal[T any] struct{ v T }
func NewSignal[T any](initial T) *Signal[T] {
s := &Signal[T]{v: initial}
if active != nil {
active.adopt(s) // server component round-trip: restore prior value, track for snapshot
}
return s
}
func (s *Signal[T]) Get() T { return s.v }
func (s *Signal[T]) Set(v T) {
s.v = v
if Schedule != nil {
Schedule()
}
}
func (s *Signal[T]) Update(fn func(T) T) { s.Set(fn(s.v)) }
func (s *Signal[T]) snapshot() []byte { b, _ := json.Marshal(s.v); return b }
func (s *Signal[T]) restoreFrom(b []byte) { _ = json.Unmarshal(b, &s.v) }
// ---- signal-state round-trip for server components ----
//
// A server component is stateless on the server: its signal values are
// serialized and round-tripped through the client. While a Collector is active
// (during a server-component render on the server), NewSignal restores each
// signal's value from the incoming snapshot by creation order (hook-order), and
// remembers it so the new values can be snapshotted back out.
type signalState interface {
snapshot() []byte
restoreFrom([]byte)
}
// Collector captures the signals created during a server render.
type Collector struct {
restore [][]byte
idx int
sigs []signalState
}
var active *Collector
func (c *Collector) adopt(s signalState) {
if c.idx < len(c.restore) {
s.restoreFrom(c.restore[c.idx])
}
c.idx++
c.sigs = append(c.sigs, s)
}
// BeginCollect starts collecting signals, restoring them from `restore` (which
// may be nil for an initial mount). Call EndCollect when construction is done.
func BeginCollect(restore [][]byte) *Collector {
active = &Collector{restore: restore}
return active
}
// EndCollect stops collecting (rendering/handlers may still read the signals).
func EndCollect() { active = nil }
// Snapshot returns the current values of the collected signals, in order.
func (c *Collector) Snapshot() [][]byte {
out := make([][]byte, len(c.sigs))
for i, s := range c.sigs {
out[i] = s.snapshot()
}
return out
}