mirror of https://github.com/status-im/pluto.git
Improve Hook protocol
This commit is contained in:
parent
2ce136b001
commit
bd3d36db87
|
@ -15,11 +15,6 @@ by the app-hook and extension must correctly refer to event from capacities map.
|
|||
### Example
|
||||
|
||||
```clojure
|
||||
;; App hook code in host application
|
||||
(reify host/AppHook
|
||||
(id [_] :wallet-asset)
|
||||
(properties [_] {:on-click :event}))
|
||||
|
||||
;; Capacities map in the host application
|
||||
{:capacities {:events #{:prefill-asset}}}
|
||||
|
||||
|
|
|
@ -15,11 +15,6 @@ by the app-hook and extension must correctly refer to query from capacities map.
|
|||
### Example
|
||||
|
||||
```clojure
|
||||
;; App hook code in host application
|
||||
(reify host/AppHook
|
||||
(id [_] :wallet-asset)
|
||||
(properties [_] {:able-to-send :query}))
|
||||
|
||||
;; Capacities map in the host application
|
||||
{:capacities {:queries #{:network-up}}}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
[ethereum.logs {:address "0xfa28ec7198028438514b49a3cf353bca5541ce1d"
|
||||
:topics ["PeepEth()"]
|
||||
:inputs [{:name :hash :type :string}] ;; Allows to decode transaction data
|
||||
:on-log [@events/fetch-ipfs]}] ;; A map of decoded data will be injected
|
||||
:on-log [events/fetch-ipfs]}] ;; A map of decoded data will be injected
|
||||
|
||||
events/fetch-ipfs
|
||||
(let [{hash :hash} properties]
|
||||
|
@ -38,8 +38,8 @@
|
|||
[screen {:style screen}
|
||||
[toolbar {}
|
||||
[text {}
|
||||
[@i18n/title {}]]]
|
||||
(let [posts @queries/all-posts]
|
||||
[i18n/title {}]]]
|
||||
(let [posts queries/all-posts]
|
||||
[list {:data posts
|
||||
:template [post]}])]
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
(ns pluto.examples
|
||||
(:require [clojure.string :as string]
|
||||
(:require [clojure.string :as string]
|
||||
[pluto.components.html :as html]
|
||||
[pluto.js :as js]
|
||||
[pluto.reader :as reader]
|
||||
[pluto.host :as host]
|
||||
[pluto.storages :as storages]
|
||||
[reagent.core :as reagent]
|
||||
[reagent.dom :as dom]
|
||||
[re-frame.core :as re-frame]
|
||||
[re-frame.loggers :as re-frame.loggers]))
|
||||
[pluto.js :as js]
|
||||
[pluto.reader :as reader]
|
||||
[pluto.reader.hooks :as hooks]
|
||||
[pluto.storages :as storages]
|
||||
[reagent.core :as reagent]
|
||||
[reagent.dom :as dom]
|
||||
[re-frame.core :as re-frame]
|
||||
[re-frame.loggers :as re-frame.loggers]))
|
||||
|
||||
(def warn (js/console.warn.bind js/console))
|
||||
(re-frame.loggers/set-loggers!
|
||||
|
@ -41,16 +41,14 @@
|
|||
[:span [:b (str type)] (pr-str (dissoc m :type))]]))]))
|
||||
|
||||
(def hook
|
||||
(reify host/AppHook
|
||||
(id [_] :main)
|
||||
(properties [_] {:view :view})
|
||||
(reify hooks/Hook
|
||||
(hook-in [_ id {:keys [description scope parameters preview short-preview]} cofx])
|
||||
(unhook [_ id {:keys [scope]} {:keys [db] :as cofx}])))
|
||||
|
||||
(defn parse [m]
|
||||
(reader/parse {:capacities {:components html/components
|
||||
:queries #{:random-boolean}
|
||||
:hooks {:main hook}}}
|
||||
:hooks {:main {:hook hook :properties {:view :view}}}}}
|
||||
m))
|
||||
|
||||
(defn render-extension [m el el-errors]
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
(ns pluto.host)
|
||||
|
||||
(defprotocol AppHook
|
||||
"Protocol which every extension point in application should implement."
|
||||
(id [this] "Keyword representing id of an extension point.")
|
||||
(properties [this] "Map of properties used to validate extensions leveraging the hook.")
|
||||
(hook-in [this id properties cofx] "Pluto will call this method with hook id and parsed hook data to hook it into host app.")
|
||||
(unhook [this id properties cofx] "Pluto will call this method with hook id to remove extension hook from app."))
|
|
@ -1,12 +1,16 @@
|
|||
(ns pluto.reader.hooks
|
||||
(:require [clojure.string :as string]
|
||||
[clojure.set :as set]
|
||||
[pluto.host :as host]
|
||||
[pluto.reader.blocks :as blocks]
|
||||
[pluto.reader.errors :as errors]
|
||||
[pluto.reader.reference :as reference]
|
||||
[pluto.reader.views :as views]))
|
||||
|
||||
(defprotocol Hook
|
||||
"Encapsulate hook lifecycle."
|
||||
(hook-in [this id properties cofx] "Hook it into host app.")
|
||||
(unhook [this id properties cofx] "Remove extension hook from app."))
|
||||
|
||||
(defmulti resolve-property
|
||||
(fn [{:keys [type]} _ _ _]
|
||||
(cond
|
||||
|
@ -123,7 +127,7 @@
|
|||
{} props))
|
||||
|
||||
(defn parse-hook [hook v opts m]
|
||||
(parse-properties (map->properties (host/properties hook)) v opts m))
|
||||
(parse-properties (map->properties (:properties hook)) v opts m))
|
||||
|
||||
(defn parse [opts m]
|
||||
(reduce-kv (fn [acc hook-key data]
|
||||
|
@ -131,7 +135,6 @@
|
|||
hook-root (root-id hook-key)
|
||||
hook (get-in opts [:capacities :hooks hook-root])
|
||||
{:keys [data errors]} (parse-hook hook data opts m)]
|
||||
|
||||
(errors/merge-errors
|
||||
(-> acc
|
||||
(assoc-in [:data :hooks hook-root hook-id :parsed] data)
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
(ns pluto.registry
|
||||
(:refer-clojure :exclude [remove])
|
||||
(:require [clojure.spec.alpha :as spec]
|
||||
[clojure.set :as set]
|
||||
[clojure.string :as string]
|
||||
[pluto.host :as host]
|
||||
[pluto.reader.hooks :as hooks]
|
||||
[pluto.utils :as utils]))
|
||||
|
||||
(spec/def :registry/registry (spec/map-of string? :registry/extension))
|
||||
|
@ -13,6 +14,8 @@
|
|||
|
||||
(spec/def :registry/extension (spec/keys :req-un [:registry/state :registry/data]))
|
||||
|
||||
;; TODO move to a protocol and provide default re-frame implementation
|
||||
|
||||
(defn add
|
||||
"Takes parsed data and coeffects map, adds extension to registry with `:inactive` initial state."
|
||||
[parsed-data {:keys [db]}]
|
||||
|
@ -31,8 +34,8 @@
|
|||
(mapcat (fn [[app-hook extension-hooks]]
|
||||
(map (fn [[hook-id {:keys [hook-ref parsed]}]]
|
||||
(if (= :active new-state)
|
||||
(partial host/hook-in hook-ref hook-id parsed)
|
||||
(partial host/unhook hook-ref hook-id parsed)))
|
||||
(partial hooks/hook-in (:hook hook-ref) hook-id parsed)
|
||||
(partial hooks/unhook (:hook hook-ref) hook-id parsed)))
|
||||
extension-hooks))
|
||||
(:hooks data))))))
|
||||
|
||||
|
@ -44,7 +47,7 @@
|
|||
"Takes extension key and de-activates it by turning off all hooks. Extension state is switched to inactive."
|
||||
(partial switch :inactive))
|
||||
|
||||
(defn delete
|
||||
(defn remove
|
||||
"Removes extension from extension map altogether, if the extension is in active state, deactives it first."
|
||||
[extension-key {:keys [db] :as cofx}]
|
||||
(when-let [{:keys [state]} (get-in db [:registry extension-key])]
|
||||
|
|
|
@ -5,5 +5,6 @@
|
|||
#?(:cljs [pluto.utils-test :include-macros true :refer [slurp]])))
|
||||
|
||||
(deftest examples
|
||||
(is (empty? (:errors (reader/parse {} (:data (reader/read (slurp "figwheel/resources/public/assets/extensions/demo/extension.edn"))))))))
|
||||
(is (empty? (:errors (reader/parse {:capacities {:hooks {:main {:properties {}}}}}
|
||||
(:data (reader/read (slurp "figwheel/resources/public/assets/extensions/demo/extension.edn"))))))))
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
(ns pluto.reader.hooks-test
|
||||
(:require [clojure.test :refer [is deftest testing]]
|
||||
[pluto.host :as host]
|
||||
[pluto.reader.blocks :as blocks]
|
||||
[pluto.reader.errors :as errors]
|
||||
[pluto.reader.hooks :as hooks]))
|
||||
|
@ -111,11 +110,7 @@
|
|||
(hooks/resolve-property {:name :keyword :type {:one-of #{:one :two :three}}} {:keyword :for} {} {})))))
|
||||
|
||||
(defn- hooks [properties]
|
||||
{:main (reify host/AppHook
|
||||
(id [_] :main)
|
||||
(properties [_] properties)
|
||||
(hook-in [_ _ _ _])
|
||||
(unhook [_ _ _ _]))})
|
||||
{:main {:properties properties}})
|
||||
|
||||
(deftest parse
|
||||
(is (= [:text {} ""]
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
(ns pluto.reader-test
|
||||
(:refer-clojure :exclude [read])
|
||||
(:require [clojure.test :refer [is deftest]]
|
||||
[pluto.host :as host]
|
||||
[pluto.reader :as reader]
|
||||
(:require [clojure.test :refer [is deftest]]
|
||||
[pluto.reader :as reader]
|
||||
[pluto.reader.errors :as errors]
|
||||
[pluto.reader.blocks :as blocks]))
|
||||
|
||||
|
@ -62,11 +61,7 @@
|
|||
(is (= [{::errors/type ::errors/invalid-key ::errors/value 'unknown/unknown}]
|
||||
(reader/validate {} (extension {'unknown/unknown {}})))))
|
||||
|
||||
(def default-hooks {:main (reify host/AppHook
|
||||
(id [_] :main)
|
||||
(properties [_] {:view :view})
|
||||
(hook-in [_ _ _ _])
|
||||
(unhook [_ _ _ _]))})
|
||||
(def default-hooks {:main {:properties {:view :view}}})
|
||||
(def default-components {'text :text 'view :view})
|
||||
(def default-capacities {:capacities {:hooks default-hooks :components default-components}})
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
(ns pluto.registry-test
|
||||
(:refer-clojure :exclude [read])
|
||||
(:require [clojure.test :refer [is deftest testing]]
|
||||
[pluto.utils :as utils]
|
||||
[pluto.host :as host]
|
||||
[pluto.registry :as registry]))
|
||||
(:require [clojure.test :refer [is deftest testing]]
|
||||
[pluto.reader.hooks :as hooks]
|
||||
[pluto.registry :as registry]
|
||||
[pluto.utils :as utils]))
|
||||
|
||||
(def parsed-data {'meta {:name "test"}
|
||||
:hooks {:main {:a {:parsed {:name "tester"}
|
||||
:hook-ref (reify host/AppHook
|
||||
(id [_] :main)
|
||||
(properties [_] {:name :string})
|
||||
:hook-ref {:properties {:name :string}
|
||||
:hook
|
||||
(reify hooks/Hook
|
||||
(hook-in [_ id properties {:keys [db]}]
|
||||
{:db (assoc-in db [:main id] properties)})
|
||||
(unhook [_ id _ {:keys [db]}]
|
||||
{:db (update db :main dissoc id)}))}}}})
|
||||
{:db (update db :main dissoc id)}))}}}}})
|
||||
|
||||
(deftest add-test
|
||||
(testing "Correctly adds extension"
|
||||
|
@ -55,10 +55,10 @@
|
|||
|
||||
(deftest remove-test
|
||||
(testing "When extension is not present, do nothing"
|
||||
(is (= nil (registry/delete "test" {:db {}}))))
|
||||
(is (= nil (registry/remove "test" {:db {}}))))
|
||||
(testing "When extension is present and inactive, remove it"
|
||||
(is (= {:db {:registry {}}}
|
||||
(registry/delete "test"
|
||||
(registry/remove "test"
|
||||
{:db {:registry {"test" {:state :inactive}}}}))))
|
||||
(testing "When extension is present and active, remove it + produce unhook effects"
|
||||
(is (= {:db {:registry {}
|
||||
|
@ -66,4 +66,4 @@
|
|||
(utils/merge-fx {:db {}}
|
||||
(partial registry/add parsed-data)
|
||||
(partial registry/activate "test")
|
||||
(partial registry/delete "test"))))))
|
||||
(partial registry/remove "test"))))))
|
||||
|
|
Loading…
Reference in New Issue