File Coverage

lib/PAGI/Endpoint/SSE.pm
Criterion Covered Total %
statement 39 40 97.5
branch 6 8 75.0
condition 1 2 50.0
subroutine 11 11 100.0
pod 3 5 60.0
total 60 66 90.9


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