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
package scoped
import (
"context"
"encoding/json"
"errors"
"strings"
commonv1 "github.com/johnandersen777/socialweb-computer-kcp/api/common/v1alpha1"
"github.com/johnandersen777/socialweb-computer-kcp/internal/contract/atprotorepo"
)
func Route(inner atprotorepo.Repo, network atprotorepo.RecordReader) atprotorepo.Repo {
if network == nil {
return inner
}
return &routed{Repo: inner, network: network}
}
type routed struct {
atprotorepo.Repo
network atprotorepo.RecordReader
}
var (
_ atprotorepo.SwapDeleter = (*routed)(nil)
_ atprotorepo.SwapPutter = (*routed)(nil)
)
func (r *routed) PutRecordSwap(ctx context.Context, collection, rkey string, value json.RawMessage, swapCID string) (commonv1.StrongRef, error) {
inner, ok := r.Repo.(atprotorepo.SwapPutter)
if !ok {
return commonv1.StrongRef{}, errors.New("scoped: the routed repo cannot put a record by its cid")
}
return inner.PutRecordSwap(ctx, collection, rkey, value, swapCID)
}
func (r *routed) DeleteRecordSwap(ctx context.Context, collection, rkey, swapCID string) error {
inner, ok := r.Repo.(atprotorepo.SwapDeleter)
if !ok {
return errors.New("scoped: the routed repo cannot delete a record by its cid")
}
return inner.DeleteRecordSwap(ctx, collection, rkey, swapCID)
}
func (r *routed) foreign(repo string) bool {
repo = strings.TrimSpace(repo)
return repo != "" && repo != r.DID()
}
func (r *routed) GetRecord(ctx context.Context, repo, collection, rkey string) (atprotorepo.Record, error) {
if r.foreign(repo) {
return r.network.GetRecord(ctx, repo, collection, rkey)
}
return r.Repo.GetRecord(ctx, repo, collection, rkey)
}
func (r *routed) ListRecords(ctx context.Context, repo, collection string, opts atprotorepo.ListOptions) (atprotorepo.ListPage, error) {
if r.foreign(repo) {
return r.network.ListRecords(ctx, repo, collection, opts)
}
return r.Repo.ListRecords(ctx, repo, collection, opts)
}
func (r *routed) Resolve(ctx context.Context, ref commonv1.StrongRef) (atprotorepo.Record, error) {
if authority, ok := uriAuthority(ref.URI); ok && r.foreign(authority) {
return r.network.Resolve(ctx, ref)
}
return r.Repo.Resolve(ctx, ref)
}
func uriAuthority(uri string) (string, bool) {
rest, ok := strings.CutPrefix(strings.TrimSpace(uri), "at://")
if !ok {
return "", false
}
authority, _, _ := strings.Cut(rest, "/")
return authority, authority != ""
}