-
Notifications
You must be signed in to change notification settings - Fork 23
/
strategies.clj
59 lines (52 loc) · 2.55 KB
/
strategies.clj
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
(ns optimus.strategies
(:require [clojure.core.memoize :as memo]
[clojure.java.io :as io]
[nextjournal.beholder :as beholder]
[optimus.asset :as asset]
[optimus.homeless :refer [assoc-non-nil]]))
(defn- serve-asset [asset]
(-> {:status 200 :body (or (:contents asset)
(io/input-stream (:resource asset)))}
(assoc-non-nil :headers (:headers asset))))
(defn- serve-asset-or-continue [assets path->asset app request]
(if-let [asset (path->asset (:uri request))]
(serve-asset asset)
(app (assoc request :optimus-assets assets))))
(defn- collapse-equal-assets [asset-1 asset-2]
(when-not (= asset-1 asset-2)
(throw (Exception. (str "Two assets have the same path \"" (:path asset-1) "\", but are not equal."))))
asset-1)
(defn- guard-against-duplicate-assets [assets]
(let [pb->assets (group-by (juxt :path :bundle) assets)]
(->> assets
(map (juxt :path :bundle))
(distinct)
(map pb->assets)
(map #(reduce collapse-equal-assets %)))))
(defn serve-live-assets [app get-assets optimize options]
(let [get-optimized-assets #(optimize (guard-against-duplicate-assets (get-assets)) options)
get-optimized-assets (if-let [ms (get options :cache-live-assets 2000)]
(memo/ttl get-optimized-assets {} :ttl/threshold ms)
get-optimized-assets)]
(fn [request]
(let [assets (get-optimized-assets)
path->asset (into {} (map (juxt asset/path identity) assets))]
(serve-asset-or-continue assets path->asset app request)))))
(defn serve-live-assets-autorefresh [app get-assets optimize options]
(let [get-optimized-assets #(optimize (guard-against-duplicate-assets (get-assets)) options)
assets-cache (atom (get-optimized-assets))
dirs-to-watch (or (:assets-dirs options)
[(:assets-dir options "resources")])]
(apply beholder/watch
(fn [_e]
(reset! assets-cache (get-optimized-assets)))
dirs-to-watch)
(fn [request]
(let [assets @assets-cache
path->asset (into {} (map (juxt asset/path identity) assets))]
(serve-asset-or-continue assets path->asset app request)))))
(defn serve-frozen-assets [app get-assets optimize options]
(let [assets (optimize (guard-against-duplicate-assets (get-assets)) options)
path->asset (into {} (map (juxt asset/path identity) assets))]
(fn [request]
(serve-asset-or-continue assets path->asset app request))))