Reintroduce simple dev env

This commit is contained in:
Julien Eluard 2019-03-26 17:10:32 +01:00
parent 7e70b10360
commit 84abea6bec
No known key found for this signature in database
GPG Key ID: 6FD7DB5437FCBEF6
9 changed files with 226 additions and 509 deletions

View File

@ -1,8 +1,11 @@
.PHONY = tests
.PHONY: dev
compile:
clojure -m cljs.main -O advanced -d target -o target/pluto.js -c pluto.js
dev:
clojure -A:dev
install:
lein install

View File

@ -3,15 +3,12 @@
reagent {:mvn/version "0.8.1"}
re-frame {:mvn/version "0.10.6"}}
:paths ["src"]
:aliases {:examples {:extra-paths ["pluto-web/src" "target" "test" "examples/src" "examples/resources"]
:extra-deps {com.bhauman/figwheel-main {:mvn/version "0.2.0"}
com.bhauman/rebel-readline-cljs {:mvn/version "0.1.4"}
binaryage/devtools {:mvn/version "0.9.10"}
cljsjs/codemirror {:mvn/version "5.40.2-1"}
cljsjs/parinfer {:mvn/version "3.11.0-0"}
cljsjs/parinfer-codemirror {:mvn/version "1.4.1-2"}
cljsjs/material-ui {:mvn/version "3.9.1-0"}}
:main-opts ["-m" "figwheel.main" "-b" "examples/dev" "-r"]}
:aliases {:dev {:extra-paths ["dev/src" "dev/resources" "target"]
:extra-deps {status-im/pluto-web {:mvn/version "0.1.0"}
com.bhauman/figwheel-main {:mvn/version "0.2.0"}
com.bhauman/rebel-readline-cljs {:mvn/version "0.1.4"}
binaryage/devtools {:mvn/version "0.9.10"}}
:main-opts ["-m" "figwheel.main" "-b" "dev/core" "-r"]}
:compile {:extra-paths ["test"]
:main-opts ["-e" "(require,'[eftest.runner,:refer,[find-tests,run-tests]]),(run-tests,(find-tests,\"test\"))"]}
:test-clj {:extra-paths ["test"]

4
dev/core.cljs.edn Normal file
View File

@ -0,0 +1,4 @@
^{:watch-dirs ["src" "dev/src"]
:log-level :info}
{:main pluto.dev}

View File

@ -0,0 +1,64 @@
{meta
{:name "Simple Demo"
:description "A simple demo of extension"
:documentation "Nothing. Just see a text with dynamic random color."}
lifecycle
{:on-activation [alert {:value "Activation !!"}]}
hooks/main.demo
{:view [main]}
events/my-alert
(let [{you :arg [value :as all] :value} properties]
[alert {:value "Eh! ${you} ${value}"}])
events/cb
(let [{value :arg v :value} properties
{cond2? :cond?} [random-boolean]]
(if cond?
[alert {:value "Eh bis! ${cond2?}"}]
[alert {:value "Eh ter! ${cond2?}"}])
[identity {:cb [my-alert {:arg value :value ["%% ${v}"]}]}])
views/local-view
{:component-did-mount [alert {:value "Mount!!"}]
:view
(let [{name :name color :color level :level} properties]
(case level
:polite [text {:style {:color color}} "Hello!! ${name}"]
:neutral [text {:style {:color color}} "Hey!! ${name}"]
[text "?? ${name}"]))}
views/local-view2
(let [{name :name color :color level :level} properties]
(case level
:polite [text {:style {:color color}} "Hey!! ${name}"]
"Hello ${name}"))
views/main
(let [{name :name users :users} properties
{cond? :cond?} [random-boolean]]
[view
[text "1"]
[text "2"]
;[local-view {:name "Hey!! ${name}" :color :red :level :polite}]
[button {:on-click [cb {:arg name :value "AA"}]}
"Click!"]
;[button {:on-click [alert {}]}
; "Click2 !"]
[button {:on-click [my-alert {:arg cond? :value ["%% ${name}"]}]}
"Click2 !"]
[button {:on-click [alert {:value "AA"}]}
"Click3 !"]
(if cond?
[text {:style {:color "green"}}
name]
[text {:style {:color "red"}}
name])
[view "Nested for block"]
(for [{nm :nm} users]
[view
(for [{nm2 :nm} users]
[text nm " and " nm2])])])}

View File

@ -0,0 +1,43 @@
<html>
<head>
<style>
main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%
}
#selection {
padding: 10px;
}
#extension {
border: 40px solid #ddd;
border-width: 55px 7px;
border-radius: 40px;
margin: 50px auto;
width: 30vh;
height: 50vh;
overflow: hidden;
}
#extension iframe {
border: 0;
height: 100%;
width: 100%
}
</style>
</head>
<body>
<main>
<div id="extension">
<iframe id="frame" srcdoc="<body><main></main></body>"></iframe>
</div>
<div id="errors"></div>
</main>
</body>
</html>
<script src="cljs-out/dev/core-main.js"></script>
<script>
pluto.dev.bootstrap("url@assets/extensions/demo", document.getElementById("frame").contentWindow.document.body.firstChild, document.getElementById("errors"));
</script>

105
dev/src/pluto/dev.cljs Normal file
View File

@ -0,0 +1,105 @@
(ns ^:figwheel-hooks pluto.dev
(:require pluto.reader.events
pluto.reader.views
pluto.web.events
pluto.web.queries
[pluto.core :as pluto]
[pluto.log :as log]
[pluto.storages :as storages]
[pluto.web.components :as components]
[devtools.core :as devtools]
[reagent.core :as reagent]
[re-frame.core :as re-frame]
[re-frame.registrar :as registrar]
[re-frame.loggers :as re-frame.loggers]))
(enable-console-print!)
(devtools/install!)
(defn ^:before-load before-reload []
(re-frame/clear-subscription-cache!)
(println "Reloading ..."))
(defn ^:after-load after-reload []
(println "Reloading done."))
(def warn (js/console.warn.bind js/console))
(re-frame.loggers/set-loggers!
{:warn (fn [& args]
(cond
(= "re-frame: overwriting" (first args)) nil
:else (apply warn args)))})
(defn- dispatch-events [ctx events]
(doseq [event events]
(if (vector? event)
(re-frame/dispatch event)
(log/fire! ctx ::log/error :event/dispatch event))))
(defn- resolve-query [ctx [id :as data]]
(if (registrar/get-handler :sub id)
(re-frame/subscribe data)
(log/fire! ctx ::log/error :query/resolve data)))
(def ctx
{:env {:id "Extension ID"}
:capacities {:components components/all
:queries {'random-boolean
{:data :random-boolean}
'identity
{:data :extensions/identity
:arguments {:value :map}}}
:hooks {:main
{:properties {:view :view}}}
:events {'identity
{:permissions [:read]
:data :identity
:arguments {:cb :event}}
'alert
{:permissions [:read]
:data :alert
:arguments {:value :string}}}}
:event-fn dispatch-events
:query-fn resolve-query})
(def payload
{:name "Test Extension"
:users [{:nm "Jane"}
{:nm "Sue"}]})
(defn render [h el]
(reagent/render (h {:name "Test Extension"
:users [{:nm "Jane"}
{:nm "Sue"}]}) el))
(defn errors-list [v]
(fn []
[:div
[:div "Errors"]
(into [:ul]
(for [[_ {type :type :as m}] v]
[:li
[:span [:b (str type)] (pr-str (dissoc m :type))]]))]))
(defn render-extension [m el el-errors]
(let [{:keys [data errors]} (pluto/parse ctx m)]
(when errors
(render (errors-list errors) el-errors))
(when-let [f (get-in data [:lifecycle :on-activation])]
(f))
(if-let [view (get-in data [:hooks :main.demo :view])]
(render view el)
(render (fn [] [:div "Oups"]) el))))
(defn read-extension [o el el-errors]
(let [{:keys [data errors]} (pluto/read (:content o))]
(render-extension data el el-errors)))
(defn render-result [{:keys [type value]} el el-errors]
(case type
:error (set! (.-innerHTML el-errors) value)
(read-extension value el el-errors)))
(defn ^:export bootstrap
[s el el-errors]
(storages/fetch s #(render-result % el el-errors)))

View File

@ -1,148 +0,0 @@
#!/bin/bash
set -eof pipefail
trap cleanup EXIT
fatal() {
echo "FATAL: $@" >&2
exit 1
}
warn() {
echo "$@"
}
confirm() {
read -p "$1 (type 'yes' to continue) " r
if [[ $r != yes ]]; then
exit 3
fi
}
load_config() {
[[ -f merge-pr.conf ]] && . merge-pr.conf
: ${OWNER:=status-im}
: ${REPO:=pluto}
: ${REMOTE:=origin}
: ${BRANCH:=master}
}
check_pr_prereq() {
if ! command -v jq >/dev/null; then
fatal "jq(1) is not found, PR cannot be queried."
fi
if ! command -v curl >/dev/null; then
fatal "curl(1) is not found, PR cannot be queried."
fi
}
GH_URL_BASE="https://api.github.com"
get_pr_info() {
echo '[ Reading PR info ]'
local pr=$1
local pr_info_url="$GH_URL_BASE/repos/${OWNER}/${REPO}/pulls/$pr"
set +e
local pr_info
pr_info=$(curl -fsS "$pr_info_url")
if [ $? -ne 0 ]; then
fatal "Unable to get PR info from $pr_info_url"
fi
set -e
if [[ $(echo "$pr_info" | jq -r .state) == closed ]]; then
fatal "PR $pr is closed, will not merge"
fi
if [[ ($(echo "$pr_info" | jq -r .maintainer_can_modify) == true) ||\
($(echo "$pr_info" | jq -r .author_association) == MEMBER) ||\
($(echo "$pr_info" | jq -r .author_association) == OWNER)]]; then
RW_PR_REPO=1
else
warn "PR does not allow 'edits from maintainers', so it will be kept open"
fi
PR_URL=$(echo "$pr_info" | jq -r .head.repo.ssh_url)
PR_REMOTE_NAME=pr-$pr
PR_BRANCH=$(echo "$pr_info" | jq -r .head.ref)
PR_LOCAL_BRANCH=pr-$pr
}
fetch_pr() {
echo '[ Fetching PR ]'
git remote add $PR_REMOTE_NAME $PR_URL
git fetch $PR_REMOTE_NAME $PR_BRANCH
}
refresh_base_branch() {
git fetch $REMOTE $BRANCH
}
rebase_pr() {
git checkout -B $PR_LOCAL_BRANCH $PR_REMOTE_NAME/$PR_BRANCH
git rebase $BRANCH
}
check_is_pr_single_commit() {
if [[ $(git rev-list $BRANCH..$PR_LOCAL_BRANCH | wc -l) -ne 1 ]] ;then
confirm "PR has multiple commits, continue merging without squashing them?"
fi
}
confirm_pr() {
git log -p $BRANCH..$PR_LOCAL_BRANCH
confirm "Do you like this PR?"
}
sign_pr() {
git commit --amend --gpg-sign --signoff
}
verify_pr() {
git show --show-signature $PR_LOCAL_BRANCH
confirm "Is the signature on the commit correct?"
}
merge_pr() {
# If PR is specified and can be pushed into, do it to mark PR as closed
if [[ -n $RW_PR_REPO ]]; then
git push -f $PR_REMOTE_NAME $PR_LOCAL_BRANCH:$PR_BRANCH
fi
git checkout $BRANCH
git merge --ff-only $PR_LOCAL_BRANCH
git push $REMOTE $BRANCH
}
cleanup() {
if [[ -z $DEBUG ]]; then
git checkout -q $BRANCH
git branch -q -D $PR_LOCAL_BRANCH 2>/dev/null || :
git remote remove $PR_REMOTE_NAME 2>/dev/null || :
fi
}
run() {
if [[ $# -ne 1 ]] ; then
cat <<EOF >&2
Requirements:
jq
curl
Usage:
./merge-pr.sh <PR-ID>
EOF
exit 2
fi
load_config
check_pr_prereq
get_pr_info "$@"
cleanup
fetch_pr
refresh_base_branch
rebase_pr
check_is_pr_single_commit
confirm_pr
sign_pr
verify_pr
merge_pr
}
run "$@"

View File

@ -1,7 +0,0 @@
clojure -m cljs.main -O advanced -d website/static/js -o website/static/js/pluto.js -c pluto.js
cd website
GIT_USER=jeluard\
CURRENT_BRANCH=#2 \
USE_SSH=true \
yarn run publish-gh-pages
cd ..

View File

@ -1,344 +0,0 @@
(ns pluto.js
"Exports reader function to JavaScript hosts.
Type conversion is properly handled."
(:require [pluto.core :as pluto]))
(defn ^:export to-clj [o]
(js->clj o))
(defn ^:export from-clj [o]
(clj->js o))
(defn component [])
;; TODO find a syntax so that :event can define associated types they will be injected
(def ctx
{:capacities {:components {'view {:data component}
'scroll-view {:data component :properties {:keyboard-should-persist-taps :keyword :content-container-style :map}}
'keyboard-avoiding-view {:data component}
'text {:data component}
'touchable-opacity {:data component :properties {:on-press :event}}
'icon {:data component :properties {:key :keyword :color :any}}
'image {:data component :properties {:uri :string :source :string}}
'input {:data component :properties {:on-change :event :placeholder :string :keyboard-type :keyword :change-delay? :number :placeholder-text-color :any :selection-color :any}}
'button {:data component :properties {:enabled :boolean :disabled :boolean :on-click :event}}
'link {:data component :properties {:uri :string}}
'list {:data component :properties {:data :vector :item-view :view :key? :keyword}}
'checkbox {:data component :properties {:on-change :event :checked :boolean}}
'activity-indicator {:data component :properties {:animating :boolean :color :string :size :keyword :hides-when-stopped :boolean}}
'picker {:data component :properties {:on-change :event :selected :string :enabled :boolean :data :vector}}
'nft-token-viewer {:data component :properties {:token :string}}
'transaction-status {:data component :properties {:outgoing :string :tx-hash :string}}
'map {:data component
:properties {:marker {:lng :number
:lat :number
:boundingbox {:lng1 :number
:lat1 :number
:lng2 :number
:lat2 :number}}
:fly? :boolean
:interactive? :boolean
:on-change :event}}
'map-link {:data component :properties {:text :string :lng :any :lat :any}}}
:queries {'identity {:data :extensions/identity :arguments {:value :map}}
'store/get {:data :store/get :arguments {:key :string}}
'contacts/all {:data :extensions.contacts/all}
'wallet/collectibles {:data :get-collectible-token :arguments {:token :string :symbol :string}}
'wallet/balance {:data :extensions.wallet/balance :arguments {:token :string}}
'wallet/token {:data :extensions.wallet/token :arguments {:token :string :amount? :number :amount-in-wei? :number}}
'wallet/tokens {:data :extensions.wallet/tokens :arguments {:filter? :vector :visible? :boolean}}}
:events {'identity
{:permissions [:read]
:data :extensions/identity-event
:arguments {:cb :event}}
'alert
{:permissions [:read]
:data :alert
:arguments {:value :string}}
'selection-screen
{:permissions [:read]
:data :extensions/show-selection-screen
:arguments {:items :vector :on-select :event :render :view :title :string :extractor-key :keyword}}
'chat.command/set-parameter
{:permissions [:read]
:data :extensions.chat.command/set-parameter
:arguments {:value :any}}
'chat.command/set-custom-parameter
{:permissions [:read]
:data :extensions.chat.command/set-custom-parameter
:arguments {:key :keyword :value :any}}
'chat.command/set-parameter-with-custom-params
{:permissions [:read]
:data :extensions.chat.command/set-parameter-with-custom-params
:arguments {:value :string :params :map}}
'chat.command/send-plain-text-message
{:permissions [:read]
:data :extensions.chat.command/send-plain-text-message
:arguments {:value :string}}
'chat.command/send-message
{:permissions [:read]
:data :extensions.chat.command/send-message
:arguments {:params :map}}
'log
{:permissions [:read]
:data :log
:arguments {:value :string}}
'arithmetic
{:permissions [:read]
:data :extensions/arithmetic
:arguments {:values :vector
:operation {:one-of #{:plus :minus :times :divide}}
:on-result :event}}
'schedule/start
{:permissions [:read]
:data :extensions/schedule-start
:arguments {:interval :number
:on-created :event
:on-result :event}}
'schedule/cancel
{:permissions [:read]
:data :extensions/schedule-cancel
:arguments {:value :number}}
'json/parse
{:permissions [:read]
:data :extensions/json-parse
:arguments {:value :string
:on-result :event}}
'json/stringify
{:permissions [:read]
:data :extensions/json-stringify
:arguments {:value :string
:on-result :event}}
'store/put
{:permissions [:read]
:data :store/put
:arguments {:key :string :value :any}}
'store/puts
{:permissions [:read]
:data :store/puts
:arguments {:value :vector}}
'store/append
{:permissions [:read]
:data :store/append
:arguments {:key :string :value :any}}
'store/clear
{:permissions [:read]
:data :store/clear
:arguments {:key :string}}
'store/clear-all
{:permissions [:read]
:data :store/clear-all}
'http/get
{:permissions [:read]
:data :http/get
:arguments {:url :string
:timeout? :string
:on-success :event
:on-failure? :event}}
'http/post
{:permissions [:read]
:data :http/post
:arguments {:url :string
:body :string
:timeout? :string
:on-success :event
:on-failure? :event}}
'ipfs/cat
{:permissions [:read]
:data :ipfs/cat
:arguments {:hash :string
:on-success :event
:on-failure? :event}}
'ipfs/add
{:permissions [:read]
:data :ipfs/add
:arguments {:value :string
:on-success :event
:on-failure? :event}}
'ethereum/transaction-receipt
{:permissions [:read]
:data :extensions/ethereum-transaction-receipt
:arguments {:value :string
:on-success :event
:on-failure? :event}}
'ethereum/await-transaction-receipt
{:permissions [:read]
:data :extensions/ethereum-await-transaction-receipt
:arguments {:value :string
:interval :number
:on-success :event
:on-failure? :event}}
'ethereum/sign
{:permissions [:read]
:data :extensions/ethereum-sign
:arguments {:message? :string
:data? :string
:on-success :event
:on-failure? :event}}
'ethereum/create-address
{:permissions [:read]
:data :extensions/ethereum-create-address
:arguments {:on-result :event}}
'ethereum/send-transaction
{:permissions [:read]
:data :extensions/ethereum-send-transaction
:arguments {:to :string
:gas? :string
:gas-price? :string
:value? :string
:method? :string
:params? :vector
:nonce? :string
:on-success :event
:on-failure? :event}}
'ethereum/logs
{:permissions [:read]
:data :extensions/ethereum-logs
:arguments {:from? :string
:to? :string
:address? :vector
:topics? :vector
:block-hash? :string
:on-success :event
:on-failure? :event}}
'ethereum/create-filter
{:permissions [:read]
:data :extensions/ethereum-create-filter
:arguments {:type {:one-of #{:filter :block :pending-transaction}}
:from? :string
:to? :string
:address? :vector
:topics? :vector
:block-hash? :string
:on-success :event
:on-failure? :event}}
'ethereum/logs-changes
{:permissions [:read]
:data :extensions/ethereum-logs-changes
:arguments {:id :string}}
'ethereum/cancel-filter
{:permissions [:read]
:data :extensions/ethereum-cancel-filter
:arguments {:id :string}}
'ethereum.ens/resolve
{:permissions [:read]
:data :extensions/ethereum-resolve-ens
:arguments {:name :string
:on-success :event
:on-failure? :event}}
'ethereum.erc20/total-supply
{:permissions [:read]
:data :extensions/ethereum-erc20-total-supply
:arguments {:contract :string
:on-success :event
:on-failure? :event}}
'ethereum.erc20/balance-of
{:permissions [:read]
:data :extensions/ethereum-erc20-balance-of
:arguments {:contract :string
:token-owner :string
:on-success :event
:on-failure? :event}}
'ethereum.erc20/transfer
{:permissions [:read]
:data :extensions/ethereum-erc20-transfer
:arguments {:contract :string
:to :string
:value :number
:on-success :event
:on-failure? :event}}
'ethereum.erc20/transfer-from
{:permissions [:read]
:data :extensions/ethereum-erc20-transfer-from
:arguments {:contract :string
:from :string
:to :string
:value :number
:on-success :event
:on-failure? :event}}
'ethereum.erc20/approve
{:permissions [:read]
:data :extensions/ethereum-erc20-approve
:arguments {:contract :string
:spender :string
:value :number
:on-success :event
:on-failure? :event}}
'ethereum.erc20/allowance
{:permissions [:read]
:data :extensions/ethereum-erc20-allowance
:arguments {:contract :string
:token-owner :string
:spender :string
:on-success :event
:on-failure? :event}}
'ethereum.erc721/owner-of
{:permissions [:read]
:data :extensions/ethereum-erc721-owner-of
:arguments {:contract :string
:token-id :string
:on-success :event
:on-failure? :event}}
'ethereum.erc721/is-approved-for-all
{:permissions [:read]
:data :extensions/ethereum-erc721-is-approved-for-all
:arguments {:contract :string
:owner :string
:operator :string
:on-success :event
:on-failure? :event}}
'ethereum.erc721/get-approved
{:permissions [:read]
:data :extensions/ethereum-erc721-get-approved
:arguments {:contract :string
:token-id :string
:on-success :event
:on-failure? :event}}
'ethereum.erc721/set-approval-for-all
{:permissions [:read]
:data :extensions/ethereum-erc721-set-approval-for-all
:arguments {:contract :string
:operator :string
:approved :boolean
:on-success :event
:on-failure? :event}}
'ethereum.erc721/safe-transfer-from
{:permissions [:read]
:data :extensions/ethereum-erc721-safe-transfer-from
:arguments {:contract :string
:from :string
:to :string
:token-id :string
:data? :string
:on-success :event
:on-failure? :event}}
'ethereum/call
{:permissions [:read]
:data :extensions/ethereum-call
:arguments {:to :string
:method :string
:params? :vector
:outputs? :vector
:on-success :event
:on-failure? :event}}}
:hooks {:wallet.settings {:properties {:label :string
:view :view
:on-click? :event}}
:chat.command {:properties {:description? :string
:scope #{:personal-chats :public-chats :group-chats}
:short-preview :view
:preview :view
:parameters? [{:id :keyword
:type {:one-of #{:text :phone :password :number}}
:placeholder :string
:suggestions? :view}]
:on-send? :event
:on-send-sync? :event
:on-receive? :event}}}}})
(defn ^:export read [s]
(pluto/read s))
(defn ^:export parse [m]
(pluto/parse ctx (:data m)))