[Fixes #109] Allow to use queries from within local events

Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
Julien Eluard
2019-01-31 14:25:15 +01:00
parent ccc9f7aa2a
commit 779743e2d0
4 changed files with 55 additions and 25 deletions
@@ -11,8 +11,9 @@
[alert {:value "Eh! ${you} ${value}"}])
events/cb
(let [{value :arg cond? :cond? v :value} properties]
[alert {:value "Eh bis! ${you} ${value}"}]
(let [{value :arg v :value} properties
{cond2? :cond?} [random-boolean]]
[alert {:value "Eh bis! ${cond2?}"}]
[identity {:cb [my-alert {:arg value :value ["%% ${v}"]}]}])
views/local-view
@@ -22,7 +23,7 @@
(case level
:polite [text {:style {:color color}} "Hello!! ${name}"]
:neutral [text {:style {:color color}} "Hey!! ${name}"]
"?? ${name}"))}
[text "?? ${name}"]))}
views/local-view2
(let [{name :name color :color level :level} properties]
@@ -35,7 +36,7 @@
{cond? :cond?} [random-boolean]]
[view
[local-view {:name "Hey!! ${name}" :color :red :level :polite}]
[button {:on-click [cb {:arg name :cond? cond? :value "AA"}]}
[button {:on-click [cb {:arg name :value "AA"}]}
"Click!"]
;[button {:on-click [alert {}]}
; "Click2 !"]
+6 -1
View File
@@ -9,6 +9,7 @@
[reagent.core :as reagent]
[reagent.dom :as dom]
[re-frame.core :as re-frame]
[re-frame.registrar :as registrar]
[re-frame.loggers :as re-frame.loggers]))
(def warn (js/console.warn.bind js/console))
@@ -36,11 +37,15 @@
(doseq [event events]
(re-frame/dispatch event)))
(defn resolve-query [[id :as data]]
(when (registrar/get-handler :sub id)
(re-frame/subscribe data)))
(defn parse [m]
(pluto/parse {:env {:id "Extension ID"
:logger nil
:event-fn dispatch-events
:query-fn nil}
:query-fn resolve-query}
:capacities {:components components/all
:queries {'random-boolean
{:data :random-boolean}
+8 -7
View File
@@ -1,11 +1,12 @@
(ns pluto.reader.blocks
(:require [clojure.walk :as walk]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
(:require [clojure.walk :as walk]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[pluto.reader.destructuring :as destructuring]
[pluto.reader.errors :as errors]
[pluto.reader.types :as types]
[pluto.utils :as utils]))
[pluto.reader.errors :as errors]
[pluto.reader.types :as types]
[pluto.utils :as utils]
[pluto.reader.reference :as reference]))
(defmulti parse
"Parse a block element. Return hiccup data."
@@ -82,7 +83,7 @@
(or (utils/primitive? v) (map? v)))
(defn valid-bindings? [k v]
(and (or (symbol? k) (map? k))
(and (or (symbol? k) (map? k) (vector? k))
(or (symbol? v) (static-value? v) (query? v))))
(defn- valid-bindings-form? [bindings]
+36 -13
View File
@@ -31,7 +31,7 @@
(defn- dispatch-events
"Dispatches an event using ctx"
[ctx events]
(let [f (get-in ctx [:env :event-fn])]
(when-let [f (get-in ctx [:env :event-fn])]
(if (seq events)
(f events)
(println "Empty event dispatched"))))
@@ -46,28 +46,41 @@
:inline inline
:errors (concat errors errors1)}))
(defn- event-dispatcher [ctx ext refs arguments bindings]
(defn- resolve-query
"Resolve a query using ctx"
[ctx ext query]
(let [{data :data} (types/resolve ctx ext :query query)]
(when-let [f (get-in ctx [:env :query-fn])]
(when-let [signal (f data)]
@signal))))
(defn merge-resolved-query [ctx ext m {:keys [value bindings]}]
(cond
(map? bindings)
(merge m (:data (destructuring/destructure bindings (merge m (resolve-query ctx ext value)))))
(symbol? bindings)
(assoc m bindings (resolve-query ctx ext value))))
(defn- event-dispatcher
"Returns a function of 2 arguments "
[ctx ext refs arguments {:keys [queries properties]}]
(let [ref (map #(create-ref ctx ext %) refs)]
(errors/merge-errors
{:data
(with-meta
(fn [dynamic env]
;; TODO env contains data that shouldn't be there
;; env is the dispatched argument. Used as default but is overridden by the local arguments
;; Perform destructuring based on dynamic and static arguments
;; Then resolve recursive properties in the aggregated env
;; Final map contains inline arguments resolved
(let [{:keys [data errors]} (destructuring/destructure bindings (merge dynamic arguments))]
(let [{:keys [data errors]} (destructuring/destructure properties (merge dynamic arguments))]
;; TODO handle errors
(let [env' (resolve-env env (merge env data))]
(let [env' (resolve-env env (merge env (reduce #(merge-resolved-query ctx ext %1 %2) data queries)))]
(dispatch-events ctx (map #(create-event ctx env' %) ref)))))
{:event true})}
nil)))
(defn- bindings
"Returns the left-hand part of a properties bindings"
[data]
(first (second data)))
(defn- references
"Returns a list of local event references"
[data]
@@ -80,20 +93,30 @@
(let [[form bindings] data]
(and (< 2 (count data))
(= 'let form)
(= 2 (count bindings))
(even? (count bindings))
(map? (first bindings))
(= 'properties (second bindings))
(every? reference/reference? (references data))))))
(defn- merge-pair [m [k v]]
(cond
(= v 'properties) (assoc m :properties k)
:else (update m :queries concat [{:value v :bindings k}])))
(defn- parse-let-bindings [bindings]
(let [pairs (partition 2 bindings)]
(reduce merge-pair
{}
pairs)))
(defn parse
"Parses local references defining let blocks"
[ctx ext local arguments]
[ctx ext [_ let-bindings :as local] arguments]
(if (local-event? local)
(event-dispatcher ctx ext (references local) arguments (bindings local))
(event-dispatcher ctx ext (references local) arguments (parse-let-bindings let-bindings))
{:errors [(errors/error ::errors/invalid-local-event local)]}))
(defmethod types/resolve :event [ctx ext _ [_ arguments :as value]]
;; TODO if kw, comes from reference, then resolve as a fn
(let [{:keys [data errors] :as m} (reference/resolve ctx ext :event value)]
;; resolve returns either data or errors
(if data