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

Upload to NPM? #29

Open
lidorcg opened this issue Feb 7, 2022 · 3 comments
Open

Upload to NPM? #29

lidorcg opened this issue Feb 7, 2022 · 3 comments

Comments

@lidorcg
Copy link

lidorcg commented Feb 7, 2022

I would like to use this tool from js (without homebase) but I can't seem to find it on npm.
Is there an easy way of integration from js (without homebase) that I'm missing?

@becomingbabyman
Copy link
Member

We're working on it. At the moment the datalog-console is designed to be used in the chrome extension almost exclusively. You can also grab it off clojars if you're using Clojurescript, but we haven't exposed all the requisite APIs to make it work outside of the chrome extension.

Are you just trying to connect it to a datascript DB?

@lidorcg
Copy link
Author

lidorcg commented Feb 13, 2022

yeah, from the js api.
That is, I'm not going through cljs atm so it would be a serious hustle to integrate it using cljs, that is why I looked for a js integration.

I'm planning to use it with chrome so that's a non-issue.
The only issue is that I can't call:

(datalog-console/enable! {:conn conn})

from js (so far as I know...)

@lidorcg
Copy link
Author

lidorcg commented Jul 10, 2022

So I was able to make it work but...
img

  1. First I needed to compile it to esm (because I work with vite which uses esm for dev) so I added this to shadow-cljs.edn:
:npm {:target :esm
      :output-dir "dist/js"
      :modules {:datalog-console {:exports {enable datalog-console.integrations.datascript/enable-js}}}}
  1. Then I found that for some reason (I still haven't discovered why) conn that was created through datascript's js interop wasn't passed to datalog-console as legit conn but as some weird object (although in datascript it seems that it is passed as a normal conn, all the methods there depends on it). Anyway I ended up passing a function that serializes the conn:
// from js
enable(() => datascript.serializable(datascript.db(conn)));
  1. And I needed to deserialize it on the cljs end, I also discovered that datalog-console doesn't work well with string keys in the schema and attributes so I had to override the from-serializable functions (:thaw-fn and :thaw-kw ) to make up for that:
(ns datalog-console.integrations.datascript
  (:require [goog.object :as gobj]
            [cljs.reader]
            [datascript.core :as d]
            [datalog-console.lib.version :as dc]
            [datascript.serialize :as ds]))


(defn- thaw-fn [s]
  (-> (cljs.reader/read-string s)
      (clj->js)
      (js->clj :keywordize-keys true)))

(defn get-db [conn-fn]
  (-> (conn-fn)
      (ds/from-serializable {:thaw-fn thaw-fn :thaw-kw keyword})))

(defn transact-from-devtool! [conn transact-str]
  (try
    (d/transact conn (cljs.reader/read-string transact-str))
    {:datalog-console.client.response/transact! :success}
    (catch js/Error e {:error (goog.object/get e "message")})))

(defn enable!
  "Takes a [datascript](https://github.com/tonsky/datascript) database connection atom. Adds message handlers for a remote datalog-console process to communicate with. E.g. the datalog-console browser [extension](https://chrome.google.com/webstore/detail/datalog-console/cfgbajnnabfanfdkhpdhndegpmepnlmb?hl=en)."
  [{:keys [conn]}]
  (try
    (js/document.documentElement.setAttribute "__datalog-console-remote-installed__" true)
    (.addEventListener js/window "message"
                       (fn [event]
                         (when-let [devtool-message (gobj/getValueByKeys event "data" ":datalog-console.client/devtool-message")]
                           (let [msg-type (:type (cljs.reader/read-string devtool-message))]
                             (case msg-type

                               :datalog-console.client/request-whole-database-as-string
                               (.postMessage js/window #js {":datalog-console.remote/remote-message" (pr-str (get-db conn))} "*")

                               :datalog-console.client/transact!
                               (let [transact-result (transact-from-devtool! conn (:data (cljs.reader/read-string devtool-message)))]
                                 (.postMessage js/window #js {":datalog-console.remote/remote-message" (pr-str transact-result)} "*"))

                               :datalog-console.client/request-integration-version
                               (.postMessage js/window #js {":datalog-console.remote/remote-message" (pr-str {:version dc/version})})
                               nil)))))
    (catch js/Error _e nil)))


(defn ^:export enable-js [conn]
  (enable! {:conn conn}))

And finally I could go to the chrome extension and load my db :)!
Hopes it will help other people.

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