ruby_event_store-browser 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ruby_event_store/browser/app.rb +36 -30
- data/lib/ruby_event_store/browser/event.rb +3 -7
- data/lib/ruby_event_store/browser/get_events_from_stream.rb +28 -24
- data/lib/ruby_event_store/browser/get_stream.rb +4 -5
- data/lib/ruby_event_store/browser/json_api_event.rb +4 -3
- data/lib/ruby_event_store/browser/routing.rb +5 -5
- data/lib/ruby_event_store/browser/stream.rb +28 -24
- data/lib/ruby_event_store/browser/version.rb +1 -1
- data/public/bootstrap.js +3 -0
- data/public/ruby_event_store_browser.css +832 -5
- data/public/ruby_event_store_browser.css.map +1 -1
- data/public/ruby_event_store_browser.js +1 -8
- data/public/ruby_event_store_browser.js.map +1 -1
- metadata +8 -6
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: df8e9b50395fcb93bc771370a2d27c6cb668753f8f0d9d7784f4ef56a4b17545
         | 
| 4 | 
            +
              data.tar.gz: 318dca02e6b96941d0375a3748385d5b48e494318b0e12a50c7dd70ee4ee4445
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 963db3c296db6dfdb4d24630a9060dc7379f6fc8f93dfb7858b903568de7f7e71bcca47e817b45eecab75c6cb870181d02cb4f66adbfad4814cc67c650e5fe20
         | 
| 7 | 
            +
              data.tar.gz: 782d3ccf1aee4a51ba1a1864ad6bfd94b8c2adbce01818ebba5f8df808224ed7ecadd111dd7696726431ab1c14dc7b13c38a8a2ec8273b122965f2ae074ccaa0
         | 
| @@ -6,7 +6,14 @@ require "sinatra/base" | |
| 6 6 | 
             
            module RubyEventStore
         | 
| 7 7 | 
             
              module Browser
         | 
| 8 8 | 
             
                class App < Sinatra::Base
         | 
| 9 | 
            -
                  def self.for( | 
| 9 | 
            +
                  def self.for(
         | 
| 10 | 
            +
                    event_store_locator:,
         | 
| 11 | 
            +
                    host: nil,
         | 
| 12 | 
            +
                    path: nil,
         | 
| 13 | 
            +
                    api_url: nil,
         | 
| 14 | 
            +
                    environment: :production,
         | 
| 15 | 
            +
                    related_streams_query: DEFAULT_RELATED_STREAMS_QUERY
         | 
| 16 | 
            +
                  )
         | 
| 10 17 | 
             
                    self.tap do |app|
         | 
| 11 18 | 
             
                      app.settings.instance_exec do
         | 
| 12 19 | 
             
                        set :event_store_locator, event_store_locator
         | 
| @@ -24,7 +31,7 @@ module RubyEventStore | |
| 24 31 | 
             
                    set :host, nil
         | 
| 25 32 | 
             
                    set :root_path, nil
         | 
| 26 33 | 
             
                    set :api_url, nil
         | 
| 27 | 
            -
                    set :event_store_locator, -> {}
         | 
| 34 | 
            +
                    set :event_store_locator, -> {  }
         | 
| 28 35 | 
             
                    set :related_streams_query, nil
         | 
| 29 36 | 
             
                    set :protection, except: :path_traversal
         | 
| 30 37 |  | 
| @@ -33,10 +40,7 @@ module RubyEventStore | |
| 33 40 |  | 
| 34 41 | 
             
                  get "/api/events/:id" do
         | 
| 35 42 | 
             
                    begin
         | 
| 36 | 
            -
                      json Event.new(
         | 
| 37 | 
            -
                        event_store: settings.event_store_locator,
         | 
| 38 | 
            -
                        params: symbolized_params,
         | 
| 39 | 
            -
                      )
         | 
| 43 | 
            +
                      json Event.new(event_store: settings.event_store_locator, params: symbolized_params)
         | 
| 40 44 | 
             
                    rescue RubyEventStore::EventNotFound
         | 
| 41 45 | 
             
                      404
         | 
| 42 46 | 
             
                    end
         | 
| @@ -44,42 +48,37 @@ module RubyEventStore | |
| 44 48 |  | 
| 45 49 | 
             
                  get "/api/streams/:id" do
         | 
| 46 50 | 
             
                    json GetStream.new(
         | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            +
                           stream_name: params[:id],
         | 
| 52 | 
            +
                           routing: routing,
         | 
| 53 | 
            +
                           related_streams_query: settings.related_streams_query
         | 
| 54 | 
            +
                         )
         | 
| 51 55 | 
             
                  end
         | 
| 52 56 |  | 
| 53 57 | 
             
                  get "/api/streams/:id/relationships/events" do
         | 
| 54 58 | 
             
                    json GetEventsFromStream.new(
         | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            +
                           event_store: settings.event_store_locator,
         | 
| 60 | 
            +
                           params: symbolized_params,
         | 
| 61 | 
            +
                           routing: routing
         | 
| 62 | 
            +
                         )
         | 
| 59 63 | 
             
                  end
         | 
| 60 64 |  | 
| 61 65 | 
             
                  get %r{/(events/.*|streams/.*)?} do
         | 
| 62 | 
            -
                    erb  | 
| 66 | 
            +
                    erb "
         | 
| 63 67 | 
             
                      <!DOCTYPE html>
         | 
| 64 68 | 
             
                      <html>
         | 
| 65 69 | 
             
                        <head>
         | 
| 66 70 | 
             
                          <title>RubyEventStore::Browser</title>
         | 
| 67 | 
            -
                          < | 
| 71 | 
            +
                          <meta name=\"ruby-event-store-browser-settings\" content='<%= browser_settings %>'>
         | 
| 68 72 | 
             
                        </head>
         | 
| 69 73 | 
             
                        <body>
         | 
| 70 | 
            -
                          <script type | 
| 71 | 
            -
                          <script type | 
| 72 | 
            -
                            RubyEventStore.Browser.Elm.Main.init({
         | 
| 73 | 
            -
                              flags: {
         | 
| 74 | 
            -
                                rootUrl:    "<%= routing.root_url %>",
         | 
| 75 | 
            -
                                apiUrl:     "<%= api_url %>",
         | 
| 76 | 
            -
                                resVersion: "<%= RubyEventStore::VERSION %>"
         | 
| 77 | 
            -
                              }
         | 
| 78 | 
            -
                            });
         | 
| 79 | 
            -
                          </script>
         | 
| 74 | 
            +
                          <script type=\"text/javascript\" src=\"<%= path %>/ruby_event_store_browser.js\"></script>
         | 
| 75 | 
            +
                          <script type=\"text/javascript\" src=\"<%= path %>/bootstrap.js\"></script>
         | 
| 80 76 | 
             
                        </body>
         | 
| 81 77 | 
             
                      </html>
         | 
| 82 | 
            -
                     | 
| 78 | 
            +
                    ",
         | 
| 79 | 
            +
                        locals: {
         | 
| 80 | 
            +
                          path: settings.root_path || request.script_name
         | 
| 81 | 
            +
                        }
         | 
| 83 82 | 
             
                  end
         | 
| 84 83 |  | 
| 85 84 | 
             
                  helpers do
         | 
| @@ -88,9 +87,16 @@ module RubyEventStore | |
| 88 87 | 
             
                    end
         | 
| 89 88 |  | 
| 90 89 | 
             
                    def routing
         | 
| 91 | 
            -
                      Routing.new(
         | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 90 | 
            +
                      Routing.new(settings.host || request.base_url, settings.root_path || request.script_name)
         | 
| 91 | 
            +
                    end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                    def browser_settings
         | 
| 94 | 
            +
                      JSON.dump(
         | 
| 95 | 
            +
                        {
         | 
| 96 | 
            +
                          rootUrl: routing.root_url,
         | 
| 97 | 
            +
                          apiUrl: settings.api_url || routing.api_url,
         | 
| 98 | 
            +
                          resVersion: RubyEventStore::VERSION
         | 
| 99 | 
            +
                        }
         | 
| 94 100 | 
             
                      )
         | 
| 95 101 | 
             
                    end
         | 
| 96 102 |  | 
| @@ -7,13 +7,11 @@ module RubyEventStore | |
| 7 7 |  | 
| 8 8 | 
             
                  def initialize(event_store:, params:)
         | 
| 9 9 | 
             
                    @event_store = event_store
         | 
| 10 | 
            -
                    @params | 
| 10 | 
            +
                    @params = params
         | 
| 11 11 | 
             
                  end
         | 
| 12 12 |  | 
| 13 13 | 
             
                  def as_json
         | 
| 14 | 
            -
                    {
         | 
| 15 | 
            -
                      data: JsonApiEvent.new(event, parent_event_id).to_h,
         | 
| 16 | 
            -
                    }
         | 
| 14 | 
            +
                    { data: JsonApiEvent.new(event, parent_event_id).to_h }
         | 
| 17 15 | 
             
                  end
         | 
| 18 16 |  | 
| 19 17 | 
             
                  def event
         | 
| @@ -21,9 +19,7 @@ module RubyEventStore | |
| 21 19 | 
             
                  end
         | 
| 22 20 |  | 
| 23 21 | 
             
                  def parent_event_id
         | 
| 24 | 
            -
                    if event.metadata.has_key?(:causation_id)
         | 
| 25 | 
            -
                      event_store.read.event(event.metadata.fetch(:causation_id))&.event_id
         | 
| 26 | 
            -
                    end
         | 
| 22 | 
            +
                    event_store.read.event(event.metadata.fetch(:causation_id))&.event_id if event.metadata.has_key?(:causation_id)
         | 
| 27 23 | 
             
                  end
         | 
| 28 24 |  | 
| 29 25 | 
             
                  def event_id
         | 
| @@ -9,51 +9,50 @@ module RubyEventStore | |
| 9 9 |  | 
| 10 10 | 
             
                  def initialize(event_store:, params:, routing:)
         | 
| 11 11 | 
             
                    @event_store = event_store
         | 
| 12 | 
            -
                    @params | 
| 12 | 
            +
                    @params = params
         | 
| 13 13 | 
             
                    @routing = routing
         | 
| 14 14 | 
             
                  end
         | 
| 15 15 |  | 
| 16 16 | 
             
                  def as_json
         | 
| 17 | 
            -
                    {
         | 
| 18 | 
            -
                      data:  events.map { |e| JsonApiEvent.new(e, nil).to_h },
         | 
| 19 | 
            -
                      links: links
         | 
| 20 | 
            -
                    }
         | 
| 17 | 
            +
                    { data: events.map { |e| JsonApiEvent.new(e, nil).to_h }, links: links }
         | 
| 21 18 | 
             
                  end
         | 
| 22 19 |  | 
| 23 20 | 
             
                  def events
         | 
| 24 | 
            -
                    @events ||= | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 21 | 
            +
                    @events ||=
         | 
| 22 | 
            +
                      case direction
         | 
| 23 | 
            +
                      when :forward
         | 
| 24 | 
            +
                        events_forward(position).reverse
         | 
| 25 | 
            +
                      when :backward
         | 
| 26 | 
            +
                        events_backward(position)
         | 
| 27 | 
            +
                      end
         | 
| 30 28 | 
             
                  end
         | 
| 31 29 |  | 
| 32 30 | 
             
                  def links
         | 
| 33 | 
            -
                    @links ||= | 
| 34 | 
            -
                       | 
| 35 | 
            -
                         | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
                         | 
| 41 | 
            -
             | 
| 31 | 
            +
                    @links ||=
         | 
| 32 | 
            +
                      {}.tap do |h|
         | 
| 33 | 
            +
                        if prev_event?
         | 
| 34 | 
            +
                          h[:prev] = prev_page_link(events.first.event_id)
         | 
| 35 | 
            +
                          h[:first] = first_page_link
         | 
| 36 | 
            +
                        end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                        if next_event?
         | 
| 39 | 
            +
                          h[:next] = next_page_link(events.last.event_id)
         | 
| 40 | 
            +
                          h[:last] = last_page_link
         | 
| 41 | 
            +
                        end
         | 
| 42 42 | 
             
                      end
         | 
| 43 | 
            -
                    end
         | 
| 44 43 | 
             
                  end
         | 
| 45 44 |  | 
| 46 45 | 
             
                  def events_forward(position)
         | 
| 47 46 | 
             
                    spec = event_store.read.limit(count)
         | 
| 48 47 | 
             
                    spec = spec.stream(stream_name) unless stream_name.eql?(SERIALIZED_GLOBAL_STREAM_NAME)
         | 
| 49 | 
            -
                    spec = spec.from(position) | 
| 48 | 
            +
                    spec = spec.from(position) unless position.equal?(HEAD)
         | 
| 50 49 | 
             
                    spec.to_a
         | 
| 51 50 | 
             
                  end
         | 
| 52 51 |  | 
| 53 52 | 
             
                  def events_backward(position)
         | 
| 54 53 | 
             
                    spec = event_store.read.limit(count).backward
         | 
| 55 54 | 
             
                    spec = spec.stream(stream_name) unless stream_name.eql?(SERIALIZED_GLOBAL_STREAM_NAME)
         | 
| 56 | 
            -
                    spec = spec.from(position) | 
| 55 | 
            +
                    spec = spec.from(position) unless position.equal?(HEAD)
         | 
| 57 56 | 
             
                    spec.to_a
         | 
| 58 57 | 
             
                  end
         | 
| 59 58 |  | 
| @@ -72,7 +71,12 @@ module RubyEventStore | |
| 72 71 | 
             
                  end
         | 
| 73 72 |  | 
| 74 73 | 
             
                  def next_page_link(event_id)
         | 
| 75 | 
            -
                    routing.paginated_events_from_stream_url( | 
| 74 | 
            +
                    routing.paginated_events_from_stream_url(
         | 
| 75 | 
            +
                      id: stream_name,
         | 
| 76 | 
            +
                      position: event_id,
         | 
| 77 | 
            +
                      direction: :backward,
         | 
| 78 | 
            +
                      count: count
         | 
| 79 | 
            +
                    )
         | 
| 76 80 | 
             
                  end
         | 
| 77 81 |  | 
| 78 82 | 
             
                  def first_page_link
         | 
| @@ -13,12 +13,12 @@ module RubyEventStore | |
| 13 13 | 
             
                        id: stream_name,
         | 
| 14 14 | 
             
                        type: "streams",
         | 
| 15 15 | 
             
                        attributes: {
         | 
| 16 | 
            -
                          related_streams: related_streams | 
| 16 | 
            +
                          related_streams: related_streams
         | 
| 17 17 | 
             
                        },
         | 
| 18 18 | 
             
                        relationships: {
         | 
| 19 19 | 
             
                          events: {
         | 
| 20 20 | 
             
                            links: {
         | 
| 21 | 
            -
                              self: routing.paginated_events_from_stream_url(id: stream_name) | 
| 21 | 
            +
                              self: routing.paginated_events_from_stream_url(id: stream_name)
         | 
| 22 22 | 
             
                            }
         | 
| 23 23 | 
             
                          }
         | 
| 24 24 | 
             
                        }
         | 
| @@ -27,12 +27,11 @@ module RubyEventStore | |
| 27 27 | 
             
                  end
         | 
| 28 28 |  | 
| 29 29 | 
             
                  private
         | 
| 30 | 
            +
             | 
| 30 31 | 
             
                  attr_reader :stream_name, :routing, :related_streams_query
         | 
| 31 32 |  | 
| 32 33 | 
             
                  def related_streams
         | 
| 33 | 
            -
                    unless related_streams_query.equal?(DEFAULT_RELATED_STREAMS_QUERY)
         | 
| 34 | 
            -
                      related_streams_query.call(stream_name)
         | 
| 35 | 
            -
                    end
         | 
| 34 | 
            +
                    related_streams_query.call(stream_name) unless related_streams_query.equal?(DEFAULT_RELATED_STREAMS_QUERY)
         | 
| 36 35 | 
             
                  end
         | 
| 37 36 | 
             
                end
         | 
| 38 37 | 
             
              end
         | 
| @@ -19,18 +19,19 @@ module RubyEventStore | |
| 19 19 | 
             
                        correlation_stream_name: correlation_stream_name,
         | 
| 20 20 | 
             
                        causation_stream_name: causation_stream_name,
         | 
| 21 21 | 
             
                        type_stream_name: type_stream_name,
         | 
| 22 | 
            -
                        parent_event_id: parent_event_id | 
| 23 | 
            -
                      } | 
| 22 | 
            +
                        parent_event_id: parent_event_id
         | 
| 23 | 
            +
                      }
         | 
| 24 24 | 
             
                    }
         | 
| 25 25 | 
             
                  end
         | 
| 26 26 |  | 
| 27 27 | 
             
                  private
         | 
| 28 | 
            +
             | 
| 28 29 | 
             
                  attr_reader :event, :parent_event_id
         | 
| 29 30 |  | 
| 30 31 | 
             
                  def metadata
         | 
| 31 32 | 
             
                    event.metadata.to_h.tap do |m|
         | 
| 32 33 | 
             
                      m[:timestamp] = event.metadata.fetch(:timestamp).iso8601(TIMESTAMP_PRECISION)
         | 
| 33 | 
            -
                      m[:valid_at] | 
| 34 | 
            +
                      m[:valid_at] = event.metadata.fetch(:valid_at).iso8601(TIMESTAMP_PRECISION)
         | 
| 34 35 | 
             
                    end
         | 
| 35 36 | 
             
                  end
         | 
| 36 37 |  | 
| @@ -24,11 +24,10 @@ module RubyEventStore | |
| 24 24 |  | 
| 25 25 | 
             
                  def paginated_events_from_stream_url(id:, position: nil, direction: nil, count: nil)
         | 
| 26 26 | 
             
                    stream_name = Rack::Utils.escape(id)
         | 
| 27 | 
            -
                    query_string = | 
| 28 | 
            -
                       | 
| 29 | 
            -
             | 
| 30 | 
            -
                       | 
| 31 | 
            -
                    }.compact)
         | 
| 27 | 
            +
                    query_string =
         | 
| 28 | 
            +
                      URI.encode_www_form(
         | 
| 29 | 
            +
                        { "page[position]" => position, "page[direction]" => direction, "page[count]" => count }.compact
         | 
| 30 | 
            +
                      )
         | 
| 32 31 |  | 
| 33 32 | 
             
                    if query_string.empty?
         | 
| 34 33 | 
             
                      "#{api_url}/streams/#{stream_name}/relationships/events"
         | 
| @@ -38,6 +37,7 @@ module RubyEventStore | |
| 38 37 | 
             
                  end
         | 
| 39 38 |  | 
| 40 39 | 
             
                  private
         | 
| 40 | 
            +
             | 
| 41 41 | 
             
                  attr_reader :host, :root_path
         | 
| 42 42 |  | 
| 43 43 | 
             
                  def base_url
         | 
| @@ -9,51 +9,50 @@ module RubyEventStore | |
| 9 9 |  | 
| 10 10 | 
             
                  def initialize(event_store:, params:, routing:)
         | 
| 11 11 | 
             
                    @event_store = event_store
         | 
| 12 | 
            -
                    @params | 
| 12 | 
            +
                    @params = params
         | 
| 13 13 | 
             
                    @routing = routing
         | 
| 14 14 | 
             
                  end
         | 
| 15 15 |  | 
| 16 16 | 
             
                  def as_json
         | 
| 17 | 
            -
                    {
         | 
| 18 | 
            -
                      data:  events.map { |e| JsonApiEvent.new(e, nil).to_h },
         | 
| 19 | 
            -
                      links: links
         | 
| 20 | 
            -
                    }
         | 
| 17 | 
            +
                    { data: events.map { |e| JsonApiEvent.new(e, nil).to_h }, links: links }
         | 
| 21 18 | 
             
                  end
         | 
| 22 19 |  | 
| 23 20 | 
             
                  def events
         | 
| 24 | 
            -
                    @events ||= | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 21 | 
            +
                    @events ||=
         | 
| 22 | 
            +
                      case direction
         | 
| 23 | 
            +
                      when :forward
         | 
| 24 | 
            +
                        events_forward(position).reverse
         | 
| 25 | 
            +
                      when :backward
         | 
| 26 | 
            +
                        events_backward(position)
         | 
| 27 | 
            +
                      end
         | 
| 30 28 | 
             
                  end
         | 
| 31 29 |  | 
| 32 30 | 
             
                  def links
         | 
| 33 | 
            -
                    @links ||= | 
| 34 | 
            -
                       | 
| 35 | 
            -
                         | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
                         | 
| 41 | 
            -
             | 
| 31 | 
            +
                    @links ||=
         | 
| 32 | 
            +
                      {}.tap do |h|
         | 
| 33 | 
            +
                        if prev_event?
         | 
| 34 | 
            +
                          h[:prev] = prev_page_link(events.first.event_id)
         | 
| 35 | 
            +
                          h[:first] = first_page_link
         | 
| 36 | 
            +
                        end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                        if next_event?
         | 
| 39 | 
            +
                          h[:next] = next_page_link(events.last.event_id)
         | 
| 40 | 
            +
                          h[:last] = last_page_link
         | 
| 41 | 
            +
                        end
         | 
| 42 42 | 
             
                      end
         | 
| 43 | 
            -
                    end
         | 
| 44 43 | 
             
                  end
         | 
| 45 44 |  | 
| 46 45 | 
             
                  def events_forward(position)
         | 
| 47 46 | 
             
                    spec = event_store.read.limit(count)
         | 
| 48 47 | 
             
                    spec = spec.stream(stream_name) unless stream_name.eql?(SERIALIZED_GLOBAL_STREAM_NAME)
         | 
| 49 | 
            -
                    spec = spec.from(position) | 
| 48 | 
            +
                    spec = spec.from(position) unless position.equal?(HEAD)
         | 
| 50 49 | 
             
                    spec.to_a
         | 
| 51 50 | 
             
                  end
         | 
| 52 51 |  | 
| 53 52 | 
             
                  def events_backward(position)
         | 
| 54 53 | 
             
                    spec = event_store.read.limit(count).backward
         | 
| 55 54 | 
             
                    spec = spec.stream(stream_name) unless stream_name.eql?(SERIALIZED_GLOBAL_STREAM_NAME)
         | 
| 56 | 
            -
                    spec = spec.from(position) | 
| 55 | 
            +
                    spec = spec.from(position) unless position.equal?(HEAD)
         | 
| 57 56 | 
             
                    spec.to_a
         | 
| 58 57 | 
             
                  end
         | 
| 59 58 |  | 
| @@ -72,7 +71,12 @@ module RubyEventStore | |
| 72 71 | 
             
                  end
         | 
| 73 72 |  | 
| 74 73 | 
             
                  def next_page_link(event_id)
         | 
| 75 | 
            -
                    routing.paginated_events_from_stream_url( | 
| 74 | 
            +
                    routing.paginated_events_from_stream_url(
         | 
| 75 | 
            +
                      id: stream_name,
         | 
| 76 | 
            +
                      position: event_id,
         | 
| 77 | 
            +
                      direction: :backward,
         | 
| 78 | 
            +
                      count: count
         | 
| 79 | 
            +
                    )
         | 
| 76 80 | 
             
                  end
         | 
| 77 81 |  | 
| 78 82 | 
             
                  def first_page_link
         | 
    
        data/public/bootstrap.js
    ADDED