A fork of the Cocoon PDS but being made more distributed.
11

Configure Feed

Select the types of activity you want to include in your feed.

return correct responses for writes

Hailey (Mar 28, 2025, 11:39 PM -0700) ba805c95 24a885b5

+61 -24
+11 -2
server/handle_repo_apply_writes.go
··· 20 20 Value *MarshalableMap `json:"value,omitempty"` 21 21 } 22 22 23 + type ComAtprotoRepoApplyWritesResponse struct { 24 + Commit RepoCommit `json:"commit"` 25 + Results []ApplyWriteResult `json:"results"` 26 + } 27 + 23 28 func (s *Server) handleApplyWrites(e echo.Context) error { 24 29 repo := e.Get("repo").(*models.RepoActor) 25 30 ··· 49 54 }) 50 55 } 51 56 52 - if err := s.repoman.applyWrites(repo.Repo, ops, req.SwapCommit); err != nil { 57 + results, err := s.repoman.applyWrites(repo.Repo, ops, req.SwapCommit) 58 + if err != nil { 53 59 s.logger.Error("error applying writes", "error", err) 54 60 return helpers.ServerError(e, nil) 55 61 } 56 62 57 - return nil 63 + return e.JSON(200, ComAtprotoRepoApplyWritesResponse{ 64 + Commit: *results[0].Commit, 65 + Results: results, 66 + }) 58 67 }
+5 -2
server/handle_repo_create_record.go
··· 40 40 optype = OpTypeUpdate 41 41 } 42 42 43 - if err := s.repoman.applyWrites(repo.Repo, []Op{ 43 + results, err := s.repoman.applyWrites(repo.Repo, []Op{ 44 44 { 45 45 Type: optype, 46 46 Collection: req.Collection, ··· 49 49 Record: &req.Record, 50 50 SwapRecord: req.SwapRecord, 51 51 }, 52 - }, req.SwapCommit); err != nil { 52 + }, req.SwapCommit) 53 + if err != nil { 53 54 s.logger.Error("error applying writes", "error", err) 54 55 return helpers.ServerError(e, nil) 55 56 } 57 + 58 + return e.JSON(200, results[0]) 56 59 57 60 return nil 58 61 }
+4 -3
server/handle_repo_put_record.go
··· 40 40 optype = OpTypeUpdate 41 41 } 42 42 43 - if err := s.repoman.applyWrites(repo.Repo, []Op{ 43 + results, err := s.repoman.applyWrites(repo.Repo, []Op{ 44 44 { 45 45 Type: optype, 46 46 Collection: req.Collection, ··· 49 49 Record: &req.Record, 50 50 SwapRecord: req.SwapRecord, 51 51 }, 52 - }, req.SwapCommit); err != nil { 52 + }, req.SwapCommit) 53 + if err != nil { 53 54 s.logger.Error("error applying writes", "error", err) 54 55 return helpers.ServerError(e, nil) 55 56 } 56 57 57 - return nil 58 + return e.JSON(200, results[0]) 58 59 }
+41 -17
server/repo.go
··· 82 82 return nil 83 83 } 84 84 85 + type ApplyWriteResult struct { 86 + Uri string `json:"string"` 87 + Cid string `json:"cid"` 88 + Commit *RepoCommit `json:"commit"` 89 + ValidationStatus *string `json:"validationStatus"` 90 + } 91 + 92 + type RepoCommit struct { 93 + Cid string `json:"cid"` 94 + Rev string `json:"rev"` 95 + } 96 + 85 97 // TODO make use of swap commit 86 - func (rm *RepoMan) applyWrites(urepo models.Repo, writes []Op, swapCommit *string) error { 98 + func (rm *RepoMan) applyWrites(urepo models.Repo, writes []Op, swapCommit *string) ([]ApplyWriteResult, error) { 87 99 rootcid, err := cid.Cast(urepo.Root) 88 100 if err != nil { 89 - return err 101 + return nil, err 90 102 } 91 103 92 104 dbs := blockstore.New(urepo.Did, rm.db) ··· 96 108 97 109 for i, op := range writes { 98 110 if op.Type != OpTypeCreate && op.Rkey == nil { 99 - return fmt.Errorf("invalid rkey") 111 + return nil, fmt.Errorf("invalid rkey") 100 112 } else if op.Rkey == nil { 101 113 op.Rkey = to.StringPtr(rm.clock.Next().String()) 102 114 writes[i].Rkey = op.Rkey ··· 104 116 105 117 _, err := syntax.ParseRecordKey(*op.Rkey) 106 118 if err != nil { 107 - return err 119 + return nil, err 108 120 } 109 121 110 122 switch op.Type { 111 123 case OpTypeCreate: 112 124 nc, err := r.PutRecord(context.TODO(), op.Collection+"/"+*op.Rkey, op.Record) 113 125 if err != nil { 114 - return err 126 + return nil, err 115 127 } 116 128 117 129 d, _ := data.MarshalCBOR(*op.Record) ··· 126 138 case OpTypeDelete: 127 139 err := r.DeleteRecord(context.TODO(), op.Collection+"/"+*op.Rkey) 128 140 if err != nil { 129 - return err 141 + return nil, err 130 142 } 131 143 case OpTypeUpdate: 132 144 nc, err := r.UpdateRecord(context.TODO(), op.Collection+"/"+*op.Rkey, op.Record) 133 145 if err != nil { 134 - return err 146 + return nil, err 135 147 } 136 148 137 149 d, _ := data.MarshalCBOR(*op.Record) ··· 148 160 149 161 newroot, rev, err := r.Commit(context.TODO(), urepo.SignFor) 150 162 if err != nil { 151 - return err 163 + return nil, err 152 164 } 153 165 154 166 buf := new(bytes.Buffer) ··· 159 171 }) 160 172 161 173 if _, err := carstore.LdWrite(buf, hb); err != nil { 162 - return err 174 + return nil, err 163 175 } 164 176 165 177 diffops, err := r.DiffSince(context.TODO(), rootcid) 166 178 if err != nil { 167 - return err 179 + return nil, err 168 180 } 169 181 170 182 ops := make([]*atproto.SyncSubscribeRepos_RepoOp, 0, len(diffops)) ··· 194 206 195 207 blk, err := dbs.Get(context.TODO(), op.NewCid) 196 208 if err != nil { 197 - return err 209 + return nil, err 198 210 } 199 211 200 212 if _, err := carstore.LdWrite(buf, blk.Cid().Bytes(), blk.RawData()); err != nil { 201 - return err 213 + return nil, err 202 214 } 203 215 } 204 216 205 217 for _, op := range dbs.GetLog() { 206 218 if _, err := carstore.LdWrite(buf, op.Cid().Bytes(), op.RawData()); err != nil { 207 - return err 219 + return nil, err 208 220 } 209 221 } 222 + 223 + var results []ApplyWriteResult 210 224 211 225 var blobs []lexutil.LexLink 212 226 for _, entry := range entries { ··· 214 228 Columns: []clause.Column{{Name: "did"}, {Name: "nsid"}, {Name: "rkey"}}, 215 229 UpdateAll: true, 216 230 }).Create(&entry).Error; err != nil { 217 - return err 231 + return nil, err 218 232 } 219 233 220 234 // we should actually check the type (i.e. delete, create,., update) here but we'll do it later 221 235 cids, err := rm.incrementBlobRefs(urepo, entry.Value) 222 236 if err != nil { 223 - return err 237 + return nil, err 224 238 } 225 239 226 240 for _, c := range cids { 227 241 blobs = append(blobs, lexutil.LexLink(c)) 228 242 } 243 + 244 + results = append(results, ApplyWriteResult{ 245 + Uri: "at://" + urepo.Did + "/" + entry.Nsid + "/" + entry.Rkey, 246 + Cid: entry.Cid, 247 + Commit: &RepoCommit{ 248 + Cid: newroot.String(), 249 + Rev: rev, 250 + }, 251 + ValidationStatus: to.StringPtr("valid"), // TODO: obviously this might not be true atm lol 252 + }) 229 253 } 230 254 231 255 rm.s.evtman.AddEvent(context.TODO(), &events.XRPCStreamEvent{ ··· 243 267 }) 244 268 245 269 if err := dbs.UpdateRepo(context.TODO(), newroot, rev); err != nil { 246 - return err 270 + return nil, err 247 271 } 248 272 249 - return nil 273 + return results, nil 250 274 } 251 275 252 276 func (rm *RepoMan) getRecordProof(urepo models.Repo, collection, rkey string) (cid.Cid, []blocks.Block, error) {