Class: Crm::ArticleRevisionDiffRowComponent::TokenDiff

Inherits:
Object
  • Object
show all
Defined in:
app/components/crm/article_revision_diff_row_component/token_diff.rb

Overview

Bounds HTMLDiff work and falls back to a whole-field replacement for very
large content, avoiding a worst-case diff on a request thread.

Constant Summary collapse

MAX_TOKENS =

Maximum combined token count before falling back to a coarse diff.

20_000

Instance Method Summary collapse

Constructor Details

#initialize(current:, proposed:, max_tokens: MAX_TOKENS) ⇒ TokenDiff

Returns a new instance of TokenDiff.

Parameters:

  • current (String, nil)

    the current field value

  • proposed (String, nil)

    the proposed field value

  • max_tokens (Integer) (defaults to: MAX_TOKENS)

    combined token count above which the diff
    falls back to a coarse whole-field replacement



15
16
17
18
19
# File 'app/components/crm/article_revision_diff_row_component/token_diff.rb', line 15

def initialize(current:, proposed:, max_tokens: MAX_TOKENS)
  @current = current.to_s
  @proposed = proposed.to_s
  @max_tokens = max_tokens
end

Instance Method Details

#changesArray<Array>

Token-level changes between the current and proposed values, or a single
whole-field replacement when the content is too large to diff.

Returns:

  • (Array<Array>)

    HTMLDiff change tuples



25
26
27
28
29
30
31
# File 'app/components/crm/article_revision_diff_row_component/token_diff.rb', line 25

def changes
  @changes ||= if coarse?
                 [["!", current.presence, proposed.presence]]
               else
                 HTMLDiff::Differ.diff(current_tokens, proposed_tokens, merge_threshold: 0)
               end
end

#coarse?Boolean

Whether the combined token count exceeds the bound, forcing a coarse diff.

Returns:

  • (Boolean)


36
37
38
# File 'app/components/crm/article_revision_diff_row_component/token_diff.rb', line 36

def coarse?
  current_tokens.size + proposed_tokens.size > max_tokens
end