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}