Class: Tempest::TimelineStore

Inherits:
Object
  • Object
show all
Defined in:
lib/tempest/timeline_store.rb

Overview

Persists the home timeline snapshot so a restarted tempest can show the last-seen posts before the network is even reachable. Stored alongside session.json / cursor.json under XDG_CONFIG_HOME.

Callers pass posts in chronological order (oldest first, newest last); the store keeps only the most recent MAX_POSTS to bound disk usage.

Constant Summary collapse

MAX_POSTS =
50

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path:) ⇒ TimelineStore

Returns a new instance of TimelineStore.



28
29
30
# File 'lib/tempest/timeline_store.rb', line 28

def initialize(path:)
  @path = path
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



32
33
34
# File 'lib/tempest/timeline_store.rb', line 32

def path
  @path
end

Class Method Details

.default_path(env = ENV) ⇒ Object



19
20
21
22
23
24
25
26
# File 'lib/tempest/timeline_store.rb', line 19

def self.default_path(env = ENV)
  explicit = env["TEMPEST_TIMELINE_PATH"]
  return explicit if explicit && !explicit.empty?

  base = env["XDG_CONFIG_HOME"]
  base = File.join(env["HOME"].to_s, ".config") if base.nil? || base.empty?
  File.join(base, "tempest", "timeline.json")
end

Instance Method Details

#loadObject



46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/tempest/timeline_store.rb', line 46

def load
  return nil unless File.exist?(@path)

  data = JSON.parse(File.read(@path))
  return nil unless data.is_a?(Hash) && data["posts"].is_a?(Array) && data["saved_at"]

  {
    posts: data["posts"].map { |hash| deserialize_post(hash) },
    saved_at: Time.iso8601(data["saved_at"]),
  }
rescue JSON::ParserError, ArgumentError
  nil
end

#save(posts:, at: Time.now) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/tempest/timeline_store.rb', line 34

def save(posts:, at: Time.now)
  payload = {
    "posts" => posts.last(MAX_POSTS).map { |p| serialize_post(p) },
    "saved_at" => at.utc.iso8601(6),
  }

  FileUtils.mkdir_p(File.dirname(@path))
  File.open(@path, File::WRONLY | File::CREAT | File::TRUNC, 0o600) do |io|
    io.write(JSON.generate(payload))
  end
end