;; ported-from: src/app/history.ts
;;
;; READ-ONLY loader for v1 device-local history (IndexedDB `sueta-history`).
;; v2 persistence is the replicated log itself (the encrypted blockstore in
;; IndexedDB) — this module only survives to feed the one-shot legacy import
;; (app/migrate.cljs), after which the old records are left untouched as a
;; safety net and simply stop being read.
;;
;; A StoredRoom is {msgs, mineIds, savedAt}; a PersistMsg is
;; {id, from, name, ts, seq, text?, thread?, img?, rx?, blob?}. Nothing is
;; reshaped here — the raw IDB record is handed to the migrator, which validates
;; every field.
(ns sueta.app.history)
;; Deliberately NOT namespaced (config/NS): this is the literal database name
;; the v1 app wrote. Forks never have it; load-history just returns nil there.
(def ^:private DB-NAME "sueta-history")
(def ^:private STORE "rooms")
(defn load-history
"The v1 record for `room-id`, or nil (absent, or no IndexedDB at all)."
[room-id]
(-> (js/Promise.
(fn [resolve reject]
(let [^js req (js/indexedDB.open DB-NAME 1)]
(set! (.-onupgradeneeded req) (fn [] (.createObjectStore ^js (.-result req) STORE)))
(set! (.-onsuccess req) (fn [] (resolve (.-result req))))
(set! (.-onerror req) (fn [] (reject (.-error req)))))))
(.then
(fn [db]
(js/Promise.
(fn [resolve _reject]
(let [^js req (-> ^js db (.transaction STORE) (.objectStore STORE) (.get room-id))]
;; TS `req.result ?? null` — NULLISH, so a stored 0/"" would be
;; honoured (the v1 records are always objects, but keep the
;; semantics identical)
(set! (.-onsuccess req)
(fn [] (let [r (.-result req)]
(resolve (if (or (nil? r) (identical? r js/undefined)) nil r)))))
(set! (.-onerror req) (fn [] (resolve nil))))))))
;; no IDB (private mode) — nothing to migrate
(.catch (fn [_] nil))))