Module: Relay::Connection

Defined in:
lib/relay/connection/array.rb,
lib/relay/connection/connection.rb

Defined Under Namespace

Classes: ArrayConnection, CompositeType, CompositeTypeConfiguration, Edge, PageInfo

Constant Summary collapse

ARRAY_CONNECTION_PREFIX =
'arrayconnection'
EmptyConnection =
ArrayConnection.new([], PageInfo.new(nil, nil, false, false))
ConnectionArguments =
[
  GraphQL::GraphQLArgument.new(:before, GraphQL::GraphQLString),
  GraphQL::GraphQLArgument.new(:after, GraphQL::GraphQLString),
  GraphQL::GraphQLArgument.new(:first, GraphQL::GraphQLInt),
  GraphQL::GraphQLArgument.new(:last, GraphQL::GraphQLInt)
]
PageInfoType =
GraphQL::GraphQLObjectType.new do
  name          'PageInfo'
  description   'Information about pagination in a connection.'

  field :hasNextPage, !GraphQL::GraphQLBoolean do
    description 'When paginating forwards, are there more items?'
  end

  field :hasPreviousPage, !GraphQL::GraphQLBoolean do
    description 'When paginating backwards, are there more items?'
  end

  field :startCursor, GraphQL::GraphQLString do
    description 'When paginating backwards, the cursor to continue.'
  end

  field :endCursor, GraphQL::GraphQLString do
    description 'When paginating forwards, the cursor to continue.'
  end
end

Class Method Summary collapse

Class Method Details

.connection_from_array(data, args) ⇒ Object



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
# File 'lib/relay/connection/array.rb', line 13

def self.connection_from_array(data, args)
  edges   = data.each_with_index.map { |item, i| Edge.new(offset_to_cursor(i), item) }

  start   = [get_offset(args[:after], -1), -1].max + 1
  finish  = [get_offset(args[:before], edges.size + 1), edges.size + 1].min

  edges = edges.slice(start, finish)

  return EmptyConnection if edges.size == 0

  first_preslice_cursor = edges.first[:cursor]
  last_preslice_cursor  = edges.last[:cursor]

  edges = edges.slice(0, args[:first]) unless args[:first].nil?
  egdes = edges.slice!(- args[:last], edges.size) unless args[:last].nil?

  return EmptyConnection if edges.size == 0

  ArrayConnection.new(edges, PageInfo.new(
    edges.first[:cursor],
    edges.last[:cursor],
    edges.first[:cursor]  != first_preslice_cursor,
    edges.last[:cursor]   != last_preslice_cursor
  ))
end

.cursor_to_offset(cursor) ⇒ Object



43
44
45
# File 'lib/relay/connection/array.rb', line 43

def self.cursor_to_offset(cursor)
  Base64.strict_decode64(cursor).split(':').last.to_i
end

.get_offset(cursor, default_offset) ⇒ Object



47
48
49
50
51
# File 'lib/relay/connection/array.rb', line 47

def self.get_offset(cursor, default_offset)
  return default_offset unless cursor
  offset = cursor_to_offset(cursor)
  offset.nil? ? default_offset : offset
end

.offset_to_cursor(index) ⇒ Object



39
40
41
# File 'lib/relay/connection/array.rb', line 39

def self.offset_to_cursor(index)
  Base64.strict_encode64([ARRAY_CONNECTION_PREFIX, index].join(':'))
end