Class: Woods::Temporal::JsonSnapshotStore
- Inherits:
-
Object
- Object
- Woods::Temporal::JsonSnapshotStore
- Defined in:
- lib/woods/temporal/json_snapshot_store.rb
Overview
JSON-file-based snapshot store for temporal tracking without SQLite.
Stores snapshots as individual JSON files in a ‘snapshots/` subdirectory of the index output directory. Each file is named by git SHA and contains manifest metadata plus per-unit content hashes.
Implements the same public interface as SnapshotStore so the MCP server tools work identically.
Instance Method Summary collapse
- #capture(manifest, unit_hashes) ⇒ Object
- #diff(sha_a, sha_b) ⇒ Object
- #find(git_sha) ⇒ Object
-
#initialize(dir:) ⇒ JsonSnapshotStore
constructor
rubocop:disable Metrics/ClassLength.
- #list(limit: 20, branch: nil) ⇒ Object
- #unit_history(identifier, limit: 20) ⇒ Object
Constructor Details
#initialize(dir:) ⇒ JsonSnapshotStore
rubocop:disable Metrics/ClassLength
25 26 27 28 |
# File 'lib/woods/temporal/json_snapshot_store.rb', line 25 def initialize(dir:) @dir = File.join(dir, 'snapshots') FileUtils.mkdir_p(@dir) end |
Instance Method Details
#capture(manifest, unit_hashes) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/woods/temporal/json_snapshot_store.rb', line 30 def capture(manifest, unit_hashes) git_sha = mget(manifest, 'git_sha') return nil unless git_sha previous = find_latest snapshot = build_snapshot(manifest, git_sha, unit_hashes) if previous diff_result = compute_diff(previous[:units], index_units(unit_hashes)) snapshot[:units_added] = diff_result[:added].size snapshot[:units_modified] = diff_result[:modified].size snapshot[:units_deleted] = diff_result[:deleted].size end write_snapshot(git_sha, snapshot) snapshot.except(:units) end |
#diff(sha_a, sha_b) ⇒ Object
62 63 64 65 66 67 68 69 |
# File 'lib/woods/temporal/json_snapshot_store.rb', line 62 def diff(sha_a, sha_b) snap_a = load_snapshot_with_units(sha_a) snap_b = load_snapshot_with_units(sha_b) return { added: [], modified: [], deleted: [] } unless snap_a && snap_b compute_diff(snap_a[:units], snap_b[:units]) end |
#find(git_sha) ⇒ Object
54 55 56 57 58 59 60 |
# File 'lib/woods/temporal/json_snapshot_store.rb', line 54 def find(git_sha) path = snapshot_path(git_sha) return nil unless File.exist?(path) data = JSON.parse(File.read(path)) symbolize_snapshot(data).except(:units) end |
#list(limit: 20, branch: nil) ⇒ Object
48 49 50 51 52 |
# File 'lib/woods/temporal/json_snapshot_store.rb', line 48 def list(limit: 20, branch: nil) snapshots = load_all_summaries snapshots.select! { |s| s[:git_branch] == branch } if branch snapshots.sort_by { |s| s[:extracted_at] || '' }.reverse.first(limit) end |
#unit_history(identifier, limit: 20) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/woods/temporal/json_snapshot_store.rb', line 71 def unit_history(identifier, limit: 20) snapshots = load_all_with_units .sort_by { |s| s[:extracted_at] || '' } .reverse .first(limit) entries = snapshots.filter_map do |snap| unit = snap[:units]&.[](identifier) next unless unit { git_sha: snap[:git_sha], extracted_at: snap[:extracted_at], git_branch: snap[:git_branch], unit_type: unit[:unit_type], source_hash: unit[:source_hash], metadata_hash: unit[:metadata_hash], dependencies_hash: unit[:dependencies_hash] } end mark_changed_entries(entries) end |