### Embed Resources at Compile Time with Mate.io Source: https://context7.com/green-coder/mate/llms.txt The `mate.io/inline-resource` macro embeds resource file contents directly into compiled code. It supports relative and absolute paths, and allows for optional content transformation via provided functions and arguments. This is useful for embedding configuration files, SQL queries, or other static assets. ```clojure (ns my-app.config (:require [mate.io :as mio] #?(:clj [clojure.data.json :as json]))) ;; Relative path (resolved relative to current namespace) (def config-text (mio/inline-resource "./test-resource.txt")) ;; => "Content of test-resource.txt" ;; Absolute path from classpath root (def config-text (mio/inline-resource "mate/test-resource.txt")) ;; => "Content of test-resource.txt" ;; Transform content with function and arguments (def config-upper (mio/inline-resource "./test-resource.txt" str " FOO" " BAR")) ;; => "Content of test-resource.txt FOO BAR" ;; Parse JSON at compile time (def config-data (mio/inline-resource "./test-resource.json" json/read-json)) ;; => [{:a 1} "hello"] ;; Practical example: embed SQL queries (ns my-app.queries (:require [mate.io :as mio])) (def user-query (mio/inline-resource "./sql/get-user.sql")) (def report-query (mio/inline-resource "./sql/monthly-report.sql" clojure.string/trim)) ``` -------------------------------- ### Clojure Partial Application Macros: Thread-First and Thread-Last Source: https://context7.com/green-coder/mate/llms.txt The `mate.core/partial->` and `mate.core/partial->>` functions create partially applied functions suitable for use in thread-first and thread-last threading macros. They enable cleaner function application within pipelines, especially when common arguments need to be pre-set. ```clojure (require '[mate.core :as m]) ;; Thread-first partial application (-> 1 ((m/partial-> vector 2 3))) ;; => [1 2 3] (->> [1 2 3] (mapv (m/partial-> vector 10))) ;; => [[1 10] [2 10] [3 10]] ;; Thread-last partial application (->> 3 ((m/partial->> vector 1 2))) ;; => [1 2 3] ;; Practical example: data transformation with partial application (def add-metadata (m/partial-> assoc :version "1.0" :source "api")) (def records [{:id 1 :name "Alice"} {:id 2 :name "Bob"}]) (mapv add-metadata records) ;; => [{:id 1, :name "Alice", :version "1.0", :source "api"} ;; {:id 2, :name "Bob", :version "1.0", :source "api"}] ``` -------------------------------- ### Clojure Threading Macros: Conditional, Binding, and Apply Source: https://context7.com/green-coder/mate/llms.txt These macros extend Clojure's threading capabilities. `if->` allows conditional branching, `let->` introduces local bindings within a thread, and `apply->` and `apply->>` apply functions with argument lists. They facilitate more complex and readable data processing pipelines. ```clojure (require '[mate.core :as m]) ;; Conditional threading (-> [] (m/if-> true (conj :a) ; executed when condition is true (conj :b)) ; executed when condition is false (conj :c)) ;; => [:a :c] ;; Threading with local bindings (-> [] (m/let-> [x :first-value] (conj x)) (m/let-> [y :second z :third] (-> (conj y) (conj z))) (conj :fourth)) ;; => [:first-value :second :third :fourth] ;; Apply with thread-first (-> [:a] (m/apply-> conj :b [:c :d])) ;; => [:a :b :c :d] ;; Apply with thread-last (->> [:c :d] (m/apply->> conj [:a] :b)) ;; => [:a :b :c :d] ;; Practical example: conditional data processing pipeline (defn process-user-data [user admin?] (-> user (m/if-> admin? (assoc :permissions #{:read :write :admin}) (assoc :permissions #{:read})) (m/let-> [created-at (java.util.Date.)] (assoc :created-at created-at)) (update :email clojure.string/lower-case))) ``` -------------------------------- ### Compose Re-frame Effects with Mate.re-frame Utilities Source: https://context7.com/green-coder/mate/llms.txt The `mate.re-frame` namespace offers utilities to compose re-frame effect maps using the thread-first macro. This simplifies event handler logic by providing functions to manipulate the `:db` and `:fx` keys within an effects map. ```clojure (ns my-app.events (:require [mate.re-frame :as mr] [re-frame.core :as rf])) ;; Helper functions for business logic (defn store-user-in-db [db user-id user-name access-token refresh-token] (update db :user assoc :id user-id :name user-name :access-token access-token :refresh-token refresh-token)) (defn user-logged-in-notification-fx [db] [:notification {:level :info :message (str (-> db :user :name) " logged in')}]) (defn load-user-data-fx [db] [:http-get (-> db :user :id) [:picture-url :accepted-end-user-agreement? :preferred-books]]) ;; Event handler using composition (rf/reg-event-fx ::user-login (fn [{:keys [db]} [_ user-id user-name access-token refresh-token]] (-> {:db db} ;; Add a single effect (mr/conj-fx [:sound :login-success]) ;; Update the database (mr/update-db store-user-in-db user-id user-name access-token refresh-token) ;; Add effect computed from current db (mr/conj-fx-using-db user-logged-in-notification-fx) (mr/conj-fx-using-db load-user-data-fx) ;; Add multiple effects from collection (mr/into-fx-using-db (fn [db] [[:save-to-storage (:history db)] [:analytics :login-event]]))))) ;; Result structure: ;; {:db {:user {...updated user data...}} ;; :fx [[:sound :login-success] ;; [:notification {...}] ;; [:http-get ...] ;; [:save-to-storage ...] ;; [:analytics :login-event]]} ``` -------------------------------- ### Index Collection by Key (Clojure) Source: https://context7.com/green-coder/mate/llms.txt Creates a hashmap from a collection where keys are computed from items. For duplicate keys, it retains only the last value, effectively forming an index. ```clojure (require '[mate.core :as m]) ;; Index by first element (last occurrence wins) (m/index-by first [[:a 1] [:a 2] [:b 3] [:a 4] [:b 5]]) ;; => {:a [:a 4], :b [:b 5]} ;; Index by first element, store only second element (m/index-by first second [[:a 1] [:a 2] [:b 3] [:a 4] [:b 5]]) ;; => {:a 4, :b 5} ;; Practical use: create lookup table from database records (def users [{:id 1 :name "Alice" :email "alice@example.com"} {:id 2 :name "Bob" :email "bob@example.com"} {:id 3 :name "Charlie" :email "charlie@example.com"}]) (def user-lookup (m/index-by :id users)) (get user-lookup 2) ;; => {:id 2, :name "Bob", :email "bob@example.com"} ``` -------------------------------- ### Enhanced Group-By with Custom Reductions (Clojure) Source: https://context7.com/green-coder/mate/llms.txt Extends Clojure's group-by with arities for custom transformations and reductions on grouped values. Supports simple grouping, value mapping, and custom reduction operations with optional initial values. ```clojure (require '[mate.core :as m]) ;; Basic grouping (identical to clojure.core/group-by) (m/group-by first [[:a 1] [:a 2] [:b 3] [:a 4] [:b 5]]) ;; => {:a [[:a 1] [:a 2] [:a 4]], :b [[:b 3] [:b 5]]} ;; Group by key, extract values (m/group-by first second [[:a 1] [:a 2] [:b 3] [:a 4] [:b 5]]) ;; => {:a [1 2 4], :b [3 5]} ;; Group by key, extract values, sum them (m/group-by first second + [[:a 1] [:a 2] [:b 3] [:a 4] [:b 5]]) ;; => {:a 7, :b 8} ;; Group by key, extract values, sum with initial value (m/group-by first second + 10 [[:a 1] [:a 2] [:b 3] [:a 4] [:b 5]]) ;; => {:a 17, :b 18} ``` -------------------------------- ### Indexed Sequence Operations (Clojure) Source: https://context7.com/green-coder/mate/llms.txt Provides indexed variants of sequence operations like `seq-indexed` and `mapcat-indexed`, returning pairs of `[index value]`. Useful for adding line numbers or processing sequences with their indices. ```clojure (require '[mate.core :as m]) ;; Create indexed sequence (m/seq-indexed [:a :a :b :a :b]) ;; => ([0 :a] [1 :a] [2 :b] [3 :a] [4 :b]) ;; Map with index and concatenate (transducer form) (into [] (m/mapcat-indexed (fn [index x] [x index])) [:a :b :c]) ;; => [:a 0 :b 1 :c 2] ;; Map with index and concatenate (collection form) (m/mapcat-indexed (fn [index x] [x index]) [:a :b :c]) ;; => (:a 0 :b 1 :c 2) ;; Practical example: add line numbers to error messages (m/mapcat-indexed (fn [line-num text] (if (clojure.string/includes? text "ERROR") [(str "Line " line-num ": " text)] [])) ["INFO: Starting process" "ERROR: Connection failed" "INFO: Retrying" "ERROR: Timeout occurred"]) ;; => ("Line 1: ERROR: Connection failed" "Line 3: ERROR: Timeout occurred") ``` -------------------------------- ### Clojure Composition Macro: Left-to-Right Function Composition Source: https://context7.com/green-coder/mate/llms.txt The `mate.core/comp->` macro provides function composition that reads from left to right, similar to threading macros, but chaining functions directly. This is the inverse of Clojure's standard `comp` macro, which composes functions from right to left. ```clojure (require '[mate.core :as m]) ;; Standard comp reads right-to-left ((comp str inc) 2) ;; => "3" ;; comp-> reads left-to-right ((m/comp-> inc str) 2) ;; => "3" ;; Practical example: data transformation pipeline (def process-number (m/comp-> inc (* 2) str (str "Result: "))) (process-number 5) ;; => "Result: 12" ``` -------------------------------- ### Add Effects to Effects Map with Mate.re-frame Source: https://context7.com/green-coder/mate/llms.txt Mate.re-frame provides `conj-fx`, `into-fx`, and their `-using-db` variants to append effects to the `:fx` vector in a re-frame effects map. These functions allow for adding single effects, multiple effects, or effects computed dynamically from the database state. ```clojure (require '[mate.re-frame :as mr]) ;; Add single effect (nil values are ignored) (-> {:db {:foo "bar"}} (mr/conj-fx [:effect-1]) (mr/conj-fx nil) (mr/conj-fx [:effect-2])) ;; => {:db {:foo "bar"}, :fx [[:effect-1] [:effect-2]]} ;; Add multiple effects at once (-> {:db {:foo "bar"}} (mr/conj-fx [:effect-1] [:effect-2] [:effect-3])) ;; => {:db {:foo "bar"}, :fx [[:effect-1] [:effect-2] [:effect-3]]} ;; Add effects from collection (nil values filtered) (-> {:db {:foo "bar"}} (mr/into-fx [[:effect-1] nil [:effect-2]])) ;; => {:db {:foo "bar"}, :fx [[:effect-1] [:effect-2]]} ;; Compute effect from current db state (-> {:db {:user-id 123}} (mr/conj-fx-using-db (fn [db] [:log-action (:user-id db)]))) ;; => {:db {:user-id 123}, :fx [[:log-action 123]]} ;; Compute multiple effects from current db state (-> {:db {:user-id 123 :session-id "abc"}} (mr/into-fx-using-db (fn [db] [[:log-action (:user-id db)] [:track-session (:session-id db)]]))) ;; => {:db {:user-id 123, :session-id "abc"}, ;; :fx [[:log-action 123] [:track-session "abc"]]} ``` -------------------------------- ### Regular Expression with Index Information (Clojure) Source: https://context7.com/green-coder/mate/llms.txt Extends `re-find` to return match positions and capture group indices. ClojureScript requires the 'd' flag for capture group indices. Useful for template variable extraction. ```clojure (require '[mate.core :as m]) ;; Simple match without capture groups (m/re-find-indexed #"\$\{[^\{\}]*\}" "xxx ${aaa} ${bbb} yyy") ;; => [4 "${aaa}"] ; match starts at index 4 ;; Match with capture group (Clojure) (m/re-find-indexed #"\$\{([^\{\}]*)\}" "xxx ${aaa} ${bbb} yyy") ;; => [[4 "${aaa}"] [6 "aaa"]] ; full match at 4, captured group at 6 ;; ClojureScript requires the 'd' flag for capture group indices #?(:cljs (let [re (m/re-with-flags #"\$\{([^\{\}]*)\}" "d")] (m/re-find-indexed re "xxx ${aaa} ${bbb} yyy")) ;; => [[4 "${aaa}"] [6 "aaa"]] ) ;; Practical use: template variable replacement with error reporting (defn find-template-vars [template] (let [re #"\{\{([^\}]+)\}}" matcher (re-matcher re template)] (loop [matches []] (if-let [[pos match var-name] (m/re-find-indexed matcher)] (recur (conj matches {:position pos :match match :var var-name})) matches)))) ``` -------------------------------- ### Update Database in Effects Map with Mate.re-frame Source: https://context7.com/green-coder/mate/llms.txt `mate.re-frame/update-db` is used to modify the `:db` key within a re-frame effects map. It takes a function and its arguments, applying them to the current `:db` value. This allows for declarative updates to the application's state within effect handlers. ```clojure (require '[mate.re-frame :as mr]) (-> {:db {}} (mr/update-db assoc :foo "bar") (mr/update-db update-in [:a :b] (fnil inc 0))) ;; => {:db {:foo "bar", :a {:b 1}}} ``` -------------------------------- ### Clojure Logical Implication Function Source: https://context7.com/green-coder/mate/llms.txt The `mate.core/implies` function implements logical implication (P implies Q), which is true unless P is true and Q is false. It's a useful tool for expressing conditional logic and validation rules more expressively in Clojure code, often simplifying complex `and`/`or` structures. ```clojure (require '[mate.core :as m]) ;; Truth table for implies (m/implies true true) ;; => true (m/implies true false) ;; => false (m/implies false true) ;; => true (m/implies false false) ;; => true ;; Expands to: (or (not x) y) ;; Practical use: validation logic (defn validate-user [user] (and (m/implies (:admin? user) (contains? user :admin-key)) ; admin users must have admin-key (m/implies (:email-verified? user) (some? (:email user))))) ; verified users must have email ``` -------------------------------- ### Clojure Map Key Ungrouping Utility Source: https://context7.com/green-coder/mate/llms.txt The `mate.core/ungroup-keys` function transforms a map by expanding keys that are collections (vectors, lists, sets) into individual key-value pairs. This is useful for configurations where multiple keys might map to the same value, such as route definitions. ```clojure (require '[mate.core :as m]) (m/ungroup-keys {[:a :b] 1 :c 2 #{:d :e} 3 {:f :g} 4}) ;; => {:a 1, :b 1, :c 2, :d 3, :e 3, {:f :g} 4} ;; Note: later values overwrite earlier ones (m/ungroup-keys {:a "overwritten" [:a :b] "final" :c 2}) ;; => {:a "final", :b "final", :c 2} ;; Practical use: route configuration (def route-handlers {[:GET :POST] "/api/users" :DELETE "/api/users/:id" #{:GET :PUT} "/api/settings"}) (m/ungroup-keys route-handlers) ;; => {:GET "/api/settings", :POST "/api/users", :DELETE "/api/users/:id", :PUT "/api/settings"} ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.