<commit_before>module React
  class State

    ALWAYS_UPDATE_STATE_AFTER_RENDER = false # Hyperloop.on_client? # if on server then we don't wait to update the state
    @rendering_level = 0

    class << self
      attr_reader :current_observer

      def has_observers?(object, name)
        !observers_by_name[object][name].empty?
      end

      def bulk_update
        saved_bulk_update_flag = @bulk_update_flag
        @bulk_update_flag = true
        yield
      ensure
        @bulk_update_flag = saved_bulk_update_flag
      end

      def set_state2(object, name, value, updates, exclusions = nil)
        # set object's name state to value, tell all observers it has changed.
        # Observers must implement update_react_js_state
        object_needs_notification = object.respond_to? :update_react_js_state
        observers_by_name[object][name].dup.each do |observer|
          next if exclusions && exclusions.include?(observer)
          updates[observer] += [object, name, value]
          object_needs_notification = false if object == observer
        end
        updates[object] += [nil, name, value] if object_needs_notification
      end

      def initialize_states(object, initial_values) # initialize objects' name/value pairs
        states[object].merge!(initial_values || {})
      end

      def get_state(object, name, current_observer = @current_observer)
        # get current value of name for object, remember that the current object depends on this state,
        # current observer can be overriden with last param
        if current_observer && !new_observers[current_observer][object].include?(name)
          new_observers[current_observer][object] << name
        end
        if @delayed_updates && @delayed_updates[object][name]
          @delayed_updates[object][name][1] << current_observer
        end
        states[object][name]
      end

      def set_state(object, name, value, delay=ALWAYS_UPDATE_STATE_AFTER_RENDER)
        states[object][name] = value
        if delay || @bulk_update_flag
          @delayed_updates ||= Hash.new { |h, k| h[k] = {} }
          @delayed_updates[object][name] = [value, Set.new]
          @delayed_updater ||= after(0.001) do
            delayed_updates = @delayed_updates
            @delayed_updates = Hash.new { |h, k| h[k] = {} } # could this be nil???
            @delayed_updater = nil
            updates = Hash.new { |hash, key| hash[key] = Array.new }
            delayed_updates.each do |object, name_hash|
              name_hash.each do |name, value_and_set|
                set_state2(object, name, value_and_set[0], updates, value_and_set[1])
              end
            end
            updates.each { |observer, args| observer.update_react_js_state(*args) }
          end
        elsif @rendering_level == 0
          updates = Hash.new { |hash, key| hash[key] = Array.new }
          set_state2(object, name, value, updates)
          updates.each { |observer, args| observer.update_react_js_state(*args) }
        end
        value
      end

      def notify_observers(object, name, value)
        object_needs_notification = object.respond_to? :update_react_js_state
        observers_by_name[object][name].dup.each do |observer|
          observer.update_react_js_state(object, name, value)
          object_needs_notification = false if object == observer
        end
        object.update_react_js_state(nil, name, value) if object_needs_notification
      end

      def notify_observers_after_thread_completes(object, name, value)
        (@delayed_updates ||= []) << [object, name, value]
        @delayed_updater ||= after(0) do
          delayed_updates = @delayed_updates
          @delayed_updates = []
          @delayed_updater = nil
          delayed_updates.each { |args| notify_observers(*args) }
        end
      end

      def will_be_observing?(object, name, current_observer)
        current_observer && new_observers[current_observer][object].include?(name)
      end

      def is_observing?(object, name, current_observer)
        current_observer && observers_by_name[object][name].include?(current_observer)
      end

      def update_states_to_observe(current_observer = @current_observer)  # should be called after the last after_render callback, currently called after components render method
        raise "update_states_to_observer called outside of watch block" unless current_observer
        current_observers[current_observer].each do |object, names|
          names.each do |name|
            observers_by_name[object][name].delete(current_observer)
          end
        end
        observers = current_observers[current_observer] = new_observers[current_observer]
        new_observers.delete(current_observer)
        observers.each do |object, names|
          names.each do |name|
            observers_by_name[object][name] << current_observer
          end
        end
      end

      def remove # call after component is unmounted
        raise "remove called outside of watch block" unless @current_observer
        current_observers[@current_observer].each do |object, names|
          names.each do |name|
            observers_by_name[object][name].delete(@current_observer)
          end
        end
        current_observers.delete(@current_observer)
      end

      def set_state_context_to(observer, rendering = nil) # wrap all execution that may set or get states in a block so we know which observer is executing

        saved_current_observer = @current_observer
        @current_observer = observer
        @rendering_level += 1 if rendering
        return_value = yield
        return_value
      ensure
        @current_observer = saved_current_observer
        @rendering_level -= 1 if rendering
        return_value
      end

      def states
        @states ||= Hash.new { |h, k| h[k] = {} }
      end
<commit_msg>revert delay setting, remove unused code, support sync_set_state<commit_after>module React
  class State

    ALWAYS_UPDATE_STATE_AFTER_RENDER = Hyperloop.on_client? # if on server then we don't wait to update the state
    @rendering_level = 0

    class << self
      attr_reader :current_observer

      def has_observers?(object, name)
        !observers_by_name[object][name].empty?
      end

      def bulk_update
        saved_bulk_update_flag = @bulk_update_flag
        @bulk_update_flag = true
        yield
      ensure
        @bulk_update_flag = saved_bulk_update_flag
      end

      def set_state2(object, name, value, updates, exclusions = nil)
        # set object's name state to value, tell all observers it has changed.
        # Observers must implement update_react_js_state
        object_needs_notification = object.respond_to?(:update_react_js_state)
        observers_by_name[object][name].dup.each do |observer|
          next if exclusions && exclusions.include?(observer)
          updates[observer] += [object, name, value]
          object_needs_notification = false if object == observer
        end
        updates[object] += [nil, name, value] if object_needs_notification
      end

      def initialize_states(object, initial_values) # initialize objects' name/value pairs
        states[object].merge!(initial_values || {})
      end

      def get_state(object, name, current_observer = @current_observer)
        # get current value of name for object, remember that the current object depends on this state,
        # current observer can be overriden with last param
        if current_observer && !new_observers[current_observer][object].include?(name)
          new_observers[current_observer][object] << name
        end
        if @delayed_updates && @delayed_updates[object][name]
          @delayed_updates[object][name][1] << current_observer
        end
        states[object][name]
      end

      def set_state(object, name, value, delay=ALWAYS_UPDATE_STATE_AFTER_RENDER)
        states[object][name] = value
        delay = false if `object.sync_set_state !== undefined && object.sync_set_state === true`
        if delay || @bulk_update_flag
          @delayed_updates ||= Hash.new { |h, k| h[k] = {} }
          @delayed_updates[object][name] = [value, Set.new]
          @delayed_updater ||= after(0.001) do
            delayed_updates = @delayed_updates
            @delayed_updates = Hash.new { |h, k| h[k] = {} } # could this be nil???
            @delayed_updater = nil
            updates = Hash.new { |hash, key| hash[key] = Array.new }
            delayed_updates.each do |object, name_hash|
              name_hash.each do |name, value_and_set|
                set_state2(object, name, value_and_set[0], updates, value_and_set[1])
              end
            end
            updates.each { |observer, args| observer.update_react_js_state(*args) }
          end
        elsif @rendering_level == 0
          updates = Hash.new { |hash, key| hash[key] = Array.new }
          set_state2(object, name, value, updates)
          updates.each { |observer, args| observer.update_react_js_state(*args) }
        end
        value
      end

      def will_be_observing?(object, name, current_observer)
        current_observer && new_observers[current_observer][object].include?(name)
      end

      def is_observing?(object, name, current_observer)
        current_observer && observers_by_name[object][name].include?(current_observer)
      end

      def update_states_to_observe(current_observer = @current_observer)  # should be called after the last after_render callback, currently called after components render method
        raise "update_states_to_observer called outside of watch block" unless current_observer
        current_observers[current_observer].each do |object, names|
          names.each do |name|
            observers_by_name[object][name].delete(current_observer)
          end
        end
        observers = current_observers[current_observer] = new_observers[current_observer]
        new_observers.delete(current_observer)
        observers.each do |object, names|
          names.each do |name|
            observers_by_name[object][name] << current_observer
          end
        end
      end

      def remove # call after component is unmounted
        raise "remove called outside of watch block" unless @current_observer
        current_observers[@current_observer].each do |object, names|
          names.each do |name|
            observers_by_name[object][name].delete(@current_observer)
          end
        end
        current_observers.delete(@current_observer)
      end

      def set_state_context_to(observer, rendering = nil) # wrap all execution that may set or get states in a block so we know which observer is executing
        saved_current_observer = @current_observer
        @current_observer = observer
        @rendering_level += 1 if rendering
        return_value = yield
        return_value
      ensure
        @current_observer = saved_current_observer
        @rendering_level -= 1 if rendering
        return_value
      end

      def states
        @states ||= Hash.new { |h, k| h[k] = {} }
      end

{'fraction_non_alphanumeric': 0.08208955223880597, 'fraction_numerical': 0.002607444704189894, 'mean_word_length': 2.700266134397871, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3664739', 'n_tokens_mistral': 3229, 'n_tokens_neox': 3156, 'n_words': 792}