File Coverage

lib/PAGI/Endpoint/SSE.pm
Criterion Covered Total %
statement 34 42 80.9
branch 3 8 37.5
condition 0 2 0.0
subroutine 11 12 91.6
pod 3 5 60.0
total 51 69 73.9


line stmt bran cond sub pod time code
1             package PAGI::Endpoint::SSE;
2              
3 3     3   321551 use strict;
  3         4  
  3         95  
4 3     3   26 use warnings;
  3         13  
  3         112  
5              
6 3     3   12 use Future::AsyncAwait;
  3         13  
  3         19  
7 3     3   176 use Carp qw(croak);
  3         4  
  3         142  
8 3     3   699 use Module::Load qw(load);
  3         2721  
  3         15  
9              
10              
11             # Factory class method - override in subclass for customization
12 3     3 1 1720 sub sse_class { 'PAGI::SSE' }
13              
14             # Keepalive interval in seconds (0 = disabled)
15 1     1 1 1374 sub keepalive_interval { 0 }
16              
17             sub new {
18 4     4 0 391869 my ($class, %args) = @_;
19 4         8 return bless \%args, $class;
20             }
21              
22 3     3 0 10 async sub handle {
23 3         6 my ($self, $sse) = @_;
24              
25             # Configure keepalive if specified
26 3         9 my $keepalive = $self->keepalive_interval;
27 3 50       11 if ($keepalive > 0) {
28 3         8 $sse->keepalive($keepalive);
29             }
30              
31             # Register disconnect callback
32 3 50       20 if ($self->can('on_disconnect')) {
33             $sse->on_close(sub {
34 3     3   18 $self->on_disconnect($sse);
35 3         12 });
36             }
37              
38             # Call on_connect if defined
39 3 50       19 if ($self->can('on_connect')) {
40 3         5 await $self->on_connect($sse);
41             } else {
42             # Default: just start the stream
43 0         0 await $sse->start;
44             }
45              
46             # Wait for disconnect
47 3         244 await $sse->run;
48             }
49              
50             sub to_app {
51 2     2 1 1288 my ($class) = @_;
52 2         81 my $sse_class = $class->sse_class;
53 2         8 load($sse_class);
54              
55 0     0     return async sub {
56 0           my ($scope, $receive, $send) = @_;
57              
58 0   0       my $type = $scope->{type} // '';
59 0 0         croak "Expected sse scope, got '$type'" unless $type eq 'sse';
60              
61 0           my $endpoint = $class->new;
62 0           my $sse = $sse_class->new($scope, $receive, $send);
63              
64 0           await $endpoint->handle($sse);
65 2         38 };
66             }
67              
68             1;
69              
70             __END__