velox

package
v0.7.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 16, 2026 License: MIT Imports: 21 Imported by: 74

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	//MinThrottle is the minimum manual State.Throttle value.
	//15ms is approximately highest resolution on the JS eventloop.
	MinThrottle = 15 * time.Millisecond
	//DefaultThrottle is the default State.Throttle value.
	DefaultThrottle = 200 * time.Millisecond
	//DefaultWriteTimeout is the default State.Throttle value.
	DefaultWriteTimeout = 30 * time.Second
	//DefaultPingInterval is the default State.PingInterval value.
	DefaultPingInterval = 25 * time.Second
)
View Source
var JS = http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
	filename := "bundle.js"
	f, err := fs.Open(filename)
	if err != nil {
		panic(err)
	}
	s, err := f.Stat()
	if err != nil {
		panic(err)
	}

	http.ServeContent(w, req, s.Name(), s.ModTime(), f)
})

JS is an HTTP handler serving the velox.js frontend library

Functions

func SyncHandler

func SyncHandler(gostruct interface{}) http.Handler

SyncHandler is a small wrapper around Sync which simply synchronises all incoming connections. Use Sync if you wish to implement user authentication or any other request-time checks.

Types

type Client added in v0.5.0

type Client[T any] struct {
	// URL is the velox sync endpoint URL
	URL string
	// HTTPClient is the HTTP client to use (optional, useful for testing)
	HTTPClient *http.Client

	// Callbacks
	OnUpdate     func() // Called after data is updated (outside lock)
	OnConnect    func()
	OnDisconnect func()
	OnError      func(err error)

	// Retry enables automatic reconnection with backoff (default: true)
	Retry bool
	// MinRetryDelay is the minimum retry delay (default: 100ms)
	MinRetryDelay time.Duration
	// MaxRetryDelay is the maximum retry delay (default: 10s)
	MaxRetryDelay time.Duration
	// contains filtered or unexported fields
}

Client connects to a Velox server and keeps a local struct in sync.

func NewClient added in v0.5.0

func NewClient[T any](url string, data *T) (*Client[T], error)

NewClient creates a new Velox client that syncs to the given struct pointer. The data parameter must be a pointer to a struct. If the struct embeds sync.Mutex (or implements sync.Locker), it will be locked during updates.

func (*Client[T]) Connect added in v0.5.0

func (c *Client[T]) Connect(ctx context.Context) error

Connect starts the client connection. It blocks until the context is cancelled or an unrecoverable error occurs. If Retry is true (default), it will automatically reconnect on connection failures.

func (*Client[T]) Connected added in v0.5.0

func (c *Client[T]) Connected() bool

Connected returns true if the client is currently connected.

func (*Client[T]) Disconnect added in v0.5.0

func (c *Client[T]) Disconnect()

Disconnect stops the client connection.

func (*Client[T]) ID added in v0.5.0

func (c *Client[T]) ID() string

ID returns the server-assigned state ID.

func (*Client[T]) Version added in v0.5.0

func (c *Client[T]) Version() int64

Version returns the current version.

type Conn

type Conn interface {
	ID() string
	Connected() bool
	Wait()
	Push()
	Close() error
}

Conn represents a single live connection being synchronised. ID is current set to the connection's remote address.

func Sync

func Sync(gostruct interface{}, w http.ResponseWriter, r *http.Request) (Conn, error)

Sync upgrades a given HTTP connection into a velox connection and synchronises the provided struct with the client. velox takes responsibility for writing the response in the event of failure. Default handlers close the TCP connection on return so when manually using this method, you'll most likely want to block using Conn.Wait().

type MarshalFunc added in v0.4.2

type MarshalFunc func() (json.RawMessage, error)

func Marshal added in v0.4.2

func Marshal(gostruct interface{}) MarshalFunc

type Pusher

type Pusher interface {
	Push() bool
}

Pusher implements a push method, similar to Flush

type RLocker added in v0.6.0

type RLocker interface {
	sync.Locker
	RLock()
	RUnlock()
}

RLocker extends sync.Locker with read-lock methods. If a struct only implements sync.Locker, velox falls back to Lock() for reads.

type State

type State struct {
	//configuration
	Locker       sync.Locker   `json:"-"` // Locker optionally overrides the lock used during marshal/unmarshal.
	Data         MarshalFunc   `json:"-"` // Data is called each Push to get the current state of the object.
	Throttle     time.Duration `json:"-"` // Throttle is the minimum time between pushes.
	WriteTimeout time.Duration `json:"-"` // WriteTimeout is the maximum time to wait for a write to complete.
	PingInterval time.Duration `json:"-"` // PingInterval is the time between pings to the client.
	Debug        bool          `json:"-"` // Debug is used to enable debug logging.
	// contains filtered or unexported fields
}

State must be embedded into a struct to make it syncable.

func New added in v0.4.2

func New(data MarshalFunc) *State

New creates a new State object with the given data function. Data must not return an error otherwise New will panic.

func NewAny added in v0.4.2

func NewAny(data any) *State

NewAny creates a new State object with the given json-serializable data. If data is a sync.Locker, it will be locked during the marshalling process.

func (*State) Handle added in v0.4.2

func (state *State) Handle(w http.ResponseWriter, r *http.Request) (Conn, error)

func (*State) ID

func (s *State) ID() string

ID uniquely identifies this state object

func (*State) NumConnections

func (s *State) NumConnections() int

NumConnections currently active

func (*State) Push

func (s *State) Push() bool

Push the changes from this object to all connected clients. Push is thread-safe and is throttled so it can be called with abandon. Returns false if a Push is already in progress.

func (*State) ServeHTTP added in v0.4.2

func (s *State) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*State) Version

func (s *State) Version() int64

Version of this state object (when the underlying struct is and a Push is performed, this version number is incremented).

type Update added in v0.4.2

type Update struct {
	ID      string          `json:"id,omitempty"`
	Ping    bool            `json:"ping,omitempty"`
	Delta   bool            `json:"delta,omitempty"`
	Version int64           `json:"version,omitempty"` //53 usable bits
	Body    json.RawMessage `json:"body,omitempty"`
}

Update is a single message sent to the client

type VMap added in v0.6.0

type VMap[K comparable, V any] struct {
	// contains filtered or unexported fields
}

VMap is a generic map container that provides automatic locking and push support. Binding to a locker and pusher happens automatically via SyncHandler (server) and Client (after unmarshal).

func (*VMap[K, V]) Batch added in v0.6.0

func (m *VMap[K, V]) Batch(fn func(data map[K]V))

Batch allows multiple operations on the map with a single push at the end. The function receives the raw map and can modify it directly.

func (*VMap[K, V]) Clear added in v0.6.0

func (m *VMap[K, V]) Clear()

Clear removes all entries from the map and triggers a push.

func (*VMap[K, V]) Delete added in v0.6.0

func (m *VMap[K, V]) Delete(key K)

Delete removes the key from the map and triggers a push.

func (*VMap[K, V]) Get added in v0.6.0

func (m *VMap[K, V]) Get(key K) (V, bool)

Get returns the value for the given key and whether it exists.

func (*VMap[K, V]) Has added in v0.6.0

func (m *VMap[K, V]) Has(key K) bool

Has returns true if the key exists in the map.

func (*VMap[K, V]) Keys added in v0.6.0

func (m *VMap[K, V]) Keys() []K

Keys returns a slice of all keys in the map.

func (*VMap[K, V]) Len added in v0.6.0

func (m *VMap[K, V]) Len() int

Len returns the number of entries in the map.

func (*VMap[K, V]) MarshalJSON added in v0.6.0

func (m *VMap[K, V]) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler. No locking - parent already holds lock during marshal.

func (*VMap[K, V]) Range added in v0.6.0

func (m *VMap[K, V]) Range(fn func(key K, value V) bool)

Range calls the given function for each key-value pair in the map. If the function returns false, iteration stops. Note: The function is called with the lock held.

func (*VMap[K, V]) Set added in v0.6.0

func (m *VMap[K, V]) Set(key K, value V)

Set sets the value for the given key and triggers a push.

func (*VMap[K, V]) Snapshot added in v0.6.0

func (m *VMap[K, V]) Snapshot() map[K]V

Snapshot returns a copy of the underlying map.

func (*VMap[K, V]) UnmarshalJSON added in v0.6.0

func (m *VMap[K, V]) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler. No locking - parent already holds lock during unmarshal.

func (*VMap[K, V]) Update added in v0.6.0

func (m *VMap[K, V]) Update(key K, fn func(*V)) bool

Update calls the given function with a pointer to the value for the given key. If the key exists, the function is called and a push is triggered. Returns true if the key existed and was updated.

func (*VMap[K, V]) Values added in v0.6.0

func (m *VMap[K, V]) Values() []V

Values returns a slice of all values in the map.

type VSlice added in v0.6.0

type VSlice[V any] struct {
	// contains filtered or unexported fields
}

VSlice is a generic slice container that provides automatic locking and push support. Binding to a locker and pusher happens automatically via SyncHandler (server) and Client (after unmarshal).

func (*VSlice[V]) Append added in v0.6.0

func (s *VSlice[V]) Append(values ...V)

Append adds values to the end of the slice and triggers a push.

func (*VSlice[V]) At added in v0.6.0

func (s *VSlice[V]) At(index int) (V, bool)

At returns the element at the given index. Returns zero value and false if index is out of bounds.

func (*VSlice[V]) Batch added in v0.6.0

func (s *VSlice[V]) Batch(fn func(*[]V))

Batch allows multiple operations on the slice with a single push at the end. The function receives a pointer to the raw slice and can modify it directly.

func (*VSlice[V]) Clear added in v0.6.0

func (s *VSlice[V]) Clear()

Clear removes all elements from the slice and triggers a push.

func (*VSlice[V]) DeleteAt added in v0.6.0

func (s *VSlice[V]) DeleteAt(index int) bool

DeleteAt removes the element at the given index and triggers a push. Returns false if index is out of bounds.

func (*VSlice[V]) Get added in v0.6.0

func (s *VSlice[V]) Get() []V

Get returns a copy of the slice.

func (*VSlice[V]) Len added in v0.6.0

func (s *VSlice[V]) Len() int

Len returns the length of the slice.

func (*VSlice[V]) MarshalJSON added in v0.6.0

func (s *VSlice[V]) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler. No locking - parent already holds lock during marshal.

func (*VSlice[V]) Range added in v0.6.0

func (s *VSlice[V]) Range(fn func(index int, value V) bool)

Range calls the given function for each element in the slice. If the function returns false, iteration stops. Note: The function is called with the lock held.

func (*VSlice[V]) Set added in v0.6.0

func (s *VSlice[V]) Set(data []V)

Set replaces the entire slice and triggers a push.

func (*VSlice[V]) SetAt added in v0.6.0

func (s *VSlice[V]) SetAt(index int, value V) bool

SetAt sets the element at the given index and triggers a push. Returns false if index is out of bounds.

func (*VSlice[V]) UnmarshalJSON added in v0.6.0

func (s *VSlice[V]) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler. No locking - parent already holds lock during unmarshal.

func (*VSlice[V]) Update added in v0.6.0

func (s *VSlice[V]) Update(index int, fn func(*V)) bool

Update calls the given function with a pointer to the element at the given index. Returns false if index is out of bounds.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL