bluesky appview implementation using microcosm and other services server.reddwarf.app
appview bluesky reddwarf microcosm
1package main 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "strings" 9 "sync" 10) 11 12type DIDDocument struct { 13 ID string `json:"id"` 14 Service []struct { 15 ID string `json:"id"` 16 Type string `json:"type"` 17 ServiceEndpoint string `json:"serviceEndpoint"` 18 } `json:"service"` 19} 20 21func ResolveDID(did string) (*DIDDocument, error) { 22 var url string 23 24 if strings.HasPrefix(did, "did:plc:") { 25 // Resolve via PLC Directory 26 url = "https://plc.directory/" + did 27 } else if strings.HasPrefix(did, "did:web:") { 28 // Resolve via Web (simplified) 29 domain := strings.TrimPrefix(did, "did:web:") 30 url = "https://" + domain + "/.well-known/did.json" 31 } else { 32 return nil, fmt.Errorf("unsupported DID format: %s", did) 33 } 34 35 resp, err := http.Get(url) 36 if err != nil { 37 return nil, err 38 } 39 defer resp.Body.Close() 40 41 if resp.StatusCode != http.StatusOK { 42 return nil, fmt.Errorf("resolver returned status: %d", resp.StatusCode) 43 } 44 45 var doc DIDDocument 46 if err := json.NewDecoder(resp.Body).Decode(&doc); err != nil { 47 return nil, err 48 } 49 50 return &doc, nil 51} 52 53type AsyncResult[T any] struct { 54 Value T 55 Err error 56} 57 58func MapConcurrent[T any, R any]( 59 ctx context.Context, 60 items []T, 61 concurrencyLimit int, 62 mapper func(context.Context, T) (R, error), 63) []AsyncResult[R] { 64 if len(items) == 0 { 65 return nil 66 } 67 68 results := make([]AsyncResult[R], len(items)) 69 var wg sync.WaitGroup 70 71 sem := make(chan struct{}, concurrencyLimit) 72 73 for i, item := range items { 74 wg.Add(1) 75 go func(idx int, input T) { 76 defer wg.Done() 77 78 sem <- struct{}{} 79 defer func() { <-sem }() 80 81 if ctx.Err() != nil { 82 results[idx] = AsyncResult[R]{Err: ctx.Err()} 83 return 84 } 85 86 val, err := mapper(ctx, input) 87 results[idx] = AsyncResult[R]{Value: val, Err: err} 88 }(i, item) 89 } 90 91 wg.Wait() 92 return results 93} 94 95func RunConcurrent(tasks ...func() error) []error { 96 var wg sync.WaitGroup 97 errs := make([]error, len(tasks)) 98 99 wg.Add(len(tasks)) 100 101 for i, task := range tasks { 102 go func(i int, t func() error) { 103 defer wg.Done() 104 if err := t(); err != nil { 105 errs[i] = err 106 } 107 }(i, task) 108 } 109 110 wg.Wait() 111 return errs 112}