Fixes to JSONL management, starting from empty state rather than default DB.

This commit is contained in:
2026-01-23 21:31:54 +00:00
parent 2ec6314264
commit 2a005692ee
2 changed files with 37 additions and 25 deletions
+23 -20
View File
@@ -32,7 +32,7 @@ class _ChangeRecord(msgspec.Struct):
_change_encoder = msgspec.json.Encoder()
async def load_jsonl(db_path: Path, empty_data: dict) -> dict:
async def load_jsonl(db_path: Path) -> dict:
"""Load data from disk by applying change log.
Replays all changes from JSONL file using plain dicts (to handle
@@ -40,29 +40,32 @@ async def load_jsonl(db_path: Path, empty_data: dict) -> dict:
Args:
db_path: Path to the JSONL database file
empty_data: Empty data structure to start with (as dict)
Returns:
The final state after applying all changes
Raises:
ValueError: If file doesn't exist or cannot be loaded
"""
data_dict = empty_data.copy()
if db_path.exists():
try:
# Read entire file at once and split into lines
async with aiofiles.open(db_path, "rb") as f:
content = await f.read()
for line_num, line in enumerate(content.split(b"\n"), 1):
line = line.strip()
if not line:
continue
try:
change = msgspec.json.decode(line)
# Apply the diff to current state (marshal=True for $-prefixed keys)
data_dict = jsondiff.patch(data_dict, change["diff"], marshal=True)
except Exception as e:
raise ValueError(f"Error parsing line {line_num}: {e}")
except (OSError, ValueError, msgspec.DecodeError) as e:
raise ValueError(f"Failed to load database: {e}")
if not db_path.exists():
raise ValueError(f"Database file not found: {db_path}")
data_dict: dict = {}
try:
# Read entire file at once and split into lines
async with aiofiles.open(db_path, "rb") as f:
content = await f.read()
for line_num, line in enumerate(content.split(b"\n"), 1):
line = line.strip()
if not line:
continue
try:
change = msgspec.json.decode(line)
# Apply the diff to current state (marshal=True for $-prefixed keys)
data_dict = jsondiff.patch(data_dict, change["diff"], marshal=True)
except Exception as e:
raise ValueError(f"Error parsing line {line_num}: {e}")
except (OSError, ValueError, msgspec.DecodeError) as e:
raise ValueError(f"Failed to load database: {e}")
return data_dict
+14 -5
View File
@@ -73,13 +73,22 @@ class DB:
self._current_actor: str = "system"
async def load(self, db_path: str | None = None) -> None:
"""Load data from JSONL change log."""
"""Load data from JSONL change log.
If file doesn't exist, keeps the initialized empty structure and
sets _previous_builtins to {} for creating a new database.
"""
if db_path is not None:
self.db_path = Path(db_path)
empty = msgspec.to_builtins(self._data)
data_dict = await load_jsonl(self.db_path, empty)
self._data = _json_decoder.decode(_json_encoder.encode(data_dict))
self._previous_builtins = msgspec.to_builtins(self._data)
try:
data_dict = await load_jsonl(self.db_path)
self._data = _json_decoder.decode(_json_encoder.encode(data_dict))
# Track the JSONL file state directly - this is what we diff against
self._previous_builtins = data_dict
except ValueError:
if self.db_path.exists():
raise # File exists but failed to load - re-raise
# File doesn't exist: keep initialized _data, _previous_builtins stays {}
def _queue_change(self) -> None:
current = msgspec.to_builtins(self._data)