Help us shape the future of Go! Take the 2026 Go Developer Survey

app

package
v1.66.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 19, 2026 License: MIT Imports: 64 Imported by: 0

Documentation

Overview

Package app is tjek: the TUI, the CLI verbs, storage and the sync glue, in one package split into files by concern (ARCHITECTURE.md). The command at the repository root only calls Main.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Main

func Main(version string)

Main runs tjek: the CLI when a subcommand is named, the TUI otherwise. version is the build's main.appVersion.

Types

type Repository

type Repository interface {
	Load() ([]todo.Todo, error)
	Save(dirty []*todo.Todo, tombstones map[string]time.Time) error
	// SaveOnto is Save for tasks edited in memory: a dirty task with a base
	// (Store.base) is written as its edits since then, applied to the task as
	// stored now, and handed back as written (rebase.go).
	SaveOnto(dirty []*todo.Todo, bases map[string]*todo.Todo, tombstones map[string]time.Time) error
	// SetRanker hands the repository the ranker it scores the persisted
	// `sequence` column with. Safe to call while a Save is running.
	SetRanker(rank.Ranker)
	// SetAuthor sets the name a save signs the history events it writes
	// with. Safe to call while a Save is running.
	SetAuthor(name string)
	// ResyncScores rewrites the persisted `sequence` column for every live
	// row with the current rank.Ranker. Without this, a bias change or
	// passage of time (Age drift) leaves the column stale relative to the
	// in-memory formula — invisible to the TUI (which sorts in memory) but
	// a trap for anything reading the database directly.
	ResyncScores() error
}

Repository is the persistence port. The app depends on this contract rather than on any concrete store: SQLite fulfils it in production (sqliteRepo), an in-memory fake fulfils it in tests. This keeps storage details out of the domain/UI layer and makes the store swappable (e.g. a future sync adapter).

Save is differential: callers pass only the tasks that changed since the last save and the tasks that have been deleted, both of which the in-memory Store tracks and hands over with drainDirty. Tombstones map a deleted ID to *when it was deleted*, not when the save runs: saves are debounced, so a flush-time stamp would order the deletion after edits that actually came after it, and it would not be comparable with the stamp an undo of the same deletion writes (touchRestored).

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store is the single source of truth: the task set, the undo history, and the per-save change set (dirtyIDs / tombstones).

Tasks are held in a map keyed by ID so:

  • Lookup by ID is O(1) with no separate index.
  • Pointers into the map are stable for the lifetime of the value, so mutators can hand *todo.Todo around without worrying about slice growth.
  • Mutation cost is independent of the corpus size.

Order is *derived* — when the UI needs a sorted list it goes through a selector against an ordered view, never directly through map iteration.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL