|
15 | 15 | [dirac.shared.async :refer [<! close! go go-channel go-wait put!]] |
16 | 16 | [dirac.shared.utils :as utils] |
17 | 17 | [goog.functions :as gfns] |
18 | | - [oops.core :refer [oapply ocall oget gget]]) |
| 18 | + [oops.core :refer [oapply gcall ocall oget gget]]) |
19 | 19 | (:import goog.net.WebSocket.ErrorEvent)) |
20 | 20 |
|
21 | 21 | (def required-repl-api-version 9) |
|
27 | 27 | (defonce ^:dynamic *last-session-id* nil) |
28 | 28 | (defonce ^:dynamic *last-connect-fn-id* 0) |
29 | 29 | (defonce ^:dynamic *ignore-next-client-change* false) |
| 30 | +(defonce ^:dynamic *loopback-repl-ns* nil) |
30 | 31 |
|
31 | 32 | (def dirac-agent-help-url "https://github.com/binaryage/dirac/blob/master/docs/installation.md#start-dirac-agent") |
32 | 33 | (def dirac-runtime-help-url "https://github.com/binaryage/dirac/blob/master/docs/installation.md#install-the-dirac-runtime") |
33 | 34 | (def dirac-upgrading-help-url "https://github.com/binaryage/dirac/blob/master/docs/upgrading.md") |
| 35 | +(def dirac-loopback-mode-url "https://github.com/binaryage/dirac/blob/master/docs/faq.md#what-is-loopback-mode") |
34 | 36 |
|
35 | 37 | (defn ^:dynamic repl-api-mismatch-msg [current-api required-api] |
36 | 38 | (str "Dirac REPL API version mismatch detected.\n" |
|
109 | 111 | "Normally we would inject playground project to get ad-hoc REPL working here " |
110 | 112 | "but it is currently not supported with shadow-cljs.")) |
111 | 113 |
|
| 114 | +(defn ^:dynamic explain-loopback-mode-msg [] |
| 115 | + (str "Dirac REPL is running in loopback mode. See " dirac-loopback-mode-url ".")) |
| 116 | + |
112 | 117 | (defn check-agent-version! [agent-version] |
113 | 118 | (let [our-version implant-version/version] |
114 | 119 | (when-not (= agent-version our-version) |
|
164 | 169 | (set! *repl-connected* false) |
165 | 170 | (set! *last-connect-fn-id* 0)) |
166 | 171 |
|
| 172 | +(defn loopback-repl? [] |
| 173 | + (= *last-connection-url* "loopback-repl")) |
| 174 | + |
| 175 | +(defn update-loopback-repl! [] |
| 176 | + (console/set-prompt-ns! *loopback-repl-ns*) |
| 177 | + (console/set-prompt-compiler! "loopback" "")) |
| 178 | + |
| 179 | +(defn connect-to-loopback-repl! [] |
| 180 | + (set! *last-connection-url* "loopback-repl") |
| 181 | + (set! *last-session-id* "loopback-session") |
| 182 | + (set! *repl-bootstrapped* true) |
| 183 | + (set! *repl-connected* true) |
| 184 | + (set! *loopback-repl-ns* "cljs.user") |
| 185 | + (update-repl-mode!) |
| 186 | + (update-loopback-repl!)) |
| 187 | + |
167 | 188 | (defn on-client-change [_key _ref old new] |
168 | 189 | (when-not *ignore-next-client-change* |
169 | 190 | (if (some? new) |
|
263 | 284 | (js->clj scope-info-js :keywordize-keys true) |
264 | 285 | {})) |
265 | 286 |
|
| 287 | +(def dirac-special-re #"\(?dirac!?.*\)?") |
| 288 | +(def in-ns-re #"\(in-ns\s+'?(.*)\)") |
| 289 | + |
| 290 | +(defn is-dirac-special? [code] |
| 291 | + (some? (re-matches dirac-special-re code))) |
| 292 | + |
| 293 | +(defn is-in-ns-call? [code] |
| 294 | + (some? (re-matches in-ns-re code))) |
| 295 | + |
| 296 | +(defn handle-dirac-special! [] |
| 297 | + (gcall "dirac.addConsoleMessageToMainTarget" "log" "info" (explain-loopback-mode-msg)) |
| 298 | + ::command-handled) |
| 299 | + |
| 300 | +(defn handle-in-ns-call! [code] |
| 301 | + (let [m (re-matches in-ns-re code) |
| 302 | + ns (second m)] |
| 303 | + (when (some? ns) |
| 304 | + (set! *loopback-repl-ns* ns) |
| 305 | + (update-loopback-repl!) |
| 306 | + ::command-handled))) |
| 307 | + |
| 308 | +(defn attempt-to-handle-loopback-repl-specials! [code] |
| 309 | + (cond |
| 310 | + (is-dirac-special? code) (handle-dirac-special!) |
| 311 | + (is-in-ns-call? code) (handle-in-ns-call! code))) |
| 312 | + |
| 313 | +(defn do-loopback-repl-eval! [code] |
| 314 | + (if-not (= ::command-handled (attempt-to-handle-loopback-repl-specials! code)) |
| 315 | + (eval/eval-cljs-in-console! code *loopback-repl-ns*))) |
| 316 | + |
266 | 317 | (defn send-eval-request! [job-id code scope-info] |
267 | | - (when (repl-ready?) |
268 | | - (console/announce-job-start! job-id (str "eval: " code)) |
269 | | - (let [message {:op "eval" |
270 | | - :dirac "short-circuit-presentation" |
271 | | - :id job-id |
272 | | - :code code |
273 | | - :scope-info (prepare-scope-info scope-info)}] |
274 | | - (nrepl-tunnel-client/tunnel-message! (utils/compact message))))) |
| 318 | + (if-not (loopback-repl?) |
| 319 | + (when (repl-ready?) |
| 320 | + (console/announce-job-start! job-id (str "eval: " code)) |
| 321 | + (let [message {:op "eval" |
| 322 | + :dirac "short-circuit-presentation" |
| 323 | + :id job-id |
| 324 | + :code code |
| 325 | + :scope-info (prepare-scope-info scope-info)}] |
| 326 | + (nrepl-tunnel-client/tunnel-message! (utils/compact message)))) |
| 327 | + (do-loopback-repl-eval! code))) |
275 | 328 |
|
276 | 329 | (defn ws-url [host port] |
277 | 330 | (str "ws://" host ":" port)) |
|
311 | 364 | (register-bootstrap-done-hook! enter-playground!) |
312 | 365 | (<! (go-init-repl! true)))) |
313 | 366 |
|
| 367 | +(defn go-start-loopback-repl! [] |
| 368 | + (feedback/post! "start-loopback-repl!") |
| 369 | + (go |
| 370 | + (connect-to-loopback-repl!) |
| 371 | + (<! (go-init-repl! true)))) |
| 372 | + |
314 | 373 | (declare go-react-on-global-object-cleared!) |
315 | 374 |
|
316 | 375 | (defn on-debugger-event [type & args] |
|
342 | 401 | (if (<! (eval/go-ask-is-runtime-repl-enabled?)) |
343 | 402 | (<! (go-start-repl!)) |
344 | 403 | (display-prompt-status (repl-support-not-enabled-msg))) |
345 | | - (if (or no-playground? (hosted?)) |
346 | | - (display-prompt-status (missing-runtime-msg runtime-present?)) |
347 | | - (if (<! (eval/go-ask-is-shadow-present?)) |
348 | | - (display-prompt-status (no-playground-due-to-shadow-msg)) |
349 | | - (<! (go-start-playground-repl!))))))))) |
| 404 | + (if (<! (eval/go-ask-is-cljs-eval-present?)) |
| 405 | + (<! (go-start-loopback-repl!)) |
| 406 | + (if (or no-playground? (hosted?)) |
| 407 | + (display-prompt-status (missing-runtime-msg runtime-present?)) |
| 408 | + (if (<! (eval/go-ask-is-shadow-present?)) |
| 409 | + (display-prompt-status (no-playground-due-to-shadow-msg)) |
| 410 | + (<! (go-start-playground-repl!)))))))))) |
350 | 411 |
|
351 | 412 | (defn go-react-on-global-object-cleared! [] |
352 | 413 | (reset-repl-state!) |
|
0 commit comments