The problem is somewhat subtle. When generating source-map info, the REPL code given a form tries to look at :source metadata(link: 2) and if not present, it simply prints the form using pr. We get Clojure-style printing because JSValue does not implement ClojureScript printing as reported in CLJS-733.
Instead of implementing the rejected idea from CLJS-733. I focused on the first-case code path with :source metadata. It turned out that :source gets added if given form supports metadata protocols. Easiest idea was to change JSValue from deftype to defrecord.
I confirm that this fixed the REPL issue in Dirac. Now I'm getting back the original source code as entered by user.
Note that similar issue is present with #uuid and #inst tags as well. Those mostly work because their printer is compatible with both Clojure and ClojureScript. But fundamentally user might get back different source-map source than entered into the REPL. For example whitespace will be missing. This might cause confusion because line/column information reported by reader which might not match this artificial source-map content generated by printing.
I believe a fix would be to wrap UUID and Date forms created by tagged literals into something similar to JSValue and work with this wrapped value instead. Same with #queue. This would make cljs.tagged-literal code consistent, because every form originated from data readers would be inside a wrapper. It would enable arbitrary metadata on wrappers.
As a side note:
I noticed that reader's metadata get lost. They are not transplanted from form produced by the reader to generated tagged literal forms.
My second goal was to copy reader's metadata. Unfortunately this wasn't possible with current implementation of tools.reader. I can get reader metadata from passed form, but that is not the full picture, it only describes content after the tag was already consumed. I would need metadata from tag itself, passed into data-reader call somehow(link: 3).
I don't know about any real-world problem caused by missing reader metadata on tagged literals, but I think ideally it should be fixed. For example when implementing error-reporting in cljs-oops, I had to handle this edge case(link: 4), because line/column metadata was missing in some edge cases.
(link: 1) https://github.com/binaryage/dirac/releases/tag/v0.8.0
(link: 2) https://github.com/clojure/clojurescript/blob/960bb9b778190aa7359acb2f74cc61d452cef2ae/src/main/clojure/cljs/repl.cljc#L476
(link: 3) https://github.com/clojure/tools.reader/blob/3f36a18a6c5d53a4fc718822131ee75625fd44dc/src/main/cljs/cljs/tools/reader.cljs#L834
(link: 4) https://github.com/binaryage/cljs-oops/blob/d530a3cdf8cbab39bd2699c36caded4414224c50/src/lib/oops/reporting.clj#L29