tangled
alpha
login
or
join now
atscan.net
/
plcbundle
A Transparent and Verifiable Way to Sync the AT Protocol's PLC Directory
14
fork
atom
overview
issues
2
pulls
pipelines
update lib docs
tree.fail
3 months ago
2024fe0f
b6642a36
1/1
build.yml
success
1min
+62
-10
1 changed file
expand all
collapse all
unified
split
docs
library.md
+62
-10
docs/library.md
···
228
228
229
229
```go
230
230
type PLCOperation struct {
231
231
-
DID string // The DID (did:plc:...)
232
232
-
Operation map[string]interface{} // The operation data
233
233
-
CID string // Content identifier
234
234
-
Nullified interface{} // nil, false, or CID string
235
235
-
CreatedAt time.Time // When it was created
236
236
-
RawJSON []byte // Original JSON bytes
231
231
+
DID string // The DID (did:plc:...)
232
232
+
Operation json.RawMessage // Raw JSON bytes (use GetOperationMap() to parse)
233
233
+
CID string // Content identifier
234
234
+
Nullified interface{} // nil, false, or CID string
235
235
+
CreatedAt time.Time // When it was created
236
236
+
237
237
+
// Internal fields (populated automatically)
238
238
+
RawJSON []byte // Original JSON line
239
239
+
ParsedOperation map[string]interface{} // Cached parsed data
237
240
}
238
241
242
242
+
// Accessing operation data:
243
243
+
operation, err := op.GetOperationMap() // Parses Operation field (cached)
244
244
+
if err != nil || operation == nil {
245
245
+
return
246
246
+
}
247
247
+
248
248
+
// Now you can access fields
249
249
+
services := operation["services"].(map[string]interface{})
250
250
+
239
251
// Check if operation was nullified
240
252
if op.IsNullified() {
241
253
log.Printf("Operation %s was nullified by %s", op.CID, op.GetNullifyingCID())
242
254
}
243
255
```
244
256
257
257
+
### Accessing Operation Data
258
258
+
259
259
+
The `Operation` field uses lazy parsing for performance. Always parse it before accessing:
260
260
+
261
261
+
```go
262
262
+
// ❌ Wrong - won't compile
263
263
+
services := op.Operation["services"]
264
264
+
265
265
+
// ✅ Correct
266
266
+
operation, err := op.GetOperationMap()
267
267
+
if err != nil || operation == nil {
268
268
+
return
269
269
+
}
270
270
+
services, ok := operation["services"].(map[string]interface{})
271
271
+
```
272
272
+
273
273
+
The parsed data is cached, so repeated calls are fast:
274
274
+
// First call: parses JSON
275
275
+
data1, _ := op.GetOperationMap()
276
276
+
277
277
+
// Second call: returns cached data (fast)
278
278
+
data2, _ := op.GetOperationMap()
279
279
+
245
280
---
246
281
247
282
## Common Patterns
···
441
476
}
442
477
443
478
func (p *OperationProcessor) processOperation(op plcbundle.PLCOperation) {
479
479
+
// Parse Operation field on-demand
480
480
+
operation, err := op.GetOperationMap()
481
481
+
if err != nil || operation == nil {
482
482
+
return
483
483
+
}
484
484
+
444
485
// Example: Extract PDS endpoints
445
445
-
if services, ok := op.Operation["services"].(map[string]interface{}); ok {
486
486
+
if services, ok := operation["services"].(map[string]interface{}); ok {
446
487
if pds, ok := services["atproto_pds"].(map[string]interface{}); ok {
447
488
if endpoint, ok := pds["endpoint"].(string); ok {
448
489
log.Printf("DID %s uses PDS: %s", op.DID, endpoint)
···
450
491
}
451
492
}
452
493
}
494
494
+
453
495
454
496
func main() {
455
497
processor, err := NewOperationProcessor("./plc_data")
···
815
857
}
816
858
817
859
func (pt *PDSTracker) extractPDS(op plcbundle.PLCOperation) string {
818
818
-
services, ok := op.Operation["services"].(map[string]interface{})
860
860
+
// Parse Operation field on-demand
861
861
+
operation, err := op.GetOperationMap()
862
862
+
if err != nil || operation == nil {
863
863
+
return ""
864
864
+
}
865
865
+
866
866
+
services, ok := operation["services"].(map[string]interface{})
819
867
if !ok {
820
868
return ""
821
869
}
···
832
880
833
881
return endpoint
834
882
}
883
883
+
835
884
836
885
func (pt *PDSTracker) PrintResults() {
837
886
log.Printf("\nFound %d unique PDS endpoints:\n", len(pt.endpoints))
···
1045
1094
}
1046
1095
1047
1096
// Check for new DIDs (operation type "create")
1048
1048
-
if opType, ok := op.Operation["type"].(string); ok && opType == "create" {
1049
1049
-
log.Printf(" ➕ New DID: %s", op.DID)
1097
1097
+
operation, err := op.GetOperationMap()
1098
1098
+
if err == nil && operation != nil {
1099
1099
+
if opType, ok := operation["type"].(string); ok && opType == "create" {
1100
1100
+
log.Printf(" ➕ New DID: %s", op.DID)
1101
1101
+
}
1050
1102
}
1051
1103
}
1052
1104
}