Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: String with metadata mode #57

Open
olivergeorge opened this issue Aug 27, 2020 · 4 comments
Open

Feature: String with metadata mode #57

olivergeorge opened this issue Aug 27, 2020 · 4 comments

Comments

@olivergeorge
Copy link

olivergeorge commented Aug 27, 2020

This is a feature idea.

I'm looking for a way to make my js/console.log display cleanly with and without cljs-devtools installed.

Motivating example

Today's job is a react native app. It's not always convenient to turn cljs-devtools on (e.g. two simulators) and it's helpful to look in the simulator logs sometimes (no cljs-devtool rendering).

Problems

  • js/console.log with regular clojure data types produces verbose/unreadable strings.
  • logging (serializing) large data structures can cause UX lag

Idea

Perhaps cljs-devtools could be adapted to look for metadata associated with a string (or string like) object.

Vaguely something like this could be used to prepare a "console.log friendly string" with some other protocol which cljs-devtools could detect...

(defn data-str [data]
  (binding [*print-level* 3 *print-length* 5]
    (specify! (pr-str data) IMeta (-meta [_] data)))))

(js/console.log (data-str {:a 1 :b (range 1000)}))

NOTE: this code doesn't work

Goal is to cover two cases

  • String form will work in all situations and not take too long to serialize.
  • If cljs-devtools is installed you can drill into metadata.
@olivergeorge
Copy link
Author

Perhaps this could result in a better enable-console-print!

@darwin
Copy link
Member

darwin commented Aug 28, 2020

I had no time to look into this yet. I believe you could achieve something similar with String object instead of using just plain js strings. The String object should be able to hold cljs metadata and should be presented as string in standard consoles.

Try something like this (from top of my head):

(specify! (js/String. (pr-str data)) IMeta (-meta [_] data)))))

@olivergeorge
Copy link
Author

olivergeorge commented Aug 29, 2020

That partially solves the "string with metadata" issue.

cljs.user=> 
(defn data-str [data]
  (binding [*print-level* 3 *print-length* 5]
    (specify! (js/String. (pr-str data)) IMeta (-meta [_] data))))

cljs.user=> (data-str {:a (range 10)})
#object[String {:a (0 1 2 3 4 ...)}]

cljs.user=> (meta (data-str {:a (range 10)}))
{:a (0 1 2 3 4 5 6 7 8 9)}

But the console output associated with String objects isn't what we were hoping for...

Test: Just console.log(new String("I am a string")) in Chrome console (no cljs devtools)

image

Test: Just (js/console.log (js/String. "I am a string")) in metro bundler log

image

Test: Just (js/console.log (data-str {:a (range 10)})) in metro bundler log

image

Test: Just (js/console.log (data-str {:a (range 10)})) in chrome console with cljs devtools

image

@olivergeorge
Copy link
Author

olivergeorge commented Aug 29, 2020

This is the best I've come up with

(defn log-data [& data]
  (binding [*print-level* 3 *print-length* 5]
    (let [s (apply pr-str data)
          d (specify! #js [] IMeta (-meta [_] data))]
      (js/console.log s d))))

(log-data :this {:is "a" :test (range 100)})

It looks fine from a metro bundler terminal.

LOG :this {:is "a", :test (0 1 2 3 4 ...)} []

I suspect cljs-devtools could be made to handle the "array with meta" better.

image

Still a bit ugly from console without devtools...

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants