Files
mesh-sdk/go/busstate/busstate.go
T
jschoubben 5fa64be894 Revert the revert of G's mesh-sdk merge (#191): G's sdk stands again over reader release 3
Main reverted G's half merge (#189, reverted by 8afc3eb in #191) and then took the reader release's S1-S5, which
copied G's code. G's form holds where they differ (process_bus.go, seats.go, state.go and their tests); the
release's kept names stay so main's callers keep building: SeatViewPrefix beside SeatReadPrefix, and QueueInvoke's
empty strings on not-ok (with its test TestQueueInvoke). The tree differs from G's head f30dee54 only by those and
the release's two tests (objects cap option, seat states and stream kinds).

Builds: design 47 G (the milestone's sdk part, as at f30dee54)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-13 12:49:56 +01:00

85 lines
3.2 KiB
Go

// Package busstate is how a bundle uses its own bus state through the runtime (novox/hq ADR 0595 §9, design 25 §
// 12.5): the object store's put, get, list, delete and fill, each naming an entry by the local name its module asks for
// it by in `requires`. The runtime serves the calls from the module's own bindings, its own entries only. The shapes
// are package buscalls's; this package makes the calls.
package busstate
import (
"encoding/json"
"fmt"
stdio "git.novox.be/novox/mesh-sdk/go"
"git.novox.be/novox/mesh-sdk/go/buscalls"
)
// Objects is one object store the module asks for in `requires` (the template objects, ADR 0595 §2), by its local name.
type Objects struct{ local string }
// ObjectsOf is the object store of that local name.
func ObjectsOf(local string) Objects { return Objects{local: local} }
func call[T any](method string, params any) (T, error) {
var out T
raw, err := stdio.BusState(method, params)
if err != nil {
return out, err
}
if err := json.Unmarshal(raw, &out); err != nil {
return out, fmt.Errorf("the runtime's answer to %s: %w", method, err)
}
return out, nil
}
// Put stores one object whole under its name, replacing one of that name, and answers it as the store holds it.
//
// A value larger than buscalls.ChunkBytes is put as a session of chunks (design 47 G §518, §345): every object is one
// object, never split over several.
func (o Objects) Put(name string, data []byte, description string) (buscalls.ObjectInfo, error) {
if len(data) > buscalls.ChunkBytes {
return o.putSession(name, data, description)
}
return call[buscalls.ObjectInfo](buscalls.ObjectsPut, buscalls.ObjectsPutRequest{Objects: o.local, Name: name,
Data: data, Description: description})
}
// Get is one object, its info and its bytes.
//
// A value the runtime answers as a session (`chunked`) is read chunk by chunk and checked against its digest (design 47 G §490).
func (o Objects) Get(name string) (buscalls.ObjectData, error) {
raw, err := stdio.BusState(buscalls.ObjectsGet, buscalls.ObjectsNameRequest{Objects: o.local, Name: name})
if err != nil {
return buscalls.ObjectData{}, err
}
return ReadObject(name, raw)
}
// ReadObject is the object a runtime's answer to a get (or to a sent-get, design 47 G §620) holds: the value itself, or the
// session of chunks it opened, read whole.
func ReadObject(name string, raw json.RawMessage) (buscalls.ObjectData, error) {
if c, ok := chunkedAnswer(raw); ok {
return getSession(name, c)
}
var out buscalls.ObjectData
if err := json.Unmarshal(raw, &out); err != nil {
return out, fmt.Errorf("the runtime's answer for %s: %w", name, err)
}
return out, nil
}
// List is every object the store holds.
func (o Objects) List() ([]buscalls.ObjectInfo, error) {
l, err := call[buscalls.ObjectsListed](buscalls.ObjectsList, buscalls.ObjectsRequest{Objects: o.local})
return l.Objects, err
}
// Delete removes one object.
func (o Objects) Delete(name string) error {
_, err := call[buscalls.Done](buscalls.ObjectsDelete, buscalls.ObjectsNameRequest{Objects: o.local, Name: name})
return err
}
// Fill is how much the store holds against its cap.
func (o Objects) Fill() (buscalls.Fill, error) {
return call[buscalls.Fill](buscalls.ObjectsInfo, buscalls.ObjectsRequest{Objects: o.local})
}