Main reverted G's half merge (#189, reverted by8afc3ebin #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 headf30dee54only 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 atf30dee54) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
85 lines
3.2 KiB
Go
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})
|
|
}
|