The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Build.PL 14
Changes 014
LICENSE 11
MANIFEST 09
META.yml 35
Makefile.PL 26
README 714
dist.ini 11
ex_complex.pl 022
examples/author-country.pl 03
examples/author.pl 05
examples/complex-either-and.pl 34
examples/complex-either-not.pl 15
examples/complex.pl 03
examples/distribution.pl 03
examples/module.pl 023
examples/pod.pl 011
examples/recent.pl 022
examples/recent_today.pl 019
examples/rev_deps-recursive.pl 69
examples/rev_deps.pl 714
lib/MetaCPAN/Client/Author.pm 24
lib/MetaCPAN/Client/Distribution.pm 24
lib/MetaCPAN/Client/Favorite.pm 24
lib/MetaCPAN/Client/File.pm 24
lib/MetaCPAN/Client/Module.pm 24
lib/MetaCPAN/Client/Pod.pm 0108
lib/MetaCPAN/Client/Rating.pm 24
lib/MetaCPAN/Client/Release.pm 24
lib/MetaCPAN/Client/Request.pm 25
lib/MetaCPAN/Client/ResultSet.pm 2659
lib/MetaCPAN/Client/Role/Entity.pm 24
lib/MetaCPAN/Client.pm 20101
switching_to_filters 052
t/00-compile.t 23
t/api/pod.t 016
t/resultset.t 17
wishlist 01
38 files changed (This is a version diff) 99581
@@ -20,7 +20,7 @@ my %module_build_args = (
     "Mickey Nasriachi <mickey\@cpan.org>"
   ],
   "dist_name" => "MetaCPAN-Client",
-  "dist_version" => "1.003000",
+  "dist_version" => "1.006000",
   "license" => "perl",
   "module_name" => "MetaCPAN::Client",
   "recommends" => {},
@@ -31,6 +31,7 @@ my %module_build_args = (
     "JSON::MaybeXS" => 0,
     "Moo" => 0,
     "Moo::Role" => 0,
+    "Safe::Isa" => 0,
     "Search::Elasticsearch" => "1.10",
     "Search::Elasticsearch::Scroll" => 0,
     "Try::Tiny" => 0,
@@ -44,6 +45,7 @@ my %module_build_args = (
     "IPC::Open3" => 0,
     "Test::Fatal" => 0,
     "Test::More" => 0,
+    "base" => 0,
     "perl" => "5.006"
   }
 );
@@ -56,6 +58,7 @@ my %fallback_build_requires = (
   "Module::Build" => "0.3601",
   "Test::Fatal" => 0,
   "Test::More" => 0,
+  "base" => 0,
   "perl" => "5.006"
 );
 
@@ -1,5 +1,19 @@
 Revision history for MetaCPAN-Client (previously MetaCPAN-API)
 
+1.006000    24.06.14
+            * Add 'recent' functionality (latest releases)
+
+1.005000    09.06.14
+            * Add Pod object to allow direct POD fetching (reneeb)
+            * Support single element without wrapping arrayref in structures
+            * Updated documents - basic/complex search links and wording (tsibley)
+
+1.004001    27.05.14
+            * correct rev_deps query
+
+1.004000    27.05.14
+            * reworked ResultSet to allow RS in non-scrolled searches.
+
 1.003000    05.05.14
             * Add proper POD fetching from module/file objects.
             * GH #1: Switch from JSON.pm to JSON::MaybeXS.
@@ -22,7 +22,7 @@ This is free software, licensed under:
                      Version 1, February 1989
 
  Copyright (C) 1989 Free Software Foundation, Inc.
- 51 Franklin St, Suite 500, Boston, MA  02110-1335  USA
+ 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
@@ -7,6 +7,7 @@ META.yml
 Makefile.PL
 README
 dist.ini
+ex_complex.pl
 examples/author-country.pl
 examples/author.pl
 examples/author_releases.pl
@@ -14,6 +15,10 @@ examples/complex-either-and.pl
 examples/complex-either-not.pl
 examples/complex.pl
 examples/distribution.pl
+examples/module.pl
+examples/pod.pl
+examples/recent.pl
+examples/recent_today.pl
 examples/release.pl
 examples/rev_deps-recursive.pl
 examples/rev_deps.pl
@@ -23,11 +28,13 @@ lib/MetaCPAN/Client/Distribution.pm
 lib/MetaCPAN/Client/Favorite.pm
 lib/MetaCPAN/Client/File.pm
 lib/MetaCPAN/Client/Module.pm
+lib/MetaCPAN/Client/Pod.pm
 lib/MetaCPAN/Client/Rating.pm
 lib/MetaCPAN/Client/Release.pm
 lib/MetaCPAN/Client/Request.pm
 lib/MetaCPAN/Client/ResultSet.pm
 lib/MetaCPAN/Client/Role/Entity.pm
+switching_to_filters
 t/00-compile.t
 t/api/_get.t
 t/api/_get_or_search.t
@@ -37,6 +44,7 @@ t/api/distribution.t
 t/api/favorite.t
 t/api/file.t
 t/api/module.t
+t/api/pod.t
 t/api/rating.t
 t/api/release.t
 t/author-critic.t
@@ -46,3 +54,4 @@ t/release-pod-coverage.t
 t/release-pod-syntax.t
 t/request.t
 t/resultset.t
+wishlist
@@ -10,12 +10,13 @@ build_requires:
   Module::Build: 0.3601
   Test::Fatal: 0
   Test::More: 0
+  base: 0
   perl: 5.006
 configure_requires:
   ExtUtils::MakeMaker: 6.30
   Module::Build: 0.3601
 dynamic_config: 0
-generated_by: 'Dist::Zilla version 5.015, CPAN::Meta::Converter version 2.120921'
+generated_by: 'Dist::Zilla version 5.015, CPAN::Meta::Converter version 2.131560'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -30,11 +31,12 @@ requires:
   JSON::MaybeXS: 0
   Moo: 0
   Moo::Role: 0
+  Safe::Isa: 0
   Search::Elasticsearch: 1.10
   Search::Elasticsearch::Scroll: 0
   Try::Tiny: 0
   strict: 0
   warnings: 0
 resources:
-  repository: git://github.com/CPAN-API/metacpan-client.git
-version: 1.003000
+  repository: https://github.com/CPAN-API/metacpan-client.git
+version: 1.006000
@@ -29,6 +29,7 @@ my %WriteMakefileArgs = (
     "JSON::MaybeXS" => 0,
     "Moo" => 0,
     "Moo::Role" => 0,
+    "Safe::Isa" => 0,
     "Search::Elasticsearch" => "1.10",
     "Search::Elasticsearch::Scroll" => 0,
     "Try::Tiny" => 0,
@@ -40,9 +41,10 @@ my %WriteMakefileArgs = (
     "IO::Handle" => 0,
     "IPC::Open3" => 0,
     "Test::Fatal" => 0,
-    "Test::More" => 0
+    "Test::More" => 0,
+    "base" => 0
   },
-  "VERSION" => "1.003000",
+  "VERSION" => "1.006000",
   "test" => {
     "TESTS" => "t/*.t t/api/*.t"
   }
@@ -59,11 +61,13 @@ my %FallbackPrereqs = (
   "Module::Build" => "0.3601",
   "Moo" => 0,
   "Moo::Role" => 0,
+  "Safe::Isa" => 0,
   "Search::Elasticsearch" => "1.10",
   "Search::Elasticsearch::Scroll" => 0,
   "Test::Fatal" => 0,
   "Test::More" => 0,
   "Try::Tiny" => 0,
+  "base" => 0,
   "strict" => 0,
   "warnings" => 0
 );
@@ -3,7 +3,7 @@ NAME
     API
 
 VERSION
-    version 1.003000
+    version 1.006000
 
 SYNOPSIS
         # simple usage
@@ -76,8 +76,8 @@ METHODS
     search.
 
   distribution
-        my $dist = $mcpan->dist('MetaCPAN-Client');
-        my $dist = $mcpan->dist($search_spec);
+        my $dist = $mcpan->distribution('MetaCPAN-Client');
+        my $dist = $mcpan->distribution($search_spec);
 
     Finds a distribution by either its distribution name or by a search spec
     defined by a hash reference. Since it is common to many other searches,
@@ -113,12 +113,20 @@ METHODS
   reverse_dependencies
         my $deps = $mcpan->reverse_dependencies('ElasticSearch');
 
-    Return an array (ref) of MetaCPAN::Client::Release matching all releases
-    that are dependent on a given module.
+    all MetaCPAN::Client::Release objects of releases that are dependent on
+    a given module, returned as MetaCPAN::Client::ResultSet.
 
   rev_deps
     Alias to "reverse_dependencies" described above.
 
+  recent
+        my $recent = $mcpan->recent(10);
+        my $recent = $mcpan->recent('today');
+
+    return the latest N releases, or all releases from today.
+
+    returns a MetaCPAN::Client::ResultSet of MetaCPAN::Client::Release.
+
   pod
     Not implemented yet.
 
@@ -129,8 +137,7 @@ SEARCH SPEC
     The hash-based search spec is common to many searches. It is quite
     feature-rich and allows to disambiguate different types of searches.
 
-  Simple
-    Simple searches just contain keys and values:
+    Basic search specs just contain a hash of keys and values:
 
         my $author = $mcpan->author( { name => 'Micha Nasriachi' } );
 
@@ -5,7 +5,7 @@ license = Perl_5
 copyright_holder = Sawyer X
 copyright_year   = 2014
 
-version = 1.003000
+version = 1.006000
 
 [@Basic]
 [PodSyntaxTests]
@@ -0,0 +1,22 @@
+use strict;
+use warnings;
+use Data::Printer;
+use MetaCPAN::Client;
+
+my $authors =
+    MetaCPAN::Client->new->author({
+        either => [
+            { name => 'Dave *'  },
+            { name => 'David *' },
+        ]
+    });
+
+my %output = (
+    TOTAL => $authors->total,
+    NAMES => [
+        map { my $x=$authors->next; [$x->name,$x->pauseid] }
+        0 .. 9
+    ],
+);
+
+p %output;
@@ -1,3 +1,6 @@
+
+# examples/author-country.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -1,3 +1,7 @@
+
+
+# examples/author.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -15,3 +19,4 @@ my %output = (
 );
 
 p %output;
+
@@ -1,3 +1,6 @@
+
+# examples/complex-either-and.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -9,9 +12,7 @@ my $authors =
             { name => 'Dave *'  },
             { name => 'David *' },
         ],
-        all => [
-            { email => '*gmail.com' }
-        ],
+        all => { email => '*gmail.com' },
     });
 
 my %output = (
@@ -1,3 +1,6 @@
+
+# examples/complex-either-not.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -16,4 +19,5 @@ my $authors =
     });
 
 print "\n";
-p ( $authors->total );
+my %out = ( TOTAL => $authors->total );
+p %out;
@@ -1,3 +1,6 @@
+
+# examples/complex.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -1,3 +1,6 @@
+
+# examples/distribution.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -0,0 +1,23 @@
+
+# examples/module.pl
+
+use strict;
+use warnings;
+use DDP;
+
+use MetaCPAN::Client;
+
+my $module =
+    MetaCPAN::Client->new->module('Moo');
+
+my %output = (
+    NAME        => $module->name,
+    ABSTRACT    => $module->abstract,
+    DESCRIPTION => $module->description,
+    RELEASE     => $module->release,
+    AUTHOR      => $module->author,
+    VERSION     => $module->version,
+);
+
+p %output;
+
@@ -0,0 +1,11 @@
+
+# examples/pod.pl
+
+use strict;
+use warnings;
+use MetaCPAN::Client;
+
+my $pod =
+    MetaCPAN::Client->new->pod('Moo');
+
+print $pod->html;
@@ -0,0 +1,22 @@
+
+# examples/recent.pl
+
+use strict;
+use warnings;
+use Data::Printer;
+use MetaCPAN::Client;
+
+my $recent =
+    MetaCPAN::Client->new->recent(3);
+
+while ( my $rel = $recent->next ) {
+    my %output = (
+        NAME    => $rel->name,
+        AUTHOR  => $rel->author,
+        DATE    => $rel->date,
+        VERSION => $rel->version,
+    );
+
+    p %output;
+}
+
@@ -0,0 +1,19 @@
+use strict;
+use warnings;
+use Data::Printer;
+use MetaCPAN::Client;
+
+my $recent =
+    MetaCPAN::Client->new->recent('today');
+
+while ( my $rel = $recent->next ) {
+    my %output = (
+        NAME    => $rel->name,
+        AUTHOR  => $rel->author,
+        DATE    => $rel->date,
+        VERSION => $rel->version,
+    );
+
+    p %output;
+}
+
@@ -1,3 +1,6 @@
+
+# examples/rev_deps-recursive.pl
+
 use strict;
 use warnings;
 use Term::ANSIColor;
@@ -5,7 +8,7 @@ use MetaCPAN::Client;
 
 $|=1;
 
-my $dist  = 'Hijk';
+my $dist  = shift || 'Hijk';
 my $mcpan = MetaCPAN::Client->new;
 
 print "\n\n", colored( "* $dist", 'green' ), "\n";
@@ -17,16 +20,16 @@ sub dig {
 
     my $res   = $mcpan->reverse_dependencies($dist);
 
-    for ( @{$res} ) {
+    while ( my $item = $res->next ) {
         if ( $level ) {
             printf "%s%s\n",
                 colored( '....' x $level, 'yellow' ),
-                $_->distribution;
+                $item->distribution;
         } else {
             printf "\n>> %s\n",
-                colored( $_->distribution, 'blue' );
+                colored( $item->distribution, 'blue' );
         }
 
-        dig( $_->distribution, $level + 1 );
+        dig( $item->distribution, $level + 1 );
     }
-};
+}
@@ -1,3 +1,6 @@
+
+# examples/rev_deps.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -6,12 +9,16 @@ use MetaCPAN::Client;
 my $deps =
     MetaCPAN::Client->new->rev_deps('Hijk');
 
-my @output = (
-    map +{
-        name   => $_->name,
-        author => $_->author,
-    },
-    @{$deps},
-);
+my @output;
+
+while ( my $rel = $deps->next ) {
+    push @output => {
+        name   => $rel->name,
+        author => $rel->author,
+    };
+}
 
+print "\n";
+my $title = "Reverse dependencies for 'Hijk':";
+p $title;
 p @output;
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Author;
 # ABSTRACT: An Author data object
-$MetaCPAN::Client::Author::VERSION = '1.003000';
+$MetaCPAN::Client::Author::VERSION = '1.006000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -46,13 +46,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Author - An Author data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.006000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Distribution;
 # ABSTRACT: A Distribution data object
-$MetaCPAN::Client::Distribution::VERSION = '1.003000';
+$MetaCPAN::Client::Distribution::VERSION = '1.006000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -29,13 +29,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Distribution - A Distribution data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.006000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Favorite;
 # ABSTRACT: A Favorite data object
-$MetaCPAN::Client::Favorite::VERSION = '1.003000';
+$MetaCPAN::Client::Favorite::VERSION = '1.006000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -29,13 +29,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Favorite - A Favorite data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.006000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::File;
 # ABSTRACT: A File data object
-$MetaCPAN::Client::File::VERSION = '1.003000';
+$MetaCPAN::Client::File::VERSION = '1.006000';
 use Moo;
 use Carp;
 
@@ -52,13 +52,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::File - A File data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.006000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Module;
 # ABSTRACT: A Module data object
-$MetaCPAN::Client::Module::VERSION = '1.003000';
+$MetaCPAN::Client::Module::VERSION = '1.006000';
 use Moo;
 extends 'MetaCPAN::Client::File';
 
@@ -12,13 +12,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Module - A Module data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.006000
 
 =head1 DESCRIPTION
 
@@ -0,0 +1,108 @@
+use strict;
+use warnings;
+package MetaCPAN::Client::Pod;
+# ABSTRACT: A Pod object
+$MetaCPAN::Client::Pod::VERSION = '1.006000';
+use Moo;
+
+has name => ( is => 'ro', required => 1 );
+
+my @known_formats = qw<
+    html plain x_pod x_markdown
+>;
+
+foreach my $format (@known_formats) {
+    has $format => (
+        is      => 'ro',
+        lazy    => 1,
+        default => sub {
+            my $self = shift;
+            return $self->_request( $format );
+        },
+    );
+}
+
+sub _request {
+    my $self   = shift;
+    my $ctype  = shift || "plain";
+
+    $ctype =~ s/_/-/;
+
+    my $name = $self->name;
+
+    require MetaCPAN::Client::Request;
+
+    return
+        MetaCPAN::Client::Request->new->fetch(
+            "pod/${name}?content-type=text/${ctype}"
+        );
+}
+
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+MetaCPAN::Client::Pod - A Pod object
+
+=head1 VERSION
+
+version 1.006000
+
+=head1 SYNOPSIS
+
+  use strict;
+  use warnings;
+  use MetaCPAN::Client;
+  
+  my $pod = MetaCPAN::Client->new->pod('Moo');
+  
+  print $pod->html;
+
+=head1 DESCRIPTION
+
+=head1 ATTRIBUTES
+
+=head2 name
+
+=head2 x_pod
+
+=head2 html
+
+=head2 x_markdown
+
+=head2 plain
+
+Get the plaintext version of the documentation
+
+  $pod = MetaCPAN::Client->new->pod( "MetaCPAN::Client" );
+  print $pod->plain;
+
+=head1 AUTHORS
+
+=over 4
+
+=item *
+
+Sawyer X <xsawyerx@cpan.org>
+
+=item *
+
+Mickey Nasriachi <mickey@cpan.org>
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2014 by Sawyer X.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Rating;
 # ABSTRACT: A Rating data object
-$MetaCPAN::Client::Rating::VERSION = '1.003000';
+$MetaCPAN::Client::Rating::VERSION = '1.006000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -31,13 +31,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Rating - A Rating data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.006000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Release;
 # ABSTRACT: A Release data object
-$MetaCPAN::Client::Release::VERSION = '1.003000';
+$MetaCPAN::Client::Release::VERSION = '1.006000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -32,13 +32,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Release - A Release data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.006000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Request;
 # ABSTRACT: Object used for making requests to MetaCPAN
-$MetaCPAN::Client::Request::VERSION = '1.003000';
+$MetaCPAN::Client::Request::VERSION = '1.006000';
 use Moo;
 use Carp;
 use JSON::MaybeXS qw<decode_json encode_json>;
@@ -140,6 +140,7 @@ sub _build_query_rec {
 
   KEY: for my $k ( qw/ all either not / ) {
         my $v = delete $args->{$k} || next KEY;
+        ref $v eq 'HASH'  and $v = [ $v ];
         ref $v eq 'ARRAY' or croak "invalid value for key $k";
 
         undef $basic_element;
@@ -179,13 +180,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Request - Object used for making requests to MetaCPAN
 
 =head1 VERSION
 
-version 1.003000
+version 1.006000
 
 =head1 ATTRIBUTES
 
@@ -2,20 +2,10 @@ use strict;
 use warnings;
 package MetaCPAN::Client::ResultSet;
 # ABSTRACT: A Result Set
-$MetaCPAN::Client::ResultSet::VERSION = '1.003000';
+$MetaCPAN::Client::ResultSet::VERSION = '1.006000';
 use Moo;
 use Carp;
 
-has scroller => (
-    is       => 'ro',
-    isa      => sub {
-        ref $_[0] eq 'Search::Elasticsearch::Scroll'
-            or croak 'scroller must be an Search::Elasticsearch::Scroll object';
-    },
-    handles  => ['total'],
-    required => 1,
-);
-
 has type => (
     is       => 'ro',
     isa      => sub {
@@ -26,31 +16,64 @@ has type => (
     required => 1,
 );
 
-has facets => (
+# in case we're returning from a scrolled search
+has scroller => (
+    is        => 'ro',
+    isa       => sub {
+        use Safe::Isa;
+        $_[0]->$_isa('Search::Elasticsearch::Scroll')
+            or croak 'scroller must be an Search::Elasticsearch::Scroll object';
+    },
+    predicate => 'has_scroller',
+);
+
+# in case we're returning from a fetch
+has items => (
+    is  => 'ro',
+    isa => sub {
+        ref $_[0] eq 'ARRAY'
+            or croak 'items must be an array ref';
+    },
+);
+
+has total => (
     is      => 'ro',
-    lazy    => 1,
-    builder => '_get_facets',
+    default => sub {
+        my $self = shift;
+
+        return $self->has_scroller ? $self->scroller->total
+                                   : scalar @{ $self->items };
+    },
 );
 
-sub _get_facets {
-    my $self = shift;
+sub BUILDARGS {
+    my ( $class, %args ) = @_;
 
-    return $self->scroller->facets || {};
-}
+    exists $args{scroller} or exists $args{items}
+        or croak 'ResultSet must get either scroller or items';
 
+    exists $args{scroller} and exists $args{items}
+        and croak 'ResultSet must get either scroller or items, not both';
+
+    return \%args;
+}
 
 sub next {
     my $self   = shift;
-    my $result = $self->scroller->next;
+    my $result = $self->has_scroller ? $self->scroller->next
+                                     : shift @{ $self->items };
 
-    defined $result
-        or return;
+    defined $result or return;
 
     my $class = 'MetaCPAN::Client::' . ucfirst $self->type;
-
     return $class->new_from_request( $result->{'_source'} || $result->{'fields'} );
 }
 
+sub facets {
+    my $self = shift;
+
+    return $self->has_scroller ? $self->scroller->facets : {};
+}
 
 1;
 
@@ -58,25 +81,31 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::ResultSet - A Result Set
 
 =head1 VERSION
 
-version 1.003000
+version 1.006000
 
 =head1 DESCRIPTION
 
 Object representing a result from Elastic Search. This is used for the complex
-(as in non-simple) queries to MetaCPAN. It provides easy access to the scroller
-and facets.
+(as in L<non-simple/MetaCPAN::Client/"SEARCH SPEC">) queries to MetaCPAN. It
+provides easy access to the scroller and facets.
 
 =head1 ATTRIBUTES
 
 =head2 scroller
 
-An L<Search::Elasticsearch::Scroll> object
+An L<Search::Elasticsearch::Scroll> object.
+
+=head2 items
+
+An arrayref of items to manually scroll over, instead of a scroller object.
 
 =head2 type
 
@@ -112,6 +141,10 @@ Iterator call to fetch the next result set object.
 
 Iterator call to fetch the total amount of objects available in result set.
 
+=head2 BUILDARGS
+
+Double checks construction of objects. You should never run this yourself.
+
 =head1 AUTHORS
 
 =over 4
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Role::Entity;
 # ABSTRACT: A role for MetaCPAN entities
-$MetaCPAN::Client::Role::Entity::VERSION = '1.003000';
+$MetaCPAN::Client::Role::Entity::VERSION = '1.006000';
 use Moo::Role;
 
 has data => (
@@ -27,13 +27,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Role::Entity - A role for MetaCPAN entities
 
 =head1 VERSION
 
-version 1.003000
+version 1.006000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client;
 # ABSTRACT: A comprehensive, DWIM-featured client to the MetaCPAN API
-$MetaCPAN::Client::VERSION = '1.003000';
+$MetaCPAN::Client::VERSION = '1.006000';
 use Moo;
 use Carp;
 
@@ -12,6 +12,7 @@ use MetaCPAN::Client::Distribution;
 use MetaCPAN::Client::Module;
 use MetaCPAN::Client::File;
 use MetaCPAN::Client::Favorite;
+use MetaCPAN::Client::Pod;
 use MetaCPAN::Client::Rating;
 use MetaCPAN::Client::Release;
 use MetaCPAN::Client::ResultSet;
@@ -69,6 +70,13 @@ sub file {
     return $self->_get( 'file', $path );
 }
 
+sub pod {
+    my $self = shift;
+    my $name = shift;
+
+    return MetaCPAN::Client::Pod->new({ name => $name });
+}
+
 #
 # $api->rating({ dist => "Moose" })
 #   is equal to http://api.metacpan.org/v0/favorite/_search?q=distribution:Moose
@@ -128,6 +136,23 @@ sub reverse_dependencies {
 
 *rev_deps = *reverse_dependencies;
 
+sub recent {
+    my $self = shift;
+    my $size = shift || 100;
+
+    $size eq 'today'
+        and return $self->_recent(
+            size   => 1000,
+            filter => _filter_today()
+        );
+
+    $size =~ /^[0-9]+$/
+        and return $self->_recent( size => $size );
+
+    croak "recent: invalid size value";
+}
+
+
 ###
 
 sub _get {
@@ -197,23 +222,70 @@ sub _reverse_deps {
         $res = $self->fetch(
             '/search/reverse_dependencies/'.$dist,
             {
-                query  => { match_all => {} },
-                filter => { term => { 'release.status' => 'latest' } },
                 size   => 5000,
+                query  => { match_all => {} },
+                filter => {
+                    and => [
+                        { term => { 'release.status' => 'latest' } },
+                        { term => { 'authorized'     => \1       } },
+                    ]
+                },
+            }
+        );
+        1;
+
+    } or do {
+        warn $@;
+        return _empty_result_set('release'),
+    };
+
+    return MetaCPAN::Client::ResultSet->new(
+        items => $res->{'hits'}{'hits'},
+        type  => 'release',
+    );
+}
+
+sub _recent {
+    my $self = shift;
+    my @args = @_;
+
+    my $res;
+
+    eval {
+        $res = $self->fetch(
+            '/release/_search',
+            {
+                from   => 0,
+                query  => { match_all => {} },
+                @args,
+                sort   => [ { 'date' => { order => "desc" } } ],
             }
         );
+        1;
 
     } or do {
         warn $@;
-        return [];
+        return _empty_result_set('release');
     };
 
-    return +[
-        map { MetaCPAN::Client::Release->new_from_request($_->{'_source'}) }
-        @{ $res->{'hits'}{'hits'} }
-    ];
+    return MetaCPAN::Client::ResultSet->new(
+        items => $res->{'hits'}{'hits'},
+        type  => 'release',
+    );
+}
+
+sub _filter_today {
+    return { range => { date => { from => "now/1d+0h" } } };
 }
 
+sub _empty_result_set {
+    my $type = shift;
+
+    return MetaCPAN::Client::ResultSet->new(
+        items => [],
+        type  => $type,
+    );
+}
 
 1;
 
@@ -221,13 +293,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client - A comprehensive, DWIM-featured client to the MetaCPAN API
 
 =head1 VERSION
 
-version 1.003000
+version 1.006000
 
 =head1 SYNOPSIS
 
@@ -289,7 +363,7 @@ under C<SEARCH SPEC>.
 
 Return a L<MetaCPAN::Client::Author> object on a simple search (PAUSE ID), or
 a L<MetaCPAN::Client::ResultSet> object propagated with
-L<MetaCPAN::Client::Author> objects on a complex (search spec based) search.
+L<MetaCPAN::Client::Author> objects on a complex (L<search spec based|/"SEARCH SPEC">) search.
 
 =head2 module
 
@@ -302,12 +376,12 @@ under C<SEARCH SPEC>.
 
 Return a L<MetaCPAN::Client::Module> object on a simple search (module name), or
 a L<MetaCPAN::Client::ResultSet> object propagated with
-L<MetaCPAN::Client::Module> objects on a complex (search spec based) search.
+L<MetaCPAN::Client::Module> objects on a complex (L<search spec based|/"SEARCH SPEC">) search.
 
 =head2 distribution
 
-    my $dist = $mcpan->dist('MetaCPAN-Client');
-    my $dist = $mcpan->dist($search_spec);
+    my $dist = $mcpan->distribution('MetaCPAN-Client');
+    my $dist = $mcpan->distribution($search_spec);
 
 Finds a distribution by either its distribution name or by a search spec
 defined by a hash reference. Since it is common to many other searches, it is
@@ -315,7 +389,7 @@ explained below under C<SEARCH SPEC>.
 
 Return a L<MetaCPAN::Client::Distribution> object on a simple search
 (distribution name), or a L<MetaCPAN::Client::ResultSet> object propagated with
-L<MetaCPAN::Client::Distribution> objects on a complex (search spec based)
+L<MetaCPAN::Client::Distribution> objects on a complex (L<search spec based|/"SEARCH SPEC">)
 search.
 
 =head2 file
@@ -341,19 +415,28 @@ below under C<SEARCH SPEC>.
 
 Return a L<MetaCPAN::Client::Release> object on a simple search (release name),
 or a L<MetaCPAN::Client::ResultSet> object propagated with
-L<MetaCPAN::Client::Release> objects on a complex (search spec based) search.
+L<MetaCPAN::Client::Release> objects on a complex (L<search spec based|/"SEARCH SPEC">) search.
 
 =head2 reverse_dependencies
 
     my $deps = $mcpan->reverse_dependencies('ElasticSearch');
 
-Return an array (ref) of L<MetaCPAN::Client::Release> matching all
-releases that are dependent on a given module.
+all L<MetaCPAN::Client::Release> objects of releases that are dependent
+on a given module, returned as L<MetaCPAN::Client::ResultSet>.
 
 =head2 rev_deps
 
 Alias to C<reverse_dependencies> described above.
 
+=head2 recent
+
+    my $recent = $mcpan->recent(10);
+    my $recent = $mcpan->recent('today');
+
+return the latest N releases, or all releases from today.
+
+returns a L<MetaCPAN::Client::ResultSet> of L<MetaCPAN::Client::Release>.
+
 =head2 pod
 
 Not implemented yet.
@@ -367,9 +450,7 @@ Internal construction wrapper. Do not use.
 The hash-based search spec is common to many searches. It is quite
 feature-rich and allows to disambiguate different types of searches.
 
-=head2 Simple
-
-Simple searches just contain keys and values:
+Basic search specs just contain a hash of keys and values:
 
     my $author = $mcpan->author( { name => 'Micha Nasriachi' } );
 
@@ -0,0 +1,52 @@
+works:
+
+{
+    query  => { match_all => {} },
+    filter => {
+        or => [
+            { prefix => { name => "Dave " } },
+            { prefix => { name => "David " } },
+        ]
+    }
+}
+
+also:
+
+{
+    query  => { match_all => {} },
+    filter => {
+        or => [
+            { prefix => { name => "Dave " } },
+            {
+                and => [
+                    { prefix => { name => "David " } },
+                    { not => { prefix => { pauseid => "D" } } },
+                ]
+            },
+        ]
+    }
+}
+
+logic:
+- and => []
+- or  => []
+- not => {}
+
+wildcard replacements:
+- start ==> prefix
+- end   ==> postfix
+- other ==> keep current query build
+
+
+
+_____________
+basic element
+all
+either
+not
+------------
+
+    { name   => '' }
+    { all    => [] }
+    { either => [] }
+    { not    => [] }
@@ -2,9 +2,9 @@ use 5.006;
 use strict;
 use warnings;
 
-# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.040
+# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.039
 
-use Test::More  tests => 11 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
+use Test::More  tests => 12 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
 
 
 
@@ -15,6 +15,7 @@ my @module_files = (
     'MetaCPAN/Client/Favorite.pm',
     'MetaCPAN/Client/File.pm',
     'MetaCPAN/Client/Module.pm',
+    'MetaCPAN/Client/Pod.pm',
     'MetaCPAN/Client/Rating.pm',
     'MetaCPAN/Client/Release.pm',
     'MetaCPAN/Client/Request.pm',
@@ -0,0 +1,16 @@
+#!perl
+
+use strict;
+use warnings;
+use Test::More tests => 5;
+
+use t::lib::Functions;
+
+my $mc = mcpan();
+can_ok( $mc, 'pod' );
+
+my $pod = $mc->pod('MetaCPAN::API');
+isa_ok( $pod, 'MetaCPAN::Client::Pod' );
+can_ok( $pod, qw<html x_pod x_markdown plain name> );
+like( $pod->x_pod, qr/=head1/, 'got pod' );
+
@@ -7,11 +7,17 @@ use Test::More tests => 3;
 use Test::Fatal;
 use MetaCPAN::Client::ResultSet;
 
+{
+    package MetaCPAN::Client::Test::ScrollerZ;
+    use base 'Search::Elasticsearch::Scroll'; # < 5.10 FTW (except, no)
+    sub total {0}
+}
+
 like(
     exception {
         MetaCPAN::Client::ResultSet->new(
             type     => 'failZZ',
-            scroller => bless {}, 'Search::Elasticsearch::Scroll',
+            scroller => bless {}, 'MetaCPAN::Client::Test::ScrollerZ',
         )
     },
     qr/Invalid type/,
@@ -0,0 +1 @@
+top uploaders