Maintain local ⭤ remote in sync with automatic AT Protocol parity for Laravel (alpha & unstable)
at main 3.3 kB view raw
1<?php 2 3namespace SocialDept\AtpParity\Discovery; 4 5use BackedEnum; 6use Generator; 7use SocialDept\AtpClient\Facades\Atp; 8use SocialDept\AtpParity\Import\ImportService; 9use Throwable; 10 11/** 12 * Service for discovering DIDs with records in specific collections. 13 */ 14class DiscoveryService 15{ 16 public function __construct( 17 protected ImportService $importService 18 ) {} 19 20 /** 21 * Discover all DIDs with records in a collection. 22 * 23 * @return Generator<string> Yields DIDs 24 */ 25 public function discoverDids(string|BackedEnum $collection, ?int $limit = null): Generator 26 { 27 $collection = $collection instanceof BackedEnum ? $collection->value : $collection; 28 $cursor = null; 29 $count = 0; 30 31 do { 32 $response = Atp::public()->atproto->sync->listReposByCollection( 33 collection: $collection, 34 limit: min(500, $limit ? $limit - $count : 500), 35 cursor: $cursor, 36 ); 37 38 foreach ($response->repos as $repo) { 39 $did = $repo['did'] ?? null; 40 41 if ($did) { 42 yield $did; 43 $count++; 44 45 if ($limit !== null && $count >= $limit) { 46 return; 47 } 48 } 49 } 50 51 $cursor = $response->cursor; 52 } while ($cursor !== null); 53 } 54 55 /** 56 * Discover DIDs and return as an array. 57 */ 58 public function discover(string|BackedEnum $collection, ?int $limit = null): DiscoveryResult 59 { 60 try { 61 $dids = iterator_to_array($this->discoverDids($collection, $limit)); 62 $incomplete = $limit !== null && count($dids) >= $limit; 63 64 return DiscoveryResult::success($dids, $incomplete); 65 } catch (Throwable $e) { 66 return DiscoveryResult::failed($e->getMessage()); 67 } 68 } 69 70 /** 71 * Discover and import all users for a collection. 72 */ 73 public function discoverAndImport( 74 string|BackedEnum $collection, 75 ?int $limit = null, 76 ?callable $onProgress = null 77 ): DiscoveryResult { 78 $collection = $collection instanceof BackedEnum ? $collection->value : $collection; 79 80 try { 81 $dids = []; 82 $count = 0; 83 84 foreach ($this->discoverDids($collection, $limit) as $did) { 85 $dids[] = $did; 86 $count++; 87 88 // Start import for this DID 89 $this->importService->import($did, [$collection]); 90 91 if ($onProgress) { 92 $onProgress($did, $count); 93 } 94 } 95 96 $incomplete = $limit !== null && count($dids) >= $limit; 97 98 return DiscoveryResult::success($dids, $incomplete); 99 } catch (Throwable $e) { 100 return DiscoveryResult::failed($e->getMessage()); 101 } 102 } 103 104 /** 105 * Count total DIDs with records in a collection. 106 * 107 * Note: This iterates through all results, which can be slow. 108 */ 109 public function count(string|BackedEnum $collection): int 110 { 111 $count = 0; 112 113 foreach ($this->discoverDids($collection) as $_) { 114 $count++; 115 } 116 117 return $count; 118 } 119}