{"id":13878690,"url":"https://github.com/tstaetter/nanites","last_synced_at":"2026-02-07T08:32:39.828Z","repository":{"id":147353477,"uuid":"427206963","full_name":"tstaetter/nanites","owner":"tstaetter","description":"Command pattern framework for Ruby","archived":false,"fork":false,"pushed_at":"2022-05-31T13:31:24.000Z","size":73,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-10T03:37:56.771Z","etag":null,"topics":["command-pattern","ruby"],"latest_commit_sha":null,"homepage":"https://github.com/tstaetter/nanites","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tstaetter.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-11-12T02:25:23.000Z","updated_at":"2023-01-07T12:11:49.000Z","dependencies_parsed_at":null,"dependency_job_id":"bbe15111-363f-4854-9640-cb70db041b1e","html_url":"https://github.com/tstaetter/nanites","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/tstaetter/nanites","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tstaetter%2Fnanites","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tstaetter%2Fnanites/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tstaetter%2Fnanites/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tstaetter%2Fnanites/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tstaetter","download_url":"https://codeload.github.com/tstaetter/nanites/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tstaetter%2Fnanites/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29190211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T07:37:03.739Z","status":"ssl_error","status_checked_at":"2026-02-07T07:37:03.029Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["command-pattern","ruby"],"created_at":"2024-08-06T08:01:56.870Z","updated_at":"2026-02-07T08:32:39.815Z","avatar_url":"https://github.com/tstaetter.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"[![RSpec](https://github.com/tstaetter/nanites/actions/workflows/main.yml/badge.svg?branch=main\u0026event=push)](https://github.com/tstaetter/nanites/actions/workflows/main.yml)\n\n# Nanites - tiny command pattern framework for Ruby\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'nanites', github: 'tstaetter/nanites', branch: 'main'\n```\n\nAnd then execute:\n\n    $ bundle install\n\nWhen available on rubygems.org, you can install it yourself as:\n\n    $ gem install nanites\n\nTODO: Push gem to rubygems when initial release is ready\n\n## Usage\n\n### \u003ca name=\"command-section\"\u003e\u003c/a\u003eCommands\n\nUsing the commands is pretty straight forward (see specs/support for more examples).\n\n```ruby\nclass MyCommand \u003c Nanites::Commands::Command\n  def execute(**params)\n    # your code here\n    if all_went_well\n      success success_payload\n    else\n      error error_payload\n    end\n  end\nend\n\n# Be sure to only use the class method #execute, it ensures save execution\nresult = MyCommand.execute some_payload\n\nputs result.option if result.success?\n# =\u003e Nanites::Some @value=\u003csuccess payload\u003e\n```\n\nResult values are always wrapped in an ```Nanites::Option``` object which\neither is a ```Nanites::Some``` indicating some return value is available or\n```Nanites::None``` for no value.\n\nThis is done in order to not having the hassle to deal with ```nil``` values. This\napproach is inspired by the Option type in [Rust](https://www.rust-lang.org/).\n\n### Compounds\n\nCompounds can be used to combine several commands.\nA little example:\n\n```ruby\ncmd1 = SomeUsefulCommand.new payload\ncmd2 = SomeAnalyticsCommand.new payload\n\ncompound = Nanites::Commands::Compound.new cmd1, cmd2\n\ncontext = compound.execute\n# =\u003e 'context' is a hash containing the execution results of each command with the commands ID as key\n```\n\n### Specialized compounds\n\nThere are some specials compounds as well, e.g. ```FirstSomeCompound``` returning the first result option which is\na ```Some```, or ```MatchSomeCompound``` returning only results of commands returning ```Some``` options.\n\nFor a full list of special compounds see ```lib/nanites/compounds```. Implementing your own specialized compound is\nas easy as the following (taken from ```lib/nanites/compounds/match_some_compound.rb```):\n\n```ruby\nclass MatchSomeCompound \u003c Compound\n  def initialize(*nanites)\n    super\n\n    @filter = -\u003e(result) { result.option.some? }\n  end\nend\n```\n\nThe magic happens here in the line ```@filter = -\u003e(result) { result.option.some? }``` defining lambda checking the result.\nThe filter is applied within the parent class ```execute``` method, getting passed each command result.\n\n### Some and None\n\n```Some``` and ```None``` are both descendants of ```Option```. Each call of ```Nanites::Commands::Command#execute``` will\nreturn either a ```Some``` or ```None```, indicating that the call returns some value, or no value resp.\n\nWhen using those values, calling ```None#value``` will always return nil. If you need to have an error raised, use ```None#value!```.\n\nTaking the example from the [above code](#command-section), the behaviour is as follows:\n\n```ruby\nputs result.option.value\n# =\u003e will return some value if result.success? is true, nil otherwise\n\nputs result.option.value!\n# =\u003e will return some value if result.success? is true, raise a Nanites::Errors::ValueError otherwise\n```\n\n## Development\n\n`rake spec` to run the tests.\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/tstaetter/nanites.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftstaetter%2Fnanites","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftstaetter%2Fnanites","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftstaetter%2Fnanites/lists"}