struct

Hwaro::Services::ChangeSet

Inherits Struct < Value < Object

Categorised set of file-system changes detected by the watcher.

Changes are split into five buckets so the server can pick the cheapest rebuild strategy.

Constructors

new(modified_content : Array(String), modified_templates : Array(String), modified_static : Array(String), added_files : Array(String), removed_files : Array(String), config_changed : Bool, modified_content_files : Array(String) = [] of String, modified_data : Array(String) = [] of String, config_files : Array(String) = [] of String)
Source

Instance methods

added_files

Files that were added (new) – present in current scan but not previous

Source
all_changed_files
Source
config_changed

Whether config.toml itself changed

Source
config_files

Which watched config files changed — config.toml, the config.<env>.toml overlay, or both. Reporting only, so the watch timeline can name the file the developer actually saved instead of always printing "config.toml"; every decision reads config_changed.

Source
content_and_template_only?

True when content and templates changed together (no structural changes)

Source
content_files_only?

True when only non-Markdown content files were modified — just republish them, no markdown re-parsing, no template re-render.

Source
content_incremental?

True when content was modified (possibly alongside static changes) but no structural / config / template changes occurred.

Source
css_only?

True when only stylesheet sources were modified — .css files or .scss sources (which publish as compiled .css). The live-reload client can swap these in place instead of reloading the page.

Source
description

Human-readable description of the change for logging. The trailing noun is pluralized by the total file count; a config change is named separately since it is one specific file, not a category count.

Source
display

What the watch timeline prints: the path itself when exactly one file changed (the common save-one-file loop), the category summary above otherwise.

Source
empty?

True when the change set is empty (nothing actually changed)

Source
merge(other : ChangeSet) : ChangeSet

Merge another ChangeSet into this one, combining all buckets. Used during debounce to batch rapid successive changes.

Order-aware semantics (self happens first, then other):

  • add→remove cancels out (file created then deleted = no-op)
  • remove→add keeps the add (file deleted then recreated = net add, e.g. atomic save via delete+move)
Source
modified_content

Content files (.md under content/) that were modified (not added/deleted)

Source
modified_content_files

Non-Markdown files under content/ (images and other assets published via [content.files] allow_extensions) that were modified. These are not pages — they're copied 1:1 to the output dir on rebuild, so they can't ride the incremental page pipeline.

Source
modified_data

Data / i18n files (data/, i18n/) that were modified. Templates read site.data and translations feed every localized string, so any page may depend on these — a change here forces a full rebuild.

Source
modified_static

Static files that were modified

Source
modified_templates

Template files that were modified

Source
needs_full_rebuild?

True when a full rebuild is unavoidable: config changed, data/i18n changed (any page may read them), or files were added / deleted (which affects section lists, navigation, taxonomy indices, etc.)

Source
rebuild_strategy

Determine the optimal rebuild strategy for this changeset.

The *_only? predicates above are mutually exclusive by bucket emptiness, so a changeset mixing two non-content buckets — templates+static, templates+content-asset, static+content-asset — matched none of them and fell through to else, taking a FULL rebuild. That was wasted work (nothing structural changed, and each of those buckets has its own cheap path) and, worse, the #760 loop: a full rebuild is the ONLY strategy that re-runs build.hooks.pre, so a pre hook rewriting one templates/ and one static/ file byte-identically on every run retriggered itself forever — the #755 mechanism, outside the two hashed buckets.

The two trailing branches route those mixed sets to the cheapest strategy their heaviest bucket needs. Nothing is left stale: apply_changeset already copies static files and content assets alongside every non-full strategy.

Source
removed_files

Files that were removed – present in previous scan but not current

Source
static_only?

True when only static files were modified

Source
templates_only?

True when only template files were modified (no content / static / structural changes)

Source