Improve Hook protocol

This commit is contained in:
jeluard 2018-10-02 09:14:19 +02:00
parent 2ce136b001
commit bd3d36db87
11 changed files with 44 additions and 67 deletions

View File

@ -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}}}

View File

@ -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}}}

View File

@ -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]}])]

View File

@ -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]

View File

@ -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."))

View File

@ -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)

View File

@ -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])]

View File

@ -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"))))))))

View File

@ -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 {} ""]

View File

@ -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}})

View File

@ -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"))))))