-
Notifications
You must be signed in to change notification settings - Fork 0
/
events.cljc
161 lines (130 loc) · 4.26 KB
/
events.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
(ns a-frame.events
(:require
[malli.experimental :as mx]
[promisespromises.error :as err]
[a-frame.schema :as schema]
[a-frame.registry :as registry]
[a-frame.std-interceptors :as std-interceptors]
[a-frame.interceptor-chain :as interceptor-chain]
[a-frame.multimethods :as mm]
[taoensso.timbre :refer [warn]]))
;; maps are a nicer representation of events, since
;; their fields have names, which makes paths easier to
;; read
(defmethod mm/event->id :map
[{id schema/a-frame-id
:as _ev}]
id)
;; vectors are the default re-frame representation of events.
;; their fields only have index names, which makes paths
;; hard to read
(defmethod mm/event->id :vector
[[id :as _ev]]
id)
(defn flatten-and-remove-nils
[_id interceptors]
(->> interceptors
flatten
(filterv some?)))
(defn register
"register an interceptor chain for an event - this should terminate
in an interceptor which has a data-reference to the pure event-handler
fn for the event"
[id interceptors]
(registry/register-handler
schema/a-frame-kind-event
id
(flatten-and-remove-nils id interceptors)))
(defn register-pure
"register a pure event-handler fn"
[id pure-handler-fn]
(registry/register-handler
schema/a-frame-kind-event-pure
id
pure-handler-fn))
(defn reg-event-fx
([id handler]
(reg-event-fx id nil handler))
([id
interceptors
handler]
(register-pure id handler)
(register
id
[interceptors
(std-interceptors/fx-handler->interceptor id)])))
(defn reg-event-ctx
([id handler]
(reg-event-ctx id nil handler))
([id
interceptors
handler]
(register-pure id handler)
(register
id
[interceptors
(std-interceptors/ctx-handler->interceptor id)])))
(defn clear-event
([]
(registry/unregister-handler
schema/a-frame-kind-event-pure)
(registry/unregister-handler
schema/a-frame-kind-event))
([id]
(registry/unregister-handler
schema/a-frame-kind-event-pure
id)
(registry/unregister-handler
schema/a-frame-kind-event
id)))
(mx/defn coerce-event-options
"Event|EventOptions -> EventOptions"
[event-or-event-options :- schema/EventOrEventOptions]
(cond
(vector? event-or-event-options)
{schema/a-frame-event event-or-event-options}
(and (map? event-or-event-options)
(contains? event-or-event-options schema/a-frame-id))
{schema/a-frame-event event-or-event-options}
(and (map? event-or-event-options)
(contains? event-or-event-options schema/a-frame-event))
event-or-event-options
:else
(throw (ex-info "malformed event-or-event-options"
{:event-or-event-options event-or-event-options}))))
(defn handle
[{app-ctx schema/a-frame-app-ctx
a-frame-router schema/a-frame-router
global-interceptors schema/a-frame-router-global-interceptors}
event-or-event-options]
;; (prn "HANDLE" event-or-event-options)
(let [{event schema/a-frame-event
init-coeffects schema/a-frame-init-coeffects
modify-interceptor-chain schema/a-frame-event-modify-interceptor-chain
:as _event-options} (coerce-event-options event-or-event-options)
event-id (mm/event->id event)
interceptors (registry/get-handler
schema/a-frame-kind-event
event-id)]
(if (some? interceptors)
(let [interceptors (into (vec global-interceptors) interceptors)
interceptors (if (some? modify-interceptor-chain)
(modify-interceptor-chain interceptors)
interceptors)
init-ctx (-> {schema/a-frame-coeffects init-coeffects
schema/a-frame-effects {}}
(assoc schema/a-frame-app-ctx app-ctx)
;; add the event to any init-ctx coeffects ...
;; so cofx handlers can access it
(assoc-in [schema/a-frame-coeffects
schema/a-frame-coeffect-event]
event))]
(interceptor-chain/execute
app-ctx
a-frame-router
interceptors
init-ctx))
(throw
(err/ex-info
(prn-str ::no-event-handler event)
{:event event})))))