-
Notifications
You must be signed in to change notification settings - Fork 27
/
core.cljc
161 lines (127 loc) · 6.06 KB
/
core.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 kee-frame.core
(:require [kee-frame.legacy :as legacy]
[kee-frame.state :as state]
[kee-frame.router :as router]
[re-frame.core :as rf :refer [console]]
[kee-frame.log :as log]
[kee-frame.spec :as spec]
[re-frame.interop :as interop]
[clojure.spec.alpha :as s]
[expound.alpha :as e]))
(def valid-option-key? #{:router :hash-routing? :routes :process-route :debug? :debug-config
:chain-links :app-db-spec :root-component :initial-db :log-spec-error
:screen :scroll :route-change-event :not-found :log :global-interceptors})
(defn extra-options
"Complete listing of invalid options sent to the `start!` function."
[options]
(->> options
(filter (fn [[k]] (not (valid-option-key? k))))
(into {})))
(defn start!
"Starts your client application with the specified `options`.
This function is intentionally forgiving in certain ways:
- You can call it as often as you want. Figwheel should call it on each code change
- You can omit the `options` altogether. kee-frame chooses sensible defaults for you and leads the way.
Usage:
```
(k/start! {:debug? true
:routes my-reitit-routes
:hash-routing? true
:initial-db {:some-property \"default value\"}
:root-component [my-reagent-root-component]
:app-db-spec :spec/my-db-spec})
```"
[options]
(log/init! (:log options))
(when-not (s/valid? ::spec/start-options options)
(e/expound ::spec/start-options options)
(throw (ex-info "Invalid options" (s/explain-data ::spec/start-options options))))
(let [extras (extra-options options)]
(when (seq extras)
(throw (ex-info (str "Uknown startup options. Valid keys are " valid-option-key?) extras))))
(router/start! options))
(def reg-chain legacy/reg-chain)
;(def reg-chain* chain/reg-chain*)
(def reg-chain-named legacy/reg-chain-named)
;(def reg-chain-named* chain/reg-chain-named*)
(def reg-event-fx legacy/reg-event-fx)
(def reg-event-db legacy/reg-event-db)
(defn -replace-controller
[controllers controller]
(reduce
(fn [ret existing-controller]
(if (= (:id controller)
(:id existing-controller))
(conj ret controller)
(conj ret existing-controller)))
interop/empty-queue
controllers))
(defn reg-controller
"Put a controller config map into the global controller registry.
Parameters:
`id`: Must be unique in controllere registry. Will appear in logs.
`controller`: A map with the following keys:
- `:params`: A function that receives the route data and returns the part that should be sent to the `start` function. A nil
return means that the controller should not run for this route.
- `:start`: A function or an event vector. Called when `params` returns a non-nil value different from the previous
invocation. The function receives whatever non-nil value that was returned from `params`,
and returns a re-frame event vector. If the function does nothing but returning the vector, the surrounding function
can be omitted.
- `:stop`: Optional. A function or an event vector. Called when previous invocation of `params` returned non-nil and the
current invocation returned nil. If the function does nothing but returning the vector, the surrounding function
can be omitted."
[id controller]
(let [controller (assoc controller :id id)]
(when-not (s/valid? ::spec/controller controller)
(e/expound ::spec/controller controller)
(throw (ex-info "Invalid controller" (s/explain-data ::spec/controller controller))))
(swap! state/controllers (fn [controllers]
(let [ids (map :id controllers)]
(if (some #{id} ids)
;; If the id already exists we replace it in-place to maintain the ordering of
;; controllers esp during hot-code reloading in development.
(-replace-controller controllers controller)
(conj controllers controller)))))))
(defn path-for
"Make a uri from route data. Useful for avoiding hard coded links in your app.
Parameters:
`handler`: The reitit handler from route data
`params`: Reitit route params for the requested route
Usage: `[:a {:href (k/path-for [:orders :sort-by :date]} \"Orders sorted by date\"]`"
[handler & params]
(apply router/url handler params))
(defn case-route
"Reagent component that renders different components for different routes.
Semantics similar to clojure.core/case
You can include a single default component at the end that serves as the default view
Parameters:
`f`: A function that receives the route data on every route change, and returns the value to dispatch on.
`pairs`: A pair consists of the dispatch value and the reagent component to dispatch to. An optional single default
component can be added at the end.
Returns the first component with a matching dispatch value.
Usage:
```
[k/switch-route (fn [route] (:handler route))
:index [:div \"This is index page\"]
:about [:div \"This is the about page\"]
[:div \"Probably also the index page\"]]
```"
[f & pairs]
(apply router/case-route f pairs))
(defn switch-route
"DEPRECATED in favor of case-route
Reagent component that renders different components for different routes.
You might need to include a case for `nil`, since there are no route data before the first navigation.
Parameters:
`f`: A function that receives the route data on every route change, and returns the value to dispatch on.
`pairs`: A pair consists of the dispatch value and the reagent component to dispatch to.
Returns the first component with a matching dispatch value.
Usage:
```
[k/switch-route (fn [route] (:handler route))
:index [:div \"This is index page\"]
:about [:div \"This is the about page\"]
nil [:div \"Probably also the index page\"]]
```"
[f & pairs]
(apply router/switch-route f pairs))