Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serializing ClojureScript edn as a text file (like json)?

I am working in ClojureScript and would like to serialize a massive EDN data structure (in particular: a large map) in the form of a text file (in the same way that JS objects are stored as .json files). Performance concerns are not an issue.

Is this possible, and if so, is there considered a standard/best practice way to do this?

like image 592
George Avatar asked Nov 01 '25 12:11

George


2 Answers

Yes. Use pr-str or clojure.pprint/pprint to write EDN and use clojure.edn/read-string to ingest EDN.

In ClojureScript you may face the same challenges as Javascript in accessing the filesystem from a browser. For example to save a file from the browser things can be a little tricky:

(defn save-file [filename t s]
  (if js/Blob
    (let [b (js/Blob. #js [s] #js {:type t})]
      (if js/window.navigator.msSaveBlob
        (js/window.navigator.msSaveBlob b filename)
        (let [link (js/document.createElement  "a")]
          (aset link "download" filename)
          (if js/window.webkitURL
            (aset link "href" (js/window.webkitURL.createObjectURL b))
            (do
              (aset link "href" (js/window.URL.createObjectURL b))
              (aset link "onclick" (fn destroy-clicked [e]
                                     (.removeChild (.-body js/document) (.-target e))))
              (aset link "style" "display" "none")
              (.appendChild (.-body js/document) link)))
          (.click link))))
    (log/error "Browser does not support Blob")))

So it depends on the context of how you access the files, but so long as you can get/put strings, it's as easy as pr-str and edn/read-string.

like image 154
Timothy Pratley Avatar answered Nov 04 '25 20:11

Timothy Pratley


It is very possible.

This approach gives you a url string such as "blob:http://localhost:3000/4a6407c6-414e-4262-a194-28bd2b72be00", where your data will be available for download on a browser.

(defn download-as-edn [coll]
  (-> coll
      str
      vector
      clj->js
      (js/Blob. #js {:type "text/edn"}))
      js/URL.createObjectURL)) 

Notice that Blob takes a sequence, therefore we pass it the edn string inside a vector.

like image 42
efraimmgon Avatar answered Nov 04 '25 21:11

efraimmgon