Files
mesh-delivery/modules/mesh-delivery-view/internal/view/source.go
T
jschoubben da8384d10e VW5: the view takes each watched branch's source from the gate's verb source, per branch
The view read the gate's state source and its history, fixed to the branch main. Each watched branch's source is now
the seat mesh-delivery's verb source given that branch, asked again on its source-moved; the source row and the event
delivered are per branch, a repository's reach is from the source of its modules' registration's first branch, laid
over the reach the view's own state kept at its start, and view_tiers given no revision answers per branch. The
manifest drops its read of mesh-delivery-gate.source and names the source answer's fields it relies on.

Builds: design 47 G §507, §512, §532, §558, A-173, A-225

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

72 lines
2.8 KiB
Go

package view
import (
"encoding/json"
"fmt"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/clients/meshdeliveryclient"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/seats/meshdelivery"
"git.novox.be/novox/mesh-sdk/go/buscalls"
"git.novox.be/novox/mesh-sdk/go/keys"
)
// SourceVerb is the seat mesh-delivery's verb source as the view's invokes names it: each watched branch's source revision,
// asked of the seat and never read from the gate's state (design 47 G §507, §512, A-173).
const SourceVerb = "seat:" + meshdelivery.Seat + "." + meshdelivery.VerbSource
// SourceOf asks the seat, through call, for one watched branch's source revision (branch as named) and reads its declared
// answer; an answer that carries an error is that error.
func SourceOf(call func(key string, body any) (json.RawMessage, error), branch string) (meshdelivery.SourceAnswer, error) {
raw, err := call(SourceVerb, meshdelivery.SourceInput{Branch: keys.EscapeName(branch)})
if err != nil {
return meshdelivery.SourceAnswer{}, fmt.Errorf("%s of %s: %w", SourceVerb, branch, err)
}
answer, said, ok := buscalls.Unwrap(raw)
if !ok {
return meshdelivery.SourceAnswer{}, fmt.Errorf("%s of %s answered: %s", SourceVerb, branch, said)
}
var a meshdelivery.SourceAnswer
if err := json.Unmarshal(answer, &a); err != nil {
return a, fmt.Errorf("the answer of %s of %s is not a source revision: %w", SourceVerb, branch, err)
}
if a.Error != "" {
return a, fmt.Errorf("%s of %s: %s", SourceVerb, branch, a.Error)
}
return a, nil
}
// SourceEntry is a branch's source answer as the model's entry of SourceBucket: keyed by the escaped branch, its revision the
// source revision, its value the heads by repository; a branch the gate holds no source revision of yet is a removal.
func SourceEntry(branch string, a meshdelivery.SourceAnswer) (Entry, error) {
heads := map[string]string{}
for _, h := range a.Repositories {
heads[h.Repository] = h.Head
}
e := Entry{Bucket: SourceBucket, Key: keys.EscapeName(branch), Revision: uint64(a.Revision)}
if a.Revision == 0 && len(heads) == 0 { // the gate holds no source revision of the branch yet
e.Deleted = true
return e, nil
}
v, err := meshdeliveryclient.EncodeSource(meshdelivery.SourceByBranchValue{Group: a.Group, Heads: heads})
if err != nil {
return Entry{}, err
}
e.Value = v
return e, nil
}
// SourcesOf is Reader.Sources over the watched branches followed now: each one's newest source revision through call.
func SourcesOf(call func(key string, body any) (json.RawMessage, error), followed func() []string) func() (map[string]uint64, error) {
return func() (map[string]uint64, error) {
out := map[string]uint64{}
for _, branch := range followed() {
a, err := SourceOf(call, branch)
if err != nil {
return nil, err
}
out[branch] = uint64(a.Revision)
}
return out, nil
}
}