polix.loader
Module loading from EDN data with dependency resolution.
Modules are collections of named policies that can import policies from other modules. The loader validates dependencies, detects circular imports, and loads modules in topological order (dependencies first).
Module Definition Format
{:namespace :auth
:imports [:common :utils]
:policies {:admin [:= :doc/role "admin"]
:has-role [:= :doc/role :param/role]}}
Usage
(require '[polix.loader :as loader]
'[polix.registry :as reg])
(def modules
[{:namespace :common
:policies {:active [:= :doc/status "active"]}}
{:namespace :auth
:imports [:common]
:policies {:admin-active [:and [:common/active]
[:= :doc/role "admin"]]}}])
(let [{:keys [ok error]} (loader/load-modules (reg/create-registry) modules)]
(if error
(println "Load failed:" error)
(println "Loaded" (count (reg/module-namespaces ok)) "modules")))
detect-cycle
(detect-cycle graph)Detects if the dependency graph contains a cycle.
Uses DFS with path tracking. Returns nil if no cycle found, or a vector representing the cycle path if found.
Example: [:a :b :c :a] means a -> b -> c -> a.
load-module
(load-module registry module-def)Loads a single module definition into a registry.
Returns the updated registry. Does not validate imports.
load-modules
(load-modules registry module-defs)Loads multiple modules into a registry with dependency resolution.
Validates all module definitions, checks for circular imports, verifies that all imports exist, and loads modules in topological order (dependencies first).
Returns: - {:ok registry} on success - {:error error-map} on failure
Error types: - :invalid-module - module definition is malformed - :circular-import - modules form an import cycle - :missing-imports - some imports reference undefined modules
topological-sort
(topological-sort graph)Returns modules in dependency order (dependencies first).
Uses DFS-based topological sort. Returns vector of nodes with dependencies before dependents. Returns nil if the graph contains a cycle.