orbit-db (.createInstance ) fails - OpenError: IO error: /keystore/LOCK: No such file or directory - orbitdb

OpenError: IO error: /home/user/.Fennec/Beeblebrox/12D3KooWD9HKFwR4tTjFnfdgs8FeseWTnGvf5RJmZ79nEtbm83Ew/keystore/LOCK: No such file or directory
at /home/user/programs/Fennec/node_modules/orbit-db-storage-adapter/node_modules/levelup/lib/levelup.js:119:23
at /home/user/programs/Fennec/node_modules/orbit-db-storage-adapter/node_modules/deferred-leveldown/node_modules/abstract-leveldown/abstract-leveldown.js:38:14
at /home/user/programs/Fennec/node_modules/orbit-db-storage-adapter/node_modules/deferred-leveldown/deferred-leveldown.js:31:21
at /home/user/programs/Fennec/node_modules/orbit-db-storage-adapter/node_modules/encoding-down/node_modules/abstract-leveldown/abstract-leveldown.js:38:14
at /home/user/programs/Fennec/node_modules/orbit-db-storage-adapter/node_modules/leveldown/node_modules/abstract-leveldown/abstract-leveldown.js:38:14
seems like orbitdb does not create db directory
but leveldb tries to open?
code
(.ensureDirSync fs (:Beeblebrox-data-dirpath root) (clj->js {:mode 0777}))
(let [ipfs (.create IPFSHttpClient "http://127.0.0.1:5001")
orbitdb (<p!
(->
(.createInstance
OrbitDB ipfs
(clj->js
{"directory" (:Beeblebrox-data-dirpath root)}))
(.catch (fn [ex]
(println ex)))))]
(println (.. orbitdb -identity -id)))
(comment
; fails as well
(<p! (.create IPFS (clj->js
{:repo (.join path (:program-data-dirpath root) "Sarah-Connor")})))
)
package.json
{
"dependencies": {
"orbit-db": "0.28.6",
"ipfs": "0.62.3",
"ipfs-http-client": "56.0.3"
}
}
go-ipfs version is 0.12.2

error has nothing to do with datahike on nodejs - Arthur-Dent
calling (set! (.-window js/global) js/global) causes the error
the call is needed for indexdbshim
solution
looked at src of indexdbshim - it does not need window, it knows glboal
this works
(defonce indexeddbshim (js/require "indexeddbshim"))
#_(set! (.-window js/global) js/global)
(indexeddbshim js/global #_(.-window js/global) #js{:checkOrigin false})
https://github.com/move-me-to-ipfs-shipyard/Fennec/blob/ae0eb02d630414e355174f78ad2b5f0d1a9fd048/src/Fennec/beans.cljs#L27
reason was in using datahike on nodejs - even just importing caused it
see this question datahike clojurescript branch cljs-206 broken - how to run datahike with clojurescript?
it contains links to what and how we had to assemble datahike on nodejs from commits force-pushed-deleted by authors of 206-cljs-support branch

Related

Howto enable Fulcro Websockets

I have a basic question about how to get started with Fulcro and Websockets.
i) I started with the Fulcro lein template. ii) Then added the websocket client and server bits. iii) In my server, I also added a com.fulcrologic.fulcro.networking.websocket-protocols.WSListener to detect when a WS client is connecting.
Between the WSListener, and the browser's network console, I can see that the client is never making a WS connection.
How does Fulcro make the initial WS connection?
After that, how can I make server pushes to client?
client.cljs
(ns foo.client
(:require [fulcro.client :as fc]
[foo.ui.root :as root]
[fulcro.client.network :as net]
[fulcro.client.data-fetch :as df]
[com.fulcrologic.fulcro.networking.websockets :as fws]
[com.fulcrologic.fulcro.application :as app]))
;; Neither this nor the below ":websocket (fws/fulcro-websocket-remote {})" works
;; (defonce app (app/fulcro-app {:remotes {:remote (fws/fulcro-websocket-remote {})}}))
(defonce SPA (atom nil))
(defn mount [] (reset! SPA (fc/mount #SPA root/Root "app")))
(defn start [] (mount))
(def secured-request-middleware
;; The CSRF token is embedded via server_components/html.clj
(->
(net/wrap-csrf-token (or js/fulcro_network_csrf_token "TOKEN-NOT-IN-HTML!"))
(net/wrap-fulcro-request)))
(defn ^:export init []
(reset! SPA (fc/make-fulcro-client
{:client-did-mount (fn [foo]
(df/load foo :all-users root/User))
;; This ensures your client can talk to a CSRF-protected server.
;; See middleware.clj to see how the token is embedded into the HTML
:networking {:remote (net/fulcro-http-remote
{:url "/api"
:request-middleware secured-request-middleware})
:websocket (fws/fulcro-websocket-remote {})}}))
(start))
middleware.cljs
(defrecord FooWSListener []
WSListener
(client-added [this ws-net cid]
(println (str "Listener for dealing with client added events." [ws-net cid])))
(client-dropped [this ws-net cid]
(println (str "listener for dealing with client dropped events." [ws-net cid]))))
(def foo-ws-listener (->FooWSListener))
(def websockets' (atom nil))
(defn query-parser [env query] )
(defstate middleware
:start
(let [websockets (fws/start! (fws/make-websockets
query-parser
{:http-server-adapter (get-sch-adapter)
:parser-accepts-env? true
;; See Sente for CSRF instructions
:sente-options {:csrf-token-fn nil}}))
defaults-config (:ring.middleware/defaults-config config)
legal-origins (get config :legal-origins #{"localhost"})]
(fwsp/add-listener websockets foo-ws-listener)
(reset! websockets' websockets)
(-> not-found-handler
(wrap-api "/api")
(fws/wrap-api websockets)
server/wrap-transit-params
server/wrap-transit-response
(wrap-html-routes)
(wrap-defaults defaults-config)
wrap-gzip)))
Since fulcro-websockets 3.1.0 the websocket connection is made on the first data transfer via websocket remote.
If you want to force the connection, you can do that by sending any mutation over the remote:
(:require [com.fulcrologic.fulcro.mutations :refer [defmutation]
[com.fulcrologic.fulcro.components :as comp])
(defmutation connect-socket [_]
(websocket [_] true))
(comment
;; trigger it via repl or a button handler
(comp/transact! foo.client/SPA `[(connect-socket {})]
Once you make a connection, you can make a push from server like this:
(:require [com.fulcrologic.fulcro.networking.websocket-protocols :refer [push]])
(let [client-uid (-> #(:connected-uids websockets')
:any
first)]
(push websockets' client-uid :foo-topic {:foo "bar"}))
To receive that on the client, you're going to need a :push-handler defined on the websocket remote:
(defn push-handler [{:keys [topic msg] :as data}]
(log/info "push-handler received: " data))
;; optionally you can listen for websocket state changes
(defn state-callback [before after]
(log/info "state-callback: " {:before before
:after after}))
(defn ^:export init []
(reset! SPA (fc/make-fulcro-client
{:client-did-mount (fn [foo]
(df/load foo :all-users root/User))
:remotes {:remote (net/fulcro-http-remote
{:url "/api"
:request-middleware secured-request-middleware})
:websocket (fws/fulcro-websocket-remote
{:push-handler push-handler
:state-callback state-callback})}}))
(start))
BTW since you're using template provided mount, you can use it to handle websockets' on the server:
(defstate websockets'
:start
(fws/start! (fws/make-websockets
query-parser
{:http-server-adapter (get-sch-adapter)
:parser-accepts-env? true})))
This way you can avoid this line: (reset! websockets' websockets)

Why does `assoc' return nil in this case?

I am trying to write a Export Backend for Emacs org-mode. This mode is derived from the ox-latex.el Exporter. I want the Exporter to embed all *.css and *.js files into the resulting .html file.
The Exporter runs but does'nt give any output in my functions, because this
assoc(t (("readthedocs" ("css" "htmlize.css" "readtheorg.css") ("js" "readtheorg.js" "jquery.js" "bootstrap.js"))))
call (it's from the debugger) returns nil.
What am I missing here ?
Any help appreciated :) Full Code can be found here https://pastebin.com/N475Uk9Z
EDIT:
(defconst org-static-html-themes
'(("readthedocs" . (("css" . ("htmlize.css"
"readtheorg.css"))
("js" . ("readtheorg.js"
"jquery.js"
"bootstrap.js"))))))
(defun org-static-html--build-head (info)
"Return information for the <head>..</head> of the HTML output.
INFO is a plist used as a communication channel."
(progn
(debug)
(org-element-normalize-string
(concat
(org-element-normalize-string (plist-get info :html-head))
(org-element-normalize-string (plist-get info :html-head-extra))
(org-element-normalize-string
(mapconcat (lambda (css)
(org-static-html-inline-css
(concat org-static-html-resource-path "/css/" css)))
(cdr (assoc "css"
(assoc
(plist-get info :static-html-theme)
org-static-html-themes))) "\n"))))))
This function is supposed to get all css files associated with the corresponding theme and return then concatenated and wrapped inside style tags.
I should say that I'm using Emacs version 27.0.50.
Your association list contains just one association: between "readthedocs" and (("css" "htmlize.css" "readtheorg.css") ("js" "readtheorg.js" "jquery.js" "bootstrap.js")).
Since nothing is associated with t, (assoc t ...) returns nil.

edebug-trace ceased to exist

In Emacs 25.2, suddenly the variable edebug-trace ceased to exist. When I set it with setq, it has no effect (the trace buffer does not appear). What could have happened and how can I fix it?
In the meanwhile, is there another way to know which function gets called when I click on an org-mode link
You could use trace.el to trace all org functions like so (I suggest not evaluating this until you're ready to click the link).
(mapatoms
(lambda (sym)
(and (fboundp sym)
(string-prefix-p "org-" (symbol-name sym))
(trace-function-foreground sym))))
Afterwards, you can remove the traces with:
M-x untrace-all RET
Edit: We could also convert that into a command ala elp-instrument-package:
(defun my-trace-package (prefix)
"Trace all functions which start with PREFIX.
For example, to trace all ELP functions, do the following:
\\[my-trace-package] RET elp- RET"
(interactive ;; derived from `elp-instrument-package'.
(list (completing-read "Prefix of package to trace: "
obarray 'my-traceable-p)))
(if (zerop (length prefix))
(error "Tracing all Emacs functions would render Emacs unusable"))
(mapc (lambda (name)
(trace-function-foreground (intern name)))
(all-completions prefix obarray 'my-traceable-p))
(message "Use %s to cease tracing."
(substitute-command-keys "\\[untrace-all]")))
(defun my-traceable-p (fun)
"Predicate for `my-trace-package'."
(or (functionp fun) (macrop fun)))

js/console.log in ClojureScript

I want to implement a function with ClojureScript to simplify js/console.log like this:
(defn log [& args]
(apply js/console.log args))
Calling it : (log "foo" "bar")
throws: TypeError: Illegal invocation
but this works : (js/console.log "foo" "bar")
What is the problem ?
js/something is for accessing a js object, but you shouldnt nest dots after that, since it is not clojure compatible syntax and it was going to be removed. In older versions of the compiler (2138) your code works, but it is possible that it has been deprecated in newer versions of the compiler. Which version are you using?
The correct way would be using straightforward js interop like this: [Caveat: see comment below from David Nolen, ClojureScript lead developer]
(defn log [& args] (apply (.-log js/console) args))
And even shorter, since console.log is already variadic (just make an alias):
(def log (.-log js/console))
You can also just use println if you first put this at top of your file: (enable-console-print!).
And pprint has been ported:
:require [cljs.pprint :refer [pprint]]
I found the actual answer
(.apply (.-log js/console) js/console (clj->js args))
Here is a working code for your function (tested with [org.clojure/clojurescript "1.7.228"]):
; working
(defn log [& args]
(.apply js/console.log js/console (to-array args)))
; not working
; (defn log [& args] (apply (.-log js/console) args))
; (defn log [& args] (apply js/console.log args))
; (def log js/console.log)
Here is an article that describes why (apply...) is not playing well with JS functions.
http://clojurescriptmadeeasy.com/blog/how-to-apply-with-the-console-api.html
With console.log makes sense to use a macro instead of a function. If you implement log as a function all the messages will be logged with the line number of where your log function is defined.
A macro solves this problem by generating inline code during compilation, it's important to understand that macros run at compile time.
Define this macro in macros.cljc:
(ns test.macros)
(defmacro log
[& msgs]
`(.log js/console ~#msgs))
`: is like ' or quote but:
Symbols are auto-resolved to include their namespace, preventing ambiguous symbols at the time of evaluation.
Evaluated forms can be inserted using ~ or unquote, as i did for msgs adding # to unpack multiple arguments: ~#msgs. More info about syntax quote.
Then call it from core.cljs:
(ns test.core
(:require-macros [test.macros :refer [log]]))
(log "foo" "bar")

Clojure compile-time escape mechanism

The language Forth offers a "compile-time" escape mechanism where code can be executed immediately, while the compiler is running (not at run-time). You can include print statements, for example, to debug tricky syntax or type errors).
Does Clojure have anything similar? I am getting a compile-time IllegalArgumentException in one of my function calls and would like to add a compile-time print statement to determine the argument type ((.getClass)).
Thanks.
UPDATE: Here is the complete defn that is failing compilation:
(ns my.ns.name
(:gen-class
:main true)
(:use
[clojure.contrib.str-utils2 :only (join)])
(:import
[java.io PrintWriter]
[java.net URL]
[java.util.concurrent Executors]
[java.util.jar Manifest]
[org.apache.commons.cli CommandLine HelpFormatter Options Option ParseException PosixParser]))
(defn set-version
"Set the version variable to the build number."
[]
(def version
(-> (str "jar:" (.. my.ns.name (getProtectionDomain)
(getCodeSource)
(getLocation))
"!/META-INF/MANIFEST.MF")
(URL.)
(.openStream)
(Manifest.)
(.. getMainAttributes)
(.getValue "Build-number"))))
This defn works:
(defn set-version
"Set the version variable to the build number."
[]
(println (str (.getClass my.ns.name)))
(def version
(-> (str "jar:" (-> my.ns.name (.getProtectionDomain)
(.getCodeSource)
(.getLocation))
"!/META-INF/MANIFEST.MF")
(URL.)
(.openStream)
(Manifest.)
(.. getMainAttributes)
(.getValue "Build-number"))))
Printing the class of things during compilation is pretty restricted to special cases. You will mostly get Symbols and Seqs. Only literals have a meaningful type during compilation. You can execute arbitrary code during compilation via macros.
(defmacro debug-type
[x]
(println (type x))
x)
However as I said: this will normally not be very helpful. And no: in general you cannot wrap x in an eval, eg. if x is a symbol refering to a let-local.
EDIT: Update for updated question.
(def version
(-> (str "jar:" (-> *ns* (.getProtectionDomain)
(.getCodeSource)
(.getLocation))
"!/META-INF/MANIFEST.MF")
(URL.)
(.openStream)
(Manifest.)
(.getMainAttributes)
(.getValue "Build-number")))
Try this. There is no need for a function. def inside defn should ring alarm bells.

Resources