···5566import { Aside } from '@astrojs/starlight/components';
7788+**Aspects** and **Contexts** are Den core arquitectural principles.
99+1010+It is how Den supports different platform configurations, packages/checks flake outputs, different home environments suppport,
1111+wsl support, third-party flake-parts perSystem modules, microvm guests, and pretty much everything.
1212+1313+It is also how more complex entities, like machine fleets, terraform or cloud infra can be configured with Den.
1414+1515+<Aside title="Aspect-Oriented">
1616+If you are familiar with Aspect-Oriented-Programming you will recognize how Den uses pointcuts to define where configurations get applied at each context stage.
1717+1818+> Pointcuts in **Aspect-Oriented-Programming** determine where additional behavior (advice) should be applied in your code, typically at method execution points.
1919+</Aside>
2020+2121+<Aside title="Context-Driven">
2222+Den is, fundamentally, a _data transformation_ pipeline (of your infra entities) to which _functions_ (producing configurations) are applied.
2323+2424+2525+> A context transformation pipeline takes initially `{host}` and traverses its topology
2626+> `host`->`[users]`->`[homes]` aggregating dependencies, optionally branching to suport
2727+> feature detection `host`->`wsl-host` or `host`->`[microvm-guest]`.
2828+</Aside>
2929+3030+From our README header example:
3131+3232+```nix
3333+# These three lines is how Den instantiates a configuration.
3434+# Other Nix configuration domains outside NixOS/nix-Darwin
3535+# can use the same pattern. demo: templates/nvf-standalone
3636+3737+# A context transformation pipeline takes initially {host}
3838+# and traverses its topology (host->[users]->[homes]) aggregating deps
3939+aspect = den.ctx.host { host = den.hosts.x86_64-linux.my-laptop; };
4040+4141+# obtain the final module for nixos class
4242+nixosModule = den.lib.aspects.resolve "nixos" aspect;
4343+4444+# Use NixOS API to instantiate or mix-in with other custom modules
4545+nixosConfigurations.my-laptop = lib.nixosConfiguration { modules = [ nixosModule ]; };
4646+```
4747+4848+Anything that you can describe via a data structure that can be traversed, can be configured like we do for NixOS.
4949+5050+### Den is Aspect-oriented
5151+5252+<Aside icon="nix" title="Dendritic Aspects">
5353+5454+A Dendritic aspect is an attrset that contains modules of different Nix `class`.
5555+5656+```nix
5757+gaming = { host, user }: { nixos = ...; homeManager = ...; hjem = ...; darwin = ...; }
5858+```
5959+6060+Such an attrset is said to be [**Dendritic**](https://dendrix.oeiuwq.com/Dendritic.html) because it allows configuring a single cross-cutting concern (`gaming`) over different configuration domains.
6161+6262+Nix classes are NOT an artificial concept created by Den. There are [many nix classes in the wild](https://github.com/search?q=language%3ANix+%28%22+class+%3D+%22+AND+%22evalModules%22%29&type=code), the most common are [`nixos`](https://github.com/search?q=repo%3ANixOS%2Fnixpkgs+%22class+%3D+%5C%22nixos%5C%22%22&type=code), [`darwin`](https://github.com/nix-darwin/nix-darwin/blob/da529ac9e46f25ed5616fd634079a5f3c579135f/eval-config.nix#L81), [`homeManager`](https://github.com/nix-community/home-manager/blob/5be5d8245cbc7bc0c09fbb5f38f23f223c543f85/nixos/common.nix#L27).
6363+</Aside>
6464+6565+Most importantly, the context `{host,user}` here are **not** `_module.args` **nor** `specialArgs`, it is an actual function, not a module-looking-as-a-function. This means config can depend on context without Nix infinite loops.
6666+6767+6868+### Den is Context-driven
6969+7070+Den uses `den.ctx.<name>.provides.<name>` as **Aspect Pointcuts** where configuration is applied to data in that context stage.
7171+Say you have a data shape: `{ x }`, that you name as a `foo` context stage:
7272+7373+```nix
7474+# This says how to move from one context stage `foo` into another stage `bar`
7575+den.ctx.foo.into.bar = { x }: [ { y = x; } ]
7676+```
7777+7878+The following `den.ctx.bar.provides.bar` is the actual pointcut that **locates** the aspect responsible for configuring
7979+using data `{ y }` available at `bar` context stage.
8080+8181+```nix
8282+# inlined aspect for this example, but can locate the aspect by any means
8383+den.ctx.bar.provides.bar = { y }: { nixos.something = y; }
8484+```
8585+8686+and since `den.ctx.bar` **is** itself an aspect, it can be used to include
8787+additional configurations at that particular stage:
8888+8989+```nix
9090+den.ctx.bar.nixos.something-else = true;
9191+den.ctx.bar.includes = [ den.aspects.other ];
9292+```
9393+9494+### `den.ctx.host` pipeline
9595+9696+This is how everything works in Den, the following is the context transitions
9797+that happen when applying `den.ctx.host { host }`
9898+9999+```nix
100100+# host configuration: THIS is where your host-aspect is hooked into the pipeline
101101+den.ctx.host.provides.host = { host }: den.aspects.${host.aspect};
102102+103103+# host -> users context transformation
104104+den.ctx.host.into.user = { host }: map (user: { inherit host user; }) (lib.attrValues host.users); # transition into many { host, user }
105105+106106+# user configuration: Lookup user aspect.
107107+den.ctx.user.provides.user = { host, user }: den.aspects.${user.aspect}; # Hook for the user-aspect.
108108+109109+# conditional transition ONLY if hm is enabled for user and host.
110110+den.ctx.user.into.hm-user = { host, user }: lib.optional (host.hm.enable && lib.elem "homeManager" user.classes) { inherit host user; }
111111+112112+# host -> wsl-host: Same data shape, different context stage.
113113+den.ctx.host.into.wsl-host = { host }: lib.optional host.wsl.enable { inherit host; }
114114+```
115115+116116+**people can define their own extensions to Den's NixOS pipeline, or define other pipelines enterely**.
117117+118118+<Aside title="Real world examples">
119119+Minimal real-life example: [wsl support](https://github.com/vic/den/blob/main/modules/aspects/provides/wsl.nix)
120120+121121+[home-env](https://github.com/vic/den/blob/main/nix/lib/home-env.nix#L97) is how Den implements homeManager/hjem/maid support
122122+123123+[flake-parts perSystem classes](https://github.com/vic/den/blob/main/templates/flake-parts-modules/modules/custom-classes.nix)
124124+125125+[microvm guests support](https://github.com/vic/den/blob/main/templates/microvm/modules/microvm-integration.nix#L46)
126126+</Aside>
127127+8128## Feature-First, Not Host-First
912910130<Aside title="Recommended Read">