···2424 RelayHost string
2525 Outbox *Outbox
26262727- FullNetworkMode bool
2727+ FullNetworkMode bool
2828+ CollectionFilters []string
28292930 lastSeq atomic.Int64
3031}
···7374 ep.Logger.Error("failed to parse operations", "did", evt.Repo, "error", err)
7475 return err
7576 }
7777+7878+ // filter ops to only matching collections after validation (since all ops are necessary for commit validation)
7979+ filteredOps := []CommitOp{}
8080+ for _, op := range commit.Ops {
8181+ if matchesCollection(op.Collection, ep.CollectionFilters) {
8282+ filteredOps = append(filteredOps, op)
8383+ }
8484+ }
8585+ if len(filteredOps) == 0 {
8686+ return nil
8787+ }
8888+ commit.Ops = filteredOps
76897790 if curr.State == models.RepoStateResyncing {
7891 if err := ep.addToResyncBuffer(commit); err != nil {
+5
nexus/resync.go
···155155 rkeyStr := rkey.String()
156156 cidStr := recCid.String()
157157158158+ // Filter collections - only process if matches filters
159159+ if !matchesCollection(collStr, n.EventProcessor.CollectionFilters) {
160160+ return nil
161161+ }
162162+158163 existingCid, exists := existingCids[recPath]
159164 if exists && existingCid == cidStr {
160165 return nil
+27
nexus/util.go
···11+package main
22+33+import "strings"
44+55+// matchesCollection checks if a collection matches any of the provided filters.
66+// Filters support wildcards at the end (e.g., "app.bsky.*" & "app.bsky.feed.*" both match "app.bsky.feed.post").
77+// If no filters are provided, all collections match.
88+func matchesCollection(collection string, filters []string) bool {
99+ if len(filters) == 0 {
1010+ return true
1111+ }
1212+1313+ for _, filter := range filters {
1414+ if strings.HasSuffix(filter, "*") {
1515+ prefix := strings.TrimSuffix(filter, "*")
1616+ if strings.HasPrefix(collection, prefix) {
1717+ return true
1818+ }
1919+ } else {
2020+ if collection == filter {
2121+ return true
2222+ }
2323+ }
2424+ }
2525+2626+ return false
2727+}