npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

autofieldr

v0.8.15

Published

Infantile IoC decorator with almost no features.

Downloads

19

Readme

AutoFieldr

Code Style: Prettier TypeScript: Strict NPM version Join the chat at https://gitter.im/FullScreenShenanigans/community

Infantile IoC decorator with almost no features.

AutoFieldr is the smallest IoC container you'll ever see (under 50 lines of code!). It's also got the fewest toys - it's only targeted for use by EightBittr.

Key tenants:

  • All @members are literally members of the container class instance.
  • Members are stored as lazily evaluated getters: circular dependencies are fine!
  • Use TypeScript.

Usage

Each @member is a literal member of your container class. Declare your members with their classes to have them automagically created as members of your class.

import { member } from "autofieldr";

class DependencyA {}

class Container {
    @member(DependencyA)
    public readonly dependencyA: DependencyA;
}

const { dependencyA } = new Container();

Members receive the instance of the container as a single constructor parameter. They can use it to reference other members.

import { member } from "autofieldr";

class DependencyA {}

class DependencyB {
    public constructor(public readonly instance: Container) {}
}

class Container {
    @member(DependencyA)
    private readonly dependencyA: DependencyA;

    @member(DependencyB)
    public readonly dependencyB: DependencyB;
}

const { dependencyB } = new Container();
const { dependencyA } = dependencyB.instance;

Factories

Your members don't have to be direct classes with dependencies. Pass functions that take in your container as an argument. The values returned by those functions are used as the member value.

Use @factory instead of @member for these.

import { factory } from "autofieldr";

class DependencyA {
    public constructor(public readonly member: string) {}
}

const createDependencyA = () => new DependencyA("value");

class Container {
    @factory(createDependencyA)
    public readonly dependencyA: DependencyA;
}

const { dependencyA } = new Container();

These factory functions have access to all the values on the container, including computed getters.

import { factory } from "autofieldr";

class DependencyA {
    public constructor(public readonly memberA: string) {}
}
class DependencyB {
    public constructor(public readonly referenceA: DependencyA, public readonly valueC: string) {}
}

const createDependencyA = () => new DependencyA("valueA");

const createDependencyB = (instance: Container) => new DependencyB(dependencyA, container.valueC);

class Container {
    @factory(createDependencyA)
    public readonly dependencyA: DependencyA;

    @factory(createDependencyB)
    public readonly dependencyB: DependencyB;

    public readonly valueC = "valueC";
}

const { dependencyA, dependencyB } = new Container();

...and that's about it!

Technical Details

Marking a member with @member or @factory creates a double-layer getter on the class prototype. The prototype will have a getter defined that writes a getter on the calling object. Both getters return a new instance of the member.

For example, with this member:

import { member } from "autofieldr";

class Dependency {}

class Container {
    @member(Dependency)
    public readonly myDependency: Dependency;
}

Container.prototype has a getter defined on "myDependency" that creates a new Dependency(this) and writes a getter on the calling scope's "myDependency" to return it. In practical use, that means the first getter will stay on Container.prototype, and the calling scope that receives the second getter will generally be an instance of the Container class.

See index.ts.

Development

This repository is a portion of the EightBittr monorepo. See its docs/Development.md for details on how to get started. 💖

Running Tests

yarn run test

Tests are written in Mocha and Chai. Their files are written using alongside source files under src/ and named *.test.ts?. Whenever you add, remove, or rename a *.test.t* file under src/, watch will re-run yarn run test:setup to regenerate the list of static test files in test/index.html. You can open that file in a browser to debug through the tests, or run yarn test:run to run them in headless Chrome.

Philosophy

Is AutoFieldr an IoC framework?

If you consider the Container classes from the samples to be equivalent to IoC containers à la Inversify, then sure. The main difference is that members are encouraged to have knowledge of the full application type instead of just their dependencies.

Is AutoFieldr a good IoC framework?

Lol, no.

Application members generally shouldn't have knowledge of the full application. AutoFieldr also has almost no features. You should probably use something standard like Inversify.

Does AutoFieldr violate SOLID principles?

Debatably no.

There's nothing inherently non-SOLID in members being passed the root IoC container. Such a thing happens behind the scenes in normal IoC frameworks; AutoFieldr members just don't have the layer of indirection given by declaring only required parameters. Just as AutoFieldr members can access anything they want, so too can traditional classes by taking in an obscene number of dependencies.