1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package participant
import (
"context"
"encoding/json"
"errors"
"net/http"
"strings"
"github.com/bluesky-social/indigo/atproto/identity"
"github.com/johnandersen777/socialweb-computer-kcp/internal/atproto/market"
"github.com/johnandersen777/socialweb-computer-kcp/internal/contract/atprotorepo"
)
type RepoConfig struct {
DID string
Directory identity.Directory
HTTP *http.Client
Open func(ctx context.Context) (atprotorepo.Repo, error)
}
func NewRepoStore(cfg RepoConfig) (*market.RepoStore, error) {
if strings.TrimSpace(cfg.DID) == "" {
return nil, errors.New("participant: the record store needs the account DID")
}
if cfg.Open == nil {
return nil, errors.New("participant: the record store needs a repo handle")
}
reader := market.NewHTTPReader(cfg.Directory)
if cfg.HTTP != nil {
reader.Client = cfg.HTTP
}
return market.NewRepoStore(market.RepoStoreConfig{DID: cfg.DID, Foreign: reader, Open: cfg.Open}), nil
}
func EnsureRecordAt(ctx context.Context, records *market.RepoStore, did, collection, rkey string, record map[string]any) (market.StrongRef, error) {
if records == nil || did == "" {
return market.StrongRef{}, errors.New("participant: no record store or DID")
}
if found, err := records.GetRecord(ctx, did, collection, rkey); err == nil {
return market.NewStrongRef(found.URI, found.CID), nil
} else if !errors.Is(err, market.ErrNotFound) {
return market.StrongRef{}, err
}
ref, err := records.CreateRecordAt(ctx, did, collection, rkey, record)
if err == nil {
return ref, nil
}
if found, getErr := records.GetRecord(ctx, did, collection, rkey); getErr == nil {
return market.NewStrongRef(found.URI, found.CID), nil
}
return market.StrongRef{}, err
}
type CreateOnly struct {
Records *market.RepoStore
}
func (w CreateOnly) CreateRecord(ctx context.Context, repo, collection string, record map[string]any) (market.StrongRef, error) {
return w.Records.CreateRecord(ctx, repo, collection, record)
}
func (w CreateOnly) PutRecord(ctx context.Context, repo, collection, rkey string, record map[string]any) (market.StrongRef, error) {
return EnsureRecordAt(ctx, w.Records, repo, collection, rkey, record)
}
func (w CreateOnly) DeleteRecord(ctx context.Context, repo, collection, rkey string) error {
return w.Records.DeleteRecord(ctx, repo, collection, rkey)
}
func StructMap(value any) (map[string]any, error) {
raw, err := json.Marshal(value)
if err != nil {
return nil, err
}
out := map[string]any{}
if err := json.Unmarshal(raw, &out); err != nil {
return nil, err
}
return out, nil
}
func LastSegment(uri string) string {
if i := strings.LastIndexByte(uri, '/'); i >= 0 {
return uri[i+1:]
}
return uri
}