from __future__ import annotations import hashlib import json from pathlib import Path from typing import Any def make_key(prefix: str, identifier: str) -> str: """Stable, collision-safe state key from prefix + arbitrary identifier.""" h = hashlib.md5(identifier.encode()).hexdigest()[:8] return f"{prefix}_{h}" class State: def __init__(self, path: str) -> None: self._path = Path(path) self._path.parent.mkdir(parents=True, exist_ok=True) self._data: dict[str, Any] = {} self._load() def _load(self) -> None: if self._path.exists(): try: self._data = json.loads(self._path.read_text()) except (json.JSONDecodeError, OSError): self._data = {} def _save(self) -> None: self._path.write_text(json.dumps(self._data, indent=2)) def get(self, key: str, default: Any = None) -> Any: return self._data.get(key, default) def set(self, key: str, value: Any) -> None: self._data[key] = value self._save() def delete(self, *keys: str) -> None: changed = any(k in self._data for k in keys) for k in keys: self._data.pop(k, None) if changed: self._save()