anchor.diff:    ((ref :initform "bookmarks"))
     (:export-class-name-p t)
     (:accessor-name-transformer #'class*:name-identity))
  -(define-class history-data-path (data-path)
  -  ((ref :initform "history"))
  +(define-class history-data-path (async-data-path)
  +  ((ref "history")
  +   (timeout 0.05))
     (:export-class-name-p t)
     (:accessor-name-transformer #'class*:name-identity))
   (define-class download-data-path (data-path) ; TODO: Rename to downloads-data-path?
  
positive.code:   (:export-accessor-names-p t)
    (:accessor-name-transformer #'class*:name-identity))
  
  (define-class cookies-data-path (data-path)
    ((ref :initform "cookies"))
    (:export-class-name-p t)
  
negative.code: (defmethod restore ((profile private-data-profile) (path data-path) &key &allow-other-keys)
    "This method guarantees PATH will not be loaded from disk in PRIVATE-DATA-PROFILE."
    nil)
  
  (defmethod store :around ((profile data-profile) (path async-data-path) &key &allow-other-keys)
    (labels ((worker ()
               (let ((store-ops (drain-channel (channel path) (timeout path))))
                 (when (< 1 (length store-ops))
                   (log:debug "Skipping ~a unnecessary ~a store ops"
                             (1- (length store-ops))
                             path))
                 ;; TODO: Lock here? Seems to dead-lock history forward/backward.
                 ;; (bt:with-recursive-lock-held ((lock (get-user-data profile path))))
                 (call-next-method))
               (worker)))
      (unless (channel path)
        (setf (channel path) (make-channel))
        (bt:make-thread #'worker))
      ;; We pass `path', but anything would do since the value is ignored.
      (calispel:! (channel path) path)))
  
  (export-always 'expand-path)
  (declaim (ftype (function ((or null data-path)) (or string null)) expand-path))
  