Patterns

Patterns

Hex VersionHex DocsCI StatusCoverage Status

Because sometimes you want a tiny *sparkle* of magic.

Patterns is an anti-framework for shaping plain Elixir code into tidy little systems.

It gives you small, composable building blocks for the parts of an app that tend to get repetitive:

Patterns is for the little bits of structure you keep rebuilding.

The query helpers, wrapper functions, scoped context, and tiny APIs that make a codebase feel like itself.

Just a few cursed cute tools that stay out of the way and make your own modules feel a little more intentional.

Installation

def deps do
  [
    {:patterns, "~> 0.0.1"}
  ]
end

Why Patterns?

Because there is a sweet spot between “copy-paste this again” and “adopt an entire platform.”

Patterns is for codebases that want:

Write the Elixir you want to write. Patterns just helps it stay pretty.

What's Inside?

Utilities

A couple of tiny tools for library-ish code:

Queryable

Patterns.Queryable gives Ecto schemas one tidy query/2 entrypoint for contexts, resolvers, dataloaders, and tests.

Think of it like a more powerful Repo.get_by/2 that works on any query, with good defaults for the boring stuff:

Post.query(title: "Hello")
Post.query([published: true, order_by: [desc: :published_at]])
Post.query(comments: [author_id: user.id])

Middleware

Patterns.Middleware wraps plain functions with explicit @middleware annotations.

Use it to extend existing functions and APIs: do a lil' auth check here, a lil' logging there.

@middleware Blog.Middlewares.AuthorizeEditor
def edit_post(post, attrs) do
  Blog.Posts.update(post, attrs)
end

@middleware [Blog.Middlewares.AuthorizeEditor, Blog.Middlewares.RecordAuditLog]
def create_post(attrs) do
  Blog.Posts.create(attrs)
end

Status

v0.0.1 is the first release. Tiny, useful, and still allowed to be a little cursed.

Development

Patterns uses Nix for the project shell and CI tooling.

If you use direnv:

direnv allow

If you prefer entering the shell manually:

nix develop

Then run the usual checks:

mix local.hex --force
mix local.rebar --force
mix deps.get
mix test
mix lint
MIX_ENV=prod mix hex.build

CI runs the same checks through the Nix shell, with nix flake check covering repo-level hooks and formatting.

License

MIT