Skip to content

Instantly share code, notes, and snippets.

@whacked
Created March 25, 2018 04:07
Show Gist options
  • Save whacked/d74eb2a89c5d18da8d63f5b14e6d3c79 to your computer and use it in GitHub Desktop.
Save whacked/d74eb2a89c5d18da8d63f5b14e6d3c79 to your computer and use it in GitHub Desktop.
example of cljs with externs using fuse.js

getting this to work

ref https://lambdaisland.com/episodes/javascript-libraries-clojurescript

suppose you put the external js in in src-compat, and the corresponding externs in src-compat/externs

get the external lib

wget -O src-compat/fuse.js https://cdnjs.cloudflare.com/ajax/libs/fuse.js/3.2.0/fuse.js

generate the extern

(using https://github.com/jmmk/javascript-externs-generator)

npm install -g externs-generator

generate-extern -f src-compat/fuse.js -n Fuse -o src-compat/externs/fuse-externs.js

(ns example.core
(:require-macros [swiss.arrows :refer [-<> -<>>]])
(:require [reagent.core :as r]
[cljs-css-modules.macro :refer-macros [defstyle]]
[goog.string :as gstring]
[goog.dom :as gdom]
[cemerick.url :refer (url url-encode)]
[js.Fuse]))
(def $fuse
(let [input-data [{:title "Old Man's War"
:author {:firstName "John"
:lastName "Scalzi"}}
{:title "The Lock Artist"
:author {:firstName "Steve"
:lastName "Hamilton"}}
]
fuse-options {:shouldSort true
:threshold 0.6
:location 0
:distance 100
:maxPatternLength 32
:minMatchCharLength 2
:includeScore true
:includeMatches true
:keys ["title" "author.firstName"]
}]
(js/Fuse.
(clj->js input-data)
(clj->js fuse-options))))
(defn transform-to-highlight-labeled-strings
[source-text highlight-indices]
(comment
(transform-to-highlight-labeled-strings
"lorem ipsum sit dolor"
[[1 2] [3 4] [6 6] [9 20]]))
(let [text-length (count source-text)
-subs (fn
([beg] (subs source-text beg))
([beg end] (subs source-text beg end)))
-normal (fn [& args] [:normal (apply -subs args)])
-highlight (fn [& args] [:highlight (apply -subs args)])]
(loop [remain-indices highlight-indices
cur-index 0
out []]
(if (empty? remain-indices)
(let [remain-text (subs source-text cur-index)]
(concat
out
(when (< cur-index text-length)
[(-normal cur-index)])))
(let [[start end] (first remain-indices)
start+1 (+ 1 start)
end+1 (+ 1 end)]
(recur (rest remain-indices)
end+1
(->> [(when (< cur-index start)
(-normal cur-index start))
(-highlight start end+1)]
(remove nil?)
(concat out))))))))
(let [results
(-> (.search $fuse "Art")
(js->clj :keywordize-keys true))
best-result (first results)
render-labeled (fn [result]
(let [match (first (:matches result))
match-key (keyword (:key match))
match-text (get-in result [:item match-key])]
[:div
[:h3 (count (:matches result))
" matches; "
"using " match-key]
[:ol
(->> (transform-to-highlight-labeled-strings
match-text (:indices match))
(map (fn [[label text]]
(case label
:normal [:span text]
:highlight [:span
{:style {:background "yellow"
:border "1px solid red"}}
text
]))))]]))
]
(r/render
[(fn []
[:div
[:h2 (count results)]
[:div (get-in best-result [:item :text])]
(render-labeled best-result)])]
(js/document.getElementById "container")))
(defproject clojurescript-fuse-js-interop "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.9.0"]
[org.clojure/clojurescript "1.9.946"]
[figwheel "0.5.13"]
[figwheel-sidecar "0.5.13"]
[com.cemerick/piggieback "0.2.2"]
[reagent "0.6.0"]
[clj-time "0.14.0"]
[hiccup "1.0.5"]
[swiss-arrows "1.0.0" :exclusions [org.clojure]]
[cljs-css-modules "0.2.1"]
[com.cemerick/url "0.1.1"]
]
:plugins [[lein-cljsbuild "1.1.7"]
[lein-figwheel "0.5.14"]
[lein-shell "0.5.0"]
[lein-environ "1.1.0"]
[lein-cooper "1.2.2"]]
:source-paths ["src"]
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}
:cljsbuild {:builds [{:figwheel {:websocket-url "wss://localhost:443/figwheel-ws"}
:id "content-script"
:source-paths ["src"]
:compiler {:asset-path "js"
:output-to "out/main.js"
:output-dir "out"
:optimizations :none
:foreign-libs [{:file "src-compat/fuse.js"
:provides ["js.Fuse"]}]
:externs ["src-compat/externs/fuse.js"]}}]})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment