cognitect / transit-cljs

Transit for ClojureScript
http://transit-format.org
Apache License 2.0
323 stars 20 forks source link

Add support for map entries #42

Closed mfikes closed 6 years ago

mfikes commented 6 years ago

transit-clj supports writing map entries (as 2-element vectors). Here is an example:

$ clj -Sdeps '{:deps {com.cognitect/transit-clj {:mvn/version "0.8.300"}}}'
Clojure 1.9.0
user=> (require '[cognitect.transit :as transit])
nil
user=> (import [java.io ByteArrayInputStream ByteArrayOutputStream])
java.io.ByteArrayOutputStream
(def out (ByteArrayOutputStream. 4096))
#'user/out
(def writer (transit/writer out :json))
#'user/writer
user=> (transit/write writer "foo")
nil
user=> (transit/write writer (into [] (sorted-map :a 1)))
nil
user=> (transit/write writer (into [] {:b 2}))
nil
user=> (.toString out)
"[\"~#'\",\"foo\"] [[\"~:a\",1]] [[\"~:b\",2]]"
user=> (def in (ByteArrayInputStream. (.toByteArray out)))
#'user/in
user=> (def reader (transit/reader in :json))
#'user/reader
user=> (prn (transit/read reader))
"foo"
nil
user=> (transit/read reader)
[[:a 1]]
user=> (type (first *1))
clojure.lang.PersistentVector
user=> (transit/read reader)
[[:b 2]]
user=> (type (first *1))
clojure.lang.PersistentVector

But, transit-cljs doesn't support this. Here is an example, illustrating attempting to a cljs.core/BlackNode and a cljs.core/MapEntry:

$ clojure -Sdeps '{:deps {com.cognitect/transit-cljs {:mvn/version "0.8.243"} org.clojure/clojurescript {:git/url "https://github.com/clojure/clojurescript" :sha "c6961d518beb69a8ecd84421b13778fab33bdaab"}}}' -m cljs.main
To quit, type: :cljs/quit
cljs.user=> (require '[cognitect.transit :as t])

cljs.user=> (defn roundtrip [x]
  (let [w (t/writer :json)
        r (t/reader :json)]
    (t/read r (t/write w x))))
#'cljs.user/roundtrip
cljs.user=> (roundtrip (into [] (sorted-map :a 1)))
Error: Cannot write
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:446:0)
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:172:0)
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:183:0)
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:436:0)
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:471:0)
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:501:0)
     cognitect$transit$write (.cljs_nashorn_repl/cognitect/transit.cljs:256:3)
     (NO_SOURCE_FILE <eval>:5:0)
     (NO_SOURCE_FILE <eval>:1:0)
     (NO_SOURCE_FILE <eval>:1:0)
     (NO_SOURCE_FILE <eval>:1:0)
cljs.user=> (roundtrip (into [] {:a 1}))
Error: Cannot write
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:446:0)
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:172:0)
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:183:0)
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:436:0)
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:471:0)
     (.cljs_nashorn_repl/com/cognitect/transit/impl/writer.js:501:0)
     cognitect$transit$write (.cljs_nashorn_repl/cognitect/transit.cljs:256:3)
     (NO_SOURCE_FILE <eval>:5:0)
     (NO_SOURCE_FILE <eval>:1:0)
     (NO_SOURCE_FILE <eval>:1:0)
     (NO_SOURCE_FILE <eval>:1:0)

As an aside: The motivating scenario where this arose is that the ClojureScript compiler serializes out, under the key :cljs.spec/registry-ref a sequence of map entries, into its analysis cache. This works fine for for the Clojure-implementation of ClojureScript when it uses transit-clj, but the same use fails if you attempt to do the same with self-hosted ClojureScript, using transit-cljs.

mfikes commented 6 years ago

Duplicate of #33