File Coverage

blib/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             $PAGI::Endpoint::SSE::VERSION = '0.002000';
3 4     4   379540 use strict;
  4         5  
  4         128  
4 4     4   13 use warnings;
  4         6  
  4         155  
5              
6 4     4   14 use Future::AsyncAwait;
  4         8  
  4         20  
7 4     4   158 use Carp qw(croak);
  4         6  
  4         2094  
8              
9             # Factory class method - override in subclass for customization
10 7     7 1 3043 sub context_class { 'PAGI::Context' }
11              
12             # Keepalive interval in seconds (0 = disabled)
13 2     2 1 1326 sub keepalive_interval { 0 }
14              
15             sub new {
16 4     4 0 173875 my ($class, %args) = @_;
17 4         8 return bless \%args, $class;
18             }
19              
20 3     3 0 2 async sub handle {
21 3         4 my ($self, $ctx) = @_;
22 3         11 my $sse = $ctx->sse;
23              
24             # Configure keepalive if specified
25 3         12 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       45 if ($self->can('on_disconnect')) {
32             $sse->on_close(sub {
33 2     2   5 $self->on_disconnect($ctx);
34 2         9 });
35             }
36              
37             # Call on_connect if defined
38 3 50       8 if ($self->can('on_connect')) {
39 3         14 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 183027 my ($class) = @_;
51 5         20 my $context_class = $class->context_class;
52              
53 3     3   32 return async sub {
54 3         6 my ($scope, $receive, $send) = @_;
55              
56 3   50     8 my $type = $scope->{type} // '';
57 3 50       9 croak "Expected sse scope, got '$type'" unless $type eq 'sse';
58              
59 3         17 require PAGI::Context;
60 3         10 my $endpoint = $class->new;
61 3         14 my $ctx = $context_class->new($scope, $receive, $send);
62              
63 3         11 await $endpoint->handle($ctx);
64 5         26 };
65             }
66              
67             1;
68              
69             __END__