Implement an LRU cache in Python as a decorator cache(maxsize) that memoizes a target function's results. Must support positional args, *args, and **kwargs so that semantically equivalent calls (e.g., f(1, b= 2) and f(1, 2)) map to the same key. Handle unhashable arguments by canonicalizing them into a deterministic, hashable representation. Provide operations: eviction by least recently used, clear(), and cache_info(). Follow-up: add persistence methods save(filepath) and load(filepath) that serialize the cache to JSON (no pickle). Define how you encode keys and values, and how you handle non-JSON-serializable return values and versioning.