File: array_connection.rb

package info (click to toggle)
ruby-graphql 2.2.17-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,584 kB
  • sloc: ruby: 67,505; ansic: 1,753; yacc: 831; javascript: 331; makefile: 6
file content (79 lines) | stat: -rw-r--r-- 2,027 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# frozen_string_literal: true
require "graphql/pagination/connection"

module GraphQL
  module Pagination
    class ArrayConnection < Pagination::Connection
      def nodes
        load_nodes
        @nodes
      end

      def has_previous_page
        load_nodes
        @has_previous_page
      end

      def has_next_page
        load_nodes
        @has_next_page
      end

      def cursor_for(item)
        idx = items.find_index(item) + 1
        encode(idx.to_s)
      end

      private

      def index_from_cursor(cursor)
        decode(cursor).to_i
      end

      # Populate all the pagination info _once_,
      # It doesn't do anything on subsequent calls.
      def load_nodes
        @nodes ||= begin
          sliced_nodes = if before && after
            end_idx = index_from_cursor(before) - 2
            end_idx < 0 ? [] : items[index_from_cursor(after)..end_idx] || []
          elsif before
            end_idx = index_from_cursor(before) - 2
            end_idx < 0 ? [] : items[0..end_idx] || []
          elsif after
            items[index_from_cursor(after)..-1] || []
          else
            items
          end

          @has_previous_page = if last
            # There are items preceding the ones in this result
            sliced_nodes.count > last
          elsif after
            # We've paginated into the Array a bit, there are some behind us
            index_from_cursor(after) > 0
          else
            false
          end

          @has_next_page = if before
            # The original array is longer than the `before` index
            index_from_cursor(before) < items.length + 1
          elsif first
            # There are more items after these items
            sliced_nodes.count > first
          else
            false
          end

          limited_nodes = sliced_nodes

          limited_nodes = limited_nodes.first(first) if first
          limited_nodes = limited_nodes.last(last) if last

          limited_nodes
        end
      end
    end
  end
end