<commit_before>(ns replumb.core
  (:require-macros [cljs.env.macros :refer [with-compiler-env]])
  (:require [cljs.js :as cljs]
            [replumb.repl :as repl]
            [replumb.common :as common]))

(defn ^:export read-eval-call
  "Reads, evaluates and calls back with the evaluation result.

  The first parameter is a map of configuration options, currently
  supporting:

  * `:verbose` will enable the the evaluation logging, defaults to false
  * `:warning-as-error` will consider a compiler warning as error
  * `:target` `:nodejs` and `:browser` supported, the latter is used if
  missing
  * `:init-fn!` user provided initialization function, it will be passed a
  map:

          :form   ;; the form to evaluate, as data
          :ns     ;; the current namespace, as symbol
          :target ;; the current target

  * `:load-fn!` will override replumb's default `cljs.js/*load-fn*`.
  It rules out `:read-file-fn!`, losing any perk of using `replumb.load`
  helpers. Use it if you know what you are doing and follow this
  protocol:

      ```
      Each runtime environment provides a different way to load a library.
      Whatever function `*load-fn*` is bound to will be passed two arguments
      - a map and a callback function: The map will have the following keys:

          :name   - the name of the library (a symbol)
          :macros - modifier signaling a macros namespace load
          :path   - munged relative library path (a string)

      The callback cb, upon resolution, will need to pass the same map:

          :lang       - the language, :clj or :js
          :source     - the source of the library (a string)
          :cache      - optional, if a :clj namespace has been precompiled to
                        :js, can give an analysis cache for faster loads.
          :source-map - optional, if a :clj namespace has been precompiled
                        to :js, can give a V3 source map JSON

      If the resource could not be resolved, the callback should be invoked with
      nil.
      ```

  * `:read-file-fn!` an asynchronous 2-arity function with signature
  `[file-path src-cb]` where src-cb is itself a function `(fn [source]
  ...)` that needs to be called with the file content as string (`nil`
  if no file is found). It is mutually exclusive with `:load-fn!` and
  will be ignored in case both are present

  * `:src-paths`  a vector of paths containing source files

  The second parameter, `callback`, should be a 1-arity function which receives
  the result map, whose result keys will be:

  ```
  :success?  ;; a boolean indicating if everything went right
  :value     ;; (if (success? result)) will contain the actual yield of the evaluation
  :error     ;; (if (not (success? result)) will contain a js/Error
  :warning   ;; in case a warning was thrown and :warning-as-error is falsey
  :form      ;; the evaluated form as data structure (not a string)
  ```

  The third parameter is the source string to be read and evaluated.

  It initializes the repl harness either on first execution or if an
  option in `#{:src-paths :init-fn!}` changes from the previous
  `read-eval-call`."
  ([callback source] (repl/read-eval-call {} callback source))
  ([opts callback source] (repl/read-eval-call opts callback source)))

(defn ^:export get-prompt
  "Retrieves the REPL prompt to display, according to the current
  namespace. Returns a string."
  []
  (str (repl/current-ns) "=> "))

(defn ^:export error->str
  "Return the message string of the input `js/Error`."
  ([error] (common/extract-message error))
  ([error print-stack?] (common/extract-message error print-stack?)))

(defn ^:export unwrap-result
  "Unwraps the result of an evaluation.

  It returns the content of `:value` in case of success and the content
  of `:error` (a `js/Error`) in case of failure.

  When `include-warning?` is true, then the value yields from, in order,
  `:error`, then `:warning` and then eventually `:value`."
  ([result-map]
   (unwrap-result result-map false))
  ([result-map include-warning?]
   (let [{:keys [error value warning]} result-map]
     (if error
       error
       (if (and include-warning? warning)
         warning
         value)))))

(defn ^:export success?
  "Given a `result-map`, tells whether the evaluation was successful."
  [result-map]
  (:success? result-map))

(defn ^:export result->string
  "Given a `result-map`, returns the result of the evaluation as string.

  - When `include-warning?` is true, then the string yields from, in
  order, `:error`, then `:warning` and then eventually `:value`.
  - When `print-stack?` is true, the error string will include the stack
  trace."
  ([result-map]
   (result->string result-map false false))
  ([result-map print-stack?]
   (result->string result-map print-stack? false))
  ([result-map print-stack? include-warning?]
   (let [{:keys [error value warning]} result-map]
     (if error
       (common/extract-message error false print-stack?)
       (if (and include-warning? warning)
         warning
         value)))))

(defn ^:export browser-options
  "Creates the browser option map for read-eval-call.

  The 1-arity function requires a `load-fn!` compatible with
  ClojureScript `cljs.js/*load-fn*`. Use it if you know what you are
  doing and follow this protocol:

      Each runtime environment provides a different way to load a library.
      Whatever function `*load-fn*` is bound to will be passed two arguments
      - a map and a callback function: The map will have the following keys:

          :name   - the name of the library (a symbol)
          :macros - modifier signaling a macros namespace load
          :path   - munged relative library path (a string)

      The callback cb, upon resolution, will need to pass the same map:

          :lang       - the language, :clj or :js
          :source     - the source of the library (a string)
          :cache      - optional, if a :clj namespace has been precompiled to
                        :js, can give an analysis cache for faster loads.
          :source-map - optional, if a :clj namespace has been precompiled
                        to :js, can give a V3 source map JSON

      If the resource could not be resolved, the callback should be invoked with
      nil.

  The 2-arity function accepts a sequence of source paths and
  `read-file-fn!`, an asynchronous 2-arity function with signature
  `[file-path src-cb]` where src-cb is itself a function `(fn [source]
  ...)` that needs to be called with the file content as string (`nil`
  if no file is found)."
  ([load-fn!]
   {:target :default
    :load-fn! load-fn!})
  ([src-paths read-file-fn!]
   {:target :default
    :read-file-fn! read-file-fn!
    :src-paths src-paths}))

(defn ^:export nodejs-options
  "Creates the Node.js option map for read-eval-call.

  The 1-arity function requires a `load-fn!` compatible with
  ClojureScript `cljs.js/*load-fn*`. Use it if you know what you are
  doing and follow this protocol:

      Each runtime environment provides a different way to load a library.
      Whatever function `*load-fn*` is bound to will be passed two arguments
      - a map and a callback function: The map will have the following keys:

          :name   - the name of the library (a symbol)
          :macros - modifier signaling a macros namespace load
          :path   - munged relative library path (a string)

      The callback cb, upon resolution, will need to pass the same map:

          :lang       - the language, :clj or :js
          :source     - the source of the library (a string)
          :cache      - optional, if a :clj namespace has been precompiled to
                        :js, can give an analysis cache for faster loads.
          :source-map - optional, if a :clj namespace has been precompiled
                        to :js, can give a V3 source map JSON

      If the resource could not be resolved, the callback should be invoked with
      nil.

  The 2-arity function accepts a sequence of source paths and
  `read-file-fn!`, an asynchronous 2-arity function with signature
  `[file-path src-cb]` where src-cb is itself a function `(fn [source]
  ...)` that needs to be called with the file content as string (`nil`
  if no file is found)."
  ([load-fn!]
   {:target :nodejs
    :load-fn! load-fn!})
  ([src-paths read-file-fn!]
   {:target :nodejs
    :read-file-fn! read-file-fn!
    :src-paths src-paths}))<commit_msg>Doc fix for adding that :src-paths are strings<commit_after>(ns replumb.core
  (:require-macros [cljs.env.macros :refer [with-compiler-env]])
  (:require [cljs.js :as cljs]
            [replumb.repl :as repl]
            [replumb.common :as common]))

(defn ^:export read-eval-call
  "Reads, evaluates and calls back with the evaluation result.

  The first parameter is a map of configuration options, currently
  supporting:

  * `:verbose` will enable the the evaluation logging, defaults to false
  * `:warning-as-error` will consider a compiler warning as error
  * `:target` `:nodejs` and `:browser` supported, the latter is used if
  missing
  * `:init-fn!` user provided initialization function, it will be passed a
  map:

          :form   ;; the form to evaluate, as data
          :ns     ;; the current namespace, as symbol
          :target ;; the current target

  * `:load-fn!` will override replumb's default `cljs.js/*load-fn*`.
  It rules out `:read-file-fn!`, losing any perk of using `replumb.load`
  helpers. Use it if you know what you are doing and follow this
  protocol:

      ```
      Each runtime environment provides a different way to load a library.
      Whatever function `*load-fn*` is bound to will be passed two arguments
      - a map and a callback function: The map will have the following keys:

          :name   - the name of the library (a symbol)
          :macros - modifier signaling a macros namespace load
          :path   - munged relative library path (a string)

      The callback cb, upon resolution, will need to pass the same map:

          :lang       - the language, :clj or :js
          :source     - the source of the library (a string)
          :cache      - optional, if a :clj namespace has been precompiled to
                        :js, can give an analysis cache for faster loads.
          :source-map - optional, if a :clj namespace has been precompiled
                        to :js, can give a V3 source map JSON

      If the resource could not be resolved, the callback should be invoked with
      nil.
      ```

  * `:read-file-fn!` an asynchronous 2-arity function with signature
  `[file-path src-cb]` where src-cb is itself a function `(fn [source]
  ...)` that needs to be called with the file content as string (`nil`
  if no file is found). It is mutually exclusive with `:load-fn!` and
  will be ignored in case both are present

  * `:src-paths`  a vector of paths containing source files

  The second parameter, `callback`, should be a 1-arity function which receives
  the result map, whose result keys will be:

  ```
  :success?  ;; a boolean indicating if everything went right
  :value     ;; (if (success? result)) will contain the actual yield of the evaluation
  :error     ;; (if (not (success? result)) will contain a js/Error
  :warning   ;; in case a warning was thrown and :warning-as-error is falsey
  :form      ;; the evaluated form as data structure (not a string)
  ```

  The third parameter is the source string to be read and evaluated.

  It initializes the repl harness either on first execution or if an
  option in `#{:src-paths :init-fn!}` changes from the previous
  `read-eval-call`."
  ([callback source] (repl/read-eval-call {} callback source))
  ([opts callback source] (repl/read-eval-call opts callback source)))

(defn ^:export get-prompt
  "Retrieves the REPL prompt to display, according to the current
  namespace. Returns a string."
  []
  (str (repl/current-ns) "=> "))

(defn ^:export error->str
  "Return the message string of the input `js/Error`."
  ([error] (common/extract-message error))
  ([error print-stack?] (common/extract-message error print-stack?)))

(defn ^:export unwrap-result
  "Unwraps the result of an evaluation.

  It returns the content of `:value` in case of success and the content
  of `:error` (a `js/Error`) in case of failure.

  When `include-warning?` is true, then the value yields from, in order,
  `:error`, then `:warning` and then eventually `:value`."
  ([result-map]
   (unwrap-result result-map false))
  ([result-map include-warning?]
   (let [{:keys [error value warning]} result-map]
     (if error
       error
       (if (and include-warning? warning)
         warning
         value)))))

(defn ^:export success?
  "Given a `result-map`, tells whether the evaluation was successful."
  [result-map]
  (:success? result-map))

(defn ^:export result->string
  "Given a `result-map`, returns the result of the evaluation as string.

  - When `include-warning?` is true, then the string yields from, in
  order, `:error`, then `:warning` and then eventually `:value`.
  - When `print-stack?` is true, the error string will include the stack
  trace."
  ([result-map]
   (result->string result-map false false))
  ([result-map print-stack?]
   (result->string result-map print-stack? false))
  ([result-map print-stack? include-warning?]
   (let [{:keys [error value warning]} result-map]
     (if error
       (common/extract-message error false print-stack?)
       (if (and include-warning? warning)
         warning
         value)))))

(defn ^:export browser-options
  "Creates the browser option map for read-eval-call.

  The 1-arity function requires a `load-fn!` compatible with
  ClojureScript `cljs.js/*load-fn*`. Use it if you know what you are
  doing and follow this protocol:

      Each runtime environment provides a different way to load a library.
      Whatever function `*load-fn*` is bound to will be passed two arguments
      - a map and a callback function: The map will have the following keys:

          :name   - the name of the library (a symbol)
          :macros - modifier signaling a macros namespace load
          :path   - munged relative library path (a string)

      The callback cb, upon resolution, will need to pass the same map:

          :lang       - the language, :clj or :js
          :source     - the source of the library (a string)
          :cache      - optional, if a :clj namespace has been precompiled to
                        :js, can give an analysis cache for faster loads.
          :source-map - optional, if a :clj namespace has been precompiled
                        to :js, can give a V3 source map JSON

      If the resource could not be resolved, the callback should be invoked with
      nil.

  The 2-arity function accepts a sequence of source path strings and
  `read-file-fn!`, an asynchronous 2-arity function with signature
  `[file-path src-cb]` where src-cb is itself a function `(fn [source]
  ...)` that needs to be called with the file content as string (`nil`
  if no file is found)."
  ([load-fn!]
   {:target :default
    :load-fn! load-fn!})
  ([src-paths read-file-fn!]
   {:target :default
    :read-file-fn! read-file-fn!
    :src-paths src-paths}))

(defn ^:export nodejs-options
  "Creates the Node.js option map for read-eval-call.

  The 1-arity function requires a `load-fn!` compatible with
  ClojureScript `cljs.js/*load-fn*`. Use it if you know what you are
  doing and follow this protocol:

      Each runtime environment provides a different way to load a library.
      Whatever function `*load-fn*` is bound to will be passed two arguments
      - a map and a callback function: The map will have the following keys:

          :name   - the name of the library (a symbol)
          :macros - modifier signaling a macros namespace load
          :path   - munged relative library path (a string)

      The callback cb, upon resolution, will need to pass the same map:

          :lang       - the language, :clj or :js
          :source     - the source of the library (a string)
          :cache      - optional, if a :clj namespace has been precompiled to
                        :js, can give an analysis cache for faster loads.
          :source-map - optional, if a :clj namespace has been precompiled
                        to :js, can give a V3 source map JSON

      If the resource could not be resolved, the callback should be invoked with
      nil.

  The 2-arity function accepts a sequence of source path strings and
  `read-file-fn!`, an asynchronous 2-arity function with signature
  `[file-path src-cb]` where src-cb is itself a function `(fn [source]
  ...)` that needs to be called with the file content as string (`nil`
  if no file is found)."
  ([load-fn!]
   {:target :nodejs
    :load-fn! load-fn!})
  ([src-paths read-file-fn!]
   {:target :nodejs
    :read-file-fn! read-file-fn!
    :src-paths src-paths}))
{'fraction_non_alphanumeric': 0.09494080923493728, 'fraction_numerical': 0.0012957182401790448, 'mean_word_length': 2.713098622348568, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3485839', 'n_tokens_mistral': 4943, 'n_tokens_neox': 4736, 'n_words': 2162}