Signed-off-by: Seongmin Lee boltlessengineer@proton.me
+20
appview/indexer/base36/base36.go
+20
appview/indexer/base36/base36.go
···
1
+
// mostly copied from gitea/modules/indexer/internal/base32
2
+
3
+
package base36
4
+
5
+
import (
6
+
"fmt"
7
+
"strconv"
8
+
)
9
+
10
+
func Encode(i int64) string {
11
+
return strconv.FormatInt(i, 36)
12
+
}
13
+
14
+
func Decode(s string) (int64, error) {
15
+
i, err := strconv.ParseInt(s, 36, 64)
16
+
if err != nil {
17
+
return 0, fmt.Errorf("invalid base36 integer %q: %w", s, err)
18
+
}
19
+
return i, nil
20
+
}
+58
appview/indexer/bleve/batch.go
+58
appview/indexer/bleve/batch.go
···
1
+
// Copyright 2021 The Gitea Authors. All rights reserved.
2
+
// SPDX-License-Identifier: MIT
3
+
4
+
package bleveutil
5
+
6
+
import (
7
+
"github.com/blevesearch/bleve/v2"
8
+
)
9
+
10
+
// FlushingBatch is a batch of operations that automatically flushes to the
11
+
// underlying index once it reaches a certain size.
12
+
type FlushingBatch struct {
13
+
maxBatchSize int
14
+
batch *bleve.Batch
15
+
index bleve.Index
16
+
}
17
+
18
+
// NewFlushingBatch creates a new flushing batch for the specified index. Once
19
+
// the number of operations in the batch reaches the specified limit, the batch
20
+
// automatically flushes its operations to the index.
21
+
func NewFlushingBatch(index bleve.Index, maxBatchSize int) *FlushingBatch {
22
+
return &FlushingBatch{
23
+
maxBatchSize: maxBatchSize,
24
+
batch: index.NewBatch(),
25
+
index: index,
26
+
}
27
+
}
28
+
29
+
// Index add a new index to batch
30
+
func (b *FlushingBatch) Index(id string, data any) error {
31
+
if err := b.batch.Index(id, data); err != nil {
32
+
return err
33
+
}
34
+
return b.flushIfFull()
35
+
}
36
+
37
+
// Delete add a delete index to batch
38
+
func (b *FlushingBatch) Delete(id string) error {
39
+
b.batch.Delete(id)
40
+
return b.flushIfFull()
41
+
}
42
+
43
+
func (b *FlushingBatch) flushIfFull() error {
44
+
if b.batch.Size() < b.maxBatchSize {
45
+
return nil
46
+
}
47
+
return b.Flush()
48
+
}
49
+
50
+
// Flush submit the batch and create a new one
51
+
func (b *FlushingBatch) Flush() error {
52
+
err := b.index.Batch(b.batch)
53
+
if err != nil {
54
+
return err
55
+
}
56
+
b.batch = b.index.NewBatch()
57
+
return nil
58
+
}
+24
appview/indexer/indexer.go
+24
appview/indexer/indexer.go
···
1
+
package indexer
2
+
3
+
import (
4
+
"context"
5
+
6
+
"tangled.sh/tangled.sh/core/appview/db"
7
+
issues_indexer "tangled.sh/tangled.sh/core/appview/indexer/issues"
8
+
)
9
+
10
+
type Indexer struct {
11
+
Issues *issues_indexer.Indexer
12
+
}
13
+
14
+
func New() *Indexer {
15
+
return &Indexer {
16
+
issues_indexer.NewIndexer("indexes.bleve"),
17
+
}
18
+
}
19
+
20
+
// Init initializes all indexers
21
+
func (ix *Indexer) Init(ctx context.Context, db *db.DB) error {
22
+
ix.Issues.Init(ctx, db)
23
+
return nil
24
+
}
+199
appview/indexer/issues/indexer.go
+199
appview/indexer/issues/indexer.go
···
1
+
package issues_indexer
2
+
3
+
import (
4
+
"context"
5
+
"errors"
6
+
"log"
7
+
"os"
8
+
9
+
"github.com/blevesearch/bleve/v2"
10
+
"github.com/blevesearch/bleve/v2/index/upsidedown"
11
+
"github.com/blevesearch/bleve/v2/search/query"
12
+
"tangled.sh/tangled.sh/core/appview/db"
13
+
"tangled.sh/tangled.sh/core/appview/indexer/base36"
14
+
bleveutil "tangled.sh/tangled.sh/core/appview/indexer/bleve"
15
+
"tangled.sh/tangled.sh/core/appview/pagination"
16
+
)
17
+
18
+
type Indexer struct {
19
+
indexer bleve.Index
20
+
path string
21
+
}
22
+
23
+
func NewIndexer(indexDir string) *Indexer {
24
+
return &Indexer{
25
+
path: indexDir,
26
+
}
27
+
}
28
+
29
+
// Init initializes the indexer
30
+
func (ix *Indexer) Init(ctx context.Context, e db.Execer) {
31
+
existed, err := ix.intialize(ctx)
32
+
if err != nil {
33
+
log.Fatalf("failed to initialize issue indexer: %v", err)
34
+
}
35
+
if !existed {
36
+
log.Println("Populating the issue indexer")
37
+
err := PopulateIndexer(ctx, ix, e)
38
+
if err != nil {
39
+
log.Fatalf("failed to populate issue indexer: %v", err)
40
+
}
41
+
}
42
+
log.Println("Initialized the issue indexer")
43
+
}
44
+
45
+
func (ix *Indexer) intialize(_ context.Context) (bool, error) {
46
+
if ix.indexer != nil {
47
+
return false, errors.New("indexer is already initialized")
48
+
}
49
+
50
+
indexer, err := openIndexer(ix.path)
51
+
if err != nil {
52
+
return false, nil
53
+
}
54
+
if indexer != nil {
55
+
ix.indexer = indexer
56
+
return true, nil
57
+
}
58
+
59
+
mapping := bleve.NewIndexMapping()
60
+
indexer, err = bleve.New(ix.path, mapping)
61
+
if err != nil {
62
+
return false, err
63
+
}
64
+
65
+
ix.indexer = indexer
66
+
67
+
return false, nil
68
+
}
69
+
70
+
func openIndexer(path string) (bleve.Index, error) {
71
+
_, err := os.Stat(path)
72
+
indexer, err := bleve.Open(path)
73
+
if err != nil {
74
+
if errors.Is(err, upsidedown.IncompatibleVersion) {
75
+
log.Println("Indexer was built with a previous version of bleve, deleting and rebuilding")
76
+
return nil, os.RemoveAll(path)
77
+
}
78
+
return nil, nil
79
+
}
80
+
return indexer, nil
81
+
}
82
+
83
+
func PopulateIndexer(ctx context.Context, ix *Indexer, e db.Execer) error {
84
+
repos, err := db.GetAllRepos(e, 10)
85
+
if err != nil {
86
+
return err
87
+
}
88
+
for _, repo := range repos {
89
+
page := pagination.FirstPage()
90
+
issues, err := db.GetIssues(e, repo.RepoAt(), true, page)
91
+
if err != nil {
92
+
return err
93
+
}
94
+
for _, issue := range issues {
95
+
issue, _, err := db.GetIssueWithComments(e, repo.RepoAt(), issue.IssueId)
96
+
if err != nil {
97
+
return err
98
+
}
99
+
data := &IssueData {
100
+
ID: issue.ID,
101
+
IssueID: issue.IssueId,
102
+
Title: issue.Title,
103
+
Body: issue.Body,
104
+
IsOpen: issue.Open,
105
+
}
106
+
err = ix.Index(ctx, data)
107
+
if err != nil {
108
+
return err
109
+
}
110
+
}
111
+
}
112
+
return nil
113
+
}
114
+
115
+
// IssueData data stored and will be indexed
116
+
type IssueData struct {
117
+
ID int64 `json:"id"`
118
+
IssueID int `json:"issue_id"`
119
+
Title string `json:"title"`
120
+
Body string `json:"body"`
121
+
122
+
IsOpen bool `json:"is_open"`
123
+
Comments []IssueCommentData `json:"comments"`
124
+
}
125
+
126
+
type IssueCommentData struct {
127
+
Body string `json:"body"`
128
+
}
129
+
130
+
type SearchOptions struct {
131
+
Keyword string
132
+
IsOpen *bool
133
+
134
+
Page pagination.Page
135
+
}
136
+
137
+
type SearchResult struct {
138
+
Hits []int64
139
+
Total uint64
140
+
}
141
+
142
+
const maxBatchSize = 16
143
+
144
+
func (ix *Indexer) Index(ctx context.Context, issues ...*IssueData) error {
145
+
batch := bleveutil.NewFlushingBatch(ix.indexer, maxBatchSize)
146
+
for _, issue := range issues {
147
+
if err := batch.Index(base36.Encode(issue.ID), issue); err != nil {
148
+
return err
149
+
}
150
+
}
151
+
return batch.Flush()
152
+
}
153
+
154
+
// Search searches for issues
155
+
func (ix *Indexer) Search(ctx context.Context, opts SearchOptions) (*SearchResult, error) {
156
+
var queries []query.Query
157
+
158
+
if opts.Keyword != "" {
159
+
queries = append(queries, bleve.NewDisjunctionQuery(
160
+
matchAndQuery(opts.Keyword, "title"),
161
+
matchAndQuery(opts.Keyword, "body"),
162
+
))
163
+
}
164
+
if opts.IsOpen != nil {
165
+
queries = append(queries, boolFieldQuery(*opts.IsOpen, "is_open"))
166
+
}
167
+
// TODO: append more queries
168
+
169
+
var indexerQuery query.Query = bleve.NewConjunctionQuery(queries...)
170
+
searchReq := bleve.NewSearchRequestOptions(indexerQuery, opts.Page.Limit, opts.Page.Offset, false)
171
+
res, err := ix.indexer.SearchInContext(ctx, searchReq)
172
+
if err != nil {
173
+
return nil, nil
174
+
}
175
+
ret := &SearchResult{
176
+
Total: res.Total,
177
+
Hits: make([]int64, len(res.Hits)),
178
+
}
179
+
for i, hit := range res.Hits {
180
+
id, err := base36.Decode(hit.ID)
181
+
if err != nil {
182
+
return nil, err
183
+
}
184
+
ret.Hits[i] = id
185
+
}
186
+
return ret, nil
187
+
}
188
+
189
+
func matchAndQuery(keyword, field string) query.Query {
190
+
q := bleve.NewMatchQuery(keyword)
191
+
q.FieldVal = field
192
+
return q
193
+
}
194
+
195
+
func boolFieldQuery(val bool, field string) query.Query {
196
+
q := bleve.NewBoolFieldQuery(val)
197
+
q.FieldVal = field
198
+
return q
199
+
}
+30
appview/indexer/notifier.go
+30
appview/indexer/notifier.go
···
1
+
package indexer
2
+
3
+
import (
4
+
"context"
5
+
6
+
"tangled.sh/tangled.sh/core/appview/db"
7
+
issues_indexer "tangled.sh/tangled.sh/core/appview/indexer/issues"
8
+
"tangled.sh/tangled.sh/core/appview/notify"
9
+
)
10
+
11
+
var _ notify.Notifier = &Indexer{}
12
+
13
+
func (ix *Indexer) NewIssue(ctx context.Context, issue *db.Issue) {
14
+
ix.Issues.Index(ctx, &issues_indexer.IssueData{
15
+
ID: issue.ID,
16
+
IssueID: issue.IssueId,
17
+
Title: issue.Title,
18
+
Body: issue.Body,
19
+
IsOpen: issue.Open,
20
+
Comments: []issues_indexer.IssueCommentData{},
21
+
})
22
+
}
23
+
24
+
func (ix *Indexer) NewIssueComment(ctx context.Context, comment db.Comment) {
25
+
panic("unimplemented")
26
+
}
27
+
28
+
func (ix *Indexer) NewPullComment(ctx context.Context, comment db.PullComment) {
29
+
panic("unimplemented")
30
+
}
+10
appview/issues/issues.go
+10
appview/issues/issues.go
···
20
20
"tangled.sh/tangled.sh/core/appview/config"
21
21
"tangled.sh/tangled.sh/core/appview/db"
22
22
"tangled.sh/tangled.sh/core/appview/idresolver"
23
+
issues_indexer "tangled.sh/tangled.sh/core/appview/indexer/issues"
24
+
"tangled.sh/tangled.sh/core/appview/notify"
23
25
"tangled.sh/tangled.sh/core/appview/oauth"
24
26
"tangled.sh/tangled.sh/core/appview/pages"
25
27
"tangled.sh/tangled.sh/core/appview/pagination"
···
34
36
db *db.DB
35
37
config *config.Config
36
38
posthog posthog.Client
39
+
notifier notify.Notifier
40
+
indexer *issues_indexer.Indexer
37
41
}
38
42
39
43
func New(
···
44
48
db *db.DB,
45
49
config *config.Config,
46
50
posthog posthog.Client,
51
+
notifier notify.Notifier,
52
+
indexer *issues_indexer.Indexer,
47
53
) *Issues {
48
54
return &Issues{
49
55
oauth: oauth,
···
53
59
db: db,
54
60
config: config,
55
61
posthog: posthog,
62
+
notifier: notifier,
63
+
indexer: indexer,
56
64
}
57
65
}
58
66
···
734
742
return
735
743
}
736
744
745
+
rp.notifier.NewIssue(r.Context(), issue)
746
+
737
747
if !rp.config.Core.Dev {
738
748
err = rp.posthog.Enqueue(posthog.Capture{
739
749
DistinctId: user.Did,
+1
-1
appview/notify/merged_notifier.go
+1
-1
appview/notify/merged_notifier.go
···
18
18
19
19
var _ Notifier = &mergedNotifier{}
20
20
21
-
func (m *mergedNotifier) NewIssue(ctx context.Context, issue db.Issue) {
21
+
func (m *mergedNotifier) NewIssue(ctx context.Context, issue *db.Issue) {
22
22
for _, notifier := range m.notifiers {
23
23
notifier.NewIssue(ctx, issue)
24
24
}
+1
-1
appview/notify/notifier.go
+1
-1
appview/notify/notifier.go
+1
-1
appview/state/router.go
+1
-1
appview/state/router.go
···
191
191
}
192
192
193
193
func (s *State) IssuesRouter(mw *middleware.Middleware) http.Handler {
194
-
issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.posthog, s.notifier)
194
+
issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.posthog, s.notifier, s.indexer.Issues)
195
195
return issues.Router(mw)
196
196
197
197
}
+10
appview/state/state.go
+10
appview/state/state.go
···
25
25
"tangled.sh/tangled.sh/core/appview/config"
26
26
"tangled.sh/tangled.sh/core/appview/db"
27
27
"tangled.sh/tangled.sh/core/appview/idresolver"
28
+
"tangled.sh/tangled.sh/core/appview/indexer"
28
29
"tangled.sh/tangled.sh/core/appview/notify"
29
30
"tangled.sh/tangled.sh/core/appview/oauth"
30
31
"tangled.sh/tangled.sh/core/appview/pages"
···
39
40
type State struct {
40
41
db *db.DB
41
42
notifier notify.Notifier
43
+
indexer *indexer.Indexer
42
44
oauth *oauth.OAuth
43
45
enforcer *rbac.Enforcer
44
46
tidClock syntax.TIDClock
···
59
61
return nil, fmt.Errorf("failed to create db: %w", err)
60
62
}
61
63
64
+
indexer := indexer.New()
65
+
err = indexer.Init(ctx, d)
66
+
if err != nil {
67
+
return nil, fmt.Errorf("failed to create indexer: %w", err)
68
+
}
69
+
62
70
enforcer, err := rbac.NewEnforcer(config.Core.DbPath)
63
71
if err != nil {
64
72
return nil, fmt.Errorf("failed to create enforcer: %w", err)
···
137
145
spindlestream.Start(ctx)
138
146
139
147
notifier := notify.NewMergedNotifier(
148
+
indexer,
140
149
)
141
150
142
151
state := &State{
143
152
d,
144
153
notifier,
154
+
indexer,
145
155
oauth,
146
156
enforcer,
147
157
clock,
+1
-1
flake.nix
+1
-1
flake.nix
···
61
61
inherit (gitignore.lib) gitignoreSource;
62
62
in {
63
63
overlays.default = final: prev: let
64
-
goModHash = "sha256-SLi+nALwCd/Lzn3aljwPqCo2UaM9hl/4OAjcHQLt2Bk=";
64
+
goModHash = "sha256-N+Rm2PanY+fVRE/6Gaz+y3vSUjqKOtngpkS4fn7VFR0=";
65
65
appviewDeps = {
66
66
inherit htmx-src htmx-ws-src lucide-src inter-fonts-src ibm-plex-mono-src goModHash gitignoreSource;
67
67
};
+27
go.mod
+27
go.mod
···
48
48
dario.cat/mergo v1.0.1 // indirect
49
49
github.com/Microsoft/go-winio v0.6.2 // indirect
50
50
github.com/ProtonMail/go-crypto v1.2.0 // indirect
51
+
github.com/RoaringBitmap/roaring/v2 v2.4.5 // indirect
51
52
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
52
53
github.com/avast/retry-go/v4 v4.6.1 // indirect
53
54
github.com/aymerick/douceur v0.2.0 // indirect
54
55
github.com/beorn7/perks v1.0.1 // indirect
56
+
github.com/bits-and-blooms/bitset v1.22.0 // indirect
57
+
github.com/blevesearch/bleve/v2 v2.5.2 // indirect
58
+
github.com/blevesearch/bleve_index_api v1.2.8 // indirect
59
+
github.com/blevesearch/geo v0.2.3 // indirect
60
+
github.com/blevesearch/go-faiss v1.0.25 // indirect
61
+
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
62
+
github.com/blevesearch/gtreap v0.1.1 // indirect
63
+
github.com/blevesearch/mmap-go v1.0.4 // indirect
64
+
github.com/blevesearch/scorch_segment_api/v2 v2.3.10 // indirect
65
+
github.com/blevesearch/segment v0.9.1 // indirect
66
+
github.com/blevesearch/snowballstem v0.9.0 // indirect
67
+
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
68
+
github.com/blevesearch/vellum v1.1.0 // indirect
69
+
github.com/blevesearch/zapx/v11 v11.4.2 // indirect
70
+
github.com/blevesearch/zapx/v12 v12.4.2 // indirect
71
+
github.com/blevesearch/zapx/v13 v13.4.2 // indirect
72
+
github.com/blevesearch/zapx/v14 v14.4.2 // indirect
73
+
github.com/blevesearch/zapx/v15 v15.4.2 // indirect
74
+
github.com/blevesearch/zapx/v16 v16.2.4 // indirect
55
75
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
56
76
github.com/casbin/govaluate v1.3.0 // indirect
57
77
github.com/cespare/xxhash/v2 v2.3.0 // indirect
···
78
98
github.com/gogo/protobuf v1.3.2 // indirect
79
99
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
80
100
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
101
+
github.com/golang/protobuf v1.5.4 // indirect
102
+
github.com/golang/snappy v0.0.4 // indirect
81
103
github.com/gorilla/css v1.0.1 // indirect
82
104
github.com/gorilla/securecookie v1.1.2 // indirect
83
105
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
···
95
117
github.com/ipfs/go-log v1.0.5 // indirect
96
118
github.com/ipfs/go-log/v2 v2.6.0 // indirect
97
119
github.com/ipfs/go-metrics-interface v0.3.0 // indirect
120
+
github.com/json-iterator/go v1.1.12 // indirect
98
121
github.com/kevinburke/ssh_config v1.2.0 // indirect
99
122
github.com/klauspost/compress v1.18.0 // indirect
100
123
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
···
108
131
github.com/moby/docker-image-spec v1.3.1 // indirect
109
132
github.com/moby/sys/atomicwriter v0.1.0 // indirect
110
133
github.com/moby/term v0.5.2 // indirect
134
+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
135
+
github.com/modern-go/reflect2 v1.0.2 // indirect
111
136
github.com/morikuni/aec v1.0.0 // indirect
112
137
github.com/mr-tron/base58 v1.2.0 // indirect
138
+
github.com/mschoch/smat v0.2.0 // indirect
113
139
github.com/multiformats/go-base32 v0.1.0 // indirect
114
140
github.com/multiformats/go-base36 v0.2.0 // indirect
115
141
github.com/multiformats/go-multibase v0.2.0 // indirect
···
135
161
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
136
162
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect
137
163
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
164
+
go.etcd.io/bbolt v1.4.0 // indirect
138
165
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
139
166
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
140
167
go.opentelemetry.io/otel v1.36.0 // indirect
+58
go.sum
+58
go.sum
···
9
9
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
10
10
github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs=
11
11
github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
12
+
github.com/RoaringBitmap/roaring/v2 v2.4.5 h1:uGrrMreGjvAtTBobc0g5IrW1D5ldxDQYe2JW2gggRdg=
13
+
github.com/RoaringBitmap/roaring/v2 v2.4.5/go.mod h1:FiJcsfkGje/nZBZgCu0ZxCPOKD/hVXDS2dXi7/eUFE0=
12
14
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
13
15
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
14
16
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
···
23
25
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
24
26
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
25
27
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
28
+
github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
29
+
github.com/bits-and-blooms/bitset v1.22.0 h1:Tquv9S8+SGaS3EhyA+up3FXzmkhxPGjQQCkcs2uw7w4=
30
+
github.com/bits-and-blooms/bitset v1.22.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
31
+
github.com/blevesearch/bleve/v2 v2.5.2 h1:Ab0r0MODV2C5A6BEL87GqLBySqp/s9xFgceCju6BQk8=
32
+
github.com/blevesearch/bleve/v2 v2.5.2/go.mod h1:5Dj6dUQxZM6aqYT3eutTD/GpWKGFSsV8f7LDidFbwXo=
33
+
github.com/blevesearch/bleve_index_api v1.2.8 h1:Y98Pu5/MdlkRyLM0qDHostYo7i+Vv1cDNhqTeR4Sy6Y=
34
+
github.com/blevesearch/bleve_index_api v1.2.8/go.mod h1:rKQDl4u51uwafZxFrPD1R7xFOwKnzZW7s/LSeK4lgo0=
35
+
github.com/blevesearch/geo v0.2.3 h1:K9/vbGI9ehlXdxjxDRJtoAMt7zGAsMIzc6n8zWcwnhg=
36
+
github.com/blevesearch/geo v0.2.3/go.mod h1:K56Q33AzXt2YExVHGObtmRSFYZKYGv0JEN5mdacJJR8=
37
+
github.com/blevesearch/go-faiss v1.0.25 h1:lel1rkOUGbT1CJ0YgzKwC7k+XH0XVBHnCVWahdCXk4U=
38
+
github.com/blevesearch/go-faiss v1.0.25/go.mod h1:OMGQwOaRRYxrmeNdMrXJPvVx8gBnvE5RYrr0BahNnkk=
39
+
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
40
+
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
41
+
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
42
+
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
43
+
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
44
+
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
45
+
github.com/blevesearch/scorch_segment_api/v2 v2.3.10 h1:Yqk0XD1mE0fDZAJXTjawJ8If/85JxnLd8v5vG/jWE/s=
46
+
github.com/blevesearch/scorch_segment_api/v2 v2.3.10/go.mod h1:Z3e6ChN3qyN35yaQpl00MfI5s8AxUJbpTR/DL8QOQ+8=
47
+
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
48
+
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
49
+
github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s=
50
+
github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs=
51
+
github.com/blevesearch/upsidedown_store_api v1.0.2 h1:U53Q6YoWEARVLd1OYNc9kvhBMGZzVrdmaozG2MfoB+A=
52
+
github.com/blevesearch/upsidedown_store_api v1.0.2/go.mod h1:M01mh3Gpfy56Ps/UXHjEO/knbqyQ1Oamg8If49gRwrQ=
53
+
github.com/blevesearch/vellum v1.1.0 h1:CinkGyIsgVlYf8Y2LUQHvdelgXr6PYuvoDIajq6yR9w=
54
+
github.com/blevesearch/vellum v1.1.0/go.mod h1:QgwWryE8ThtNPxtgWJof5ndPfx0/YMBh+W2weHKPw8Y=
55
+
github.com/blevesearch/zapx/v11 v11.4.2 h1:l46SV+b0gFN+Rw3wUI1YdMWdSAVhskYuvxlcgpQFljs=
56
+
github.com/blevesearch/zapx/v11 v11.4.2/go.mod h1:4gdeyy9oGa/lLa6D34R9daXNUvfMPZqUYjPwiLmekwc=
57
+
github.com/blevesearch/zapx/v12 v12.4.2 h1:fzRbhllQmEMUuAQ7zBuMvKRlcPA5ESTgWlDEoB9uQNE=
58
+
github.com/blevesearch/zapx/v12 v12.4.2/go.mod h1:TdFmr7afSz1hFh/SIBCCZvcLfzYvievIH6aEISCte58=
59
+
github.com/blevesearch/zapx/v13 v13.4.2 h1:46PIZCO/ZuKZYgxI8Y7lOJqX3Irkc3N8W82QTK3MVks=
60
+
github.com/blevesearch/zapx/v13 v13.4.2/go.mod h1:knK8z2NdQHlb5ot/uj8wuvOq5PhDGjNYQQy0QDnopZk=
61
+
github.com/blevesearch/zapx/v14 v14.4.2 h1:2SGHakVKd+TrtEqpfeq8X+So5PShQ5nW6GNxT7fWYz0=
62
+
github.com/blevesearch/zapx/v14 v14.4.2/go.mod h1:rz0XNb/OZSMjNorufDGSpFpjoFKhXmppH9Hi7a877D8=
63
+
github.com/blevesearch/zapx/v15 v15.4.2 h1:sWxpDE0QQOTjyxYbAVjt3+0ieu8NCE0fDRaFxEsp31k=
64
+
github.com/blevesearch/zapx/v15 v15.4.2/go.mod h1:1pssev/59FsuWcgSnTa0OeEpOzmhtmr/0/11H0Z8+Nw=
65
+
github.com/blevesearch/zapx/v16 v16.2.4 h1:tGgfvleXTAkwsD5mEzgM3zCS/7pgocTCnO1oyAUjlww=
66
+
github.com/blevesearch/zapx/v16 v16.2.4/go.mod h1:Rti/REtuuMmzwsI8/C/qIzRaEoSK/wiFYw5e5ctUKKs=
26
67
github.com/bluesky-social/indigo v0.0.0-20250520232546-236dd575c91e h1:DVD+HxQsDCVJtAkjfIKZVaBNc3kayHaU+A2TJZkFdp4=
27
68
github.com/bluesky-social/indigo v0.0.0-20250520232546-236dd575c91e/go.mod h1:ovyxp8AMO1Hoe838vMJUbqHTZaAR8ABM3g3TXu+A5Ng=
28
69
github.com/bluesky-social/jetstream v0.0.0-20241210005130-ea96859b93d1 h1:CFvRtYNSnWRAi/98M3O466t9dYuwtesNbu6FVPymRrA=
···
143
184
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
144
185
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
145
186
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
187
+
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
188
+
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
189
+
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
190
+
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
146
191
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
147
192
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
148
193
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
···
151
196
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
152
197
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
153
198
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
199
+
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
154
200
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
155
201
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
156
202
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
···
220
266
github.com/ipfs/go-test v0.2.1/go.mod h1:dzu+KB9cmWjuJnXFDYJwC25T3j1GcN57byN+ixmK39M=
221
267
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
222
268
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
269
+
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
270
+
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
223
271
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
224
272
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
225
273
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
···
273
321
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
274
322
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
275
323
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
324
+
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
325
+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
326
+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
327
+
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
328
+
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
276
329
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
277
330
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
278
331
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
279
332
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
333
+
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
334
+
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
280
335
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
281
336
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
282
337
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
···
411
466
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8=
412
467
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q=
413
468
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02/go.mod h1:JTnUj0mpYiAsuZLmKjTx/ex3AtMowcCgnE7YNyCEP0I=
469
+
go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
470
+
go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
414
471
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
415
472
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
416
473
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
···
592
649
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
593
650
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
594
651
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
652
+
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
595
653
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
596
654
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
597
655
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=