-
-
Notifications
You must be signed in to change notification settings - Fork 81
/
load.cljs
64 lines (56 loc) · 1.91 KB
/
load.cljs
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
(ns portal.ui.load)
(defn- module-wrapper
"https://nodejs.org/api/modules.html#the-module-wrapper"
[{:keys [source]}]
(str "(function (exports, require, module, __filename, __dirname) { " source "\n });"))
(defn load-fn-sync [m]
(let [_label (str "load-fn-sync: " (pr-str m))
xhr (js/XMLHttpRequest.)]
#_(.time js/console _label)
(.open xhr "POST" "/load" false)
(.setRequestHeader xhr "content-type" "application/edn")
(.send xhr (pr-str m))
#_(.timeEnd js/console _label)
(some->
(.parse js/JSON (.-responseText xhr))
(js->clj :keywordize-keys true)
(update :lang keyword)
(assoc :name (:name m)))))
(def load-cache (atom {}))
(def ^:private require-cache (atom {}))
(deftype Module [exports])
(defn load-require-cache [modules]
(swap!
require-cache
(fn [cache]
(reduce-kv
(fn [cache module-name export]
(assoc cache module-name (Module. export)))
cache
modules))))
(declare node-require)
(defn node-require
([module]
(node-require nil module))
([parent module-name]
(or
(some-> ^Module (get @require-cache module-name) .-exports)
(try
(let [{:keys [file] :as value} (load-fn-sync {:npm true :name module-name :parent parent})]
(if-let [^Module module (get @require-cache file)]
(.-exports module)
(let [exports #js {}
module-obj (Module. exports)]
(swap! require-cache assoc file module-obj)
((js/eval (module-wrapper value))
exports #(node-require (:dir value) %) module-obj (:file value) (:dir value))
(.-exports module-obj))))
(catch :default e
(.error js/console e)
(throw e))))))
(set! (.-require js/window) node-require)
(set! (.-process js/window)
#js {:env #js {:NODE_ENV
(if js/goog.DEBUG
"development"
"production")}})