Build Reactive Signals for Bluesky's AT Protocol Firehose in Laravel
at dev 3.2 kB view raw
1<?php 2 3namespace SocialDept\AtpSignals\Commands; 4 5use Illuminate\Console\Command; 6use InvalidArgumentException; 7use SocialDept\AtpSignals\Events\CommitEvent; 8use SocialDept\AtpSignals\Events\SignalEvent; 9 10class TestSignalCommand extends Command 11{ 12 protected $signature = 'signal:test 13 {signal : The Signal class name} 14 {--sample=commit : The type of sample event to use}'; 15 16 protected $description = 'Test a Signal with sample data'; 17 18 public function handle(): int 19 { 20 $signalClass = $this->resolveSignalClass(); 21 22 if ($signalClass === null) { 23 return self::FAILURE; 24 } 25 26 $signal = app($signalClass); 27 28 $this->displayTestHeader($signalClass); 29 30 $event = $this->createAndDisplaySampleEvent(); 31 32 return $this->executeSignal($signal, $event); 33 } 34 35 private function resolveSignalClass(): ?string 36 { 37 $signalClass = $this->argument('signal'); 38 39 if (! class_exists($signalClass)) { 40 $signalClass = 'App\\Signals\\'.$signalClass; 41 } 42 43 if (! class_exists($signalClass)) { 44 $this->error("Signal class not found: {$signalClass}"); 45 46 return null; 47 } 48 49 return $signalClass; 50 } 51 52 private function displayTestHeader(string $signalClass): void 53 { 54 $this->info("Testing signal: {$signalClass}"); 55 $this->newLine(); 56 } 57 58 private function createAndDisplaySampleEvent(): SignalEvent 59 { 60 $event = $this->createSampleEvent($this->option('sample')); 61 62 $this->info('Sample event created:'); 63 $this->line(json_encode($event->toArray(), JSON_PRETTY_PRINT)); 64 $this->newLine(); 65 66 return $event; 67 } 68 69 private function executeSignal(object $signal, SignalEvent $event): int 70 { 71 try { 72 if ($signal->shouldHandle($event)) { 73 $this->info('Calling signal->handle()...'); 74 $signal->handle($event); 75 $this->info('✓ Signal executed successfully'); 76 } else { 77 $this->warn('Signal->shouldHandle() returned false'); 78 } 79 } catch (\Exception $e) { 80 $this->error('Error executing signal: '.$e->getMessage()); 81 82 return self::FAILURE; 83 } 84 85 return self::SUCCESS; 86 } 87 88 protected function createSampleEvent(string $type): SignalEvent 89 { 90 return match ($type) { 91 'commit' => new SignalEvent( 92 did: 'did:plc:sample123456789', 93 timeUs: time() * 1000000, 94 kind: 'commit', 95 commit: new CommitEvent( 96 rev: 'sample-rev', 97 operation: 'create', 98 collection: 'app.bsky.feed.post', 99 rkey: 'sample-rkey', 100 record: (object) [ 101 'text' => 'This is a sample post for testing', 102 'createdAt' => now()->toIso8601String(), 103 ], 104 cid: 'sample-cid', 105 ), 106 ), 107 default => throw new InvalidArgumentException("Unknown sample type: {$type}"), 108 }; 109 } 110}